From 3a4298cf15379678c4d437a6554a1453706cc3b3 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 22 Jul 2020 18:09:46 -0700 Subject: [PATCH 001/755] Try re-enabling IBC on macOS. (#39801) --- eng/codeOptimization.targets | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/eng/codeOptimization.targets b/eng/codeOptimization.targets index 6ed7e997487b..73e19c956055 100644 --- a/eng/codeOptimization.targets +++ b/eng/codeOptimization.targets @@ -4,12 +4,7 @@ true false false - - false + false Date: Wed, 22 Jul 2020 18:20:55 -0700 Subject: [PATCH 002/755] Disabled tests with the PlatformDetection.IsPreciseGcSupported (#39796) --- .../tests/DefaultHttpClientFactoryTest.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs index e06530dd842d..72d89b17f8ab 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs @@ -341,8 +341,7 @@ public async Task Factory_CreateClient_WithExpiry_HandlerCanBeReusedBeforeExpiry Assert.NotSame(activeEntry1.Handler, activeEntry2.Handler); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34023", TestRuntimes.Mono)] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported), nameof(PlatformDetection.IsPreciseGcSupported))] public async Task Factory_CleanupCycle_DisposesEligibleHandler() { // Arrange @@ -412,8 +411,7 @@ private async Task SimulateClientUse_Factory_Cleanu return cleanupEntry; } - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34023", TestRuntimes.Mono)] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))] public async Task Factory_CleanupCycle_DisposesLiveHandler() { // Arrange From 811c8c7ffb244c098f22ac134ddb43bf3e152396 Mon Sep 17 00:00:00 2001 From: Anton Lapounov Date: Wed, 22 Jul 2020 21:17:42 -0700 Subject: [PATCH 003/755] Fix FCall implementation collision on ARM64 (#39810) Two FCalls, DependentHandle::nSetPrimary and MarshalNative::GCHandleInternalSet, had identical implementations, which led to a failure in ECall::GetFCallImpl ("Duplicate pImplementation entries found in reverse fcall table"). Add FCUnique() to make them different. --- src/coreclr/src/vm/comdependenthandle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/vm/comdependenthandle.cpp b/src/coreclr/src/vm/comdependenthandle.cpp index 6144483ddc6b..e261f16064a6 100644 --- a/src/coreclr/src/vm/comdependenthandle.cpp +++ b/src/coreclr/src/vm/comdependenthandle.cpp @@ -86,6 +86,9 @@ FCIMPL2(VOID, DependentHandle::nSetPrimary, OBJECTHANDLE handle, Object *_primar _ASSERTE(handle != NULL); + // Avoid collision with MarshalNative::GCHandleInternalSet + FCUnique(0x12); + IGCHandleManager *mgr = GCHandleUtilities::GetGCHandleManager(); mgr->StoreObjectInHandle(handle, _primary); } From 27329074edb0443f724483203b6297e13cc8eba1 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Thu, 23 Jul 2020 00:17:29 -0700 Subject: [PATCH 004/755] Switch Windows arm64 testing to use Windows.10.Arm64v8.Open queue. (#39802) Windows arm testing has been scaled back in #39655 so now we can start using better machines for Windows arm64 testing. These machines were previously used for Windows arm testing. --- eng/pipelines/coreclr/templates/helix-queues-setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index c7c62451b779..caebaea069a0 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -124,7 +124,7 @@ jobs: # Windows_NT arm64 - ${{ if eq(parameters.platform, 'Windows_NT_arm64') }}: - ${{ if and(eq(variables['System.TeamProject'], 'public'), in(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}: - - Windows.10.Arm64.Open + - Windows.10.Arm64v8.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - Windows.10.Arm64 From 5c274f699d9e63d5e3054dff0b995ec186b96426 Mon Sep 17 00:00:00 2001 From: Jan Jahoda Date: Thu, 23 Jul 2020 11:59:00 +0200 Subject: [PATCH 005/755] Suppress credscan false positives (#38026) * Suppress initial cred issues * Another bunch of supresses * Clean up * Another bunch of supresses * Revert to suppression messages * Clean up * Apply suggestions from code review Co-authored-by: Jeremy Barton * Revert passwords literals * Fix suppression justification comment Co-authored-by: Jan Jahoda Co-authored-by: Jeremy Barton --- .config/CredScanSuppressions.json | 115 +++++++++++------- .../Windows/WinHttp/Interop.winhttp_types.cs | 2 + .../Net/Http/HttpClientHandlerTest.Proxy.cs | 4 +- ...ttpClientHandlerTest.ServerCertificates.cs | 2 +- .../System/Net/Http/HttpClientHandlerTest.cs | 1 + .../EC/ECKeyFileTests.cs | 1 + .../RSA/RSAKeyFileTests.cs | 3 + .../tests/ProcessStartInfoTests.cs | 1 + .../AccountManagement/constants.cs | 1 + .../tests/PrincipalTest.cs | 4 +- .../tests/UserPrincipalTest.cs | 4 +- .../UnitTests/ClientCertificateHelper.cs | 5 + .../FunctionalTests/SocketsHttpHandlerTest.cs | 3 +- .../tests/Functional/SmtpClientTest.cs | 6 +- .../src/System/Net/FtpControlStream.cs | 1 + .../src/System/Net/FtpWebRequest.cs | 1 + .../tests/ConnectTest.cs | 1 + .../tests/Rfc2898Tests.cs | 3 + .../tests/Pkcs12/Pkcs12Documents.cs | 1 + .../tests/ExportTests.cs | 4 +- .../tests/EncryptedXmlTest.cs | 6 +- .../tests/TestHelpers.cs | 1 + 22 files changed, 109 insertions(+), 61 deletions(-) diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json index da14baee20e3..984a86f68e69 100644 --- a/.config/CredScanSuppressions.json +++ b/.config/CredScanSuppressions.json @@ -1,49 +1,70 @@ { - "tool": "Credential Scanner", - "suppressions": [ - { - "file": [ - "/eng/common/internal-feed-operations.ps1", - "/eng/common/internal-feed-operations.sh", - "/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs", - "/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs", - "/src/libraries/Common/tests/System/Net/Configuration.Certificates.cs", - "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs", - "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs", - "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.DefaultProxyCredentials.cs", - "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs", - "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs", - "/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs", - "/src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_certificates.ps1", - "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs", - "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.LimitedPrivate.cs", - "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs", - "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs", - "/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionStringBuilderTest.cs", - "/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs", - "/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs", - "/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs", - "/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs", - "/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs", - "/src/libraries/System.Net.Http/tests/UnitTests/DigestAuthenticationTests.cs", - "/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs", - "/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs", - "/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs", - "/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs", - "/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs", - "/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriRelativeResolutionTest.cs", - "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderRefreshTest.cs", - "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs", - "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriRelativeResolutionTest.cs", - "/src/libraries/System.Runtime/tests/System/Uri.CreateStringTests.cs", - "/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs", - "/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs", - "/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs", - "/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs", - "/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs", - "/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs" - ], - "_justification": "Mostly test files. Other files contain harmless examples or constants." - }, - ] + "tool": "Credential Scanner", + "suppressions": [ + { + "_justification": "Unit test containing connection strings under the test.", + "file": [ + "src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionStringBuilderTest.cs" + ] + }, + { + "_justification": "Private key for testing purpose.", + "file": [ + "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyPemTests.cs", + "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs", + "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs", + "src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs" + ], + "placeholder": [ + "-----BEGIN PRIVATE KEY-----", + "-----BEGIN * PRIVATE KEY-----" + ] + }, + { + "_justification": "Test credential for Uri testing", + "file": [ + "src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs", + "src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriRelativeResolutionTest.cs", + "src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderRefreshTest.cs", + "src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs", + "src/libraries/System.Private.Uri/tests/FunctionalTests/UriRelativeResolutionTest.cs", + "src/libraries/System.Runtime/tests/System/Uri.CreateStringTests.cs" + ], + "placeholder": [ + "//*:;&$=123USERINFO@", + "//*:bar@", + "//*:bar1@", + "//*:password1@", + "//*:psw@", + "//*:userinfo2@" + ] + }, + { + "_justification": "Generic test password.", + "file": [ + "src/libraries/Common/tests/System/Net/Configuration.Certificates.cs", + "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs", + "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs", + "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.DefaultProxyCredentials.cs", + "src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs", + "src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_certificates.ps1", + "src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs", + "src/libraries/System.Net.Http/tests/UnitTests/DigestAuthenticationTests.cs", + "src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs", + "src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs", + "src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs", + "src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs" + ], + "placeholder": [ + "\"anotherpassword\"", + "\"bar\"", + "\"mono\"", + "\"password1\"", + "\"rightpassword\"", + "\"testcertificate\"", + "\"unused\"", + "\"wrongpassword\"" + ] + } + ] } diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs index 9dd0d81b56cf..0ab94178f5d5 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs @@ -129,8 +129,10 @@ internal partial class WinHttp public const uint WINHTTP_AUTH_TARGET_PROXY = 0x00000001; public const uint WINHTTP_OPTION_USERNAME = 0x1000; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="It is property descriptor, not secret value.")] public const uint WINHTTP_OPTION_PASSWORD = 0x1001; public const uint WINHTTP_OPTION_PROXY_USERNAME = 0x1002; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="It is property descriptor, not secret value.")] public const uint WINHTTP_OPTION_PROXY_PASSWORD = 0x1003; public const uint WINHTTP_OPTION_SERVER_SPN_USED = 106; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs index ca4c5ce5562a..2580ea977b29 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs @@ -261,8 +261,8 @@ public async Task Proxy_SendSecureRequestThruProxy_ConnectTunnelUsed() [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))] public async Task ProxyAuth_Digest_Succeeds() { - const string expectedUsername = "testusername"; - const string expectedPassword = "testpassword"; + const string expectedUsername = "user"; + const string expectedPassword = "password"; const string authHeader = "Proxy-Authenticate: Digest realm=\"NetCore\", nonce=\"PwOnWgAAAAAAjnbW438AAJSQi1kAAAAA\", qop=\"auth\", stale=false\r\n"; LoopbackServer.Options options = new LoopbackServer.Options { IsProxy = true, Username = expectedUsername, Password = expectedPassword }; var proxyCreds = new NetworkCredential(expectedUsername, expectedPassword); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs index dba69f304dd6..d04b1d7aee68 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs @@ -108,7 +108,7 @@ public async Task UseCallback_HaveCredsAndUseAuthenticatedCustomProxyAndPostToSe handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; handler.Proxy = new WebProxy(proxyServer.Uri) { - Credentials = new NetworkCredential("rightusername", "rightpassword") + Credentials = new NetworkCredential("user", "password") }; const string content = "This is a test"; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index e243987445c9..2aa3c26ee16b 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1004,6 +1004,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => $"Accept-Patch:{fold} text/example;charset=utf-8{newline}" + $"Accept-Ranges:{fold} bytes{newline}" + $"Age: {fold}12{newline}" + + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy authorization.")] $"Authorization: Bearer 63123a47139a49829bcd8d03005ca9d7{newline}" + $"Allow: {fold}GET, HEAD{newline}" + $"Alt-Svc:{fold} http/1.1=\"http2.example.com:8001\"; ma=7200{newline}" + 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 4775d6b0013c..62fc99addf55 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 @@ -176,6 +176,7 @@ public void ReadNistP521EncryptedPkcs8_Pbes2_Aes128_Sha384() public void ReadNistP521EncryptedPkcs8_Pbes2_Aes128_Sha384_PasswordBytes() { // PBES2, PBKDF2 (SHA384), AES128 + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] const string base64 = @" MIIBXTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI/JyXWyp/t3kCAggA MAwGCCqGSIb3DQIKBQAwHQYJYIZIAWUDBAECBBA3H8mbFK5afB5GzIemCCQkBIIB 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 f2a79bcc7290..d47ad3b3dca1 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 @@ -763,6 +763,7 @@ public static void ReadPbes2Rc2EncryptedDiminishedDP() public static void ReadPbes2Rc2EncryptedDiminishedDP_PasswordBytes() { // PBES2: PBKDF2 + RC2-128 + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] const string base64 = @" MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIKZEFT76zCFECAggA AgEQMBkGCCqGSIb3DQMCMA0CAToECE1Yyzk6++IPBIIBYDDvaYLkET8eudcYLQMf @@ -788,6 +789,7 @@ public static void ReadPbes2Rc2EncryptedDiminishedDP_PasswordBytes() [Fact] public static void ReadEncryptedDiminishedDP_EmptyPassword() { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] const string base64 = @" MIIBgTAbBgkqhkiG9w0BBQMwDgQIJtjMez/9Gg4CAggABIIBYElq9UOOphEPU3b7 G/mV8M1uEdjigidMPih3b9IIJhrjMAEix2IjS+brFL7KRQgucpZZoaFU1utvkUHg @@ -812,6 +814,7 @@ public static void ReadEncryptedDiminishedDP_EmptyPassword() [Fact] public static void ReadEncryptedDiminishedDP_EmptyPasswordBytes() { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] const string base64 = @" MIIBgTAbBgkqhkiG9w0BBQMwDgQIJtjMez/9Gg4CAggABIIBYElq9UOOphEPU3b7 G/mV8M1uEdjigidMPih3b9IIJhrjMAEix2IjS+brFL7KRQgucpZZoaFU1utvkUHg diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs index 09eea0aba657..ced27b832ab3 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs @@ -354,6 +354,7 @@ public void TestWorkingDirectoryPropertyInChildProcess() [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported)), PlatformSpecific(TestPlatforms.Windows), OuterLoop] // Uses P/Invokes, Requires admin privileges public void TestUserCredentialsPropertiesOnWindows() { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] string username = "test", password = "PassWord123!!"; try { diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs index 8662ef2bf3ca..93c5e6f23c77 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs @@ -95,6 +95,7 @@ private PropertyNames() { } // these two are not publicly exposed properties, but are used internally to track ResetPassword/ExpirePasswordNow // operations against unpersisted principals, so that they can be performed once the principal has been Saved + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Not a password.")] internal const string PwdInfoPassword = "AuthenticablePrincipal.PasswordInfo.Password"; internal const string PwdInfoExpireImmediately = "AuthenticablePrincipal.PasswordInfo.ExpireImmediately"; } diff --git a/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs b/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs index b46ceab58626..7b91de75941b 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs @@ -15,8 +15,8 @@ public abstract class PrincipalTest : IDisposable private void RefreshContext() { - string username = "Administrator"; - string password = "Adrumble@6"; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] + string username = "Administrator", password = "Adrumble@6"; string OU = "Tests"; string baseDomain = WindowsIdentity.GetCurrent().Name.Split(new char[] { '\\' })[1] + "-TEST"; diff --git a/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs b/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs index 73d1a9210747..22fa3f7053b3 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs @@ -31,8 +31,8 @@ public void UserPrincipalConstructorTest() public void ComputedUACCheck() { - string username = "Administrator"; - string password = "Adrumble@6"; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] + string username = "Administrator", password = "Adrumble@6"; //TODO: don't assume it exists, create it if its not string OU = "TestNull"; string baseDomain =WindowsIdentity.GetCurrent().Name.Split(new char[] { '\\' })[1] + "-TEST"; diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/ClientCertificateHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/ClientCertificateHelper.cs index b0e144992937..c284d2be5925 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/ClientCertificateHelper.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/ClientCertificateHelper.cs @@ -13,6 +13,7 @@ public class ClientCertificateHelper private readonly X509Certificate2 _cert_KeyUsageIncludesDigitalSignature_EKUIncludesClientAuth_PrivateKey = new X509Certificate2( Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Dummy certificate for testing.")] @"MIIKTgIBAzCCCgoGCSqGSIb3DQEHAaCCCfsEggn3MIIJ8zCCBgwGCSqGSIb3DQEHAaCCBf0EggX5 MIIF9TCCBfEGCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAiHDatvDr8QBQIC B9AEggTYv1r4ckwt7o6f6DCMHlb/zv4t7rPju+PP0PjoJ8kzPfj419aSeyPuE+65YH9WFDqafJed @@ -65,6 +66,7 @@ public class ClientCertificateHelper private readonly X509Certificate2 _cert_KeyUsageMissingDigitalSignature_EKUIncludesClientAuth_PrivateKey = new X509Certificate2( Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Dummy certificate for testing.")] @"MIIKTgIBAzCCCgoGCSqGSIb3DQEHAaCCCfsEggn3MIIJ8zCCBgwGCSqGSIb3DQEHAaCCBf0EggX5 MIIF9TCCBfEGCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAiSNi65ZF5ZTQIC B9AEggTYRTivDtzHOWRR+MobtGFEUu6d1PiIlF1Ic84FWvmFCcJShkBmg3cBqDilqtamAkDkga4h @@ -117,6 +119,7 @@ public class ClientCertificateHelper private readonly X509Certificate2 _cert_KeyUsageIncludesDigitalSignature_EKUMissingClientAuth_PrivateKey = new X509Certificate2( Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Dummy certificate for testing.")] @"MIIKRgIBAzCCCgIGCSqGSIb3DQEHAaCCCfMEggnvMIIJ6zCCBgQGCSqGSIb3DQEHAaCCBfUEggXx MIIF7TCCBekGCyqGSIb3DQEMCgECoIIE9jCCBPIwHAYKKoZIhvcNAQwBAzAOBAhCUuNQ0RqfZQIC B9AEggTQHCQRSiCiNI7egTvUaI1Z3tfeLwFWvG7B/za5v9fb97MExoyVQSDmUyUDTlVEcg3gVqJZ @@ -169,6 +172,7 @@ public class ClientCertificateHelper private readonly X509Certificate2 _cert_KeyUsageIncludesDigitalSignature_NoEKU_PrivateKey = new X509Certificate2( Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Dummy certificate for testing.")] @"MIIKPgIBAzCCCfoGCSqGSIb3DQEHAaCCCesEggnnMIIJ4zCCBgwGCSqGSIb3DQEHAaCCBf0EggX5 MIIF9TCCBfEGCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAijQh1kbOZOYQIC B9AEggTY+wDp3V31Lh7f8YrsqEsyGZ+GlYvFhLWvDASjisYJi5NlQ0ONbf0KOXHVSvBj3tVyuHm4 @@ -221,6 +225,7 @@ public class ClientCertificateHelper private readonly X509Certificate2 _cert_KeyUsageIncludesDigitalSignature_EKUIncludesClientAuth_NoPrivateKey = new X509Certificate2( Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Dummy certificate for testing.")] @"MIIDFjCCAf6gAwIBAgIQTm8+EF94L4FJ0nBFl5LICzANBgkqhkiG9w0BAQsFADAb MRkwFwYDVQQDDBB1c2VyQGV4YW1wbGUuY29tMCAXDTE1MTAwNTEwMDMwMFoYDzIx MTUxMDA1MTAwMzAwWjAbMRkwFwYDVQQDDBB1c2VyQGV4YW1wbGUuY29tMIIBIjAN diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index a60e509ba7fd..ae32a02a0ef3 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -663,6 +663,7 @@ await TestHelper.WhenAllCompletedOrAnyFailed( [Theory] [InlineData("Age", "1")] + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy authorisation header.")] [InlineData("Authorization", "Basic YWxhZGRpbjpvcGVuc2VzYW1l")] [InlineData("Cache-Control", "no-cache")] [InlineData("Content-Encoding", "gzip")] @@ -1519,7 +1520,7 @@ public async Task ProxyAuth_SameConnection_Succeeds() using (var handler = new HttpClientHandler()) { - handler.Proxy = new UseSpecifiedUriWebProxy(proxyUrl, new NetworkCredential("abc", "def")); + handler.Proxy = new UseSpecifiedUriWebProxy(proxyUrl, new NetworkCredential("abc", "password")); using (HttpClient client = CreateHttpClient(handler)) { diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs index 8a6f58093f4d..3d55574f0cab 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs @@ -293,7 +293,7 @@ public void TestMailDelivery() { using var server = new LoopbackSmtpServer(); using SmtpClient client = server.CreateClient(); - client.Credentials = new NetworkCredential("Foo", "Bar"); + client.Credentials = new NetworkCredential("foo", "bar"); MailMessage msg = new MailMessage("foo@example.com", "bar@example.com", "hello", "howdydoo"); client.Send(msg); @@ -303,8 +303,8 @@ public void TestMailDelivery() Assert.Equal("hello", server.Message.Subject); Assert.Equal("howdydoo", server.Message.Body); Assert.Equal(GetClientDomain(), server.ClientDomain); - Assert.Equal("Foo", server.Username); - Assert.Equal("Bar", server.Password); + Assert.Equal("foo", server.Username); + Assert.Equal("bar", server.Password); Assert.Equal("LOGIN", server.AuthMethodUsed, StringComparer.OrdinalIgnoreCase); } diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs index 5ddcd417e9b2..4fb863569a6b 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs @@ -499,6 +499,7 @@ protected override PipelineEntry[] BuildCommandsList(WebRequest req) if (domainUserName.Length == 0 && password.Length == 0) { domainUserName = "anonymous"; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Anonymous FTP credential in production code.")] password = "anonymous@"; } diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs index b95ba4b49d10..dacc4b7cf962 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs @@ -220,6 +220,7 @@ public sealed class FtpWebRequest : WebRequest private LazyAsyncResult? _readAsyncResult; private LazyAsyncResult? _requestCompleteAsyncResult; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Anonymous FTP credential in production code.")] private static readonly NetworkCredential s_defaultFtpNetworkCredential = new NetworkCredential("anonymous", "anonymous@", string.Empty); private const int s_DefaultTimeout = 100000; // 100 seconds private static readonly TimerThread.Queue s_DefaultTimerQueue = TimerThread.GetOrCreateQueue(s_DefaultTimeout); diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs index 20d1cc5fdb19..6d4d63a730f1 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs @@ -214,6 +214,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => using (var clientSocket = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy authorisation header.")] clientSocket.Options.SetRequestHeader("Authorization", "AWS4-HMAC-SHA256 Credential= AKIAXXXXXXXXXXXYSZA /20190301/us-east-2/neptune-db/aws4_request, SignedHeaders=host;x-amz-date, Signature=b8155de54d9faab00000000000000000000000000a07e0d7dda49902e4d9202"); await clientSocket.ConnectAsync(uri, cts.Token); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs b/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs index e4ec0101290f..3a13bd7b3e89 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs @@ -518,6 +518,7 @@ private static IEnumerable GetKnownValuesTestCases() { CaseName = "SHA256 alternate", HashAlgorithmName = "SHA256", + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] Password = "abcdefghij", Salt = ascii.GetBytes("abcdefghij"), IterationCount = 1, @@ -532,6 +533,7 @@ private static IEnumerable GetKnownValuesTestCases() { CaseName = "SHA384 alternate", HashAlgorithmName = "SHA384", + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] Password = "abcdefghij", Salt = ascii.GetBytes("abcdefghij"), IterationCount = 1, @@ -546,6 +548,7 @@ private static IEnumerable GetKnownValuesTestCases() { CaseName = "SHA512 alternate", HashAlgorithmName = "SHA512", + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] Password = "abcdefghij", Salt = ascii.GetBytes("abcdefghij"), IterationCount = 1, 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 0fc7f919bbd7..51c80e09c768 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs @@ -222,6 +222,7 @@ internal static class Pkcs12Documents "2b0e03021a05000414c429b968eeca558cc2ec486f89b78c024bdecf2804" + "087cbeafa8089685a102030927c1").HexToByteArray(); + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy credentials.")] internal const string OracleWalletPassword = "123Wallet"; } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs index b508552ea01a..7f0455ea74d7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs @@ -76,6 +76,7 @@ public static void ExportAsPfx() [Fact] public static void ExportAsPfxWithPassword() { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Password for testing purpose.")] const string password = "Cotton"; using (X509Certificate2 c1 = new X509Certificate2(TestData.MsCertificate)) @@ -94,6 +95,7 @@ public static void ExportAsPfxWithPassword() [Fact] public static void ExportAsPfxVerifyPassword() { + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Password for testing purpose.")] const string password = "Cotton"; using (X509Certificate2 c1 = new X509Certificate2(TestData.MsCertificate)) @@ -109,7 +111,7 @@ public static void ExportAsPfxWithPrivateKeyVerifyPassword() using (var cert = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword, X509KeyStorageFlags.Exportable)) { Assert.True(cert.HasPrivateKey, "cert.HasPrivateKey"); - + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Password for testing purpose.")] const string password = "Cotton"; byte[] pfx = cert.Export(X509ContentType.Pkcs12, password); diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs b/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs index fc0a7d80195a..f547ba74dda2 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs @@ -141,6 +141,7 @@ public void Sample2() { aes.Mode = CipherMode.CBC; aes.KeySize = 256; + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] aes.Key = Convert.FromBase64String("o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); aes.Padding = PaddingMode.Zeros; @@ -173,6 +174,7 @@ public void RoundtripSample1() aes.Mode = CipherMode.CBC; aes.KeySize = 256; aes.IV = Convert.FromBase64String("pBUM5P03rZ6AE4ZK5EyBrw=="); + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] aes.Key = Convert.FromBase64String("o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); aes.Padding = PaddingMode.Zeros; @@ -203,8 +205,8 @@ public void RoundtripSample1() { aes.Mode = CipherMode.CBC; aes.KeySize = 256; - aes.Key = Convert.FromBase64String( - "o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test key.")] + aes.Key = Convert.FromBase64String("o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); aes.Padding = PaddingMode.Zeros; XmlDocument doc = new XmlDocument(); diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs b/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs index 3f138acfd762..4cdcd7d48334 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs @@ -185,6 +185,7 @@ public static IEnumerable GetSymmetricAlgorithms(bool } private static readonly byte[] SamplePfx = Convert.FromBase64String( + // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Unit test dummy certificate.")] @"MIIFpQIBAzCCBV8GCSqGSIb3DQEHAaCCBVAEggVMMIIFSDCCAl8GCSqGSIb3DQEHBqCCAlAwggJMAgEAMIICRQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIGTfVa4+vR1UCAgfQgIICGJuFE9alFWJFkaoeewKDIEnVwRxXfMsi8dcySYnp7jljEUQBfW/GIbOf7Lg2nHd0qxvxYI2YL4Zs+d0jWbqfNHamGFCMPe1dK957Z2PsKXR183vMSgnmlLAHktsIN+Gor7q1GbQ4ljfZkGqZ/rkgUsgsSYZSnJevP/uH0VnvxemljVJ7N7gKMYO0aqrca4qJ0O4YxBYyaerPFUOYunQlvk6DOF3SQXza5oFKcPGrSpE/9eQrnmm64BtbdnUE6qqEjfZfNa6MOD3vOnapLUBsel2TtVCu8tEl7I8FGxozTLXVTXOBkL3k7xLRS52ZtpbcU2JIhlDGpxeFXmjKYzdzHoL20iJubfdkUYtHwB0XjBKKLcI7jfgGgjNauaTLAx8FF+5O9s7Zbj2+SKWv56kqAwdX+iH21VgjAN9EByIXHb3p2ZOvy4ONDXTmfSn7jbuPLZTi+u6bxn2JOLf/gjEA8FiCuQDL9gF247bnUq08Z1uzuAUeaPL13U8mxwEuvCOXx5NEQIuf3cusnaH4+7uIhPk5tnfA5XOaABySetRjZhVN5dC5/g3KTwmaDamlW3Y7Az/NzAC4uKa2ny5jwYKBgHviEKOyJfLDKr5fOMRToOfgxvAdXZohQQTE1+TcBjp+eeV5koDfB1ReCKIRHugPZu5j9SCVcYanwFeJ5M4cEHZ9U1Ytsmzjh0fwV17D/hxQ4aS4VwVpOMypMIIC4QYJKoZIhvcNAQcBoIIC0gSCAs4wggLKMIICxgYLKoZIhvcNAQwKAQKgggKeMIICmjAcBgoqhkiG9w0BDAEDMA4ECBRdKqx022cfAgIH0ASCAnjZx9fvPCHizdH6apVzWWmfy/84HvDPjFOUV1TPehTnDPkNpF/uK/ya4jlbl4Kw0Zfknt5Xydl89SMXIWa2q+nWmxyG3XyfGqOAeBfJBSdCF5K3qkZZnzEfraKZZ5Hh8IEmK+ey45O6sltua6Xl5MRBmKLiwma7vX4ihXQTMfb0WlWDYCXZi85OeF0OlUjRWAwz4PeeiBK4nmI/vNmF1EzDVdZGkrrE8mot3Y4z6bvwqip2tUUbHuMnC+/1ikAcJzCOw4NpnEWCRtIJxgJ9es8E8CUfHESnWKe4nh6tJVJ15B8/7oF7N6j7oq4Oj346JthKoWWkzifNaH79A60/uFh08Rv7zrtJf6kedY6Ve2bR5lhWn0cv9Q6IaoqTmKKTmKJnjdQO9lKRCR6iI2OsYtXBropD8xhNNqsyfpNmP0G6wFiEZZxZjWOkZEJLUzFbH+Su+7l2l4FN9sM7k211/l3/3YF1QJHwZsgL98DZL4qE+nkuZQcdtOUx8QTyTOcVb3IzgCAwZm0rgdXQpJ9yRBgOC/6MnqaCPI0jJuavXF/a28GJWWGlazx7SWTrbzNVJ83ZhQ+pfPEPtMi3t0YVLLvapu3otgpiMkv4ew/ssXwYbg6xBWfotK+NG1cPwVFy9/V9+H5dpdvRI/le2QG0F5xCfCeKh/3AuNiMPEGoVUR5kj5cwFK6eskvt/+74ZenxfNPZ2Uttiw8DsqtTx1gxhcSZeU5YWpO7O78RaYE4Ll4kPbbvIaR18Napb6NKP846z02zvaw+feXARLe0HUY58TlmUjSX3MZRK4PEdyMIQ/URyPimj4rImaDfFrKPAHIjqT3EKv+KuNs8TEVMBMGCSqGSIb3DQEJFTEGBAQBAAAAMD0wITAJBgUrDgMCGgUABBRZOo132cuo2zNyy+SH2c+pN4OGmQQU2nQao3je7DTj2G6Gge8pooPf2ncCAgfQ"); public static X509Certificate2 GetSampleX509Certificate() From 05f17e3170d014efe63202c4e7e7b641e8f8fef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 23 Jul 2020 14:14:44 +0200 Subject: [PATCH 006/755] Hardcode path to ICU on macOS (#39833) --- .../Native/Unix/System.Globalization.Native/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt index ca9ed1fbe159..f71af8ada58e 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt @@ -28,7 +28,7 @@ if(CLR_CMAKE_TARGET_UNIX) message(FATAL_ERROR "Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.") return() endif() - add_definitions(-DOSX_ICU_LIBRARY_PATH=\"${ICUCORE}\") + add_definitions(-DOSX_ICU_LIBRARY_PATH=\"/usr/lib/libicucore.dylib\") add_definitions(-DU_DISABLE_RENAMING) else() find_library(ICUUC icuuc) From 30e6b797883a49afc57954bd0dc73e0d124e5aa0 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Thu, 23 Jul 2020 16:21:59 +0300 Subject: [PATCH 007/755] [wasm] Enable System.Threading.Thread.Tests test suite (#39826) --- src/libraries/System.Threading.Thread/tests/ThreadTests.cs | 1 + src/libraries/tests.proj | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs index 443c500fd8e8..5bc54ba6b75b 100644 --- a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs +++ b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs @@ -160,6 +160,7 @@ public static IEnumerable ApartmentStateTest_MemberData() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))] [ActiveIssue("https://github.com/dotnet/runtime/issues/34543", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Diagnostics.Process is not supported on this platform. [InlineData("STAMain.exe", "GetApartmentStateTest")] [InlineData("STAMain.exe", "SetApartmentStateTest")] [InlineData("STAMain.exe", "WaitAllNotSupportedOnSta_Test0")] diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 98273a01002a..626c4ea4992f 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -37,7 +37,6 @@ - From 7de187a2a28ce02bf7000bdbf3f2c82092ef643b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 23 Jul 2020 16:43:07 +0200 Subject: [PATCH 008/755] WASM: Fix System.Net.Primitives and tests (#39748) Add HostInformationPal and InterfaceInfoPal implementations for Browser. In CookiePortTest.cs use example.com instead of localhost for the tests since Browser uses `localhost` as the `Environment.MachineName` and that changes the test values. Allows the tests to run on WebAssembly: ``` System.Net.Primitives.Pal.Tests: Tests run: 60, Errors: 0, Failures: 0, Skipped: 0. Time: 0.15872s System.Net.Primitives.Functional.Tests: Tests run: 2620, Errors: 0, Failures: 0, Skipped: 1. Time: 3.145804s ``` --- .../HostInformationPal.Browser.cs | 18 +++++++++++ .../InterfaceInfoPal.Browser.cs | 14 ++++++++ .../src/System.Net.Primitives.csproj | 24 +++++++++----- .../CookieTest/CookiePortTest.cs | 20 ++++++------ .../FunctionalTests/SocketAddressTest.cs | 2 +- .../System.Net.Primitives.Pal.Tests.csproj | 32 ++++++++++++------- src/libraries/tests.proj | 2 -- 7 files changed, 79 insertions(+), 33 deletions(-) create mode 100644 src/libraries/Common/src/System/Net/NetworkInformation/HostInformationPal.Browser.cs create mode 100644 src/libraries/Common/src/System/Net/NetworkInformation/InterfaceInfoPal.Browser.cs diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/HostInformationPal.Browser.cs b/src/libraries/Common/src/System/Net/NetworkInformation/HostInformationPal.Browser.cs new file mode 100644 index 000000000000..01c30fda1644 --- /dev/null +++ b/src/libraries/Common/src/System/Net/NetworkInformation/HostInformationPal.Browser.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Net.NetworkInformation +{ + internal static class HostInformationPal + { + public static string GetHostName() + { + return Environment.MachineName; + } + + public static string GetDomainName() + { + return Environment.UserDomainName; + } + } +} diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/InterfaceInfoPal.Browser.cs b/src/libraries/Common/src/System/Net/NetworkInformation/InterfaceInfoPal.Browser.cs new file mode 100644 index 000000000000..d5d50a2aa336 --- /dev/null +++ b/src/libraries/Common/src/System/Net/NetworkInformation/InterfaceInfoPal.Browser.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Net.NetworkInformation +{ + internal static class InterfaceInfoPal + { + public static uint InterfaceNameToIndex(string interfaceName) + { + // zero means "unknown" + return 0; + } + } +} diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index 8c5c2d9924ea..cfc1e85797bb 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -117,14 +117,22 @@ - + + + + + + - - - + + + + diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookiePortTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookiePortTest.cs index d7a342850767..5ed895d050d1 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookiePortTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookiePortTest.cs @@ -13,65 +13,65 @@ public class CookiePortTest public CookiePortTest() { _cc = new CookieContainer(); - _cookie = new Cookie("name", "value1", "/path", "localhost"); + _cookie = new Cookie("name", "value1", "/path", "example.com"); // use both space and comma as delimiter _cookie.Port = "\"80 110,1050, 1090 ,1100\""; - _cc.Add(new Uri("http://localhost/path"), _cookie); + _cc.Add(new Uri("http://example.com/path"), _cookie); } [Fact] public void Port_SetMultiplePorts_Port1Set() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:80/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:80/path")); Assert.Equal(1, cookies.Count); } [Fact] public void Port_SpaceDelimiter_PortSet() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:110/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:110/path")); Assert.Equal(1, cookies.Count); } [Fact] public void Port_CommaDelimiter_PortSet() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:1050/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:1050/path")); Assert.Equal(1, cookies.Count); } [Fact] public void Port_CommaSpaceDelimiter_PortSet() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:1090/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:1090/path")); Assert.Equal(1, cookies.Count); } [Fact] public void Port_SpaceCommaDelimiter_PortSet() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:1100/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:1100/path")); Assert.Equal(1, cookies.Count); } [Fact] public void Port_SetMultiplePorts_NoPortMatch() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:1000/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:1000/path")); Assert.Equal(0, cookies.Count); } [Fact] public void Port_SetMultiplePorts_NoPathMatch() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost:1050")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com:1050")); Assert.Equal(0, cookies.Count); } [Fact] public void Port_NoPortSpecified_ReturnsCookies() { - CookieCollection cookies = _cc.GetCookies(new Uri("http://localhost/path")); + CookieCollection cookies = _cc.GetCookies(new Uri("http://example.com/path")); Assert.Equal(1, cookies.Count); } } diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/SocketAddressTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/SocketAddressTest.cs index a4ce20f12fbd..af2a89c4807a 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/SocketAddressTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/SocketAddressTest.cs @@ -98,7 +98,7 @@ public static void ToString_LegacyUnknownFamily_Success(AddressFamily family) [Theory] [InlineData(AddressFamily.Packet)] [InlineData(AddressFamily.ControllerAreaNetwork)] - [PlatformSpecific(~TestPlatforms.Linux)] + [PlatformSpecific(~(TestPlatforms.Linux | TestPlatforms.Browser))] public static void ToString_UnsupportedFamily_Throws(AddressFamily family) { Assert.Throws(() => new SocketAddress(family)); diff --git a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj index 38a9e23817f9..212d2de6287e 100644 --- a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj +++ b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj @@ -85,8 +85,6 @@ - - - - - + + + + Link="Common\System\Net\NetworkInformation\InterfaceInfoPal.Unix.cs" /> + + + + + Link="Common\Interop\Unix\System.Native\Interop.InterfaceNameToIndex.cs" /> + + + + \ No newline at end of file diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 626c4ea4992f..eb67053b5b88 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -32,8 +32,6 @@ - - From e8c4169b4fc4eb9a71f296b3bd2e96db16d32d35 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 23 Jul 2020 08:19:04 -0700 Subject: [PATCH 009/755] Fix CNG persisted symmetric key operations During a code cleanup the encoding changed from UTF-16LE to UTF-8, which is not valid for the P/Invoke. --- .../src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs | 4 ++-- .../System.Security.Cryptography.Cng/tests/AesCngTests.cs | 3 --- .../tests/TripleDESCngTests.cs | 3 --- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs index 47754356c939..9b88e7e5382c 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs @@ -112,8 +112,8 @@ private void Reset() private readonly bool _encrypting; private static readonly CngProperty s_ECBMode = - new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.UTF8.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_ECB + "\0"), CngPropertyOptions.None); + new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_ECB + "\0"), CngPropertyOptions.None); private static readonly CngProperty s_CBCMode = - new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.UTF8.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CBC + "\0"), CngPropertyOptions.None); + new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CBC + "\0"), CngPropertyOptions.None); } } diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/AesCngTests.cs b/src/libraries/System.Security.Cryptography.Cng/tests/AesCngTests.cs index abd62a6fbc25..981242fd983a 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/AesCngTests.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/AesCngTests.cs @@ -11,7 +11,6 @@ public static class AesCngTests private static readonly CngAlgorithm s_cngAlgorithm = new CngAlgorithm("AES"); - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalTheory(nameof(SupportsPersistedSymmetricKeys))] // AES128-ECB-NoPadding 2 blocks. @@ -48,7 +47,6 @@ public static void GetKey_NonExportable() keyName => new AesCng(keyName)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalFact(nameof(SupportsPersistedSymmetricKeys))] public static void SetKey_DetachesFromPersistedKey() @@ -75,7 +73,6 @@ public static void LoadWrongKeyType() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalFact(nameof(SupportsPersistedSymmetricKeys), nameof(IsAdministrator))] public static void VerifyMachineKey() diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs b/src/libraries/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs index 6abee43359c7..60934e5b7379 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs @@ -11,7 +11,6 @@ public static class TripleDESCngTests private static readonly CngAlgorithm s_cngAlgorithm = new CngAlgorithm("3DES"); - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalTheory(nameof(SupportsPersistedSymmetricKeys))] // 3DES192-ECB-NoPadding 2 blocks. @@ -46,7 +45,6 @@ public static void GetKey_NonExportable() keyName => new TripleDESCng(keyName)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalFact(nameof(SupportsPersistedSymmetricKeys))] public static void SetKey_DetachesFromPersistedKey() @@ -73,7 +71,6 @@ public static void LoadWrongKeyType() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/31092")] [OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)] [ConditionalFact(nameof(SupportsPersistedSymmetricKeys), nameof(IsAdministrator))] public static void VerifyMachineKey() From 809a06f45161ae686a06b9e9ccc2f45097b91657 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 23 Jul 2020 17:20:26 +0200 Subject: [PATCH 010/755] Remove depprojs in favor of PackageReferences (#35606) - Remove depprojs which currently binplace external references into the RefPath folders in favor of PackageReference and PackageDownload items. - Build all configurations by default when building an individual project (either on the CLI or inside VS) same as with the official SDK. This enables .NETFramework Test Explorer support. - Centrally define libraries that compose the shared framework instead of in each Directory.Build.props file to be able to build the targeting pack first and consume it in the OOB libraries. - Use ProjectReferences to reference OOB projects. Compile against the reference assembly but use the implementation assembly app-local during runtime. - Remove OOBs from the testhost and remove the testhost folder for .NETFramework as it isn't required anymore. - Only binplace for $(NetCoreAppCurrent) to compose a) the targeting pack, b) the runtime pack, c) the testhost, d) a full closure for the shims. - Use Targeting Packs for OOB projects (with their implicit assembly references) but still explicitly define granular references for .NETCoreApp configurations (DisableImplicitAssemblyReferences switch). Use the implicit targeting pack references in some Microsoft.Extensions.* cases. - Remove placeholder configurations as they aren't needed anymore with explicit P2Ps vs Targeting Pack references. - Remove implicit assembly references (ie for .NETFramework, mscorlib) - Remove AssemblySearchPath hacks that were introduced with b7c4cb7 as the targeting pack is now used by default. - Reduce unnecessary .NETFramework configurations that were added to run tests in favor of the already existing ref&src configurations. - Stop hardcoding the paths for wasm assemblies and use the returned TargetPath of the ProjectReferences. - Addressed formatting (ItemGroups, References at the bottom of the project file, ordering of references, use LibrariesProjectRoot instead of a relative path, unnecessary AssemblyName and RootNamespace properties which are identical to the project name, ordering of tfms) - Revert "fix clean (#33758)" --- Build.proj | 6 +- Directory.Build.props | 2 +- docs/coding-guidelines/project-guidelines.md | 21 +-- docs/project/library-servicing.md | 2 +- docs/workflow/building/libraries/README.md | 2 +- eng/AvoidRestoreCycleOnSelfReference.targets | 14 ++ eng/BeforeTargetFrameworkInference.targets | 4 - eng/Configurations.props | 2 - eng/Subsets.props | 9 +- eng/Version.Details.xml | 2 +- eng/Versions.props | 37 +++- eng/build.ps1 | 2 +- eng/build.sh | 2 +- eng/illink.targets | 2 +- eng/pipelines/coreclr/templates/perf-job.yml | 6 +- eng/pipelines/libraries/base-job.yml | 6 +- eng/pipelines/libraries/build-job.yml | 4 +- .../libraries/helix-queues-setup.yml | 12 +- eng/pipelines/libraries/outerloop.yml | 2 +- eng/pipelines/libraries/run-test-job.yml | 4 +- eng/pipelines/runtime.yml | 2 +- eng/referenceAssemblies.props | 8 +- eng/referenceFromRuntime.targets | 124 -------------- eng/references.targets | 91 +++++----- eng/resolveContract.targets | 49 +++++- eng/restore/repoRestore.props | 1 + eng/targetingpacks.targets | 106 ++++++++++++ eng/testing/.runsettings | 4 - eng/testing/RunnerTemplate.cmd | 6 - eng/testing/netfx.exe.config | 1 - eng/testing/outerBuild.targets | 8 +- eng/testing/runsettings.targets | 1 - eng/testing/runtimeConfiguration.targets | 40 ++--- eng/testing/tests.mobile.targets | 15 +- eng/testing/tests.props | 2 - eng/testing/tests.targets | 10 +- eng/testing/xunit/xunit.console.targets | 10 +- eng/testing/xunit/xunit.targets | 7 + global.json | 2 +- ...ateRuntimeRootILLinkDescriptorFile.targets | 2 +- .../Common/src/System/HexConverter.cs | 2 +- .../test/ConditionalFactTest.cs | 2 +- .../test/ConditionalTheoryTest.cs | 2 +- .../tests/TestUtilities/TestUtilities.csproj | 11 +- src/libraries/Directory.Build.props | 82 ++------- src/libraries/Directory.Build.targets | 123 ++++++------- .../Microsoft.CSharp/Directory.Build.props | 1 - .../src/Microsoft.CSharp.csproj | 2 - .../tests/Microsoft.CSharp.Tests.csproj | 5 +- ...gnostics.Tracing.EventSource.Redist.csproj | 7 +- ...cs.Tracing.EventSource.Redist.Tests.csproj | 3 +- ...oft.Extensions.Caching.Abstractions.csproj | 2 +- ...oft.Extensions.Caching.Abstractions.csproj | 8 +- ...Microsoft.Extensions.Caching.Memory.csproj | 15 +- ...Microsoft.Extensions.Caching.Memory.csproj | 18 +- ...oft.Extensions.Caching.Memory.Tests.csproj | 8 +- ...tensions.Configuration.Abstractions.csproj | 6 +- ...tensions.Configuration.Abstractions.csproj | 17 +- ...oft.Extensions.Configuration.Binder.csproj | 8 +- ...oft.Extensions.Configuration.Binder.csproj | 13 +- ...tensions.Configuration.Binder.Tests.csproj | 5 +- ...xtensions.Configuration.CommandLine.csproj | 6 +- ...xtensions.Configuration.CommandLine.csproj | 13 +- ...ons.Configuration.CommandLine.Tests.csproj | 6 +- ....Configuration.EnvironmentVariables.csproj | 6 +- ....Configuration.EnvironmentVariables.csproj | 12 +- ...guration.EnvironmentVariables.Tests.csproj | 6 +- ...nsions.Configuration.FileExtensions.csproj | 10 +- ...nsions.Configuration.FileExtensions.csproj | 17 +- ....Configuration.FileExtensions.Tests.csproj | 3 +- ...rosoft.Extensions.Configuration.Ini.csproj | 10 +- ...rosoft.Extensions.Configuration.Ini.csproj | 15 +- ....Extensions.Configuration.Ini.Tests.csproj | 5 +- ...osoft.Extensions.Configuration.Json.csproj | 16 +- ...osoft.Extensions.Configuration.Json.csproj | 29 ++-- ...Extensions.Configuration.Json.Tests.csproj | 5 +- ...xtensions.Configuration.UserSecrets.csproj | 8 +- ...xtensions.Configuration.UserSecrets.csproj | 25 +-- ...ons.Configuration.UserSecrets.Tests.csproj | 4 +- ...rosoft.Extensions.Configuration.Xml.csproj | 12 +- ...rosoft.Extensions.Configuration.Xml.csproj | 26 +-- ....Extensions.Configuration.Xml.Tests.csproj | 11 +- .../Microsoft.Extensions.Configuration.csproj | 6 +- .../Microsoft.Extensions.Configuration.csproj | 12 +- ...ions.Configuration.Functional.Tests.csproj | 11 +- ...soft.Extensions.Configuration.Tests.csproj | 6 +- ...ns.DependencyInjection.Abstractions.csproj | 2 +- ...ns.DependencyInjection.Abstractions.csproj | 9 +- ...soft.Extensions.DependencyInjection.csproj | 12 +- ...soft.Extensions.DependencyInjection.csproj | 57 +++---- ...yInjection.ExternalContainers.Tests.csproj | 23 ++- ...xtensions.DependencyInjection.Tests.csproj | 9 +- .../ServiceCollectionServiceExtensionsTest.cs | 5 +- ...icrosoft.Extensions.DependencyModel.csproj | 6 +- ...icrosoft.Extensions.DependencyModel.csproj | 16 +- .../tests/DependencyContextLoaderTests.cs | 2 +- ...ft.Extensions.DependencyModel.Tests.csproj | 12 +- .../NonEntryPointClass.cs | 12 ++ .../nonentrypointassembly.csproj | 8 + ...tensions.FileProviders.Abstractions.csproj | 4 +- ...tensions.FileProviders.Abstractions.csproj | 12 +- ....Extensions.FileProviders.Composite.csproj | 6 +- ....Extensions.FileProviders.Composite.csproj | 12 +- ...sions.FileProviders.Composite.Tests.csproj | 5 +- ...t.Extensions.FileProviders.Physical.csproj | 8 +- ...t.Extensions.FileProviders.Physical.csproj | 23 +-- ...nsions.FileProviders.Physical.Tests.csproj | 4 +- ...osoft.Extensions.FileSystemGlobbing.csproj | 2 +- ...osoft.Extensions.FileSystemGlobbing.csproj | 9 +- ...Extensions.FileSystemGlobbing.Tests.csproj | 6 +- .../BuildWebHostInvalidSignature.csproj | 2 +- .../BuildWebHostPatternTestSite.csproj | 2 +- .../CreateHostBuilderInvalidSignature.csproj | 2 +- .../CreateHostBuilderPatternTestSite.csproj | 2 +- ...reateWebHostBuilderInvalidSignature.csproj | 2 +- ...CreateWebHostBuilderPatternTestSite.csproj | 2 +- ...xtensions.HostFactoryResolver.Tests.csproj | 2 +- .../tests/MockHostTypes/MockHostTypes.csproj | 2 +- ...oft.Extensions.Hosting.Abstractions.csproj | 19 ++- ...oft.Extensions.Hosting.Abstractions.csproj | 26 ++- .../ref/Microsoft.Extensions.Hosting.csproj | 22 +-- .../src/Microsoft.Extensions.Hosting.csproj | 71 +++----- ...Extensions.Hosting.Functional.Tests.csproj | 6 +- ...icrosoft.Extensions.Hosting.TestApp.csproj | 9 +- .../tests/UnitTests/HostBuilderTests.cs | 4 +- ...osoft.Extensions.Hosting.Unit.Tests.csproj | 4 +- .../ref/Microsoft.Extensions.Http.csproj | 17 +- .../src/Microsoft.Extensions.Http.csproj | 18 +- .../Microsoft.Extensions.Http.Tests.csproj | 9 +- ...oft.Extensions.Logging.Abstractions.csproj | 2 +- ...oft.Extensions.Logging.Abstractions.csproj | 8 +- ...ft.Extensions.Logging.Configuration.csproj | 12 +- ...ft.Extensions.Logging.Configuration.csproj | 30 ++-- ...icrosoft.Extensions.Logging.Console.csproj | 13 +- ...icrosoft.Extensions.Logging.Console.csproj | 49 ++---- ...ft.Extensions.Logging.Console.Tests.csproj | 4 +- .../Microsoft.Extensions.Logging.Debug.csproj | 8 +- .../Microsoft.Extensions.Logging.Debug.csproj | 19 +-- ...crosoft.Extensions.Logging.EventLog.csproj | 10 +- ...crosoft.Extensions.Logging.EventLog.csproj | 32 ++-- ...soft.Extensions.Logging.EventSource.csproj | 8 +- ...soft.Extensions.Logging.EventSource.csproj | 38 ++--- ...xtensions.Logging.EventSource.Tests.csproj | 6 +- ...soft.Extensions.Logging.TraceSource.csproj | 8 +- ...soft.Extensions.Logging.TraceSource.csproj | 23 +-- .../ref/Microsoft.Extensions.Logging.csproj | 10 +- .../src/Microsoft.Extensions.Logging.csproj | 38 ++--- .../Microsoft.Extensions.Logging.Tests.csproj | 19 ++- .../Common/TraceSourceLoggerProviderTest.cs | 2 +- .../tests/Common/TraceSourceScopeTest.cs | 2 +- ...ft.Extensions.Logging.Testing.Tests.csproj | 7 +- ...ons.Options.ConfigurationExtensions.csproj | 14 +- ...ons.Options.ConfigurationExtensions.csproj | 24 +-- ....Extensions.Options.DataAnnotations.csproj | 8 +- ....Extensions.Options.DataAnnotations.csproj | 20 +-- .../ref/Microsoft.Extensions.Options.csproj | 14 +- .../src/Microsoft.Extensions.Options.csproj | 25 +-- .../Microsoft.Extensions.Options.Tests.csproj | 12 +- .../Microsoft.Extensions.Primitives.csproj | 9 +- .../Microsoft.Extensions.Primitives.csproj | 30 ++-- ...crosoft.Extensions.Primitives.Tests.csproj | 3 +- .../Microsoft.IO.Redist/Directory.Build.props | 1 - .../src/Microsoft.IO.Redist.csproj | 11 +- .../Directory.Build.props | 1 - .../src/Microsoft.VisualBasic.Core.vbproj | 2 +- .../Microsoft.VisualBasic.Core.Tests.csproj | 6 +- .../Directory.Build.props | 1 - ...rosoft.Win32.Registry.AccessControl.csproj | 6 +- ...rosoft.Win32.Registry.AccessControl.csproj | 17 +- ....Win32.Registry.AccessControl.Tests.csproj | 8 +- .../Directory.Build.props | 2 - .../ref/Microsoft.Win32.Registry.csproj | 5 +- .../src/Microsoft.Win32.Registry.csproj | 18 +- .../Microsoft.Win32.Registry.Tests.csproj | 5 +- .../ref/Microsoft.Win32.SystemEvents.csproj | 6 +- .../src/Microsoft.Win32.SystemEvents.csproj | 15 +- .../Microsoft.Win32.SystemEvents.Tests.csproj | 5 +- ...osoft.XmlSerializer.Generator.Tests.csproj | 6 +- src/libraries/Native/build-native.proj | 32 ++-- src/libraries/Native/native-binplace.proj | 7 +- src/libraries/NetCoreAppLibrary.props | 161 ++++++++++++++++++ .../System.AppContext/Directory.Build.props | 1 - .../src/System.AppContext.csproj | 1 - .../System.Buffers/Directory.Build.props | 1 - .../System.CodeDom/ref/System.CodeDom.csproj | 7 +- .../System.CodeDom/src/System.CodeDom.csproj | 7 +- .../tests/System.CodeDom.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Collections.Concurrent.csproj | 8 +- .../Directory.Build.props | 1 - .../ref/System.Collections.Immutable.cs | 4 +- .../ref/System.Collections.Immutable.csproj | 19 ++- .../src/System.Collections.Immutable.csproj | 29 ++-- .../System.Collections.Immutable.Tests.csproj | 10 +- .../Directory.Build.props | 1 - .../src/System.Collections.NonGeneric.csproj | 2 - .../Directory.Build.props | 1 - .../src/System.Collections.Specialized.csproj | 2 - .../System.Collections/Directory.Build.props | 1 - .../src/System.Collections.csproj | 1 - .../Directory.Build.props | 1 - ...em.ComponentModel.Annotations.Tests.csproj | 5 +- ...onentModel.Composition.Registration.csproj | 5 +- ...odel.Composition.Registration.Tests.csproj | 3 + .../System.ComponentModel.Composition.csproj | 2 +- .../System.ComponentModel.Composition.csproj | 6 +- ...nentModel.Composition.Noop.Assembly.csproj | 3 + ...em.ComponentModel.Composition.Tests.csproj | 16 +- .../Directory.Build.props | 1 - ...stem.ComponentModel.EventBasedAsync.csproj | 2 - .../Directory.Build.props | 1 - .../System.ComponentModel.Primitives.csproj | 2 - .../Directory.Build.props | 1 - ...System.ComponentModel.TypeConverter.csproj | 2 - .../Directory.Build.props | 1 - .../src/System.ComponentModel.csproj | 2 - .../System.Composition.AttributedModel.csproj | 7 +- ...em.Composition.AttributeModel.Tests.csproj | 8 +- .../src/System.Composition.Convention.csproj | 13 +- ...System.Composition.Convention.Tests.csproj | 7 +- .../src/System.Composition.Hosting.csproj | 12 +- .../System.Composition.Hosting.Tests.csproj | 8 +- .../src/System.Composition.Runtime.csproj | 9 +- .../System.Composition.Runtime.Tests.csproj | 8 +- .../src/System.Composition.TypedParts.csproj | 14 +- ...System.Composition.TypedParts.Tests.csproj | 10 +- ...ion.Demos.ExtendedCollectionImports.csproj | 6 +- .../tests/System.Composition.Tests.csproj | 7 +- .../tests/TestLibrary/TestLibrary.csproj | 5 +- ....Configuration.ConfigurationManager.csproj | 8 +- ....Configuration.ConfigurationManager.csproj | 12 +- ...guration.ConfigurationManager.Tests.csproj | 8 +- .../System/Configuration/TypeUtilTests.cs | 9 +- .../System.Console/Directory.Build.props | 1 - .../System.Data.Common/Directory.Build.props | 1 - .../src/System.Data.Common.csproj | 1 - .../tests/System.Data.Common.Tests.csproj | 1 + .../Directory.Build.props | 1 - .../src/System.Data.DataSetExtensions.csproj | 1 - .../ref/System.Data.Odbc.csproj | 7 +- .../src/System.Data.Odbc.csproj | 35 ++-- .../tests/OdbcParameterTests.cs | 1 - .../tests/System.Data.Odbc.Tests.csproj | 5 +- .../ref/System.Data.OleDb.csproj | 6 +- .../src/System.Data.OleDb.csproj | 19 +-- .../tests/System.Data.OleDb.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../src/System.Diagnostics.Contracts.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Diagnostics.Debug.csproj | 1 - .../System.Diagnostics.Debug.Tests.csproj | 13 +- .../Directory.Build.props | 1 - ...System.Diagnostics.DiagnosticSource.csproj | 18 +- ...System.Diagnostics.DiagnosticSource.csproj | 24 +-- ....Diagnostics.DiagnosticSource.Tests.csproj | 6 +- .../ref/System.Diagnostics.EventLog.csproj | 9 +- .../src/System.Diagnostics.EventLog.csproj | 19 +-- .../System.Diagnostics.EventLog.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../System.Diagnostics.FileVersionInfo.csproj | 4 +- ...ostics.FileVersionInfo.TestAssembly.csproj | 1 - ...stem.Diagnostics.PerformanceCounter.csproj | 7 +- ...stem.Diagnostics.PerformanceCounter.csproj | 21 +-- ...iagnostics.PerformanceCounter.Tests.csproj | 10 +- .../Directory.Build.props | 1 - .../src/System.Diagnostics.Process.csproj | 3 +- .../System.Diagnostics.Process.Tests.csproj | 6 +- .../Directory.Build.props | 1 - .../src/System.Diagnostics.StackTrace.csproj | 15 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Diagnostics.Tools.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Diagnostics.TraceSource.csproj | 18 +- .../Directory.Build.props | 1 - .../src/System.Diagnostics.Tracing.csproj | 1 - ...DirectoryServices.AccountManagement.csproj | 21 ++- ...oryServices.AccountManagement.Tests.csproj | 12 +- .../System.DirectoryServices.Protocols.csproj | 9 +- ...m.DirectoryServices.Protocols.Tests.csproj | 10 +- .../ref/System.DirectoryServices.csproj | 2 +- .../src/System.DirectoryServices.csproj | 14 +- .../System.DirectoryServices.Tests.csproj | 8 +- .../src/System.Drawing.Common.csproj | 5 +- .../tests/System.Drawing.Common.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../src/System.Drawing.Primitives.csproj | 20 +-- .../Directory.Build.props | 1 - .../src/System.Dynamic.Runtime.csproj | 2 - .../System.Formats.Asn1/Directory.Build.props | 1 - .../ref/System.Formats.Asn1.csproj | 4 +- .../src/System.Formats.Asn1.csproj | 11 +- .../tests/System.Formats.Asn1.Tests.csproj | 6 +- .../ref/System.Formats.Cbor.csproj | 4 +- .../tests/System.Formats.Cbor.Tests.csproj | 3 + .../Directory.Build.props | 1 - .../src/System.Globalization.Calendars.csproj | 1 - .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Globalization.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.IO.Compression.Brotli.csproj | 2 - .../Directory.Build.props | 1 - .../src/System.IO.Compression.ZipFile.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.IO.Compression.csproj | 2 - .../Directory.Build.props | 2 - .../System.IO.FileSystem.AccessControl.csproj | 6 +- .../System.IO.FileSystem.AccessControl.csproj | 30 ++-- ...m.IO.FileSystem.AccessControl.Tests.csproj | 11 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../System.IO.FileSystem.Primitives.csproj | 1 - .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.IO.FileSystem.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.IO.IsolatedStorage.csproj | 6 +- .../System.IO.IsolatedStorage.Tests.csproj | 3 + .../Directory.Build.props | 1 - .../src/System.IO.MemoryMappedFiles.csproj | 1 - .../ref/System.IO.Packaging.csproj | 13 +- .../src/System.IO.Packaging.csproj | 20 +-- .../tests/System.IO.Packaging.Tests.csproj | 6 +- .../ref/System.IO.Pipelines.csproj | 9 +- .../src/System.IO.Pipelines.csproj | 14 +- .../tests/System.IO.Pipelines.Tests.csproj | 14 +- .../Directory.Build.props | 2 - .../src/System.IO.Pipes.AccessControl.csproj | 23 +-- ...System.IO.Pipes.AccessControl.Tests.csproj | 3 + .../System.IO.Pipes/Directory.Build.props | 1 - .../src/System.IO.Pipes.csproj | 8 +- .../tests/System.IO.Pipes.Tests.csproj | 4 + .../ref/System.IO.Ports.csproj | 7 +- .../src/System.IO.Ports.csproj | 29 +--- .../tests/System.IO.Ports.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../System.IO.UnmanagedMemoryStream.csproj | 1 - src/libraries/System.IO/Directory.Build.props | 1 - src/libraries/System.IO/src/System.IO.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Linq.Expressions.csproj | 2 - .../System.Linq.Expressions.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Linq.Parallel.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Linq.Queryable.csproj | 2 - .../System.Linq/Directory.Build.props | 1 - .../System.Linq/src/System.Linq.csproj | 7 - .../src/System.Management.csproj | 8 +- .../tests/System.Management.Tests.csproj | 8 +- .../System.Memory/Directory.Build.props | 1 - .../tests/System.Memory.Tests.csproj | 1 - .../Directory.Build.props | 1 - .../ref/System.Net.Http.Json.csproj | 5 +- .../src/System.Net.Http.Json.csproj | 30 ++-- ...stem.Net.Http.Json.Functional.Tests.csproj | 6 +- .../System.Net.Http.Json.Unit.Tests.csproj | 7 +- .../ref/System.Net.Http.WinHttpHandler.csproj | 9 +- .../src/System.Net.Http.WinHttpHandler.csproj | 12 +- ...ttp.WinHttpHandler.Functional.Tests.csproj | 11 +- ....Net.Http.WinHttpHandler.Unit.Tests.csproj | 2 +- .../System.Net.Http/Directory.Build.props | 1 - .../src/System.Net.Http.csproj | 9 +- .../System.Net.Http.Functional.Tests.csproj | 7 +- .../System.Net.Http.Unit.Tests.csproj | 4 +- .../Directory.Build.props | 1 - .../src/System.Net.HttpListener.csproj | 5 +- .../System.Net.HttpListener.Tests.csproj | 3 - .../System.Net.Mail/Directory.Build.props | 1 - .../src/System.Net.Mail.csproj | 5 +- .../System.Net.Mail.Functional.Tests.csproj | 3 - .../Unit/System.Net.Mail.Unit.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../src/System.Net.NameResolution.csproj | 3 +- ...System.Net.NameResolution.Pal.Tests.csproj | 2 +- ...ystem.Net.NameResolution.Unit.Tests.csproj | 2 +- .../Directory.Build.props | 1 - .../src/System.Net.NetworkInformation.csproj | 4 +- .../System.Net.Ping/Directory.Build.props | 1 - .../src/System.Net.Ping.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Net.Primitives.csproj | 2 - ...tem.Net.Primitives.Functional.Tests.csproj | 3 - .../System.Net.Primitives.Pal.Tests.csproj | 2 +- ...stem.Net.Primitives.UnitTests.Tests.csproj | 2 +- .../System.Net.Requests/Directory.Build.props | 1 - .../src/System.Net.Requests.csproj | 4 +- .../System.Net.Security/Directory.Build.props | 1 - .../ref/System.Net.Security.csproj | 4 +- .../src/System.Net.Security.csproj | 5 +- .../System.Net.Security.Tests.csproj | 1 + .../System.Net.Security.Unit.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../System.Net.Sockets/Directory.Build.props | 1 - .../src/System.Net.Sockets.csproj | 3 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Net.WebHeaderCollection.csproj | 1 - .../System.Net.WebProxy/Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../System.Net.WebSockets.Client.Tests.csproj | 2 +- ...em.Net.WebSockets.WebSocketProtocol.csproj | 4 +- ...em.Net.WebSockets.WebSocketProtocol.csproj | 23 +-- ....WebSockets.WebSocketProtocol.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Net.WebSockets.csproj | 1 - .../ref/System.Numerics.Tensors.csproj | 14 +- .../src/System.Numerics.Tensors.csproj | 17 +- .../System.Numerics.Tensors.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../System.ObjectModel/Directory.Build.props | 1 - .../src/System.ObjectModel.csproj | 1 - .../Directory.Build.props | 2 - ...m.Private.DataContractSerialization.csproj | 2 - .../System.Private.Uri/Directory.Build.props | 1 - .../src/System.Private.Uri.csproj | 1 - .../Directory.Build.props | 2 - .../src/System.Private.Xml.Linq.csproj | 3 +- .../System.Private.Xml/Directory.Build.props | 2 - .../src/System.Private.Xml.csproj | 1 - .../System.Xml.RW.XmlWriterApi.Tests.csproj | 6 +- .../ref/System.Reflection.Context.csproj | 4 - .../src/System.Reflection.Context.csproj | 7 +- .../System.Reflection.Context.Tests.csproj | 3 + .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - ...System.Reflection.Emit.ILGeneration.csproj | 1 - .../Directory.Build.props | 1 - .../System.Reflection.Emit.Lightweight.csproj | 1 - .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Reflection.Extensions.csproj | 1 - .../Directory.Build.props | 1 - .../ref/System.Reflection.Metadata.csproj | 11 +- .../src/System.Reflection.Metadata.csproj | 17 +- .../System.Reflection.Metadata.Tests.csproj | 10 +- ...stem.Reflection.MetadataLoadContext.csproj | 2 +- ...stem.Reflection.MetadataLoadContext.csproj | 15 +- ...eflection.MetadataLoadContext.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Reflection.Primitives.csproj | 1 - .../Directory.Build.props | 1 - .../System.Reflection.TypeExtensions.csproj | 1 - .../System.Reflection/Directory.Build.props | 1 - .../src/System.Reflection.csproj | 1 - .../ref/System.Resources.Extensions.csproj | 4 +- .../src/System.Resources.Extensions.csproj | 11 +- .../System.Resources.Extensions.Tests.csproj | 11 +- .../Directory.Build.props | 1 - .../src/System.Resources.Reader.csproj | 1 - .../Directory.Build.props | 1 - .../System.Resources.ResourceManager.csproj | 1 - ...tem.Resources.ResourceManager.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Resources.Writer.csproj | 1 - .../src/System.Runtime.Caching.csproj | 5 +- .../tests/System.Runtime.Caching.Tests.csproj | 8 +- .../Directory.Build.props | 1 - ...tem.Runtime.CompilerServices.Unsafe.csproj | 8 +- ...tem.Runtime.CompilerServices.Unsafe.ilproj | 19 ++- ...ntime.CompilerServices.Unsafe.Tests.csproj | 5 +- .../Directory.Build.props | 1 - ...em.Runtime.CompilerServices.VisualC.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Runtime.Extensions.csproj | 8 +- .../Directory.Build.props | 1 - .../src/System.Runtime.Handles.csproj | 1 - .../Directory.Build.props | 1 - ....Runtime.InteropServices.JavaScript.csproj | 1 - ...me.InteropServices.JavaScript.Tests.csproj | 8 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Runtime.InteropServices.csproj | 2 - .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../src/System.Runtime.Loader.csproj | 1 - ...Runtime.Loader.DefaultContext.Tests.csproj | 9 +- ...ime.Loader.RefEmitLoadContext.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../src/System.Runtime.Numerics.csproj | 1 - .../Directory.Build.props | 1 - ...em.Runtime.Serialization.Formatters.csproj | 12 +- .../tests/FormatterServicesTests.Windows.cs | 1 + ...time.Serialization.Formatters.Tests.csproj | 34 +++- .../Directory.Build.props | 1 - .../System.Runtime.Serialization.Json.csproj | 3 - .../Directory.Build.props | 1 - ...em.Runtime.Serialization.Primitives.csproj | 2 - .../Directory.Build.props | 1 - .../System.Runtime.Serialization.Xml.csproj | 5 +- ....Serialization.Xml.Canonicalization.csproj | 4 + ...ialization.Xml.ReflectionOnly.Tests.csproj | 3 + ...tem.Runtime.Serialization.Xml.Tests.csproj | 3 + .../System.Runtime/Directory.Build.props | 1 - .../System.Runtime/src/System.Runtime.csproj | 5 +- .../tests/System.Runtime.Tests.csproj | 7 +- .../Directory.Build.props | 2 - .../ref/System.Security.AccessControl.csproj | 12 +- .../src/System.Security.AccessControl.csproj | 21 +-- ...System.Security.AccessControl.Tests.csproj | 6 +- .../Directory.Build.props | 1 - .../src/System.Security.Claims.csproj | 1 - .../Directory.Build.props | 1 - ...urity.Cryptography.Algorithms.Tests.csproj | 4 + .../Directory.Build.props | 2 - .../System.Security.Cryptography.Cng.csproj | 15 +- .../System.Security.Cryptography.Cng.csproj | 19 ++- ...tem.Security.Cryptography.Cng.Tests.csproj | 6 +- .../Directory.Build.props | 1 - .../System.Security.Cryptography.Csp.csproj | 1 - ...tem.Security.Cryptography.Csp.Tests.csproj | 3 + .../Directory.Build.props | 1 - ...stem.Security.Cryptography.Encoding.csproj | 1 - .../Directory.Build.props | 2 - ...ystem.Security.Cryptography.OpenSsl.csproj | 15 +- ...ystem.Security.Cryptography.OpenSsl.csproj | 15 +- ...Security.Cryptography.OpenSsl.Tests.csproj | 5 +- .../System.Security.Cryptography.Pkcs.csproj | 19 +-- .../System.Security.Cryptography.Pkcs.csproj | 83 ++++----- .../tests/EnvelopedCms/EdgeCasesTests.cs | 8 +- .../tests/EnvelopedCms/GeneralTests.cs | 4 +- .../SignedCms/SignedCmsWholeDocumentTests.cs | 4 +- ...em.Security.Cryptography.Pkcs.Tests.csproj | 9 +- .../Directory.Build.props | 1 - ...em.Security.Cryptography.Primitives.csproj | 1 - ...Security.Cryptography.ProtectedData.csproj | 4 +- ...Security.Cryptography.ProtectedData.csproj | 12 +- ...ty.Cryptography.ProtectedData.Tests.csproj | 8 +- .../Directory.Build.props | 1 - ...urity.Cryptography.X509Certificates.csproj | 4 +- ...Cryptography.X509Certificates.Tests.csproj | 2 + .../System.Security.Cryptography.Xml.csproj | 7 +- .../System.Security.Cryptography.Xml.csproj | 31 +--- ...tem.Security.Cryptography.Xml.Tests.csproj | 8 +- .../ref/System.Security.Permissions.csproj | 37 ++-- .../src/System.Security.Permissions.csproj | 22 +-- .../System.Security.Permissions.Tests.csproj | 5 +- .../Directory.Build.props | 2 - .../System.Security.Principal.Windows.csproj | 13 +- .../System.Security.Principal.Windows.csproj | 9 +- ...em.Security.Principal.Windows.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Security.Principal.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Security.SecureString.csproj | 2 - .../System.ServiceModel.Syndication.csproj | 25 ++- .../System.ServiceModel.Syndication.csproj | 15 +- ...stem.ServiceModel.Syndication.Tests.csproj | 8 +- ...em.ServiceProcess.ServiceController.csproj | 4 +- ...em.ServiceProcess.ServiceController.csproj | 23 +-- ...ocess.ServiceController.TestService.csproj | 5 +- ...viceProcess.ServiceController.Tests.csproj | 7 +- .../Directory.Build.props | 1 - .../ref/System.Text.Encoding.CodePages.csproj | 8 +- .../src/System.Text.Encoding.CodePages.csproj | 39 ++--- ...ystem.Text.Encoding.CodePages.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../System.Text.Encoding.Extensions.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Text.Encoding.csproj | 1 - .../Directory.Build.props | 1 - .../ref/System.Text.Encodings.Web.csproj | 19 +-- .../src/System.Text.Encodings.Web.csproj | 18 +- .../System.Text.Encodings.Web.Tests.csproj | 5 +- .../System.Text.Json/Directory.Build.props | 1 - .../System.Text.Json/ref/System.Text.Json.cs | 4 +- .../ref/System.Text.Json.csproj | 24 +-- .../src/System.Text.Json.csproj | 58 ++++--- .../tests/System.Text.Json.Tests.csproj | 9 +- .../Directory.Build.props | 1 - .../src/System.Text.RegularExpressions.csproj | 1 - ...ystem.Text.RegularExpressions.Tests.csproj | 2 +- .../ref/System.Threading.AccessControl.csproj | 7 +- .../src/System.Threading.AccessControl.csproj | 13 +- ...ystem.Threading.AccessControl.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../ref/System.Threading.Channels.csproj | 19 ++- .../src/System.Threading.Channels.csproj | 15 +- .../System.Threading.Channels.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../System.Threading.Tasks.Dataflow.csproj | 6 +- .../System.Threading.Tasks.Dataflow.csproj | 29 +--- ...stem.Threading.Tasks.Dataflow.Tests.csproj | 5 +- .../Directory.Build.props | 1 - .../Directory.Build.props | 1 - .../System.Threading.Tasks.Parallel.csproj | 2 - .../Directory.Build.props | 1 - .../src/System.Threading.Tasks.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Threading.Thread.csproj | 2 - .../Directory.Build.props | 1 - .../src/System.Threading.ThreadPool.csproj | 1 - .../Directory.Build.props | 1 - .../src/System.Threading.Timer.csproj | 1 - .../System.Threading/Directory.Build.props | 1 - .../src/System.Threading.csproj | 1 - .../Directory.Build.props | 1 - .../ref/System.Transactions.Local.csproj | 1 - .../src/System.Transactions.Local.csproj | 4 +- ...System.Utf8String.Experimental.Forwards.cs | 2 +- .../ref/System.Utf8String.Experimental.cs | 6 +- .../ref/System.Utf8String.Experimental.csproj | 26 +-- .../src/System.Utf8String.Experimental.csproj | 44 ++--- ...ystem.Utf8String.Experimental.Tests.csproj | 12 +- .../System.ValueTuple/Directory.Build.props | 1 - .../ref/System.ValueTuple.csproj | 4 +- .../src/System.ValueTuple.csproj | 2 +- .../Directory.Build.props | 1 - .../ref/System.Windows.Extensions.csproj | 14 +- .../src/System.Windows.Extensions.csproj | 6 +- .../System.Windows.Extensions.Tests.csproj | 2 + .../Directory.Build.props | 1 - .../src/System.Xml.ReaderWriter.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Xml.XDocument.csproj | 7 +- .../Directory.Build.props | 1 - .../src/System.Xml.XPath.XDocument.csproj | 6 +- .../System.Xml.XPath/Directory.Build.props | 1 - .../src/System.Xml.XPath.csproj | 5 +- .../Directory.Build.props | 1 - .../src/System.Xml.XmlDocument.csproj | 6 +- .../Directory.Build.props | 1 - .../src/System.Xml.XmlSerializer.csproj | 6 +- src/libraries/pkg/baseline/packageIndex.json | 1 + src/libraries/pkg/test/testPackages.proj | 3 - src/libraries/pretest.proj | 149 ++++++++-------- src/libraries/ref.proj | 75 +++++++- src/libraries/restore/Directory.Build.props | 3 +- src/libraries/restore/Directory.Build.targets | 2 - .../binplacePackages/binplacePackages.depproj | 53 ------ src/libraries/restore/depproj.proj | 28 --- .../netcoreapp/external.netcoreapp.depproj | 20 --- src/libraries/restore/netfx/netfx.depproj | 126 -------------- .../netstandard/external.netstandard.depproj | 128 -------------- .../runtime/referenceFromRuntime.targets | 13 -- src/libraries/restore/runtime/runtime.depproj | 34 ++-- src/libraries/sendtohelix.proj | 11 +- src/libraries/sendtohelixhelp.proj | 7 +- src/libraries/shims/ApiCompat.proj | 27 +-- src/libraries/shims/Directory.Build.props | 7 +- .../shims/generated/Directory.Build.props | 33 +++- .../shims/manual/Directory.Build.props | 6 +- src/libraries/shims/manual/System.Data.csproj | 5 +- src/libraries/src.proj | 47 ++--- src/mono/wasm/wasm.targets | 63 +++---- .../installer.tasks/installer.tasks.csproj | 2 +- 648 files changed, 2707 insertions(+), 3318 deletions(-) create mode 100644 eng/AvoidRestoreCycleOnSelfReference.targets delete mode 100644 eng/referenceFromRuntime.targets create mode 100644 eng/targetingpacks.targets create mode 100644 src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/NonEntryPointClass.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/nonentrypointassembly.csproj create mode 100644 src/libraries/NetCoreAppLibrary.props delete mode 100644 src/libraries/restore/binplacePackages/binplacePackages.depproj delete mode 100644 src/libraries/restore/depproj.proj delete mode 100644 src/libraries/restore/netcoreapp/external.netcoreapp.depproj delete mode 100644 src/libraries/restore/netfx/netfx.depproj delete mode 100644 src/libraries/restore/netstandard/external.netstandard.depproj delete mode 100644 src/libraries/restore/runtime/referenceFromRuntime.targets diff --git a/Build.proj b/Build.proj index dc4a15ab5f41..2041d3d4fcc1 100644 --- a/Build.proj +++ b/Build.proj @@ -1,5 +1,9 @@ + + BuildTargetFramework=$([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)')) + + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'installer.tasks')) $([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'netstandard2.0', 'installer.tasks.dll')) - $([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'net46', 'installer.tasks.dll')) + $([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'net461', 'installer.tasks.dll')) $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'docs')) $([MSBuild]::NormalizeDirectory('$(DocsDir)', 'manpages')) diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index 36a43555afff..60afda9ea793 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -7,8 +7,6 @@ once before you can iterate and work on a given library project. - Setup tools (currently done in restore in build.cmd/sh) - Restore external dependencies - CoreCLR - Copy to `bin\runtime\$(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)` - - Netstandard Library - Copy to `bin\ref\netstandard2.0` - - NetFx targeting pack - Copy to `bin\ref\net472` - Build targeting pack - Build src\libraries\ref.proj which builds all references assembly projects. For reference assembly project information see [ref](#ref) - Build product @@ -28,7 +26,7 @@ Below is a list of all the various options we pivot the project builds on: ## Individual build properties The following are the properties associated with each build pivot -- `$(BuildTargetFramework) -> netstandard2.1 | net5.0 | net472` +- `$(BuildTargetFramework) -> Any .NETCoreApp, .NETStandard or .NETFramework TFM, e.g. net5.0` - `$(TargetOS) -> Windows | Linux | OSX | FreeBSD | [defaults to running OS when empty]` - `$(Configuration) -> Release | [defaults to Debug when empty]` - `$(TargetArchitecture) - x86 | x64 | arm | arm64 | [defaults to x64 when empty]` @@ -60,23 +58,10 @@ Pure netstandard configuration: All supported targets with unique windows/unix build for netcoreapp: ``` - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;net461-Windows_NT ``` -### Placeholder Target Frameworks -Placeholder Target Framework can be added to the `` property to indicate the build system that the specific project is inbox in that framework and that Build Setting needs to be ignored. - -Placeholder target frameworks start with _ prefix. - -Example: -When we have a project that has a `netstandard2.0` target framework that means that this project is compatible with any build setting. So if we do a vertical build for `net472` this project will be built as part of the vertical because `net472` is compatible with `netstandard2.0`. This means that in the runtime and testhost binaries the netstandard2.0 implementation will be included, and we will test against those assets instead of testing against the framework inbox asset. In order to tell the build system to not include this project as part of the `net472` vertical we need to add a placeholder target framework: -``` - - netstandard2.0;_net472 - -``` - ## Options for building A full or individual project build is centered around BuildTargetFramework, TargetOS, Configuration and TargetArchitecture. @@ -94,7 +79,7 @@ When building an individual project the `BuildTargetFramework` and `TargetOS` wi ## Supported full build settings - .NET Core latest on current OS (default) -> `$(NetCoreAppCurrent)-[RunningOS]` -- .NET Framework latest -> `$(NetFrameworkCurrent)-Windows_NT` +- .NET Framework latest -> `net48-Windows_NT` # Library project guidelines diff --git a/docs/project/library-servicing.md b/docs/project/library-servicing.md index 29934d1606f1..3dc16895951d 100644 --- a/docs/project/library-servicing.md +++ b/docs/project/library-servicing.md @@ -4,7 +4,7 @@ This document provides the steps necessary after modifying a CoreFx library in a ## Check for existence of a .pkgproj -Most CoreFx libraries are not packaged by default. Some libraries have their output packaged in `Microsoft.Private.CoreFx.NetCoreApp`, which is always built, while other libraries have their own specific packages, which are only built on-demand. Your first step is to determine whether or not your library has its own package. To do this, go into the root folder for the library you've made changes to. If there is a `pkg` folder there (which should have a `.pkgproj` file inside of it), your library does have its own package. If there is no `pkg` folder there, the library should be built as part of `Microsoft.Private.CoreFx.NetCoreApp` and shipped as part of `Microsoft.NetCore.App`. To confirm this, check for the `IsNETCoreApp` property being set to `true` in the library's `Directory.Build.props` (or dir.props). If it is, then there is nothing that needs to be done. If it's not, contact a member of the servicing team for guidance, as this situation goes against our convention. +Most libraries are not packaged by default. Some libraries have their output packaged in `Microsoft.Private.CoreFx.NetCoreApp`, which is always built, while other libraries have their own specific packages, which are only built on-demand. Your first step is to determine whether or not your library has its own package. To do this, go into the root folder for the library you've made changes to. If there is a `pkg` folder there (which should have a `.pkgproj` file inside of it), your library does have its own package. If there is no `pkg` folder there, the library should be built as part of `Microsoft.Private.CoreFx.NetCoreApp` and shipped as part of `Microsoft.NetCore.App`. To confirm this, check if the library is listed in NetCoreAppLibrary.props. If it is, then there is nothing that needs to be done. If it's not, contact a member of the servicing team for guidance, as this situation goes against our convention. For example, if you made changes to [System.Data.SqlClient](https://github.com/dotnet/runtime/tree/master/src/libraries/Microsoft.Win32.Registry), then you have a .pkgproj, and will have to follow the steps in this document. However, if you made changes to [System.Collections](https://github.com/dotnet/runtime/tree/master/src/libraries/System.Collections), then you don't have a .pkgproj, and you do not need to do any further work for servicing. diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md index 44eb0eb209ee..7f8c12b108e1 100644 --- a/docs/workflow/building/libraries/README.md +++ b/docs/workflow/building/libraries/README.md @@ -74,7 +74,7 @@ The libraries build has two logical components, the native build which produces The build settings (BuildTargetFramework, TargetOS, Configuration, Architecture) are generally defaulted based on where you are building (i.e. which OS or which architecture) but we have a few shortcuts for the individual properties that can be passed to the build scripts: -- `-framework|-f` identifies the target framework for the build. Possible values include `net5.0` (currently the latest .NET version) or `net472`. (msbuild property `BuildTargetFramework`) +- `-framework|-f` identifies the target framework for the build. Possible values include `net5.0` (currently the latest .NET version) or `net48` (the latest .NETFramework version). (msbuild property `BuildTargetFramework`) - `-os` identifies the OS for the build. It defaults to the OS you are running on but possible values include `Windows_NT`, `Unix`, `Linux`, or `OSX`. (msbuild property `TargetOS`) - `-configuration|-c Debug|Release` controls the optimization level the compilers use for the build. It defaults to `Debug`. (msbuild property `Configuration`) - `-arch` identifies the architecture for the build. It defaults to `x64` but possible values include `x64`, `x86`, `arm`, or `arm64`. (msbuild property `TargetArchitecture`) diff --git a/eng/AvoidRestoreCycleOnSelfReference.targets b/eng/AvoidRestoreCycleOnSelfReference.targets new file mode 100644 index 000000000000..cb665cb070d9 --- /dev/null +++ b/eng/AvoidRestoreCycleOnSelfReference.targets @@ -0,0 +1,14 @@ + + + + <_PackageIdTemp>$(PackageId) + $(PackageId)_temp + + + + + $(_PackageIdTemp) + + + \ No newline at end of file diff --git a/eng/BeforeTargetFrameworkInference.targets b/eng/BeforeTargetFrameworkInference.targets index 92adb5df6353..abef4c8981a2 100644 --- a/eng/BeforeTargetFrameworkInference.targets +++ b/eng/BeforeTargetFrameworkInference.targets @@ -6,10 +6,6 @@ $(TargetFramework.SubString(0, $(TargetFramework.IndexOf('-')))) - - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(TargetFramework)')) - - diff --git a/eng/Configurations.props b/eng/Configurations.props index aa8e9add17dd..59424f7cc30a 100644 --- a/eng/Configurations.props +++ b/eng/Configurations.props @@ -29,8 +29,6 @@ $(NetCoreAppCurrent) Microsoft.NETCore.App .NET $(NetCoreAppCurrentVersion) - - net472 WINDOWS7.0 diff --git a/eng/Subsets.props b/eng/Subsets.props index 958389db150f..ba103417c838 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -59,7 +59,7 @@ mono.llvm+ $(DefaultMonoSubsets)mono.runtime+mono.corelib - libs.depprojs+libs.native+libs.ref+libs.src+libs.pretest+libs.packages + libs.native+libs.ref+libs.src+libs.pretest+libs.packages corehost+installer.managed+installer.depprojs+installer.pkgprojs+bundles+installers+installer.tests installer.pkgprojs @@ -95,7 +95,6 @@ - @@ -177,12 +176,6 @@ - - - Configuration=$(LibrariesConfiguration) - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2940b3c13c76..cf9414cfae45 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -46,7 +46,7 @@ https://github.com/dotnet/arcade ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 - + https://github.com/dotnet/arcade ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 diff --git a/eng/Versions.props b/eng/Versions.props index c06cc9058abc..4d00ac9bfe4e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -18,6 +18,7 @@ true true false + true dotnet $(ContainerName) @@ -56,10 +57,10 @@ 5.0.0-beta.20364.3 5.0.0-beta.20364.3 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 + 5.0.0-beta.20367.6 2.5.1-beta.20364.3 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 + 5.0.0-beta.20367.6 5.0.0-beta.20364.3 5.0.0-preview.4.20202.18 @@ -69,7 +70,36 @@ 5.0.0-preview.8.20359.4 + 4.5.1 + 4.3.0 + 4.3.0 + 4.7.0 + 4.8.1 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.5.4 + 4.3.4 + 4.3.1 + 4.5.0 + 4.3.0 + 4.3.1 + 4.3.1 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.1 + 4.7.0 + 4.7.0 + 4.7.0 5.0.0-preview.4.20202.18 + 4.3.0 + 4.5.4 + 4.5.0 + 1.1.1 + 4.3.0 5.0.0-alpha.1.19563.3 5.0.0-beta.20364.1 @@ -82,6 +112,7 @@ 5.0.0-beta.20364.1 2.2.0-prerelease.19564.1 + 2.0.3 99.99.99-master-20200228.3 99.99.99-master-20200228.3 @@ -101,8 +132,6 @@ $(RefOnlyMicrosoftBuildVersion) 4.9.4 4.9.4 - - 4.8.0 16.8.0-preview-20200716-03 1.0.0-prerelease.20352.3 diff --git a/eng/build.ps1 b/eng/build.ps1 index f8b205bd3930..016ed15d2035 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -65,7 +65,7 @@ function Get-Help() { Write-Host "Libraries settings:" Write-Host " -allconfigurations Build packages for all build configurations." Write-Host " -coverage Collect code coverage when testing." - Write-Host " -framework (-f) Build framework: net5.0 or net472." + Write-Host " -framework (-f) Build framework: net5.0 or net48." Write-Host " [Default: net5.0]" Write-Host " -testnobuild Skip building tests when invoking -test." Write-Host " -testscope Scope tests, allowed values: innerloop, outerloop, all." diff --git a/eng/build.sh b/eng/build.sh index eb0cb586ebf3..da8e3770f595 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -60,7 +60,7 @@ usage() echo "Libraries settings:" echo " --allconfigurations Build packages for all build configurations." echo " --coverage Collect code coverage when testing." - echo " --framework (-f) Build framework: net5.0 or net472." + echo " --framework (-f) Build framework: net5.0 or net48." echo " [Default: net5.0]" echo " --testnobuild Skip building tests when invoking -test." echo " --testscope Test scope, allowed values: innerloop, outerloop, all." diff --git a/eng/illink.targets b/eng/illink.targets index 601b0b798fbc..79eb5d409643 100644 --- a/eng/illink.targets +++ b/eng/illink.targets @@ -27,7 +27,7 @@ $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NET_ILLink_Tasks)', 'tools')) $(ILLinkTasksDir)netcoreapp3.0/ILLink.Tasks.dll - $(ILLinkTasksDir)$(NetFrameworkCurrent)/ILLink.Tasks.dll + $(ILLinkTasksDir)net472/ILLink.Tasks.dll $(IntermediateOutputPath)$(TargetName)$(TargetExt) $(IntermediateOutputPath)$(TargetName).pdb $(IntermediateOutputPath)PreTrim/ diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index 4284a79368f9..d0cc3cee0a52 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -91,10 +91,12 @@ jobs: displayName: Create Core_Root condition: and(succeeded(), ne(variables.runtimeFlavorName, 'Mono')) - - script: "build.cmd -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)\\bin\\mono\\$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\.dotnet-mono /E /I /Y;copy $(Build.SourcesDirectory)\\artifacts\\bin\\coreclr\\$(osGroup).$(archType).$(buildConfigUpper)\\corerun.exe $(Build.SourcesDirectory)\\.dotnet-mono\\shared\\Microsoft.NETCore.App\\5.0.0\\corerun.exe" + # Copy the runtime directory into the testhost folder to include OOBs. + + - script: "build.cmd -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)\\bin\\mono\\$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\runtime\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\shared\\Microsoft.NETCore.App\\5.0.0 /E /I /Y;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\.dotnet-mono /E /I /Y;copy $(Build.SourcesDirectory)\\artifacts\\bin\\coreclr\\$(osGroup).$(archType).$(buildConfigUpper)\\corerun.exe $(Build.SourcesDirectory)\\.dotnet-mono\\shared\\Microsoft.NETCore.App\\5.0.0\\corerun.exe" displayName: "Create mono dotnet (Windows)" condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), eq(variables.osGroup, 'Windows_NT')) - - script: "mkdir $(Build.SourcesDirectory)/.dotnet-mono;./build.sh -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;cp $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/.dotnet-mono -r;cp $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)/corerun $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun" + - script: "mkdir $(Build.SourcesDirectory)/.dotnet-mono;./build.sh -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;cp $(Build.SourcesDirectory)/artifacts/bin/runtime/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/shared/Microsoft.NETCore.App/5.0.0 -rf;cp $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/.dotnet-mono -r;cp $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)/corerun $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun" displayName: "Create mono dotnet (Linux)" condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), ne(variables.osGroup, 'Windows_NT')) diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index bf5a9a2321fd..2ae778e89393 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -4,7 +4,7 @@ parameters: archType: '' osSubgroup: '' crossrootfsDir: '' - framework: '' + framework: 'net5.0' isOfficialAllConfigurations: false isSourceBuild: false liveRuntimeBuildConfig: '' @@ -25,10 +25,10 @@ parameters: jobs: - template: /eng/common/templates/job/job.yml parameters: - ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: + ${{ if notIn(parameters.framework, 'allConfigurations', 'net48') }}: displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if in(parameters.framework, 'allConfigurations', 'net472') }}: + ${{ if in(parameters.framework, 'allConfigurations', 'net48') }}: displayName: ${{ format('Libraries {0} {1} {2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.framework, parameters.archType, parameters.buildConfig) }} name: ${{ format('libraries_{0}_{1}_{2}{3}_{4}_{5}', parameters.name, parameters.framework, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index f4b02cf06215..4854b682716a 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -4,7 +4,7 @@ parameters: osSubgroup: '' archType: '' crossrootfsDir: '' - framework: '' + framework: 'net5.0' isOfficialBuild: false isOfficialAllConfigurations: false runtimeVariant: '' @@ -65,7 +65,7 @@ jobs: - ${{ if eq(parameters.osGroup, 'Browser') }}: - EMSDK_PATH: /usr/local/emscripten - # Tests only run for 'allConfiguration' and 'net472' build-jobs + # Tests only run for 'allConfiguration' and 'net48' build-jobs # If platform is in testBuildPlatforms we build tests as well. - ${{ if or(eq(parameters.runTests, true), containsValue(parameters.testBuildPlatforms, parameters.platform)) }}: - _subset: libs+libs.tests diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 58d1f89fe3c0..33d0ea5aa9db 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -88,7 +88,7 @@ jobs: # Windows_NT x64 - ${{ if eq(parameters.platform, 'Windows_NT_x64') }}: # netcoreapp - - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net472') }}: + - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net48') }}: - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - Windows.81.Amd64.Open - Windows.10.Amd64.ServerRS5.Open @@ -101,8 +101,8 @@ jobs: - ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}: - (Windows.Nano.1809.Amd64.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504 - # NET472 - - ${{ if eq(parameters.jobParameters.framework, 'net472') }}: + # .NETFramework + - ${{ if eq(parameters.jobParameters.framework, 'net48') }}: - Windows.10.Amd64.Client19H1.Open # AllConfigurations @@ -112,7 +112,7 @@ jobs: # Windows_NT x86 - ${{ if eq(parameters.platform, 'Windows_NT_x86') }}: # netcoreapp - - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net472') }}: + - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net48') }}: - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - Windows.7.Amd64.Open - Windows.10.Amd64.ServerRS5.Open @@ -124,8 +124,8 @@ jobs: - Windows.7.Amd64.Open - Windows.10.Amd64.Server19H1.Open - # NET472 - - ${{ if eq(parameters.jobParameters.framework, 'net472') }}: + # .NETFramework + - ${{ if eq(parameters.jobParameters.framework, 'net48') }}: - Windows.10.Amd64.Client19H1.Open # Windows_NT arm diff --git a/eng/pipelines/libraries/outerloop.yml b/eng/pipelines/libraries/outerloop.yml index 9afbf206e5f3..d88481ea37dd 100644 --- a/eng/pipelines/libraries/outerloop.yml +++ b/eng/pipelines/libraries/outerloop.yml @@ -99,6 +99,6 @@ jobs: jobParameters: isOfficialBuild: ${{ variables['isOfficialBuild'] }} isFullMatrix: ${{ variables['isFullMatrix'] }} - framework: net472 + framework: net48 runTests: true testScope: outerloop \ No newline at end of file diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml index 6c5e397d4dd0..faa5ab29e300 100644 --- a/eng/pipelines/libraries/run-test-job.yml +++ b/eng/pipelines/libraries/run-test-job.yml @@ -3,7 +3,7 @@ parameters: osGroup: '' osSubgroup: '' archType: '' - framework: '' + framework: 'net5.0' isOfficialBuild: false liveRuntimeBuildConfig: '' runtimeFlavor: 'coreclr' @@ -55,7 +55,7 @@ jobs: - ${{ if ne(parameters.dependsOn[0], '') }}: - ${{ parameters.dependsOn }} - ${{ if eq(parameters.dependsOn[0], '') }}: - - ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: + - ${{ if notIn(parameters.framework, 'allConfigurations', 'net48') }}: - ${{ 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)) }}: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 831fa959900c..17afa74cdb36 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -576,7 +576,7 @@ jobs: helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml jobParameters: isFullMatrix: ${{ variables.isFullMatrix }} - framework: net472 + framework: net48 runTests: true testScope: innerloop condition: >- diff --git a/eng/referenceAssemblies.props b/eng/referenceAssemblies.props index a5e0e553f12f..94508fa244ad 100644 --- a/eng/referenceAssemblies.props +++ b/eng/referenceAssemblies.props @@ -1,9 +1,9 @@ - $(AdditionalBuildTargetFrameworks);netstandard2.0 - $(AdditionalBuildTargetFrameworks);netstandard2.1 + !$(BuildTargetFramework.StartsWith('netstandard')) and + !$(BuildTargetFramework.StartsWith('net4'))"> + $(AdditionalBuildTargetFrameworks);netstandard2.0 + $(AdditionalBuildTargetFrameworks);netstandard2.1 diff --git a/eng/referenceFromRuntime.targets b/eng/referenceFromRuntime.targets deleted file mode 100644 index 34d0eb49199c..000000000000 --- a/eng/referenceFromRuntime.targets +++ /dev/null @@ -1,124 +0,0 @@ - - - - AddRuntimeProjectReference; - $(PrepareProjectReferencesDependsOn); - - - AddRuntimeProjectReference; - $(ResolveReferencesDependsOn); - - - AddRuntimeProjectReference; - $(CleanDependsOn) - - - - - $([MSBuild]::NormalizePath('$(LibrariesProjectRoot)', 'restore', 'runtime', 'runtime.depproj')) - - - - - - - - false - _referencePathFromRestoredRuntime - - - - - - - - - - - - - - - - - - - - - - - - - <_referencePathFromRuntime Include="@(RuntimeFiles)" Private="false" /> - <_referencePathFromRuntime Include="@(_referencePathFromRestoredRuntime)" Private="false" /> - - <_referencePathFromRuntime Include="@(ReferenceFromRuntime->'$(RuntimePath)%(Identity).dll')" Condition="'$(IsTestProject)' == 'true' or '$(IsTestSupportProject)' == 'true'" /> - - <_referencePathFromRuntimeByFileName Include="@(_referencePathFromRuntime->'%(FileName)')" Condition="'%(_referencePathFromRuntime.Extension)' == '.dll'" > - %(Identity) - - - - - - - - - - - <_filteredReferencePathFromRuntimeByFileName Include="@(_referencePathFromRuntimeByFileNameFiltered)" - Condition="'@(_referencePathFromRuntimeByFileNameFiltered)' == '@(ReferenceFromRuntime)' and '%(Identity)' != ''"> - @(ReferenceFromRuntime->'%(Aliases)') - - - <_remainingReferenceFromRuntime Include="@(ReferenceFromRuntime)" Exclude="@(_filteredReferencePathFromRuntimeByFileName)" /> - - - <_remainingReferenceFromRuntimeWithNI Include="@(_remainingReferenceFromRuntime->'%(Identity).ni')"> - %(Identity) - - - <_filteredReferencePathFromRuntimeByFileName Include="@(_referencePathFromRuntimeByFileNameFiltered)" - Condition="'@(_referencePathFromRuntimeByFileNameFiltered)' == '@(_remainingReferenceFromRuntimeWithNI)' and '%(Identity)' != ''"> - @(_remainingReferenceFromRuntimeWithNI->'%(Aliases)') - - - <_missingReferenceFromRuntime Include="@(_remainingReferenceFromRuntimeWithNI)" Exclude="@(_filteredReferencePathFromRuntimeByFileName)" /> - - - - - - - - <_aliasedReferencePathFromRuntime Include="@(_filteredReferencePathFromRuntimeByFileName->'%(ReferencePath)')" Condition="'%(_filteredReferencePathFromRuntimeByFileName.Aliases)' != ''" /> - - - - - - - - - - - - - - diff --git a/eng/references.targets b/eng/references.targets index efcac7d05152..0f3ea17b4a4f 100644 --- a/eng/references.targets +++ b/eng/references.targets @@ -1,67 +1,56 @@ - $(RefPath) - $(RefPath) - $(AssemblySearchPaths);$(RefPath);{RawFileName} <_FindDependencies>false - - <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory) - <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory) - - - true - true - - - - - - - - - - - - - - false - - - + + + + - - - + + + + - - - + + + + false + + - - %(DefaultReferenceDirs.Identity) - - <_defaultReferenceExclusionsFullPath Include="%(DefaultReferenceExclusions.RefDir)%(DefaultReferenceExclusions.Identity).dll" /> - - - + + + + <_transitiveProjectReferenceWithExclusion Include="@(ProjectReference)"> + %(DefaultReferenceExclusion.Identity) + + - + + - + - - \ No newline at end of file + diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 2f59f5d9a517..6f4bb0e253ee 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -1,8 +1,18 @@ + + $(MicrosoftNetCoreAppRefPackRefDir) + + $(ContractDependencyPaths);@(ReferencePath->'%(RelativeDir)'->Distinct()) + + - $(LibrariesProjectRoot)$(MSBuildProjectName)/ref/$(MSBuildProjectName).csproj + $(LibrariesProjectRoot)$(MSBuildProjectName)\ref\$(MSBuildProjectName).csproj true - $(RefPath)/$(MSBuildProjectName).dll + $(NetCoreAppCurrentRefPath)$(TargetFileName) + $([MSBuild]::NormalizePath('$(BaseOutputPath)', 'ref', '$(TargetFramework)-$(Configuration)', '$(TargetFileName)')) false @@ -10,8 +20,43 @@ + + + false + ResolvedMatchingContract + + + + + + + + + + + + + false + + + + <_resolvedP2PFiltered Include="@(ProjectReference)"> + $([System.IO.Path]::GetFullPath('%(ProjectReference.Identity)')) + %(ProjectReference.SkipUseReferenceAssembly) + + <_ResolvedProjectReferencePaths Update="@(_resolvedProjectReferenceFiltred)" + Condition="'%(_resolvedP2PFiltered.ProjectReferenceItemSpec)' == '%(_resolvedP2PFiltered.MSBuildSourceProjectFile)' and + '%(_resolvedP2PFiltered.SkipUseReferenceAssembly)' == 'true'" + ReferenceAssembly="" /> + + \ No newline at end of file diff --git a/eng/restore/repoRestore.props b/eng/restore/repoRestore.props index 300c542e8cbe..d2ca92d6db01 100644 --- a/eng/restore/repoRestore.props +++ b/eng/restore/repoRestore.props @@ -1,5 +1,6 @@ + $(RepoRoot)artifacts\toolset\Common\ false unused diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets new file mode 100644 index 000000000000..e39ce8fdada6 --- /dev/null +++ b/eng/targetingpacks.targets @@ -0,0 +1,106 @@ + + + <_UseLocalTargetingRuntimePack>true + false + + + + + + + $(PkgMicrosoft_NETCore_App)\ref\$(_ShortFrameworkIdentifier)$(_ShortFrameworkVersion)\ + + + + + + + + + + + false + + + + + + + %(ResolvedFrameworkReference.TargetingPackPath)\ref\$(_ShortFrameworkIdentifier)$(_ShortFrameworkVersion)\ + + + + + + + + + + $(AssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\')) + $(DesignTimeAssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\')) + + + + + + + + + + + + + + + + + + + + + + + <_targetingPackReferenceExclusion Include="$(TargetName)" /> + <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->'%(Filename)')" /> + <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" /> + + + + <_targetingPackReferenceWithExclusion Include="@(Reference)"> + %(_targetingPackReferenceExclusion.Identity) + + + + + \ No newline at end of file diff --git a/eng/testing/.runsettings b/eng/testing/.runsettings index fabc0310a7aa..cf00c4a46737 100644 --- a/eng/testing/.runsettings +++ b/eng/testing/.runsettings @@ -18,10 +18,6 @@ $$TESTCASEFILTER$$ $$DOTNETHOSTPATH$$ - - - $$DEVPATH$$ - diff --git a/eng/testing/RunnerTemplate.cmd b/eng/testing/RunnerTemplate.cmd index fe28e9157a6e..10737eabe709 100644 --- a/eng/testing/RunnerTemplate.cmd +++ b/eng/testing/RunnerTemplate.cmd @@ -41,12 +41,6 @@ set EXECUTION_DIR=%~dp0 :argparser_end -if not defined RUNTIME_PATH ( - echo error: -r^|--runtime-path argument is required. - call :usage - exit /b -1 -) - :: Don't use a globally installed SDK. set DOTNET_MULTILEVEL_LOOKUP=0 diff --git a/eng/testing/netfx.exe.config b/eng/testing/netfx.exe.config index ed7d7d082438..e131497fc761 100644 --- a/eng/testing/netfx.exe.config +++ b/eng/testing/netfx.exe.config @@ -1,7 +1,6 @@ - \ No newline at end of file diff --git a/eng/testing/outerBuild.targets b/eng/testing/outerBuild.targets index 4623b0e54d25..c071944c21d9 100644 --- a/eng/testing/outerBuild.targets +++ b/eng/testing/outerBuild.targets @@ -1,8 +1,12 @@ + Targets="Test"> + + + + \ No newline at end of file diff --git a/eng/testing/runsettings.targets b/eng/testing/runsettings.targets index 10496127b8a9..5a2c9a84d689 100644 --- a/eng/testing/runsettings.targets +++ b/eng/testing/runsettings.targets @@ -36,7 +36,6 @@ .Replace('$$DISABLEPARALLELIZATION$$', '$([MSBuild]::ValueOrDefault('$(TestDisableParallelization)', 'false'))') .Replace('$$DISABLEAPPDOMAIN$$', '$([MSBuild]::ValueOrDefault('$(TestDisableAppDomain)', 'false'))') .Replace('$$TESTCASEFILTER$$', '$(_testFilter)') - .Replace('$$DEVPATH$$', '$(TestHostRootPath)') .Replace('$$DOTNETHOSTPATH$$', '$(TestHostRootPath)$([System.IO.Path]::GetFileName('$(DotNetTool)'))')) diff --git a/eng/testing/runtimeConfiguration.targets b/eng/testing/runtimeConfiguration.targets index f687adfad40f..d69182992c7b 100644 --- a/eng/testing/runtimeConfiguration.targets +++ b/eng/testing/runtimeConfiguration.targets @@ -1,45 +1,31 @@ - - $(MSBuildThisFileDirectory)netfx.exe.config - - true + true + true + true + $(MSBuildThisFileDirectory)netfx.exe.config + + $(TargetPath).config - - + - - - - - - - \ No newline at end of file diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 5622b19e249b..dc7dd97397e5 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -183,21 +183,8 @@ - - - - - - - - - - - - + DependsOnTargets="Publish;BundleTestAppleApp;BundleTestAndroidApp;BundleTestWasmApp;ArchiveTests" /> diff --git a/eng/testing/tests.props b/eng/testing/tests.props index bf2f93fcceb3..65664f7f7499 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -29,8 +29,6 @@ $(PackageRID) true - false - diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 757ff0163600..2fe669a10ba0 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -19,11 +19,6 @@ $(RunScriptHostDir)dotnet - - - - - PrepareForRun @@ -96,7 +91,10 @@ - "$(RunScriptOutputPath)" --runtime-path "$(TestHostRootPath.TrimEnd('\/'))" + "$(RunScriptOutputPath)" + + $(RunTestsCommand) --runtime-path "$(TestHostRootPath.TrimEnd('\/'))" $(RunTestsCommand) --rsp-file "$(TestRspFile)" "$(RunScriptOutputPath)" $(AssemblyName) $(TargetArchitecture) "$(RunScriptOutputPath)" $(JSEngine) $(AssemblyName).dll $(_withoutCategories.Replace(';', ' -notrait category=')) diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index 6364d461124c..5b71327e9645 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -43,19 +43,17 @@ - - <_testRunnerConfigSourceFile Include="$(TargetDir)$(TargetName).exe.config" /> <_testRunnerConfigDestFile Include="$(TargetDir)xunit.console.exe.config" /> - - diff --git a/eng/testing/xunit/xunit.targets b/eng/testing/xunit/xunit.targets index b14d3b7cbf22..feb429aab6bf 100644 --- a/eng/testing/xunit/xunit.targets +++ b/eng/testing/xunit/xunit.targets @@ -1,4 +1,11 @@ + + + + + $(OutDir) diff --git a/global.json b/global.json index 64916dd7429c..1c3df45ddb57 100644 --- a/global.json +++ b/global.json @@ -12,7 +12,7 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20364.3", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20372.2", "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20364.3", "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20364.3", "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20364.3", diff --git a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets index 18a6d21e57dc..bbed0d419853 100644 --- a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets +++ b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets @@ -12,7 +12,7 @@ <_RexcepFilePath Condition=" '$(_RexcepFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\rexcep.h <_ILLinkDescriptorsIntermediatePath>$(IntermediateOutputPath)ILLink.Descriptors.Combined.xml <_ILLinkTasksToolsDir>$(PkgMicrosoft_NET_ILLink_Tasks)/tools - <_ILLinkTasksDir>$(_ILLinkTasksToolsDir)/$(NetFrameworkCurrent)/ + <_ILLinkTasksDir>$(_ILLinkTasksToolsDir)/net472/ <_ILLinkTasksDir Condition="'$(MSBuildRuntimeType)' == 'Core'">$(_ILLinkTasksToolsDir)/netcoreapp3.0/ <_ILLinkTasksPath>$(_ILLinkTasksDir)ILLink.Tasks.dll diff --git a/src/libraries/Common/src/System/HexConverter.cs b/src/libraries/Common/src/System/HexConverter.cs index df2e4417b40c..d0cd3f074dc0 100644 --- a/src/libraries/Common/src/System/HexConverter.cs +++ b/src/libraries/Common/src/System/HexConverter.cs @@ -98,7 +98,7 @@ public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Cas #endif public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) { -#if NET45 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NETSTANDARD1_0 || NETSTANDARD1_3 || NETSTANDARD2_0 +#if NETFRAMEWORK || NETSTANDARD1_0 || NETSTANDARD1_3 || NETSTANDARD2_0 Span result = stackalloc char[0]; if (bytes.Length > 16) { diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs index da0f988066e4..c66728c0ac96 100644 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs +++ b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs @@ -36,7 +36,7 @@ public void ThisTestMustRunOnCoreCLR() { Asserter.TestRan = true; } -#elif NET472 +#elif NETFRAMEWORK [ConditionalFact] [FrameworkSkipCondition(RuntimeFrameworks.CoreCLR)] public void ThisTestMustRunOnCLR() diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs index a5fbb8ecc317..b55264f85da2 100644 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs +++ b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs @@ -89,7 +89,7 @@ public void ThisTestMustRunOnCoreCLR(int value) { Asserter.TestRan = true; } -#elif NET472 +#elif NETFRAMEWORK [ConditionalTheory] [FrameworkSkipCondition(RuntimeFrameworks.CoreCLR)] [MemberData(nameof(GetInts))] diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index cc22d6724e6a..8b6dd4699023 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -5,7 +5,7 @@ This assembly is referenced from rid agnostic configurations therefore we can't make it RID specific and instead use runtime checks. --> - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -63,4 +63,13 @@ + + + + + + + + + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 834d3a24ce7c..57898d4ff67e 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -3,6 +3,7 @@ true + true @@ -10,14 +11,11 @@ $(RepositoryEngineeringDir)BeforeTargetFrameworkInference.targets - $(RepoRoot)artifacts\toolset\Common\ $([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectDirectory), 'src%24')) true $(RepositoryEngineeringDir)depProj.common.targets $(LibrariesProjectRoot)OSGroups.json - $(NetCoreAppCurrent) false - $(AdditionalBuildTargetFrameworks);$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-NetBSD;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris $(RepositoryEngineeringDir)LicenseHeader.txt @@ -40,10 +38,13 @@ the build system to use browser/ios/android as the RuntimeOS for produced package RIDs. --> $(TargetOS.ToLowerInvariant()) - - Debug - $(TargetFramework) - $(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture) + + Debug + $(TargetFramework) + + net45;net451;net452;net46;net461;net462;net47;net471;net472 + $(AdditionalBuildTargetFrameworks);netstandard2.0 + $(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture) @@ -142,11 +143,10 @@ $(RuntimeOS)-$(TargetArchitecture) - - true - true - true + true + true - true - true - false - false true - - true false @@ -238,14 +232,7 @@ true - - - $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'Common')) - $([MSBuild]::NormalizeDirectory('$(CommonPathRoot)', 'src')) - $([MSBuild]::NormalizeDirectory('$(CommonPathRoot)', 'tests')) - - - + false - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'runtime', '$(BuildSettings)')) - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(BuildTargetFramework)')) - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', 'netstandard2.0')) - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', 'netstandard2.1')) - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(NetFrameworkCurrent)')) + $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'runtime', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)')) $([MSBuild]::NormalizePath('$(CoreClrProjectRoot)', 'src', 'System.Private.CoreLib', 'System.Private.CoreLib.csproj')) @@ -280,6 +264,7 @@ $(ArtifactsBinDir)pkg\aspnetcoreapp\lib $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'testhost', '$(BuildSettings)')) + $([MSBuild]::NormalizeDirectory('$(TestHostRootPath)', 'shared', '$(SharedFrameworkName)', '$(ProductVersion)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.ref')) $([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRefPackDir)', 'ref', '$(NetCoreAppCurrent)')) @@ -292,7 +277,9 @@ $(ArtifactsObjDir)version.txt - $(AdditionalBuildTargetFrameworks);netstandard2.0 + $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'Common')) + $([MSBuild]::NormalizeDirectory('$(CommonPathRoot)', 'src')) + $([MSBuild]::NormalizeDirectory('$(CommonPathRoot)', 'tests')) @@ -308,23 +295,6 @@ false - - - true - true - - $([MSBuild]::NormalizeDirectory('$(TestHostRootPath)', 'shared', 'Microsoft.NETCore.App', '$(ProductVersion)')) - - $(NETCoreAppTestSharedFrameworkPath) - $(TestHostRootPath) - - $(TestHostRuntimePath)PlatformManifest.txt - - - - - - @@ -354,22 +324,6 @@ - - - - false - - - - - - - - false true diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 39a6e0ecaef5..7fdfb48f2a97 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -1,7 +1,4 @@ - - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(TargetFramework)')) - @@ -17,6 +14,22 @@ $(OutputPath)$(MSBuildProjectName).xml + true + true + + true + + true @@ -41,21 +54,18 @@ - + true true - $(IsNETCoreApp) - $(IsNetFxNETStandard) true true true - net45;net451;net46;net461;net462;net47;net471;net472;netstandard1.0;netstandard1.1;netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0;netstandard2.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;$(netcoreappCurrent); - + @@ -63,74 +73,52 @@ - - $(RuntimePath) - $(BuildTargetFrameworkRefPath) - $(RuntimePath) + + $(NetCoreAppCurrentRuntimePath) + $(NetCoreAppCurrentRefPath) + $(NetCoreAppCurrentRuntimePath) + - - $(NETCoreAppPackageRuntimePath) + + $(NETCoreAppPackageRuntimePath) $(NETCoreAppPackageRefPath) - $(NETCoreAppPackageRuntimePath) - $(NETCoreAppPackageRuntimePath)\..\runtime\$(TargetOS)-$(Configuration)-$(TargetArchitecture) - $(RefRootPath)microsoft.netcore.app\$(Configuration) - $(NETCoreAppPackageRuntimePath)\..\runtime\$(TargetOS)-$(Configuration)-$(TargetArchitecture) + $(NETCoreAppPackageRuntimePath) + $(NETCoreAppPackageRuntimePath)\..\runtime\$(TargetOS)-$(Configuration)-$(TargetArchitecture) + $(RefRootPath)microsoft.netcore.app\$(Configuration) + $(NETCoreAppPackageRuntimePath)\..\runtime\$(TargetOS)-$(Configuration)-$(TargetArchitecture) - ILLinkTrimAssembly=true + ILLinkTrimAssembly=true - + $(ASPNETCoreAppPackageRuntimePath) $(ASPNETCoreAppPackageRefPath) - - $(NETCoreAppTestSharedFrameworkPath) - $(NETCoreAppTestSharedFrameworkPath) - - - $(TestHostRootPath) - $(TestHostRootPath) + + $(NETCoreAppTestSharedFrameworkPath) + $(NETCoreAppTestSharedFrameworkPath) - - - $(MicrosoftNetCoreAppRefPackRefDir) - - - + $(MicrosoftNetCoreAppRuntimePackNativeDir) - $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) - - - - - $(NetStandard20RefPath) - - - $(NetStandard21RefPath) - - - - $(RefRootPath)netcoreapp2.0/ - - - - - $(RefRootPath)%(Identity)/ - - - - $(ArtifactsBinDir)runtime/%(Identity)-$(Configuration)-$(TargetArchitecture) - $(ArtifactsBinDir)runtime/%(Identity)-$(Configuration)-$(TargetArchitecture) + $(MicrosoftNetCoreAppRefPackRefDir) + $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) + @@ -141,9 +129,9 @@ - + @@ -193,6 +181,7 @@ '$(Configuration)' != '$(CoreCLRConfiguration)'">Configuration=$(CoreCLRConfiguration) Configuration=$(MonoConfiguration) + false @@ -200,7 +189,9 @@ - + @@ -222,6 +213,19 @@ + + + + + + + @@ -233,7 +237,6 @@ true - true @@ -253,7 +256,7 @@ - true + true diff --git a/src/libraries/Microsoft.CSharp/Directory.Build.props b/src/libraries/Microsoft.CSharp/Directory.Build.props index 9155a7a07649..5073e779defc 100644 --- a/src/libraries/Microsoft.CSharp/Directory.Build.props +++ b/src/libraries/Microsoft.CSharp/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj index 0a85130f66d8..5aadca703ef1 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj +++ b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj @@ -1,7 +1,5 @@ - Microsoft.CSharp - Microsoft.CSharp $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) enable $(NoWarn);nullable diff --git a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj index 11dfc740701c..b36a8845bbd3 100644 --- a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj +++ b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 - netstandard2.0 + netstandard2.0;net461 - + - - - - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj b/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj index bb1022311814..3992cb1adb56 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj @@ -1,22 +1,16 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj index 5cff85d11fe3..d72fff10e633 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -10,7 +10,11 @@ Link="Common\tests\Extensions\TestingUtils\Microsoft.AspNetCore.Testing\src\ExceptionAssertions.cs" /> - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.csproj index b7895cdb04d2..d6b7d921c7a1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.csproj @@ -1,9 +1,11 @@ - netstandard2.0 + netstandard2.0;net461 - + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Microsoft.Extensions.Configuration.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Microsoft.Extensions.Configuration.Abstractions.csproj index 1bc83e66b5ce..c8f491379042 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Microsoft.Extensions.Configuration.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Microsoft.Extensions.Configuration.Abstractions.csproj @@ -1,23 +1,16 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 + true - + - - - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj index 4df616e01320..4a128e5c3845 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj @@ -1,10 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 2a1759b0d0c6..0c2ba3fbdfe6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -1,20 +1,13 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj index 2f02865ce4f5..219d53b133ef 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -13,7 +13,8 @@ - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/ref/Microsoft.Extensions.Configuration.CommandLine.csproj b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/ref/Microsoft.Extensions.Configuration.CommandLine.csproj index 152fd02a2657..041fb7e77f76 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/ref/Microsoft.Extensions.Configuration.CommandLine.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/ref/Microsoft.Extensions.Configuration.CommandLine.csproj @@ -1,10 +1,10 @@ - netstandard2.0 + netstandard2.0;net461 - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj index 980c31e3b203..5797401b7fe5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj @@ -1,18 +1,15 @@ - netstandard2.0;$(DefaultNetCoreTargetFramework);net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/tests/Microsoft.Extensions.Configuration.CommandLine.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/tests/Microsoft.Extensions.Configuration.CommandLine.Tests.csproj index 6fd320df92db..14a7ec39efdc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/tests/Microsoft.Extensions.Configuration.CommandLine.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/tests/Microsoft.Extensions.Configuration.CommandLine.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -15,7 +15,9 @@ - + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/ref/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/ref/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj index 2cdfea08ba7b..45d78b92ea24 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/ref/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/ref/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj @@ -1,10 +1,10 @@ - netstandard2.0 + netstandard2.0;net461 - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj index 7debc9c3c30e..0c2ba3fbdfe6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/Microsoft.Extensions.Configuration.EnvironmentVariables.csproj @@ -1,19 +1,13 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/Microsoft.Extensions.Configuration.EnvironmentVariables.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/Microsoft.Extensions.Configuration.EnvironmentVariables.Tests.csproj index ad7e1cb18d53..62b5a8e31deb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/Microsoft.Extensions.Configuration.EnvironmentVariables.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/Microsoft.Extensions.Configuration.EnvironmentVariables.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -15,7 +15,9 @@ - + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/ref/Microsoft.Extensions.Configuration.FileExtensions.csproj b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/ref/Microsoft.Extensions.Configuration.FileExtensions.csproj index a40874d8ed40..510044d8e6b3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/ref/Microsoft.Extensions.Configuration.FileExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/ref/Microsoft.Extensions.Configuration.FileExtensions.csproj @@ -1,12 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj index 9c7df603e519..4eb56f8e802f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj @@ -1,21 +1,16 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/tests/Microsoft.Extensions.Configuration.FileExtensions.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/tests/Microsoft.Extensions.Configuration.FileExtensions.Tests.csproj index d3c63062e038..89a8fb5ee48b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/tests/Microsoft.Extensions.Configuration.FileExtensions.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/tests/Microsoft.Extensions.Configuration.FileExtensions.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -12,6 +12,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/ref/Microsoft.Extensions.Configuration.Ini.csproj b/src/libraries/Microsoft.Extensions.Configuration.Ini/ref/Microsoft.Extensions.Configuration.Ini.csproj index ea7d74103535..84d96fe5db4a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/ref/Microsoft.Extensions.Configuration.Ini.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/ref/Microsoft.Extensions.Configuration.Ini.csproj @@ -1,12 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/Microsoft.Extensions.Configuration.Ini.csproj b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/Microsoft.Extensions.Configuration.Ini.csproj index 88f10cc47d33..f30343e2fcb3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/Microsoft.Extensions.Configuration.Ini.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/Microsoft.Extensions.Configuration.Ini.csproj @@ -1,20 +1,15 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/Microsoft.Extensions.Configuration.Ini.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/Microsoft.Extensions.Configuration.Ini.Tests.csproj index ea3ba9cfb775..d395499e6355 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/Microsoft.Extensions.Configuration.Ini.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/Microsoft.Extensions.Configuration.Ini.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -15,7 +15,8 @@ - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/ref/Microsoft.Extensions.Configuration.Json.csproj b/src/libraries/Microsoft.Extensions.Configuration.Json/ref/Microsoft.Extensions.Configuration.Json.csproj index ee7309646a16..2ab4a8b6be9b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/ref/Microsoft.Extensions.Configuration.Json.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/ref/Microsoft.Extensions.Configuration.Json.csproj @@ -1,14 +1,16 @@ - netstandard2.0 + netstandard2.0;net461 - - - - - - + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj index d313804efd7d..0f4b2c3d3253 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj @@ -1,31 +1,24 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true true + + false - - - - - - + + + + - - - - - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/Microsoft.Extensions.Configuration.Json.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/Microsoft.Extensions.Configuration.Json.Tests.csproj index 06c4ed8eefcd..a106c36d4409 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/Microsoft.Extensions.Configuration.Json.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/Microsoft.Extensions.Configuration.Json.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -15,8 +15,9 @@ - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/ref/Microsoft.Extensions.Configuration.UserSecrets.csproj b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/ref/Microsoft.Extensions.Configuration.UserSecrets.csproj index 97089510aa49..9d75126ff173 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/ref/Microsoft.Extensions.Configuration.UserSecrets.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/ref/Microsoft.Extensions.Configuration.UserSecrets.csproj @@ -1,10 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj index 5df32c910337..fe99bc62fc99 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj @@ -1,21 +1,17 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - - - - - - + + + + @@ -23,11 +19,4 @@ - - - - - - - diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/tests/Microsoft.Extensions.Configuration.UserSecrets.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/tests/Microsoft.Extensions.Configuration.UserSecrets.Tests.csproj index 6f5aa314eabc..5563693f653c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/tests/Microsoft.Extensions.Configuration.UserSecrets.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/tests/Microsoft.Extensions.Configuration.UserSecrets.Tests.csproj @@ -1,13 +1,13 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true - + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/ref/Microsoft.Extensions.Configuration.Xml.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/ref/Microsoft.Extensions.Configuration.Xml.csproj index 68a8306997a1..07a5625a3ced 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/ref/Microsoft.Extensions.Configuration.Xml.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/ref/Microsoft.Extensions.Configuration.Xml.csproj @@ -1,12 +1,14 @@ - netstandard2.0 + netstandard2.0;net461 - - - - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj index 9260eb9ec9d0..c90577e4fe84 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj @@ -1,31 +1,21 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - - - - - - - - - + + + + + - - - - diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj index dfb45ab9f8ce..7a98c89e480e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -22,13 +22,18 @@ Link="Common\tests\Extensions\TestingUtils\Microsoft.AspNetCore.Testing\src\xunit\RuntimeFrameworks.cs" /> - + - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.csproj b/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.csproj index 724bfef2ca5b..e1533c3eadf9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.csproj @@ -1,10 +1,10 @@ - netstandard2.0 + netstandard2.0;net461 - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/Microsoft.Extensions.Configuration.csproj b/src/libraries/Microsoft.Extensions.Configuration/src/Microsoft.Extensions.Configuration.csproj index 0c4d78a16ea3..a017ce7e5230 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/Microsoft.Extensions.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration/src/Microsoft.Extensions.Configuration.csproj @@ -1,19 +1,13 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/Microsoft.Extensions.Configuration.Functional.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/Microsoft.Extensions.Configuration.Functional.Tests.csproj index c162152be6bd..c2e3a8eeef9e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/Microsoft.Extensions.Configuration.Functional.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/Microsoft.Extensions.Configuration.Functional.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -11,6 +11,15 @@ + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/tests/Microsoft.Extensions.Configuration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration/tests/Microsoft.Extensions.Configuration.Tests.csproj index ddfc57ce028d..a1bf18a9e98b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/tests/Microsoft.Extensions.Configuration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration/tests/Microsoft.Extensions.Configuration.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -11,7 +11,9 @@ - + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index 942dbe0ee152..36abc792ab94 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0;net461 enable diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index 0d3119d83d6b..a8e1db4822e5 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -1,8 +1,7 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 $(DefineConstants);ActivatorUtilities_In_DependencyInjection true enable @@ -19,10 +18,4 @@ Link="Common\src\Extensions\ActivatorUtilities\ObjectFactory.cs" /> - - - - - - diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj index d4098d54f3b8..549b9e74322b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj @@ -1,13 +1,15 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 - - - - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj index 50cdcabc140e..17dc779a7105 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent);net461;netstandard2.0;netstandard2.1 - true + $(NetCoreAppCurrent);net461;netstandard2.0;netstandard2.1 False @@ -14,36 +13,6 @@ $(DefineConstants);SAVE_ASSEMBLIES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -56,4 +25,28 @@ Link="Common\src\Extensions\TypeNameHelper\TypeNameHelper.cs" /> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj index bf641d02f32f..d741185f4189 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj @@ -1,10 +1,14 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true $(NoWarn);CS8002 - false + + + + + false @@ -16,8 +20,8 @@ - - + + @@ -29,4 +33,15 @@ + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj index 6a2b15545e16..5dcd273c8b5f 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -13,13 +13,10 @@ - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs index 2ceeab1ac0b5..cdecbb6bc703 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.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. -extern alias DIAbstractions; using System; using Microsoft.AspNetCore.Testing; @@ -8,8 +7,6 @@ using Microsoft.Extensions.DependencyInjection.Specification.Fakes; using Xunit; -using AbstractionsSR = DIAbstractions::System.SR; - namespace Microsoft.Extensions.DependencyInjection { public class ServiceCollectionServiceExtensionsTest @@ -350,7 +347,7 @@ public void TryAddEnumerable_ThrowsWhenAddingIndistinguishableImplementationType ExceptionAssert.ThrowsArgument( () => collection.TryAddEnumerable(descriptor), "descriptor", - AbstractionsSR.Format(AbstractionsSR.TryAddIndistinguishableTypeToEnumerable, implementationType, serviceType)); + string.Format(@"Implementation type cannot be '{0}' because it is indistinguishable from other services registered for '{1}'.", implementationType, serviceType)); } [Fact] diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj index 4133d3704eca..86069259a9bc 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj @@ -1,12 +1,8 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) + netstandard2.0;net461 - - - - diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj index b6794fc1c8e8..39dbc1992197 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true @@ -19,16 +18,15 @@ - - - + - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextLoaderTests.cs b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextLoaderTests.cs index fe4dc14c93d4..8e8070e8a513 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextLoaderTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextLoaderTests.cs @@ -81,7 +81,7 @@ public void LoadCanLoadANonEntryAssembly() var loader = new DependencyContextLoader(); var context = loader.Load(typeof(DependencyContextLoaderTests).Assembly); - context.RuntimeLibraries.Should().Contain(l => l.Name == "Microsoft.Extensions.DependencyModel"); + context.RuntimeLibraries.Should().Contain(l => l.Name == "nonentrypointassembly"); } [Fact] diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/Microsoft.Extensions.DependencyModel.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/tests/Microsoft.Extensions.DependencyModel.Tests.csproj index fa4e2326a573..d9f4d1ebc92b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/tests/Microsoft.Extensions.DependencyModel.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/Microsoft.Extensions.DependencyModel.Tests.csproj @@ -1,21 +1,23 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true + $(DefaultItemExcludes);nonentrypointassembly\* true - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/NonEntryPointClass.cs b/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/NonEntryPointClass.cs new file mode 100644 index 000000000000..283734eebf5d --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/NonEntryPointClass.cs @@ -0,0 +1,12 @@ +// 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; + +namespace nonentrypointassembly +{ + public class NonEntryPointClass + { + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/nonentrypointassembly.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/nonentrypointassembly.csproj new file mode 100644 index 000000000000..0f39283f6e18 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/nonentrypointassembly/nonentrypointassembly.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.0 + true + + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.csproj index 778d01d8f903..32239798f1f1 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.csproj @@ -1,11 +1,11 @@ - netstandard2.0 + netstandard2.0;net461 - + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/Microsoft.Extensions.FileProviders.Abstractions.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/Microsoft.Extensions.FileProviders.Abstractions.csproj index 8c16ef3ce824..b55c758da87b 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/Microsoft.Extensions.FileProviders.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/Microsoft.Extensions.FileProviders.Abstractions.csproj @@ -2,8 +2,7 @@ Microsoft.Extensions.FileProviders - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true @@ -13,13 +12,8 @@ - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/ref/Microsoft.Extensions.FileProviders.Composite.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Composite/ref/Microsoft.Extensions.FileProviders.Composite.csproj index 9c945ef56a72..bb27ead33941 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Composite/ref/Microsoft.Extensions.FileProviders.Composite.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Composite/ref/Microsoft.Extensions.FileProviders.Composite.csproj @@ -1,13 +1,13 @@ Microsoft.Extensions.FileProviders - netstandard2.0 + netstandard2.0;net461 - - + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/Microsoft.Extensions.FileProviders.Composite.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/Microsoft.Extensions.FileProviders.Composite.csproj index 898fe2fbd58c..80db265cd682 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/Microsoft.Extensions.FileProviders.Composite.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/Microsoft.Extensions.FileProviders.Composite.csproj @@ -2,19 +2,13 @@ Microsoft.Extensions.FileProviders - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/Microsoft.Extensions.FileProviders.Composite.Tests.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/Microsoft.Extensions.FileProviders.Composite.Tests.csproj index 05183b81816c..a9e97be7d366 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/Microsoft.Extensions.FileProviders.Composite.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/Microsoft.Extensions.FileProviders.Composite.Tests.csproj @@ -2,12 +2,15 @@ Microsoft.Extensions.FileProviders.Composite - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true + + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.csproj index c6b18a0ac307..cb4948ba130a 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.csproj @@ -1,13 +1,13 @@ - netstandard2.0 + netstandard2.0;net461 - - - + + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj index ba390655fe15..376c72160f6d 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Microsoft.Extensions.FileProviders.Physical.csproj @@ -2,17 +2,11 @@ Microsoft.Extensions.FileProviders - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true true - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) - - @@ -21,17 +15,14 @@ - - - + + + - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj index 11edb64eab69..b59f5900e886 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj @@ -2,7 +2,7 @@ Microsoft.Extensions.FileProviders.Physical - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -15,7 +15,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj index 3b99a60054e9..b939996a35bc 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0;net461 diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj index ab4b23464b4d..cf923440da6e 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj @@ -1,8 +1,7 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true @@ -11,10 +10,4 @@ Link="Common\src\Extensions\HashCodeCombiner\HashCodeCombiner.cs" /> - - - - - - diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/Microsoft.Extensions.FileSystemGlobbing.Tests.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/Microsoft.Extensions.FileSystemGlobbing.Tests.csproj index 80a382c4ba14..d871ed685eaa 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/Microsoft.Extensions.FileSystemGlobbing.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/Microsoft.Extensions.FileSystemGlobbing.Tests.csproj @@ -1,8 +1,12 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true + + + + diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostInvalidSignature/BuildWebHostInvalidSignature.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/BuildWebHostPatternTestSite/BuildWebHostPatternTestSite.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderInvalidSignature/CreateHostBuilderInvalidSignature.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderInvalidSignature/CreateHostBuilderInvalidSignature.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderInvalidSignature/CreateHostBuilderInvalidSignature.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderInvalidSignature/CreateHostBuilderInvalidSignature.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderPatternTestSite/CreateHostBuilderPatternTestSite.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderPatternTestSite/CreateHostBuilderPatternTestSite.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderPatternTestSite/CreateHostBuilderPatternTestSite.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateHostBuilderPatternTestSite/CreateHostBuilderPatternTestSite.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderInvalidSignature/CreateWebHostBuilderInvalidSignature.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderPatternTestSite/CreateWebHostBuilderPatternTestSite.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderPatternTestSite/CreateWebHostBuilderPatternTestSite.csproj index fcc7214c0b5f..716b25a87281 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderPatternTestSite/CreateWebHostBuilderPatternTestSite.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/CreateWebHostBuilderPatternTestSite/CreateWebHostBuilderPatternTestSite.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/Microsoft.Extensions.HostFactoryResolver.Tests.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/Microsoft.Extensions.HostFactoryResolver.Tests.csproj index ce58ed38bbc1..686592b47604 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/Microsoft.Extensions.HostFactoryResolver.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/Microsoft.Extensions.HostFactoryResolver.Tests.csproj @@ -1,6 +1,6 @@  - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/MockHostTypes/MockHostTypes.csproj b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/MockHostTypes/MockHostTypes.csproj index 80a382c4ba14..88e03293e6ce 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/MockHostTypes/MockHostTypes.csproj +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/tests/MockHostTypes/MockHostTypes.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj index cd10bfb2b381..6b237427cde2 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -1,16 +1,19 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 $(NoWarn);CS0618 - - - - - - - + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index 3de7d53d9c9e..1cd83144a389 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -1,28 +1,24 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 Microsoft.Extensions.Hosting true + + false - - - - - - + + + + - - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj index 8f69092efa8b..63f62d833dee 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj @@ -1,18 +1,20 @@ - netstandard2.0 + netstandard2.0;net461 $(NoWarn);CS0618 - - - - - - - - - + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index d384aae9cc35..24879b235bb9 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -1,58 +1,43 @@ - $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;net461 true - - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) + + false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - + + + - - diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj index fe116dda28fd..2d67db82d52c 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -24,4 +24,8 @@ + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/TestApp/Microsoft.Extensions.Hosting.TestApp.csproj b/src/libraries/Microsoft.Extensions.Hosting/tests/TestApp/Microsoft.Extensions.Hosting.TestApp.csproj index 28b6ff9259f9..399232d63b79 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/TestApp/Microsoft.Extensions.Hosting.TestApp.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/TestApp/Microsoft.Extensions.Hosting.TestApp.csproj @@ -1,7 +1,14 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true Exe + + + + + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs index 07e9c021a57a..5c1a3b67d128 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs @@ -143,7 +143,7 @@ public void DefaultIHostEnvironmentValues() Assert.Equal(Environments.Production, env.EnvironmentName); #if NETCOREAPP Assert.NotNull(env.ApplicationName); -#elif NET472 +#elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. Assert.Null(env.ApplicationName); #else @@ -159,7 +159,7 @@ public void DefaultIHostEnvironmentValues() Assert.Equal(Environments.Production, env.EnvironmentName); #if NETCOREAPP Assert.NotNull(env.ApplicationName); -#elif NET472 +#elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. Assert.Null(env.ApplicationName); #else diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj index af2ed3b68a5c..b5365cdda844 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);net461 true @@ -12,6 +12,8 @@ + + diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj index c798ddd1c309..d0551567b5ec 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj @@ -1,12 +1,17 @@ - netstandard2.0 + netstandard2.0;net461 - + - - - - + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj index 47eeebc131c9..e27e847e380f 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj @@ -1,14 +1,9 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) - - - - - + + + + - - - diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj index 81926a709d7b..3c192f903d02 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -24,7 +24,12 @@ - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj index 805321e4b709..905c8b20bbec 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0;net461 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj index 1462166794f3..26c5d1f3329d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj @@ -1,8 +1,7 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 true @@ -15,9 +14,4 @@ Link="Common\src\Extensions\Logging\NullScope.cs" /> - - - - - diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj index d5e676b199f9..880386c22985 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj @@ -1,12 +1,14 @@ - netstandard2.0 + netstandard2.0;net461 - - - - + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj index 31d6673acd76..b666c263a402 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj @@ -1,9 +1,10 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false @@ -11,24 +12,15 @@ Link="Common\Extensions\ProviderAliasUtilities\ProviderAliasUtilities.cs" /> - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj index 0756d569fde5..f56ed2cc9d0b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj @@ -1,13 +1,16 @@ - netstandard2.0 + netstandard2.0;net461 - - - - + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 3afd1b9ed232..84bcd7c43588 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -1,25 +1,14 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true annotations $(DefineConstants);NO_SUPPRESS_GC_TRANSITION - - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) + + false - - - - - - - - @@ -39,33 +28,23 @@ - - + + - - - - - - - - - - - - - + + + + + + - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj index 2524f77b4b46..6d1c916ab02d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj @@ -1,13 +1,13 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true true - + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/ref/Microsoft.Extensions.Logging.Debug.csproj b/src/libraries/Microsoft.Extensions.Logging.Debug/ref/Microsoft.Extensions.Logging.Debug.csproj index 3857ebe8a7bf..046103224ca3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/ref/Microsoft.Extensions.Logging.Debug.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/ref/Microsoft.Extensions.Logging.Debug.csproj @@ -1,10 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj b/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj index d1d2c4274e5b..a6a8adb91caf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj @@ -1,14 +1,12 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - @@ -17,14 +15,9 @@ - - - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/ref/Microsoft.Extensions.Logging.EventLog.csproj b/src/libraries/Microsoft.Extensions.Logging.EventLog/ref/Microsoft.Extensions.Logging.EventLog.csproj index 21d4d4cb7309..41ab6a29cfaf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/ref/Microsoft.Extensions.Logging.EventLog.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/ref/Microsoft.Extensions.Logging.EventLog.csproj @@ -1,11 +1,13 @@ - netstandard2.0 + netstandard2.0;net461 - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj index fca2aa1bcf1a..893cded069d0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj @@ -1,26 +1,12 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent);net461;netstandard2.0;netstandard2.1 - true + $(NetCoreAppCurrent);net461;netstandard2.0;netstandard2.1 true + + false - - - - - - - - - - - - - - - @@ -29,10 +15,14 @@ - - - - + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/ref/Microsoft.Extensions.Logging.EventSource.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/ref/Microsoft.Extensions.Logging.EventSource.csproj index ecf0ef7df93a..fe5b5ee697d3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/ref/Microsoft.Extensions.Logging.EventSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/ref/Microsoft.Extensions.Logging.EventSource.csproj @@ -1,10 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj index d55f53f867f6..0c532335ff2d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj @@ -1,10 +1,11 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true true + + false @@ -12,32 +13,21 @@ Link="Common\src\Extensions\Logging\NullExternalScopeProvider.cs" /> - - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj index 4fa230c5669f..ba8087956f5d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj @@ -1,12 +1,14 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true - + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/ref/Microsoft.Extensions.Logging.TraceSource.csproj b/src/libraries/Microsoft.Extensions.Logging.TraceSource/ref/Microsoft.Extensions.Logging.TraceSource.csproj index eaa0a981e27e..35d85582fedf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/ref/Microsoft.Extensions.Logging.TraceSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/ref/Microsoft.Extensions.Logging.TraceSource.csproj @@ -1,10 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj index ca883dd4c7dd..30ddca780a41 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj @@ -1,27 +1,16 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - - - - - - - - - - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.csproj b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.csproj index c79d0fdc6128..745210c36582 100644 --- a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.csproj @@ -1,11 +1,13 @@ - netstandard2.0 + netstandard2.0;net461 - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj index 5d4787254c6b..50302ec29144 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj @@ -1,9 +1,10 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false @@ -15,34 +16,21 @@ Link="Common\src\Extensions\Logging\NullScope.cs" /> - - - - - - - - - - - - + + + + + - - - - - - + + - - - - - + + diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/Microsoft.Extensions.Logging.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging/tests/Common/Microsoft.Extensions.Logging.Tests.csproj index cec257df2eca..83ceb2b24735 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/Microsoft.Extensions.Logging.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/Microsoft.Extensions.Logging.Tests.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);net461 true @@ -18,10 +18,21 @@ Link="tests\DI.Common\Common\src\TestLogger.cs" /> + + + - - - + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs index b67ef0e79346..80d9e7ab1909 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET472 +#if NETFRAMEWORK using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs index 6f9255dce6e3..25bd315a8679 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.Logging.Test { public class TraceSourceScopeTest { -#if NET472 +#if NETFRAMEWORK [Fact] public static void DiagnosticsScope_PushesAndPops_LogicalOperationStack() { diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj index 420524704ece..908e9d0062db 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -18,4 +18,9 @@ + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index be66538ec516..b28dde039c48 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -1,13 +1,15 @@ - netstandard2.0 + netstandard2.0;net461 - - - - - + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index 3d9e3c322e96..1f9712661344 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -1,26 +1,18 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - - - - - - - - - - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj index b8dd59bff6fe..c7fe04287c37 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -1,10 +1,12 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 - - + + + + diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj index 9adaadcc69d5..1936fb85d671 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -1,28 +1,22 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - + + - - - - - - - - + + - diff --git a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj index a119724225af..a71d9b27e599 100644 --- a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj @@ -1,13 +1,15 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 - - - - - + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index eda46678ac44..d9840099d4ed 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -1,32 +1,23 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true + + false - - + + - - - - - - - - - - - + + - - + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj index 80a382c4ba14..3dfad737c847 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj @@ -1,8 +1,18 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.csproj b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.csproj index a96a2cac069c..aee88d8e2349 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.csproj +++ b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.csproj @@ -1,11 +1,12 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj index bd8c31c27a13..0472414867b5 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj +++ b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj @@ -1,10 +1,12 @@ - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 true true + + false + @@ -20,23 +22,11 @@ - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/libraries/Microsoft.Extensions.Primitives/tests/Microsoft.Extensions.Primitives.Tests.csproj b/src/libraries/Microsoft.Extensions.Primitives/tests/Microsoft.Extensions.Primitives.Tests.csproj index d468ddb10026..5bdba47205fd 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/tests/Microsoft.Extensions.Primitives.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Primitives/tests/Microsoft.Extensions.Primitives.Tests.csproj @@ -1,12 +1,13 @@ - $(NetCoreAppCurrent);net472 + $(NetCoreAppCurrent);net461 true + diff --git a/src/libraries/Microsoft.IO.Redist/Directory.Build.props b/src/libraries/Microsoft.IO.Redist/Directory.Build.props index 7dcfd0eaa201..ba1f965d83ca 100644 --- a/src/libraries/Microsoft.IO.Redist/Directory.Build.props +++ b/src/libraries/Microsoft.IO.Redist/Directory.Build.props @@ -2,6 +2,5 @@ Open - false diff --git a/src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj b/src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj index 41b1e51a0b58..b9a0737a28de 100644 --- a/src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj +++ b/src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj @@ -1,7 +1,6 @@ - Microsoft.IO.Redist - $(NetFrameworkCurrent) + net472 $(DefineConstants);MS_IO_REDIST true false @@ -196,12 +195,8 @@ - - - - - - + + diff --git a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props index 49b11607763d..df1a19548772 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props +++ b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props @@ -5,6 +5,5 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) 10.0.6.0 Microsoft - true \ No newline at end of file diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj index 3fe68cb9c087..9d76a13c5fce 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj @@ -95,8 +95,8 @@ + - diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft.VisualBasic.Core.Tests.csproj b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft.VisualBasic.Core.Tests.csproj index f7ed31e0b036..74c7f14cfeeb 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft.VisualBasic.Core.Tests.csproj +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft.VisualBasic.Core.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -50,4 +50,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Primitives/Directory.Build.props b/src/libraries/Microsoft.Win32.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/Microsoft.Win32.Primitives/Directory.Build.props +++ b/src/libraries/Microsoft.Win32.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/ref/Microsoft.Win32.Registry.AccessControl.csproj b/src/libraries/Microsoft.Win32.Registry.AccessControl/ref/Microsoft.Win32.Registry.AccessControl.csproj index ab5061eb5c8d..ac6eb1b1d339 100644 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/ref/Microsoft.Win32.Registry.AccessControl.csproj +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/ref/Microsoft.Win32.Registry.AccessControl.csproj @@ -1,16 +1,12 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 enable - - - diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj index 9ceaab881111..f93606b6a960 100644 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj @@ -1,8 +1,7 @@ true - netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT enable @@ -10,17 +9,11 @@ SR.PlatformNotSupported_RegistryAccessControl true - - - - - - - - - - + + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/tests/Microsoft.Win32.Registry.AccessControl.Tests.csproj b/src/libraries/Microsoft.Win32.Registry.AccessControl/tests/Microsoft.Win32.Registry.AccessControl.Tests.csproj index ee2fa0f75fae..c7ded4394f35 100644 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/tests/Microsoft.Win32.Registry.AccessControl.Tests.csproj +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/tests/Microsoft.Win32.Registry.AccessControl.Tests.csproj @@ -1,8 +1,14 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT + + + + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry/Directory.Build.props b/src/libraries/Microsoft.Win32.Registry/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/Microsoft.Win32.Registry/Directory.Build.props +++ b/src/libraries/Microsoft.Win32.Registry/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.csproj index b8b7036446b5..cdf33b7f09e1 100644 --- a/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.csproj @@ -1,6 +1,6 @@ - netstandard2.0;$(NetFrameworkCurrent);net461 + netstandard2.0;net461 enable @@ -10,9 +10,6 @@ - - - diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj index 3030b9a60d1e..76c93e82be74 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj @@ -2,9 +2,8 @@ true $(DefineConstants);REGISTRY_ASSEMBLY - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);$(NetFrameworkCurrent)-Windows_NT;netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT true - true $(NoWarn);CA2249 enable @@ -74,10 +73,11 @@ - - + + + - + @@ -87,7 +87,11 @@ - - + + + + + + diff --git a/src/libraries/Microsoft.Win32.Registry/tests/Microsoft.Win32.Registry.Tests.csproj b/src/libraries/Microsoft.Win32.Registry/tests/Microsoft.Win32.Registry.Tests.csproj index 1323c1260758..36f086dad552 100644 --- a/src/libraries/Microsoft.Win32.Registry/tests/Microsoft.Win32.Registry.Tests.csproj +++ b/src/libraries/Microsoft.Win32.Registry/tests/Microsoft.Win32.Registry.Tests.csproj @@ -1,7 +1,7 @@ $(DefineConstants);REGISTRY_ASSEMBLY - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.SystemEvents/ref/Microsoft.Win32.SystemEvents.csproj b/src/libraries/Microsoft.Win32.SystemEvents/ref/Microsoft.Win32.SystemEvents.csproj index 00a2bef840b0..e0413852feda 100644 --- a/src/libraries/Microsoft.Win32.SystemEvents/ref/Microsoft.Win32.SystemEvents.csproj +++ b/src/libraries/Microsoft.Win32.SystemEvents/ref/Microsoft.Win32.SystemEvents.csproj @@ -1,6 +1,6 @@ - netstandard2.0;$(NetFrameworkCurrent);net461 + netstandard2.0;net461 enable @@ -10,8 +10,4 @@ - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft.Win32.SystemEvents.csproj b/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft.Win32.SystemEvents.csproj index ba2d1c66aa26..4cdba1a506ea 100644 --- a/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft.Win32.SystemEvents.csproj +++ b/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft.Win32.SystemEvents.csproj @@ -2,9 +2,8 @@ true enable - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;netcoreapp3.0-Windows_NT;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;netcoreapp3.0-Windows_NT;net461 true - true @@ -118,14 +117,13 @@ - - - - - + + @@ -135,7 +133,4 @@ - - - diff --git a/src/libraries/Microsoft.Win32.SystemEvents/tests/Microsoft.Win32.SystemEvents.Tests.csproj b/src/libraries/Microsoft.Win32.SystemEvents/tests/Microsoft.Win32.SystemEvents.Tests.csproj index 3faa8abcdbe7..dd4771652224 100644 --- a/src/libraries/Microsoft.Win32.SystemEvents/tests/Microsoft.Win32.SystemEvents.Tests.csproj +++ b/src/libraries/Microsoft.Win32.SystemEvents/tests/Microsoft.Win32.SystemEvents.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT + + + diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/tests/Microsoft.XmlSerializer.Generator.Tests.csproj b/src/libraries/Microsoft.XmlSerializer.Generator/tests/Microsoft.XmlSerializer.Generator.Tests.csproj index 7109d5ba3180..13024a3e7a7f 100644 --- a/src/libraries/Microsoft.XmlSerializer.Generator/tests/Microsoft.XmlSerializer.Generator.Tests.csproj +++ b/src/libraries/Microsoft.XmlSerializer.Generator/tests/Microsoft.XmlSerializer.Generator.Tests.csproj @@ -29,11 +29,7 @@ - - - true - + - - + $(ArtifactsObjDir)_version.h @@ -11,9 +6,14 @@ <_BuildNativeArgs>$(TargetArchitecture) $(Configuration) outconfig $(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture) -os $(TargetOS) + + + + - - + BeforeTargets="Build" + Condition="'$(TargetOS)' == 'Windows_NT' and + '$(BuildTargetFramework)' == '$(NetCoreAppCurrent)'"> - - - + + - - diff --git a/src/libraries/Native/native-binplace.proj b/src/libraries/Native/native-binplace.proj index f8a558defe35..4c49de39a4b1 100644 --- a/src/libraries/Native/native-binplace.proj +++ b/src/libraries/Native/native-binplace.proj @@ -2,10 +2,11 @@ - $(NetCoreAppCurrent);netstandard2.0;$(NetFrameworkCurrent) + $(NetCoreAppCurrent) $(BuildTargetFramework) false true + true @@ -22,10 +23,6 @@ - - - - diff --git a/src/libraries/NetCoreAppLibrary.props b/src/libraries/NetCoreAppLibrary.props new file mode 100644 index 000000000000..710e7b172db0 --- /dev/null +++ b/src/libraries/NetCoreAppLibrary.props @@ -0,0 +1,161 @@ + + + + + Microsoft.CSharp; + Microsoft.VisualBasic.Core; + Microsoft.Win32.Primitives; + Microsoft.Win32.Registry; + System.AppContext; + System.Buffers; + System.Collections; + System.Collections.Concurrent; + System.Collections.Immutable; + System.Collections.NonGeneric; + System.Collections.Specialized; + System.ComponentModel; + System.ComponentModel.Annotations; + System.ComponentModel.EventBasedAsync; + System.ComponentModel.Primitives; + System.ComponentModel.TypeConverter; + System.Console; + System.Data.Common; + System.Data.DataSetExtensions; + System.Diagnostics.Contracts; + System.Diagnostics.Debug; + System.Diagnostics.DiagnosticSource; + System.Diagnostics.FileVersionInfo; + System.Diagnostics.Process; + System.Diagnostics.StackTrace; + System.Diagnostics.TextWriterTraceListener; + System.Diagnostics.Tools; + System.Diagnostics.TraceSource; + System.Diagnostics.Tracing; + System.Drawing.Primitives; + System.Dynamic.Runtime; + System.Formats.Asn1; + System.Globalization; + System.Globalization.Calendars; + System.Globalization.Extensions; + System.IO; + System.IO.Compression; + System.IO.Compression.Brotli; + System.IO.Compression.ZipFile; + System.IO.FileSystem; + System.IO.FileSystem.AccessControl; + System.IO.FileSystem.DriveInfo; + System.IO.FileSystem.Primitives; + System.IO.FileSystem.Watcher; + System.IO.IsolatedStorage; + System.IO.MemoryMappedFiles; + System.IO.Pipes; + System.IO.Pipes.AccessControl; + System.IO.UnmanagedMemoryStream; + System.Linq; + System.Linq.Expressions; + System.Linq.Parallel; + System.Linq.Queryable; + System.Memory; + System.Net.Http; + System.Net.Http.Json; + System.Net.HttpListener; + System.Net.Mail; + System.Net.NameResolution; + System.Net.NetworkInformation; + System.Net.Ping; + System.Net.Primitives; + System.Net.Requests; + System.Net.Security; + System.Net.ServicePoint; + System.Net.Sockets; + System.Net.WebClient; + System.Net.WebHeaderCollection; + System.Net.WebProxy; + System.Net.WebSockets; + System.Net.WebSockets.Client; + System.Numerics.Vectors; + System.ObjectModel; + System.Private.DataContractSerialization; + System.Private.Uri; + System.Private.Xml; + System.Private.Xml.Linq; + System.Reflection; + System.Reflection.DispatchProxy; + System.Reflection.Emit; + System.Reflection.Emit.ILGeneration; + System.Reflection.Emit.Lightweight; + System.Reflection.Extensions; + System.Reflection.Metadata; + System.Reflection.Primitives; + System.Reflection.TypeExtensions; + System.Resources.Reader; + System.Resources.ResourceManager; + System.Resources.Writer; + System.Runtime; + System.Runtime.CompilerServices.Unsafe; + System.Runtime.CompilerServices.VisualC; + System.Runtime.Extensions; + System.Runtime.Handles; + System.Runtime.InteropServices; + System.Runtime.InteropServices.JavaScript; + System.Runtime.InteropServices.RuntimeInformation; + System.Runtime.Intrinsics; + System.Runtime.Loader; + System.Runtime.Numerics; + System.Runtime.Serialization.Formatters; + System.Runtime.Serialization.Json; + System.Runtime.Serialization.Primitives; + System.Runtime.Serialization.Xml; + System.Security.AccessControl; + System.Security.Claims; + System.Security.Cryptography.Algorithms; + System.Security.Cryptography.Cng; + System.Security.Cryptography.Csp; + System.Security.Cryptography.Encoding; + System.Security.Cryptography.OpenSsl; + System.Security.Cryptography.Primitives; + System.Security.Cryptography.X509Certificates; + System.Security.Principal; + System.Security.Principal.Windows; + System.Security.SecureString; + System.Text.Encoding; + System.Text.Encoding.CodePages; + System.Text.Encoding.Extensions; + System.Text.Encodings.Web; + System.Text.Json; + System.Text.RegularExpressions; + System.Threading; + System.Threading.Channels; + System.Threading.Overlapped; + System.Threading.Tasks; + System.Threading.Tasks.Dataflow; + System.Threading.Tasks.Extensions; + System.Threading.Tasks.Parallel; + System.Threading.Thread; + System.Threading.ThreadPool; + System.Threading.Timer; + System.Transactions.Local; + System.ValueTuple; + System.Web.HttpUtility; + System.Xml.ReaderWriter; + System.Xml.XDocument; + System.Xml.XmlDocument; + System.Xml.XmlSerializer; + System.Xml.XPath; + System.Xml.XPath.XDocument; + + + Microsoft.Win32.Registry; + System.IO.FileSystem.AccessControl; + System.IO.Pipes.AccessControl; + System.Security.AccessControl; + System.Security.Cryptography.Cng; + System.Security.Cryptography.OpenSsl; + System.Security.Principal.Windows; + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.AppContext/Directory.Build.props b/src/libraries/System.AppContext/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.AppContext/Directory.Build.props +++ b/src/libraries/System.AppContext/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.AppContext/src/System.AppContext.csproj b/src/libraries/System.AppContext/src/System.AppContext.csproj index 0b924ac9f8c3..4f2d15aa3b6a 100644 --- a/src/libraries/System.AppContext/src/System.AppContext.csproj +++ b/src/libraries/System.AppContext/src/System.AppContext.csproj @@ -1,6 +1,5 @@ - System.AppContext true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Buffers/Directory.Build.props b/src/libraries/System.Buffers/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Buffers/Directory.Build.props +++ b/src/libraries/System.Buffers/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.CodeDom/ref/System.CodeDom.csproj b/src/libraries/System.CodeDom/ref/System.CodeDom.csproj index 189b1e644761..fdc597d599cc 100644 --- a/src/libraries/System.CodeDom/ref/System.CodeDom.csproj +++ b/src/libraries/System.CodeDom/ref/System.CodeDom.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -10,10 +9,6 @@ - - - - diff --git a/src/libraries/System.CodeDom/src/System.CodeDom.csproj b/src/libraries/System.CodeDom/src/System.CodeDom.csproj index 7217ca52bc65..e3622bd5d65e 100644 --- a/src/libraries/System.CodeDom/src/System.CodeDom.csproj +++ b/src/libraries/System.CodeDom/src/System.CodeDom.csproj @@ -2,8 +2,7 @@ true $(DefineConstants);CODEDOM - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -129,8 +128,4 @@ - - - - \ No newline at end of file diff --git a/src/libraries/System.CodeDom/tests/System.CodeDom.Tests.csproj b/src/libraries/System.CodeDom/tests/System.CodeDom.Tests.csproj index 9e92688da3e9..f90d915dffa5 100644 --- a/src/libraries/System.CodeDom/tests/System.CodeDom.Tests.csproj +++ b/src/libraries/System.CodeDom/tests/System.CodeDom.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -110,4 +110,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Collections.Concurrent/Directory.Build.props b/src/libraries/System.Collections.Concurrent/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Collections.Concurrent/Directory.Build.props +++ b/src/libraries/System.Collections.Concurrent/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Collections.Concurrent/src/System.Collections.Concurrent.csproj b/src/libraries/System.Collections.Concurrent/src/System.Collections.Concurrent.csproj index 93f3a50fc275..0584d13dbe8e 100644 --- a/src/libraries/System.Collections.Concurrent/src/System.Collections.Concurrent.csproj +++ b/src/libraries/System.Collections.Concurrent/src/System.Collections.Concurrent.csproj @@ -1,7 +1,5 @@ - System.Collections.Concurrent - System.Collections.Concurrent true enable $(NetCoreAppCurrent) @@ -23,8 +21,8 @@ - - - + + + diff --git a/src/libraries/System.Collections.Immutable/Directory.Build.props b/src/libraries/System.Collections.Immutable/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Collections.Immutable/Directory.Build.props +++ b/src/libraries/System.Collections.Immutable/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index 403bbf8aff65..bd650bdc3235 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -413,7 +413,7 @@ public static partial class ImmutableHashSet public static System.Collections.Immutable.ImmutableHashSet ToImmutableHashSet(this System.Collections.Immutable.ImmutableHashSet.Builder builder) { throw null; } } - #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !NETSTANDARD2_0 + #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !NETSTANDARD2_0 && !NETFRAMEWORK public sealed partial class ImmutableHashSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Immutable.IImmutableSet #else public sealed partial class ImmutableHashSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.ISet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Immutable.IImmutableSet @@ -916,7 +916,7 @@ public static partial class ImmutableSortedSet public static System.Collections.Immutable.ImmutableSortedSet ToImmutableSortedSet(this System.Collections.Immutable.ImmutableSortedSet.Builder builder) { throw null; } } - #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !NETSTANDARD2_0 + #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !NETSTANDARD2_0 && !NETFRAMEWORK public sealed partial class ImmutableSortedSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableSet #else public sealed partial class ImmutableSortedSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.ISet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableSet diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.csproj b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.csproj index 48e1f0bde560..57d3d7cec3d4 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.csproj +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);netstandard1.0;netstandard1.3;netstandard2.0 + $(NetCoreAppCurrent);netstandard1.0;netstandard1.3;netstandard2.0;net461 true enable @@ -12,16 +12,17 @@ - - - + + + - - - + - - + + + \ No newline at end of file diff --git a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj index f2fc64f714f3..f950c965cac2 100644 --- a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj +++ b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);netstandard1.0;netstandard1.3;netstandard2.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard1.0;netstandard1.3;netstandard2.0;net461 true - true enable @@ -88,13 +87,13 @@ + - - + @@ -104,22 +103,14 @@ - - - - - - + - - - - - - - - - + + + + diff --git a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj index f5130bcc181d..f71e364a81ea 100644 --- a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj +++ b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj @@ -1,10 +1,10 @@ 0436 - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 - @@ -77,8 +77,7 @@ - - + @@ -96,4 +95,7 @@ + + + diff --git a/src/libraries/System.Collections.NonGeneric/Directory.Build.props b/src/libraries/System.Collections.NonGeneric/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Collections.NonGeneric/Directory.Build.props +++ b/src/libraries/System.Collections.NonGeneric/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj index 9ec5c3a1eb93..5009669653d1 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj +++ b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj @@ -1,7 +1,5 @@ - System.Collections.NonGeneric - System.Collections.NonGeneric true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Collections.Specialized/Directory.Build.props b/src/libraries/System.Collections.Specialized/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Collections.Specialized/Directory.Build.props +++ b/src/libraries/System.Collections.Specialized/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj index 6139444928b2..1eff0c5b1da7 100644 --- a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj +++ b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj @@ -1,7 +1,5 @@ - System.Collections.Specialized - System.Collections.Specialized $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Collections/Directory.Build.props b/src/libraries/System.Collections/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Collections/Directory.Build.props +++ b/src/libraries/System.Collections/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Collections/src/System.Collections.csproj b/src/libraries/System.Collections/src/System.Collections.csproj index 7ac500622b24..9f8e4b8bb629 100644 --- a/src/libraries/System.Collections/src/System.Collections.csproj +++ b/src/libraries/System.Collections/src/System.Collections.csproj @@ -1,6 +1,5 @@ - System.Collections true true $(NetCoreAppCurrent) diff --git a/src/libraries/System.ComponentModel.Annotations/Directory.Build.props b/src/libraries/System.ComponentModel.Annotations/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.ComponentModel.Annotations/Directory.Build.props +++ b/src/libraries/System.ComponentModel.Annotations/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj b/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj index 17571c6c8694..5c9152f2cd21 100644 --- a/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj +++ b/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 @@ -42,4 +42,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj b/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj index bca38d6e8f46..68bae6aecf01 100644 --- a/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj +++ b/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj @@ -1,6 +1,5 @@ - System.ComponentModel.Composition.Registration netstandard2.1 @@ -25,7 +24,7 @@ Link="Common\System\Composition\Diagnostics\TraceWriter.cs" /> - - + + diff --git a/src/libraries/System.ComponentModel.Composition.Registration/tests/System.ComponentModel.Composition.Registration.Tests.csproj b/src/libraries/System.ComponentModel.Composition.Registration/tests/System.ComponentModel.Composition.Registration.Tests.csproj index 8c0707afe31b..56a677088748 100644 --- a/src/libraries/System.ComponentModel.Composition.Registration/tests/System.ComponentModel.Composition.Registration.Tests.csproj +++ b/src/libraries/System.ComponentModel.Composition.Registration/tests/System.ComponentModel.Composition.Registration.Tests.csproj @@ -19,4 +19,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.csproj b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.csproj index cbf8732c35c4..543c5c85ca1d 100644 --- a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.csproj +++ b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.csproj @@ -1,6 +1,6 @@ - netstandard2.0;_net461 + netstandard2.0 enable diff --git a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj index 826fc8dd9fa5..519abadf0b66 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj +++ b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj @@ -1,8 +1,6 @@ - - - $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.0;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.0 true enable @@ -214,4 +212,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Noop.Assembly/System.ComponentModel.Composition.Noop.Assembly.csproj b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Noop.Assembly/System.ComponentModel.Composition.Noop.Assembly.csproj index 6d6060c2a287..6bf5cb7f9f9e 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Noop.Assembly/System.ComponentModel.Composition.Noop.Assembly.csproj +++ b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Noop.Assembly/System.ComponentModel.Composition.Noop.Assembly.csproj @@ -5,4 +5,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj index fc7811e645ef..08e2e4cbaea7 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj +++ b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj @@ -4,11 +4,6 @@ true $(NetCoreAppCurrent) - - - - - @@ -171,10 +166,11 @@ - - false - content - PreserveNewest - + + + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/Directory.Build.props b/src/libraries/System.ComponentModel.EventBasedAsync/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/Directory.Build.props +++ b/src/libraries/System.ComponentModel.EventBasedAsync/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj index a33080137075..ad8ffe0f0061 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj +++ b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj @@ -1,7 +1,5 @@ - System.ComponentModel.EventBasedAsync - System.ComponentModel.EventBasedAsync $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.ComponentModel.Primitives/Directory.Build.props b/src/libraries/System.ComponentModel.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.ComponentModel.Primitives/Directory.Build.props +++ b/src/libraries/System.ComponentModel.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj index 53e44fa05eac..aa386aae2df8 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj +++ b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj @@ -1,7 +1,5 @@ - System.ComponentModel.Primitives - System.ComponentModel.Primitives $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.ComponentModel.TypeConverter/Directory.Build.props b/src/libraries/System.ComponentModel.TypeConverter/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/Directory.Build.props +++ b/src/libraries/System.ComponentModel.TypeConverter/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj index f4869cbbb261..dfdb2e989362 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj @@ -1,7 +1,5 @@ - System.ComponentModel.TypeConverter - System.ComponentModel.TypeConverter true true $(NetCoreAppCurrent) diff --git a/src/libraries/System.ComponentModel/Directory.Build.props b/src/libraries/System.ComponentModel/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.ComponentModel/Directory.Build.props +++ b/src/libraries/System.ComponentModel/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj b/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj index fcaa643da271..5b0195df044a 100644 --- a/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj +++ b/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj @@ -1,7 +1,5 @@ - System.ComponentModel - System.ComponentModel true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj b/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj index a39f3494bb05..999ec09ad8fc 100644 --- a/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj +++ b/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj @@ -1,8 +1,6 @@ - System.Composition.AttributedModel - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -19,7 +17,4 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Composition.AttributedModel/tests/System.Composition.AttributeModel.Tests.csproj b/src/libraries/System.Composition.AttributedModel/tests/System.Composition.AttributeModel.Tests.csproj index 45d5ed3df29f..b10127ed9daa 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/System.Composition.AttributeModel.Tests.csproj +++ b/src/libraries/System.Composition.AttributedModel/tests/System.Composition.AttributeModel.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -15,4 +15,10 @@ + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj b/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj index eed8dbc7d09c..f954e1930f70 100644 --- a/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj +++ b/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj @@ -1,11 +1,6 @@ - System.Composition.Convention - - - - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -26,10 +21,6 @@ Link="Common\System\Composition\Diagnostics\TraceWriter.cs" /> - - - - - + \ No newline at end of file diff --git a/src/libraries/System.Composition.Convention/tests/System.Composition.Convention.Tests.csproj b/src/libraries/System.Composition.Convention/tests/System.Composition.Convention.Tests.csproj index 376dc6bc76e7..9474efba0b95 100644 --- a/src/libraries/System.Composition.Convention/tests/System.Composition.Convention.Tests.csproj +++ b/src/libraries/System.Composition.Convention/tests/System.Composition.Convention.Tests.csproj @@ -1,7 +1,6 @@ - System.Composition.Convention.Tests - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -16,4 +15,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj index 23a9f0f48769..09ae2efdf032 100644 --- a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj +++ b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj @@ -1,11 +1,6 @@ - System.Composition.Hosting - - - - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -36,12 +31,9 @@ - + - - - \ No newline at end of file diff --git a/src/libraries/System.Composition.Hosting/tests/System.Composition.Hosting.Tests.csproj b/src/libraries/System.Composition.Hosting/tests/System.Composition.Hosting.Tests.csproj index 3d7e2480f351..931a211e1518 100644 --- a/src/libraries/System.Composition.Hosting/tests/System.Composition.Hosting.Tests.csproj +++ b/src/libraries/System.Composition.Hosting/tests/System.Composition.Hosting.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -12,4 +12,10 @@ + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj index 25aab756fed3..cdd6654321fe 100644 --- a/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj +++ b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj @@ -1,9 +1,7 @@ System.Composition - System.Composition.Runtime - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -14,9 +12,4 @@ - - - - - \ No newline at end of file diff --git a/src/libraries/System.Composition.Runtime/tests/System.Composition.Runtime.Tests.csproj b/src/libraries/System.Composition.Runtime/tests/System.Composition.Runtime.Tests.csproj index 8270d6438106..83e64920c6c6 100644 --- a/src/libraries/System.Composition.Runtime/tests/System.Composition.Runtime.Tests.csproj +++ b/src/libraries/System.Composition.Runtime/tests/System.Composition.Runtime.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -10,4 +10,10 @@ + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj index 2d6a799248f5..7294633de7eb 100644 --- a/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj +++ b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj @@ -1,9 +1,7 @@ System.Composition - System.Composition.TypedParts - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -31,12 +29,8 @@ Link="Common\System\Numerics\Hashing\HashHelpers.cs" /> - - - - - - - + + + \ No newline at end of file diff --git a/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj b/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj index b2a05265bb1e..5701c13ee3fb 100644 --- a/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj +++ b/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -8,4 +8,12 @@ Link="Common\System\Diagnostics\DebuggerAttributes.cs" /> + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition/tests/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj b/src/libraries/System.Composition/tests/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj index 83405db26224..13c75ae1df6f 100644 --- a/src/libraries/System.Composition/tests/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj +++ b/src/libraries/System.Composition/tests/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj @@ -1,7 +1,6 @@ - Microsoft.Composition.Demos.ExtendedCollectionImports - netstandard2.0;$(NetFrameworkCurrent) + netstandard2.0;net461 @@ -10,4 +9,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Composition/tests/System.Composition.Tests.csproj b/src/libraries/System.Composition/tests/System.Composition.Tests.csproj index 412844950a7a..2eace5fc8d2a 100644 --- a/src/libraries/System.Composition/tests/System.Composition.Tests.csproj +++ b/src/libraries/System.Composition/tests/System.Composition.Tests.csproj @@ -1,8 +1,7 @@ System.Composition.Lightweight.UnitTests - System.Composition.Tests - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -36,7 +35,11 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Composition/tests/TestLibrary/TestLibrary.csproj b/src/libraries/System.Composition/tests/TestLibrary/TestLibrary.csproj index dd2b89535774..bc524e4f37f4 100644 --- a/src/libraries/System.Composition/tests/TestLibrary/TestLibrary.csproj +++ b/src/libraries/System.Composition/tests/TestLibrary/TestLibrary.csproj @@ -1,8 +1,11 @@ - netstandard2.0;$(NetFrameworkCurrent) + netstandard2.0;net461 + + + \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj index d4a6743c1415..4adc0b2edb5f 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj @@ -1,8 +1,7 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) + netstandard2.0;net461 $(NoWarn);CS0618 - true @@ -15,11 +14,6 @@ - - - - - \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 2d71eb3b7e37..574ed1ed3739 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -251,15 +250,10 @@ Link="Common\System\IO\TempFileCollection.cs" /> - - + + - - - - - diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index e4572e3663fc..555d37eb2cb3 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -4,7 +4,7 @@ true true true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net461 + + + + + + diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/TypeUtilTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/TypeUtilTests.cs index 52da2e86daa7..d9420fb1c037 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/TypeUtilTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/TypeUtilTests.cs @@ -46,15 +46,12 @@ public void GetType_NoAssemblyQualifcation(string typeString, Type expectedType) [Theory, // ConfigurationManager types roll forward + // ConfigurationManager isn't part of the shared framework and potentially app-local. + // https://github.com/dotnet/runtime/issues/12376#issuecomment-479670104 explains why testing the type roll forward behavior doesn't work in such cases. InlineData( "System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", - typeof(UserSettingsGroup)), - // Mono doesn't care about the versioning here and will resolve the type back - InlineData( - "System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=255.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", - null) + typeof(UserSettingsGroup)) ] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38351", TestRuntimes.Mono)] public void GetType_ConfigurationManagerTypes(string typeString, Type expectedType) { Assert.Equal(expectedType, TypeUtil.GetType(typeString, throwOnError: false)); diff --git a/src/libraries/System.Console/Directory.Build.props b/src/libraries/System.Console/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Console/Directory.Build.props +++ b/src/libraries/System.Console/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Data.Common/Directory.Build.props b/src/libraries/System.Data.Common/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Data.Common/Directory.Build.props +++ b/src/libraries/System.Data.Common/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Data.Common/src/System.Data.Common.csproj b/src/libraries/System.Data.Common/src/System.Data.Common.csproj index a872f6cefe45..5e445cebc31d 100644 --- a/src/libraries/System.Data.Common/src/System.Data.Common.csproj +++ b/src/libraries/System.Data.Common/src/System.Data.Common.csproj @@ -1,6 +1,5 @@ - System.Data.Common true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj index 75ae4978aa7c..3eff311a0a4b 100644 --- a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj +++ b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj @@ -119,6 +119,7 @@ + diff --git a/src/libraries/System.Data.DataSetExtensions/Directory.Build.props b/src/libraries/System.Data.DataSetExtensions/Directory.Build.props index 46a67e8e6034..bfb6ea882438 100644 --- a/src/libraries/System.Data.DataSetExtensions/Directory.Build.props +++ b/src/libraries/System.Data.DataSetExtensions/Directory.Build.props @@ -4,6 +4,5 @@ 4.0.0.0 ECMA - true diff --git a/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj b/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj index 03a9ccaaf1a7..e777c148ed64 100644 --- a/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj +++ b/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj @@ -1,6 +1,5 @@ - System.Data.DataSetExtensions $(NetCoreAppCurrent) true diff --git a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj index 1aa56e780adb..dec34df2a0f8 100644 --- a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj @@ -1,6 +1,6 @@ - netstandard2.0;$(NetFrameworkCurrent);net461 + netstandard2.0;net461 @@ -9,9 +9,4 @@ - - - - - \ No newline at end of file diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index 0592f1dd00be..8efc6e4c3553 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent);netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent);netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;netstandard2.0;net461-Windows_NT true - true $(NoWarn);CA2249 @@ -126,12 +125,16 @@ - - - + + + System.Data.Odbc.OdbcMetaData.xml + + + + - - + @@ -148,10 +151,9 @@ + - - @@ -160,18 +162,13 @@ - - - - + - - - System.Data.Odbc.OdbcMetaData.xml - + + - - + + diff --git a/src/libraries/System.Data.Odbc/tests/OdbcParameterTests.cs b/src/libraries/System.Data.Odbc/tests/OdbcParameterTests.cs index 0264246c1a80..369bd2a07b60 100644 --- a/src/libraries/System.Data.Odbc/tests/OdbcParameterTests.cs +++ b/src/libraries/System.Data.Odbc/tests/OdbcParameterTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Data.SqlClient; using System.Text; using Xunit; diff --git a/src/libraries/System.Data.Odbc/tests/System.Data.Odbc.Tests.csproj b/src/libraries/System.Data.Odbc/tests/System.Data.Odbc.Tests.csproj index 95c97d667a0a..208f6a4ab831 100644 --- a/src/libraries/System.Data.Odbc/tests/System.Data.Odbc.Tests.csproj +++ b/src/libraries/System.Data.Odbc/tests/System.Data.Odbc.Tests.csproj @@ -1,7 +1,7 @@ $(DefineConstants);TargetsWindows - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;net461-Windows_NT @@ -39,4 +39,7 @@ + + + diff --git a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj index 445fc32cff3d..44d08a1f18d0 100644 --- a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 $(NoWarn);0618 @@ -13,9 +12,6 @@ - - - diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj index 1ab198757c5d..815959031dba 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -1,8 +1,7 @@ true - netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT true @@ -96,15 +95,11 @@ System.Data.OleDb.OleDbMetaData.xml - - - - - - - - - - + + + + + + diff --git a/src/libraries/System.Data.OleDb/tests/System.Data.OleDb.Tests.csproj b/src/libraries/System.Data.OleDb/tests/System.Data.OleDb.Tests.csproj index 268d99b2c716..d4874a8727ff 100644 --- a/src/libraries/System.Data.OleDb/tests/System.Data.OleDb.Tests.csproj +++ b/src/libraries/System.Data.OleDb/tests/System.Data.OleDb.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT @@ -12,4 +12,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Contracts/Directory.Build.props b/src/libraries/System.Diagnostics.Contracts/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Diagnostics.Contracts/Directory.Build.props +++ b/src/libraries/System.Diagnostics.Contracts/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Diagnostics.Contracts/src/System.Diagnostics.Contracts.csproj b/src/libraries/System.Diagnostics.Contracts/src/System.Diagnostics.Contracts.csproj index 2e459ec3a069..dd3dc2940a54 100644 --- a/src/libraries/System.Diagnostics.Contracts/src/System.Diagnostics.Contracts.csproj +++ b/src/libraries/System.Diagnostics.Contracts/src/System.Diagnostics.Contracts.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.Contracts true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Diagnostics.Debug/Directory.Build.props b/src/libraries/System.Diagnostics.Debug/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.Debug/Directory.Build.props +++ b/src/libraries/System.Diagnostics.Debug/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Debug/src/System.Diagnostics.Debug.csproj b/src/libraries/System.Diagnostics.Debug/src/System.Diagnostics.Debug.csproj index b7a84d2aed17..dd3dc2940a54 100644 --- a/src/libraries/System.Diagnostics.Debug/src/System.Diagnostics.Debug.csproj +++ b/src/libraries/System.Diagnostics.Debug/src/System.Diagnostics.Debug.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.Debug true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Diagnostics.Debug/tests/System.Diagnostics.Debug.Tests.csproj b/src/libraries/System.Diagnostics.Debug/tests/System.Diagnostics.Debug.Tests.csproj index 4d90da957da2..96893aa3faa2 100644 --- a/src/libraries/System.Diagnostics.Debug/tests/System.Diagnostics.Debug.Tests.csproj +++ b/src/libraries/System.Diagnostics.Debug/tests/System.Diagnostics.Debug.Tests.csproj @@ -3,15 +3,16 @@ System.Diagnostics.Tests true None - $(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix true - - - - - + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/Directory.Build.props b/src/libraries/System.Diagnostics.DiagnosticSource/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/Directory.Build.props +++ b/src/libraries/System.Diagnostics.DiagnosticSource/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj index 1766bbf56253..e34e24c6fbf3 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj @@ -1,9 +1,9 @@ - netstandard2.0;netstandard1.1;netstandard1.3;net45;$(NetFrameworkCurrent) - true + netstandard2.0;netstandard1.1;netstandard1.3;net45 false enable + true @@ -15,21 +15,9 @@ - + - - - - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 0745b28f5a95..275bebeb1fec 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -4,8 +4,8 @@ false $(NoWarn);SA1205 enable - $(NetCoreAppCurrent);netstandard1.1;netstandard1.3;net45;net46;netstandard2.0;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard1.1;netstandard1.3;net45;net46;netstandard2.0 + true @@ -45,8 +45,6 @@ - - @@ -60,8 +58,6 @@ - - @@ -78,26 +74,24 @@ + + - + + + - - - - - - - - + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj index d06639f76f9c..8cc016a37866 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent);net48-Windows_NT @@ -18,4 +18,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.csproj index 4a6216abc116..3413c45fda3e 100644 --- a/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.csproj @@ -1,6 +1,6 @@ - $(NetFrameworkCurrent);net461;netstandard2.0 + netstandard2.0;net461 @@ -11,13 +11,6 @@ - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj index db056eb6bf98..42937d19fb58 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;net461;netstandard2.0;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;net461;netstandard2.0 true - true @@ -99,14 +98,11 @@ - - - - - - + + + - @@ -121,12 +117,13 @@ - - + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.EventLog/tests/System.Diagnostics.EventLog.Tests.csproj b/src/libraries/System.Diagnostics.EventLog/tests/System.Diagnostics.EventLog.Tests.csproj index efb0b608cbcd..8ebc945c1214 100644 --- a/src/libraries/System.Diagnostics.EventLog/tests/System.Diagnostics.EventLog.Tests.csproj +++ b/src/libraries/System.Diagnostics.EventLog/tests/System.Diagnostics.EventLog.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net461 @@ -22,4 +22,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/Directory.Build.props b/src/libraries/System.Diagnostics.FileVersionInfo/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/Directory.Build.props +++ b/src/libraries/System.Diagnostics.FileVersionInfo/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj b/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj index e2c079b60206..06ae2e9836a5 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj +++ b/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.FileVersionInfo true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) enable @@ -47,8 +46,7 @@ - - + diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj index 74112e70a896..2067fee50c59 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj +++ b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj @@ -1,7 +1,6 @@ Exe - .dll false $(NetCoreAppCurrent) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/ref/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/ref/System.Diagnostics.PerformanceCounter.csproj index d7a3700fc963..7a9aa75f8c3e 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/ref/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/ref/System.Diagnostics.PerformanceCounter.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) + netstandard2.0;net461 true @@ -10,9 +10,4 @@ - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj index 5c19edbe2729..225439e49732 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj @@ -1,10 +1,8 @@ - AnyCPU true - $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;netstandard2.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;netstandard2.0;net461 true - true @@ -123,20 +121,16 @@ - - - - - - - + + + + - @@ -148,9 +142,12 @@ - + + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/System.Diagnostics.PerformanceCounter.Tests.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/tests/System.Diagnostics.PerformanceCounter.Tests.csproj index 18c5796f93d2..0ddd69a7a648 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/System.Diagnostics.PerformanceCounter.Tests.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/System.Diagnostics.PerformanceCounter.Tests.csproj @@ -1,8 +1,7 @@ - provider.res true - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net461 @@ -18,9 +17,10 @@ - - Always - + + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Process/Directory.Build.props b/src/libraries/System.Diagnostics.Process/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Diagnostics.Process/Directory.Build.props +++ b/src/libraries/System.Diagnostics.Process/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index 7c759f49f81a..947d0f2a1bb0 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -1,6 +1,5 @@ - AnyCPU $(DefineConstants);FEATURE_REGISTRY true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent);$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS @@ -325,8 +324,8 @@ + - diff --git a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj index 83b129811ed2..091c18cdbb75 100644 --- a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj +++ b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj @@ -18,7 +18,6 @@ - @@ -39,9 +38,14 @@ Link="System\PasteArguments.Windows.cs" /> + + + + + diff --git a/src/libraries/System.Diagnostics.StackTrace/Directory.Build.props b/src/libraries/System.Diagnostics.StackTrace/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.StackTrace/Directory.Build.props +++ b/src/libraries/System.Diagnostics.StackTrace/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj b/src/libraries/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj index 0b3dadaa19cf..4c218b7212f8 100644 --- a/src/libraries/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj +++ b/src/libraries/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.StackTrace true true enable @@ -23,15 +22,13 @@ - - - - - - - - + + + + + + diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/Directory.Build.props b/src/libraries/System.Diagnostics.TextWriterTraceListener/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/Directory.Build.props +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Tools/Directory.Build.props b/src/libraries/System.Diagnostics.Tools/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.Tools/Directory.Build.props +++ b/src/libraries/System.Diagnostics.Tools/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Tools/src/System.Diagnostics.Tools.csproj b/src/libraries/System.Diagnostics.Tools/src/System.Diagnostics.Tools.csproj index 7e813184ea81..4f2d15aa3b6a 100644 --- a/src/libraries/System.Diagnostics.Tools/src/System.Diagnostics.Tools.csproj +++ b/src/libraries/System.Diagnostics.Tools/src/System.Diagnostics.Tools.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.Tools true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Diagnostics.TraceSource/Directory.Build.props b/src/libraries/System.Diagnostics.TraceSource/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.TraceSource/Directory.Build.props +++ b/src/libraries/System.Diagnostics.TraceSource/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj index 7baa10ff2bb9..7b62f85f073b 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj @@ -28,17 +28,15 @@ - - - - - - - - - - + + + + + + + + diff --git a/src/libraries/System.Diagnostics.Tracing/Directory.Build.props b/src/libraries/System.Diagnostics.Tracing/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Diagnostics.Tracing/Directory.Build.props +++ b/src/libraries/System.Diagnostics.Tracing/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Tracing/src/System.Diagnostics.Tracing.csproj b/src/libraries/System.Diagnostics.Tracing/src/System.Diagnostics.Tracing.csproj index bae87cb23cbb..dd3dc2940a54 100644 --- a/src/libraries/System.Diagnostics.Tracing/src/System.Diagnostics.Tracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing/src/System.Diagnostics.Tracing.csproj @@ -1,6 +1,5 @@ - System.Diagnostics.Tracing true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj index 04288a7c8775..adbd9aecb521 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj @@ -3,7 +3,7 @@ true $(DefineConstants);FLAVOR_WHIDBEY;PAPI_AD;PAPI_REGSAM;USE_CTX_CACHE true - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT true $(NoWarn);CA2249 @@ -91,24 +91,26 @@ Link="Common\Interop\Windows\Advapi32\Interop.LookupAccountSid.cs" /> - - - - - - - + + + + + + + + @@ -119,7 +121,4 @@ - - - diff --git a/src/libraries/System.DirectoryServices.AccountManagement/tests/System.DirectoryServices.AccountManagement.Tests.csproj b/src/libraries/System.DirectoryServices.AccountManagement/tests/System.DirectoryServices.AccountManagement.Tests.csproj index f896e5f1babd..ff681406c78e 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/tests/System.DirectoryServices.AccountManagement.Tests.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/tests/System.DirectoryServices.AccountManagement.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net48 @@ -18,4 +18,14 @@ PreserveNewest + + + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index 8ac014eba2d5..c37e4da51fa4 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -2,7 +2,7 @@ true true - $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;$(NetCoreAppCurrent)-OSX;netcoreapp2.0-OSX;$(NetCoreAppCurrent)-Linux;netcoreapp2.0-Linux;netstandard2.0;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;$(NetCoreAppCurrent)-OSX;netcoreapp2.0-OSX;$(NetCoreAppCurrent)-Linux;netcoreapp2.0-Linux;netstandard2.0 true @@ -81,13 +81,13 @@ - - + + @@ -103,7 +103,4 @@ - - - diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj index 682e1a9711a7..1175b1d42159 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;net48 @@ -56,4 +56,12 @@ PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj index 3df27100b060..68593ef6e13e 100644 --- a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj @@ -1,6 +1,6 @@ - netstandard2.0;_$(NetFrameworkCurrent) + netstandard2.0 diff --git a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj index fcbbc47ff8df..fe5b6232d96a 100644 --- a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT true @@ -137,18 +137,18 @@ + + + + + + - - - - - - diff --git a/src/libraries/System.DirectoryServices/tests/System.DirectoryServices.Tests.csproj b/src/libraries/System.DirectoryServices/tests/System.DirectoryServices.Tests.csproj index 53be1a5cb23a..f71b684f686b 100644 --- a/src/libraries/System.DirectoryServices/tests/System.DirectoryServices.Tests.csproj +++ b/src/libraries/System.DirectoryServices/tests/System.DirectoryServices.Tests.csproj @@ -2,7 +2,7 @@ $(NoWarn);SYSLIB0003 - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net48 @@ -31,4 +31,10 @@ + + + + + + diff --git a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj index 0a20f1221511..a2a362564252 100644 --- a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -347,10 +347,11 @@ placeholder.ico - + + + - diff --git a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj index 0b1354728a10..5537f87099e4 100644 --- a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj +++ b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj @@ -2,8 +2,7 @@ true true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;net48 @@ -106,4 +105,10 @@ System.Drawing.Tests.Icon_toolboxBitmapAttributeTest + + + + + + diff --git a/src/libraries/System.Drawing.Primitives/Directory.Build.props b/src/libraries/System.Drawing.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Drawing.Primitives/Directory.Build.props +++ b/src/libraries/System.Drawing.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj index be4e03afc744..fd17cd2352c3 100644 --- a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj +++ b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj @@ -1,21 +1,10 @@ - Library System.Drawing - System.Drawing.Primitives $(DefineConstants);FEATURE_WINDOWS_SYSTEM_COLORS $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) enable - - - - - - - - - @@ -46,4 +35,13 @@ + + + + + + + + + diff --git a/src/libraries/System.Dynamic.Runtime/Directory.Build.props b/src/libraries/System.Dynamic.Runtime/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Dynamic.Runtime/Directory.Build.props +++ b/src/libraries/System.Dynamic.Runtime/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Dynamic.Runtime/src/System.Dynamic.Runtime.csproj b/src/libraries/System.Dynamic.Runtime/src/System.Dynamic.Runtime.csproj index 2fb5c055bf30..152b87d25dd6 100644 --- a/src/libraries/System.Dynamic.Runtime/src/System.Dynamic.Runtime.csproj +++ b/src/libraries/System.Dynamic.Runtime/src/System.Dynamic.Runtime.csproj @@ -1,7 +1,5 @@ - System.Dynamic.Runtime - System.Dynamic.Runtime true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Formats.Asn1/Directory.Build.props b/src/libraries/System.Formats.Asn1/Directory.Build.props index 749d7fc1c6b5..ba1f965d83ca 100644 --- a/src/libraries/System.Formats.Asn1/Directory.Build.props +++ b/src/libraries/System.Formats.Asn1/Directory.Build.props @@ -2,6 +2,5 @@ Open - true diff --git a/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.csproj b/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.csproj index 7715f692f9c0..ee0ebfbfe104 100644 --- a/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.csproj +++ b/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.csproj @@ -1,12 +1,12 @@ - netstandard2.0 + netstandard2.0;net461 enable - + diff --git a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj index 501a4f5ad368..f9fdc8c95a08 100644 --- a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj +++ b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj @@ -2,8 +2,7 @@ true enable - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -48,13 +47,11 @@ - - + + - - - + diff --git a/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj b/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj index beb4397ba6c5..1c4965e48777 100644 --- a/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj +++ b/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj @@ -1,7 +1,7 @@  true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -52,4 +52,8 @@ CommonTest\System\Security\Cryptography\ByteUtils.cs + + + + diff --git a/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.csproj b/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.csproj index db6640ae50f7..574a834fd1ed 100644 --- a/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.csproj +++ b/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.csproj @@ -7,7 +7,7 @@ - - + + diff --git a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj index f1c45bd8a8e5..e72dd108eeeb 100644 --- a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj +++ b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj @@ -29,4 +29,7 @@ + + + diff --git a/src/libraries/System.Globalization.Calendars/Directory.Build.props b/src/libraries/System.Globalization.Calendars/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Globalization.Calendars/Directory.Build.props +++ b/src/libraries/System.Globalization.Calendars/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Globalization.Calendars/src/System.Globalization.Calendars.csproj b/src/libraries/System.Globalization.Calendars/src/System.Globalization.Calendars.csproj index c251f69ea9e3..4f2d15aa3b6a 100644 --- a/src/libraries/System.Globalization.Calendars/src/System.Globalization.Calendars.csproj +++ b/src/libraries/System.Globalization.Calendars/src/System.Globalization.Calendars.csproj @@ -1,6 +1,5 @@ - System.Globalization.Calendars true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Globalization.Extensions/Directory.Build.props b/src/libraries/System.Globalization.Extensions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Globalization.Extensions/Directory.Build.props +++ b/src/libraries/System.Globalization.Extensions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Globalization/Directory.Build.props b/src/libraries/System.Globalization/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Globalization/Directory.Build.props +++ b/src/libraries/System.Globalization/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Globalization/src/System.Globalization.csproj b/src/libraries/System.Globalization/src/System.Globalization.csproj index 4dacec6ff437..4f2d15aa3b6a 100644 --- a/src/libraries/System.Globalization/src/System.Globalization.csproj +++ b/src/libraries/System.Globalization/src/System.Globalization.csproj @@ -1,6 +1,5 @@ - System.Globalization true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.IO.Compression.Brotli/Directory.Build.props b/src/libraries/System.IO.Compression.Brotli/Directory.Build.props index aa25926ea66c..8cda5782c1d1 100644 --- a/src/libraries/System.IO.Compression.Brotli/Directory.Build.props +++ b/src/libraries/System.IO.Compression.Brotli/Directory.Build.props @@ -2,6 +2,5 @@ ECMA - true \ No newline at end of file diff --git a/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj b/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj index 40101d08ad98..bdb837e5ef95 100644 --- a/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj +++ b/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj @@ -1,7 +1,5 @@ - System.IO.Compression.Brotli - Library true enable $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) diff --git a/src/libraries/System.IO.Compression.ZipFile/Directory.Build.props b/src/libraries/System.IO.Compression.ZipFile/Directory.Build.props index aa25926ea66c..8cda5782c1d1 100644 --- a/src/libraries/System.IO.Compression.ZipFile/Directory.Build.props +++ b/src/libraries/System.IO.Compression.ZipFile/Directory.Build.props @@ -2,6 +2,5 @@ ECMA - true \ No newline at end of file diff --git a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj index ca1e0b343502..366de34f8b92 100644 --- a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj +++ b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj @@ -1,6 +1,5 @@ - System.IO.Compression.ZipFile true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.IO.Compression/Directory.Build.props b/src/libraries/System.IO.Compression/Directory.Build.props index aa25926ea66c..8cda5782c1d1 100644 --- a/src/libraries/System.IO.Compression/Directory.Build.props +++ b/src/libraries/System.IO.Compression/Directory.Build.props @@ -2,6 +2,5 @@ ECMA - true \ No newline at end of file diff --git a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj index 8ec233ee5dec..e22bba9c0c10 100644 --- a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj +++ b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj @@ -1,7 +1,5 @@ - System.IO.Compression - Library true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable diff --git a/src/libraries/System.IO.FileSystem.AccessControl/Directory.Build.props b/src/libraries/System.IO.FileSystem.AccessControl/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/Directory.Build.props +++ b/src/libraries/System.IO.FileSystem.AccessControl/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem.AccessControl/ref/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/ref/System.IO.FileSystem.AccessControl.csproj index ed7f15c6b990..33c93c6d8195 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/ref/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/ref/System.IO.FileSystem.AccessControl.csproj @@ -1,7 +1,6 @@ - netstandard2.0;$(NetFrameworkCurrent);net461 - true + netstandard2.0;net461 enable @@ -11,9 +10,6 @@ - - - diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index 3d496a69c3f2..e7f893498e48 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netstandard2.0-Windows_NT;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netstandard2.0-Windows_NT;net461-Windows_NT true - true enable @@ -99,27 +98,26 @@ - - - - - - - + + + - - - - - + + + + - - + + + + + + diff --git a/src/libraries/System.IO.FileSystem.AccessControl/tests/System.IO.FileSystem.AccessControl.Tests.csproj b/src/libraries/System.IO.FileSystem.AccessControl/tests/System.IO.FileSystem.AccessControl.Tests.csproj index 2130178404f3..663ab486f555 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/tests/System.IO.FileSystem.AccessControl.Tests.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/tests/System.IO.FileSystem.AccessControl.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT @@ -14,4 +14,13 @@ + + + + + + + + + diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/Directory.Build.props b/src/libraries/System.IO.FileSystem.DriveInfo/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/Directory.Build.props +++ b/src/libraries/System.IO.FileSystem.DriveInfo/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem.Primitives/Directory.Build.props b/src/libraries/System.IO.FileSystem.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.IO.FileSystem.Primitives/Directory.Build.props +++ b/src/libraries/System.IO.FileSystem.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem.Primitives/src/System.IO.FileSystem.Primitives.csproj b/src/libraries/System.IO.FileSystem.Primitives/src/System.IO.FileSystem.Primitives.csproj index 3297291a2953..94d0c6401304 100644 --- a/src/libraries/System.IO.FileSystem.Primitives/src/System.IO.FileSystem.Primitives.csproj +++ b/src/libraries/System.IO.FileSystem.Primitives/src/System.IO.FileSystem.Primitives.csproj @@ -1,6 +1,5 @@ - System.IO.FileSystem.Primitives true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.IO.FileSystem.Watcher/Directory.Build.props b/src/libraries/System.IO.FileSystem.Watcher/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/Directory.Build.props +++ b/src/libraries/System.IO.FileSystem.Watcher/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem/Directory.Build.props b/src/libraries/System.IO.FileSystem/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.IO.FileSystem/Directory.Build.props +++ b/src/libraries/System.IO.FileSystem/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj b/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj index 827969b02813..0c36fbf8b216 100644 --- a/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj +++ b/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj @@ -1,6 +1,5 @@ - System.IO.FileSystem true true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser diff --git a/src/libraries/System.IO.IsolatedStorage/Directory.Build.props b/src/libraries/System.IO.IsolatedStorage/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.IO.IsolatedStorage/Directory.Build.props +++ b/src/libraries/System.IO.IsolatedStorage/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj index 75bb5e2176c7..066018d64f7c 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj +++ b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj @@ -36,8 +36,8 @@ - - - + + + diff --git a/src/libraries/System.IO.IsolatedStorage/tests/System.IO.IsolatedStorage.Tests.csproj b/src/libraries/System.IO.IsolatedStorage/tests/System.IO.IsolatedStorage.Tests.csproj index 47504a43fde6..57f315d88506 100644 --- a/src/libraries/System.IO.IsolatedStorage/tests/System.IO.IsolatedStorage.Tests.csproj +++ b/src/libraries/System.IO.IsolatedStorage/tests/System.IO.IsolatedStorage.Tests.csproj @@ -52,4 +52,7 @@ + + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/Directory.Build.props b/src/libraries/System.IO.MemoryMappedFiles/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/Directory.Build.props +++ b/src/libraries/System.IO.MemoryMappedFiles/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj index 587c80451114..875e392be708 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj +++ b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj @@ -1,6 +1,5 @@ - System.IO.MemoryMappedFiles true enable $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser diff --git a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj index 56941538f8b0..bb30574d28d8 100644 --- a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj +++ b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj @@ -1,7 +1,6 @@ - netstandard2.0;netstandard1.3;net46;$(NetFrameworkCurrent) - true + netstandard2.0;netstandard1.3;net46 @@ -15,15 +14,7 @@ - - - + - - - - - - \ No newline at end of file diff --git a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj index 44240d763755..d8d6ce3f3da3 100644 --- a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj +++ b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj @@ -1,8 +1,7 @@ true - netstandard2.0;net46;netstandard1.3;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0;net46;netstandard1.3 enable @@ -10,22 +9,6 @@ $(DefineConstants);FEATURE_SERIALIZATION true - - - - - - - - - - - - - - - - @@ -57,7 +40,6 @@ - \ No newline at end of file diff --git a/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj b/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj index 611983cc55b0..41d84a259611 100644 --- a/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj +++ b/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj @@ -1,11 +1,15 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48-Windows_NT + + + + \ No newline at end of file diff --git a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj index 2af41b5283fb..a038d3552d1f 100644 --- a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj +++ b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj @@ -1,7 +1,8 @@ - netstandard2.0 + netstandard2.0;net461 enable + true netcoreapp2.0 @@ -10,8 +11,8 @@ - - - + + + diff --git a/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj b/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj index 545a857a9515..f5e9a5531f5e 100644 --- a/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj +++ b/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj @@ -1,7 +1,6 @@ - $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461 true enable @@ -46,11 +45,14 @@ - - - + + + + - + diff --git a/src/libraries/System.IO.Pipelines/tests/System.IO.Pipelines.Tests.csproj b/src/libraries/System.IO.Pipelines/tests/System.IO.Pipelines.Tests.csproj index 0e9b268811fc..5c0a2a305f4f 100644 --- a/src/libraries/System.IO.Pipelines/tests/System.IO.Pipelines.Tests.csproj +++ b/src/libraries/System.IO.Pipelines/tests/System.IO.Pipelines.Tests.csproj @@ -1,13 +1,8 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 - - - - - @@ -49,4 +44,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.IO.Pipes.AccessControl/Directory.Build.props b/src/libraries/System.IO.Pipes.AccessControl/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/Directory.Build.props +++ b/src/libraries/System.IO.Pipes.AccessControl/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj index aa09673b2ed7..81ac8d687ca3 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj +++ b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj @@ -1,25 +1,26 @@ - System.IO.Pipes.AccessControl - false - true - true - SR.PlatformNotSupported_AccessControl - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) enable + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) + + SR.PlatformNotSupported_AccessControl + true + true - - - + + + + + + + - - diff --git a/src/libraries/System.IO.Pipes.AccessControl/tests/System.IO.Pipes.AccessControl.Tests.csproj b/src/libraries/System.IO.Pipes.AccessControl/tests/System.IO.Pipes.AccessControl.Tests.csproj index 21202e86f0e7..57015e7b6788 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/tests/System.IO.Pipes.AccessControl.Tests.csproj +++ b/src/libraries/System.IO.Pipes.AccessControl/tests/System.IO.Pipes.AccessControl.Tests.csproj @@ -15,4 +15,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.IO.Pipes/Directory.Build.props b/src/libraries/System.IO.Pipes/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.IO.Pipes/Directory.Build.props +++ b/src/libraries/System.IO.Pipes/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj index becae30a11a9..2016c93b4c04 100644 --- a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj @@ -1,6 +1,5 @@ - System.IO.Pipes true true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) @@ -183,10 +182,11 @@ - + + + + - - diff --git a/src/libraries/System.IO.Pipes/tests/System.IO.Pipes.Tests.csproj b/src/libraries/System.IO.Pipes/tests/System.IO.Pipes.Tests.csproj index d3759ed22d1c..ead46c1faaa2 100644 --- a/src/libraries/System.IO.Pipes/tests/System.IO.Pipes.Tests.csproj +++ b/src/libraries/System.IO.Pipes/tests/System.IO.Pipes.Tests.csproj @@ -59,4 +59,8 @@ + + + + diff --git a/src/libraries/System.IO.Ports/ref/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/ref/System.IO.Ports.csproj index fba4e13b9047..bb26f9be9a08 100644 --- a/src/libraries/System.IO.Ports/ref/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/ref/System.IO.Ports.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -10,8 +9,4 @@ - - - - \ No newline at end of file diff --git a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj index 307aa3bf4b45..595800abe838 100644 --- a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj @@ -4,8 +4,7 @@ $(DefineConstants);NOSPAN;SERIAL_PORTS true annotations - netstandard2.0-Windows_NT;netstandard2.0-Linux;netstandard2.0-OSX;netstandard2.0;net461-Windows_NT;netstandard2.0-FreeBSD;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;netstandard2.0-Linux;netstandard2.0-OSX;netstandard2.0;net461-Windows_NT;netstandard2.0-FreeBSD @@ -134,28 +133,8 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/libraries/System.IO.Ports/tests/System.IO.Ports.Tests.csproj b/src/libraries/System.IO.Ports/tests/System.IO.Ports.Tests.csproj index 67de446f5471..d0797175561f 100644 --- a/src/libraries/System.IO.Ports/tests/System.IO.Ports.Tests.csproj +++ b/src/libraries/System.IO.Ports/tests/System.IO.Ports.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-FreeBSD;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-FreeBSD;net461-Windows_NT @@ -117,4 +117,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.IO.UnmanagedMemoryStream/Directory.Build.props b/src/libraries/System.IO.UnmanagedMemoryStream/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.IO.UnmanagedMemoryStream/Directory.Build.props +++ b/src/libraries/System.IO.UnmanagedMemoryStream/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.IO.UnmanagedMemoryStream/src/System.IO.UnmanagedMemoryStream.csproj b/src/libraries/System.IO.UnmanagedMemoryStream/src/System.IO.UnmanagedMemoryStream.csproj index af6feb105785..4f2d15aa3b6a 100644 --- a/src/libraries/System.IO.UnmanagedMemoryStream/src/System.IO.UnmanagedMemoryStream.csproj +++ b/src/libraries/System.IO.UnmanagedMemoryStream/src/System.IO.UnmanagedMemoryStream.csproj @@ -1,6 +1,5 @@ - System.IO.UnmanagedMemoryStream true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.IO/Directory.Build.props b/src/libraries/System.IO/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.IO/Directory.Build.props +++ b/src/libraries/System.IO/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.IO/src/System.IO.csproj b/src/libraries/System.IO/src/System.IO.csproj index d7effb020f5c..3b108d682676 100644 --- a/src/libraries/System.IO/src/System.IO.csproj +++ b/src/libraries/System.IO/src/System.IO.csproj @@ -1,6 +1,5 @@ - System.IO true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Linq.Expressions/Directory.Build.props b/src/libraries/System.Linq.Expressions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Linq.Expressions/Directory.Build.props +++ b/src/libraries/System.Linq.Expressions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj index 07d0cebd1746..7972cdb54f1f 100644 --- a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj +++ b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj @@ -3,8 +3,6 @@ true $(NetCoreAppCurrent) enable - - false $(DefineConstants);FEATURE_DLG_INVOKE;FEATURE_FAST_CREATE $(DefineConstants);FEATURE_COMPILE diff --git a/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj b/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj index 48bc8a57cc68..ea477dc9d04e 100644 --- a/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj +++ b/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj @@ -6,10 +6,6 @@ $(DefineConstants);FEATURE_INTERPRET $(NetCoreAppCurrent) - - - - @@ -246,5 +242,6 @@ + diff --git a/src/libraries/System.Linq.Parallel/Directory.Build.props b/src/libraries/System.Linq.Parallel/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Linq.Parallel/Directory.Build.props +++ b/src/libraries/System.Linq.Parallel/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj index f2c2c5627ed0..c04ba4bf4e38 100644 --- a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj +++ b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj @@ -1,6 +1,5 @@ - System.Linq.Parallel true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Linq.Queryable/Directory.Build.props b/src/libraries/System.Linq.Queryable/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Linq.Queryable/Directory.Build.props +++ b/src/libraries/System.Linq.Queryable/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj index a531c2e84940..d3def1d1063a 100644 --- a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj +++ b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj @@ -1,7 +1,5 @@ - System.Linq.Queryable - System.Linq.Queryable $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Linq/Directory.Build.props b/src/libraries/System.Linq/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Linq/Directory.Build.props +++ b/src/libraries/System.Linq/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Linq/src/System.Linq.csproj b/src/libraries/System.Linq/src/System.Linq.csproj index a9caa2e36d3e..ea585685f3e6 100644 --- a/src/libraries/System.Linq/src/System.Linq.csproj +++ b/src/libraries/System.Linq/src/System.Linq.csproj @@ -1,15 +1,8 @@ - System.Linq - System.Linq $(NetCoreAppCurrent) enable - - - $(NetCoreAppCurrent) - - diff --git a/src/libraries/System.Management/src/System.Management.csproj b/src/libraries/System.Management/src/System.Management.csproj index ac50cd7a9b1b..c91da1b9c5b6 100644 --- a/src/libraries/System.Management/src/System.Management.csproj +++ b/src/libraries/System.Management/src/System.Management.csproj @@ -3,7 +3,7 @@ true $(NoWarn);0618 true - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT true @@ -60,11 +60,11 @@ - - - + + + diff --git a/src/libraries/System.Management/tests/System.Management.Tests.csproj b/src/libraries/System.Management/tests/System.Management.Tests.csproj index d71c4999db1a..dfa032993bcd 100644 --- a/src/libraries/System.Management/tests/System.Management.Tests.csproj +++ b/src/libraries/System.Management/tests/System.Management.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;net48 @@ -23,4 +23,10 @@ CleanUp.mof + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Memory/Directory.Build.props b/src/libraries/System.Memory/Directory.Build.props index 749d7fc1c6b5..ba1f965d83ca 100644 --- a/src/libraries/System.Memory/Directory.Build.props +++ b/src/libraries/System.Memory/Directory.Build.props @@ -2,6 +2,5 @@ Open - true diff --git a/src/libraries/System.Memory/tests/System.Memory.Tests.csproj b/src/libraries/System.Memory/tests/System.Memory.Tests.csproj index 1b310ee36a43..d0508aaa6c78 100644 --- a/src/libraries/System.Memory/tests/System.Memory.Tests.csproj +++ b/src/libraries/System.Memory/tests/System.Memory.Tests.csproj @@ -1,7 +1,6 @@ true - true true true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Net.Http.Json/Directory.Build.props b/src/libraries/System.Net.Http.Json/Directory.Build.props index 749d7fc1c6b5..ba1f965d83ca 100644 --- a/src/libraries/System.Net.Http.Json/Directory.Build.props +++ b/src/libraries/System.Net.Http.Json/Directory.Build.props @@ -2,6 +2,5 @@ Open - true diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj index af8add8a69fa..37e96e45e225 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);netstandard2.0 + $(NetCoreAppCurrent);netstandard2.0;net461 enable @@ -15,4 +15,7 @@ + + + diff --git a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj index ee6e5c6a9af4..031e3a30153c 100644 --- a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj @@ -1,13 +1,8 @@ - netstandard2.0;$(NetCoreAppCurrent);net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 enable - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) - @@ -18,26 +13,31 @@ - - - - - + - - + + + + + + + + + + + - - diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj index 2653fcb9dc52..81605d947b36 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/System.Net.Http.Json.Functional.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 @@ -29,4 +29,8 @@ + + + + diff --git a/src/libraries/System.Net.Http.Json/tests/UnitTests/System.Net.Http.Json.Unit.Tests.csproj b/src/libraries/System.Net.Http.Json/tests/UnitTests/System.Net.Http.Json.Unit.Tests.csproj index 0f09eb18d9f7..0997a1c96f77 100644 --- a/src/libraries/System.Net.Http.Json/tests/UnitTests/System.Net.Http.Json.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http.Json/tests/UnitTests/System.Net.Http.Json.Unit.Tests.csproj @@ -1,12 +1,12 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 - + @@ -16,4 +16,7 @@ + + + diff --git a/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj index 69bfc2c5a79b..806d5504734c 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj @@ -1,19 +1,12 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 enable - - - $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\;$(AssemblySearchPaths) - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index 8c06bc26a682..e29dc793e5e5 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -1,9 +1,7 @@ - AnyCPU true - netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT true $(DefineConstants);WINHTTPHANDLER_DLL enable @@ -87,14 +85,10 @@ Link="Common\System\Net\Logging\NetEventSource.Common.cs" /> - - - + + - - - diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj index 98985ef8fc34..b1dbc739244a 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net48-Windows_NT true $(DefineConstants);WINHTTPHANDLER_TEST 8.0 @@ -141,5 +141,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj index 502c0cc8e46e..2471fc4aeee5 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj @@ -8,7 +8,7 @@ annotations - + Microsoft - true \ No newline at end of file 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 e6c23001804d..62a033499f44 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -1,7 +1,5 @@ - Library - System.Net.Http win true $(DefineConstants);HTTP_DLL @@ -666,6 +664,7 @@ + @@ -691,20 +690,22 @@ - + - + + + PreserveNewest diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index 01fafd5a6ff7..dc5bc00ef6ad 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -281,12 +281,13 @@ - - - SelectedSitesTest.txt + + + + \ No newline at end of file diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 9ca98181f81f..cde8ce72f86e 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -8,8 +8,8 @@ - - + + Open - true true \ No newline at end of file diff --git a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj index 8f6ce68838a6..dfcacc7b6656 100644 --- a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj +++ b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj @@ -6,6 +6,7 @@ annotations + @@ -28,14 +29,10 @@ - - - - diff --git a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj index ea16d78ce8d3..9da20596f814 100644 --- a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj +++ b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj @@ -27,7 +27,4 @@ - - - diff --git a/src/libraries/System.Net.Mail/Directory.Build.props b/src/libraries/System.Net.Mail/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Net.Mail/Directory.Build.props +++ b/src/libraries/System.Net.Mail/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file 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 766dc25eab7d..73db7cf4eb50 100644 --- a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj +++ b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj @@ -225,6 +225,7 @@ Link="Common\Interop\Windows\SspiCli\SSPIWrapper.cs" /> + @@ -244,10 +245,6 @@ - - - - diff --git a/src/libraries/System.Net.Mail/tests/Functional/System.Net.Mail.Functional.Tests.csproj b/src/libraries/System.Net.Mail/tests/Functional/System.Net.Mail.Functional.Tests.csproj index 9ceee73590e4..83bb83a34f4d 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/System.Net.Mail.Functional.Tests.csproj +++ b/src/libraries/System.Net.Mail/tests/Functional/System.Net.Mail.Functional.Tests.csproj @@ -31,7 +31,4 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj b/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj index 6b9e7bd1dfa4..be49fc3e0072 100644 --- a/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj +++ b/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj @@ -23,10 +23,6 @@ - - - - @@ -264,4 +260,9 @@ + + + + + diff --git a/src/libraries/System.Net.NameResolution/Directory.Build.props b/src/libraries/System.Net.NameResolution/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.NameResolution/Directory.Build.props +++ b/src/libraries/System.Net.NameResolution/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ 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 73f80add914c..27f4e9570af9 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -1,6 +1,5 @@ - System.Net.NameResolution true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable @@ -113,6 +112,7 @@ + @@ -123,7 +123,6 @@ - diff --git a/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj b/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj index 66a902b68b37..3d260d337f6c 100644 --- a/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj +++ b/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj @@ -8,7 +8,7 @@ - + - + Microsoft - true \ No newline at end of file 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 5360c88d8995..3bb0644d9947 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj +++ b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj @@ -1,7 +1,5 @@ - System.Net.NetworkInformation - Library true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-FreeBSD enable @@ -193,6 +191,7 @@ + @@ -203,7 +202,6 @@ - diff --git a/src/libraries/System.Net.Ping/Directory.Build.props b/src/libraries/System.Net.Ping/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.Ping/Directory.Build.props +++ b/src/libraries/System.Net.Ping/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ 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 b64a73e871a0..b817ebac3ef9 100644 --- a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj +++ b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj @@ -1,6 +1,5 @@ - System.Net.Ping true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable diff --git a/src/libraries/System.Net.Primitives/Directory.Build.props b/src/libraries/System.Net.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.Primitives/Directory.Build.props +++ b/src/libraries/System.Net.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index cfc1e85797bb..07f176ab3ad6 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -1,7 +1,5 @@ - System.Net.Primitives - Library true false $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj b/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj index 7dca1982f9e4..26cd2568e157 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj @@ -27,7 +27,4 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj index 212d2de6287e..26647c83c7f1 100644 --- a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj +++ b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj @@ -11,7 +11,7 @@ - + - + diff --git a/src/libraries/System.Net.Requests/Directory.Build.props b/src/libraries/System.Net.Requests/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.Requests/Directory.Build.props +++ b/src/libraries/System.Net.Requests/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj index 9db098574bbd..96471eef5eb5 100644 --- a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj +++ b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj @@ -1,7 +1,5 @@ - System.Net.Requests - System.Net.Requests true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable @@ -85,6 +83,7 @@ + @@ -103,7 +102,6 @@ - diff --git a/src/libraries/System.Net.Security/Directory.Build.props b/src/libraries/System.Net.Security/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.Security/Directory.Build.props +++ b/src/libraries/System.Net.Security/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.csproj b/src/libraries/System.Net.Security/ref/System.Net.Security.csproj index 6e4bace9eb56..f5519a69b602 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.csproj @@ -9,12 +9,10 @@ + - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 1c423af89c5e..25be34b5258c 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -1,6 +1,5 @@ - System.Net.Security true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS @@ -345,6 +344,7 @@ + @@ -361,15 +361,14 @@ - + - diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 3845b272ae6a..84bada8bc9ff 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -108,5 +108,6 @@ + diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 8379fd48c479..1d83e45035d6 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -76,11 +76,4 @@ - - - - - - - - + \ No newline at end of file diff --git a/src/libraries/System.Net.ServicePoint/Directory.Build.props b/src/libraries/System.Net.ServicePoint/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Net.ServicePoint/Directory.Build.props +++ b/src/libraries/System.Net.ServicePoint/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Net.Sockets/Directory.Build.props b/src/libraries/System.Net.Sockets/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Net.Sockets/Directory.Build.props +++ b/src/libraries/System.Net.Sockets/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file 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 ac3e781f745b..3d4d3c791e27 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -1,6 +1,5 @@ - System.Net.Sockets true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable @@ -302,6 +301,7 @@ Link="Common\Interop\Unix\System.Native\Interop.Write.cs" /> + @@ -315,7 +315,6 @@ - diff --git a/src/libraries/System.Net.WebClient/Directory.Build.props b/src/libraries/System.Net.WebClient/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Net.WebClient/Directory.Build.props +++ b/src/libraries/System.Net.WebClient/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Net.WebHeaderCollection/Directory.Build.props b/src/libraries/System.Net.WebHeaderCollection/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.WebHeaderCollection/Directory.Build.props +++ b/src/libraries/System.Net.WebHeaderCollection/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj b/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj index d97d8456081b..3d060d6ebc3c 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj +++ b/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj @@ -1,6 +1,5 @@ - System.Net.WebHeaderCollection true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Net.WebProxy/Directory.Build.props b/src/libraries/System.Net.WebProxy/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Net.WebProxy/Directory.Build.props +++ b/src/libraries/System.Net.WebProxy/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Net.WebSockets.Client/Directory.Build.props b/src/libraries/System.Net.WebSockets.Client/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.WebSockets.Client/Directory.Build.props +++ b/src/libraries/System.Net.WebSockets.Client/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj index 413be9b039fd..248546468d0f 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj @@ -6,7 +6,7 @@ - + - netstandard2.0 + netstandard2.0;net461 enable - + \ No newline at end of file diff --git a/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj b/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj index 189e51596d37..092e7a753fab 100644 --- a/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj +++ b/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj @@ -1,9 +1,7 @@ - System.Net.WebSockets.WebSocketProtocol True - $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.1;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.1;net461 true enable @@ -21,27 +19,30 @@ - - - + - - + + + - - - + + + + + diff --git a/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/System.Net.WebSockets.WebSocketProtocol.Tests.csproj b/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/System.Net.WebSockets.WebSocketProtocol.Tests.csproj index eb4d89c4de15..16b078941bfc 100644 --- a/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/System.Net.WebSockets.WebSocketProtocol.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/System.Net.WebSockets.WebSocketProtocol.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 + + + diff --git a/src/libraries/System.Net.WebSockets/Directory.Build.props b/src/libraries/System.Net.WebSockets/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Net.WebSockets/Directory.Build.props +++ b/src/libraries/System.Net.WebSockets/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj index c39977d00644..212dea7f6eb9 100644 --- a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj +++ b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj @@ -1,6 +1,5 @@ - System.Net.WebSockets True $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj index 3bffad18351b..c3ce692b4dfe 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj @@ -1,22 +1,12 @@ - netstandard2.0;netstandard1.1 + netstandard2.0;netstandard1.1;net461 enable - - - - true - - - - - - - + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index b9e1821c6d4f..655b63c27655 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -1,8 +1,7 @@ true - netstandard2.0;netstandard1.1;net461;$(NetFrameworkCurrent) - true + netstandard2.0;netstandard1.1;net461 enable @@ -19,18 +18,6 @@ - - - - - - - - - - - - - + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj index ecbee2462914..669b0084f4ab 100644 --- a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj @@ -1,9 +1,7 @@ - True - $(NetCoreAppCurrent) - - + true + $(NetCoreAppCurrent);net461 @@ -34,8 +32,7 @@ - - + diff --git a/src/libraries/System.Numerics.Vectors/Directory.Build.props b/src/libraries/System.Numerics.Vectors/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Numerics.Vectors/Directory.Build.props +++ b/src/libraries/System.Numerics.Vectors/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ObjectModel/Directory.Build.props b/src/libraries/System.ObjectModel/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.ObjectModel/Directory.Build.props +++ b/src/libraries/System.ObjectModel/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj index b531e567ae7c..89776eac649a 100644 --- a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj +++ b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj @@ -1,6 +1,5 @@ - System.ObjectModel true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Private.DataContractSerialization/Directory.Build.props b/src/libraries/System.Private.DataContractSerialization/Directory.Build.props index 8c72c62fd593..63f02a0f817e 100644 --- a/src/libraries/System.Private.DataContractSerialization/Directory.Build.props +++ b/src/libraries/System.Private.DataContractSerialization/Directory.Build.props @@ -2,7 +2,5 @@ Microsoft - true - false \ No newline at end of file diff --git a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj index 2252cd2cdc12..7ab4ab7cd8d0 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj +++ b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj @@ -1,7 +1,5 @@ - System.Private.DataContractSerialization - System.Private.DataContractSerialization $(NoWarn);1634;1691;649 true true diff --git a/src/libraries/System.Private.Uri/Directory.Build.props b/src/libraries/System.Private.Uri/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Private.Uri/Directory.Build.props +++ b/src/libraries/System.Private.Uri/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj b/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj index a639777cb800..731f081a11eb 100644 --- a/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj +++ b/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj @@ -1,6 +1,5 @@ - System.Private.Uri true enable $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) diff --git a/src/libraries/System.Private.Xml.Linq/Directory.Build.props b/src/libraries/System.Private.Xml.Linq/Directory.Build.props index 05cc2bde64e5..bdcfca3b543c 100644 --- a/src/libraries/System.Private.Xml.Linq/Directory.Build.props +++ b/src/libraries/System.Private.Xml.Linq/Directory.Build.props @@ -2,7 +2,5 @@ Open - true - false \ No newline at end of file diff --git a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj index a24010636c27..4db38b8700d2 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj +++ b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj @@ -1,11 +1,9 @@ - System.Private.Xml.Linq System.Xml $(NetCoreAppCurrent) - + diff --git a/src/libraries/System.Private.Xml/Directory.Build.props b/src/libraries/System.Private.Xml/Directory.Build.props index 05cc2bde64e5..bdcfca3b543c 100644 --- a/src/libraries/System.Private.Xml/Directory.Build.props +++ b/src/libraries/System.Private.Xml/Directory.Build.props @@ -2,7 +2,5 @@ Open - true - false \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj index 01dcb093e6e2..c3b7f512fce2 100644 --- a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj +++ b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj @@ -1,6 +1,5 @@ - System.Private.Xml System.Xml true $(DefineConstants);FEATURE_COMPILED_XSL diff --git a/src/libraries/System.Private.Xml/tests/Writers/XmlWriterApi/System.Xml.RW.XmlWriterApi.Tests.csproj b/src/libraries/System.Private.Xml/tests/Writers/XmlWriterApi/System.Xml.RW.XmlWriterApi.Tests.csproj index 3e6c23049796..66a1626bfe18 100644 --- a/src/libraries/System.Private.Xml/tests/Writers/XmlWriterApi/System.Xml.RW.XmlWriterApi.Tests.csproj +++ b/src/libraries/System.Private.Xml/tests/Writers/XmlWriterApi/System.Xml.RW.XmlWriterApi.Tests.csproj @@ -38,11 +38,9 @@ - + - - - + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Context/ref/System.Reflection.Context.csproj b/src/libraries/System.Reflection.Context/ref/System.Reflection.Context.csproj index 7381fb80af83..4bce12a35227 100644 --- a/src/libraries/System.Reflection.Context/ref/System.Reflection.Context.csproj +++ b/src/libraries/System.Reflection.Context/ref/System.Reflection.Context.csproj @@ -10,8 +10,4 @@ - - - - \ No newline at end of file diff --git a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj index ea0fb7407b34..8ca7664c3e26 100644 --- a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj +++ b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj @@ -1,6 +1,6 @@ - netstandard2.0;netstandard1.1;netstandard2.1 + netstandard2.1;netstandard2.0;netstandard1.1 enable @@ -64,9 +64,4 @@ - - - - - \ No newline at end of file diff --git a/src/libraries/System.Reflection.Context/tests/System.Reflection.Context.Tests.csproj b/src/libraries/System.Reflection.Context/tests/System.Reflection.Context.Tests.csproj index c405873f4ebd..490b4b0a011f 100644 --- a/src/libraries/System.Reflection.Context/tests/System.Reflection.Context.Tests.csproj +++ b/src/libraries/System.Reflection.Context/tests/System.Reflection.Context.Tests.csproj @@ -25,4 +25,7 @@ Designer + + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.DispatchProxy/Directory.Build.props b/src/libraries/System.Reflection.DispatchProxy/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection.DispatchProxy/Directory.Build.props +++ b/src/libraries/System.Reflection.DispatchProxy/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/Directory.Build.props b/src/libraries/System.Reflection.Emit.ILGeneration/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/Directory.Build.props +++ b/src/libraries/System.Reflection.Emit.ILGeneration/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/src/System.Reflection.Emit.ILGeneration.csproj b/src/libraries/System.Reflection.Emit.ILGeneration/src/System.Reflection.Emit.ILGeneration.csproj index 7294575b536b..4f2d15aa3b6a 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/src/System.Reflection.Emit.ILGeneration.csproj +++ b/src/libraries/System.Reflection.Emit.ILGeneration/src/System.Reflection.Emit.ILGeneration.csproj @@ -1,6 +1,5 @@ - System.Reflection.Emit.ILGeneration true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Reflection.Emit.Lightweight/Directory.Build.props b/src/libraries/System.Reflection.Emit.Lightweight/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/Directory.Build.props +++ b/src/libraries/System.Reflection.Emit.Lightweight/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Reflection.Emit.Lightweight/src/System.Reflection.Emit.Lightweight.csproj b/src/libraries/System.Reflection.Emit.Lightweight/src/System.Reflection.Emit.Lightweight.csproj index 2747800b8775..4f2d15aa3b6a 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/src/System.Reflection.Emit.Lightweight.csproj +++ b/src/libraries/System.Reflection.Emit.Lightweight/src/System.Reflection.Emit.Lightweight.csproj @@ -1,6 +1,5 @@ - System.Reflection.Emit.Lightweight true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Reflection.Emit/Directory.Build.props b/src/libraries/System.Reflection.Emit/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Reflection.Emit/Directory.Build.props +++ b/src/libraries/System.Reflection.Emit/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Reflection.Extensions/Directory.Build.props b/src/libraries/System.Reflection.Extensions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection.Extensions/Directory.Build.props +++ b/src/libraries/System.Reflection.Extensions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection.Extensions/src/System.Reflection.Extensions.csproj b/src/libraries/System.Reflection.Extensions/src/System.Reflection.Extensions.csproj index 5c08b886e3e9..94d0c6401304 100644 --- a/src/libraries/System.Reflection.Extensions/src/System.Reflection.Extensions.csproj +++ b/src/libraries/System.Reflection.Extensions/src/System.Reflection.Extensions.csproj @@ -1,6 +1,5 @@ - System.Reflection.Extensions true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Reflection.Metadata/Directory.Build.props b/src/libraries/System.Reflection.Metadata/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection.Metadata/Directory.Build.props +++ b/src/libraries/System.Reflection.Metadata/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.csproj index 33546830d98f..d3f3c661e77f 100644 --- a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.csproj @@ -2,8 +2,7 @@ true false - $(NetCoreAppCurrent);netstandard1.1;netstandard2.0 - true + $(NetCoreAppCurrent);netstandard1.1;netstandard2.0;net461 enable @@ -14,11 +13,11 @@ + - - - - + + + diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index 80692bdfc3a8..2417558b7857 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -3,8 +3,7 @@ true en-US false - $(NetCoreAppCurrent);netstandard1.1;netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard1.1;netstandard2.0;net461 true enable @@ -249,9 +248,9 @@ - - + + @@ -266,12 +265,10 @@ - - + + - - - - + + diff --git a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj index e3d82ffed0a3..7d2de986909a 100644 --- a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj +++ b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj @@ -3,7 +3,7 @@ true false 436 - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 - - + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.MetadataLoadContext/ref/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/ref/System.Reflection.MetadataLoadContext.csproj index aceadd0d97dd..c065d83b357a 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/ref/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/ref/System.Reflection.MetadataLoadContext.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0;net461 enable diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj index 006e205f072b..7e70cb22fd65 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj @@ -3,8 +3,7 @@ System.Reflection true - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 true enable @@ -146,7 +145,8 @@ - + @@ -160,9 +160,10 @@ - - - - + + + + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj index be8b471a6eca..68a69ab158b7 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 $(NoWarn);SYSLIB0005 @@ -71,4 +71,7 @@ + + + diff --git a/src/libraries/System.Reflection.Primitives/Directory.Build.props b/src/libraries/System.Reflection.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection.Primitives/Directory.Build.props +++ b/src/libraries/System.Reflection.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection.Primitives/src/System.Reflection.Primitives.csproj b/src/libraries/System.Reflection.Primitives/src/System.Reflection.Primitives.csproj index 5c3faa57e4aa..dd3dc2940a54 100644 --- a/src/libraries/System.Reflection.Primitives/src/System.Reflection.Primitives.csproj +++ b/src/libraries/System.Reflection.Primitives/src/System.Reflection.Primitives.csproj @@ -1,6 +1,5 @@ - System.Reflection.Primitives true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Reflection.TypeExtensions/Directory.Build.props b/src/libraries/System.Reflection.TypeExtensions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection.TypeExtensions/Directory.Build.props +++ b/src/libraries/System.Reflection.TypeExtensions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection.TypeExtensions/src/System.Reflection.TypeExtensions.csproj b/src/libraries/System.Reflection.TypeExtensions/src/System.Reflection.TypeExtensions.csproj index 058466cbef43..8668954a3efb 100644 --- a/src/libraries/System.Reflection.TypeExtensions/src/System.Reflection.TypeExtensions.csproj +++ b/src/libraries/System.Reflection.TypeExtensions/src/System.Reflection.TypeExtensions.csproj @@ -1,6 +1,5 @@ - System.Reflection.TypeExtensions true enable $(NetCoreAppCurrent) diff --git a/src/libraries/System.Reflection/Directory.Build.props b/src/libraries/System.Reflection/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Reflection/Directory.Build.props +++ b/src/libraries/System.Reflection/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Reflection/src/System.Reflection.csproj b/src/libraries/System.Reflection/src/System.Reflection.csproj index dff84ed49963..4f2d15aa3b6a 100644 --- a/src/libraries/System.Reflection/src/System.Reflection.csproj +++ b/src/libraries/System.Reflection/src/System.Reflection.csproj @@ -1,6 +1,5 @@ - System.Reflection true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Resources.Extensions/ref/System.Resources.Extensions.csproj b/src/libraries/System.Resources.Extensions/ref/System.Resources.Extensions.csproj index 7b32ba82d118..2be35155d6da 100644 --- a/src/libraries/System.Resources.Extensions/ref/System.Resources.Extensions.csproj +++ b/src/libraries/System.Resources.Extensions/ref/System.Resources.Extensions.csproj @@ -1,8 +1,6 @@ - netstandard2.0 - - + netstandard2.0;net461 diff --git a/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj b/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj index 00a7a46104f0..d4d12186c561 100644 --- a/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj +++ b/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj @@ -1,13 +1,10 @@ true - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 $(DefineConstants);RESOURCES_EXTENSIONS annotations - - @@ -31,11 +28,7 @@ Link="System\Numerics\Hashing\HashHelpers.cs" /> - - - - - + diff --git a/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj b/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj index 8bed771d6512..b48848c7a454 100644 --- a/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj +++ b/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;net461 true @@ -16,7 +16,16 @@ + + + + + + + + + diff --git a/src/libraries/System.Resources.Reader/Directory.Build.props b/src/libraries/System.Resources.Reader/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Resources.Reader/Directory.Build.props +++ b/src/libraries/System.Resources.Reader/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Resources.Reader/src/System.Resources.Reader.csproj b/src/libraries/System.Resources.Reader/src/System.Resources.Reader.csproj index 041d99ec9bd1..81ff3cda55d8 100644 --- a/src/libraries/System.Resources.Reader/src/System.Resources.Reader.csproj +++ b/src/libraries/System.Resources.Reader/src/System.Resources.Reader.csproj @@ -1,6 +1,5 @@ - System.Resources.Reader System.Resources true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Resources.ResourceManager/Directory.Build.props b/src/libraries/System.Resources.ResourceManager/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Resources.ResourceManager/Directory.Build.props +++ b/src/libraries/System.Resources.ResourceManager/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj b/src/libraries/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj index 61a965e9a83b..4f2d15aa3b6a 100644 --- a/src/libraries/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj +++ b/src/libraries/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj @@ -1,6 +1,5 @@ - System.Resources.ResourceManager true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Resources.ResourceManager/tests/System.Resources.ResourceManager.Tests.csproj b/src/libraries/System.Resources.ResourceManager/tests/System.Resources.ResourceManager.Tests.csproj index 90486ca2aea7..e049d6d494ca 100644 --- a/src/libraries/System.Resources.ResourceManager/tests/System.Resources.ResourceManager.Tests.csproj +++ b/src/libraries/System.Resources.ResourceManager/tests/System.Resources.ResourceManager.Tests.csproj @@ -4,7 +4,7 @@ true true true - $(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix @@ -56,6 +56,9 @@ CopyToOutputDirectory="PreserveNewest" Visible="false" /> + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/System.Runtime.CompilerServices.Unsafe.Tests.csproj b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/System.Runtime.CompilerServices.Unsafe.Tests.csproj index 4fc905dec87c..8852455f7829 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/System.Runtime.CompilerServices.Unsafe.Tests.csproj +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/System.Runtime.CompilerServices.Unsafe.Tests.csproj @@ -1,9 +1,12 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/Directory.Build.props b/src/libraries/System.Runtime.CompilerServices.VisualC/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/Directory.Build.props +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj b/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj index 2b8596cf8d90..d0ca0d4c3203 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj @@ -1,6 +1,5 @@ - System.Runtime.CompilerServices.VisualC enable true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Runtime.Extensions/Directory.Build.props b/src/libraries/System.Runtime.Extensions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Extensions/Directory.Build.props +++ b/src/libraries/System.Runtime.Extensions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj b/src/libraries/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj index 1501be79fa89..b6029a4baee6 100644 --- a/src/libraries/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj +++ b/src/libraries/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj @@ -1,16 +1,12 @@ - System.Runtime.Extensions - Library true $(NetCoreAppCurrent) enable - - - - + + diff --git a/src/libraries/System.Runtime.Handles/Directory.Build.props b/src/libraries/System.Runtime.Handles/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Handles/Directory.Build.props +++ b/src/libraries/System.Runtime.Handles/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Handles/src/System.Runtime.Handles.csproj b/src/libraries/System.Runtime.Handles/src/System.Runtime.Handles.csproj index 48cc45350aaf..94d0c6401304 100644 --- a/src/libraries/System.Runtime.Handles/src/System.Runtime.Handles.csproj +++ b/src/libraries/System.Runtime.Handles/src/System.Runtime.Handles.csproj @@ -1,6 +1,5 @@ - System.Runtime.Handles true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props b/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true 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 5d43a5781c2d..c5455ea87f81 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 @@ -1,6 +1,5 @@ - System.Runtime.InteropServices.JavaScript true enable $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj index 0bb06264f93e..0ee941723584 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj @@ -1,13 +1,13 @@ true - $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-Browser true - + @@ -16,4 +16,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/Directory.Build.props b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/Directory.Build.props +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/Directory.Build.props b/src/libraries/System.Runtime.InteropServices/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Runtime.InteropServices/Directory.Build.props +++ b/src/libraries/System.Runtime.InteropServices/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj b/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj index 213c5439847d..d1eeee845aa2 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj +++ b/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj @@ -1,7 +1,5 @@ - System.Runtime.InteropServices - Library true enable $(NetCoreAppCurrent) diff --git a/src/libraries/System.Runtime.Intrinsics/Directory.Build.props b/src/libraries/System.Runtime.Intrinsics/Directory.Build.props index 9f52a8a30505..ba1f965d83ca 100644 --- a/src/libraries/System.Runtime.Intrinsics/Directory.Build.props +++ b/src/libraries/System.Runtime.Intrinsics/Directory.Build.props @@ -1,7 +1,6 @@  - true Open diff --git a/src/libraries/System.Runtime.Loader/Directory.Build.props b/src/libraries/System.Runtime.Loader/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Runtime.Loader/Directory.Build.props +++ b/src/libraries/System.Runtime.Loader/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Runtime.Loader/src/System.Runtime.Loader.csproj b/src/libraries/System.Runtime.Loader/src/System.Runtime.Loader.csproj index 2697388749b0..dd3dc2940a54 100644 --- a/src/libraries/System.Runtime.Loader/src/System.Runtime.Loader.csproj +++ b/src/libraries/System.Runtime.Loader/src/System.Runtime.Loader.csproj @@ -1,6 +1,5 @@ - System.Runtime.Loader true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj index 17348b2b70e9..861551441fc2 100644 --- a/src/libraries/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj @@ -9,11 +9,10 @@ - - false - content - PreserveNewest - + diff --git a/src/libraries/System.Runtime.Loader/tests/RefEmitLoadContext/System.Runtime.Loader.RefEmitLoadContext.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/RefEmitLoadContext/System.Runtime.Loader.RefEmitLoadContext.Tests.csproj index 5fe8fb3bc7b4..f1580207d39c 100644 --- a/src/libraries/System.Runtime.Loader/tests/RefEmitLoadContext/System.Runtime.Loader.RefEmitLoadContext.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/RefEmitLoadContext/System.Runtime.Loader.RefEmitLoadContext.Tests.csproj @@ -7,10 +7,9 @@ - - false - content - PreserveNewest - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Numerics/Directory.Build.props b/src/libraries/System.Runtime.Numerics/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Numerics/Directory.Build.props +++ b/src/libraries/System.Runtime.Numerics/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj index 52ae4fe33fc9..7e938de2925e 100644 --- a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj +++ b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj @@ -1,7 +1,6 @@ System.Numerics - System.Runtime.Numerics true enable $(NetCoreAppCurrent) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/Directory.Build.props b/src/libraries/System.Runtime.Serialization.Formatters/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/Directory.Build.props +++ b/src/libraries/System.Runtime.Serialization.Formatters/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj index 6dd50fdba5e2..dba845f2eeb9 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj @@ -1,7 +1,5 @@ - System.Runtime.Serialization.Formatters - System.Runtime.Serialization.Formatters $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser enable @@ -76,10 +74,10 @@ - - - - - + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterServicesTests.Windows.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterServicesTests.Windows.cs index 8dd3da0bbdc5..a64cab793e98 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterServicesTests.Windows.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterServicesTests.Windows.cs @@ -11,6 +11,7 @@ namespace System.Runtime.Serialization.Formatters.Tests public partial class FormatterServicesTests { [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39704", TestRuntimes.Mono)] public void GetUninitializedObject_COMObject_ThrowsNotSupportedException() { Type comObjectType = typeof(COMObject); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj b/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj index 635709d50421..7e37cb04eed7 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj @@ -2,7 +2,7 @@ true true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;net48 @@ -29,14 +29,38 @@ - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Json/Directory.Build.props b/src/libraries/System.Runtime.Serialization.Json/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Runtime.Serialization.Json/Directory.Build.props +++ b/src/libraries/System.Runtime.Serialization.Json/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj b/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj index 42818f089790..59304bfd403e 100644 --- a/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj +++ b/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj @@ -1,13 +1,10 @@ - System.Runtime.Serialization.Json true $(NetCoreAppCurrent) - - \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Primitives/Directory.Build.props b/src/libraries/System.Runtime.Serialization.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/Directory.Build.props +++ b/src/libraries/System.Runtime.Serialization.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj index adf56d49ade1..e314354aef4a 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj +++ b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj @@ -1,7 +1,5 @@ - System.Runtime.Serialization.Primitives - System.Runtime.Serialization.Primitives true enable $(NetCoreAppCurrent) diff --git a/src/libraries/System.Runtime.Serialization.Xml/Directory.Build.props b/src/libraries/System.Runtime.Serialization.Xml/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/Directory.Build.props +++ b/src/libraries/System.Runtime.Serialization.Xml/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj b/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj index 9763bac66722..4c211819d418 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj @@ -1,13 +1,10 @@ - System.Runtime.Serialization.Xml true $(NetCoreAppCurrent) - - - + diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj index c7ff1d9518f2..320a4c93973d 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj @@ -66,4 +66,8 @@ Always + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/ReflectionOnly/System.Runtime.Serialization.Xml.ReflectionOnly.Tests.csproj b/src/libraries/System.Runtime.Serialization.Xml/tests/ReflectionOnly/System.Runtime.Serialization.Xml.ReflectionOnly.Tests.csproj index 96a02163e070..e62c8b7f82d8 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/ReflectionOnly/System.Runtime.Serialization.Xml.ReflectionOnly.Tests.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/ReflectionOnly/System.Runtime.Serialization.Xml.ReflectionOnly.Tests.csproj @@ -45,4 +45,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/System.Runtime.Serialization.Xml.Tests.csproj b/src/libraries/System.Runtime.Serialization.Xml/tests/System.Runtime.Serialization.Xml.Tests.csproj index 5a4999f43791..3080bd813ac9 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/System.Runtime.Serialization.Xml.Tests.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/System.Runtime.Serialization.Xml.Tests.csproj @@ -30,4 +30,7 @@ + + + diff --git a/src/libraries/System.Runtime/Directory.Build.props b/src/libraries/System.Runtime/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Runtime/Directory.Build.props +++ b/src/libraries/System.Runtime/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Runtime/src/System.Runtime.csproj b/src/libraries/System.Runtime/src/System.Runtime.csproj index 79e6ec207864..6e3a18228e7e 100644 --- a/src/libraries/System.Runtime/src/System.Runtime.csproj +++ b/src/libraries/System.Runtime/src/System.Runtime.csproj @@ -1,6 +1,5 @@ - System.Runtime true $(NetCoreAppCurrent) enable @@ -12,10 +11,8 @@ - - - + diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index 39ca7313460b..eff661cba396 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -270,13 +270,14 @@ Link="Common\System\Runtime\Serialization\Formatters\BinaryFormatterHelpers.cs" /> + - - - + + + \ No newline at end of file diff --git a/src/libraries/System.Security.AccessControl/Directory.Build.props b/src/libraries/System.Security.AccessControl/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/System.Security.AccessControl/Directory.Build.props +++ b/src/libraries/System.Security.AccessControl/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.csproj b/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.csproj index d5c601747004..b586ad270537 100644 --- a/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.csproj +++ b/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard2.0;net461 true - true enable @@ -12,14 +11,11 @@ - - - - + - - + + \ No newline at end of file diff --git a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj index 5218ab9aa1ae..5da1fe7abb56 100644 --- a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj +++ b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT;netcoreapp2.0-Windows_NT;netstandard2.0;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT;netcoreapp2.0-Windows_NT;netstandard2.0 true - true enable @@ -11,9 +10,6 @@ true SR.PlatformNotSupported_AccessControl - - - @@ -82,19 +78,20 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj b/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj index 386ccc3d9052..2d5068b4dcb7 100644 --- a/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj +++ b/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj @@ -1,7 +1,6 @@ - Linux;NetBSD;OSX - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT @@ -68,4 +67,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Security.Claims/Directory.Build.props b/src/libraries/System.Security.Claims/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.Claims/Directory.Build.props +++ b/src/libraries/System.Security.Claims/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj index 2e3b10f4d024..ca146c46b5db 100644 --- a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj +++ b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj @@ -1,6 +1,5 @@ - System.Security.Claims $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Security.Cryptography.Algorithms/Directory.Build.props b/src/libraries/System.Security.Cryptography.Algorithms/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Algorithms/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj b/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj index 6dd12410eb03..c10e46d86206 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj @@ -225,4 +225,8 @@ + + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/Directory.Build.props b/src/libraries/System.Security.Cryptography.Cng/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/System.Security.Cryptography.Cng/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Cng/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj index 6650cbce60e9..5828d6872998 100644 --- a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;net461;net462;net47;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;net461;net462;net47 true - true enable @@ -17,18 +16,14 @@ - - - - - - - + + + - + diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj b/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj index 19dc0301e455..f689e3889e4d 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj @@ -2,9 +2,8 @@ true true - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);netstandard2.0;netstandard2.1;net461-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;net462-Windows_NT;net47-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);netstandard2.0;netstandard2.1;net461-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;net462-Windows_NT;net47-Windows_NT true - true enable @@ -355,18 +354,17 @@ - - - - + + + - @@ -380,4 +378,11 @@ + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj index 395f9a3db844..86112ff45cfe 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj @@ -1,7 +1,7 @@ $(DefineConstants);TESTING_CNG_IMPLEMENTATION - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net47-Windows_NT @@ -165,4 +165,8 @@ + + + + diff --git a/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props b/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj b/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj index 3f8bf0c98f0d..36b40fc20162 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj +++ b/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj @@ -1,6 +1,5 @@ - System.Security.Cryptography.Csp true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj b/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj index b37c10623638..a70488b38e81 100644 --- a/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj @@ -92,4 +92,7 @@ + + + diff --git a/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props b/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj b/src/libraries/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj index 8b57296b06ee..aaf3fc1530b2 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj +++ b/src/libraries/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj @@ -1,6 +1,5 @@ - System.Security.Cryptography.Encoding true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent);$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS enable diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props index 8c72c62fd593..63f02a0f817e 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props @@ -2,7 +2,5 @@ Microsoft - true - false \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj index 2c895046911c..1465cb0fabc9 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj @@ -1,7 +1,6 @@ - $(NetCoreAppCurrent);netcoreapp3.0;net47;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netcoreapp3.0;net47 true enable @@ -17,19 +16,15 @@ - - - + + + + - - - - - diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj index 1edf80722b5e..54ff81d2fb94 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj @@ -1,8 +1,7 @@ true - $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent);netcoreapp3.0-Unix;netcoreapp3.0;netstandard2.0;net47;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent);netcoreapp3.0-Unix;netcoreapp3.0;netstandard2.0;net47 true enable @@ -108,13 +107,14 @@ - + + - @@ -129,7 +129,10 @@ - - + + + + + diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj index 23783475d351..011e86be3859 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj @@ -1,6 +1,5 @@ - Windows_NT $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser @@ -127,4 +126,8 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs" /> + + + + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj index 07a5f1e62c22..5b42437c4fab 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj @@ -1,14 +1,13 @@ - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;net461 true - true enable true - + 4.0.4.0 @@ -16,17 +15,15 @@ - - - - - - - - + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj index 3fe54dc82832..6ecdaa9e8656 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj @@ -5,18 +5,15 @@ true $(NoWarn);CA5384 enable - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);netstandard2.0;netstandard2.0-Windows_NT;netstandard2.1;netstandard2.1-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);netstandard2.0;netstandard2.0-Windows_NT;netstandard2.1;netstandard2.1-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;net461-Windows_NT true - true true true - + 4.0.4.0 - - SR.SystemSecurityCryptographyPkcs_PlatformNotSupported @@ -318,39 +315,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -667,4 +631,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/EdgeCasesTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/EdgeCasesTests.cs index 5bf2db1c71fb..6d9458cbc7b3 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/EdgeCasesTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/EdgeCasesTests.cs @@ -309,7 +309,7 @@ public static void EnvelopedCmsNullDecode() } [Theory] -#if !NET472 +#if !NETFRAMEWORK [InlineData(true)] #endif [InlineData(false)] @@ -319,7 +319,7 @@ public static void EnvelopedCmsEmptyDecode(bool useSpan) if (useSpan) { -#if !NET472 +#if !NETFRAMEWORK Assert.ThrowsAny(() => cms.Decode(ReadOnlySpan.Empty)); #else throw new Xunit.Sdk.XunitException( @@ -502,7 +502,7 @@ public static void ContentInfoGetContentTypeNull() [Theory] [InlineData(false)] -#if !NET472 +#if !NETFRAMEWORK [InlineData(true)] #endif public static void ContentInfoGetContentTypeUnknown(bool fromSpan) @@ -512,7 +512,7 @@ public static void ContentInfoGetContentTypeUnknown(bool fromSpan) if (fromSpan) { -#if NET472 +#if NETFRAMEWORK throw new Xunit.Sdk.XunitException( "This test should not evaluate for .NET Framework, the API is missing."); #else diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs index b94d0b764273..27f46fc67ee8 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs @@ -217,7 +217,7 @@ public static void TestContentTypeSigned() [Theory] [InlineData(false)] -#if !NET472 +#if !NETFRAMEWORK [InlineData(true)] #endif public static void TestContent(bool fromSpan) @@ -238,7 +238,7 @@ public static void TestContent(bool fromSpan) if (fromSpan) { -#if !NET472 +#if !NETFRAMEWORK cms.Decode(encodedMessage.AsSpan()); #else throw new Xunit.Sdk.XunitException( diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs index a68b49eef979..8dc711c7df26 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs @@ -10,7 +10,7 @@ namespace System.Security.Cryptography.Pkcs.Tests public static class SignedCmsWholeDocumentTests { [Theory] -#if !NET472 +#if !NETFRAMEWORK [InlineData(true)] #endif [InlineData(false)] @@ -19,7 +19,7 @@ public static void ReadRsaPssDocument(bool fromSpan) SignedCms cms = new SignedCms(); if (fromSpan) { -#if !NET472 +#if !NETFRAMEWORK cms.Decode(SignedDocuments.RsaPssDocument.AsSpan()); #else throw new Xunit.Sdk.XunitException( diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj b/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj index d050b65b7044..64a3a8a6cb88 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent);net48-Windows_NT + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props b/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Primitives/src/System.Security.Cryptography.Primitives.csproj b/src/libraries/System.Security.Cryptography.Primitives/src/System.Security.Cryptography.Primitives.csproj index 13998e38436f..a75db1230a9d 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/src/System.Security.Cryptography.Primitives.csproj +++ b/src/libraries/System.Security.Cryptography.Primitives/src/System.Security.Cryptography.Primitives.csproj @@ -1,6 +1,5 @@ - System.Security.Cryptography.Primitives true true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/ref/System.Security.Cryptography.ProtectedData.csproj b/src/libraries/System.Security.Cryptography.ProtectedData/ref/System.Security.Cryptography.ProtectedData.csproj index 7cb462c9f93b..ac9410e6b68f 100644 --- a/src/libraries/System.Security.Cryptography.ProtectedData/ref/System.Security.Cryptography.ProtectedData.csproj +++ b/src/libraries/System.Security.Cryptography.ProtectedData/ref/System.Security.Cryptography.ProtectedData.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 enable @@ -12,7 +11,6 @@ - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj b/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj index 21221a5eba83..3a9ef745e2f2 100644 --- a/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj +++ b/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj @@ -1,8 +1,7 @@ true - netstandard2.0-Windows_NT;net461-Windows_NT;netstandard2.0;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;net461-Windows_NT;netstandard2.0 enable @@ -34,14 +33,9 @@ Link="Common\System\HResults.cs" /> - - - - - - - + + \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/tests/System.Security.Cryptography.ProtectedData.Tests.csproj b/src/libraries/System.Security.Cryptography.ProtectedData/tests/System.Security.Cryptography.ProtectedData.Tests.csproj index 2d90d9b44f07..acdc3f5b6583 100644 --- a/src/libraries/System.Security.Cryptography.ProtectedData/tests/System.Security.Cryptography.ProtectedData.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.ProtectedData/tests/System.Security.Cryptography.ProtectedData.Tests.csproj @@ -1,11 +1,17 @@ true - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT + + + + + + diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props b/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props index 42c6eafce67e..d68d22c1b917 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj index 8e1034901493..a62bc53a9220 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj @@ -676,12 +676,12 @@ - + + - diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj index 2f97db5e5446..c666f2f3e54c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj @@ -116,6 +116,8 @@ Link="Common\Microsoft\Win32\SafeHandles\SafeHandleCache.cs" /> + + diff --git a/src/libraries/System.Security.Cryptography.Xml/ref/System.Security.Cryptography.Xml.csproj b/src/libraries/System.Security.Cryptography.Xml/ref/System.Security.Cryptography.Xml.csproj index 43030e53132c..4d4f20e941f5 100644 --- a/src/libraries/System.Security.Cryptography.Xml/ref/System.Security.Cryptography.Xml.csproj +++ b/src/libraries/System.Security.Cryptography.Xml/ref/System.Security.Cryptography.Xml.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -11,10 +10,6 @@ - - - - diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj b/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj index d3b17b793958..5f39ed504d48 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj +++ b/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj @@ -1,8 +1,7 @@ true - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 @@ -91,32 +90,12 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + - - diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj b/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj index 9ad0a17ec742..2bfad93e7780 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -65,4 +65,10 @@ + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj index 9905b3157eef..f8b4eb6709a2 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj @@ -1,7 +1,6 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;netcoreapp3.0;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461;netcoreapp3.0 @@ -19,12 +18,8 @@ - - - - @@ -33,20 +28,23 @@ - + + + + - - - - - - - - - - - + + + + + + + + + + + @@ -62,7 +60,4 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj index 265879918e8c..d51a2ae77f46 100644 --- a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj +++ b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj @@ -1,8 +1,7 @@ true - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 @@ -187,24 +186,16 @@ - - - - - - - - - - - @@ -213,7 +204,11 @@ + + + + @@ -229,6 +224,5 @@ - diff --git a/src/libraries/System.Security.Permissions/tests/System.Security.Permissions.Tests.csproj b/src/libraries/System.Security.Permissions/tests/System.Security.Permissions.Tests.csproj index 2097721d5d4f..35536edbef15 100644 --- a/src/libraries/System.Security.Permissions/tests/System.Security.Permissions.Tests.csproj +++ b/src/libraries/System.Security.Permissions/tests/System.Security.Permissions.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Windows_NT $(NoWarn);SYSLIB0003 @@ -23,4 +23,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Security.Principal.Windows/Directory.Build.props b/src/libraries/System.Security.Principal.Windows/Directory.Build.props index 27a4a5522a27..33e65b7cb465 100644 --- a/src/libraries/System.Security.Principal.Windows/Directory.Build.props +++ b/src/libraries/System.Security.Principal.Windows/Directory.Build.props @@ -2,8 +2,6 @@ Microsoft - true - false true \ No newline at end of file diff --git a/src/libraries/System.Security.Principal.Windows/ref/System.Security.Principal.Windows.csproj b/src/libraries/System.Security.Principal.Windows/ref/System.Security.Principal.Windows.csproj index a469aff9a617..fe63b0436d4a 100644 --- a/src/libraries/System.Security.Principal.Windows/ref/System.Security.Principal.Windows.csproj +++ b/src/libraries/System.Security.Principal.Windows/ref/System.Security.Principal.Windows.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461 true - true enable @@ -12,14 +11,10 @@ - - - - - - - + + + diff --git a/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj b/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj index d4f8f3eac3d1..d8193f00625f 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj +++ b/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;netstandard2.0;netcoreapp2.0-Windows_NT;netcoreapp2.0-Unix;netcoreapp2.1-Windows_NT;netcoreapp2.1-Unix;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;netstandard2.0;netcoreapp2.0-Windows_NT;netcoreapp2.0-Unix;netcoreapp2.1-Windows_NT;netcoreapp2.1-Unix;net461-Windows_NT true - true enable @@ -135,10 +134,8 @@ - - - - + diff --git a/src/libraries/System.Security.Principal.Windows/tests/System.Security.Principal.Windows.Tests.csproj b/src/libraries/System.Security.Principal.Windows/tests/System.Security.Principal.Windows.Tests.csproj index 8a99afb50bf1..cb45482460cc 100644 --- a/src/libraries/System.Security.Principal.Windows/tests/System.Security.Principal.Windows.Tests.csproj +++ b/src/libraries/System.Security.Principal.Windows/tests/System.Security.Principal.Windows.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT @@ -15,4 +15,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Security.Principal/Directory.Build.props b/src/libraries/System.Security.Principal/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.Principal/Directory.Build.props +++ b/src/libraries/System.Security.Principal/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.Principal/src/System.Security.Principal.csproj b/src/libraries/System.Security.Principal/src/System.Security.Principal.csproj index d9b7db3e5583..4f2d15aa3b6a 100644 --- a/src/libraries/System.Security.Principal/src/System.Security.Principal.csproj +++ b/src/libraries/System.Security.Principal/src/System.Security.Principal.csproj @@ -1,6 +1,5 @@ - System.Security.Principal true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Security.SecureString/Directory.Build.props b/src/libraries/System.Security.SecureString/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Security.SecureString/Directory.Build.props +++ b/src/libraries/System.Security.SecureString/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Security.SecureString/src/System.Security.SecureString.csproj b/src/libraries/System.Security.SecureString/src/System.Security.SecureString.csproj index 7d220aa8a520..c1ef027e6f6a 100644 --- a/src/libraries/System.Security.SecureString/src/System.Security.SecureString.csproj +++ b/src/libraries/System.Security.SecureString/src/System.Security.SecureString.csproj @@ -1,7 +1,5 @@ - System.Security.SecureString - System.Security.SecureString true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj b/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj index bca4baa304a2..9c9fcf889142 100644 --- a/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj +++ b/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj @@ -1,8 +1,7 @@ - $(NetCoreAppCurrent);net461;netcoreapp2.1;netstandard2.0;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461;netcoreapp2.1;netstandard2.0 true - true @@ -14,13 +13,16 @@ + + + - - - - - - + + + + + + @@ -30,11 +32,4 @@ - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj b/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj index f996315dab78..302d11eb2fc3 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj +++ b/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT - true + $(NetCoreAppCurrent);netstandard2.0;net461-Windows_NT + true @@ -53,7 +53,16 @@ - + + + + + + + + + + diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System.ServiceModel.Syndication.Tests.csproj b/src/libraries/System.ServiceModel.Syndication/tests/System.ServiceModel.Syndication.Tests.csproj index 59a0a2db745a..d85a1393b8d0 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System.ServiceModel.Syndication.Tests.csproj +++ b/src/libraries/System.ServiceModel.Syndication/tests/System.ServiceModel.Syndication.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461-Windows_NT @@ -58,4 +58,10 @@ PreserveNewest + + + + + + \ No newline at end of file diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.csproj b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.csproj index 4e3eff244909..50d5af47646b 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.csproj +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.csproj @@ -1,6 +1,6 @@ - netstandard2.0;$(NetFrameworkCurrent);net461 + netstandard2.0;net461 enable @@ -11,8 +11,6 @@ - - diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj b/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj index 47dfe7649b4d..10d0d7168bb1 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netstandard2.0-Windows_NT;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netstandard2.0-Windows_NT;net461-Windows_NT true - true $(NoWarn);CA2249 enable @@ -74,14 +73,8 @@ - - - - - - - - + @@ -98,4 +91,14 @@ + + + + + + + + + + diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.TestService/System.ServiceProcess.ServiceController.TestService.csproj b/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.TestService/System.ServiceProcess.ServiceController.TestService.csproj index d68e5e8dab42..8886ffe02e9c 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.TestService/System.ServiceProcess.ServiceController.TestService.csproj +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.TestService/System.ServiceProcess.ServiceController.TestService.csproj @@ -2,7 +2,7 @@ true Exe - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 annotations @@ -37,4 +37,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.Tests.csproj b/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.Tests.csproj index 1fcc105e57b1..2bf38334f76d 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.Tests.csproj +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/System.ServiceProcess.ServiceController.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT @@ -10,6 +10,9 @@ - + + + + \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.CodePages/Directory.Build.props b/src/libraries/System.Text.Encoding.CodePages/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Text.Encoding.CodePages/Directory.Build.props +++ b/src/libraries/System.Text.Encoding.CodePages/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.CodePages/ref/System.Text.Encoding.CodePages.csproj b/src/libraries/System.Text.Encoding.CodePages/ref/System.Text.Encoding.CodePages.csproj index ff67cc8cca7d..532f6e7ebe43 100644 --- a/src/libraries/System.Text.Encoding.CodePages/ref/System.Text.Encoding.CodePages.csproj +++ b/src/libraries/System.Text.Encoding.CodePages/ref/System.Text.Encoding.CodePages.csproj @@ -1,17 +1,13 @@ enable - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 - - - - + \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj index 3ca2e7453ec8..504f90a32415 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj +++ b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj @@ -2,10 +2,20 @@ true enable - $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;netstandard2.0-Windows_NT;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT - true + $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;netstandard2.0-Windows_NT;net461-Windows_NT true + + + + Data\CodePageNameMappings.csv + + Data\PreferredCodePageNames.csv + System\Text\EncodingTable.Data.cs + @@ -55,10 +65,14 @@ codepages.nlp - - + + + + + @@ -67,22 +81,5 @@ - - - - - - - - - - Data\CodePageNameMappings.csv - - Data\PreferredCodePageNames.csv - System\Text\EncodingTable.Data.cs - diff --git a/src/libraries/System.Text.Encoding.CodePages/tests/System.Text.Encoding.CodePages.Tests.csproj b/src/libraries/System.Text.Encoding.CodePages/tests/System.Text.Encoding.CodePages.Tests.csproj index 353fe29ea301..0b05fa533b0e 100644 --- a/src/libraries/System.Text.Encoding.CodePages/tests/System.Text.Encoding.CodePages.Tests.csproj +++ b/src/libraries/System.Text.Encoding.CodePages/tests/System.Text.Encoding.CodePages.Tests.csproj @@ -1,11 +1,14 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461-Windows_NT + + + \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.Extensions/Directory.Build.props b/src/libraries/System.Text.Encoding.Extensions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Text.Encoding.Extensions/Directory.Build.props +++ b/src/libraries/System.Text.Encoding.Extensions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.Extensions/src/System.Text.Encoding.Extensions.csproj b/src/libraries/System.Text.Encoding.Extensions/src/System.Text.Encoding.Extensions.csproj index bc0555cf2c62..dd3dc2940a54 100644 --- a/src/libraries/System.Text.Encoding.Extensions/src/System.Text.Encoding.Extensions.csproj +++ b/src/libraries/System.Text.Encoding.Extensions/src/System.Text.Encoding.Extensions.csproj @@ -1,6 +1,5 @@ - System.Text.Encoding.Extensions true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Text.Encoding/Directory.Build.props b/src/libraries/System.Text.Encoding/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Text.Encoding/Directory.Build.props +++ b/src/libraries/System.Text.Encoding/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding/src/System.Text.Encoding.csproj b/src/libraries/System.Text.Encoding/src/System.Text.Encoding.csproj index 16ab188781b8..4f2d15aa3b6a 100644 --- a/src/libraries/System.Text.Encoding/src/System.Text.Encoding.csproj +++ b/src/libraries/System.Text.Encoding/src/System.Text.Encoding.csproj @@ -1,6 +1,5 @@ - System.Text.Encoding true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Text.Encodings.Web/Directory.Build.props b/src/libraries/System.Text.Encodings.Web/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Text.Encodings.Web/Directory.Build.props +++ b/src/libraries/System.Text.Encodings.Web/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Text.Encodings.Web/ref/System.Text.Encodings.Web.csproj b/src/libraries/System.Text.Encodings.Web/ref/System.Text.Encodings.Web.csproj index 3de8b872e748..eff1dfbb548c 100644 --- a/src/libraries/System.Text.Encodings.Web/ref/System.Text.Encodings.Web.csproj +++ b/src/libraries/System.Text.Encodings.Web/ref/System.Text.Encodings.Web.csproj @@ -1,7 +1,6 @@ - $(NetCoreAppCurrent);netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;net461 true true @@ -12,16 +11,12 @@ - - - + + + - - - - - - - + + \ No newline at end of file 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 449759c379dd..906f6d9dc252 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 @@ -1,8 +1,7 @@ true - $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;netstandard2.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;netstandard2.0;net461 true enable @@ -42,19 +41,18 @@ - + + - - - - - - - + + + diff --git a/src/libraries/System.Text.Encodings.Web/tests/System.Text.Encodings.Web.Tests.csproj b/src/libraries/System.Text.Encodings.Web/tests/System.Text.Encodings.Web.Tests.csproj index 26f3b0dd17c6..5ad0343d6c04 100644 --- a/src/libraries/System.Text.Encodings.Web/tests/System.Text.Encodings.Web.Tests.csproj +++ b/src/libraries/System.Text.Encodings.Web/tests/System.Text.Encodings.Web.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 13.0 @@ -53,4 +53,7 @@ + + + diff --git a/src/libraries/System.Text.Json/Directory.Build.props b/src/libraries/System.Text.Json/Directory.Build.props index 749d7fc1c6b5..ba1f965d83ca 100644 --- a/src/libraries/System.Text.Json/Directory.Build.props +++ b/src/libraries/System.Text.Json/Directory.Build.props @@ -2,6 +2,5 @@ Open - true 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 0de194ebde5b..514e3bd8b53f 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -184,7 +184,7 @@ public partial struct JsonReaderState } public static partial class JsonSerializer { -#if NETCOREAPP +#if NETCOREAPP && !NETCOREAPP3_0 private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -518,7 +518,7 @@ internal JsonConverter() { } public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute { protected JsonConverterAttribute() { } -#if NETCOREAPP +#if NETCOREAPP && !NETCOREAPP3_0 public JsonConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type converterType) { } [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public System.Type? ConverterType { get { throw null; } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index b06efdcf9ac2..e22a2d475c2e 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -1,25 +1,29 @@ - $(NetCoreAppCurrent);netstandard2.0;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 enable - - - + + + - - - + - - + + + + + + + - + \ 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 64d2b0562b0e..ca40e1777447 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -1,9 +1,8 @@ true - $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);netstandard2.0;netcoreapp3.0;net461 true - true @@ -16,6 +15,8 @@ $(DefineConstants);BUILDING_INBOX_LIBRARY $(NoWarn);nullable + + netstandard2.0 @@ -214,46 +215,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + 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 6edf36ca7a30..808880d9af6a 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,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true @@ -146,10 +146,15 @@ - + + + + + + diff --git a/src/libraries/System.Text.RegularExpressions/Directory.Build.props b/src/libraries/System.Text.RegularExpressions/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Text.RegularExpressions/Directory.Build.props +++ b/src/libraries/System.Text.RegularExpressions/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj index f323acb4be50..5313bf0d9481 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj +++ b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj @@ -1,6 +1,5 @@ - System.Text.RegularExpressions true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj index dc756043b949..20878cabf96e 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj @@ -3,7 +3,7 @@ true $(NoWarn);xUnit2008 - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net48 diff --git a/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.csproj b/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.csproj index a88ecaa24bca..561c79249b27 100644 --- a/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.csproj +++ b/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.csproj @@ -1,7 +1,6 @@ - netstandard2.0;net461;$(NetFrameworkCurrent) - true + netstandard2.0;net461 enable @@ -11,10 +10,6 @@ - - - - diff --git a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj index e5398bcb532b..3ca55d255159 100644 --- a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj +++ b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj @@ -1,7 +1,6 @@ - netstandard2.0-Windows_NT;net461-Windows_NT;netstandard2.0;$(NetFrameworkCurrent)-Windows_NT - true + netstandard2.0-Windows_NT;net461-Windows_NT;netstandard2.0 true enable @@ -44,16 +43,14 @@ - - - - - - + + + + diff --git a/src/libraries/System.Threading.AccessControl/tests/System.Threading.AccessControl.Tests.csproj b/src/libraries/System.Threading.AccessControl/tests/System.Threading.AccessControl.Tests.csproj index c60e1d656cd0..5d41e0bac88d 100644 --- a/src/libraries/System.Threading.AccessControl/tests/System.Threading.AccessControl.Tests.csproj +++ b/src/libraries/System.Threading.AccessControl/tests/System.Threading.AccessControl.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;net461-Windows_NT + + + diff --git a/src/libraries/System.Threading.Channels/Directory.Build.props b/src/libraries/System.Threading.Channels/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Threading.Channels/Directory.Build.props +++ b/src/libraries/System.Threading.Channels/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.csproj b/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.csproj index 4aace39265e8..464fca7b6b67 100644 --- a/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.csproj +++ b/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.csproj @@ -1,26 +1,27 @@ - $(NetCoreAppCurrent);netcoreapp3.0;netstandard1.3;netstandard2.0;netstandard2.1 + $(NetCoreAppCurrent);netcoreapp3.0;netstandard1.3;netstandard2.0;netstandard2.1;net461 true enable - + - - - - + - - - + + + + \ No newline at end of file diff --git a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj index b52a5869a938..498f88004c83 100644 --- a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj +++ b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj @@ -1,7 +1,6 @@ - $(NetCoreAppCurrent);netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.0;net461 true enable @@ -31,8 +30,8 @@ - - + @@ -40,12 +39,12 @@ - + - - - + + diff --git a/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj b/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj index 5c1178c3d1c6..c67e5e5fed5c 100644 --- a/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj +++ b/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -18,4 +18,7 @@ + + + diff --git a/src/libraries/System.Threading.Overlapped/Directory.Build.props b/src/libraries/System.Threading.Overlapped/Directory.Build.props index 0f058f12cba8..33e65b7cb465 100644 --- a/src/libraries/System.Threading.Overlapped/Directory.Build.props +++ b/src/libraries/System.Threading.Overlapped/Directory.Build.props @@ -2,7 +2,6 @@ Microsoft - true true \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks.Dataflow/Directory.Build.props b/src/libraries/System.Threading.Tasks.Dataflow/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/Directory.Build.props +++ b/src/libraries/System.Threading.Tasks.Dataflow/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj index 915b6a275eae..7c65f89d1bf1 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj @@ -1,13 +1,9 @@ - netstandard2.0;netstandard1.0;netstandard1.1 + netstandard2.0;netstandard1.0;netstandard1.1;net461 enable - - - - \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index 9aefb2928ff4..ffb871269eee 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -1,7 +1,6 @@ - netstandard2.0;netstandard1.0;netstandard1.1;net461;$(NetFrameworkCurrent) - true + netstandard2.0;netstandard1.0;netstandard1.1;net461 enable @@ -61,27 +60,9 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/src/libraries/System.Threading.Tasks.Dataflow/tests/System.Threading.Tasks.Dataflow.Tests.csproj b/src/libraries/System.Threading.Tasks.Dataflow/tests/System.Threading.Tasks.Dataflow.Tests.csproj index 64d15af718d8..f81782213136 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/tests/System.Threading.Tasks.Dataflow.Tests.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/tests/System.Threading.Tasks.Dataflow.Tests.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 @@ -26,4 +26,7 @@ + + + diff --git a/src/libraries/System.Threading.Tasks.Extensions/Directory.Build.props b/src/libraries/System.Threading.Tasks.Extensions/Directory.Build.props index 749d7fc1c6b5..ba1f965d83ca 100644 --- a/src/libraries/System.Threading.Tasks.Extensions/Directory.Build.props +++ b/src/libraries/System.Threading.Tasks.Extensions/Directory.Build.props @@ -2,6 +2,5 @@ Open - true diff --git a/src/libraries/System.Threading.Tasks.Parallel/Directory.Build.props b/src/libraries/System.Threading.Tasks.Parallel/Directory.Build.props index 5f6e490332e1..e8d65546d0c8 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/Directory.Build.props +++ b/src/libraries/System.Threading.Tasks.Parallel/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true diff --git a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj index 0363727de456..3d0ccd82d99c 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj +++ b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj @@ -1,7 +1,5 @@ - System.Threading.Tasks.Parallel - System.Threading.Tasks.Parallel $(DefineConstants);FEATURE_TRACING true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Threading.Tasks/Directory.Build.props b/src/libraries/System.Threading.Tasks/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading.Tasks/Directory.Build.props +++ b/src/libraries/System.Threading.Tasks/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks/src/System.Threading.Tasks.csproj b/src/libraries/System.Threading.Tasks/src/System.Threading.Tasks.csproj index 1b8aa100783f..4f2d15aa3b6a 100644 --- a/src/libraries/System.Threading.Tasks/src/System.Threading.Tasks.csproj +++ b/src/libraries/System.Threading.Tasks/src/System.Threading.Tasks.csproj @@ -1,6 +1,5 @@ - System.Threading.Tasks true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Threading.Thread/Directory.Build.props b/src/libraries/System.Threading.Thread/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading.Thread/Directory.Build.props +++ b/src/libraries/System.Threading.Thread/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj index 7bde58cfb98b..dd3dc2940a54 100644 --- a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj @@ -1,7 +1,5 @@ - System.Threading.Thread - Library true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Threading.ThreadPool/Directory.Build.props b/src/libraries/System.Threading.ThreadPool/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading.ThreadPool/Directory.Build.props +++ b/src/libraries/System.Threading.ThreadPool/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading.ThreadPool/src/System.Threading.ThreadPool.csproj b/src/libraries/System.Threading.ThreadPool/src/System.Threading.ThreadPool.csproj index 14a425e48851..dd3dc2940a54 100644 --- a/src/libraries/System.Threading.ThreadPool/src/System.Threading.ThreadPool.csproj +++ b/src/libraries/System.Threading.ThreadPool/src/System.Threading.ThreadPool.csproj @@ -1,6 +1,5 @@ - System.Threading.ThreadPool true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Threading.Timer/Directory.Build.props b/src/libraries/System.Threading.Timer/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading.Timer/Directory.Build.props +++ b/src/libraries/System.Threading.Timer/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading.Timer/src/System.Threading.Timer.csproj b/src/libraries/System.Threading.Timer/src/System.Threading.Timer.csproj index 68aff5403a4e..4f2d15aa3b6a 100644 --- a/src/libraries/System.Threading.Timer/src/System.Threading.Timer.csproj +++ b/src/libraries/System.Threading.Timer/src/System.Threading.Timer.csproj @@ -1,6 +1,5 @@ - System.Threading.Timer true $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Threading/Directory.Build.props b/src/libraries/System.Threading/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Threading/Directory.Build.props +++ b/src/libraries/System.Threading/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Threading/src/System.Threading.csproj b/src/libraries/System.Threading/src/System.Threading.csproj index 6b4aeb5e8a1c..895b45827937 100644 --- a/src/libraries/System.Threading/src/System.Threading.csproj +++ b/src/libraries/System.Threading/src/System.Threading.csproj @@ -1,6 +1,5 @@ - System.Threading true true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Transactions.Local/Directory.Build.props b/src/libraries/System.Transactions.Local/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Transactions.Local/Directory.Build.props +++ b/src/libraries/System.Transactions.Local/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.csproj b/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.csproj index b7a65a17fae2..ce48f9db195f 100644 --- a/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.csproj +++ b/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.csproj @@ -1,6 +1,5 @@ - Library $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj b/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj index dd7771979978..1715d21528c9 100644 --- a/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj +++ b/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj @@ -33,6 +33,7 @@ + @@ -50,7 +51,4 @@ - - - diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs index 04a0cc861ba1..5f1d14ec279d 100644 --- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs +++ b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Index))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Range))] diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs index b37545e6f47a..a72e76090dea 100644 --- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs +++ b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs @@ -90,12 +90,12 @@ public Utf8String(string value) { } public bool Contains(System.Text.Rune value, System.StringComparison comparison) { throw null; } public bool Contains(System.Utf8String value) { throw null; } public bool Contains(System.Utf8String value, System.StringComparison comparison) { throw null; } -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK public static System.Utf8String Create(int length, TState state, System.Buffers.SpanAction action) { throw null; } #endif public static System.Utf8String CreateFromRelaxed(System.ReadOnlySpan buffer) { throw null; } public static System.Utf8String CreateFromRelaxed(System.ReadOnlySpan buffer) { throw null; } -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK public static System.Utf8String CreateRelaxed(int length, TState state, System.Buffers.SpanAction action) { throw null; } #endif public bool EndsWith(char value) { throw null; } @@ -168,7 +168,7 @@ public Utf8String(string value) { } public bool TryFindLast(System.Utf8String value, out System.Range range) { throw null; } public bool TryFindLast(System.Utf8String value, System.StringComparison comparisonType, out System.Range range) { throw null; } public static System.Utf8String UnsafeCreateWithoutValidation(System.ReadOnlySpan utf8Contents) { throw null; } -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK public static System.Utf8String UnsafeCreateWithoutValidation(int length, TState state, System.Buffers.SpanAction action) { throw null; } #endif public readonly partial struct ByteEnumerable : System.Collections.Generic.IEnumerable diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj index 4ef79b71fc46..eb5a1414f8cd 100644 --- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj +++ b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj @@ -3,25 +3,31 @@ true $(NoWarn);0809;0618 - netstandard2.0;netstandard2.1;netcoreapp3.0;$(NetCoreAppCurrent) + netstandard2.0;netstandard2.1;netcoreapp3.0;$(NetCoreAppCurrent);net461 enable - + - + - + - - + + + + + + + + @@ -30,10 +36,8 @@ - - - - - + + + \ No newline at end of file diff --git a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj b/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj index 016238e9a83e..8b72b9161c55 100644 --- a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj +++ b/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj @@ -1,8 +1,7 @@ true - $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;netcoreapp3.0;net461;$(NetFrameworkCurrent) - true + $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;netcoreapp3.0;net461 enable $(DefineContants);FEATURE_UTF8STRING @@ -17,7 +16,7 @@ - + - - - - - + + + + + + + + + - - + + + + + + + + + @@ -134,21 +145,10 @@ - - - - - - - - - - - - + diff --git a/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj b/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj index 1edb4b7d68e5..73efb5b00c82 100644 --- a/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj +++ b/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj @@ -2,11 +2,9 @@ true true - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent);net461 true true - - true @@ -43,7 +41,13 @@ - + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.ValueTuple/Directory.Build.props b/src/libraries/System.ValueTuple/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.ValueTuple/Directory.Build.props +++ b/src/libraries/System.ValueTuple/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.ValueTuple/ref/System.ValueTuple.csproj b/src/libraries/System.ValueTuple/ref/System.ValueTuple.csproj index 7de77702d277..48439ada9ee5 100644 --- a/src/libraries/System.ValueTuple/ref/System.ValueTuple.csproj +++ b/src/libraries/System.ValueTuple/ref/System.ValueTuple.csproj @@ -3,13 +3,13 @@ 4.0.3.0 - $(NetCoreAppCurrent);_$(NetFrameworkCurrent) + $(NetCoreAppCurrent) enable - + diff --git a/src/libraries/System.ValueTuple/src/System.ValueTuple.csproj b/src/libraries/System.ValueTuple/src/System.ValueTuple.csproj index 37b43aecf36c..7a4c99705513 100644 --- a/src/libraries/System.ValueTuple/src/System.ValueTuple.csproj +++ b/src/libraries/System.ValueTuple/src/System.ValueTuple.csproj @@ -2,7 +2,7 @@ true - $(NetCoreAppCurrent);_$(NetFrameworkCurrent) + $(NetCoreAppCurrent) enable diff --git a/src/libraries/System.Web.HttpUtility/Directory.Build.props b/src/libraries/System.Web.HttpUtility/Directory.Build.props index 2b9e2844e4ee..bdcfca3b543c 100644 --- a/src/libraries/System.Web.HttpUtility/Directory.Build.props +++ b/src/libraries/System.Web.HttpUtility/Directory.Build.props @@ -2,6 +2,5 @@ Open - true \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj index ebbd3e46f767..d8548ee597d3 100644 --- a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj @@ -7,17 +7,17 @@ - - - - - + + + + + - - + + \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj index ea77d6793f77..7e4df72fa5eb 100644 --- a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj @@ -2,7 +2,7 @@ SR.PlatformNotSupported_System_Windows_Extensions true - $(NetCoreAppCurrent)-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp3.0-Windows_NT;$(NetCoreAppCurrent);netcoreapp3.0 true @@ -55,6 +55,9 @@ + + + @@ -63,7 +66,6 @@ - diff --git a/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj b/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj index 7396a53455fe..f41f912cb05b 100644 --- a/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj +++ b/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj @@ -25,5 +25,7 @@ + + diff --git a/src/libraries/System.Xml.ReaderWriter/Directory.Build.props b/src/libraries/System.Xml.ReaderWriter/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.ReaderWriter/Directory.Build.props +++ b/src/libraries/System.Xml.ReaderWriter/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj b/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj index e7413a357835..eccf2f839b93 100644 --- a/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj +++ b/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj @@ -1,14 +1,11 @@ - System.Xml.ReaderWriter System.Xml true $(NetCoreAppCurrent) - - - + \ No newline at end of file diff --git a/src/libraries/System.Xml.XDocument/Directory.Build.props b/src/libraries/System.Xml.XDocument/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.XDocument/Directory.Build.props +++ b/src/libraries/System.Xml.XDocument/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj b/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj index 6bfd8d595b07..f4c9ec075a89 100644 --- a/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj +++ b/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj @@ -1,15 +1,12 @@ - System.Xml.XDocument System.Xml true $(NetCoreAppCurrent) - - - - + + \ No newline at end of file diff --git a/src/libraries/System.Xml.XPath.XDocument/Directory.Build.props b/src/libraries/System.Xml.XPath.XDocument/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.XPath.XDocument/Directory.Build.props +++ b/src/libraries/System.Xml.XPath.XDocument/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj b/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj index 27b08b9f75ff..6ef3750484c7 100644 --- a/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj +++ b/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/src/libraries/System.Xml.XPath/Directory.Build.props b/src/libraries/System.Xml.XPath/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.XPath/Directory.Build.props +++ b/src/libraries/System.Xml.XPath/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj b/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj index c78bfe73a9d4..8159a0e77d94 100644 --- a/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj +++ b/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj @@ -1,13 +1,10 @@ - System.Xml.XPath true $(NetCoreAppCurrent) - - - + \ No newline at end of file diff --git a/src/libraries/System.Xml.XmlDocument/Directory.Build.props b/src/libraries/System.Xml.XmlDocument/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.XmlDocument/Directory.Build.props +++ b/src/libraries/System.Xml.XmlDocument/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.XmlDocument/src/System.Xml.XmlDocument.csproj b/src/libraries/System.Xml.XmlDocument/src/System.Xml.XmlDocument.csproj index 7abca9d22ec5..2700e39cf27b 100644 --- a/src/libraries/System.Xml.XmlDocument/src/System.Xml.XmlDocument.csproj +++ b/src/libraries/System.Xml.XmlDocument/src/System.Xml.XmlDocument.csproj @@ -1,15 +1,11 @@ - System.Xml.XmlDocument - System.Xml.XmlDocument true true $(NetCoreAppCurrent) - - - + \ No newline at end of file diff --git a/src/libraries/System.Xml.XmlSerializer/Directory.Build.props b/src/libraries/System.Xml.XmlSerializer/Directory.Build.props index 465e1110d6b0..63f02a0f817e 100644 --- a/src/libraries/System.Xml.XmlSerializer/Directory.Build.props +++ b/src/libraries/System.Xml.XmlSerializer/Directory.Build.props @@ -2,6 +2,5 @@ Microsoft - true \ No newline at end of file diff --git a/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj b/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj index d9aa0818fdf0..8159a0e77d94 100644 --- a/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj +++ b/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj @@ -1,14 +1,10 @@ - System.Xml.XmlSerializer - System.Xml.XmlSerializer true $(NetCoreAppCurrent) - - - + \ No newline at end of file diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index 95fb67f15b89..2c2fd2238699 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -6538,6 +6538,7 @@ "4.1.0.0": "4.3.0", "4.1.1.0": "4.4.0", "4.2.0.0": "4.5.0", + "4.2.0.1": "4.5.4", "4.2.1.0": "4.6.0" } }, diff --git a/src/libraries/pkg/test/testPackages.proj b/src/libraries/pkg/test/testPackages.proj index a624abf7878b..94f5111179a6 100644 --- a/src/libraries/pkg/test/testPackages.proj +++ b/src/libraries/pkg/test/testPackages.proj @@ -21,9 +21,6 @@ - - - diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 23a4041ff30a..5cd55be973cb 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -1,17 +1,16 @@ - - BuildAllProjects=true - - true true - + @@ -20,8 +19,8 @@ - - + BeforeTargets="Build" + Condition="'$(CreateIntermediateRunSettingsFile)' == 'true'" /> - - + - <_manualSharedFrameworkRuntimeFiles Include="System.Security.Cryptography.Native.OpenSsl.so" /> - <_manualSharedFrameworkRuntimeFiles Include="System.Security.Cryptography.Native.Apple.dylib" /> - <_manualSharedFrameworkRuntimeFiles Include="System.Security.Cryptography.Native.OpenSsl.dylib" /> - - - + + + + + - - + + - + + + - + - + + - - + - <_refPackLibFile Include="$(MicrosoftNetCoreAppRefPackRefDir)*.*"> - ref/$(NetCoreAppCurrent) - - <_runtimePackLibFiles Include="$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)*.*"> + runtimes/$(PackageRID)/lib/$(NetCoreAppCurrent) - - <_runtimePackNativeFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)*.*"> + + runtimes/$(PackageRID)/native true - - - <_runtimePackNativeFiles Update="@(_runtimePackNativeFiles)" Condition="'%(FileName)%(Extension)' == 'System.Private.CoreLib.dll'" IsNative="" /> - - - - - + + + - - <_refPackLibFile> - true - - <_runtimePackLibFiles> + true - - <_runtimePackNativeFiles> + + true - + + - + + + + + + + + + - + RootAttributes="@(FrameworkListRootAttribute)" /> diff --git a/src/libraries/ref.proj b/src/libraries/ref.proj index c13c10044388..c80789e51e53 100644 --- a/src/libraries/ref.proj +++ b/src/libraries/ref.proj @@ -1,24 +1,91 @@ + BuildAllProjects=true - + <_allRef Include="$(MSBuildThisFileDirectory)*\ref\*.csproj" + Exclude="@(ProjectExclusions)" /> + + + - + + - + + AfterTargets="Build" + Condition="'@(GeneratedShimProject)' != ''"> + + + + ref/$(NetCoreAppCurrent) + true + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/restore/Directory.Build.props b/src/libraries/restore/Directory.Build.props index 359dfd63da6a..4cc238039b41 100644 --- a/src/libraries/restore/Directory.Build.props +++ b/src/libraries/restore/Directory.Build.props @@ -1,4 +1,4 @@ - + @@ -11,7 +11,6 @@ true false - netstandard2.0 - - - $(RefPath) - - - - - - - BinPlaceLib - $(RuntimePath) - - - BinPlaceLib - $(TestHostRuntimePath) - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/restore/depproj.proj b/src/libraries/restore/depproj.proj deleted file mode 100644 index 7825325f9239..000000000000 --- a/src/libraries/restore/depproj.proj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/restore/netcoreapp/external.netcoreapp.depproj b/src/libraries/restore/netcoreapp/external.netcoreapp.depproj deleted file mode 100644 index 72e15fde6cdf..000000000000 --- a/src/libraries/restore/netcoreapp/external.netcoreapp.depproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Reference - false - true - netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;netcoreapp3.1 - - - - - - - - - - - - diff --git a/src/libraries/restore/netfx/netfx.depproj b/src/libraries/restore/netfx/netfx.depproj deleted file mode 100644 index 7fcdb7329068..000000000000 --- a/src/libraries/restore/netfx/netfx.depproj +++ /dev/null @@ -1,126 +0,0 @@ - - - - true - true - Reference - NETStandard.Library.NETFramework - 2.0.1-servicing-26011-01 - $(NuGetPackageRoot)$(NETStandardSupportPackageId.ToLower())\$(NETStandardSupportPackageVersion)\build - true - net45;net451;net46;net461;net462;net47;net471;net472 - - $(TargetFrameworks);$(NetCoreAppCurrent) - - - - $(NetFrameworkCurrent) - Microsoft.TargetingPack.NETFramework.v4.7.2 - - - - - <_ShortFrameworkIdentifier>$(TargetFramework.TrimEnd('.0123456789')) - <_ShortFrameworkVersion>$(TargetFramework.Substring($(_ShortFrameworkIdentifier.Length))) - - - - - v$(_ShortFrameworkVersion) - - - - - v$(_ShortFrameworkVersion[0]).0 - v$(_ShortFrameworkVersion[0]).$(_ShortFrameworkVersion[1]) - v$(_ShortFrameworkVersion[0]).$(_ShortFrameworkVersion[1]).$(_ShortFrameworkVersion[2]) - - - - - .NETStandard - .NETCoreApp - - - .NETFramework - .NETCoreApp - - - - Microsoft.TargetingPack.NETFramework.$(TargetFrameworkVersion) - - - - - - $(NetFxRefPath) - - - - - $(RefPath) - - - - - <_TargetingPackVersion>1.0.1 - <_TargetingPackVersion Condition="'$(TargetingPackNugetPackageId)' == 'Microsoft.TargetingPack.NETFramework.v4.7.1' or '$(TargetingPackNugetPackageId)' == 'Microsoft.TargetingPack.NETFramework.v4.7.2'">1.0.0 - - - - - $(_TargetingPackVersion) - - - 4.5.2 - - - 4.5.0 - - - 4.5.0 - - - $(NETStandardSupportPackageVersion) - - - - - - - - - - <_netStandardReference Condition="'$(TargetFramework)' != 'net461' and '$(TargetFramework)' != 'net462'" - Include="$(NETStandardSupportRoot)\net47\lib\*.dll" - Exclude="@(_netStandardReference->'$(NETStandardSupportRoot)\net47\lib\%(FileName).dll')" /> - <_netStandardReference Condition="'$(TargetFramework)' != 'net461'" - Include="$(NETStandardSupportRoot)\net462\lib\*.dll" - Exclude="@(_netStandardReference->'$(NETStandardSupportRoot)\net462\lib\%(FileName).dll')" /> - <_netStandardReference Include="$(NETStandardSupportRoot)\net461\lib\*.dll" - Exclude="@(_netStandardReference->'$(NETStandardSupportRoot)\net461\lib\%(FileName).dll')" /> - - <_netStandardReference> - False - $(NETStandardSupportPackageId) - $(NETStandardSupportPackageVersion) - - - <_referenceByFileName Include="@(Reference->'%(FileName)%(Extension)')"> - %(Identity) - - <_netStandardReferenceByFileName Include="@(_netStandardReference->'%(FileName)%(Extension)')" /> - - <_remainingReferenceByFileName Include="@(_referenceByFileName)" Exclude="@(_netStandardReferenceByFileName)" /> - <_remainingReference Include="@(_remainingReferenceByFileName->'%(OriginalIdentity)')" /> - - - - - - diff --git a/src/libraries/restore/netstandard/external.netstandard.depproj b/src/libraries/restore/netstandard/external.netstandard.depproj deleted file mode 100644 index 1d80925bf173..000000000000 --- a/src/libraries/restore/netstandard/external.netstandard.depproj +++ /dev/null @@ -1,128 +0,0 @@ - - - $(TargetFramework.SubString(11)) - true - true - true - Reference - <_NETStandardTFMFolder Condition="'$(TargetFramework)' == 'netstandard2.0'">netstandard2.0 - netstandard1.0;netstandard1.1;netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0 - - - - - $(NETStandardLibraryVersion) - - - - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - 4.3.0 - - - - - 4.5.0 - - - 4.5.0 - - - 4.5.1 - - - 4.5.2 - - - 4.7.0 - - - - - - - $(RefPath) - - - - $(TestHostRootPath) - - - - - - <_NETStandard21RefFolder>$(NuGetPackageRoot)$(NETStandardLibraryPackage)\$(NETStandardLibraryVersion)\build\netstandard2.1\ref - - - - - - <_NetStandard21Files - Include="$(_NETStandard21RefFolder)\*.dll" - Exclude="@(ExcludeNetStandard21Refs -> '$(_NETStandard21RefFolder)\%(Identity).dll')" /> - - - - - - - - - - <_NETStandardRefFolder>$(NuGetPackageRoot)$(NETStandardLibraryPackage)\$(NETStandardLibraryVersion)\build\$(_NETStandardTFMFolder)\ref - - - - - - - - - - - - False - $(NETStandardLibraryPackage) - $(NETStandardLibraryVersion) - - - - diff --git a/src/libraries/restore/runtime/referenceFromRuntime.targets b/src/libraries/restore/runtime/referenceFromRuntime.targets deleted file mode 100644 index 2a013d8d05d0..000000000000 --- a/src/libraries/restore/runtime/referenceFromRuntime.targets +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj index b8cd8ce65baa..92ebdb6d285e 100644 --- a/src/libraries/restore/runtime/runtime.depproj +++ b/src/libraries/restore/runtime/runtime.depproj @@ -6,7 +6,7 @@ false true false - netcoreapp3.0-Windows_NT;netcoreapp3.0-Unix;$(netcoreappCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser @@ -22,10 +22,6 @@ - - - - - - - - - cross/ - - - include/%(RecursiveDir) - - - - + - + Condition="'$(RuntimeFlavor)' == 'Mono'"> + + + + + + + @@ -109,10 +101,8 @@ - $([System.Text.RegularExpressions.Regex]::Replace('$(TargetFrameworks)', '_[^;]+;?', '')) $([System.Text.RegularExpressions.Regex]::Replace('$(TargetFrameworks)', '-[^;]+', '')) diff --git a/src/libraries/sendtohelix.proj b/src/libraries/sendtohelix.proj index d5729d8e5d7c..92b7b688e77b 100644 --- a/src/libraries/sendtohelix.proj +++ b/src/libraries/sendtohelix.proj @@ -18,7 +18,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -80,7 +80,8 @@ true - $(TestArchiveRuntimeRoot)test-runtime-$(BuildSettings).zip + $(TestArchiveRuntimeRoot)test-runtime-$(BuildSettings).zip $(TestArchiveRuntimeRoot)packages-testPayload-$(Configuration).zip @@ -144,7 +145,9 @@ + Condition="'$(TestPackages)' != 'true' and + '$(TargetsMobile)' != 'true' and + '$(TestArchiveRuntimeFile)' != ''"> diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index f5b2ab2489aa..fecc281788d9 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -136,7 +136,9 @@ so if we don't use "call", then we cause the parent script to exit, and anything after will not be executed. --> call RunTests.cmd --runtime-path %HELIX_CORRELATION_PAYLOAD% + $(HelixCommand) --runtime-path %HELIX_CORRELATION_PAYLOAD% ./RunTests.sh --runtime-path "$HELIX_CORRELATION_PAYLOAD" + $(HelixCommand) --runtime-path "$HELIX_CORRELATION_PAYLOAD" @@ -155,14 +157,15 @@ - + - + <_WorkItem Include="$(WorkItemArchiveWildCard)" Exclude="$(HelixCorrelationPayload)" /> diff --git a/src/libraries/shims/ApiCompat.proj b/src/libraries/shims/ApiCompat.proj index d275e0efeacd..da102c545083 100644 --- a/src/libraries/shims/ApiCompat.proj +++ b/src/libraries/shims/ApiCompat.proj @@ -4,7 +4,9 @@ $(BuildTargetFramework) false - <_RunApiCompat>true + netcoreapp3.1 + microsoft.netcore.app.ref + 3.1.0 @@ -14,6 +16,11 @@ + + + + + @@ -28,14 +35,13 @@ - $(BuildTargetFrameworkRefPath.TrimEnd('\/')) + $(NetCoreAppCurrentRefPath.TrimEnd('\/')) $(ApiCompatArgs) --exclude-attributes "$(ApiCompatExcludeAttributeList)" $(ApiCompatArgs) --impl-dirs "$(ApiCompatImplementationDirs)" --baseline "$(ApiCompatBaselineIgnoreFile)" @@ -53,7 +59,7 @@ - + - @@ -100,8 +104,7 @@ - netcoreapp3.1 - $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(PreviousNetCoreApp)')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', '$(PreviousNetCoreAppPackageId)', '$(PreviousNetCoreAppPackageVersion)', 'ref', '$(PreviousNetCoreApp)')) <_previousNetCoreAppBaselineFile>$(MSBuildThisFileDirectory)ApiCompatBaseline.PreviousNetCoreApp.txt <_previousNetCoreAppBaselineParam>--baseline "$(_previousNetCoreAppBaselineFile)" <_previousNetCoreAppBaselineParam Condition="'$(UpdatePreviousNetCoreAppBaseline)' == 'true'">> "$(_previousNetCoreAppBaselineFile)" diff --git a/src/libraries/shims/Directory.Build.props b/src/libraries/shims/Directory.Build.props index d0835fdd9bb9..55920bf3ba2f 100644 --- a/src/libraries/shims/Directory.Build.props +++ b/src/libraries/shims/Directory.Build.props @@ -4,7 +4,8 @@ - true + true + true $(TargetFramework) @@ -16,8 +17,10 @@ to reference the latest packages. netstandard.dll doesn't need to do this since it has no dangling dependencies --> true - false true + net48 + $(NuGetPackageRoot)microsoft.netframework.referenceassemblies.$(NETFrameworkReferenceAssemblyTFM)\$(MicrosoftNetFrameworkReferenceAssembliesVersion)\build\.NETFramework\v4.8\ + $(NuGetPackageRoot)netstandard.library\$(NETStandardLibraryVersion)\build\netstandard2.1\ref\ diff --git a/src/libraries/shims/generated/Directory.Build.props b/src/libraries/shims/generated/Directory.Build.props index 2768718a10e5..096ac6881640 100644 --- a/src/libraries/shims/generated/Directory.Build.props +++ b/src/libraries/shims/generated/Directory.Build.props @@ -7,22 +7,37 @@ - + + $(NetCoreAppCurrent) + + + + + + + + + + + Include="$(NetCoreAppCurrentRefPath)*.dll" + Exclude="$(NetCoreAppCurrentRefPath)$(MSBuildProjectName).dll; + $(NetCoreAppCurrentRefPath)netstandard.dll; + $(NetCoreAppCurrentRefPath)Microsoft.Extensions.DependencyModel.dll" /> - + - - - $(NetCoreAppCurrent) - diff --git a/src/libraries/shims/manual/Directory.Build.props b/src/libraries/shims/manual/Directory.Build.props index ee66f309890f..4070e431ee57 100644 --- a/src/libraries/shims/manual/Directory.Build.props +++ b/src/libraries/shims/manual/Directory.Build.props @@ -17,8 +17,10 @@ - + diff --git a/src/libraries/shims/manual/System.Data.csproj b/src/libraries/shims/manual/System.Data.csproj index 417d9bf1d034..2f89b12251ad 100644 --- a/src/libraries/shims/manual/System.Data.csproj +++ b/src/libraries/shims/manual/System.Data.csproj @@ -3,8 +3,7 @@ - - - + + diff --git a/src/libraries/src.proj b/src/libraries/src.proj index 91225466df01..c534a380309d 100644 --- a/src/libraries/src.proj +++ b/src/libraries/src.proj @@ -2,41 +2,48 @@ BuildAllProjects=true - BuildWasmRuntimes - + <_allSrc Include="$(MSBuildThisFileDirectory)*\src\*.csproj" + Exclude="@(ProjectExclusions)" /> + + - - - - - - - + Condition="'$(DotNetBuildFromSource)' != 'true' and + '$(BuildingNETCoreAppVertical)' == 'true' and + '$(RunApiCompat)' != 'false'" /> - - - - + - + + + - + + + + AfterTargets="BuildNonNetCoreAppProjects" + Condition="'@(ManualShimProject)' != ''"> diff --git a/src/mono/wasm/wasm.targets b/src/mono/wasm/wasm.targets index 520dd9c7d7b2..be87c207b15d 100644 --- a/src/mono/wasm/wasm.targets +++ b/src/mono/wasm/wasm.targets @@ -1,48 +1,49 @@ - - - - $(ArtifactsObjDir)wasm/pinvoke-table.h - - - - - - - - - - - - - - - - - - - - + + + + + + + $(ArtifactsObjDir)wasm\pinvoke-table.h + + + + + + + + + + + - + - + + + diff --git a/tools-local/tasks/installer.tasks/installer.tasks.csproj b/tools-local/tasks/installer.tasks/installer.tasks.csproj index 356f22ac74eb..368fe4c58d9f 100644 --- a/tools-local/tasks/installer.tasks/installer.tasks.csproj +++ b/tools-local/tasks/installer.tasks/installer.tasks.csproj @@ -1,7 +1,7 @@ netstandard2.0 - $(TargetFrameworks);net46 + $(TargetFrameworks);net461 false false From 24f63eca6350ce0f9d311b848427a4aa97a14ccd Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 23 Jul 2020 18:20:02 +0200 Subject: [PATCH 011/755] Remove outdated comment in System.CM.Composition.Tests (#39839) We don't plan to add a .NETFramework test configuration for this library anymore. --- .../tests/System.ComponentModel.Composition.Tests.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj index 08e2e4cbaea7..72e124ecebf0 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj +++ b/src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj @@ -1,5 +1,4 @@ - true $(NetCoreAppCurrent) @@ -173,4 +172,4 @@ - \ No newline at end of file + From 56c882ecbbac7113a09321b013809f9de27b9eec Mon Sep 17 00:00:00 2001 From: John Salem Date: Thu, 23 Jul 2020 10:46:36 -0700 Subject: [PATCH 012/755] turn pauseonstart test off for Windows (#39789) --- src/coreclr/tests/issues.targets | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index c65f9541767d..c6c0b0120466 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -304,6 +304,13 @@ + + + + https://github.com/dotnet/runtime/issues/38847 + + + From 73f0750dd3622391cd5f12e90baea83344c63e76 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 23 Jul 2020 11:41:38 -0700 Subject: [PATCH 013/755] Ensure the size of Vector takes COMPlus_EnableHWIntrinsic into account (#39368) * Ensure the size of Vector takes COMPlus_EnableHWIntrinsic into account * Add basic logging to Runtime_34587 * Exclude InstructionSet_POPCNT and InstructionSet_POPCNT_X64 if featureSIMD is disabled --- src/coreclr/src/jit/compiler.h | 6 +-- src/coreclr/src/jit/ee_il_dll.cpp | 3 +- src/coreclr/src/jit/hwintrinsicxarch.cpp | 5 +- .../JitBlue/Runtime_34587/Runtime_34587.cs | 54 +++++++++++++++++++ .../Runtime_34587/Runtime_34587.csproj | 3 ++ 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index c5f571838d4b..28521b87f6b3 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -8190,7 +8190,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if defined(TARGET_XARCH) if (getSIMDSupportLevel() == SIMD_AVX2_Supported) { - return TYP_SIMD32; + return JitConfig.EnableHWIntrinsic() ? TYP_SIMD32 : TYP_SIMD16; } else { @@ -8231,7 +8231,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if defined(TARGET_XARCH) if (getSIMDSupportLevel() == SIMD_AVX2_Supported) { - return YMM_REGSIZE_BYTES; + return JitConfig.EnableHWIntrinsic() ? YMM_REGSIZE_BYTES : XMM_REGSIZE_BYTES; } else { @@ -8261,7 +8261,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if defined(FEATURE_HW_INTRINSICS) && defined(TARGET_XARCH) if (compOpportunisticallyDependsOn(InstructionSet_AVX)) { - return YMM_REGSIZE_BYTES; + return JitConfig.EnableHWIntrinsic() ? YMM_REGSIZE_BYTES : XMM_REGSIZE_BYTES; } else { diff --git a/src/coreclr/src/jit/ee_il_dll.cpp b/src/coreclr/src/jit/ee_il_dll.cpp index 150efed411f6..bfd80ffb1200 100644 --- a/src/coreclr/src/jit/ee_il_dll.cpp +++ b/src/coreclr/src/jit/ee_il_dll.cpp @@ -316,7 +316,8 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) // ensure that AVX2 is actually supported. Otherwise, we will end up getting asserts downstream. if ((JitConfig.EnableAVX2() != 0) && (JitConfig.EnableAVX() != 0) && (JitConfig.EnableSSE42() != 0) && (JitConfig.EnableSSE41() != 0) && (JitConfig.EnableSSSE3() != 0) && (JitConfig.EnableSSE3_4() != 0) && - (JitConfig.EnableSSE3() != 0) && (JitConfig.EnableSSE2() != 0) && (JitConfig.EnableSSE() != 0)) + (JitConfig.EnableSSE3() != 0) && (JitConfig.EnableSSE2() != 0) && (JitConfig.EnableSSE() != 0) && + (JitConfig.EnableHWIntrinsic() != 0)) { if (GetJitTls() != nullptr && JitTls::GetCompiler() != nullptr) { diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp index 8d7824ea189b..e624f18e713f 100644 --- a/src/coreclr/src/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp @@ -405,11 +405,12 @@ bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) case InstructionSet_BMI2_X64: case InstructionSet_LZCNT: case InstructionSet_LZCNT_X64: - case InstructionSet_POPCNT: - case InstructionSet_POPCNT_X64: case InstructionSet_X86Base: case InstructionSet_X86Base_X64: { + // InstructionSet_POPCNT and InstructionSet_POPCNT_X64 are excluded + // even though they are "scalar" ISA because they depend on SSE4.2 + // and Popcnt.IsSupported implies Sse42.IsSupported return true; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs index 3b4898b3769f..7cea12d04c9a 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs @@ -14,6 +14,60 @@ class Runtime_34587 { public static int Main() { + TestLibrary.TestFramework.LogInformation("Supported x86 ISAs:"); + TestLibrary.TestFramework.LogInformation($" AES: {X86Aes.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" AVX: {Avx.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" AVX2: {Avx2.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" BMI1: {Bmi1.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" BMI2: {Bmi2.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" FMA: {Fma.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" LZCNT: {Lzcnt.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" PCLMULQDQ: {Pclmulqdq.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" POPCNT: {Popcnt.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE: {Sse.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE2: {Sse2.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE3: {Sse3.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE4.1: {Sse41.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE4.2: {Sse42.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSSE3: {Ssse3.IsSupported}"); + + TestLibrary.TestFramework.LogInformation("Supported x64 ISAs:"); + TestLibrary.TestFramework.LogInformation($" AES.X64: {X86Aes.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" AVX.X64: {Avx.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" AVX2.X64: {Avx2.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" BMI1.X64: {Bmi1.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" BMI2.X64: {Bmi2.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" FMA.X64: {Fma.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" LZCNT.X64: {Lzcnt.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" PCLMULQDQ.X64: {Pclmulqdq.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" POPCNT.X64: {Popcnt.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE.X64: {Sse.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE2.X64: {Sse2.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE3.X64: {Sse3.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE4.1.X64: {Sse41.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSE4.2.X64: {Sse42.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SSSE3.X64: {Ssse3.X64.IsSupported}"); + + TestLibrary.TestFramework.LogInformation("Supported Arm ISAs:"); + TestLibrary.TestFramework.LogInformation($" AdvSimd: {AdvSimd.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Aes: {ArmAes.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" ArmBase: {ArmBase.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Crc32: {Crc32.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Dp: {Dp.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Rdm: {Rdm.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sha1: {Sha1.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sha256: {Sha256.IsSupported}"); + + TestLibrary.TestFramework.LogInformation("Supported Arm64 ISAs:"); + TestLibrary.TestFramework.LogInformation($" AdvSimd.Arm64: {AdvSimd.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Aes.Arm64: {ArmAes.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" ArmBase.Arm64: {ArmBase.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Crc32.Arm64: {Crc32.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Dp.Arm64: {Dp.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Rdm.Arm64: {Rdm.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sha1.Arm64: {Sha1.Arm64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sha256.Arm64: {Sha256.Arm64.IsSupported}"); + bool succeeded = true; succeeded &= ValidateArm(); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.csproj index 5d49e8d49736..17923c1464d4 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.csproj @@ -10,4 +10,7 @@ + + + From 0bed2de8ed48e7d8ccb0bb7e6c878e22d0b2fa14 Mon Sep 17 00:00:00 2001 From: Next Turn <45985406+NextTurn@users.noreply.github.com> Date: Fri, 24 Jul 2020 03:10:43 +0800 Subject: [PATCH 014/755] Write error events for service errors (#39766) * Write error events for service errors * Explicitly specify EventLogEntryType.Error --- .../src/System/ServiceProcess/ServiceBase.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index 00a392a2bec0..f4ef7e7467f4 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -412,7 +412,7 @@ private unsafe void DeferredContinue() catch (Exception e) { _status.currentState = ServiceControlStatus.STATE_PAUSED; - WriteLogEntry(SR.Format(SR.ContinueFailed, e), true); + WriteLogEntry(SR.Format(SR.ContinueFailed, e), EventLogEntryType.Error); // We re-throw the exception so that the advapi32 code can report // ERROR_EXCEPTION_IN_SERVICE as it would for native services. @@ -434,7 +434,7 @@ private void DeferredCustomCommand(int command) } catch (Exception e) { - WriteLogEntry(SR.Format(SR.CommandFailed, e), true); + WriteLogEntry(SR.Format(SR.CommandFailed, e), EventLogEntryType.Error); // We should re-throw the exception so that the advapi32 code can report // ERROR_EXCEPTION_IN_SERVICE as it would for native services. @@ -455,7 +455,7 @@ private unsafe void DeferredPause() catch (Exception e) { _status.currentState = ServiceControlStatus.STATE_RUNNING; - WriteLogEntry(SR.Format(SR.PauseFailed, e), true); + WriteLogEntry(SR.Format(SR.PauseFailed, e), EventLogEntryType.Error); // We re-throw the exception so that the advapi32 code can report // ERROR_EXCEPTION_IN_SERVICE as it would for native services. @@ -482,7 +482,7 @@ private void DeferredPowerEvent(int eventType, IntPtr eventData) } catch (Exception e) { - WriteLogEntry(SR.Format(SR.PowerEventFailed, e), true); + WriteLogEntry(SR.Format(SR.PowerEventFailed, e), EventLogEntryType.Error); // We rethrow the exception so that advapi32 code can report // ERROR_EXCEPTION_IN_SERVICE as it would for native services. @@ -498,7 +498,7 @@ private void DeferredSessionChange(int eventType, int sessionId) } catch (Exception e) { - WriteLogEntry(SR.Format(SR.SessionChangeFailed, e), true); + WriteLogEntry(SR.Format(SR.SessionChangeFailed, e), EventLogEntryType.Error); // We rethrow the exception so that advapi32 code can report // ERROR_EXCEPTION_IN_SERVICE as it would for native services. @@ -530,7 +530,7 @@ private unsafe void DeferredStop() { _status.currentState = previousState; SetServiceStatus(_statusHandle, pStatus); - WriteLogEntry(SR.Format(SR.StopFailed, e), true); + WriteLogEntry(SR.Format(SR.StopFailed, e), EventLogEntryType.Error); throw; } } @@ -556,7 +556,7 @@ private unsafe void DeferredShutdown() } catch (Exception e) { - WriteLogEntry(SR.Format(SR.ShutdownFailed, e), true); + WriteLogEntry(SR.Format(SR.ShutdownFailed, e), EventLogEntryType.Error); throw; } } @@ -641,7 +641,7 @@ public static unsafe void Run(ServiceBase[] services) service.Dispose(); if (!res) { - service.WriteLogEntry(SR.Format(SR.StartFailed, errorMessage), true); + service.WriteLogEntry(SR.Format(SR.StartFailed, errorMessage), EventLogEntryType.Error); } } } @@ -847,7 +847,7 @@ private void ServiceQueuedMainCallback(object state) } catch (Exception e) { - WriteLogEntry(SR.Format(SR.StartFailed, e), true); + WriteLogEntry(SR.Format(SR.StartFailed, e), EventLogEntryType.Error); _status.currentState = ServiceControlStatus.STATE_STOPPED; // We capture the exception so that it can be propagated @@ -900,7 +900,7 @@ public unsafe void ServiceMainCallback(int argCount, IntPtr argPointer) if (_statusHandle == (IntPtr)0) { string errorMessage = new Win32Exception().Message; - WriteLogEntry(SR.Format(SR.StartFailed, errorMessage), true); + WriteLogEntry(SR.Format(SR.StartFailed, errorMessage), EventLogEntryType.Error); } _status.controlsAccepted = _acceptedCommands; @@ -943,21 +943,21 @@ public unsafe void ServiceMainCallback(int argCount, IntPtr argPointer) statusOK = SetServiceStatus(_statusHandle, pStatus); if (!statusOK) { - WriteLogEntry(SR.Format(SR.StartFailed, new Win32Exception().Message), true); + WriteLogEntry(SR.Format(SR.StartFailed, new Win32Exception().Message), EventLogEntryType.Error); _status.currentState = ServiceControlStatus.STATE_STOPPED; SetServiceStatus(_statusHandle, pStatus); } } } - private void WriteLogEntry(string message, bool error = false) + private void WriteLogEntry(string message, EventLogEntryType type = EventLogEntryType.Information) { // EventLog failures shouldn't affect the service operation try { if (AutoLog) { - EventLog.WriteEntry(message); + EventLog.WriteEntry(message, type); } } catch From 8d5e475ddafde08253968bd25e25346119210086 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 23 Jul 2020 14:01:07 -0700 Subject: [PATCH 015/755] Add @dotnet/jit-contrib to CODEOWNERS (#39862) --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3f2a376ee711..e5a4552409f5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,6 +7,12 @@ /src/libraries/System.Buffers/ @ahsonkhan /src/libraries/System.Memory/ @ahsonkhan +# CoreCLR Code Owners + +/src/coreclr/src/inc/corinfo.h @dotnet/jit-contrib +/src/coreclr/src/inc/corjit.h @dotnet/jit-contrib +/src/coreclr/src/jit/ @dotnet/jit-contrib + # Mono Code Owners /src/mono @marek-safar From 9a74d3baf87060daff92adcbb037ddd4aad62993 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Thu, 23 Jul 2020 14:05:35 -0700 Subject: [PATCH 016/755] Remove a new assert that can fire with unsafe code and type casts (#38912) --- src/coreclr/src/jit/gentree.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 03b1d7ef87f1..98c47e3eb55c 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -17471,7 +17471,9 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree) { CORINFO_FIELD_HANDLE fieldHnd = fieldSeq->m_fieldHnd; CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &structHnd); - assert(fieldCorType == CORINFO_TYPE_VALUECLASS); + // With unsafe code and type casts + // this can return a primitive type and have nullptr for structHnd + // see runtime/issues/38541 } } } From bac644a17416eba863ca6fda5a177fefee1e9b15 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 23 Jul 2020 14:06:09 -0700 Subject: [PATCH 017/755] Extend Linker test job timeout to 2 hours (#39847) --- eng/pipelines/runtime-linker-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index ceffb1e237e7..bb51f3c0c736 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -64,6 +64,7 @@ jobs: - Linux_x64 jobParameters: testGroup: innerloop + timeoutInMinutes: 120 nameSuffix: Runtime_Release buildArgs: -s clr+libs -c $(_BuildConfig) extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml From e46da2fbd99556624ae24ad0348ed74361754444 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 23 Jul 2020 23:18:40 +0200 Subject: [PATCH 018/755] Remove obsolete ActiveIssue attributes for #23972 (#39842) --- .../Hosting/Core/CompositionHostTests.cs | 10 --- .../Hosting/Core/CompositionOperationTests.cs | 4 - .../Hosting/Core/LifetimeContextTests.cs | 10 --- .../tests/ContainerConfigurationTests.cs | 20 ----- .../tests/ReflectionTests.cs | 1 - .../tests/ActivationEventOrderingTests.cs | 1 - .../tests/CardinalityTests.cs | 2 - .../tests/CircularityTests.cs | 9 --- .../CompositionContextExtensionsTests.cs | 1 - .../tests/ConcurrencyTests.cs | 1 - .../tests/ConstraintTests.cs | 4 - .../tests/CustomerReportedMetadataBug.cs | 1 - .../tests/DictionaryImportTests.cs | 6 -- .../tests/DiscoveryTests.cs | 8 -- .../tests/ErrorMessageQualityTests.cs | 5 -- .../tests/ExportDescriptorProviderTests.cs | 2 - .../tests/ExportFactoryTests.cs | 8 -- .../tests/ExportMetadataDiscoveryTests.cs | 7 -- .../tests/ImportManyTests.cs | 2 - .../tests/ImportOrderingTests.cs | 2 - .../tests/InheritanceTests.cs | 12 --- .../System.Composition/tests/LazyTests.cs | 4 - .../tests/LightContainerTests.cs | 8 -- .../tests/LooseImportsTests.cs | 1 - .../tests/MetadataConstraintTests.cs | 5 -- .../System.Composition/tests/MetadataTests.cs | 9 --- .../tests/MetadataViewGenerationTests.cs | 6 -- .../tests/OpenGenericsTests.cs | 10 --- .../tests/OptionalImportTests.cs | 2 - .../tests/PropertyExportTests.cs | 2 - .../System.Composition/tests/SharingTests.cs | 12 --- .../tests/DirectoryObjectSecurityTests.cs | 1 - .../tests/BinaryFormatterTestData.cs | 73 ++++++++----------- 33 files changed, 32 insertions(+), 217 deletions(-) diff --git a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs index 0f74a27fdbb1..f70334512044 100644 --- a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs +++ b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs @@ -10,7 +10,6 @@ namespace System.Composition.Hosting.Core.Tests public class CompositionHostTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_CompositionContextContract_ReturnsExpected() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -21,7 +20,6 @@ public void GetExport_CompositionContextContract_ReturnsExpected() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_MultipleDependencies_ReturnsExpected() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new MultipleDependency())) @@ -56,7 +54,6 @@ public override IEnumerable GetExportDescriptors(Compos } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] [InlineData(typeof(int), new Type[] { typeof(int) })] [InlineData(typeof(IList<>), new Type[] { typeof(IList<>) })] [InlineData(typeof(ICollection<>), new Type[] { typeof(ICollection<>) })] @@ -86,7 +83,6 @@ public void GetExport_LazyOrExportFactoryContractType_ReturnsExpected(Type type, } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] [InlineData(typeof(string[]), new Type[] { typeof(string[]), typeof(string) })] [InlineData(typeof(IList), new Type[] { typeof(IList), typeof(string) })] [InlineData(typeof(ICollection), new Type[] { typeof(ICollection), typeof(string) })] @@ -105,7 +101,6 @@ public void GetExport_ImoportManyWithMetadataConstraints_ReturnsExpected(Type co } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] [InlineData(typeof(ExportFactory), null, new Type[] { typeof(int), typeof(ExportFactory) })] [InlineData(typeof(ExportFactory), new string[] { "1", "2", "3" }, new Type[] { typeof(int), typeof(ExportFactory) })] [InlineData(typeof(ExportFactory), null, new Type[] { typeof(int), typeof(ExportFactory) })] @@ -134,7 +129,6 @@ public override IEnumerable GetExportDescriptors(Compos } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] [InlineData(typeof(Lazy))] [InlineData(typeof(Lazy>))] [InlineData(typeof(Lazy))] @@ -148,7 +142,6 @@ public void GetExport_InvalidMetadata_ThrowsComposititionFailedException(Type ty } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_AbstractMetadata_ThrowsInvalidOperationException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -158,7 +151,6 @@ public void GetExport_AbstractMetadata_ThrowsInvalidOperationException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_NullProviderInProviders_ThrowsNullReferenceException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[] { null })) @@ -177,7 +169,6 @@ public void TryGetExport_NullContract_ThrowsArgumentNullException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_MultipleReturns_ThrowsCompositionFailedException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new MultiplePromises())) @@ -200,7 +191,6 @@ public override IEnumerable GetExportDescriptors(Compos } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_FailedDependency_ThrowsCompositionFailedException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new FailedDependency())) diff --git a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionOperationTests.cs b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionOperationTests.cs index 15c61603be55..d66a21c433ac 100644 --- a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionOperationTests.cs +++ b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionOperationTests.cs @@ -9,7 +9,6 @@ namespace System.Composition.Hosting.Core.Tests public class CompositionOperationTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void Run_ValidContextAndAction_ReturnsExpected() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -49,7 +48,6 @@ public void Run_NullOutmostContext_ThrowsArgumentNullException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void Run_NullActivator_ThrowsArgumentNullException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -62,7 +60,6 @@ public void Run_NullActivator_ThrowsArgumentNullException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AddNonPrequisiteAction_NullAction_ThrowsArgumentNullException() { object Activator(LifetimeContext context, CompositionOperation operation) @@ -81,7 +78,6 @@ object Activator(LifetimeContext context, CompositionOperation operation) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AddPostCompositionAction_NullAction_ThrowsArgumentNullException() { object Activator(LifetimeContext context, CompositionOperation operation) diff --git a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/LifetimeContextTests.cs b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/LifetimeContextTests.cs index a7a77d7e25d5..2cc06006ef96 100644 --- a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/LifetimeContextTests.cs +++ b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/LifetimeContextTests.cs @@ -14,7 +14,6 @@ public void AllocateSharingId_InvokeMultipleTimes_ReturnsDifferentValue() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AddBoundInstance_NonNullInstance_DisposesInstanceOnDisposal() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -35,7 +34,6 @@ public void AddBoundInstance_NonNullInstance_DisposesInstanceOnDisposal() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AddBoundInstance_NullInstance_ThrowsNullReferenceExceptionOnDisposal() { CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]); @@ -47,7 +45,6 @@ public void AddBoundInstance_NullInstance_ThrowsNullReferenceExceptionOnDisposal } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AddBoundInstance_Disposed_ThrowsObjectDisposedException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -61,7 +58,6 @@ public void AddBoundInstance_Disposed_ThrowsObjectDisposedException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetOrCreate_ValidActivatorDuringInitialization_Success() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -90,7 +86,6 @@ object GetOrCreateActivate(LifetimeContext getOrCreateContext, CompositionOperat } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetOrCreate_ValidActivatorAfterInitialization_Success() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -120,7 +115,6 @@ object Activator(LifetimeContext activatorContext, CompositionOperation activato } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetOrCreate_NullActivator_ThrowsNullReferenceException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -139,7 +133,6 @@ object Activator(LifetimeContext activatorContext, CompositionOperation activato } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetOrCreate_NullOperation_ThrowsNullReferenceException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -152,7 +145,6 @@ public void GetOrCreate_NullOperation_ThrowsNullReferenceException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void FindContextWithin_NullSharingBoundary_ReturnsRoot() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -165,7 +157,6 @@ public void FindContextWithin_NullSharingBoundary_ReturnsRoot() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void FindContextWithin_UnknownSharingBoundary_ThrowsCompositionFailedException() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) @@ -178,7 +169,6 @@ public void FindContextWithin_UnknownSharingBoundary_ThrowsCompositionFailedExce } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ToString_NoParent_ReturnsExpected() { using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0])) diff --git a/src/libraries/System.Composition.TypedParts/tests/ContainerConfigurationTests.cs b/src/libraries/System.Composition.TypedParts/tests/ContainerConfigurationTests.cs index 2edd7f7987eb..480cd9e537f9 100644 --- a/src/libraries/System.Composition.TypedParts/tests/ContainerConfigurationTests.cs +++ b/src/libraries/System.Composition.TypedParts/tests/ContainerConfigurationTests.cs @@ -15,7 +15,6 @@ namespace System.Composition.Hosting.Tests public class ContainerConfigurationTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithProvider_ValidProvider_RegistersProvider() { var configuration = new ContainerConfiguration(); @@ -62,7 +61,6 @@ public void WithProvider_NullProvider_ThrowsArgumentNullException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithDefaultConventions_PartWithNoMatchingConvention_Success() { var conventions = new ConventionBuilder(); @@ -77,7 +75,6 @@ public void WithDefaultConventions_PartWithNoMatchingConvention_Success() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithDefaultConventions_IEnumerablePartsWithNoMatchingConvention_Success() { var conventions = new ConventionBuilder(); @@ -92,7 +89,6 @@ public void WithDefaultConventions_IEnumerablePartsWithNoMatchingConvention_Succ } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithDefaultConventions_PartsArrayWithNoMatchingConvention_Success() { var conventions = new ConventionBuilder(); @@ -107,7 +103,6 @@ public void WithDefaultConventions_PartsArrayWithNoMatchingConvention_Success() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithDefaultConventions_PartTNoMatchingConvention_Success() { var conventions = new ConventionBuilder(); @@ -143,7 +138,6 @@ public void WithDefaultConventions_AlreadyHasDefaultConventions_ThrowsInvalidOpe } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithPartT_Convention_Success() { var conventions = new ConventionBuilder(); @@ -157,7 +151,6 @@ public void WithPartT_Convention_Success() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithPart_Convention_Success() { var conventions = new ConventionBuilder(); @@ -179,7 +172,6 @@ public void WithPart_NullPartType_ThrowsArgumentNullException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WithParts_Convention_Success() { var conventions = new ConventionBuilder(); @@ -262,7 +254,6 @@ public void WithAssemby_Null_ThrowsNullReferenceExceptionOnCreation() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_ExportedSubClass_Success() { CompositionHost container = new ContainerConfiguration() @@ -283,7 +274,6 @@ public class Base } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_OpenGenericTypes_Success() { var conventions = new ConventionBuilder(); @@ -313,7 +303,6 @@ public EFRepository(IContainer test) { } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_ImportConventionsWithInheritedProperties_Success() { var conventions = new ConventionBuilder(); @@ -341,7 +330,6 @@ public class BaseWithImport public class DerivedFromBaseWithImport : BaseWithImport { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_ExportConventionsWithInheritedProperties_Success() { var conventions = new ConventionBuilder(); @@ -363,7 +351,6 @@ public class BaseWithExport public class DerivedFromBaseWithExport : BaseWithExport { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_ExportsToInheritedProperties_DontInterfereWithBase() { var conventions = new ConventionBuilder(); @@ -387,7 +374,6 @@ public class BaseWithExport2 public class DerivedFromBaseWithExport2 : BaseWithExport { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_HasConventions_ClassExportsAreNotInherited() { CompositionHost container = new ContainerConfiguration() @@ -397,7 +383,6 @@ public void CreateContainer_HasConventions_ClassExportsAreNotInherited() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_HasConventions_PropertyExportsAreNotInherited() { CompositionHost container = new ContainerConfiguration() @@ -420,7 +405,6 @@ public class DerivedFromBaseWithDeclaredExports : BaseWithDeclaredExports { } public class CustomExport : ExportAttribute { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_HasConventions_CustomAttributesAreNotInherited() { CompositionHost container = new ContainerConfiguration() @@ -435,7 +419,6 @@ public class BaseWithCustomExport { } public class DerivedFromBaseWithCustomExport : BaseWithCustomExport { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_OpenGenericTypePart_Success() { ContainerConfiguration configuration = new ContainerConfiguration().WithParts(typeof(GenericExportedType<>)); @@ -489,7 +472,6 @@ public void CreateContainer_UnassignableType_ThrowsCompositionFailedException() public class ContractExportedType { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_AbstractOrStructType_Success() { ContainerConfiguration configuration = new ContainerConfiguration().WithParts(typeof(AbstractClass), typeof(StructType)); @@ -503,7 +485,6 @@ public abstract class AbstractClass { } public struct StructType { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_MetadataProperty_Success() { ContainerConfiguration configuration = new ContainerConfiguration().WithPart(typeof(MetadataProperty)); @@ -541,7 +522,6 @@ public class MetadataProperty } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreateContainer_MetadataClass_Success() { ContainerConfiguration configuration = new ContainerConfiguration().WithPart(typeof(MetadataClass)); diff --git a/src/libraries/System.Composition.TypedParts/tests/ReflectionTests.cs b/src/libraries/System.Composition.TypedParts/tests/ReflectionTests.cs index 5ca91f762aa7..291a1e5bbf13 100644 --- a/src/libraries/System.Composition.TypedParts/tests/ReflectionTests.cs +++ b/src/libraries/System.Composition.TypedParts/tests/ReflectionTests.cs @@ -27,7 +27,6 @@ public class ReflectionTests /// revert to a default value during GetExport. /// [ConditionalFact(nameof(HasMultiplerProcessors))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultiThreadedGetExportsWorkWithImportingConstuctor() { var errors = new ConcurrentBag(); diff --git a/src/libraries/System.Composition/tests/ActivationEventOrderingTests.cs b/src/libraries/System.Composition/tests/ActivationEventOrderingTests.cs index d1e172e76726..f023b805963b 100644 --- a/src/libraries/System.Composition/tests/ActivationEventOrderingTests.cs +++ b/src/libraries/System.Composition/tests/ActivationEventOrderingTests.cs @@ -31,7 +31,6 @@ public void OnImportsSatisfied() public class ActivationEventOrderingTests : ContainerTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void OnImportsSatisfiedIsCalledAfterPropertyInjection() { var cc = CreateContainer(typeof(TracksImportSatisfaction), typeof(Imported)); diff --git a/src/libraries/System.Composition/tests/CardinalityTests.cs b/src/libraries/System.Composition/tests/CardinalityTests.cs index 76b2b8bb9bcd..149287cfa872 100644 --- a/src/libraries/System.Composition/tests/CardinalityTests.cs +++ b/src/libraries/System.Composition/tests/CardinalityTests.cs @@ -31,7 +31,6 @@ public UsesLog(ILog log) { } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void RequestingOneWhereMultipleArePresentFails() { var c = CreateContainer(typeof(LogA), typeof(LogB)); @@ -42,7 +41,6 @@ public void RequestingOneWhereMultipleArePresentFails() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportingOneWhereMultipleArePresentFails() { var c = CreateContainer(typeof(LogA), typeof(LogB), typeof(UsesLog)); diff --git a/src/libraries/System.Composition/tests/CircularityTests.cs b/src/libraries/System.Composition/tests/CircularityTests.cs index 707bdde3f2e6..98a4f0b36efd 100644 --- a/src/libraries/System.Composition/tests/CircularityTests.cs +++ b/src/libraries/System.Composition/tests/CircularityTests.cs @@ -116,7 +116,6 @@ public PrDepB(PrDepA a) { } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanHandleDefinitionCircularity() { var cc = CreateContainer(typeof(ACircular), typeof(BLazy)); @@ -126,7 +125,6 @@ public void CanHandleDefinitionCircularity() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanHandleDefinitionCircularity2() { var cc = CreateContainer(typeof(ACircular), typeof(BLazy)); @@ -135,7 +133,6 @@ public void CanHandleDefinitionCircularity2() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesPropertyPropertyCircularity() { var cc = CreateContainer(typeof(PropertyPropertyA), typeof(PropertyPropertyB)); @@ -144,7 +141,6 @@ public void HandlesPropertyPropertyCircularity() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesPropertyPropertyCircularityReversed() { var cc = CreateContainer(typeof(PropertyPropertyA), typeof(PropertyPropertyB)); @@ -153,7 +149,6 @@ public void HandlesPropertyPropertyCircularityReversed() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesConstructorPropertyCircularity() { var cc = CreateContainer(typeof(ConstructorPropertyA), typeof(ConstructorPropertyB)); @@ -162,7 +157,6 @@ public void HandlesConstructorPropertyCircularity() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesConstructorPropertyCircularityReversed() { var cc = CreateContainer(typeof(ConstructorPropertyA), typeof(ConstructorPropertyB)); @@ -171,7 +165,6 @@ public void HandlesConstructorPropertyCircularityReversed() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesMetadataCircularity() { var cc = CreateContainer(typeof(MetadataCircularityA), typeof(MetadataCircularityB)); @@ -182,7 +175,6 @@ public void HandlesMetadataCircularity() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SharedPartCanHaveNonPrereqDependencyOnSelf() { var cc = CreateContainer(typeof(NonPrereqSelfDependency)); @@ -191,7 +183,6 @@ public void SharedPartCanHaveNonPrereqDependencyOnSelf() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void PrerequisiteCircularitiesAreDetected() { var cc = CreateContainer(typeof(PrDepA), typeof(PrDepB)); diff --git a/src/libraries/System.Composition/tests/CompositionContextExtensionsTests.cs b/src/libraries/System.Composition/tests/CompositionContextExtensionsTests.cs index 0ed5f7db0575..6e555c5ab25a 100644 --- a/src/libraries/System.Composition/tests/CompositionContextExtensionsTests.cs +++ b/src/libraries/System.Composition/tests/CompositionContextExtensionsTests.cs @@ -15,7 +15,6 @@ public class CompositionContextExtensionsTests : ContainerTests public interface IUnregistered { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GettingAnOptionalExportThatDoesntExistReturnsNull() { var c = CreateContainer(); diff --git a/src/libraries/System.Composition/tests/ConcurrencyTests.cs b/src/libraries/System.Composition/tests/ConcurrencyTests.cs index 8e76ea3b1196..6801f55a57d3 100644 --- a/src/libraries/System.Composition/tests/ConcurrencyTests.cs +++ b/src/libraries/System.Composition/tests/ConcurrencyTests.cs @@ -28,7 +28,6 @@ public void OnImportsSatisfied() // This does not test the desired behaviour deterministically, // but is close enough to be repeatable at least on my machine :) [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SharedInstancesAreNotVisibleUntilActivationCompletes() { var c = CreateContainer(typeof(PausesDuringActivation)); diff --git a/src/libraries/System.Composition/tests/ConstraintTests.cs b/src/libraries/System.Composition/tests/ConstraintTests.cs index 03de969a50be..8efacc487485 100644 --- a/src/libraries/System.Composition/tests/ConstraintTests.cs +++ b/src/libraries/System.Composition/tests/ConstraintTests.cs @@ -41,7 +41,6 @@ public class UnrelatedThings : ObservableCollection, IUnrelatedThing } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GenericPartDiscoveryIgnoresAPartAndDoesntThrowAnExceptionWhenItsConstraintOnTypeParameterIsNotAssignableFromTheExportTarget() { var container = CreateContainer(typeof(ThingHandler<>), typeof(BookHandler<>)); @@ -53,7 +52,6 @@ public void GenericPartDiscoveryIgnoresAPartAndDoesntThrowAnExceptionWhenItsCons } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GenericPartDiscoveryIncludesAPartWhenItsConstraintOnTypeParameterIsAssignableFromTheExportTarget() { var container = CreateContainer(typeof(ThingHandler<>), typeof(BookHandler<>)); @@ -66,7 +64,6 @@ public void GenericPartDiscoveryIncludesAPartWhenItsConstraintOnTypeParameterIsA } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_ComplexConstraint_ExportSuccessful() { CompositionContext container = CreateContainer(typeof(UnrelatedThings<,>)); @@ -79,7 +76,6 @@ public void GetExport_ComplexConstraint_ExportSuccessful() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/23356")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExport_WhereClause_ExportSuccessful() { CompositionContext container = CreateContainer(typeof(InheritedThings<,>)); diff --git a/src/libraries/System.Composition/tests/CustomerReportedMetadataBug.cs b/src/libraries/System.Composition/tests/CustomerReportedMetadataBug.cs index bcb84b5e417a..5a9f99de980f 100644 --- a/src/libraries/System.Composition/tests/CustomerReportedMetadataBug.cs +++ b/src/libraries/System.Composition/tests/CustomerReportedMetadataBug.cs @@ -37,7 +37,6 @@ public class LooseImporter } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SampleServicesCorrectlyImported() { var container = new ContainerConfiguration() diff --git a/src/libraries/System.Composition/tests/DictionaryImportTests.cs b/src/libraries/System.Composition/tests/DictionaryImportTests.cs index 30dc2965e864..8d2b9d0f2b8d 100644 --- a/src/libraries/System.Composition/tests/DictionaryImportTests.cs +++ b/src/libraries/System.Composition/tests/DictionaryImportTests.cs @@ -68,7 +68,6 @@ private CompositionContext CreateContainer(params Type[] types) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DictionaryImportsKeyedByMetadata() { var container = CreateContainer(new[] { typeof(ValueA), typeof(ValueB), typeof(Consumer) }); @@ -81,7 +80,6 @@ public void DictionaryImportsKeyedByMetadata() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DictionaryImportsReceiveMetadataFromNestedAdapters() { var container = CreateContainer(new[] { typeof(ValueA), typeof(ValueB), typeof(LazyConsumer) }); @@ -93,7 +91,6 @@ public void DictionaryImportsReceiveMetadataFromNestedAdapters() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WhenAMetadataKeyIsDuplicatedAnInformativeExceptionIsThrown() { var container = CreateContainer(typeof(ValueA), typeof(ValueA), typeof(Consumer)); @@ -102,7 +99,6 @@ public void WhenAMetadataKeyIsDuplicatedAnInformativeExceptionIsThrown() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WhenAMetadataKeyIsMissingAnInformativeExceptionIsThrown() { var container = CreateContainer(typeof(ValueA), typeof(ValueMissing), typeof(Consumer)); @@ -111,7 +107,6 @@ public void WhenAMetadataKeyIsMissingAnInformativeExceptionIsThrown() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WhenAMetadataValueIsOfTheWrongTypeAnInformativeExceptionIsThrown() { var container = CreateContainer(typeof(ValueA), typeof(NonStringValue), typeof(Consumer)); @@ -120,7 +115,6 @@ public void WhenAMetadataValueIsOfTheWrongTypeAnInformativeExceptionIsThrown() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DictionaryImportsCompatibleWithConventionBuilder() { var rb = new ConventionBuilder(); diff --git a/src/libraries/System.Composition/tests/DiscoveryTests.cs b/src/libraries/System.Composition/tests/DiscoveryTests.cs index 2cfc58a60ded..833001774e4e 100644 --- a/src/libraries/System.Composition/tests/DiscoveryTests.cs +++ b/src/libraries/System.Composition/tests/DiscoveryTests.cs @@ -40,7 +40,6 @@ public class IncompatibleRuleProperty public class NotDiscoverable { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversCustomExportAttributes() { var container = CreateContainer(typeof(UnfairRule)); @@ -49,7 +48,6 @@ public void DiscoversCustomExportAttributes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversCustomExportAttributesUnderConventions() { var container = CreateContainer(new ConventionBuilder(), typeof(UnfairRule)); @@ -58,7 +56,6 @@ public void DiscoversCustomExportAttributesUnderConventions() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void InstanceExportsOfIncompatibleContractsAreDetected() { var x = Assert.Throws(() => CreateContainer(typeof(IncompatibleRule))); @@ -66,7 +63,6 @@ public void InstanceExportsOfIncompatibleContractsAreDetected() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void PropertyExportsOfIncompatibleContractsAreDetected() { var x = Assert.Throws(() => CreateContainer(typeof(IncompatibleRuleProperty))); @@ -74,7 +70,6 @@ public void PropertyExportsOfIncompatibleContractsAreDetected() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ANonDiscoverablePartIsIgnored() { var container = CreateContainer(typeof(NotDiscoverable)); @@ -90,7 +85,6 @@ public class CloudBus : IBus { } public class SpecialCloudBus : CloudBus { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DoesNotDiscoverExportAttributesFromBase() { var container = CreateContainer(typeof(SpecialCloudBus)); @@ -111,7 +105,6 @@ public class HomeController : BaseController } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SatisfiesImportsAppliedToBase() { var container = CreateContainer(typeof(HomeController), typeof(CloudBus)); @@ -129,7 +122,6 @@ public class MultipleImportsOnProperty } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultipleImportAttributesAreDetected() { var c = new ContainerConfiguration() diff --git a/src/libraries/System.Composition/tests/ErrorMessageQualityTests.cs b/src/libraries/System.Composition/tests/ErrorMessageQualityTests.cs index be67604f8664..f0918e392c29 100644 --- a/src/libraries/System.Composition/tests/ErrorMessageQualityTests.cs +++ b/src/libraries/System.Composition/tests/ErrorMessageQualityTests.cs @@ -63,7 +63,6 @@ public class RequiresOnlyOne } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MissingTopLevelExportMessageIsInformative() { var cc = CreateContainer(); @@ -72,7 +71,6 @@ public void MissingTopLevelExportMessageIsInformative() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MissingTopLevelNamedExportMessageIsInformative() { var cc = CreateContainer(); @@ -81,7 +79,6 @@ public void MissingTopLevelNamedExportMessageIsInformative() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MissingDependencyMessageIsInformative() { var cc = CreateContainer(typeof(UserOfUnregistered)); @@ -92,7 +89,6 @@ public void MissingDependencyMessageIsInformative() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CycleMessageIsInformative() { var cc = CreateContainer(typeof(CycleA), typeof(CycleB), typeof(CycleC)); @@ -106,7 +102,6 @@ public void CycleMessageIsInformative() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CardinalityViolationMessageIsInformative() { var cc = CreateContainer(typeof(ShouldBeOne), typeof(ButThereIsAnother), typeof(RequiresOnlyOne)); diff --git a/src/libraries/System.Composition/tests/ExportDescriptorProviderTests.cs b/src/libraries/System.Composition/tests/ExportDescriptorProviderTests.cs index a0371ccf9232..f0d941b54863 100644 --- a/src/libraries/System.Composition/tests/ExportDescriptorProviderTests.cs +++ b/src/libraries/System.Composition/tests/ExportDescriptorProviderTests.cs @@ -40,7 +40,6 @@ public class ExportsObject } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ProvidersCanLocateImplementationsOfAContractItSupports() { var container = new ContainerConfiguration() @@ -53,7 +52,6 @@ public void ProvidersCanLocateImplementationsOfAContractItSupports() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ProvidersCanDetectAbsenceOfAContractItSupports() { var container = new ContainerConfiguration() diff --git a/src/libraries/System.Composition/tests/ExportFactoryTests.cs b/src/libraries/System.Composition/tests/ExportFactoryTests.cs index 385f8b177147..ba9b2757e0f4 100644 --- a/src/libraries/System.Composition/tests/ExportFactoryTests.cs +++ b/src/libraries/System.Composition/tests/ExportFactoryTests.cs @@ -105,7 +105,6 @@ public void Dispose() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SharedPartsAreSharedBetweenAllScopes() { var cc = CreateContainer(typeof(SharedUnbounded), typeof(DataConsistencyBoundaryProvider)); @@ -116,7 +115,6 @@ public void SharedPartsAreSharedBetweenAllScopes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void TheSameSharedInstanceIsReusedWithinItsSharingBoundary() { var cc = CreateContainer(typeof(SharedBoundedByDC), typeof(SharedPartConsumer), typeof(DataConsistencyBoundaryProvider)); @@ -130,7 +128,6 @@ public void TheSameSharedInstanceIsReusedWithinItsSharingBoundary() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void NonSharedInstancesCreatedByAnExportFactoryAreControlledByTheirExportLifetimeContext() { var cc = CreateContainer(typeof(A), typeof(UseExportFactory)); @@ -143,7 +140,6 @@ public void NonSharedInstancesCreatedByAnExportFactoryAreControlledByTheirExport } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DependenciesOfSharedPartsAreResolvedInTheGlobalScope() { var cc = new ContainerConfiguration() @@ -159,7 +155,6 @@ public void DependenciesOfSharedPartsAreResolvedInTheGlobalScope() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WhenABoundaryIsPresentBoundedPartsCannotBeCreatedOutsideIt() { var container = CreateContainer(typeof(DataConsistencyBoundaryProvider), typeof(SharedBoundedByDC)); @@ -167,7 +162,6 @@ public void WhenABoundaryIsPresentBoundedPartsCannotBeCreatedOutsideIt() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void TheProductOfAnExportFactoryCanBeDisposedDuringDisposalOfTheParent() { var container = new ContainerConfiguration() @@ -199,7 +193,6 @@ public class AConsumer } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ExportFactoryCanBeComposedWithImportManyAndNames() { var cc = CreateContainer(typeof(AConsumer), typeof(A1), typeof(A2)); @@ -233,7 +226,6 @@ public class HasFactory } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void WhenReleasingAnExportFromAnExportFactoryItsNonSharedDependenciesAreDisposed() { var cc = CreateContainer(typeof(Disposable), typeof(HasDisposableDependency), typeof(HasFactory)); diff --git a/src/libraries/System.Composition/tests/ExportMetadataDiscoveryTests.cs b/src/libraries/System.Composition/tests/ExportMetadataDiscoveryTests.cs index f20437e16474..28f7e822a498 100644 --- a/src/libraries/System.Composition/tests/ExportMetadataDiscoveryTests.cs +++ b/src/libraries/System.Composition/tests/ExportMetadataDiscoveryTests.cs @@ -51,7 +51,6 @@ public class Prioritized {[DefaultValue(0)] public int Priority { get; set; } } public class MultipleNames { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversMetadataSpecifiedUsingMetadataAttributeOnExportAttribute() { var cc = CreateContainer(typeof(SingleNamedExport)); @@ -60,7 +59,6 @@ public void DiscoversMetadataSpecifiedUsingMetadataAttributeOnExportAttribute() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void IfMetadataIsSpecifiedOnAnExportAttributeOtherExportsDoNotHaveIt() { var cc = CreateContainer(typeof(MultipleExportsOneNamedAndBothPrioritized)); @@ -70,7 +68,6 @@ public void IfMetadataIsSpecifiedOnAnExportAttributeOtherExportsDoNotHaveIt() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversStandaloneExportMetadata() { var cc = CreateContainer(typeof(NamedAndPrioritized)); @@ -79,7 +76,6 @@ public void DiscoversStandaloneExportMetadata() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversStandaloneExportMetadataUsingMetadataAttributes() { var cc = CreateContainer(typeof(NamedWithCustomMetadata)); @@ -88,7 +84,6 @@ public void DiscoversStandaloneExportMetadataUsingMetadataAttributes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void StandaloneExportMetadataAppliesToAllExportsOnAMember() { var cc = CreateContainer(typeof(MultipleExportsOneNamedAndBothPrioritized)); @@ -98,7 +93,6 @@ public void StandaloneExportMetadataAppliesToAllExportsOnAMember() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultiplePiecesOfMetadataAreCombinedIntoAnArray() { var cc = CreateContainer(typeof(MultipleNames)); @@ -119,7 +113,6 @@ public MultipleExportsNonDefaultConstructor(ConstructorImported c) { } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultipleExportsCanBeRetrievedWhenANonDefaultConstructorExists() { var c = CreateContainer(typeof(ConstructorImported), typeof(MultipleExportsNonDefaultConstructor)); diff --git a/src/libraries/System.Composition/tests/ImportManyTests.cs b/src/libraries/System.Composition/tests/ImportManyTests.cs index 63a4c7674446..f9c02063055a 100644 --- a/src/libraries/System.Composition/tests/ImportManyTests.cs +++ b/src/libraries/System.Composition/tests/ImportManyTests.cs @@ -41,7 +41,6 @@ public ImportManyPropsOfA() } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportsMany() { var cc = CreateContainer(typeof(A), typeof(A2), typeof(ImportManyIA)); @@ -50,7 +49,6 @@ public void ImportsMany() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportsManyProperties() { var cc = CreateContainer(typeof(A), typeof(A2), typeof(ImportManyPropsOfA)); diff --git a/src/libraries/System.Composition/tests/ImportOrderingTests.cs b/src/libraries/System.Composition/tests/ImportOrderingTests.cs index 717f38b30ba4..0372c95e797b 100644 --- a/src/libraries/System.Composition/tests/ImportOrderingTests.cs +++ b/src/libraries/System.Composition/tests/ImportOrderingTests.cs @@ -48,7 +48,6 @@ public class HasImportedItems } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CollectionsImportedWithAnOrderingAttributeComeInOrder() { var container = CreateExtendedContainer(typeof(HasImportedItems), typeof(Item1), typeof(Item4), typeof(Item2), typeof(Item3)); @@ -62,7 +61,6 @@ public void CollectionsImportedWithAnOrderingAttributeComeInOrder() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void IfAnItemIsMissingMetadataAnInformativeExceptionIsThrown() { var container = CreateExtendedContainer(typeof(HasImportedItems), typeof(Item1), typeof(ItemWithoutOrder)); diff --git a/src/libraries/System.Composition/tests/InheritanceTests.cs b/src/libraries/System.Composition/tests/InheritanceTests.cs index 79292823345e..43d1f276723b 100644 --- a/src/libraries/System.Composition/tests/InheritanceTests.cs +++ b/src/libraries/System.Composition/tests/InheritanceTests.cs @@ -25,7 +25,6 @@ public class Base public class Derived : Base { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ClassExportsAreNotInherited() { var cc = CreateContainer(typeof(Derived)); @@ -34,7 +33,6 @@ public void ClassExportsAreNotInherited() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void PropertyExportsAreNotInherited() { var cc = CreateContainer(typeof(Derived)); @@ -46,7 +44,6 @@ public void PropertyExportsAreNotInherited() public class ExportingDerived : Base { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ExportsAtTheClassLevelAreAppliedIgnoringBaseExports() { var cc = CreateContainer(typeof(ExportingDerived)); @@ -87,7 +84,6 @@ public class OverridingImporter : BaseImporter public class NonOverridingImporter : BaseImporter { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportsOnOverriddenPropertiesOverrideImportsOnTheBase() { var c = CreateContainer(typeof(Exporter), typeof(OverridingImporter), typeof(NonOverridingImporter)); @@ -98,7 +94,6 @@ public void ImportsOnOverriddenPropertiesOverrideImportsOnTheBase() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void LooseImportsOnDerivedPropertiesOverrideImportsOnTheBase() { var c = CreateContainer(typeof(Exporter)); @@ -111,7 +106,6 @@ public void LooseImportsOnDerivedPropertiesOverrideImportsOnTheBase() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportsOnBaseAreInherited() { var c = CreateContainer(typeof(Exporter), typeof(NonOverridingImporter)); @@ -121,7 +115,6 @@ public void ImportsOnBaseAreInherited() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void LooseImportsOnBaseAreInherited() { var c = CreateContainer(typeof(Exporter)); @@ -137,7 +130,6 @@ public class NotDiscoverableBase { } public class DiscoverableDerived : NotDiscoverableBase { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void PartNotDiscoverableAttributeIsNotInherited() { var c = CreateContainer(typeof(DiscoverableDerived)); @@ -152,7 +144,6 @@ public class SharedBase { } public class SharedDerived : SharedBase { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void PartMetadataIsNotInherited() { var c = CreateContainer(typeof(SharedDerived)); @@ -173,7 +164,6 @@ public class HasImportsSatisfied public class InheritsImportsSatisfied : HasImportsSatisfied { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void OnImportsSatisfiedAttributeIsInherited() { var c = CreateContainer(typeof(InheritsImportsSatisfied)); @@ -192,7 +182,6 @@ public class AHandler : IHandler { } public class ABHandler : AHandler { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MetadataIsOnlyDrawnFromTheTypeToWhichItIsApplied() { var c = CreateContainer(typeof(ABHandler)); @@ -214,7 +203,6 @@ public class DerivedOverrideExporter : BaseVirtualExporter } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ExportsOnOverridePropertiesOverrideExportsOnTheBase() { var c = CreateContainer(typeof(DerivedOverrideExporter)); diff --git a/src/libraries/System.Composition/tests/LazyTests.cs b/src/libraries/System.Composition/tests/LazyTests.cs index 0af4972d8a22..75899fa7abb0 100644 --- a/src/libraries/System.Composition/tests/LazyTests.cs +++ b/src/libraries/System.Composition/tests/LazyTests.cs @@ -35,7 +35,6 @@ public class NamedFred { } public class Named { public string Name { get; set; } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ComposesLazily() { var cc = CreateContainer(typeof(A), typeof(BLazy)); @@ -44,7 +43,6 @@ public void ComposesLazily() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SupportsExportMetadata() { var cc = CreateContainer(typeof(NamedFred)); @@ -53,7 +51,6 @@ public void SupportsExportMetadata() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ReturnsExportMetadataAsADictionary() { var cc = CreateContainer(typeof(NamedFred)); @@ -75,7 +72,6 @@ public class AConsumer } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void LazyCanBeComposedWithImportManyAndNames() { var cc = CreateContainer(typeof(AConsumer), typeof(A1), typeof(A2)); diff --git a/src/libraries/System.Composition/tests/LightContainerTests.cs b/src/libraries/System.Composition/tests/LightContainerTests.cs index 1ce818bf48f7..a7933d565619 100644 --- a/src/libraries/System.Composition/tests/LightContainerTests.cs +++ b/src/libraries/System.Composition/tests/LightContainerTests.cs @@ -53,7 +53,6 @@ public class HasPropertyA } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CreatesInstanceWithNoDependencies() { var cc = CreateContainer(typeof(A)); @@ -62,7 +61,6 @@ public void CreatesInstanceWithNoDependencies() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DefaultLifetimeIsNonShared() { var cc = CreateContainer(typeof(A)); @@ -72,7 +70,6 @@ public void DefaultLifetimeIsNonShared() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void Composes() { var cc = CreateContainer(typeof(A), typeof(B)); @@ -81,7 +78,6 @@ public void Composes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanSpecifyExportsWithConventionBuilder() { var rb = new ConventionBuilder(); @@ -92,7 +88,6 @@ public void CanSpecifyExportsWithConventionBuilder() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanSpecifyLifetimeWithConventionBuilder() { var rb = new ConventionBuilder(); @@ -104,7 +99,6 @@ public void CanSpecifyLifetimeWithConventionBuilder() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void InjectsPropertyImports() { var rb = new ConventionBuilder(); @@ -115,7 +109,6 @@ public void InjectsPropertyImports() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void VerifyAssemblyNameCanBeUsedWithContainer() { var test = new ContainerConfiguration() @@ -127,7 +120,6 @@ public void VerifyAssemblyNameCanBeUsedWithContainer() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void VerifyAssemblyWithTwoBaseTypeWithOnlyOneExportedWorks() { var test = new ContainerConfiguration() diff --git a/src/libraries/System.Composition/tests/LooseImportsTests.cs b/src/libraries/System.Composition/tests/LooseImportsTests.cs index cf7d03bbba2e..0dfd80c996eb 100644 --- a/src/libraries/System.Composition/tests/LooseImportsTests.cs +++ b/src/libraries/System.Composition/tests/LooseImportsTests.cs @@ -23,7 +23,6 @@ public class SaveChangesAttribute } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SatisfyImportsSetsLooseImportsOnAttributedPart() { var container = CreateContainer(typeof(Transaction)); diff --git a/src/libraries/System.Composition/tests/MetadataConstraintTests.cs b/src/libraries/System.Composition/tests/MetadataConstraintTests.cs index 0b95b0dae40b..4f6429612bf3 100644 --- a/src/libraries/System.Composition/tests/MetadataConstraintTests.cs +++ b/src/libraries/System.Composition/tests/MetadataConstraintTests.cs @@ -31,7 +31,6 @@ public class ManySettingUser } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AnImportMetadataConstraintMatchesMetadataOnTheExport() { var cc = CreateContainer(typeof(SomeSetting), typeof(SomeSettingUser)); @@ -40,7 +39,6 @@ public void AnImportMetadataConstraintMatchesMetadataOnTheExport() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AnImportMetadataConstraintMatchesMetadataOnTheExportEvenIfDiscoveryHasCompletedForTheExport() { var cc = CreateContainer(typeof(SomeSetting), typeof(SomeSettingUser)); @@ -50,7 +48,6 @@ public void AnImportMetadataConstraintMatchesMetadataOnTheExportEvenIfDiscoveryH } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ImportMetadataConstraintsComposeWithOtherRelationshipTypes() { var cc = CreateContainer(typeof(SomeSetting), typeof(ManySettingUser)); @@ -62,7 +59,6 @@ public void ImportMetadataConstraintsComposeWithOtherRelationshipTypes() public class SomeSetting { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ConstraintsCanBeAppliedToGenerics() { var contract = new CompositionContract(typeof(SomeSetting), null, new Dictionary @@ -86,7 +82,6 @@ public class Controller } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ItemEqualityIsUsedWhenMatchingMetadataValuesThatAreArrays() { var c = CreateContainer(typeof(Presenter), typeof(Controller)); diff --git a/src/libraries/System.Composition/tests/MetadataTests.cs b/src/libraries/System.Composition/tests/MetadataTests.cs index f9740fa56a88..77343806aadc 100644 --- a/src/libraries/System.Composition/tests/MetadataTests.cs +++ b/src/libraries/System.Composition/tests/MetadataTests.cs @@ -31,7 +31,6 @@ public class MetadataCircularityB } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void HandlesMetadataCircularity() { var cc = CreateContainer(typeof(MetadataCircularityA), typeof(MetadataCircularityB)); @@ -90,7 +89,6 @@ public class MultiValuedName { public string[] Name { get; set; } } public class Prioritized {[DefaultValue(0)] public int Priority { get; set; } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultipleMetadataAttributesWithAPropertyThatReturnsNull() { var cc = CreateContainer(typeof(NameNullTwiceExport)); @@ -99,7 +97,6 @@ public void MultipleMetadataAttributesWithAPropertyThatReturnsNull() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversMetadataSpecifiedUsingMetadataAttributeOnExportAttribute() { var cc = CreateContainer(typeof(SingleNamedExport)); @@ -108,7 +105,6 @@ public void DiscoversMetadataSpecifiedUsingMetadataAttributeOnExportAttribute() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void IfMetadataIsSpecifiedOnAnExportAttributeOtherExportsDoNotHaveIt() { var cc = CreateContainer(typeof(MultipleExportsOneNamedAndBothPrioritized)); @@ -118,7 +114,6 @@ public void IfMetadataIsSpecifiedOnAnExportAttributeOtherExportsDoNotHaveIt() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversStandaloneExportMetadata() { var cc = CreateContainer(typeof(NamedAndPrioritized)); @@ -127,7 +122,6 @@ public void DiscoversStandaloneExportMetadata() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void DiscoversStandaloneExportMetadataUsingMetadataAttributes() { var cc = CreateContainer(typeof(NamedWithCustomMetadata)); @@ -136,7 +130,6 @@ public void DiscoversStandaloneExportMetadataUsingMetadataAttributes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void StandaloneExportMetadataAppliesToAllExportsOnAMember() { var cc = CreateContainer(typeof(MultipleExportsOneNamedAndBothPrioritized)); @@ -146,7 +139,6 @@ public void StandaloneExportMetadataAppliesToAllExportsOnAMember() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultiplePiecesOfMetadataAreCombinedIntoAnArray() { var cc = CreateContainer(typeof(MultipleNames)); @@ -160,7 +152,6 @@ public void MultiplePiecesOfMetadataAreCombinedIntoAnArray() public class NamedFred { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SupportsExportMetadata() { var cc = CreateContainer(typeof(NamedFred)); diff --git a/src/libraries/System.Composition/tests/MetadataViewGenerationTests.cs b/src/libraries/System.Composition/tests/MetadataViewGenerationTests.cs index a34ab54c1c88..9786a7db1ae4 100644 --- a/src/libraries/System.Composition/tests/MetadataViewGenerationTests.cs +++ b/src/libraries/System.Composition/tests/MetadataViewGenerationTests.cs @@ -21,7 +21,6 @@ public class HasNameA { } public class Named { public string Name { get; set; } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AConcreteTypeWithWritablePropertiesIsAMetadataView() { var cc = new ContainerConfiguration() @@ -39,7 +38,6 @@ public class HasNoName { } public class OptionallyNamed {[DefaultValue("B")] public string Name { get; set; } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MetadataViewsCanCarryDefaultValues() { var cc = new ContainerConfiguration() @@ -62,7 +60,6 @@ public DictionaryName(IDictionary metadata) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AConcreteTypeWithDictionaryConstructorIsAMetadataView() { var cc = new ContainerConfiguration() @@ -80,7 +77,6 @@ public InvalidConcreteView(string unsupported) { } } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void AConcreteTypeWithUnsupportedConstructorsCannotBeUsedAsAMetadataView() { var cc = new ContainerConfiguration() @@ -105,7 +101,6 @@ public class ImportsWithMetadataInterface } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void UnsupportedMetadataViewMessageIsInformative() { var cc = new ContainerConfiguration().WithParts(typeof(ImportsWithMetadataInterface), typeof(ExportsWithMetadata)).CreateContainer(); @@ -123,7 +118,6 @@ public class ReadonlyNameOrderMetadata public class HasOrder { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ReadOnlyPropertiesOnMetadataViewsAreIgnored() { var c = new ContainerConfiguration() diff --git a/src/libraries/System.Composition/tests/OpenGenericsTests.cs b/src/libraries/System.Composition/tests/OpenGenericsTests.cs index 22c1c2c10348..a7eec57c15b0 100644 --- a/src/libraries/System.Composition/tests/OpenGenericsTests.cs +++ b/src/libraries/System.Composition/tests/OpenGenericsTests.cs @@ -64,7 +64,6 @@ private class SomeGenericType { } private class ExportsBase : SomeGenericType { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanExportBasicOpenGeneric() { var cc = CreateContainer(typeof(BasicRepository<>)); @@ -73,7 +72,6 @@ public void CanExportBasicOpenGeneric() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void OpenGenericProvidesMultipleInstantiations() { var cc = CreateContainer(typeof(BasicRepository<>)); @@ -83,7 +81,6 @@ public void OpenGenericProvidesMultipleInstantiations() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanExportOpenGenericProperty() { var cc = CreateContainer(typeof(RepositoryProperty<>)); @@ -92,7 +89,6 @@ public void CanExportOpenGenericProperty() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ASharedOpenGenericWithTwoExportsIsProvidedByASingleInstance() { var cc = CreateContainer(typeof(TwoGenericExports<>)); @@ -104,7 +100,6 @@ public void ASharedOpenGenericWithTwoExportsIsProvidedByASingleInstance() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void APartWithMultipleGenericExportsIsOnlyDiscoveredOnce() { var cc = CreateContainer(typeof(BasicRepository<>), typeof(TwoGenericExports<>)); @@ -118,7 +113,6 @@ public void APartWithMultipleGenericExportsIsOnlyDiscoveredOnce() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultipleGenericExportsCanBeSpecifiedAtTheClassLevel() { var cc = CreateContainer(typeof(FirstAndSecond<>)); @@ -129,7 +123,6 @@ public void MultipleGenericExportsCanBeSpecifiedAtTheClassLevel() // In future, the set of allowable generic type mappings will be expanded (see // ignored tests above). [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void TypesWithMismatchedGenericParameterListsAreDetectedDuringDiscovery() { var x = Assert.Throws(() => CreateContainer(typeof(RepositoryWithKey<,>))); @@ -137,7 +130,6 @@ public void TypesWithMismatchedGenericParameterListsAreDetectedDuringDiscovery() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void TypesWithNonGenericExportsAreDetectedDuringDiscovery() { var x = Assert.Throws(() => CreateContainer(typeof(RepositoryWithNonGenericExport<>))); @@ -145,7 +137,6 @@ public void TypesWithNonGenericExportsAreDetectedDuringDiscovery() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void OpenGenericsCanExportSelf() { var cc = CreateContainer(typeof(ExportSelf<>)); @@ -154,7 +145,6 @@ public void OpenGenericsCanExportSelf() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void OpenGenericsCanExportBase() { var cc = CreateContainer(typeof(ExportsBase<>)); diff --git a/src/libraries/System.Composition/tests/OptionalImportTests.cs b/src/libraries/System.Composition/tests/OptionalImportTests.cs index d2290da93cae..6db89fb08db2 100644 --- a/src/libraries/System.Composition/tests/OptionalImportTests.cs +++ b/src/libraries/System.Composition/tests/OptionalImportTests.cs @@ -54,7 +54,6 @@ public Missing Missing } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MissingOptionalConstructorParametersAreSuppliedTheirDefaultValue() { var cc = CreateContainer(typeof(Supplied), typeof(HasOptionalConstructorParameter)); @@ -64,7 +63,6 @@ public void MissingOptionalConstructorParametersAreSuppliedTheirDefaultValue() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MissingOptionalPropertyImportsAreIgnored() { var cc = CreateContainer(typeof(Supplied), typeof(HasOptionalProperty)); diff --git a/src/libraries/System.Composition/tests/PropertyExportTests.cs b/src/libraries/System.Composition/tests/PropertyExportTests.cs index 4f8af0b674aa..84e94caed629 100644 --- a/src/libraries/System.Composition/tests/PropertyExportTests.cs +++ b/src/libraries/System.Composition/tests/PropertyExportTests.cs @@ -19,7 +19,6 @@ public class Messenger } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CanExportProperty() { var cc = CreateContainer(typeof(Messenger)); @@ -44,7 +43,6 @@ public class Selfless } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ExportedPropertiesShareTheSameSharedPartInstance() { var cc = CreateContainer(typeof(SelfObsessed), typeof(Selfless)); diff --git a/src/libraries/System.Composition/tests/SharingTests.cs b/src/libraries/System.Composition/tests/SharingTests.cs index 5154a12aca3c..826881f349c5 100644 --- a/src/libraries/System.Composition/tests/SharingTests.cs +++ b/src/libraries/System.Composition/tests/SharingTests.cs @@ -318,7 +318,6 @@ public class SharingTest : ContainerTests /// we fail only when we create instance of B.. is that correct. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void BoundaryExposedBoundaryButNoneImported() { try @@ -338,7 +337,6 @@ public void BoundaryExposedBoundaryButNoneImported() /// Needs to be fixed so that specifying boundary would automatically create the shared /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void BoundarySharingTest() { var cc = CreateContainer(typeof(A), typeof(B), typeof(C), typeof(D)); @@ -360,7 +358,6 @@ public void BoundarySharingTest() /// CirA root of the composition has to be shared explicitly. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void CircularBoundarySharingTest() { var cc = CreateContainer(typeof(CirA), typeof(CirB), typeof(CirC)); @@ -377,7 +374,6 @@ public void CircularBoundarySharingTest() /// Something is badly busted here.. I am getting a null ref exception /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void MultipleBoundarySpecified() { var cc = CreateContainer(typeof(ProjA), typeof(ProjB), typeof(SolA), typeof(DocA), typeof(DocB), typeof(ColA), typeof(ColB)); @@ -387,7 +383,6 @@ public void MultipleBoundarySpecified() [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void SharedPartExportingMultipleContractsSharesAnInstance() { var cc = CreateContainer(typeof(XY)); @@ -397,7 +392,6 @@ public void SharedPartExportingMultipleContractsSharesAnInstance() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExportsCreatesInstancedObjectByDefault() { var cc = CreateContainer(typeof(NonSharedClass)); @@ -407,7 +401,6 @@ public void GetExportsCreatesInstancedObjectByDefault() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetExportsCreatesSharedObjectsWhenSpecified() { var cc = CreateContainer(typeof(SharedClass)); @@ -422,7 +415,6 @@ public void GetExportsCreatesSharedObjectsWhenSpecified() /// verify that On Method call different instances are returned. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ExportFactoryCreatesNewInstances() { var cc = CreateContainer(typeof(ClassWithExportFactoryShared), typeof(NonSharedClass)); @@ -438,7 +430,6 @@ public void ExportFactoryCreatesNewInstances() /// ExportFactory should be importable as a property /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ClassWithExportFactoryAsAProperty() { var cc = CreateContainer(typeof(ClassWithExportFactoryAsAProperty), typeof(NonSharedClass)); @@ -455,7 +446,6 @@ public void ClassWithExportFactoryAsAProperty() /// is creating a part which is shared, it will return back the same instance of the part. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ClassWithExportFactoryAndSharedExport() { var cc = CreateContainer(typeof(ClassWithExportFactoryShared), typeof(SharedClass)); @@ -472,7 +462,6 @@ public void ClassWithExportFactoryAndSharedExport() /// Two instances of the root class are created , the part created using export factory should not be shared /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ClassWithNonSharedExportFactoryCreatesSharedInstances() { var cc = CreateContainer(typeof(ClassWithExportFactoryNonShared), typeof(SharedClass)); @@ -488,7 +477,6 @@ public void ClassWithNonSharedExportFactoryCreatesSharedInstances() public class ASharedPart { } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void ConsistentResultsAreReturneWhenResolvingLargeNumbersOfSharedParts() { var config = new ContainerConfiguration(); diff --git a/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs b/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs index 7f8998a27ca1..fd14735f299a 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs @@ -67,7 +67,6 @@ public void ObjectInitialization_InvalidSecurityDescriptor() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/23972", TargetFrameworkMonikers.NetFramework)] public void GetAccessRules_InvalidTargetType() { var activeDirectorySecurity = new ActiveDirectorySecurity(); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 3e9099231db1..54af864c8c4e 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -1441,63 +1441,54 @@ public static IEnumerable SerializableObjects() var privilegeNotHeldException = new PrivilegeNotHeldException("privilege", exception); yield return new object[] { PopulateException(privilegeNotHeldException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAADdTeXN0ZW0uU2VjdXJpdHkuQWNjZXNzQ29udHJvbC5Qcml2aWxlZ2VOb3RIZWxkRXhjZXB0aW9uDQAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMNUHJpdmlsZWdlTmFtZQEBAwMBAQEAAQABBwEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYCAAAAN1N5c3RlbS5TZWN1cml0eS5BY2Nlc3NDb250cm9sLlByaXZpbGVnZU5vdEhlbGRFeGNlcHRpb24GAwAAAFxUaGUgcHJvY2VzcyBkb2VzIG5vdCBwb3NzZXNzIHRoZSAncHJpdmlsZWdlJyBwcml2aWxlZ2Ugd2hpY2ggaXMgcmVxdWlyZWQgZm9yIHRoaXMgb3BlcmF0aW9uLgkEAAAACQUAAAAGBgAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBgcAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCAAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCQAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoGCgAAAAlwcml2aWxlZ2UEBAAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAUAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uBg0AAAAHbWVzc2FnZQkOAAAACQ8AAAAJBgAAAAkHAAAACQgAAAAAAAAACugDAAAJCQAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABAAAAAkWAAAAAgAAAAIAAAABDwAAAAUAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAADdTeXN0ZW0uU2VjdXJpdHkuQWNjZXNzQ29udHJvbC5Qcml2aWxlZ2VOb3RIZWxkRXhjZXB0aW9uDQAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMNUHJpdmlsZWdlTmFtZQEBAwMBAQEAAQABBwEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYCAAAAN1N5c3RlbS5TZWN1cml0eS5BY2Nlc3NDb250cm9sLlByaXZpbGVnZU5vdEhlbGRFeGNlcHRpb24GAwAAAFxUaGUgcHJvY2VzcyBkb2VzIG5vdCBwb3NzZXNzIHRoZSAncHJpdmlsZWdlJyBwcml2aWxlZ2Ugd2hpY2ggaXMgcmVxdWlyZWQgZm9yIHRoaXMgb3BlcmF0aW9uLgkEAAAACQUAAAAGBgAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBgcAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCAAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCQAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoGCgAAAAlwcml2aWxlZ2UEBAAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAUAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uBg0AAAAHbWVzc2FnZQkOAAAACQ8AAAAJBgAAAAkHAAAACQgAAAAAAAAACugDAAAJCQAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABAAAAAkWAAAAAgAAAAIAAAABDwAAAAUAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; - // Infrastructure issue where the netstandard dll is PNSE assembly but in .NET Framework DirectoryServices should use the inbox assembly since they have the same identity. - // See: https://github.com/dotnet/runtime/issues/23972 - if (!PlatformDetection.IsNetFramework) - { - var activeDirectoryOperationException = new ActiveDirectoryOperationException("message", exception, 0); - yield return new object[] { PopulateException(activeDirectoryOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABKU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAASlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABKU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAASlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; + var activeDirectoryOperationException = new ActiveDirectoryOperationException("message", exception, 0); + yield return new object[] { PopulateException(activeDirectoryOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABKU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAASlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABKU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAASlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; - var activeDirectoryObjectNotFoundException = new ActiveDirectoryObjectNotFoundException("message", exception); - yield return new object[] { PopulateException(activeDirectoryObjectNotFoundException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var activeDirectoryObjectNotFoundException = new ActiveDirectoryObjectNotFoundException("message", exception); + yield return new object[] { PopulateException(activeDirectoryObjectNotFoundException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABPU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3ROb3RGb3VuZEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var activeDirectoryObjectExistsException = new ActiveDirectoryObjectExistsException("message", exception); - yield return new object[] { PopulateException(activeDirectoryObjectExistsException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3RFeGlzdHNFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T2JqZWN0RXhpc3RzRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3RFeGlzdHNFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T2JqZWN0RXhpc3RzRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; + var activeDirectoryObjectExistsException = new ActiveDirectoryObjectExistsException("message", exception); + yield return new object[] { PopulateException(activeDirectoryObjectExistsException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3RFeGlzdHNFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T2JqZWN0RXhpc3RzRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlPYmplY3RFeGlzdHNFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuQWN0aXZlRGlyZWN0b3J5T2JqZWN0RXhpc3RzRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; - var directoryException = new DirectoryException("message", exception); - yield return new object[] { PopulateException(directoryException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAANVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5RXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeUV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAANVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5RXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeUV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var directoryException = new DirectoryException("message", exception); + yield return new object[] { PopulateException(directoryException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAANVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5RXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeUV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAANVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5RXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeUV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var directoryOperationException = new DirectoryOperationException("message", exception); - yield return new object[] { PopulateException(directoryOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAPlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAD5TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeU9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAPlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAD5TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeU9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var directoryOperationException = new DirectoryOperationException("message", exception); + yield return new object[] { PopulateException(directoryOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAPlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAD5TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeU9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAPlN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuRGlyZWN0b3J5T3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAD5TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLkRpcmVjdG9yeU9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var directoryServicesCOMException = new DirectoryServicesCOMException("message", exception); - yield return new object[] { PopulateException(directoryServicesCOMException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAAA2U3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkRpcmVjdG9yeVNlcnZpY2VzQ09NRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADZTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuRGlyZWN0b3J5U2VydmljZXNDT01FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAAA2U3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkRpcmVjdG9yeVNlcnZpY2VzQ09NRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADZTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuRGlyZWN0b3J5U2VydmljZXNDT01FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; + var directoryServicesCOMException = new DirectoryServicesCOMException("message", exception); + yield return new object[] { PopulateException(directoryServicesCOMException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAAA2U3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkRpcmVjdG9yeVNlcnZpY2VzQ09NRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADZTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuRGlyZWN0b3J5U2VydmljZXNDT01FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAAA2U3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkRpcmVjdG9yeVNlcnZpY2VzQ09NRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADZTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuRGlyZWN0b3J5U2VydmljZXNDT01FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; - var ldapException = new LdapException("message", exception); - yield return new object[] { PopulateException(ldapException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAMFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuTGRhcEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAwU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLlByb3RvY29scy5MZGFwRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAMFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuTGRhcEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAwU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLlByb3RvY29scy5MZGFwRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; + var ldapException = new LdapException("message", exception); + yield return new object[] { PopulateException(ldapException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAMFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuTGRhcEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAwU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLlByb3RvY29scy5MZGFwRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAMFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuTGRhcEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAwU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLlByb3RvY29scy5MZGFwRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; - var tlsOperationException = new TlsOperationException("message", exception); - yield return new object[] { PopulateException(tlsOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAOFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuVGxzT3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADhTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLlRsc09wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAOFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuVGxzT3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADhTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLlRsc09wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var tlsOperationException = new TlsOperationException("message", exception); + yield return new object[] { PopulateException(tlsOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAOFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuVGxzT3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADhTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLlRsc09wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGVTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUBAAAAOFN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5Qcm90b2NvbHMuVGxzT3BlcmF0aW9uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAADhTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuUHJvdG9jb2xzLlRsc09wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var principalExistsException = new PrincipalExistsException("message", exception); - yield return new object[] { PopulateException(principalExistsException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var principalExistsException = new PrincipalExistsException("message", exception); + yield return new object[] { PopulateException(principalExistsException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABDU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbEV4aXN0c0V4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var principalOperationException = new PrincipalOperationException("message", exception, 200); - yield return new object[] { PopulateException(principalOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbg0AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCWVycm9yQ29kZQEBAwMBAQEAAQABBwApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAggCAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKyAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbg0AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCWVycm9yQ29kZQEBAwMBAQEAAQABBwApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAggCAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKyAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; + var principalOperationException = new PrincipalOperationException("message", exception, 200); + yield return new object[] { PopulateException(principalOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbg0AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCWVycm9yQ29kZQEBAwMBAQEAAQABBwApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAggCAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKyAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbg0AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCWVycm9yQ29kZQEBAwMBAQEAAQABBwApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAggCAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbE9wZXJhdGlvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKyAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; - var principalServerDownException = new PrincipalServerDownException("message", exception, 200, "localhost"); - yield return new object[] { PopulateException(principalServerDownException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABHU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbFNlcnZlckRvd25FeGNlcHRpb24OAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwllcnJvckNvZGUKc2VydmVyTmFtZQEBAwMBAQEAAQABBwABKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIIAgAAAAYDAAAAR1N5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY2NvdW50TWFuYWdlbWVudC5QcmluY2lwYWxTZXJ2ZXJEb3duRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwrIAAAABgsAAAAJbG9jYWxob3N0BAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQwAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBg0AAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ8AAAAJEAAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQMAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYVAAAABnNlY3JldAgBAQkWAAAAAQ8AAAAFAAAACRcAAAACAAAAAgAAAAEQAAAABgAAAAkNAAAABhkAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARYAAAAMAAAACAgBAAAABhoAAAADb25lCgEXAAAADAAAAAkVAAAACAEBCRwAAAABHAAAAAwAAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABHU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbFNlcnZlckRvd25FeGNlcHRpb24OAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwllcnJvckNvZGUKc2VydmVyTmFtZQEBAwMBAQEAAQABBwABKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIIAgAAAAYDAAAAR1N5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY2NvdW50TWFuYWdlbWVudC5QcmluY2lwYWxTZXJ2ZXJEb3duRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwrIAAAABgsAAAAJbG9jYWxob3N0BAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQwAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBg0AAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ8AAAAJEAAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQMAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYVAAAABnNlY3JldAgBAQkWAAAAAQ8AAAAFAAAACRcAAAACAAAAAgAAAAEQAAAABgAAAAkNAAAABhkAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARYAAAAMAAAACAgBAAAABhoAAAADb25lCgEXAAAADAAAAAkVAAAACAEBCRwAAAABHAAAAAwAAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var principalServerDownException = new PrincipalServerDownException("message", exception, 200, "localhost"); + yield return new object[] { PopulateException(principalServerDownException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABHU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbFNlcnZlckRvd25FeGNlcHRpb24OAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwllcnJvckNvZGUKc2VydmVyTmFtZQEBAwMBAQEAAQABBwABKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIIAgAAAAYDAAAAR1N5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY2NvdW50TWFuYWdlbWVudC5QcmluY2lwYWxTZXJ2ZXJEb3duRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwrIAAAABgsAAAAJbG9jYWxob3N0BAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQwAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBg0AAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ8AAAAJEAAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQMAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYVAAAABnNlY3JldAgBAQkWAAAAAQ8AAAAFAAAACRcAAAACAAAAAgAAAAEQAAAABgAAAAkNAAAABhkAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARYAAAAMAAAACAgBAAAABhoAAAADb25lCgEXAAAADAAAAAkVAAAACAEBCRwAAAABHAAAAAwAAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAG1TeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWNjb3VudE1hbmFnZW1lbnQsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABHU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjY291bnRNYW5hZ2VtZW50LlByaW5jaXBhbFNlcnZlckRvd25FeGNlcHRpb24OAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwllcnJvckNvZGUKc2VydmVyTmFtZQEBAwMBAQEAAQABBwABKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIIAgAAAAYDAAAAR1N5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY2NvdW50TWFuYWdlbWVudC5QcmluY2lwYWxTZXJ2ZXJEb3duRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwrIAAAABgsAAAAJbG9jYWxob3N0BAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQwAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBg0AAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ8AAAAJEAAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQMAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYVAAAABnNlY3JldAgBAQkWAAAAAQ8AAAAFAAAACRcAAAACAAAAAgAAAAEQAAAABgAAAAkNAAAABhkAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARYAAAAMAAAACAgBAAAABhoAAAADb25lCgEXAAAADAAAAAkVAAAACAEBCRwAAAABHAAAAAwAAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var activeDirectoryServerDownException = new ActiveDirectoryServerDownException("message", exception, 0, "name"); - yield return new object[] { PopulateException(activeDirectoryServerDownException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABLU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlTZXJ2ZXJEb3duRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAEtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWN0aXZlRGlyZWN0b3J5LkFjdGl2ZURpcmVjdG9yeVNlcnZlckRvd25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABLU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlTZXJ2ZXJEb3duRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAEtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWN0aXZlRGlyZWN0b3J5LkFjdGl2ZURpcmVjdG9yeVNlcnZlckRvd25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; + var activeDirectoryServerDownException = new ActiveDirectoryServerDownException("message", exception, 0, "name"); + yield return new object[] { PopulateException(activeDirectoryServerDownException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABLU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlTZXJ2ZXJEb3duRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAEtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWN0aXZlRGlyZWN0b3J5LkFjdGl2ZURpcmVjdG9yeVNlcnZlckRvd25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABLU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5BY3RpdmVEaXJlY3RvcnlTZXJ2ZXJEb3duRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgIAAAAGAwAAAEtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMuQWN0aXZlRGlyZWN0b3J5LkFjdGl2ZURpcmVjdG9yeVNlcnZlckRvd25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkLAAAAAgAAAAIAAAAEBgAAABBTeXN0ZW0uRXhjZXB0aW9uDAAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMBAQMDAQEBAAEAAQcpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgYMAAAAEFN5c3RlbS5FeGNlcHRpb24JBAAAAAkOAAAACQ8AAAAJBwAAAAkIAAAACQkAAAAAAAAACugDAAAJCgAAAAoECwAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGFAAAAAZzZWNyZXQIAQEJFQAAAAEOAAAABQAAAAkWAAAAAgAAAAIAAAABDwAAAAYAAAAJDAAAAAYYAAAAF0lubmVyIGV4Y2VwdGlvbiBtZXNzYWdlCgoKCgoAAAAACgAVE4AKCgEVAAAACwAAAAgIAQAAAAYZAAAAA29uZQoBFgAAAAsAAAAJFAAAAAgBAQkbAAAAARsAAAALAAAACAgBAAAACRkAAAAKCw==", TargetFrameworkMoniker.netfx461) } }; - var forestTrustCollisionException = new ForestTrustCollisionException("message", exception); - yield return new object[] { PopulateException(forestTrustCollisionException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var forestTrustCollisionException = new ForestTrustCollisionException("message", exception); + yield return new object[] { PopulateException(forestTrustCollisionException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5Gb3Jlc3RUcnVzdENvbGxpc2lvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var syncFromAllServersOperationException = new SyncFromAllServersOperationException("message", exception); - yield return new object[] { PopulateException(syncFromAllServersOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5TeW5jRnJvbUFsbFNlcnZlcnNPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuU3luY0Zyb21BbGxTZXJ2ZXJzT3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5TeW5jRnJvbUFsbFNlcnZlcnNPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuU3luY0Zyb21BbGxTZXJ2ZXJzT3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; - } + var syncFromAllServersOperationException = new SyncFromAllServersOperationException("message", exception); + yield return new object[] { PopulateException(syncFromAllServersOperationException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5TeW5jRnJvbUFsbFNlcnZlcnNPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuU3luY0Zyb21BbGxTZXJ2ZXJzT3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFtTeXN0ZW0uRGlyZWN0b3J5U2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABNU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkFjdGl2ZURpcmVjdG9yeS5TeW5jRnJvbUFsbFNlcnZlcnNPcGVyYXRpb25FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAATVN5c3RlbS5EaXJlY3RvcnlTZXJ2aWNlcy5BY3RpdmVEaXJlY3RvcnkuU3luY0Zyb21BbGxTZXJ2ZXJzT3BlcmF0aW9uRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; } - // TODO: Inbox framework assemblies with same identity aren't currently used for running tests. https://github.com/dotnet/runtime/issues/23972 - if (!PlatformDetection.IsNetFramework) - { - var compositionContractMismatchException = new CompositionContractMismatchException("message", exception); - yield return new object[] { PopulateException(compositionContractMismatchException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; + var compositionContractMismatchException = new CompositionContractMismatchException("message", exception); + yield return new object[] { PopulateException(compositionContractMismatchException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAABGU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkNvbXBvc2l0aW9uQ29udHJhY3RNaXNtYXRjaEV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQsAAAACAAAAAgAAAAQGAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgwAAAAQU3lzdGVtLkV4Y2VwdGlvbgkEAAAACQ4AAAAJDwAAAAkHAAAACQgAAAAJCQAAAAAAAAAK6AMAAAkKAAAACgQLAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYUAAAABnNlY3JldAgBAQkVAAAAAQ4AAAAFAAAACRYAAAACAAAAAgAAAAEPAAAABgAAAAkMAAAABhgAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARUAAAALAAAACAgBAAAABhkAAAADb25lCgEWAAAACwAAAAkUAAAACAEBCRsAAAABGwAAAAsAAAAICAEAAAAJGQAAAAoL", TargetFrameworkMoniker.netfx461) } }; - var importCardinalityMismatchException = new ImportCardinalityMismatchException("message", exception); - yield return new object[] { PopulateException(importCardinalityMismatchException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABEU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkltcG9ydENhcmRpbmFsaXR5TWlzbWF0Y2hFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAARFN5c3RlbS5Db21wb25lbnRNb2RlbC5Db21wb3NpdGlvbi5JbXBvcnRDYXJkaW5hbGl0eU1pc21hdGNoRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABEU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkltcG9ydENhcmRpbmFsaXR5TWlzbWF0Y2hFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAARFN5c3RlbS5Db21wb25lbnRNb2RlbC5Db21wb3NpdGlvbi5JbXBvcnRDYXJkaW5hbGl0eU1pc21hdGNoRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; - } + var importCardinalityMismatchException = new ImportCardinalityMismatchException("message", exception); + yield return new object[] { PopulateException(importCardinalityMismatchException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAABEU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkltcG9ydENhcmRpbmFsaXR5TWlzbWF0Y2hFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAARFN5c3RlbS5Db21wb25lbnRNb2RlbC5Db21wb3NpdGlvbi5JbXBvcnRDYXJkaW5hbGl0eU1pc21hdGNoRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAGRTeXN0ZW0uQ29tcG9uZW50TW9kZWwuQ29tcG9zaXRpb24sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAABEU3lzdGVtLkNvbXBvbmVudE1vZGVsLkNvbXBvc2l0aW9uLkltcG9ydENhcmRpbmFsaXR5TWlzbWF0Y2hFeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCAgAAAAYDAAAARFN5c3RlbS5Db21wb25lbnRNb2RlbC5Db21wb3NpdGlvbi5JbXBvcnRDYXJkaW5hbGl0eU1pc21hdGNoRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACQYAAAAGBwAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBggAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCQAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCgAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDAAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJDgAAAAkPAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhQAAAAGc2VjcmV0CAEBCRUAAAABDgAAAAUAAAAJFgAAAAIAAAACAAAAAQ8AAAAGAAAACQwAAAAGGAAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFQAAAAsAAAAICAEAAAAGGQAAAANvbmUKARYAAAALAAAACRQAAAAIAQEJGwAAAAEbAAAACwAAAAgIAQAAAAkZAAAACgs=", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { new ValueTuple(), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAABFTeXN0ZW0uVmFsdWVUdXBsZQAAAAAL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAABFTeXN0ZW0uVmFsdWVUdXBsZQAAAAAL", TargetFrameworkMoniker.netfx471) } }; yield return new object[] { ValueTuple.Create(1), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAHBTeXN0ZW0uVmFsdWVUdXBsZWAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAAVJdGVtMQAIAQAAAAs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAAHBTeXN0ZW0uVmFsdWVUdXBsZWAxW1tTeXN0ZW0uSW50MzIsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAQAAAAVJdGVtMQAIAQAAAAs=", TargetFrameworkMoniker.netfx471) } }; From 4ac596dba139df2789965c094bb2b58607fa3a9e Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 23 Jul 2020 15:05:43 -0700 Subject: [PATCH 019/755] WASM: enable System.ObjectModel.Tests (#39849) --- .../System.ObjectModel/tests/KeyedCollection/Serialization.cs | 2 +- .../ObservableCollection/ObservableCollection_Serialization.cs | 2 +- .../ReadOnlyDictionary/ReadOnlyDictionary_SerializationTests.cs | 2 +- .../ReadOnlyObservableCollection_SerializationTests.cs | 2 +- src/libraries/tests.proj | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.ObjectModel/tests/KeyedCollection/Serialization.cs b/src/libraries/System.ObjectModel/tests/KeyedCollection/Serialization.cs index a43c4f08d496..1c1440600677 100644 --- a/src/libraries/System.ObjectModel/tests/KeyedCollection/Serialization.cs +++ b/src/libraries/System.ObjectModel/tests/KeyedCollection/Serialization.cs @@ -16,7 +16,7 @@ public static IEnumerable SerializeDeserialize_Roundtrips_MemberData() yield return new object[] { new TestCollection() { "hello", "world" } }; } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] [MemberData(nameof(SerializeDeserialize_Roundtrips_MemberData))] public void SerializeDeserialize_Roundtrips(TestCollection c) { diff --git a/src/libraries/System.ObjectModel/tests/ObservableCollection/ObservableCollection_Serialization.cs b/src/libraries/System.ObjectModel/tests/ObservableCollection/ObservableCollection_Serialization.cs index 1d2875576e41..65d5694a93a8 100644 --- a/src/libraries/System.ObjectModel/tests/ObservableCollection/ObservableCollection_Serialization.cs +++ b/src/libraries/System.ObjectModel/tests/ObservableCollection/ObservableCollection_Serialization.cs @@ -17,7 +17,7 @@ public static IEnumerable SerializeDeserialize_Roundtrips_MemberData() yield return new object[] { new ObservableCollection() { 1, 5, 3, 4, 2 } }; } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] [MemberData(nameof(SerializeDeserialize_Roundtrips_MemberData))] public void SerializeDeserialize_Roundtrips(ObservableCollection c) { diff --git a/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionary_SerializationTests.cs b/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionary_SerializationTests.cs index af7aec630bbd..d0bb38d21623 100644 --- a/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionary_SerializationTests.cs +++ b/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionary_SerializationTests.cs @@ -16,7 +16,7 @@ public static IEnumerable SerializeDeserialize_Roundtrips_MemberData() yield return new object[] { new ReadOnlyDictionary(new Dictionary() { { "a", "b" }, { "c", "d" } }) }; } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] [MemberData(nameof(SerializeDeserialize_Roundtrips_MemberData))] public void SerializeDeserialize_Roundtrips(ReadOnlyDictionary d) { diff --git a/src/libraries/System.ObjectModel/tests/ReadOnlyObservableCollection/ReadOnlyObservableCollection_SerializationTests.cs b/src/libraries/System.ObjectModel/tests/ReadOnlyObservableCollection/ReadOnlyObservableCollection_SerializationTests.cs index b2e102dd64b2..ed818b6a6198 100644 --- a/src/libraries/System.ObjectModel/tests/ReadOnlyObservableCollection/ReadOnlyObservableCollection_SerializationTests.cs +++ b/src/libraries/System.ObjectModel/tests/ReadOnlyObservableCollection/ReadOnlyObservableCollection_SerializationTests.cs @@ -17,7 +17,7 @@ public static IEnumerable SerializeDeserialize_Roundtrips_MemberData() yield return new object[] { new ReadOnlyObservableCollection(new ObservableCollection() { 1, 2, 3 }) }; } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] [MemberData(nameof(SerializeDeserialize_Roundtrips_MemberData))] public void SerializeDeserialize_Roundtrips(ReadOnlyObservableCollection c) { diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index eb67053b5b88..b35563aebd64 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -33,7 +33,6 @@ - From df35f269e351b8ed51e7746ab561387fef7bf865 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 23 Jul 2020 16:21:06 -0700 Subject: [PATCH 020/755] WASM: Enable Invariant.Tests (#39814) * WASM: Enable Invariant.Tests * Fix build and PR Feedback --- eng/testing/tests.mobile.targets | 15 +++------------ .../pal_icushim_static.c | 11 ++++++++++- .../tests/Invariant/Invariant.Tests.csproj | 1 + src/libraries/tests.proj | 3 +-- .../mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs | 15 +++++++++++++-- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index dc7dd97397e5..c69aa634b71d 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -133,19 +133,9 @@ - + - - - - - - - - - - @@ -163,12 +153,13 @@ + AssemblySearchPaths="@(AssemblySearchPaths)" /> #include +static int32_t isLoaded = 0; + static void log_icu_error(const char* name, UErrorCode status) { const char * statusText = u_errorName(status); @@ -65,7 +67,8 @@ int32_t GlobalizationNative_LoadICU(void) log_icu_error("ulocdata_getCLDRVersion", status); return 0; } - + + isLoaded = 1; return 1; } @@ -76,6 +79,12 @@ void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, const char* int32_t GlobalizationNative_GetICUVersion(void) { + // this method is only used from our tests + // this way we ensure we're testing on the right mode + // even though we can call u_getVersion without loading since it is statically linked. + if (!isLoaded) + return 0; + UVersionInfo versionInfo; u_getVersion(versionInfo); diff --git a/src/libraries/System.Globalization/tests/Invariant/Invariant.Tests.csproj b/src/libraries/System.Globalization/tests/Invariant/Invariant.Tests.csproj index 1de762de1564..6979cd759d0e 100644 --- a/src/libraries/System.Globalization/tests/Invariant/Invariant.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Invariant/Invariant.Tests.csproj @@ -3,6 +3,7 @@ $(NetCoreAppCurrent) true true + true diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index b35563aebd64..8212eca5be3f 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -25,8 +25,7 @@ - - + diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 94ad3a5267fd..a9a6ffc7e789 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -32,6 +32,7 @@ public class WasmAppBuilder : Task public ITaskItem[]? ExtraAssemblies { get; set; } public ITaskItem[]? FilesToIncludeInFileSystem { get; set; } public ITaskItem[]? RemoteSources { get; set; } + public bool InvariantGlobalization { get; set; } SortedDictionary? _assemblies; Resolver? _resolver; @@ -117,7 +118,15 @@ public override bool Execute () Directory.CreateDirectory(Path.Join(AppDir, config.AssemblyRoot)); foreach (var assembly in _assemblies!.Values) 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" }) + + List nativeAssets = new List() { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat" }; + + if (!InvariantGlobalization) + { + nativeAssets.Add("icudt.dat"); + } + + foreach (var f in nativeAssets) File.Copy(Path.Join (MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true); File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true); @@ -152,7 +161,9 @@ public override bool Execute () } } - config.Assets.Add(new IcuData { LoadRemote = RemoteSources?.Length > 0 }); + if (!InvariantGlobalization) + config.Assets.Add(new IcuData { LoadRemote = RemoteSources?.Length > 0 }); + config.Assets.Add(new VfsEntry ("dotnet.timezones.blat") { VirtualPath = "/usr/share/zoneinfo/"}); if (RemoteSources?.Length > 0) { From 90619d5d3577f2aaddf670ee6bf431f393afccaf Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Thu, 23 Jul 2020 17:20:46 -0700 Subject: [PATCH 021/755] Implementation of CSE for GT_CNS_INT benefits ARM64 (#39096) * Change the type of csdHashKey to size_t * Update gtCostSz and gtCostEx for constant nodes * Implementation of code size optimization, CSE of constant values for ARM64 Implementation of code size optimization, CSE of constant values for ARM64 We will share a single CSE for constants that differ only in their low 12 bits on ARM64 Number of shared constant low bits set in target.h CSE_CONST_SHARED_LOW_BITS we use 12 bits on Arm platforms and 16 bits on XArch platforms Disable the CSE of the REG_R2R_INDIRECT_PARAM on Arm32 as it hits Assertion failed 'candidates != candidateBit' in lsra.cpp Line: 3723 Config variable: COMPlus_JitConstCSE // Default 0: enable the CSE of Constants, including nearby offsets. (only for ARM64) // If 1, disable all the CSE of Constants // If 2, enable the CSE of Constants but don't combine with nearby offsets. (only for ARM64) // If 3, enable the CSE of Constants including nearby offsets. (all platforms) // If 4, enable the CSE of Constants but don't combine with nearby offsets. (all platforms) // * Added additional Priority 0 test coverage for Floating Point optimizations * Fix for COMPLUS_JitConstCSE=4 * Renamed config variable from COMPlus_JitDisableConstCSE to COMPlus_JitConstCSE * Updated with Codereview feedback, removed sort from Const CSE phase * Fix for assertionProp issue in the refTypesdynamic test --- src/coreclr/src/jit/compiler.h | 22 +- src/coreclr/src/jit/gentree.cpp | 192 ++++++-- src/coreclr/src/jit/jitconfigvalues.h | 14 + src/coreclr/src/jit/morph.cpp | 7 + src/coreclr/src/jit/optcse.cpp | 465 +++++++++++++----- src/coreclr/src/jit/target.h | 9 +- .../Old/Conformance_Base/beq_r4.ilproj | 2 +- .../Old/Conformance_Base/beq_r8.ilproj | 2 +- .../Old/Conformance_Base/bge_r4.ilproj | 2 +- .../Old/Conformance_Base/bge_r8.ilproj | 2 +- .../Old/Conformance_Base/bge_un_r4.ilproj | 2 +- .../Old/Conformance_Base/bge_un_r8.ilproj | 2 +- .../Old/Conformance_Base/bne_un_r4.ilproj | 2 +- .../Old/Conformance_Base/bne_un_r8.ilproj | 2 +- .../JIT/Methodical/NaN/arithm64_cs_d.csproj | 2 +- .../JIT/Methodical/NaN/arithm64_cs_do.csproj | 2 +- .../JIT/Methodical/NaN/arithm64_cs_r.csproj | 2 +- .../JIT/Methodical/NaN/arithm64_cs_ro.csproj | 2 +- 18 files changed, 567 insertions(+), 166 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 28521b87f6b3..37897a64fda2 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -6326,11 +6326,12 @@ class Compiler struct CSEdsc { - CSEdsc* csdNextInBucket; // used by the hash table - - unsigned csdHashKey; // the orginal hashkey - - unsigned csdIndex; // 1..optCSECandidateCount + CSEdsc* csdNextInBucket; // used by the hash table + size_t csdHashKey; // the orginal hashkey + ssize_t csdConstDefValue; // When we CSE similar constants, this is the value that we use as the def + ValueNum csdConstDefVN; // When we CSE similar constants, this is the ValueNumber that we use for the LclVar + // assignment + unsigned csdIndex; // 1..optCSECandidateCount bool csdLiveAcrossCall; unsigned short csdDefCount; // definition count @@ -6359,6 +6360,7 @@ class Compiler ValueNum defConservNormVN; // if all def occurrences share the same conservative normal value // number, this will reflect it; otherwise, NoVN. + // not used for shared const CSE's }; static const size_t s_optCSEhashSize; @@ -6406,6 +6408,16 @@ class Compiler void optEnsureClearCSEInfo(); #endif // DEBUG + static bool Is_Shared_Const_CSE(size_t key) + { + return ((key & TARGET_SIGN_BIT) != 0); + } + + static size_t Decode_Shared_Const_CSE_Value(size_t key) + { + return (key & ~TARGET_SIGN_BIT) << CSE_CONST_SHARED_LOW_BITS; + } + #endif // FEATURE_ANYCSE #if FEATURE_VALNUM_CSE diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 98c47e3eb55c..e39c9c76f90b 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -3250,78 +3250,138 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) switch (oper) { #ifdef TARGET_ARM - case GT_CNS_LNG: - costSz = 9; - costEx = 4; - goto COMMON_CNS; - case GT_CNS_STR: // Uses movw/movt - costSz = 7; - costEx = 3; + costSz = 8; + costEx = 2; goto COMMON_CNS; + case GT_CNS_LNG: + { + GenTreeIntConCommon* con = tree->AsIntConCommon(); + + INT64 lngVal = con->LngValue(); + INT32 loVal = (INT32)(lngVal & 0xffffffff); + INT32 hiVal = (INT32)(lngVal >> 32); + + if (lngVal == 0) + { + costSz = 1; + costEx = 1; + } + else + { + // Minimum of one instruction to setup hiVal, + // and one instruction to setup loVal + costSz = 4 + 4; + costEx = 1 + 1; + + if (!codeGen->validImmForInstr(INS_mov, (target_ssize_t)hiVal) && + !codeGen->validImmForInstr(INS_mvn, (target_ssize_t)hiVal)) + { + // Needs extra instruction: movw/movt + costSz += 4; + costEx += 1; + } + + if (!codeGen->validImmForInstr(INS_mov, (target_ssize_t)loVal) && + !codeGen->validImmForInstr(INS_mvn, (target_ssize_t)loVal)) + { + // Needs extra instruction: movw/movt + costSz += 4; + costEx += 1; + } + } + goto COMMON_CNS; + } + case GT_CNS_INT: { // If the constant is a handle then it will need to have a relocation // applied to it. // Any constant that requires a reloc must use the movw/movt sequence // - GenTreeIntConCommon* con = tree->AsIntConCommon(); + GenTreeIntConCommon* con = tree->AsIntConCommon(); + INT32 conVal = con->IconValue(); - if (con->ImmedValNeedsReloc(this) || - !codeGen->validImmForInstr(INS_mov, (target_ssize_t)tree->AsIntCon()->gtIconVal)) + if (con->ImmedValNeedsReloc(this)) { - // Uses movw/movt - costSz = 7; - costEx = 3; + // Requires movw/movt + costSz = 8; + costEx = 2; } - else if (((unsigned)tree->AsIntCon()->gtIconVal) <= 0x00ff) + else if (codeGen->validImmForInstr(INS_add, (target_ssize_t)conVal)) { - // mov Rd, - costSz = 1; + // Typically included with parent oper + costSz = 2; costEx = 1; } - else + else if (codeGen->validImmForInstr(INS_mov, (target_ssize_t)conVal) && + codeGen->validImmForInstr(INS_mvn, (target_ssize_t)conVal)) { - // Uses movw/mvn - costSz = 3; + // Uses mov or mvn + costSz = 4; costEx = 1; } + else + { + // Needs movw/movt + costSz = 8; + costEx = 2; + } goto COMMON_CNS; } #elif defined TARGET_XARCH - case GT_CNS_LNG: - costSz = 10; - costEx = 3; - goto COMMON_CNS; - case GT_CNS_STR: +#ifdef TARGET_AMD64 + costSz = 10; + costEx = 2; +#else // TARGET_X86 costSz = 4; costEx = 1; +#endif goto COMMON_CNS; + case GT_CNS_LNG: case GT_CNS_INT: { + GenTreeIntConCommon* con = tree->AsIntConCommon(); + ssize_t conVal = (oper == GT_CNS_LNG) ? (ssize_t)con->LngValue() : con->IconValue(); + bool fitsInVal = true; + +#ifdef TARGET_X86 + if (oper == GT_CNS_LNG) + { + INT64 lngVal = con->LngValue(); + + conVal = (ssize_t)lngVal; // truncate to 32-bits + + fitsInVal = ((INT64)conVal == lngVal); + } +#endif // TARGET_X86 + // If the constant is a handle then it will need to have a relocation // applied to it. // - GenTreeIntConCommon* con = tree->AsIntConCommon(); - bool iconNeedsReloc = con->ImmedValNeedsReloc(this); - if (!iconNeedsReloc && con->FitsInI8()) + if (iconNeedsReloc) + { + costSz = 4; + costEx = 1; + } + else if (fitsInVal && GenTreeIntConCommon::FitsInI8(conVal)) { costSz = 1; costEx = 1; } -#if defined(TARGET_AMD64) - else if (iconNeedsReloc || !con->FitsInI32()) +#ifdef TARGET_AMD64 + else if (!GenTreeIntConCommon::FitsInI32(conVal)) { costSz = 10; - costEx = 3; + costEx = 2; } #endif // TARGET_AMD64 else @@ -3329,21 +3389,83 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) costSz = 4; costEx = 1; } +#ifdef TARGET_X86 + if (oper == GT_CNS_LNG) + { + costSz += fitsInVal ? 1 : 4; + costEx += 1; + } +#endif // TARGET_X86 + goto COMMON_CNS; } #elif defined(TARGET_ARM64) - case GT_CNS_LNG: + case GT_CNS_STR: + case GT_CNS_LNG: case GT_CNS_INT: - // TODO-ARM64-NYI: Need cost estimates. - costSz = 1; - costEx = 1; + { + GenTreeIntConCommon* con = tree->AsIntConCommon(); + bool iconNeedsReloc = con->ImmedValNeedsReloc(this); + INT64 imm = con->LngValue(); + emitAttr size = EA_SIZE(emitActualTypeSize(tree)); + + if (iconNeedsReloc) + { + costSz = 8; + costEx = 2; + } + else if (emitter::emitIns_valid_imm_for_add(imm, size)) + { + costSz = 2; + costEx = 1; + } + else if (emitter::emitIns_valid_imm_for_mov(imm, size)) + { + costSz = 4; + costEx = 1; + } + else + { + // Arm64 allows any arbitrary 16-bit constant to be loaded into a register halfword + // There are three forms + // movk which loads into any halfword preserving the remaining halfwords + // movz which loads into any halfword zeroing the remaining halfwords + // movn which loads into any halfword zeroing the remaining halfwords then bitwise inverting + // the register + // In some cases it is preferable to use movn, because it has the side effect of filling the + // other halfwords + // with ones + + // Determine whether movn or movz will require the fewest instructions to populate the immediate + bool preferMovz = false; + bool preferMovn = false; + int instructionCount = 4; + + for (int i = (size == EA_8BYTE) ? 48 : 16; i >= 0; i -= 16) + { + if (!preferMovn && (uint16_t(imm >> i) == 0x0000)) + { + preferMovz = true; // by using a movk to start we can save one instruction + instructionCount--; + } + else if (!preferMovz && (uint16_t(imm >> i) == 0xffff)) + { + preferMovn = true; // by using a movn to start we can save one instruction + instructionCount--; + } + } + + costEx = instructionCount; + costSz = 4 * instructionCount; + } + } goto COMMON_CNS; #else - case GT_CNS_LNG: case GT_CNS_STR: + case GT_CNS_LNG: case GT_CNS_INT: #error "Unknown TARGET" #endif diff --git a/src/coreclr/src/jit/jitconfigvalues.h b/src/coreclr/src/jit/jitconfigvalues.h index e6c1ab307e46..329f526e9004 100644 --- a/src/coreclr/src/jit/jitconfigvalues.h +++ b/src/coreclr/src/jit/jitconfigvalues.h @@ -285,6 +285,20 @@ CONFIG_INTEGER(JitDisableSimdVN, W("JitDisableSimdVN"), 0) // Default 0, ValueNu // If 3, disable both SIMD and HW Intrinsic nodes #endif // FEATURE_SIMD +// Default 0, enable the CSE of Constants, including nearby offsets. (only for ARM64) +// If 1, disable all the CSE of Constants +// If 2, enable the CSE of Constants but don't combine with nearby offsets. (only for ARM64) +// If 3, enable the CSE of Constants including nearby offsets. (all platforms) +// If 4, enable the CSE of Constants but don't combine with nearby offsets. (all platforms) +// +CONFIG_INTEGER(JitConstCSE, W("JitConstCSE"), 0) + +#define CONST_CSE_ENABLE_ARM64 0 +#define CONST_CSE_DISABLE_ALL 1 +#define CONST_CSE_ENABLE_ARM64_NO_SHARING 2 +#define CONST_CSE_ENABLE_ALL 3 +#define CONST_CSE_ENABLE_ALL_NO_SHARING 4 + /// /// JIT /// diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index c333a2799fe4..2979a784570f 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -2707,6 +2707,13 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) indirectCellAddress->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd; #endif indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM); +#ifdef TARGET_ARM + // Issue #xxxx : Don't attempt to CSE this constant on ARM32 + // + // This constant has specific register requirements, and LSRA doesn't currently correctly + // handle them when the value is in a CSE'd local. + indirectCellAddress->SetDoNotCSE(); +#endif // TARGET_ARM // Push the stub address onto the list of arguments. call->gtCallArgs = gtPrependNewCallArg(indirectCellAddress, call->gtCallArgs); diff --git a/src/coreclr/src/jit/optcse.cpp b/src/coreclr/src/jit/optcse.cpp index 46e834df0dc4..1b70f7a027b6 100644 --- a/src/coreclr/src/jit/optcse.cpp +++ b/src/coreclr/src/jit/optcse.cpp @@ -401,10 +401,27 @@ void Compiler::optValnumCSE_Init() // unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) { - unsigned key; + size_t key; unsigned hash; unsigned hval; CSEdsc* hashDsc; + bool isIntConstHash = false; + bool enableSharedConstCSE = false; + int configValue = JitConfig.JitConstCSE(); + +#if defined(TARGET_ARM64) + // ARM64 - allow to combine with nearby offsets, when config is not 2 or 4 + if ((configValue != CONST_CSE_ENABLE_ARM64_NO_SHARING) && (configValue != CONST_CSE_ENABLE_ALL_NO_SHARING)) + { + enableSharedConstCSE = true; + } +#endif // TARGET_ARM64 + + // All Platforms - also allow to combine with nearby offsets, when config is 3 + if (configValue == CONST_CSE_ENABLE_ALL) + { + enableSharedConstCSE = true; + } // We use the liberal Value numbers when building the set of CSE ValueNum vnLib = tree->GetVN(VNK_Liberal); @@ -446,11 +463,11 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) // if (vnOp2Lib != vnLib) { - key = (unsigned)vnLib; // include the exc set in the hash key + key = vnLib; // include the exc set in the hash key } else { - key = (unsigned)vnLibNorm; + key = vnLibNorm; } // If we didn't do the above we would have op1 as the CSE def @@ -459,14 +476,36 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) // assert(vnLibNorm == vnStore->VNNormalValue(vnOp2Lib)); } - else // Not a GT_COMMA + else if (enableSharedConstCSE && tree->IsIntegralConst()) { - key = (unsigned)vnLibNorm; + assert(vnStore->IsVNConstant(vnLibNorm)); + key = vnStore->CoercedConstantValue(vnLibNorm); + + // We don't shared small offset constants when we require a reloc + if (!tree->AsIntConCommon()->ImmedValNeedsReloc(this)) + { + // Make constants that have the same upper bits use the same key + + // Shift the key right by CSE_CONST_SHARED_LOW_BITS bits, this sets the upper bits to zero + key >>= CSE_CONST_SHARED_LOW_BITS; + } + assert((key & TARGET_SIGN_BIT) == 0); + + // We use the sign bit of 'key' as the flag + // that we are hashing constants (with a shared offset) + key |= TARGET_SIGN_BIT; + } + else // Not a GT_COMMA or a GT_CNS_INT + { + key = vnLibNorm; } // Compute the hash value for the expression - hash = key; + hash = (unsigned)key; +#ifdef TARGET_64BIT + hash ^= (unsigned)(key >> 32); +#endif hash *= (unsigned)(s_optCSEhashSize + 1); hash >>= 7; @@ -480,6 +519,12 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) { if (hashDsc->csdHashKey == key) { + // Check for mismatched types on GT_CNS_INT nodes + if ((tree->OperGet() == GT_CNS_INT) && (tree->TypeGet() != hashDsc->csdTree->TypeGet())) + { + continue; + } + treeStmtLst* newElem; /* Have we started the list of matching nodes? */ @@ -585,6 +630,8 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) hashDsc = new (this, CMK_CSE) CSEdsc; hashDsc->csdHashKey = key; + hashDsc->csdConstDefValue = 0; + hashDsc->csdConstDefVN = vnStore->VNForNull(); // uninit value hashDsc->csdIndex = 0; hashDsc->csdLiveAcrossCall = false; hashDsc->csdDefCount = 0; @@ -645,8 +692,17 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) #ifdef DEBUG if (verbose) { - printf("\nCSE candidate #%02u, vn=", CSEindex); - vnPrint(key, 0); + printf("\nCSE candidate #%02u, key=", CSEindex); + if (!Compiler::Is_Shared_Const_CSE(key)) + { + vnPrint((unsigned)key, 0); + } + else + { + size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(key); + printf("K_%p", dspPtr(kVal)); + } + printf(" in " FMT_BB ", [cost=%2u, size=%2u]: \n", compCurBB->bbNum, tree->GetCostEx(), tree->GetCostSz()); gtDispTree(tree); } @@ -666,6 +722,29 @@ unsigned Compiler::optValnumCSE_Locate() { // Locate CSE candidates and assign them indices + bool enableConstCSE = true; + + int configValue = JitConfig.JitConstCSE(); + + // all platforms - disable CSE of constant values when config is 1 + if (configValue == CONST_CSE_DISABLE_ALL) + { + enableConstCSE = false; + } + +#if !defined(TARGET_ARM64) + // non-ARM64 platforms - disable by default + // + enableConstCSE = false; + + // Check for the two enable cases for all platforms + // + if ((configValue == CONST_CSE_ENABLE_ALL) || (configValue == CONST_CSE_ENABLE_ALL_NO_SHARING)) + { + enableConstCSE = true; + } +#endif + for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext) { /* Make the block publicly available */ @@ -691,6 +770,16 @@ unsigned Compiler::optValnumCSE_Locate() optCseUpdateCheckedBoundMap(tree); } + // Don't allow CSE of constants if it is disabled + // + if (tree->IsIntegralConst()) + { + if (!enableConstCSE) + { + continue; + } + } + if (!optIsCSEcandidate(tree)) { continue; @@ -701,15 +790,17 @@ unsigned Compiler::optValnumCSE_Locate() continue; } - // Don't CSE constant values, instead let the Value Number - // based Assertion Prop phase handle them. Here, unlike - // the rest of optCSE, we use the conservative value number + // We want to CSE simple constant leaf nodes, but we don't want to + // CSE non-leaf trees that compute CSE constant values. + // Instead we let the Value Number based Assertion Prop phase handle them. + // + // Here, unlike the rest of optCSE, we use the conservative value number // rather than the liberal one, since the conservative one // is what the Value Number based Assertion Prop will use // and the point is to avoid optimizing cases that it will // handle. // - if (vnStore->IsVNConstant(vnStore->VNConservativeNormalValue(tree->gtVNPair))) + if (!tree->OperIsLeaf() && vnStore->IsVNConstant(vnStore->VNConservativeNormalValue(tree->gtVNPair))) { continue; } @@ -1428,23 +1519,28 @@ void Compiler::optValnumCSE_Availablity() } } - // Record or update the value of desc->defConservNormVN + // For shared const CSE we don't set/use the defConservNormVN // - ValueNum theConservNormVN = vnStore->VNConservativeNormalValue(tree->gtVNPair); - - // Is defConservNormVN still set to the uninit marker value of VNForNull() ? - if (desc->defConservNormVN == vnStore->VNForNull()) - { - // This is the first def that we have visited, set defConservNormVN - desc->defConservNormVN = theConservNormVN; - } - else + if (!Is_Shared_Const_CSE(desc->csdHashKey)) { - // Check to see if all defs have the same conservative normal VN - if (theConservNormVN != desc->defConservNormVN) + // Record or update the value of desc->defConservNormVN + // + ValueNum theConservNormVN = vnStore->VNConservativeNormalValue(tree->gtVNPair); + + // Is defConservNormVN still set to the uninit marker value of VNForNull() ? + if (desc->defConservNormVN == vnStore->VNForNull()) { - // This candidate has defs with differing conservative normal VNs, mark it with NoVN - desc->defConservNormVN = ValueNumStore::NoVN; // record the marker for differing VNs + // This is the first def that we have visited, set defConservNormVN + desc->defConservNormVN = theConservNormVN; + } + else + { + // Check to see if all defs have the same conservative normal VN + if (theConservNormVN != desc->defConservNormVN) + { + // This candidate has defs with differing conservative normal VNs, mark it with NoVN + desc->defConservNormVN = ValueNumStore::NoVN; // record the marker for differing VNs + } } } @@ -1894,9 +1990,19 @@ class CSE_Heuristic cost = dsc->csdTree->GetCostEx(); } - printf("CSE #%02u, {$%-3x, $%-3x} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ", - dsc->csdIndex, dsc->csdHashKey, dsc->defExcSetPromise, dsc->csdUseCount, def, use, cost, - dsc->csdLiveAcrossCall ? ", call" : " "); + if (!Compiler::Is_Shared_Const_CSE(dsc->csdHashKey)) + { + printf("CSE #%02u, {$%-3x, $%-3x} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ", + dsc->csdIndex, dsc->csdHashKey, dsc->defExcSetPromise, dsc->csdUseCount, def, use, cost, + dsc->csdLiveAcrossCall ? ", call" : " "); + } + else + { + size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(dsc->csdHashKey); + printf("CSE #%02u, {K_%p} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ", dsc->csdIndex, + dspPtr(kVal), dsc->csdUseCount, def, use, cost, + dsc->csdLiveAcrossCall ? ", call" : " "); + } m_pCompiler->gtDispTree(expr, nullptr, nullptr, true); } @@ -2660,8 +2766,7 @@ class CSE_Heuristic // // Later we will unmark any nested CSE's for the CSE uses. // - Compiler::CSEdsc* dsc = successfulCandidate->CseDsc(); - Compiler::treeStmtLst* lst; + Compiler::CSEdsc* dsc = successfulCandidate->CseDsc(); // If there's just a single def for the CSE, we'll put this // CSE into SSA form on the fly. We won't need any PHIs. @@ -2678,53 +2783,122 @@ class CSE_Heuristic cseSsaNum = m_pCompiler->lvaTable[cseLclVarNum].lvPerSsaData.AllocSsaNum(allocator); } -#ifdef DEBUG // Verify that all of the ValueNumbers in this list are correct as // Morph will change them when it performs a mutating operation. // - ValueNum firstVN = ValueNumStore::NoVN; - ValueNum currVN; - bool allSame = true; + bool setRefCnt = true; + bool allSame = true; + bool isSharedConst = Compiler::Is_Shared_Const_CSE(dsc->csdHashKey); + ValueNum bestVN = ValueNumStore::NoVN; + bool bestIsDef = false; + ssize_t bestConstValue = 0; + Compiler::treeStmtLst* lst = dsc->csdTreeList; - lst = dsc->csdTreeList; while (lst != nullptr) { // Ignore this node if the gtCSEnum value has been cleared if (IS_CSE_INDEX(lst->tslTree->gtCSEnum)) { // We used the liberal Value numbers when building the set of CSE - currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair); + ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair); assert(currVN != ValueNumStore::NoVN); + ssize_t curConstValue = isSharedConst ? m_pCompiler->vnStore->CoercedConstantValue(currVN) : 0; - if (firstVN == ValueNumStore::NoVN) + GenTree* exp = lst->tslTree; + bool isDef = IS_CSE_DEF(exp->gtCSEnum); + + if (bestVN == ValueNumStore::NoVN) { - firstVN = currVN; + // first entry + // set bestVN + bestVN = currVN; + + if (isSharedConst) + { + // set bestConstValue and bestIsDef + bestConstValue = curConstValue; + bestIsDef = isDef; + } } - else if (currVN != firstVN) + else if (currVN != bestVN) { + assert(isSharedConst); // Must be true when we have differing VNs + + // subsequent entry + // clear allSame and check for a lower constant allSame = false; - break; + + ssize_t diff = curConstValue - bestConstValue; + + // The ARM64 ldr addressing modes allow for a subtraction of up to 255 + // so we will allow the diff to be up to -255 before replacing a CSE def + // This will minimize the number of extra subtract instructions. + // + if ((bestIsDef && (diff < -255)) || (!bestIsDef && (diff < 0))) + { + // set new bestVN, bestConstValue and bestIsDef + bestVN = currVN; + bestConstValue = curConstValue; + bestIsDef = isDef; + } + } + + BasicBlock* blk = lst->tslBlock; + BasicBlock::weight_t curWeight = blk->getBBWeight(m_pCompiler); + + if (setRefCnt) + { + m_pCompiler->lvaTable[cseLclVarNum].setLvRefCnt(1); + m_pCompiler->lvaTable[cseLclVarNum].setLvRefCntWtd(curWeight); + setRefCnt = false; + } + else + { + m_pCompiler->lvaTable[cseLclVarNum].incRefCnts(curWeight, m_pCompiler); + } + + // A CSE Def references the LclVar twice + // + if (isDef) + { + m_pCompiler->lvaTable[cseLclVarNum].incRefCnts(curWeight, m_pCompiler); } } lst = lst->tslNext; } - if (!allSame) + + dsc->csdConstDefValue = bestConstValue; + dsc->csdConstDefVN = bestVN; + +#ifdef DEBUG + if (m_pCompiler->verbose) { - lst = dsc->csdTreeList; - GenTree* firstTree = lst->tslTree; - printf("In %s, CSE (oper = %s, type = %s) has differing VNs: ", m_pCompiler->info.compFullName, - GenTree::OpName(firstTree->OperGet()), varTypeName(firstTree->TypeGet())); - while (lst != nullptr) + if (!allSame) { - if (IS_CSE_INDEX(lst->tslTree->gtCSEnum)) + if (isSharedConst) + { + printf("\nWe have shared Const CSE's and selected " FMT_VN " with a value of 0x%p as the base.\n", + dsc->csdConstDefVN, dspPtr(dsc->csdConstDefValue)); + } + else // !isSharedConst { - currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair); - printf("0x%x(%s " FMT_VN ") ", lst->tslTree, IS_CSE_USE(lst->tslTree->gtCSEnum) ? "use" : "def", - currVN); + lst = dsc->csdTreeList; + GenTree* firstTree = lst->tslTree; + printf("In %s, CSE (oper = %s, type = %s) has differing VNs: ", m_pCompiler->info.compFullName, + GenTree::OpName(firstTree->OperGet()), varTypeName(firstTree->TypeGet())); + while (lst != nullptr) + { + if (IS_CSE_INDEX(lst->tslTree->gtCSEnum)) + { + ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair); + printf("0x%x(%s " FMT_VN ") ", lst->tslTree, + IS_CSE_USE(lst->tslTree->gtCSEnum) ? "use" : "def", currVN); + } + lst = lst->tslNext; + } + printf("\n"); } - lst = lst->tslNext; } - printf("\n"); } #endif // DEBUG @@ -2762,7 +2936,8 @@ class CSE_Heuristic // The cseLclVarType must be a compatible with expTyp // - noway_assert(IsCompatibleType(cseLclVarTyp, expTyp)); + ValueNumStore* vnStore = m_pCompiler->vnStore; + noway_assert(IsCompatibleType(cseLclVarTyp, expTyp) || (dsc->csdConstDefVN != vnStore->VNForNull())); // This will contain the replacement tree for exp // It will either be the CSE def or CSE ref @@ -2790,63 +2965,86 @@ class CSE_Heuristic // We will replace the CSE ref with a new tree // this is typically just a simple use of the new CSE LclVar // - ValueNumStore* vnStore = m_pCompiler->vnStore; - cse = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp); - // Assign the ssa num for the use. Note it may be the reserved num. - cse->AsLclVarCommon()->SetSsaNum(cseSsaNum); - - // assign the proper ValueNumber, A CSE use discards any exceptions - cse->gtVNPair = vnStore->VNPNormalPair(exp->gtVNPair); + // Create a reference to the CSE temp + GenTree* cseLclVar = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp); + cseLclVar->gtVNPair.SetBoth(dsc->csdConstDefVN); - ValueNum theConservativeVN = successfulCandidate->CseDsc()->defConservNormVN; + // Assign the ssa num for the lclvar use. Note it may be the reserved num. + cseLclVar->AsLclVarCommon()->SetSsaNum(cseSsaNum); - if (theConservativeVN != ValueNumStore::NoVN) + cse = cseLclVar; + if (isSharedConst) { - // All defs of this CSE share the same normal conservative VN, and we are rewriting this - // use to fetch the same value with no reload, so we can safely propagate that - // conservative VN to this use. This can help range check elimination later on. - cse->gtVNPair.SetConservative(theConservativeVN); - - // If the old VN was flagged as a checked bound, propagate that to the new VN - // to make sure assertion prop will pay attention to this VN. - ValueNum oldVN = exp->gtVNPair.GetConservative(); - if (!vnStore->IsVNConstant(theConservativeVN) && vnStore->IsVNCheckedBound(oldVN)) + ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair); + ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN); + ssize_t delta = curValue - dsc->csdConstDefValue; + if (delta != 0) { - vnStore->SetVNIsCheckedBound(theConservativeVN); + GenTree* deltaNode = m_pCompiler->gtNewIconNode(delta, cseLclVarTyp); + cse = m_pCompiler->gtNewOperNode(GT_ADD, cseLclVarTyp, cseLclVar, deltaNode); + cse->SetDoNotCSE(); } + } - GenTree* cmp; - if ((m_pCompiler->optCseCheckedBoundMap != nullptr) && - (m_pCompiler->optCseCheckedBoundMap->Lookup(exp, &cmp))) - { - // Propagate the new value number to this compare node as well, since - // subsequent range check elimination will try to correlate it with - // the other appearances that are getting CSEd. + // assign the proper ValueNumber, A CSE use discards any exceptions + cse->gtVNPair = vnStore->VNPNormalPair(exp->gtVNPair); - ValueNum oldCmpVN = cmp->gtVNPair.GetConservative(); - ValueNum newCmpArgVN; + // shared const CSE has the correct value number assigned + // and both liberal and conservative are identical + // and they do not use theConservativeVN + // + if (!isSharedConst) + { + ValueNum theConservativeVN = successfulCandidate->CseDsc()->defConservNormVN; - ValueNumStore::CompareCheckedBoundArithInfo info; - if (vnStore->IsVNCompareCheckedBound(oldCmpVN)) + if (theConservativeVN != ValueNumStore::NoVN) + { + // All defs of this CSE share the same normal conservative VN, and we are rewriting this + // use to fetch the same value with no reload, so we can safely propagate that + // conservative VN to this use. This can help range check elimination later on. + cse->gtVNPair.SetConservative(theConservativeVN); + + // If the old VN was flagged as a checked bound, propagate that to the new VN + // to make sure assertion prop will pay attention to this VN. + ValueNum oldVN = exp->gtVNPair.GetConservative(); + if (!vnStore->IsVNConstant(theConservativeVN) && vnStore->IsVNCheckedBound(oldVN)) { - // Comparison is against the bound directly. - - newCmpArgVN = theConservativeVN; - vnStore->GetCompareCheckedBound(oldCmpVN, &info); + vnStore->SetVNIsCheckedBound(theConservativeVN); } - else + + GenTree* cmp; + if ((m_pCompiler->optCseCheckedBoundMap != nullptr) && + (m_pCompiler->optCseCheckedBoundMap->Lookup(exp, &cmp))) { - // Comparison is against the bound +/- some offset. + // Propagate the new value number to this compare node as well, since + // subsequent range check elimination will try to correlate it with + // the other appearances that are getting CSEd. - assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN)); - vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info); - newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, - info.arrOp, theConservativeVN); + ValueNum oldCmpVN = cmp->gtVNPair.GetConservative(); + ValueNum newCmpArgVN; + + ValueNumStore::CompareCheckedBoundArithInfo info; + if (vnStore->IsVNCompareCheckedBound(oldCmpVN)) + { + // Comparison is against the bound directly. + + newCmpArgVN = theConservativeVN; + vnStore->GetCompareCheckedBound(oldCmpVN, &info); + } + else + { + // Comparison is against the bound +/- some offset. + + assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN)); + vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info); + newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, + info.arrOp, theConservativeVN); + } + ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper, + info.cmpOp, newCmpArgVN); + cmp->gtVNPair.SetConservative(newCmpVN); } - ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper, - info.cmpOp, newCmpArgVN); - cmp->gtVNPair.SetConservative(newCmpVN); } } #ifdef DEBUG @@ -2878,10 +3076,9 @@ class CSE_Heuristic } #endif - GenTree* cseVal = cse; - GenTree* curSideEff = sideEffList; - ValueNumStore* vnStore = m_pCompiler->vnStore; - ValueNumPair exceptions_vnp = ValueNumStore::VNPForEmptyExcSet(); + GenTree* cseVal = cse; + GenTree* curSideEff = sideEffList; + ValueNumPair exceptions_vnp = ValueNumStore::VNPForEmptyExcSet(); while ((curSideEff->OperGet() == GT_COMMA) || (curSideEff->OperGet() == GT_ASG)) { @@ -2936,6 +3133,17 @@ class CSE_Heuristic exp->gtCSEnum = NO_CSE; // clear the gtCSEnum field GenTree* val = exp; + if (isSharedConst) + { + ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair); + ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN); + ssize_t delta = curValue - dsc->csdConstDefValue; + if (delta != 0) + { + val = m_pCompiler->gtNewIconNode(dsc->csdConstDefValue, cseLclVarTyp); + val->gtVNPair.SetBoth(dsc->csdConstDefVN); + } + } /* Create an assignment of the value to the temp */ GenTree* asg = m_pCompiler->gtNewTempAssign(cseLclVarNum, val); @@ -2977,19 +3185,37 @@ class CSE_Heuristic } /* Create a reference to the CSE temp */ - GenTree* ref = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp); - ref->gtVNPair = val->gtVNPair; // The new 'ref' is the same as 'val' + GenTree* cseLclVar = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp); + cseLclVar->gtVNPair.SetBoth(dsc->csdConstDefVN); + + // Assign the ssa num for the lclvar use. Note it may be the reserved num. + cseLclVar->AsLclVarCommon()->SetSsaNum(cseSsaNum); - // Assign the ssa num for the ref use. Note it may be the reserved num. - ref->AsLclVarCommon()->SetSsaNum(cseSsaNum); + GenTree* cseUse = cseLclVar; + if (isSharedConst) + { + ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair); + ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN); + ssize_t delta = curValue - dsc->csdConstDefValue; + if (delta != 0) + { + GenTree* deltaNode = m_pCompiler->gtNewIconNode(delta, cseLclVarTyp); + cseUse = m_pCompiler->gtNewOperNode(GT_ADD, cseLclVarTyp, cseLclVar, deltaNode); + cseUse->SetDoNotCSE(); + } + } + cseUse->gtVNPair = val->gtVNPair; // The 'cseUse' is equal to 'val' /* Create a comma node for the CSE assignment */ - cse = m_pCompiler->gtNewOperNode(GT_COMMA, expTyp, origAsg, ref); - cse->gtVNPair = ref->gtVNPair; // The comma's value is the same as 'val' - // as the assignment to the CSE LclVar - // cannot add any new exceptions + cse = m_pCompiler->gtNewOperNode(GT_COMMA, expTyp, origAsg, cseUse); + cse->gtVNPair = cseUse->gtVNPair; // The comma's value is the same as 'val' + // as the assignment to the CSE LclVar + // cannot add any new exceptions } + cse->CopyReg(exp); // The cse inheirits any reg num property from the orginal exp node + exp->ClearRegNum(); // The exp node (for a CSE def) no longer has a register requirement + // Walk the statement 'stmt' and find the pointer // in the tree is pointing to 'exp' // @@ -3069,9 +3295,19 @@ class CSE_Heuristic #ifdef DEBUG if (m_pCompiler->verbose) { - printf("\nConsidering CSE #%02u {$%-3x, $%-3x} [def=%3u, use=%3u, cost=%3u%s]\n", candidate.CseIndex(), - dsc->csdHashKey, dsc->defExcSetPromise, candidate.DefCount(), candidate.UseCount(), - candidate.Cost(), dsc->csdLiveAcrossCall ? ", call" : " "); + if (!Compiler::Is_Shared_Const_CSE(dsc->csdHashKey)) + { + printf("\nConsidering CSE #%02u {$%-3x, $%-3x} [def=%3u, use=%3u, cost=%3u%s]\n", + candidate.CseIndex(), dsc->csdHashKey, dsc->defExcSetPromise, candidate.DefCount(), + candidate.UseCount(), candidate.Cost(), dsc->csdLiveAcrossCall ? ", call" : " "); + } + else + { + size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(dsc->csdHashKey); + printf("\nConsidering CSE #%02u {K_%p} [def=%3u, use=%3u, cost=%3u%s]\n", candidate.CseIndex(), + dspPtr(kVal), candidate.DefCount(), candidate.UseCount(), candidate.Cost(), + dsc->csdLiveAcrossCall ? ", call" : " "); + } printf("CSE Expression : \n"); m_pCompiler->gtDispTree(candidate.Expr()); printf("\n"); @@ -3306,8 +3542,11 @@ bool Compiler::optIsCSEcandidate(GenTree* tree) return (tree->AsOp()->gtOp1->gtOper != GT_ARR_ELEM); - case GT_CNS_INT: case GT_CNS_LNG: +#ifndef TARGET_64BIT + return false; // Don't CSE 64-bit constants on 32-bit platforms +#endif + case GT_CNS_INT: case GT_CNS_DBL: case GT_CNS_STR: return true; // We reach here only when CSE_CONSTS is enabled diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index 4e75434cd242..9d6bc46472eb 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -31,12 +31,15 @@ // with static const members of Target #if defined(TARGET_XARCH) #define REGMASK_BITS 32 +#define CSE_CONST_SHARED_LOW_BITS 16 #elif defined(TARGET_ARM) #define REGMASK_BITS 64 +#define CSE_CONST_SHARED_LOW_BITS 12 #elif defined(TARGET_ARM64) #define REGMASK_BITS 64 +#define CSE_CONST_SHARED_LOW_BITS 12 #else #error Unsupported or unset target architecture @@ -1997,9 +2000,13 @@ C_ASSERT((RBM_INT_CALLEE_SAVED & RBM_FPBASE) == RBM_NONE); #ifdef TARGET_64BIT typedef unsigned __int64 target_size_t; typedef __int64 target_ssize_t; -#else // !TARGET_64BIT +#define TARGET_SIGN_BIT (1ULL << 63) + +#else // !TARGET_64BIT typedef unsigned int target_size_t; typedef int target_ssize_t; +#define TARGET_SIGN_BIT (1ULL << 31) + #endif // !TARGET_64BIT C_ASSERT(sizeof(target_size_t) == TARGET_POINTER_SIZE); diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r4.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r4.ilproj index cef275ea4942..ab2089808340 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r4.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r4.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r8.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r8.ilproj index e92e57de25c7..ca0982693df2 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r8.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/beq_r8.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r4.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r4.ilproj index b5e9a76cdac4..191bb09523af 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r4.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r4.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r8.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r8.ilproj index 62ed8ad09721..5e8c0aed782c 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r8.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_r8.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r4.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r4.ilproj index ba5b4cd85720..b0a46391cdbd 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r4.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r4.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r8.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r8.ilproj index ca67fefcb764..8d689526c4de 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r8.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bge_un_r8.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r4.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r4.ilproj index 891402dd071a..a3b92f67f70b 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r4.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r4.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r8.ilproj b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r8.ilproj index eb0db5833a1d..ededde0d346d 100644 --- a/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r8.ilproj +++ b/src/tests/JIT/IL_Conformance/Old/Conformance_Base/bne_un_r8.ilproj @@ -2,7 +2,7 @@ Exe true - 1 + 0 PdbOnly diff --git a/src/tests/JIT/Methodical/NaN/arithm64_cs_d.csproj b/src/tests/JIT/Methodical/NaN/arithm64_cs_d.csproj index 3c8a6b09632f..882dbd5ce4de 100644 --- a/src/tests/JIT/Methodical/NaN/arithm64_cs_d.csproj +++ b/src/tests/JIT/Methodical/NaN/arithm64_cs_d.csproj @@ -1,7 +1,7 @@ Exe - 1 + 0 Full diff --git a/src/tests/JIT/Methodical/NaN/arithm64_cs_do.csproj b/src/tests/JIT/Methodical/NaN/arithm64_cs_do.csproj index 645b85538bf6..63895dbcfb49 100644 --- a/src/tests/JIT/Methodical/NaN/arithm64_cs_do.csproj +++ b/src/tests/JIT/Methodical/NaN/arithm64_cs_do.csproj @@ -1,7 +1,7 @@ Exe - 1 + 0 Full diff --git a/src/tests/JIT/Methodical/NaN/arithm64_cs_r.csproj b/src/tests/JIT/Methodical/NaN/arithm64_cs_r.csproj index f70b11917026..750ade690621 100644 --- a/src/tests/JIT/Methodical/NaN/arithm64_cs_r.csproj +++ b/src/tests/JIT/Methodical/NaN/arithm64_cs_r.csproj @@ -1,7 +1,7 @@ Exe - 1 + 0 None diff --git a/src/tests/JIT/Methodical/NaN/arithm64_cs_ro.csproj b/src/tests/JIT/Methodical/NaN/arithm64_cs_ro.csproj index a453a807abb1..21d4a502b6b4 100644 --- a/src/tests/JIT/Methodical/NaN/arithm64_cs_ro.csproj +++ b/src/tests/JIT/Methodical/NaN/arithm64_cs_ro.csproj @@ -1,7 +1,7 @@ Exe - 1 + 0 None From cbf79b686ae59a31868f5b46f7df49c46fa58b2d Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 23 Jul 2020 17:54:19 -0700 Subject: [PATCH 022/755] Annotate TypeConverterAttribute so that the ILLinker preserves the ctor on the converter (#39144) * Annotate TypeConverterAttribute so that the ILLinker preserves the ctor on the converter * Address review feedback & add attributes to ref * Use custom enum converter type * Split tests --- .../ref/System.ObjectModel.cs | 5 +- .../ComponentModel/TypeConverterAttribute.cs | 7 ++- ...TypeConverterAttributeStringArgCtorTest.cs | 40 ++++++++++++++++ .../TypeConverterAttributeTypeArgCtorTest.cs | 47 +++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeStringArgCtorTest.cs create mode 100644 src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeTypeArgCtorTest.cs diff --git a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs index 6761a3092a6b..e29b22bb1505 100644 --- a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs +++ b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs @@ -198,8 +198,9 @@ public sealed partial class TypeConverterAttribute : System.Attribute { public static readonly System.ComponentModel.TypeConverterAttribute Default; public TypeConverterAttribute() { } - public TypeConverterAttribute(string typeName) { } - public TypeConverterAttribute(System.Type type) { } + public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName) { } + public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public string ConverterTypeName { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } diff --git a/src/libraries/System.ObjectModel/src/System/ComponentModel/TypeConverterAttribute.cs b/src/libraries/System.ObjectModel/src/System/ComponentModel/TypeConverterAttribute.cs index 0d44850745f7..df6569a283a7 100644 --- a/src/libraries/System.ObjectModel/src/System/ComponentModel/TypeConverterAttribute.cs +++ b/src/libraries/System.ObjectModel/src/System/ComponentModel/TypeConverterAttribute.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.ComponentModel { /// @@ -30,7 +32,7 @@ public TypeConverterAttribute() /// class, using the specified type as the data converter for the object this attribute /// is bound to. /// - public TypeConverterAttribute(Type type) + public TypeConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { if (type == null) { @@ -45,7 +47,7 @@ public TypeConverterAttribute(Type type) /// class, using the specified type name as the data converter for the object this attribute /// is bound to. /// - public TypeConverterAttribute(string typeName) + public TypeConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName) { if (typeName == null) { @@ -59,6 +61,7 @@ public TypeConverterAttribute(string typeName) /// Gets the fully qualified type name of the to use as a /// converter for the object this attribute is bound to. /// + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] public string ConverterTypeName { get; } public override bool Equals(object? obj) diff --git a/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeStringArgCtorTest.cs b/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeStringArgCtorTest.cs new file mode 100644 index 000000000000..4803dce6b7c5 --- /dev/null +++ b/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeStringArgCtorTest.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.ComponentModel; +using System.Globalization; + +namespace TypeConverterAttributeTest +{ + /// + /// Tests that the public constructors of types passed into System.ComponentModel.TypeConverterAttribute + /// are not trimmed out when needed in a trimmed application. + /// + class Program + { + static int Main(string[] args) + { + // String-based TypeConverterAttribute ctor overload, ensure public parameterless ctor of TypeConverter type is preserved. + TypeDescriptor.AddAttributes(typeof(string), new TypeConverterAttribute("TypeConverterAttributeTest.MyStringConverter, project, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); + var attribute = new DefaultValueAttribute(typeof(string), "Hello, world!"); + return (string)attribute.Value == "Hello, world!trivia" ? 100 : -1; + } + } + + internal class MyStringConverter : StringConverter + { + /// + /// Converts the specified value object to a string object. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string str) + { + return str + "trivia"; + } + + throw new NotSupportedException(); + } + } +} diff --git a/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeTypeArgCtorTest.cs b/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeTypeArgCtorTest.cs new file mode 100644 index 000000000000..bfa67ddf27a3 --- /dev/null +++ b/src/libraries/System.ObjectModel/tests/TrimmingTests/TypeConverterAttributeTypeArgCtorTest.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.ComponentModel; +using System.Globalization; + +namespace TypeConverterAttributeTest +{ + /// + /// Tests that the public constructors of types passed into System.ComponentModel.TypeConverterAttribute + /// are not trimmed out when needed in a trimmed application. + /// + class Program + { + static int Main(string[] args) + { + // Type-based TypeConverterAttribute ctor overload, ensure public parameterized ctor of TypeConverter type is preserved. + TypeDescriptor.AddAttributes(typeof(DayOfWeek), new TypeConverterAttribute(typeof(MyDayOfWeekConverter))); + var attribute = new DefaultValueAttribute(typeof(DayOfWeek), "Friday"); + return (DayOfWeek)attribute.Value == DayOfWeek.Monday ? 100 : -1; + } + } + + internal class MyDayOfWeekConverter : TypeConverter + { + private readonly Type _type; + + public MyDayOfWeekConverter(Type type) + { + _type = type; + } + + /// + /// Converts the specified value object to a DayOfWeek value. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (_type == typeof(DayOfWeek) && value is string str && str == "Friday") + { + return DayOfWeek.Monday; + } + + throw new NotSupportedException(); + } + } +} From b2d9dac0d44b21ec3de4fcada196610500763cca Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 23 Jul 2020 20:58:24 -0400 Subject: [PATCH 023/755] [aot] Avoid a crash in generic sharing for invalid generic instances. Fixes https://github.com/mono/mono/issues/20138. (#39869) Co-authored-by: vargaz --- src/mono/mono/mini/mini-generic-sharing.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 8c042132af15..5fb8bbb39c96 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1170,6 +1170,8 @@ get_wrapper_shared_vtype (MonoType *t) if ((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT) return NULL; mono_class_setup_fields (klass); + if (mono_class_has_failure (klass)) + return NULL; int num_fields = mono_class_get_field_count (klass); MonoClassField *klass_fields = m_class_get_fields (klass); From df5d9ccd60d638106627d12038c15d9b2693496c Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 23 Jul 2020 18:03:29 -0700 Subject: [PATCH 024/755] Remove unused pinvokes for WinRT scenarios (#39846) * Remove GetRestructedErrorInfo P/Invoke * Remove win32 core memory P/Invokes * Remove RoGetBufferMarshaler P/Invoke * Remove RoGetActivationFactory P/Invoke * Remove CoreComm P/Invokes * Remove IRestrictedErrorInfo definition. --- .../src/Interop/Windows/Interop.Libraries.cs | 6 ----- .../Windows/Mincore/Interop.GetCommPorts.cs | 27 ------------------- .../Mincore/Interop.GetRestrictedErrorInfo.cs | 15 ----------- .../Windows/Mincore/Interop.OpenCommPort.cs | 19 ------------- .../Mincore/Interop.OpenFileMappingFromApp.cs | 18 ------------- .../Mincore/Interop.RoGetActivationFactory.cs | 18 ------------- .../Mincore/Interop.RoGetBufferMarshaler.cs | 18 ------------- .../Mincore/Interop.VirtualAllocFromApp.cs | 19 ------------- .../WindowsRuntime/IRestrictedErrorInfo.cs | 20 -------------- 9 files changed, 160 deletions(-) delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetCommPorts.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetRestrictedErrorInfo.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenCommPort.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenFileMappingFromApp.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetActivationFactory.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetBufferMarshaler.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Mincore/Interop.VirtualAllocFromApp.cs delete mode 100644 src/libraries/Common/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs diff --git a/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs index 692cdd783f2f..74c014c71799 100644 --- a/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs @@ -7,16 +7,12 @@ internal static partial class Libraries { internal const string Advapi32 = "advapi32.dll"; internal const string BCrypt = "BCrypt.dll"; - internal const string CoreComm_L1_1_1 = "api-ms-win-core-comm-l1-1-1.dll"; - internal const string CoreComm_L1_1_2 = "api-ms-win-core-comm-l1-1-2.dll"; internal const string Crypt32 = "crypt32.dll"; internal const string CryptUI = "cryptui.dll"; - internal const string Error_L1 = "api-ms-win-core-winrt-error-l1-1-0.dll"; internal const string Gdi32 = "gdi32.dll"; internal const string HttpApi = "httpapi.dll"; internal const string IpHlpApi = "iphlpapi.dll"; internal const string Kernel32 = "kernel32.dll"; - internal const string Memory_L1_3 = "api-ms-win-core-memory-l1-1-3.dll"; internal const string Mswsock = "mswsock.dll"; internal const string NCrypt = "ncrypt.dll"; internal const string NtDll = "ntdll.dll"; @@ -24,7 +20,6 @@ internal static partial class Libraries internal const string Ole32 = "ole32.dll"; internal const string OleAut32 = "oleaut32.dll"; internal const string PerfCounter = "perfcounter.dll"; - internal const string RoBuffer = "api-ms-win-core-winrt-robuffer-l1-1-0.dll"; internal const string Secur32 = "secur32.dll"; internal const string Shell32 = "shell32.dll"; internal const string SspiCli = "sspicli.dll"; @@ -37,7 +32,6 @@ internal static partial class Libraries internal const string Ws2_32 = "ws2_32.dll"; internal const string Wtsapi32 = "wtsapi32.dll"; internal const string CompressionNative = "clrcompression.dll"; - internal const string CoreWinRT = "api-ms-win-core-winrt-l1-1-0.dll"; internal const string MsQuic = "msquic.dll"; internal const string HostPolicy = "hostpolicy.dll"; } diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetCommPorts.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetCommPorts.cs deleted file mode 100644 index 1ed2e964b7d4..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetCommPorts.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.CoreComm_L1_1_2, SetLastError = true)] - private static extern unsafe int GetCommPorts( - uint* lpPortNumbers, - uint uPortNumbersCount, - out uint puPortNumbersFound); - - internal static unsafe int GetCommPorts( - Span portNumbers, - out uint portNumbersFound) - { - fixed (uint* portNumbersBuffer = &MemoryMarshal.GetReference(portNumbers)) - { - return GetCommPorts(portNumbersBuffer, (uint)portNumbers.Length, out portNumbersFound); - } - } - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetRestrictedErrorInfo.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetRestrictedErrorInfo.cs deleted file mode 100644 index 8bfeebb4f3a3..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.GetRestrictedErrorInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.WindowsRuntime; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.Error_L1, PreserveSig = false)] - internal static extern IRestrictedErrorInfo GetRestrictedErrorInfo(); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenCommPort.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenCommPort.cs deleted file mode 100644 index 60a3408b3631..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenCommPort.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Win32.SafeHandles; -using System; -using System.IO; -using System.Runtime.InteropServices; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.CoreComm_L1_1_1, SetLastError = true)] - internal static extern SafeFileHandle OpenCommPort( - uint uPortNumber, - int dwDesiredAccess, - int dwFlagsAndAttributes); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenFileMappingFromApp.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenFileMappingFromApp.cs deleted file mode 100644 index 01448ecf2853..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.OpenFileMappingFromApp.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.InteropServices; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.Memory_L1_3, CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern SafeMemoryMappedFileHandle OpenFileMappingFromApp( - int DesiredAccess, - [MarshalAs(UnmanagedType.Bool)] bool InheritHandle, - string Name); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetActivationFactory.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetActivationFactory.cs deleted file mode 100644 index a8c9a93d5920..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetActivationFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.InteropServices; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.CoreWinRT, PreserveSig = true)] - internal static extern int RoGetActivationFactory( - [MarshalAs(UnmanagedType.HString)] string activatableClassId, - [In] ref Guid iid, - [Out, MarshalAs(UnmanagedType.IInspectable)] out object factory); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetBufferMarshaler.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetBufferMarshaler.cs deleted file mode 100644 index 08ba54063873..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.RoGetBufferMarshaler.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.RoBuffer, CallingConvention = CallingConvention.StdCall, PreserveSig = true)] - internal static extern int RoGetBufferMarshaler(out IMarshal bufferMarshalerPtr); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.VirtualAllocFromApp.cs b/src/libraries/Common/src/Interop/Windows/Mincore/Interop.VirtualAllocFromApp.cs deleted file mode 100644 index 179e6263ab25..000000000000 --- a/src/libraries/Common/src/Interop/Windows/Mincore/Interop.VirtualAllocFromApp.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.InteropServices; - -internal partial class Interop -{ - internal partial class mincore - { - [DllImport(Libraries.Memory_L1_3, CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern IntPtr VirtualAllocFromApp( - SafeHandle BaseAddress, - UIntPtr Size, - int AllocationType, - int Protection); - } -} diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs b/src/libraries/Common/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs deleted file mode 100644 index 1cf4566c7616..000000000000 --- a/src/libraries/Common/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace System.Runtime.InteropServices.WindowsRuntime -{ - [ComImport] - [Guid("82BA7092-4C88-427D-A7BC-16DD93FEB67E")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - internal interface IRestrictedErrorInfo - { - void GetErrorDetails([MarshalAs(UnmanagedType.BStr)] out string description, - out int error, - [MarshalAs(UnmanagedType.BStr)] out string restrictedDescription, - [MarshalAs(UnmanagedType.BStr)] out string capabilitySid); - - void GetReference([MarshalAs(UnmanagedType.BStr)] out string reference); - } -} From e65c3091bd2c3a38e465c40c9e8e38202584a449 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 23 Jul 2020 23:13:07 -0700 Subject: [PATCH 025/755] Add ReferenceConverter entry to intrinsic type converters table (#39854) * Add ReferenceConverter entry to intrinsic type converters table * Add tests --- .../System/ComponentModel/ReflectTypeDescriptionProvider.cs | 1 + .../tests/TypeDescriptorTests.cs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs index ce355d14ac3c..5423539159f7 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs @@ -132,6 +132,7 @@ internal ReflectTypeDescriptionProvider() [typeof(ICollection)] = typeof(CollectionConverter), [typeof(Enum)] = typeof(EnumConverter), [s_intrinsicNullableKey] = typeof(NullableConverter), + [s_intrinsicReferenceKey] = typeof(ReferenceConverter), }); private static Hashtable PropertyCache => LazyInitializer.EnsureInitialized(ref s_propertyCache, () => new Hashtable()); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs index 60aeeed511e1..16c67b724059 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs @@ -485,6 +485,7 @@ public void GetAssociationReturnsDesigner() [InlineData(typeof(CultureInfo), typeof(CultureInfoConverter))] [InlineData(typeof(Version), typeof(VersionConverter))] [InlineData(typeof(IComponent), typeof(ComponentConverter))] + [InlineData(typeof(IFooComponent), typeof(ReferenceConverter))] public static void GetConverter(Type targetType, Type resultConverterType) { TypeConverter converter = TypeDescriptor.GetConverter(targetType); @@ -1151,5 +1152,10 @@ class FooBarDerived : FooBarBase [Description("Derived")] public override int Value { get; set; } } + + interface IFooComponent + { + bool Flag { get; set; } + } } } From 3ff193b1f90b4474ec37406cae1e2e504c2df613 Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Fri, 24 Jul 2020 10:18:00 +0300 Subject: [PATCH 026/755] Remove leading dot check for cookie domain (#39781) Minimal fix for domain-related cookie issues of #26141 To fully comply with RFC 6265, one should remove deprecated cookie properties, such as Version, from public API. So only the stated issues with leading dot were addressed now. Also note that the leading dot was not stripped from the domain even though RFC 6265 proposed it. This behavior was chosen because browsers like Chrome and Edge also don't strip the leading dot. --- .../src/System/Net/Cookie.cs | 8 -- .../CookieTest/CookieContainerTest.cs | 5 +- .../tests/UnitTests/CookieContainerTest.cs | 80 ++++++++++++++++++- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs index c953ef2b8973..c9a4ef4efe43 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs @@ -414,14 +414,6 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma // Domain must start with '.' if set explicitly. if (domain[0] != '.') { - if (!(variant == CookieVariant.Rfc2965 || variant == CookieVariant.Plain)) - { - if (shouldThrow) - { - throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, m_domain)); - } - return false; - } domain = '.' + domain; } diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookieContainerTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookieContainerTest.cs index 621bc1d37105..ca5086386b14 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookieContainerTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest/CookieContainerTest.cs @@ -13,7 +13,7 @@ public partial class CookieContainerTest private const string CookieValue2 = "CookieValue2"; [Fact] - public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_ThrowsCookieException() + public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_Success() { const string SchemePrefix = "http://"; const string OriginalDomain = "contoso.com"; @@ -21,7 +21,8 @@ public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_ThrowsCookieExceptio var container = new CookieContainer(); var cookie = new Cookie(CookieName1, CookieValue1) { Version = 1, Domain = OriginalDomain }; var uri = new Uri(SchemePrefix + OriginalDomain); - Assert.Throws(() => container.Add(uri, cookie)); + container.Add(uri, cookie); + Assert.Equal(1, container.GetCookies(uri).Count); } [Fact] diff --git a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs index ec97b807714d..cd2ba344da44 100644 --- a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs +++ b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs @@ -364,7 +364,7 @@ public void SetCookies_Success(Uri uri, string cookieHeader, Cookie[] expected) } [Fact] - public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_ThrowsCookieException() + public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_Success() { const string SchemePrefix = "http://"; const string OriginalDomain = "contoso.com"; @@ -372,7 +372,8 @@ public void Add_CookieVersion1AndRootDomainWithNoLeadingDot_ThrowsCookieExceptio var container = new CookieContainer(); var cookie = new Cookie(CookieName1, CookieValue1) { Version = 1, Domain = OriginalDomain }; var uri = new Uri(SchemePrefix + OriginalDomain); - Assert.Throws(() => container.Add(uri, cookie)); + container.Add(uri, cookie); + Assert.Equal(1, container.GetCookies(uri).Count); } [Fact] @@ -762,5 +763,80 @@ private void VerifyGetCookies(CookieContainer cc1, Uri uri, Cookie[] expected) Assert.Equal(c1.Value, c2.Value); } } + + public static IEnumerable DomainCheckIgnoresVersionData() + { + string[] hosts = { "localhost", "example.com", "test.example.com" }; + int?[] ports = { null, 5000 }; + int?[] versions = { null, 0, 1, 100 }; + + foreach (string host in hosts) + { + foreach (int? port in ports) + { + string url = $"http://{host}" + (port != null ? $":{port}" : ""); + string domainWithLeadingDot = "." + host; + + foreach (int? version in versions) + { + // domain with leading dot + yield return new object[] { url, domainWithLeadingDot, version }; + + // domain without leading dot + yield return new object[] { url, host, version }; + } + } + } + } + + [Theory] + [MemberData(nameof(DomainCheckIgnoresVersionData))] + public void SetCookies_DomainCheckSuccess_IgnoresVersion(string url, string domain, int? version) + { + var uri = new Uri(url); + + string cookie = $"my_cookie=my_value; Domain={domain}" + (version != null ? $"; Version = {version}" : ""); + CookieContainer container = new CookieContainer(); + + container.SetCookies(uri, cookie); + + CookieCollection acceptedCookies = container.GetCookies(uri); + Assert.Equal(1, acceptedCookies.Count); + Assert.Equal(domain, acceptedCookies[0].Domain); + } + + [Theory] + [InlineData(".example.com")] + [InlineData("example.com")] + [InlineData(".test.example.com")] + [InlineData("test.example.com")] + public void SetCookies_DomainCheckSuccess_IgnoresAbsenceOfLeadingDot(string domain) + { + var uri = new Uri("http://test.example.com"); + + string cookie = $"my_cookie=my_value; Domain={domain}"; + CookieContainer container = new CookieContainer(); + + container.SetCookies(uri, cookie); + + CookieCollection acceptedCookies = container.GetCookies(uri); + Assert.Equal(1, acceptedCookies.Count); + Assert.Equal(domain, acceptedCookies[0].Domain); + } + + [Theory] + [InlineData(".other.example.com")] + [InlineData("other.example.com")] + [InlineData(".xample.com")] + [InlineData("xample.com")] + public void SetCookies_DomainCheckFailure_IgnoresAbsenceOfLeadingDot(string domain) + { + var uri = new Uri("http://test.example.com"); + + string cookie = $"my_cookie=my_value; Domain={domain}"; + CookieContainer container = new CookieContainer(); + + Assert.Throws(() => container.SetCookies(uri, cookie)); + } } } From dd7edf82e36e6c350a2c3fef0a0c2b69e8c11d61 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 24 Jul 2020 05:23:38 -0400 Subject: [PATCH 027/755] [runtime] Fix some more gc tracking problems in create_cattr_named/typed_arg. (#39856) --- src/mono/mono/metadata/custom-attrs.c | 41 ++++++++++++++++++--------- src/mono/mono/metadata/handle.h | 3 ++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 344ebbd9ec46..648f5a068d96 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -489,6 +489,7 @@ MONO_RESTORE_WARNING case MONO_TYPE_SZARRAY: { MonoArray *arr; guint32 i, alen, basetype; + if (!bcheck_blob (p, 3, boundp, error)) return NULL; alen = read32 (p); @@ -497,8 +498,10 @@ MONO_RESTORE_WARNING *end = p; return NULL; } + arr = mono_array_new_checked (mono_domain_get(), tklass, alen, error); return_val_if_nok (error, NULL); + basetype = m_class_get_byval_arg (tklass)->type; if (basetype == MONO_TYPE_VALUETYPE && m_class_is_enumtype (tklass)) basetype = mono_class_enum_basetype_internal (tklass)->type; @@ -569,7 +572,10 @@ MONO_RESTORE_WARNING case MONO_TYPE_CLASS: case MONO_TYPE_OBJECT: case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: + case MONO_TYPE_SZARRAY: { + HANDLE_FUNCTION_ENTER (); + MONO_HANDLE_NEW (MonoArray, arr); + for (i = 0; i < alen; i++) { MonoObject *item = NULL; load_cattr_value (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); @@ -577,13 +583,16 @@ MONO_RESTORE_WARNING return NULL; mono_array_setref_internal (arr, i, item); } + HANDLE_FUNCTION_RETURN (); break; + } default: g_error ("Type 0x%02x not handled in custom attr array decoding", basetype); } *end = p; g_assert (out_obj); *out_obj = (MonoObject*)arr; + return NULL; } default: @@ -618,13 +627,15 @@ load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const } static MonoObject* -create_cattr_typed_arg (MonoType *t, MonoObjectHandleOut res_h, MonoObject *val, MonoError *error) +create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error) { MonoObject *retval; void *params [2], *unboxed; error_init (error); + HANDLE_FUNCTION_ENTER (); + MONO_STATIC_POINTER_INIT (MonoMethod, ctor) ctor = mono_class_get_method_from_name_checked (mono_class_get_custom_attribute_typed_argument_class (), ".ctor", 2, 0, error); @@ -634,29 +645,33 @@ create_cattr_typed_arg (MonoType *t, MonoObjectHandleOut res_h, MonoObject *val, params [0] = mono_type_get_object_checked (mono_domain_get (), t, error); return_val_if_nok (error, NULL); + MONO_HANDLE_PIN ((MonoObject*)params [0]); params [1] = val; retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_typed_argument_class (), error); return_val_if_nok (error, NULL); - /* This will keep retval pinned during the runtime invoke */ - MONO_HANDLE_ASSIGN_RAW (res_h, retval); + MONO_HANDLE_PIN (retval); unboxed = mono_object_unbox_internal (retval); mono_runtime_invoke_checked (ctor, unboxed, params, error); return_val_if_nok (error, NULL); + HANDLE_FUNCTION_RETURN (); + return retval; } static MonoObject* -create_cattr_named_arg (void *minfo, MonoObjectHandleOut res_h, MonoObject *typedarg, MonoError *error) +create_cattr_named_arg (void *minfo, MonoObject *typedarg, MonoError *error) { MonoObject *retval; void *unboxed, *params [2]; error_init (error); + HANDLE_FUNCTION_ENTER (); + MONO_STATIC_POINTER_INIT (MonoMethod, ctor) ctor = mono_class_get_method_from_name_checked (mono_class_get_custom_attribute_named_argument_class (), ".ctor", 2, 0, error); @@ -668,14 +683,15 @@ create_cattr_named_arg (void *minfo, MonoObjectHandleOut res_h, MonoObject *type params [1] = typedarg; retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_named_argument_class (), error); return_val_if_nok (error, NULL); - /* This will keep retval pinned during the runtime invoke */ - MONO_HANDLE_ASSIGN_RAW (res_h, retval); + MONO_HANDLE_PIN (retval); unboxed = mono_object_unbox_internal (retval); mono_runtime_invoke_checked (ctor, unboxed, params, error); return_val_if_nok (error, NULL); + HANDLE_FUNCTION_RETURN (); + return retval; } @@ -1352,7 +1368,7 @@ ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoRe MonoReflectionMethod *ref_method = MONO_HANDLE_RAW (ref_method_h); MonoReflectionAssembly *assembly = MONO_HANDLE_RAW (assembly_h); MonoMethodSignature *sig; - MonoObjectHandle obj_h, namedarg_h, typedarg_h, minfo_h, arg_h; + MonoObjectHandle obj_h, namedarg_h, typedarg_h, minfo_h; int i; if (len == 0) @@ -1362,7 +1378,6 @@ ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoRe namedarg_h = MONO_HANDLE_NEW (MonoObject, NULL); typedarg_h = MONO_HANDLE_NEW (MonoObject, NULL); minfo_h = MONO_HANDLE_NEW (MonoObject, NULL); - arg_h = MONO_HANDLE_NEW (MonoObject, NULL); image = assembly->assembly->image; method = ref_method->method; @@ -1394,7 +1409,7 @@ ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoRe t = sig->params [i]; if (t->type == MONO_TYPE_OBJECT && obj) t = m_class_get_byval_arg (obj->vtable->klass); - typedarg = create_cattr_typed_arg (t, arg_h, obj, error); + typedarg = create_cattr_typed_arg (t, obj, error); goto_if_nok (error, leave); mono_array_setref_internal (typed_args, i, typedarg); } @@ -1416,13 +1431,13 @@ ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoRe MONO_HANDLE_ASSIGN_RAW (minfo_h, minfo); #if ENABLE_NETCORE - namedarg = create_cattr_named_arg (minfo, arg_h, obj, error); + namedarg = create_cattr_named_arg (minfo, obj, error); MONO_HANDLE_ASSIGN_RAW (namedarg_h, namedarg); #else - MonoObject* typedarg = create_cattr_typed_arg (arginfo [i].type, arg_h, obj, error); + MonoObject* typedarg = create_cattr_typed_arg (arginfo [i].type, obj, error); MONO_HANDLE_ASSIGN_RAW (typedarg_h, typedarg); goto_if_nok (error, leave); - namedarg = create_cattr_named_arg (minfo, arg_h, typedarg, error); + namedarg = create_cattr_named_arg (minfo, typedarg, error); MONO_HANDLE_ASSIGN_RAW (namedarg_h, namedarg); #endif goto_if_nok (error, leave); diff --git a/src/mono/mono/metadata/handle.h b/src/mono/mono/metadata/handle.h index 2cedc51bb7ea..6a9ad056deb7 100644 --- a/src/mono/mono/metadata/handle.h +++ b/src/mono/mono/metadata/handle.h @@ -516,6 +516,9 @@ TYPED_HANDLE_DECL (MonoObject); TYPED_HANDLE_DECL (MonoException); TYPED_HANDLE_DECL (MonoAppContext); +/* Simpler version of MONO_HANDLE_NEW if the handle is not used */ +#define MONO_HANDLE_PIN(object) MONO_HANDLE_NEW (MonoObject, (object)) + // Structs cannot be cast to structs. // As well, a function is needed because an anonymous struct cannot be initialized in C. static inline MonoObjectHandle From 2b2eb5ad72cd22c7ce0364efa836e3372cecc092 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 24 Jul 2020 11:50:41 +0200 Subject: [PATCH 028/755] [browser][tests] Activate System.Private.Uri.Functional.Tests (#39817) Local: ``` info: test[0] Tests run: 883, Errors: 0, Failures: 0, Skipped: 1. Time: 188.7140968s ``` --- src/libraries/tests.proj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 8212eca5be3f..37ddac60b2de 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -32,7 +32,6 @@ - From efd5565f3f8e209f7fada00e0c8c0779459faf35 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 24 Jul 2020 14:56:12 +0100 Subject: [PATCH 029/755] Add CBOR property-based tests (#39828) * Add CBOR property-based tests * address feedback --- eng/Versions.props | 1 + .../System.Formats.Cbor.sln | 7 + .../tests/CborDocument/CborDocument.fs | 51 ++++ .../CborDocument/CborDocumentSerializer.fs | 185 +++++++++++++++ .../CborDocument/CborPropertyTestContext.fs | 106 +++++++++ ...System.Formats.Cbor.Tests.DataModel.fsproj | 16 ++ .../tests/CborRoundtripTests.cs | 180 -------------- .../tests/PropertyTests/CborPropertyTests.cs | 219 ++++++++++++++++++ .../PropertyTests/CborRandomGenerators.cs | 68 ++++++ .../tests/System.Formats.Cbor.Tests.csproj | 22 +- 10 files changed, 673 insertions(+), 182 deletions(-) create mode 100644 src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocument.fs create mode 100644 src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocumentSerializer.fs create mode 100644 src/libraries/System.Formats.Cbor/tests/CborDocument/CborPropertyTestContext.fs create mode 100644 src/libraries/System.Formats.Cbor/tests/CborDocument/System.Formats.Cbor.Tests.DataModel.fsproj delete mode 100644 src/libraries/System.Formats.Cbor/tests/CborRoundtripTests.cs create mode 100644 src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs create mode 100644 src/libraries/System.Formats.Cbor/tests/PropertyTests/CborRandomGenerators.cs diff --git a/eng/Versions.props b/eng/Versions.props index 4d00ac9bfe4e..8a36d350af35 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -142,6 +142,7 @@ 2.0.5 12.0.3 4.12.0 + 2.14.3 3.0.0-preview-20200715.1 diff --git a/src/libraries/System.Formats.Cbor/System.Formats.Cbor.sln b/src/libraries/System.Formats.Cbor/System.Formats.Cbor.sln index baed5dfb1956..31f26813ae83 100644 --- a/src/libraries/System.Formats.Cbor/System.Formats.Cbor.sln +++ b/src/libraries/System.Formats.Cbor/System.Formats.Cbor.sln @@ -14,6 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Cbor", "ref\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Cbor.Tests", "tests\System.Formats.Cbor.Tests.csproj", "{1C84C43C-69A8-493E-AC11-0DA9C22BFB46}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "System.Formats.Cbor.Tests.DataModel", "tests\CborDocument\System.Formats.Cbor.Tests.DataModel.fsproj", "{3BF538B4-0985-4918-90A7-8F15BA9E661C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,6 +34,10 @@ Global {1C84C43C-69A8-493E-AC11-0DA9C22BFB46}.Debug|Any CPU.Build.0 = Debug|Any CPU {1C84C43C-69A8-493E-AC11-0DA9C22BFB46}.Release|Any CPU.ActiveCfg = Release|Any CPU {1C84C43C-69A8-493E-AC11-0DA9C22BFB46}.Release|Any CPU.Build.0 = Release|Any CPU + {3BF538B4-0985-4918-90A7-8F15BA9E661C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BF538B4-0985-4918-90A7-8F15BA9E661C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BF538B4-0985-4918-90A7-8F15BA9E661C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BF538B4-0985-4918-90A7-8F15BA9E661C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -40,6 +46,7 @@ Global {57B5AD1E-D0BA-4811-9276-9BBAFF44AB31} = {59B37ECC-D5BB-488A-9571-1E239EDF19A9} {B17130D2-0A75-464A-A3E7-67123C567CAF} = {B3417D0B-D64E-4CC8-AEAA-F0C7C963248F} {1C84C43C-69A8-493E-AC11-0DA9C22BFB46} = {00675670-C8E7-4428-A16F-9E6B933586A8} + {3BF538B4-0985-4918-90A7-8F15BA9E661C} = {00675670-C8E7-4428-A16F-9E6B933586A8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {36EE2FB8-4CD8-4A12-8FD5-9FDF3D0F6D40} diff --git a/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocument.fs b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocument.fs new file mode 100644 index 000000000000..7e63f401de20 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocument.fs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Formats.Cbor.Tests.DataModel + +open System + +// -- +// Models a CBOR document type using a discriminated union. +// Discriminated unions have structural equality for free +// and random instances can be generated using FsCheck. +// +// The type and serialization helpers are used by the +// property tests in the main test project. +// + +type CborDocument = + // Major type 0 + | UnsignedInteger of uint64 + // Major type 1 + | NegativeInteger of uint64 + // Major type 2 + | ByteString of byte[] + | ByteStringIndefiniteLength of byte[][] + // Major type 3 + | TextString of string + | TextStringIndefiniteLength of string[] + // Major type 4 + | Array of isDefiniteLength:bool * CborDocument[] + // Major type 5 + | Map of isDefiniteLength:bool * Map + // Major type 6 + | Tag of tag:uint64 * CborDocument + | SemanticValue of CborSemanticValue + // Major type 7 + | Double of double + | SimpleValue of value:byte + +// Defines a set of semantic values drawing either from the CBOR spec +// or invented here for the purposes of this test. +and CborSemanticValue = + | Null + | Bool of bool + | Int32 of int + | Int64 of int64 + | Half of Half + | Single of single + | DateTimeOffset of DateTimeOffset + | UnixTimeSeconds of seconds:int64 + | BigInt of bigint + | Decimal of decimal diff --git a/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocumentSerializer.fs b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocumentSerializer.fs new file mode 100644 index 000000000000..44728b426ed7 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborDocumentSerializer.fs @@ -0,0 +1,185 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +module rec System.Formats.Cbor.Tests.DataModel.CborDocumentSerializer + +open System +open System.Formats.Cbor +open System.Formats.Cbor.Tests.DataModel + +let createWriter (context : CborPropertyTestContext) = + new CborWriter( + conformanceMode = context.ConformanceMode, + convertIndefiniteLengthEncodings = context.ConvertIndefiniteLengthItems, + allowMultipleRootLevelValues = (context.RootDocuments.Length > 1)) + +let createReader (context : CborPropertyTestContext) (encoding : byte[]) = + new CborReader( + data = ReadOnlyMemory.op_Implicit encoding, + conformanceMode = context.ConformanceMode, + allowMultipleRootLevelValues = (context.RootDocuments.Length > 1)) + +let encode (context : CborPropertyTestContext) = + let writer = createWriter context + for doc in context.RootDocuments do + write writer doc + writer.Encode() + +let decode (context : CborPropertyTestContext) (data : byte[]) = + let reader = createReader context data + let values = new System.Collections.Generic.List<_>() + while reader.PeekState() <> CborReaderState.Finished do + values.Add(read reader) + values.ToArray() + +let rec write (writer : CborWriter) (doc : CborDocument) = + match doc with + | UnsignedInteger i -> writer.WriteUInt64 i + | NegativeInteger i -> writer.WriteCborNegativeIntegerRepresentation i + | ByteString bs -> writer.WriteByteString bs + | TextString ts -> writer.WriteTextString ts + | ByteStringIndefiniteLength bss -> + writer.WriteStartIndefiniteLengthByteString() + for bs in bss do + writer.WriteByteString bs + writer.WriteEndIndefiniteLengthByteString() + + | TextStringIndefiniteLength tss -> + writer.WriteStartIndefiniteLengthTextString() + for ts in tss do + writer.WriteTextString ts + writer.WriteEndIndefiniteLengthTextString() + + | Array (isDefiniteLength, elements) -> + writer.WriteStartArray (if isDefiniteLength then Nullable elements.Length else Nullable()) + for elem in elements do + write writer elem + writer.WriteEndArray() + + | Map (isDefiniteLength, pairs) -> + writer.WriteStartMap (if isDefiniteLength then Nullable pairs.Count else Nullable()) + for kv in pairs do + write writer kv.Key ; write writer kv.Value + writer.WriteEndMap() + + | Tag (tag, nested) -> + writer.WriteTag (LanguagePrimitives.EnumOfValue tag) + write writer nested + + | Double d -> writer.WriteDouble d + | SimpleValue v -> writer.WriteSimpleValue(LanguagePrimitives.EnumOfValue v) + + | SemanticValue value -> + writer.WriteTag CborTagExt.SemValueGuard + writeSemanticValue writer value + +let private writeSemanticValue (writer : CborWriter) (s : CborSemanticValue) = + match s with + | Null -> writer.WriteTag CborTagExt.Null; writer.WriteNull() + | Bool b -> writer.WriteTag CborTagExt.Bool; writer.WriteBoolean b + | Int32 i -> writer.WriteTag CborTagExt.Int32; writer.WriteInt32 i + | Int64 i -> writer.WriteTag CborTagExt.Int64; writer.WriteInt64 i + | Half f -> writer.WriteTag CborTagExt.Half; writer.WriteHalf f + | Single f -> writer.WriteTag CborTagExt.Single; writer.WriteSingle f + | DateTimeOffset d -> writer.WriteDateTimeOffset d + | UnixTimeSeconds s -> writer.WriteUnixTimeSeconds s + | BigInt i -> writer.WriteBigInteger i + | Decimal d -> writer.WriteDecimal d + +let rec read (reader : CborReader) : CborDocument = + match reader.PeekState() with + | CborReaderState.UnsignedInteger -> UnsignedInteger(reader.ReadUInt64()) + | CborReaderState.NegativeInteger -> NegativeInteger(reader.ReadCborNegativeIntegerRepresentation()) + | CborReaderState.ByteString -> ByteString(reader.ReadByteString()) + | CborReaderState.TextString -> TextString(reader.ReadTextString()) + | CborReaderState.StartArray -> + let length = reader.ReadStartArray() + if length.HasValue then + let results = Array.zeroCreate length.Value + for i = 0 to results.Length - 1 do + results.[i] <- read reader + + reader.ReadEndArray() + Array(true, results) + else + let results = new System.Collections.Generic.List<_>() + while reader.PeekState() <> CborReaderState.EndArray do + results.Add(read reader) + + reader.ReadEndArray() + Array(false, results.ToArray()) + + | CborReaderState.StartIndefiniteLengthByteString -> + reader.ReadStartIndefiniteLengthByteString() + let chunks = new System.Collections.Generic.List() + while reader.PeekState() <> CborReaderState.EndIndefiniteLengthByteString do + chunks.Add(reader.ReadByteString()) + reader.ReadEndIndefiniteLengthByteString() + ByteStringIndefiniteLength(chunks.ToArray()) + + | CborReaderState.StartIndefiniteLengthTextString -> + reader.ReadStartIndefiniteLengthTextString() + let chunks = new System.Collections.Generic.List() + while reader.PeekState() <> CborReaderState.EndIndefiniteLengthTextString do + chunks.Add(reader.ReadTextString()) + reader.ReadEndIndefiniteLengthTextString() + TextStringIndefiniteLength(chunks.ToArray()) + + | CborReaderState.StartMap -> + let length = reader.ReadStartMap() + if length.HasValue then + let results = Array.zeroCreate length.Value + for i = 0 to results.Length - 1 do + results.[i] <- (read reader, read reader) + reader.ReadEndMap() + Map(true, Map.ofArray results) + else + let results = new System.Collections.Generic.List<_>() + while reader.PeekState() <> CborReaderState.EndMap do + results.Add(read reader, read reader) + reader.ReadEndMap() + Map(false, Map.ofSeq results) + + | CborReaderState.Tag -> + let tag = reader.ReadTag() + if tag = CborTagExt.SemValueGuard then SemanticValue(readSemanticValue reader) + else Tag (LanguagePrimitives.EnumToValue tag, read reader) + + | CborReaderState.HalfPrecisionFloat + | CborReaderState.SinglePrecisionFloat + | CborReaderState.DoublePrecisionFloat -> Double (reader.ReadDouble()) + + | CborReaderState.Null + | CborReaderState.Boolean + | CborReaderState.SimpleValue -> + let value = reader.ReadSimpleValue() + SimpleValue(LanguagePrimitives.EnumToValue value) + + | state -> failwithf "Unrecognized reader state %O" state + +let private readSemanticValue (reader : CborReader) : CborSemanticValue = + match reader.PeekTag() with + | CborTagExt.Null -> let _ = reader.ReadTag() in reader.ReadNull(); Null + | CborTagExt.Bool -> let _ = reader.ReadTag() in Bool(reader.ReadBoolean()) + | CborTagExt.Int32 -> let _ = reader.ReadTag() in Int32(reader.ReadInt32()) + | CborTagExt.Int64 -> let _ = reader.ReadTag() in Int64(reader.ReadInt64()) + | CborTagExt.Half -> let _ = reader.ReadTag() in Half(reader.ReadHalf()) + | CborTagExt.Single -> let _ = reader.ReadTag() in Single(reader.ReadSingle()) + | CborTag.DateTimeString -> DateTimeOffset(reader.ReadDateTimeOffset()) + | CborTag.UnixTimeSeconds -> let dto = reader.ReadUnixTimeSeconds() in UnixTimeSeconds(dto.ToUnixTimeSeconds()) + | CborTag.UnsignedBigNum + | CborTag.NegativeBigNum -> BigInt(reader.ReadBigInteger()) + | CborTag.DecimalFraction -> Decimal(reader.ReadDecimal()) + | tag -> failwithf "Unrecognized tag %O" tag + +// defines a set of custom CBOR tags for semantic value encodings +module private CborTagExt = + + let [] SemValueGuard : CborTag = LanguagePrimitives.EnumOfValue 50015001uL + + let [] Null : CborTag = LanguagePrimitives.EnumOfValue 5001uL + let [] Bool : CborTag = LanguagePrimitives.EnumOfValue 5002uL + let [] Int32 : CborTag = LanguagePrimitives.EnumOfValue 5003uL + let [] Int64 : CborTag = LanguagePrimitives.EnumOfValue 5004uL + let [] Half : CborTag = LanguagePrimitives.EnumOfValue 5005uL + let [] Single : CborTag = LanguagePrimitives.EnumOfValue 5006uL diff --git a/src/libraries/System.Formats.Cbor/tests/CborDocument/CborPropertyTestContext.fs b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborPropertyTestContext.fs new file mode 100644 index 000000000000..921000f3ef51 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/CborDocument/CborPropertyTestContext.fs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Formats.Cbor.Tests.DataModel + +open System.Formats.Cbor +open System.Formats.Cbor.Tests.DataModel + +/// Randomly generated record containing parameters for a CBOR property-based test +[] +type CborPropertyTestContext = + { + RootDocuments : CborDocument[] + ConformanceMode : CborConformanceMode + ConvertIndefiniteLengthItems : bool + } + +module rec CborPropertyTestContextHelper = + + /// Identifies & transforms documents that might not be accepted under the supplied conformance mode + let create (mode : CborConformanceMode) (convertIndefiniteLengthItems : bool) (docs : CborDocument[]) = + { + RootDocuments = Array.map (normalize mode convertIndefiniteLengthItems) docs + ConvertIndefiniteLengthItems = convertIndefiniteLengthItems + ConformanceMode = mode + } + + /// Gets the expected value that we would expected to see after a full serialization/deserialization roundtrip + let getExpectedRoundtripValues (context : CborPropertyTestContext) = + Array.map (getExpectedRoundtripValue context.ConvertIndefiniteLengthItems) context.RootDocuments + + /// Identifies & transforms documents that might not be accepted under the supplied conformance mode + let private normalize (mode : CborConformanceMode) (convertIndefiniteLengthItems : bool) (doc : CborDocument) = + // normalization can lead to collisions in conformance modes that require field uniqueness + // mitigate by wrapping with a unique CBOR node + let mutable counter = 19000uL + let createUniqueWrapper (doc : CborDocument) = + counter <- counter + 1uL + Array(true, [|UnsignedInteger counter; doc|]) + + // not accepted by strict & canonical conformance modes + let trimNonCanonicalSimpleValue doc = + match doc with + | SimpleValue value when value >= 24uy && value < 32uy -> createUniqueWrapper(SimpleValue 0uy) + | _ -> doc + + // completely replace indefinite-length nodes in canonical conformance modes + let trimIndefiniteLengthNode doc = + match doc with + | ByteStringIndefiniteLength bss -> createUniqueWrapper(ByteString (Array.concat bss)) + | TextStringIndefiniteLength tss -> createUniqueWrapper(TextString (String.concat "" tss)) + | Array(false, elems) -> createUniqueWrapper(Array(true, elems)) + | Map(false, fields) -> createUniqueWrapper(Map(true, fields)) + | _ -> doc + + // CTAP2 does not allow major type 6, at all + let trimTagNode doc = + match doc with + | Tag (tag, doc) -> Array(true, [| UnsignedInteger (uint64 tag) ; doc|]) + | SemanticValue _ -> createUniqueWrapper(UnsignedInteger 0uL) + | _ -> doc + + match mode with + | CborConformanceMode.Lax -> doc + | CborConformanceMode.Strict + | CborConformanceMode.Canonical -> map (trimNonCanonicalSimpleValue << trimIndefiniteLengthNode) doc + | CborConformanceMode.Ctap2Canonical -> map (trimNonCanonicalSimpleValue << trimIndefiniteLengthNode << trimTagNode) doc + | _ -> doc + + /// Gets the expected value that we would expected to see after a full serialization/deserialization roundtrip + let private getExpectedRoundtripValue (convertIndefiniteLengthItems : bool) (doc : CborDocument) = + if not convertIndefiniteLengthItems then doc else + + let trimIndefiniteLengthNode doc = + match doc with + | ByteStringIndefiniteLength bss -> ByteString (Array.concat bss) + | TextStringIndefiniteLength tss -> TextString (String.concat "" tss) + | Array(false, elems) -> Array(true, elems) + | Map(false, fields) -> Map(true, fields) + | _ -> doc + + map trimIndefiniteLengthNode doc + + /// Depth-first application of update function on a CBOR doc tree + let rec private map (updater : CborDocument -> CborDocument) (doc : CborDocument) = + match updater doc with + | UnsignedInteger _ + | NegativeInteger _ + | ByteString _ + | ByteStringIndefiniteLength _ + | TextString _ + | TextStringIndefiniteLength _ + | SemanticValue _ + | SimpleValue _ + | Double _ as updated -> updated + + | Tag(tag, value) -> Tag(tag, map updater value) + | Array(isDefiniteLength, elems) -> Array(isDefiniteLength, Array.map (map updater) elems) + | Map(isDefiniteLength, fields) -> + let updatedFields = + fields + |> Map.toSeq + |> Seq.map (fun (k,v) -> map updater k, map updater v) + |> Map.ofSeq + + Map(isDefiniteLength, updatedFields) diff --git a/src/libraries/System.Formats.Cbor/tests/CborDocument/System.Formats.Cbor.Tests.DataModel.fsproj b/src/libraries/System.Formats.Cbor/tests/CborDocument/System.Formats.Cbor.Tests.DataModel.fsproj new file mode 100644 index 000000000000..94a84ccfa461 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/CborDocument/System.Formats.Cbor.Tests.DataModel.fsproj @@ -0,0 +1,16 @@ + + + + $(NetCoreAppCurrent) + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Formats.Cbor/tests/CborRoundtripTests.cs b/src/libraries/System.Formats.Cbor/tests/CborRoundtripTests.cs deleted file mode 100644 index 1e410d77a99a..000000000000 --- a/src/libraries/System.Formats.Cbor/tests/CborRoundtripTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Linq; -using Test.Cryptography; -using Xunit; -#if CBOR_PROPERTY_TESTS -using FsCheck.Xunit; -#endif - -namespace System.Formats.Cbor.Tests -{ - public partial class CborRoundtripTests - { - -#if CBOR_PROPERTY_TESTS - private const string ReplaySeed = "(0,0)"; // set a seed for deterministic runs - private const int MaxTests = 10_000; -#endif - -#if CBOR_PROPERTY_TESTS - [Property(Replay = ReplaySeed, MaxTest = MaxTests)] -#else - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(10)] - [InlineData(23)] - [InlineData(24)] - [InlineData(25)] - [InlineData(100)] - [InlineData(1000)] - [InlineData(1000000)] - [InlineData(1000000000000)] - [InlineData(-1)] - [InlineData(-10)] - [InlineData(-100)] - [InlineData(-1000)] - [InlineData(byte.MaxValue)] - [InlineData(byte.MaxValue + 1)] - [InlineData(-1 - byte.MaxValue)] - [InlineData(-2 - byte.MaxValue)] - [InlineData(ushort.MaxValue)] - [InlineData(ushort.MaxValue + 1)] - [InlineData(-1 - ushort.MaxValue)] - [InlineData(-2 - ushort.MaxValue)] - [InlineData(uint.MaxValue)] - [InlineData((long)uint.MaxValue + 1)] - [InlineData(-1 - uint.MaxValue)] - [InlineData(-2 - uint.MaxValue)] - [InlineData(long.MinValue)] - [InlineData(long.MaxValue)] -#endif - public static void Roundtrip_Int64(long input) - { - var writer = new CborWriter(); - writer.WriteInt64(input); - byte[] encoding = writer.Encode(); - - var reader = new CborReader(encoding); - long result = reader.ReadInt64(); - Assert.Equal(input, result); - } - -#if CBOR_PROPERTY_TESTS - [Property(Replay = ReplaySeed, MaxTest = MaxTests)] -#else - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(10)] - [InlineData(23)] - [InlineData(24)] - [InlineData(25)] - [InlineData(100)] - [InlineData(1000)] - [InlineData(1000000)] - [InlineData(1000000000000)] - [InlineData(byte.MaxValue)] - [InlineData(byte.MaxValue + 1)] - [InlineData(ushort.MaxValue)] - [InlineData(ushort.MaxValue + 1)] - [InlineData(uint.MaxValue)] - [InlineData((long)uint.MaxValue + 1)] - [InlineData(long.MaxValue)] - [InlineData(ulong.MaxValue)] -#endif - public static void Roundtrip_UInt64(ulong input) - { - var writer = new CborWriter(); - writer.WriteUInt64(input); - byte[] encoding = writer.Encode(); - - var reader = new CborReader(encoding); - ulong result = reader.ReadUInt64(); - Assert.Equal(input, result); - } - -#if CBOR_PROPERTY_TESTS - [Property(Replay = ReplaySeed, MaxTest = MaxTests)] - public static void Roundtrip_ByteString(byte[] input) - { -#else - [Theory] - [InlineData("")] - [InlineData("01020304")] - [InlineData("ffffffffffffffffffffffffffff")] - public static void Roundtrip_ByteString(string hexInput) - { - byte[] input = hexInput.HexToByteArray(); -#endif - var writer = new CborWriter(); - writer.WriteByteString(input); - byte[] encoding = writer.Encode(); - - var reader = new CborReader(encoding); - byte[] result = reader.ReadByteString(); - AssertHelper.HexEqual(input ?? Array.Empty(), result); - } - -#if CBOR_PROPERTY_TESTS - [Property(Replay = ReplaySeed, MaxTest = MaxTests)] -#else - [Theory] - [InlineData("")] - [InlineData("a")] - [InlineData("IETF")] - [InlineData("\"\\")] - [InlineData("\u00fc")] - [InlineData("\u6c34")] - [InlineData("\ud800\udd51")] -#endif - public static void Roundtrip_TextString(string input) - { - var writer = new CborWriter(); - writer.WriteTextString(input); - byte[] encoding = writer.Encode(); - - var reader = new CborReader(encoding); - string result = reader.ReadTextString(); - Assert.Equal(input ?? "", result); - } - -#if CBOR_PROPERTY_TESTS - [Property(Replay = ReplaySeed, MaxTest = MaxTests)] - public static void ByteString_Encoding_ShouldContainInputBytes(byte[] input) - { -#else - [Theory] - [InlineData("")] - [InlineData("01020304")] - [InlineData("ffffffffffffffffffffffffffff")] - public static void ByteString_Encoding_ShouldContainInputBytes(string hexInput) - { - byte[] input = hexInput.HexToByteArray(); -#endif - var writer = new CborWriter(); - writer.WriteByteString(input); - byte[] encoding = writer.Encode(); - - int length = input?.Length ?? 0; - int lengthEncodingLength = GetLengthEncodingLength(length); - - Assert.Equal(lengthEncodingLength + length, encoding.Length); - AssertHelper.HexEqual(input ?? Array.Empty(), encoding.Skip(lengthEncodingLength).ToArray()); - - static int GetLengthEncodingLength(int length) - { - return length switch - { - _ when (length < 24) => 1, - _ when (length < byte.MaxValue) => 1 + sizeof(byte), - _ when (length < ushort.MaxValue) => 1 + sizeof(ushort), - _ => 1 + sizeof(uint) - }; - } - } - } -} diff --git a/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs new file mode 100644 index 000000000000..6aca08ffc7bc --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs @@ -0,0 +1,219 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Formats.Cbor.Tests.DataModel; +using System.Linq; +using FsCheck; +using FsCheck.Xunit; +using Xunit; + +namespace System.Formats.Cbor.Tests +{ + public static class CborPropertyTests + { + private const string? ReplaySeed = "(42,42)"; // set a seed for deterministic runs, null for randomized runs + private const int MaxTests = 10_000; + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_Int64(CborConformanceMode mode, long input) + { + var writer = new CborWriter(mode); + writer.WriteInt64(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + long result = reader.ReadInt64(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_UInt64(CborConformanceMode mode, ulong input) + { + var writer = new CborWriter(mode); + writer.WriteUInt64(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + ulong result = reader.ReadUInt64(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_NegativeInteger(CborConformanceMode mode, ulong input) + { + var writer = new CborWriter(mode); + writer.WriteCborNegativeIntegerRepresentation(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + ulong result = reader.ReadCborNegativeIntegerRepresentation(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_ByteString(CborConformanceMode mode, byte[] input) + { + var writer = new CborWriter(mode); + writer.WriteByteString(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + byte[] result = reader.ReadByteString(); + AssertHelper.HexEqual(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_TextString(CborConformanceMode mode, string input) + { + var writer = new CborWriter(mode); + writer.WriteTextString(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + string result = reader.ReadTextString(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_IndefiniteByteString(CborConformanceMode mode, byte[][] chunks) + { + bool convertIndefiniteLengthEncodings = mode is CborConformanceMode.Canonical or CborConformanceMode.Ctap2Canonical; + var writer = new CborWriter(convertIndefiniteLengthEncodings: convertIndefiniteLengthEncodings); + + writer.WriteStartIndefiniteLengthByteString(); + foreach (byte[] chunk in chunks) + { + writer.WriteByteString(chunk); + } + writer.WriteEndIndefiniteLengthByteString(); + + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding); + byte[] expected = chunks.SelectMany(ch => ch).ToArray(); + byte[] result = reader.ReadByteString(); + AssertHelper.HexEqual(expected, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_IndefiniteTextString(CborConformanceMode mode, string[] chunks) + { + bool convertIndefiniteLengthEncodings = mode is CborConformanceMode.Canonical or CborConformanceMode.Ctap2Canonical; + var writer = new CborWriter(convertIndefiniteLengthEncodings: convertIndefiniteLengthEncodings); + + writer.WriteStartIndefiniteLengthTextString(); + foreach (string chunk in chunks) + { + writer.WriteTextString(chunk); + } + writer.WriteEndIndefiniteLengthTextString(); + + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding); + string expected = String.Concat(chunks); + string result = reader.ReadTextString(); + Assert.Equal(expected, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_Half(CborConformanceMode mode, Half input) + { + var writer = new CborWriter(mode); + writer.WriteHalf(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding, mode); + Half result = reader.ReadHalf(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_Double(CborConformanceMode mode, double input) + { + var writer = new CborWriter(); + writer.WriteDouble(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding); + double result = reader.ReadDouble(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void Roundtrip_Decimal(CborConformanceMode mode, decimal input) + { + var writer = new CborWriter(); + writer.WriteDecimal(input); + byte[] encoding = writer.Encode(); + + var reader = new CborReader(encoding); + decimal result = reader.ReadDecimal(); + Assert.Equal(input, result); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void ByteString_Encoding_ShouldContainInputBytes(CborConformanceMode mode, byte[] input) + { + var writer = new CborWriter(mode); + writer.WriteByteString(input); + byte[] encoding = writer.Encode(); + + int length = input?.Length ?? 0; + int lengthEncodingLength = GetLengthEncodingLength(length); + + Assert.Equal(lengthEncodingLength + length, encoding.Length); + AssertHelper.HexEqual(input ?? Array.Empty(), encoding.Skip(lengthEncodingLength).ToArray()); + + static int GetLengthEncodingLength(int length) + { + return length switch + { + _ when (length < 24) => 1, + _ when (length < byte.MaxValue) => 1 + sizeof(byte), + _ when (length < ushort.MaxValue) => 1 + sizeof(ushort), + _ => 1 + sizeof(uint) + }; + } + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void PropertyTest_Roundtrip(CborPropertyTestContext input) + { + byte[] encoding = CborDocumentSerializer.encode(input); + + CborDocument[] expectedResults = CborPropertyTestContextHelper.getExpectedRoundtripValues(input); + CborDocument[] roundtrippedDocuments = CborDocumentSerializer.decode(input, encoding); + Assert.Equal(expectedResults, roundtrippedDocuments); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void PropertyTest_SkipValue(CborPropertyTestContext input) + { + int length = input.RootDocuments.Length; + input.RootDocuments = new[] { CborDocument.NewArray(_isDefiniteLength: true, input.RootDocuments) }; + byte[] encoding = CborDocumentSerializer.encode(input); + + CborReader reader = CborDocumentSerializer.createReader(input, encoding); + reader.ReadStartArray(); + for (int i = 0; i < length; i++) + { + reader.SkipValue(); + } + reader.ReadEndArray(); + Assert.Equal(CborReaderState.Finished, reader.PeekState()); + } + + [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] + public static void PropertyTest_SkipToParent(CborPropertyTestContext input) + { + input.RootDocuments = new[] { CborDocument.NewArray(_isDefiniteLength: true, input.RootDocuments) }; + byte[] encoding = CborDocumentSerializer.encode(input); + + CborReader reader = CborDocumentSerializer.createReader(input, encoding); + reader.ReadStartArray(); + reader.SkipToParent(); + Assert.Equal(CborReaderState.Finished, reader.PeekState()); + } + } +} diff --git a/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborRandomGenerators.cs b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborRandomGenerators.cs new file mode 100644 index 000000000000..2cf77cf39d97 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborRandomGenerators.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Formats.Cbor.Tests.DataModel; +using System.Linq; +using FsCheck; + +namespace System.Formats.Cbor.Tests +{ + public static class CborRandomGenerators + { + public static Arbitrary PropertyTestInput() + { + Arbitrary> documentArb = Arb.Default.NonEmptyArray(); + Arbitrary convertArb = Arb.Default.Bool(); + Gen conformanceModes = Gen.Elements( + CborConformanceMode.Lax, + CborConformanceMode.Strict, + CborConformanceMode.Canonical, + CborConformanceMode.Ctap2Canonical); + + Gen inputGen = + from docs in documentArb.Generator + from convert in convertArb.Generator + from mode in conformanceModes + select CborPropertyTestContextHelper.create(mode, convert, docs.Get); + + IEnumerable Shrinker(CborPropertyTestContext input) + { + var nonEmptyArrayInput = NonEmptyArray.NewNonEmptyArray(input.RootDocuments); + + foreach (NonEmptyArray shrunkDoc in documentArb.Shrinker(nonEmptyArrayInput)) + { + yield return CborPropertyTestContextHelper.create(input.ConformanceMode, input.ConvertIndefiniteLengthItems, input.RootDocuments); + } + } + + return Arb.From(inputGen, Shrinker); + } + + // Do not generate null strings and byte arrays + public static Arbitrary String() => Arb.Default.String().Filter(s => s is not null); + public static Arbitrary ByteArray() => Arb.Default.Array().Filter(s => s is not null); + + // forgo NaN value generation in order to simplify equality checks + public static Arbitrary Single() => Arb.Default.Float32().Filter(s => !float.IsNaN(s)); + public static Arbitrary Double() => Arb.Default.Float().Filter(s => !double.IsNaN(s)); + + // FsCheck has no built-in System.Half generator, define one here + public static Arbitrary Half() + { + Arbitrary singleArb = Arb.Default.Float32(); + + Gen generator = + from f in singleArb.Generator + where !float.IsNaN(f) + select (Half)f; + + IEnumerable Shrinker(Half h) + { + foreach (float shrunk in singleArb.Shrinker((float)h)) + { + yield return (Half)shrunk; + } + } + + return Arb.From(generator, Shrinker); + } + } +} diff --git a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj index e72dd108eeeb..71735ea6c7b8 100644 --- a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj +++ b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj @@ -1,8 +1,16 @@ - + $(NetCoreAppCurrent) enable + false + + + $(DefineConstants),CBOR_PROPERTY_TESTS + + CS8002 + + CommonTest\System\Security\Cryptography\ByteUtils.cs @@ -26,10 +34,20 @@ - + + + + + + + + + + + From b5293d49e0643f8cf16854c28cca81e2f7987027 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 24 Jul 2020 10:42:10 -0400 Subject: [PATCH 030/755] [debugger] Removing unhandled_exception which was used for android. (#39377) Trying to remove the usage of unhandled_exception function to make debugger handle with an exception when running on android. We should ignore the try catch that is in an WRAPPER_SUBTYPE_ICALL_WRAPPER, then we can walk through all the callstack and find any try catch in managed code if it exists. Co-authored-by: thaystg --- src/mono/mono/mini/debugger-agent-stubs.c | 7 ------- src/mono/mono/mini/debugger-agent.c | 21 --------------------- src/mono/mono/mini/debugger-agent.h | 1 - src/mono/mono/mini/mini-exceptions.c | 11 +++++++++-- src/mono/mono/mini/mini-runtime.c | 5 ----- 5 files changed, 9 insertions(+), 36 deletions(-) diff --git a/src/mono/mono/mini/debugger-agent-stubs.c b/src/mono/mono/mini/debugger-agent-stubs.c index 98054f84ce02..539f454f044d 100644 --- a/src/mono/mono/mini/debugger-agent-stubs.c +++ b/src/mono/mono/mini/debugger-agent-stubs.c @@ -73,12 +73,6 @@ stub_debugger_agent_debug_log_is_enabled (void) return FALSE; } -static void -stub_debugger_agent_unhandled_exception (MonoException *exc) -{ - g_assert_not_reached (); -} - static void stub_debugger_agent_single_step_from_context (MonoContext *ctx) { @@ -110,7 +104,6 @@ mono_debugger_agent_stub_init (void) cbs.single_step_from_context = stub_debugger_agent_single_step_from_context; cbs.breakpoint_from_context = stub_debugger_agent_breakpoint_from_context; cbs.free_domain_info = stub_debugger_agent_free_domain_info; - cbs.unhandled_exception = stub_debugger_agent_unhandled_exception; cbs.handle_exception = stub_debugger_agent_handle_exception; cbs.begin_exception_filter = stub_debugger_agent_begin_exception_filter; cbs.end_exception_filter = stub_debugger_agent_end_exception_filter; diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index ace0affe8d73..eb26b88570e1 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -5286,26 +5286,6 @@ debugger_agent_debug_log_is_enabled (void) return agent_config.enabled; } -static void -debugger_agent_unhandled_exception (MonoException *exc) -{ - int suspend_policy; - GSList *events; - EventInfo ei; - - if (!inited) - return; - - memset (&ei, 0, sizeof (ei)); - ei.exc = (MonoObject*)exc; - - mono_loader_lock (); - events = create_event_list (EVENT_KIND_EXCEPTION, NULL, NULL, &ei, &suspend_policy); - mono_loader_unlock (); - - process_event (EVENT_KIND_EXCEPTION, &ei, 0, NULL, events, suspend_policy); -} - static void debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame) @@ -10420,7 +10400,6 @@ mono_debugger_agent_init (void) cbs.single_step_from_context = debugger_agent_single_step_from_context; cbs.breakpoint_from_context = debugger_agent_breakpoint_from_context; cbs.free_domain_info = debugger_agent_free_domain_info; - cbs.unhandled_exception = debugger_agent_unhandled_exception; cbs.handle_exception = debugger_agent_handle_exception; cbs.begin_exception_filter = debugger_agent_begin_exception_filter; cbs.end_exception_filter = debugger_agent_end_exception_filter; diff --git a/src/mono/mono/mini/debugger-agent.h b/src/mono/mono/mini/debugger-agent.h index 908189059611..750e5248f248 100644 --- a/src/mono/mono/mini/debugger-agent.h +++ b/src/mono/mono/mini/debugger-agent.h @@ -21,7 +21,6 @@ struct _MonoDebuggerCallbacks { void (*single_step_from_context) (MonoContext *ctx); void (*breakpoint_from_context) (MonoContext *ctx); void (*free_domain_info) (MonoDomain *domain); - void (*unhandled_exception) (MonoException *exc); void (*handle_exception) (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame); void (*begin_exception_filter) (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx); diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index e75267929377..2fc607c05ca6 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -2366,8 +2366,15 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED && ftnptr_eh_callback) { result = MONO_FIRST_PASS_CALLBACK_TO_NATIVE; } - - + +#if defined(HOST_ANDROID) || defined(TARGET_ANDROID) + //ignore the try catch in the .. icall_wrapper call + if (method->wrapper_type == WRAPPER_SUBTYPE_ICALL_WRAPPER) { + *ctx = new_ctx; + continue; + } +#endif + for (i = clause_index_start; i < ji->num_clauses; i++) { MonoJitExceptionInfo *ei = &ji->clauses [i]; gboolean filtered = FALSE; diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 53ef84742998..2176226b554b 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4640,11 +4640,6 @@ register_icalls (void) mono_add_internal_call_internal ("Mono.Runtime::mono_runtime_cleanup_handlers", mono_runtime_cleanup_handlers); -#if defined(HOST_ANDROID) || defined(TARGET_ANDROID) - mono_add_internal_call_internal ("System.Diagnostics.Debugger::Mono_UnhandledException_internal", - mini_get_dbg_callbacks ()->unhandled_exception); -#endif - /* * It's important that we pass `TRUE` as the last argument here, as * it causes the JIT to omit a wrapper for these icalls. If the JIT From 4f38b755fd8953830b58b4bc42943c57feeec419 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Fri, 24 Jul 2020 18:35:17 +0300 Subject: [PATCH 031/755] Convert math intrinsics to named intrinsics (#39730) * Convert math intrinsics to named intrinsics * Annotate Floor and Ceiling with [Intrinsic] --- .../src/System/Math.CoreCLR.cs | 2 + .../src/System/MathF.CoreCLR.cs | 2 + src/coreclr/src/inc/corinfo.h | 32 +- src/coreclr/src/jit/codegenarmarch.cpp | 12 +- src/coreclr/src/jit/codegenxarch.cpp | 26 +- src/coreclr/src/jit/compiler.h | 10 +- src/coreclr/src/jit/gentree.cpp | 301 ++++++++++-------- src/coreclr/src/jit/gentree.h | 39 ++- src/coreclr/src/jit/hwintrinsic.cpp | 4 +- src/coreclr/src/jit/importer.cpp | 281 +++++++++------- src/coreclr/src/jit/lowerxarch.cpp | 6 +- src/coreclr/src/jit/lsraarm.cpp | 6 +- src/coreclr/src/jit/lsraarm64.cpp | 10 +- src/coreclr/src/jit/lsraxarch.cpp | 16 +- src/coreclr/src/jit/morph.cpp | 4 +- src/coreclr/src/jit/namedintrinsiclist.h | 23 +- src/coreclr/src/jit/rationalize.cpp | 4 +- src/coreclr/src/jit/valuenum.cpp | 92 +++--- src/coreclr/src/jit/valuenum.h | 11 +- .../JitInterface/CorInfoImpl.Intrinsics.cs | 59 +--- .../tools/Common/JitInterface/CorInfoImpl.cs | 2 +- .../tools/Common/JitInterface/CorInfoTypes.cs | 22 -- .../src/tools/aot/jitinterface/jitwrapper.cpp | 10 +- src/coreclr/src/vm/ecalllist.h | 84 ++--- src/coreclr/src/zap/zapinfo.cpp | 19 +- 25 files changed, 555 insertions(+), 522 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs index 74aca4342ee3..beeb322b52c0 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs @@ -56,6 +56,7 @@ public static partial class Math [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Cbrt(double d); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Ceiling(double a); @@ -71,6 +72,7 @@ public static partial class Math [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Exp(double d); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Floor(double d); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs index 371780f6abe0..f3dd3289c1c2 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs @@ -45,6 +45,7 @@ public static partial class MathF [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Cbrt(float x); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Ceiling(float x); @@ -60,6 +61,7 @@ public static partial class MathF [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Exp(float x); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Floor(float x); diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index 7341e43358bb..7870683ecf43 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -208,11 +208,11 @@ TODO: Talk about initializing strutures before use // ////////////////////////////////////////////////////////////////////////////////////////////////////////// -constexpr GUID JITEEVersionIdentifier = { /* 164b4e4f-21f6-4d05-b560-3728395404f2 */ - 0x164b4e4f, - 0x21f6, - 0x4d05, - { 0xb5, 0x60, 0x37, 0x28, 0x39, 0x54, 0x04, 0xf2 } +constexpr GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */ + 0xa5eec3a4, + 0x4176, + 0x43a7, + {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -891,28 +891,6 @@ enum CorInfoException enum CorInfoIntrinsics { - CORINFO_INTRINSIC_Sin, - CORINFO_INTRINSIC_Cos, - CORINFO_INTRINSIC_Cbrt, - CORINFO_INTRINSIC_Sqrt, - CORINFO_INTRINSIC_Abs, - CORINFO_INTRINSIC_Round, - CORINFO_INTRINSIC_Cosh, - CORINFO_INTRINSIC_Sinh, - CORINFO_INTRINSIC_Tan, - CORINFO_INTRINSIC_Tanh, - CORINFO_INTRINSIC_Asin, - CORINFO_INTRINSIC_Asinh, - CORINFO_INTRINSIC_Acos, - CORINFO_INTRINSIC_Acosh, - CORINFO_INTRINSIC_Atan, - CORINFO_INTRINSIC_Atan2, - CORINFO_INTRINSIC_Atanh, - CORINFO_INTRINSIC_Log10, - CORINFO_INTRINSIC_Pow, - CORINFO_INTRINSIC_Exp, - CORINFO_INTRINSIC_Ceiling, - CORINFO_INTRINSIC_Floor, CORINFO_INTRINSIC_GetChar, // fetch character out of string CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index a2d881588ab5..45319861754c 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -616,31 +616,31 @@ void CodeGen::genIntrinsic(GenTree* treeNode) // Right now only Abs/Ceiling/Floor/Round/Sqrt are treated as math intrinsics. // - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_ABS, emitActualTypeSize(treeNode), treeNode, srcNode); break; #ifdef TARGET_ARM64 - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintp, emitActualTypeSize(treeNode), treeNode, srcNode); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintn, emitActualTypeSize(treeNode), treeNode, srcNode); break; #endif // TARGET_ARM64 - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_SQRT, emitActualTypeSize(treeNode), treeNode, srcNode); break; diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index e65dda6b46c7..ed1a67b7ca5b 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -6781,7 +6781,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) break; case GT_INTRINSIC: - assert(treeNode->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs); + assert(treeNode->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs); // Abs(x) = set sign-bit to zero // Abs(f) = f & 0x7fffffff @@ -6859,7 +6859,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) // ii) treeNode oper is a GT_INTRINSIC // iii) treeNode type is a floating point type // iv) treeNode is not used from memory -// v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor +// v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor // vi) caller of this routine needs to call genProduceReg() void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) { @@ -6887,18 +6887,18 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) unsigned ival = 0; - // v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + // v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: ival = 4; break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: ival = 10; break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: ival = 9; break; @@ -7020,9 +7020,9 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) void CodeGen::genIntrinsic(GenTree* treeNode) { // Right now only Sqrt/Abs are treated as math intrinsics. - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: { // Both operand and its result must be of the same floating point type. GenTree* srcNode = treeNode->AsOp()->gtOp1; @@ -7034,13 +7034,13 @@ void CodeGen::genIntrinsic(GenTree* treeNode) break; } - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: genSSE2BitwiseOp(treeNode); break; - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: genSSE41RoundOp(treeNode->AsOp()); break; diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 37897a64fda2..7c3a3473508a 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3741,7 +3741,7 @@ class Compiler GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, - CorInfoIntrinsics intrinsicID, + NamedIntrinsic intrinsicName, bool tailCall); NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method); GenTree* impUnsupportedNamedIntrinsic(unsigned helper, @@ -3937,9 +3937,9 @@ class Compiler bool VarTypeIsMultiByteAndCanEnreg( var_types type, CORINFO_CLASS_HANDLE typeClass, unsigned* typeSize, bool forReturn, bool isVarArg); - bool IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId); - bool IsTargetIntrinsic(CorInfoIntrinsics intrinsicId); - bool IsMathIntrinsic(CorInfoIntrinsics intrinsicId); + bool IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName); + bool IsTargetIntrinsic(NamedIntrinsic intrinsicName); + bool IsMathIntrinsic(NamedIntrinsic intrinsicName); bool IsMathIntrinsic(GenTree* tree); private: @@ -9079,7 +9079,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool compIsVarArgs : 1; // Does the method have varargs parameters? bool compInitMem : 1; // Is the CORINFO_OPT_INIT_LOCALS bit set in the method info options? bool compProfilerCallback : 1; // JIT inserted a profiler Enter callback - bool compPublishStubParam : 1; // EAX captured in prolog will be available through an instrinsic + bool compPublishStubParam : 1; // EAX captured in prolog will be available through an intrinsic bool compRetBuffDefStack : 1; // The ret buff argument definitely points into the stack. bool compHasNextCallRetAddr : 1; // The NextCallReturnAddress intrinsic is used. diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index e39c9c76f90b..ca5c6d4df7fb 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -3624,6 +3624,8 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) level = gtSetEvalOrder(op1); + GenTreeIntrinsic* intrinsic; + /* Special handling for some operators */ switch (oper) @@ -3685,54 +3687,82 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) break; case GT_INTRINSIC: - // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs. - // TODO: tune these costs target specific as some of these are - // target intrinsics and would cost less to generate code. - switch (tree->AsIntrinsic()->gtIntrinsicId) + intrinsic = tree->AsIntrinsic(); + if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal) { - default: - assert(!"missing case for gtIntrinsicId"); - costEx = 12; - costSz = 12; - break; + // named intrinsic + assert(intrinsic->gtIntrinsicName != NI_Illegal); - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: - case CORINFO_INTRINSIC_Object_GetType: - // Giving intrinsics a large fixed execution cost is because we'd like to CSE - // them, even if they are implemented by calls. This is different from modeling - // user calls since we never CSE user calls. - costEx = 36; - costSz = 4; - break; + // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs. + // TODO: tune these costs target specific as some of these are + // target intrinsics and would cost less to generate code. + switch (intrinsic->gtIntrinsicName) + { + default: + assert(!"missing case for gtIntrinsicName"); + costEx = 12; + costSz = 12; + break; - case CORINFO_INTRINSIC_Abs: - costEx = 5; - costSz = 15; - break; + case NI_System_Math_Sin: + case NI_System_Math_Cos: + case NI_System_Math_Sqrt: + case NI_System_Math_Cbrt: + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atanh: + case NI_System_Math_Atan2: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: + // Giving intrinsics a large fixed execution cost is because we'd like to CSE + // them, even if they are implemented by calls. This is different from modeling + // user calls since we never CSE user calls. + costEx = 36; + costSz = 4; + break; - case CORINFO_INTRINSIC_Round: - costEx = 3; - costSz = 4; - break; + case NI_System_Math_Abs: + costEx = 5; + costSz = 15; + break; + + case NI_System_Math_Round: + costEx = 3; + costSz = 4; + break; + } + } + else + { + // old style intrinsic + assert(intrinsic->gtIntrinsicName == NI_Illegal); + + switch (intrinsic->gtIntrinsicId) + { + default: + assert(!"missing case for gtIntrinsicId"); + costEx = 12; + costSz = 12; + break; + + case CORINFO_INTRINSIC_Object_GetType: + // Giving intrinsics a large fixed execution cost is because we'd like to CSE + // them, even if they are implemented by calls. This is different from modeling + // user calls since we never CSE user calls. + costEx = 36; + costSz = 4; + break; + } } level++; break; @@ -4215,10 +4245,10 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) case GT_INTRINSIC: - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Pow: + case NI_System_Math_Atan2: + case NI_System_Math_Pow: // These math intrinsics are actually implemented by user calls. // Increase the Sethi 'complexity' by two to reflect the argument // register requirement. @@ -4275,7 +4305,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) // so if possible it was set above. tryToSwap = false; } - else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicId)) + else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicName)) { // We do not swap operand execution order for intrinsics that are implemented by user calls // because of trickiness around ensuring the execution order does not change during rationalization. @@ -5477,7 +5507,7 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp) return true; case GT_INTRINSIC: - return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicId); + return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicName); #if FEATURE_FIXED_OUT_ARGS && !defined(TARGET_64BIT) case GT_LSH: @@ -7699,7 +7729,8 @@ GenTree* Compiler::gtCloneExpr( case GT_INTRINSIC: copy = new (this, GT_INTRINSIC) GenTreeIntrinsic(tree->TypeGet(), tree->AsOp()->gtOp1, tree->AsOp()->gtOp2, - tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtMethodHandle); + tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtIntrinsicName, + tree->AsIntrinsic()->gtMethodHandle); #ifdef FEATURE_READYTORUN_COMPILER copy->AsIntrinsic()->gtEntryPoint = tree->AsIntrinsic()->gtEntryPoint; #endif @@ -11460,80 +11491,98 @@ void Compiler::gtDispTree(GenTree* tree, if (tree->gtOper == GT_INTRINSIC) { - switch (tree->AsIntrinsic()->gtIntrinsicId) + GenTreeIntrinsic* intrinsic = tree->AsIntrinsic(); + + if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal) { - case CORINFO_INTRINSIC_Sin: - printf(" sin"); - break; - case CORINFO_INTRINSIC_Cos: - printf(" cos"); - break; - case CORINFO_INTRINSIC_Cbrt: - printf(" cbrt"); - break; - case CORINFO_INTRINSIC_Sqrt: - printf(" sqrt"); - break; - case CORINFO_INTRINSIC_Abs: - printf(" abs"); - break; - case CORINFO_INTRINSIC_Round: - printf(" round"); - break; - case CORINFO_INTRINSIC_Cosh: - printf(" cosh"); - break; - case CORINFO_INTRINSIC_Sinh: - printf(" sinh"); - break; - case CORINFO_INTRINSIC_Tan: - printf(" tan"); - break; - case CORINFO_INTRINSIC_Tanh: - printf(" tanh"); - break; - case CORINFO_INTRINSIC_Asin: - printf(" asin"); - break; - case CORINFO_INTRINSIC_Asinh: - printf(" asinh"); - break; - case CORINFO_INTRINSIC_Acos: - printf(" acos"); - break; - case CORINFO_INTRINSIC_Acosh: - printf(" acosh"); - break; - case CORINFO_INTRINSIC_Atan: - printf(" atan"); - break; - case CORINFO_INTRINSIC_Atan2: - printf(" atan2"); - break; - case CORINFO_INTRINSIC_Atanh: - printf(" atanh"); - break; - case CORINFO_INTRINSIC_Log10: - printf(" log10"); - break; - case CORINFO_INTRINSIC_Pow: - printf(" pow"); - break; - case CORINFO_INTRINSIC_Exp: - printf(" exp"); - break; - case CORINFO_INTRINSIC_Ceiling: - printf(" ceiling"); - break; - case CORINFO_INTRINSIC_Floor: - printf(" floor"); - break; - case CORINFO_INTRINSIC_Object_GetType: - printf(" objGetType"); - break; + // named intrinsic + assert(intrinsic->gtIntrinsicName != NI_Illegal); + switch (intrinsic->gtIntrinsicName) + { + case NI_System_Math_Sin: + printf(" sin"); + break; + case NI_System_Math_Cos: + printf(" cos"); + break; + case NI_System_Math_Cbrt: + printf(" cbrt"); + break; + case NI_System_Math_Sqrt: + printf(" sqrt"); + break; + case NI_System_Math_Abs: + printf(" abs"); + break; + case NI_System_Math_Round: + printf(" round"); + break; + case NI_System_Math_Cosh: + printf(" cosh"); + break; + case NI_System_Math_Sinh: + printf(" sinh"); + break; + case NI_System_Math_Tan: + printf(" tan"); + break; + case NI_System_Math_Tanh: + printf(" tanh"); + break; + case NI_System_Math_Asin: + printf(" asin"); + break; + case NI_System_Math_Asinh: + printf(" asinh"); + break; + case NI_System_Math_Acos: + printf(" acos"); + break; + case NI_System_Math_Acosh: + printf(" acosh"); + break; + case NI_System_Math_Atan: + printf(" atan"); + break; + case NI_System_Math_Atan2: + printf(" atan2"); + break; + case NI_System_Math_Atanh: + printf(" atanh"); + break; + case NI_System_Math_Log10: + printf(" log10"); + break; + case NI_System_Math_Pow: + printf(" pow"); + break; + case NI_System_Math_Exp: + printf(" exp"); + break; + case NI_System_Math_Ceiling: + printf(" ceiling"); + break; + case NI_System_Math_Floor: + printf(" floor"); + break; - default: - unreached(); + default: + unreached(); + } + } + else + { + // old style intrinsic + assert(intrinsic->gtIntrinsicName == NI_Illegal); + switch (intrinsic->gtIntrinsicId) + { + case CORINFO_INTRINSIC_Object_GetType: + printf(" objGetType"); + break; + + default: + unreached(); + } } } @@ -18758,7 +18807,7 @@ bool GenTree::isCommutativeSIMDIntrinsic() } } -// Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeSIMD::OperIsMemoryLoad() const { if (gtSIMDIntrinsicID == SIMDIntrinsicInitArray) @@ -18980,7 +19029,7 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode( GenTreeHWIntrinsic(type, gtNewArgList(op1, op2, op3), hwIntrinsicID, TYP_UNKNOWN, 0); } -// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryLoad() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) @@ -19023,7 +19072,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() const return false; } -// Returns true for the HW Instrinsic instructions that have MemoryStore semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryStore semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryStore() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) @@ -19059,7 +19108,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore() const return false; } -// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index b6a95a1d3c7a..7e2536573072 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -4729,6 +4729,7 @@ struct GenTreeQmark : public GenTreeOp struct GenTreeIntrinsic : public GenTreeOp { CorInfoIntrinsics gtIntrinsicId; + NamedIntrinsic gtIntrinsicName; CORINFO_METHOD_HANDLE gtMethodHandle; // Method handle of the method which is treated as an intrinsic. #ifdef FEATURE_READYTORUN_COMPILER @@ -4736,15 +4737,31 @@ struct GenTreeIntrinsic : public GenTreeOp CORINFO_CONST_LOOKUP gtEntryPoint; #endif - GenTreeIntrinsic(var_types type, GenTree* op1, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) - : GenTreeOp(GT_INTRINSIC, type, op1, nullptr), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle) + GenTreeIntrinsic(var_types type, + GenTree* op1, + CorInfoIntrinsics intrinsicId, + NamedIntrinsic intrinsicName, + CORINFO_METHOD_HANDLE methodHandle) + : GenTreeOp(GT_INTRINSIC, type, op1, nullptr) + , gtIntrinsicId(intrinsicId) + , gtIntrinsicName(intrinsicName) + , gtMethodHandle(methodHandle) { + assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal); } - GenTreeIntrinsic( - var_types type, GenTree* op1, GenTree* op2, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) - : GenTreeOp(GT_INTRINSIC, type, op1, op2), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle) + GenTreeIntrinsic(var_types type, + GenTree* op1, + GenTree* op2, + CorInfoIntrinsics intrinsicId, + NamedIntrinsic intrinsicName, + CORINFO_METHOD_HANDLE methodHandle) + : GenTreeOp(GT_INTRINSIC, type, op1, op2) + , gtIntrinsicId(intrinsicId) + , gtIntrinsicName(intrinsicName) + , gtMethodHandle(methodHandle) { + assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal); } #if DEBUGGABLE_GENTREE @@ -4848,7 +4865,7 @@ struct GenTreeSIMD : public GenTreeJitIntrinsic gtSIMDIntrinsicID = simdIntrinsicID; } - bool OperIsMemoryLoad() const; // Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics, + bool OperIsMemoryLoad() const; // Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, // false otherwise #if DEBUGGABLE_GENTREE @@ -4889,15 +4906,15 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic } } - // Note that HW Instrinsic instructions are a sub class of GenTreeOp which only supports two operands - // However there are HW Instrinsic instructions that have 3 or even 4 operands and this is + // Note that HW Intrinsic instructions are a sub class of GenTreeOp which only supports two operands + // However there are HW Intrinsic instructions that have 3 or even 4 operands and this is // supported using a single op1 and using an ArgList for it: gtNewArgList(op1, op2, op3) - bool OperIsMemoryLoad() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, + bool OperIsMemoryLoad() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, // false otherwise - bool OperIsMemoryStore() const; // Returns true for the HW Instrinsic instructions that have MemoryStore semantics, + bool OperIsMemoryStore() const; // Returns true for the HW Intrinsic instructions that have MemoryStore semantics, // false otherwise - bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad or + bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad or // MemoryStore semantics, false otherwise #if DEBUGGABLE_GENTREE diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 5e7eda61c30d..5723ac8f322b 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -202,7 +202,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va { int numArgs = HWIntrinsicInfo::lookupNumArgs(hwIntrinsicID); - // HW Instrinsic's with -1 for numArgs have a varying number of args, so we currently + // HW Intrinsic's with -1 for numArgs have a varying number of args, so we currently // give themm a unique value number them, and don't add an extra argument. // if (numArgs == -1) @@ -210,7 +210,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va return false; } - // We iterate over all of the different baseType's for this instrinsic in the HWIntrinsicInfo table + // We iterate over all of the different baseType's for this intrinsic in the HWIntrinsicInfo table // We set diffInsCount to the number of instructions that can execute differently. // unsigned diffInsCount = 0; diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index e1443b849ad3..6280e1be9d77 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -3623,31 +3623,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTree* op1; GenTree* op2; - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: - retNode = impMathIntrinsic(method, sig, callType, intrinsicID, tailCall); - break; - #if defined(TARGET_XARCH) || defined(TARGET_ARM64) // TODO-ARM-CQ: reenable treating Interlocked operation as intrinsic @@ -3921,7 +3896,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { JITDUMP("Expanding as special intrinsic\n"); impPopStack(); - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, ni, method); // Set the CALL flag to indicate that the operator is implemented by a call. // Set also the EXCEPTION flag because the native implementation of @@ -4218,7 +4193,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, #ifdef FEATURE_HW_INTRINSICS case NI_System_Math_FusedMultiplyAdd: - case NI_System_MathF_FusedMultiplyAdd: { #ifdef TARGET_XARCH if (compExactlyDependsOn(InstructionSet_FMA) && supportSIMDTypes()) @@ -4248,15 +4222,30 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, } #endif // FEATURE_HW_INTRINSICS + case NI_System_Math_Sin: + case NI_System_Math_Cbrt: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Cos: case NI_System_Math_Round: - case NI_System_MathF_Round: - { - // Math.Round and MathF.Round used to be a traditional JIT intrinsic. In order - // to simplify the transition, we will just treat it as if it was still the - // old intrinsic, CORINFO_INTRINSIC_Round. This should end up flowing properly - // everywhere else. - - retNode = impMathIntrinsic(method, sig, callType, CORINFO_INTRINSIC_Round, tailCall); + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atan2: + case NI_System_Math_Atanh: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: + { + retNode = impMathIntrinsic(method, sig, callType, ni, tailCall); break; } @@ -4345,14 +4334,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, - CorInfoIntrinsics intrinsicID, + NamedIntrinsic intrinsicName, bool tailCall) { GenTree* op1; GenTree* op2; assert(callType != TYP_STRUCT); - assert(IsMathIntrinsic(intrinsicID)); + assert(IsMathIntrinsic(intrinsicName)); op1 = nullptr; @@ -4363,12 +4352,12 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, // a) For back compatibility reasons on desktop .NET Framework 4.6 / 4.6.1 // b) It will be non-trivial task or too late to re-materialize a surviving // tail prefixed GT_INTRINSIC as tail call in rationalizer. - if (!IsIntrinsicImplementedByUserCall(intrinsicID) || !tailCall) + if (!IsIntrinsicImplementedByUserCall(intrinsicName) || !tailCall) #else // On x86 RyuJIT, importing intrinsics that are implemented as user calls can cause incorrect calculation // of the depth of the stack if these intrinsics are used as arguments to another call. This causes bad // code generation for certain EH constructs. - if (!IsIntrinsicImplementedByUserCall(intrinsicID)) + if (!IsIntrinsicImplementedByUserCall(intrinsicName)) #endif { switch (sig->numArgs) @@ -4383,7 +4372,8 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, op1 = gtNewCastNode(callType, op1, false, callType); } - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) + GenTreeIntrinsic(genActualType(callType), op1, CORINFO_INTRINSIC_Illegal, intrinsicName, method); break; case 2: @@ -4402,14 +4392,15 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, op1 = gtNewCastNode(callType, op1, false, callType); } - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2, + CORINFO_INTRINSIC_Illegal, intrinsicName, method); break; default: - NO_WAY("Unsupported number of args for Math Instrinsic"); + NO_WAY("Unsupported number of args for Math Intrinsic"); } - if (IsIntrinsicImplementedByUserCall(intrinsicID)) + if (IsIntrinsicImplementedByUserCall(intrinsicName)) { op1->gtFlags |= GTF_CALL; } @@ -4474,31 +4465,99 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Enum_HasFlag; } - else if (strncmp(className, "Math", 4) == 0) + else if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0) { - className += 4; - - if (className[0] == '\0') + if (strcmp(methodName, "FusedMultiplyAdd") == 0) { - if (strcmp(methodName, "FusedMultiplyAdd") == 0) - { - result = NI_System_Math_FusedMultiplyAdd; - } - else if (strcmp(methodName, "Round") == 0) - { - result = NI_System_Math_Round; - } + result = NI_System_Math_FusedMultiplyAdd; } - else if (strcmp(className, "F") == 0) + else if (strcmp(methodName, "Round") == 0) { - if (strcmp(methodName, "FusedMultiplyAdd") == 0) - { - result = NI_System_MathF_FusedMultiplyAdd; - } - else if (strcmp(methodName, "Round") == 0) - { - result = NI_System_MathF_Round; - } + result = NI_System_Math_Round; + } + else if (strcmp(methodName, "Sin") == 0) + { + result = NI_System_Math_Sin; + } + else if (strcmp(methodName, "Cos") == 0) + { + result = NI_System_Math_Cos; + } + else if (strcmp(methodName, "Cbrt") == 0) + { + result = NI_System_Math_Cbrt; + } + else if (strcmp(methodName, "Sqrt") == 0) + { + result = NI_System_Math_Sqrt; + } + else if (strcmp(methodName, "Abs") == 0) + { + result = NI_System_Math_Abs; + } + else if (strcmp(methodName, "Cosh") == 0) + { + result = NI_System_Math_Cosh; + } + else if (strcmp(methodName, "Sinh") == 0) + { + result = NI_System_Math_Sinh; + } + else if (strcmp(methodName, "Tan") == 0) + { + result = NI_System_Math_Tan; + } + else if (strcmp(methodName, "Tanh") == 0) + { + result = NI_System_Math_Tanh; + } + else if (strcmp(methodName, "Asin") == 0) + { + result = NI_System_Math_Asin; + } + else if (strcmp(methodName, "Asinh") == 0) + { + result = NI_System_Math_Asinh; + } + else if (strcmp(methodName, "Acos") == 0) + { + result = NI_System_Math_Acos; + } + else if (strcmp(methodName, "Acosh") == 0) + { + result = NI_System_Math_Acosh; + } + else if (strcmp(methodName, "Atan") == 0) + { + result = NI_System_Math_Atan; + } + else if (strcmp(methodName, "Atan2") == 0) + { + result = NI_System_Math_Atan2; + } + else if (strcmp(methodName, "Atanh") == 0) + { + result = NI_System_Math_Atanh; + } + else if (strcmp(methodName, "Log10") == 0) + { + result = NI_System_Math_Log10; + } + else if (strcmp(methodName, "Pow") == 0) + { + result = NI_System_Math_Pow; + } + else if (strcmp(methodName, "Exp") == 0) + { + result = NI_System_Math_Exp; + } + else if (strcmp(methodName, "Ceiling") == 0) + { + result = NI_System_Math_Ceiling; + } + else if (strcmp(methodName, "Floor") == 0) + { + result = NI_System_Math_Floor; } } else if (strcmp(className, "GC") == 0) @@ -7944,9 +8003,9 @@ var_types Compiler::impImportCall(OPCODE opcode, // This is for a non-virtual, non-interface etc. call call = gtNewCallNode(CT_USER_FUNC, callInfo->hMethod, callRetTyp, nullptr, ilOffset); - // We remove the nullcheck for the GetType call instrinsic. + // We remove the nullcheck for the GetType call intrinsic. // TODO-CQ: JIT64 does not introduce the null check for many more helper calls - // and instrinsics. + // and intrinsics. if (callInfo->nullInstanceCheck && !((mflags & CORINFO_FLG_INTRINSIC) != 0 && (intrinsicID == CORINFO_INTRINSIC_Object_GetType))) { @@ -20072,10 +20131,10 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, // Returns true if the given intrinsic will be implemented by target-specific // instructions -bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) +bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName) { #if defined(TARGET_XARCH) - switch (intrinsicId) + switch (intrinsicName) { // AMD64/x86 has SSE2 instructions to directly compute sqrt/abs and SSE4.1 // instructions to directly compute round/ceiling/floor. @@ -20086,37 +20145,37 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) // a CQ problem, it may be necessary to change the implementation of // the helper calls to decrease call overhead or switch back to the // x87 instructions. This is tracked by #7097. - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: return true; - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: return compOpportunisticallyDependsOn(InstructionSet_SSE41); default: return false; } #elif defined(TARGET_ARM64) - switch (intrinsicId) + switch (intrinsicName) { - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Floor: - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Round: + case NI_System_Math_Floor: + case NI_System_Math_Ceiling: return true; default: return false; } #elif defined(TARGET_ARM) - switch (intrinsicId) + switch (intrinsicName) { - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Round: return true; default: @@ -20134,41 +20193,41 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) // Returns true if the given intrinsic will be implemented by calling System.Math // methods. -bool Compiler::IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId) +bool Compiler::IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName) { // Currently, if a math intrinsic is not implemented by target-specific // instructions, it will be implemented by a System.Math call. In the // future, if we turn to implementing some of them with helper calls, // this predicate needs to be revisited. - return !IsTargetIntrinsic(intrinsicId); + return !IsTargetIntrinsic(intrinsicName); } -bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId) +bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName) { - switch (intrinsicId) - { - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + switch (intrinsicName) + { + case NI_System_Math_Sin: + case NI_System_Math_Cbrt: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Cos: + case NI_System_Math_Round: + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atan2: + case NI_System_Math_Atanh: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: return true; default: return false; @@ -20177,7 +20236,7 @@ bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId) bool Compiler::IsMathIntrinsic(GenTree* tree) { - return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicId); + return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicName); } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 331c674eab9e..052abaf890df 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -4616,10 +4616,10 @@ void Lowering::ContainCheckIntrinsic(GenTreeOp* node) { assert(node->OperIs(GT_INTRINSIC)); - CorInfoIntrinsics intrinsicId = node->AsIntrinsic()->gtIntrinsicId; + NamedIntrinsic intrinsicName = node->AsIntrinsic()->gtIntrinsicName; - if (intrinsicId == CORINFO_INTRINSIC_Sqrt || intrinsicId == CORINFO_INTRINSIC_Round || - intrinsicId == CORINFO_INTRINSIC_Ceiling || intrinsicId == CORINFO_INTRINSIC_Floor) + if (intrinsicName == NI_System_Math_Sqrt || intrinsicName == NI_System_Math_Round || + intrinsicName == NI_System_Math_Ceiling || intrinsicName == NI_System_Math_Floor) { GenTree* op1 = node->gtGetOp1(); if (IsContainableMemoryOp(op1) || op1->IsCnsNonZeroFltOrDbl()) diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index f3b480fddd6d..b9b4d0f6d3e6 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -290,10 +290,10 @@ int LinearScan::BuildNode(GenTree* tree) BuildUse(op1); srcCount = 1; - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Sqrt: assert(dstCount == 1); BuildDef(tree); break; diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index 514ed90feef4..bdb626d7d98d 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -319,11 +319,11 @@ int LinearScan::BuildNode(GenTree* tree) case GT_INTRINSIC: { - noway_assert((tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Ceiling) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Floor) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Sqrt)); + noway_assert((tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Ceiling) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Floor) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Sqrt)); // Both operand and its result must be of the same floating point type. GenTree* op1 = tree->gtGetOp1(); diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 8895dc95ecec..e0be880d16d7 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -1779,9 +1779,9 @@ int LinearScan::BuildIntrinsic(GenTree* tree) assert(op1->TypeGet() == tree->TypeGet()); RefPosition* internalFloatDef = nullptr; - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: // Abs(float x) = x & 0x7fffffff // Abs(double x) = x & 0x7ffffff ffffffff @@ -1798,16 +1798,16 @@ int LinearScan::BuildIntrinsic(GenTree* tree) break; #ifdef TARGET_X86 - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Cos: + case NI_System_Math_Sin: NYI_X86("Math intrinsics Cos and Sin"); break; #endif // TARGET_X86 - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Sqrt: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: break; default: diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 2979a784570f..28b15c6f6cbe 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -5890,7 +5890,7 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) } #ifdef FEATURE_SIMD - // if this field belongs to simd struct, translate it to simd instrinsic. + // if this field belongs to simd struct, translate it to simd intrinsic. if (mac == nullptr) { GenTree* newTree = fgMorphFieldToSIMDIntrinsicGet(tree); @@ -12166,7 +12166,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) #ifdef TARGET_ARM case GT_INTRINSIC: - if (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round) + if (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) { switch (tree->TypeGet()) { diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h index 63d79fbeff19..bc84f851deac 100644 --- a/src/coreclr/src/jit/namedintrinsiclist.h +++ b/src/coreclr/src/jit/namedintrinsiclist.h @@ -12,9 +12,28 @@ enum NamedIntrinsic : unsigned short NI_System_Enum_HasFlag, NI_System_Math_FusedMultiplyAdd, + NI_System_Math_Sin, + NI_System_Math_Cos, + NI_System_Math_Cbrt, + NI_System_Math_Sqrt, + NI_System_Math_Abs, NI_System_Math_Round, - NI_System_MathF_FusedMultiplyAdd, - NI_System_MathF_Round, + NI_System_Math_Cosh, + NI_System_Math_Sinh, + NI_System_Math_Tan, + NI_System_Math_Tanh, + NI_System_Math_Asin, + NI_System_Math_Asinh, + NI_System_Math_Acos, + NI_System_Math_Acosh, + NI_System_Math_Atan, + NI_System_Math_Atan2, + NI_System_Math_Atanh, + NI_System_Math_Log10, + NI_System_Math_Pow, + NI_System_Math_Exp, + NI_System_Math_Ceiling, + NI_System_Math_Floor, NI_System_Collections_Generic_EqualityComparer_get_Default, NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness, NI_System_GC_KeepAlive, diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index b878a30beeae..8054fda6e8ef 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -726,7 +726,7 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge case GT_INTRINSIC: // Non-target intrinsics should have already been rewritten back into user calls. - assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicId)); + assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicName)); break; #ifdef FEATURE_SIMD @@ -903,7 +903,7 @@ PhaseStatus Rationalizer::DoPhase() { GenTree* const node = *use; if (node->OperGet() == GT_INTRINSIC && - m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicId)) + m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicName)) { m_rationalizer.RewriteIntrinsicAsUserCall(use, this->m_ancestors); } diff --git a/src/coreclr/src/jit/valuenum.cpp b/src/coreclr/src/jit/valuenum.cpp index 1cc0cab621ca..f436216064ae 100644 --- a/src/coreclr/src/jit/valuenum.cpp +++ b/src/coreclr/src/jit/valuenum.cpp @@ -4548,7 +4548,7 @@ void ValueNumStore::SetVNIsCheckedBound(ValueNum vn) m_checkedBoundVNs.AddOrUpdate(vn, true); } -ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN) +ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN) { assert(arg0VN == VNNormalValue(arg0VN)); @@ -4568,25 +4568,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat double res = 0.0; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: res = sin(arg0Val); break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: res = cos(arg0Val); break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: res = sqrt(arg0Val); break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: res = fabs(arg0Val); break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: res = ceil(arg0Val); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: res = floor(arg0Val); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: res = FloatingPointUtils::round(arg0Val); break; default: @@ -4604,25 +4604,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat float res = 0.0f; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: res = sinf(arg0Val); break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: res = cosf(arg0Val); break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: res = sqrtf(arg0Val); break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: res = fabsf(arg0Val); break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: res = ceilf(arg0Val); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: res = floorf(arg0Val); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: res = FloatingPointUtils::round(arg0Val); break; default: @@ -4633,11 +4633,11 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } else { - // CORINFO_INTRINSIC_Round is currently the only intrinsic that takes floating-point arguments - // and that returns a non floating-point result. + // NI_System_Math{F}_Round are currently the only intrinsic that take floating-point arguments + // and return a non floating-point result. assert(typ == TYP_INT); - assert(gtMathFN == CORINFO_INTRINSIC_Round); + assert(gtMathFN == NI_System_Math_Round); int res = 0; @@ -4664,27 +4664,27 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } else { - assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || (typ == TYP_INT && gtMathFN == CORINFO_INTRINSIC_Round)); + assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || typ == TYP_INT && gtMathFN == NI_System_Math_Round); VNFunc vnf = VNF_Boundary; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: vnf = VNF_Sin; break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: vnf = VNF_Cos; break; - case CORINFO_INTRINSIC_Cbrt: + case NI_System_Math_Cbrt: vnf = VNF_Cbrt; break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: vnf = VNF_Sqrt; break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: vnf = VNF_Abs; break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: if (typ == TYP_DOUBLE) { vnf = VNF_RoundDouble; @@ -4702,46 +4702,46 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat noway_assert(!"Invalid INTRINSIC_Round"); } break; - case CORINFO_INTRINSIC_Cosh: + case NI_System_Math_Cosh: vnf = VNF_Cosh; break; - case CORINFO_INTRINSIC_Sinh: + case NI_System_Math_Sinh: vnf = VNF_Sinh; break; - case CORINFO_INTRINSIC_Tan: + case NI_System_Math_Tan: vnf = VNF_Tan; break; - case CORINFO_INTRINSIC_Tanh: + case NI_System_Math_Tanh: vnf = VNF_Tanh; break; - case CORINFO_INTRINSIC_Asin: + case NI_System_Math_Asin: vnf = VNF_Asin; break; - case CORINFO_INTRINSIC_Asinh: + case NI_System_Math_Asinh: vnf = VNF_Asinh; break; - case CORINFO_INTRINSIC_Acos: + case NI_System_Math_Acos: vnf = VNF_Acos; break; - case CORINFO_INTRINSIC_Acosh: + case NI_System_Math_Acosh: vnf = VNF_Acosh; break; - case CORINFO_INTRINSIC_Atan: + case NI_System_Math_Atan: vnf = VNF_Atan; break; - case CORINFO_INTRINSIC_Atanh: + case NI_System_Math_Atanh: vnf = VNF_Atanh; break; - case CORINFO_INTRINSIC_Log10: + case NI_System_Math_Log10: vnf = VNF_Log10; break; - case CORINFO_INTRINSIC_Exp: + case NI_System_Math_Exp: vnf = VNF_Exp; break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: vnf = VNF_Ceiling; break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: vnf = VNF_Floor; break; default: @@ -4752,7 +4752,7 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } } -ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN, ValueNum arg1VN) +ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN, ValueNum arg1VN) { assert(varTypeIsFloating(typ)); assert(arg0VN == VNNormalValue(arg0VN)); @@ -4765,11 +4765,11 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMa switch (gtMathFN) { - case CORINFO_INTRINSIC_Atan2: + case NI_System_Math_Atan2: vnf = VNF_Atan2; break; - case CORINFO_INTRINSIC_Pow: + case NI_System_Math_Pow: vnf = VNF_Pow; break; @@ -8389,7 +8389,7 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree) vnStore->VNPUnpackExc(intrinsic->AsOp()->gtOp2->gtVNPair, &arg1VNP, &arg1VNPx); } - if (IsMathIntrinsic(intrinsic->gtIntrinsicId)) + if (IsMathIntrinsic(intrinsic->gtIntrinsicName)) { // GT_INTRINSIC is a currently a subtype of binary operators. But most of // the math intrinsics are actually unary operations. @@ -8397,13 +8397,13 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree) if (intrinsic->AsOp()->gtOp2 == nullptr) { intrinsic->gtVNPair = - vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP), + vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP), arg0VNPx); } else { ValueNumPair newVNP = - vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP, arg1VNP); + vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP, arg1VNP); ValueNumPair excSet = vnStore->VNPExcSetUnion(arg0VNPx, arg1VNPx); intrinsic->gtVNPair = vnStore->VNPWithExc(newVNP, excSet); } @@ -8615,7 +8615,7 @@ void Compiler::fgValueNumberHWIntrinsic(GenTree* tree) else if (tree->AsOp()->gtOp1->OperIs(GT_LIST) || (lookupNumArgs == -1)) { // We have a HWINTRINSIC node in the GT_LIST form with 3 or more args - // Or the numArgs was specified as -1 in the numArgs column in "hwinstrinsiclistxarch.h" + // Or the numArgs was specified as -1 in the numArgs column in "hwintrinsiclistxarch.h" // For now we will generate a unique value number for this case. // Generate unique VN diff --git a/src/coreclr/src/jit/valuenum.h b/src/coreclr/src/jit/valuenum.h index 9f3cc2025be2..2f57b6323e67 100644 --- a/src/coreclr/src/jit/valuenum.h +++ b/src/coreclr/src/jit/valuenum.h @@ -818,20 +818,17 @@ class ValueNumStore // "arg0VN". For binary ops, return the value number for the application of this function to "arg0VN" and // "arg1VN". - ValueNum EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN); + ValueNum EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN); - ValueNum EvalMathFuncBinary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN, ValueNum arg1VN); + ValueNum EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN, ValueNum arg1VN); - ValueNumPair EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNumPair arg0VNP) + ValueNumPair EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP) { return ValueNumPair(EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetLiberal()), EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetConservative())); } - ValueNumPair EvalMathFuncBinary(var_types typ, - CorInfoIntrinsics mthFunc, - ValueNumPair arg0VNP, - ValueNumPair arg1VNP) + ValueNumPair EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP, ValueNumPair arg1VNP) { return ValueNumPair(EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetLiberal(), arg1VNP.GetLiberal()), EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetConservative(), arg1VNP.GetConservative())); diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs index 3f6c089744b2..46cac9f2e8d4 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs @@ -76,55 +76,6 @@ static IntrinsicHashtable InitializeIntrinsicHashtable() { IntrinsicHashtable table = new IntrinsicHashtable(); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Abs, "Abs", "System", "Math"); - // No System.MathF entry for CORINFO_INTRTINSIC_Abs as System.Math exposes and handles both float and double - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "MathF"); -#if !READYTORUN - // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. - // However, we don't know the ISAs the target machine supports so we should - // fallback to the method call implementation instead. - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "MathF"); -#endif // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetChar, null, null, null); // unused // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_GetDimLength, "GetLength", "System", "Array"); // not handled table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get, "Get", null, null); @@ -163,7 +114,7 @@ static IntrinsicHashtable InitializeIntrinsicHashtable() table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle, "AllocatorOf", "System", "Activator"); // If this assert fails, make sure to add the new intrinsics to the table above and update the expected count below. - Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 56, "Please update intrinsic hash table"); + Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 34, "Please update intrinsic hash table"); return table; } @@ -201,14 +152,6 @@ private CorInfoIntrinsics getIntrinsicID(MethodDesc method, byte* pMustExpand) CorInfoIntrinsics id = entry.Id; switch (id) { - case CorInfoIntrinsics.CORINFO_INTRINSIC_Abs: - { - // RyuJIT handles floating point overloads only - var returnTypeCategory = method.Signature.ReturnType.Category; - if (returnTypeCategory != TypeFlags.Double && returnTypeCategory != TypeFlags.Single) - return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal; - } - break; case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get: case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address: case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set: diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index da5d691a39cf..f5496370e4e8 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -811,7 +811,7 @@ private uint getMethodAttribsInternal(MethodDesc method) // do a dynamic check instead. if ( !HardwareIntrinsicHelpers.IsIsSupportedMethod(method) - || !_compilation.IsHardwareInstrinsicWithRuntimeDeterminedSupport(method)) + || !_compilation.IsHardwareIntrinsicWithRuntimeDeterminedSupport(method)) #endif { result |= CorInfoFlag.CORINFO_FLG_JIT_INTRINSIC; diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs index c1a9f87533ad..8f4b1f60b92a 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs @@ -416,28 +416,6 @@ public enum CorInfoOptions public enum CorInfoIntrinsics { - CORINFO_INTRINSIC_Sin, - CORINFO_INTRINSIC_Cos, - CORINFO_INTRINSIC_Cbrt, - CORINFO_INTRINSIC_Sqrt, - CORINFO_INTRINSIC_Abs, - CORINFO_INTRINSIC_Round, - CORINFO_INTRINSIC_Cosh, - CORINFO_INTRINSIC_Sinh, - CORINFO_INTRINSIC_Tan, - CORINFO_INTRINSIC_Tanh, - CORINFO_INTRINSIC_Asin, - CORINFO_INTRINSIC_Asinh, - CORINFO_INTRINSIC_Acos, - CORINFO_INTRINSIC_Acosh, - CORINFO_INTRINSIC_Atan, - CORINFO_INTRINSIC_Atan2, - CORINFO_INTRINSIC_Atanh, - CORINFO_INTRINSIC_Log10, - CORINFO_INTRINSIC_Pow, - CORINFO_INTRINSIC_Exp, - CORINFO_INTRINSIC_Ceiling, - CORINFO_INTRINSIC_Floor, CORINFO_INTRINSIC_GetChar, // fetch character out of string CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array diff --git a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp index c9530e40a056..1a1ef6ff17bb 100644 --- a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp +++ b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp @@ -26,11 +26,11 @@ class CORJIT_FLAGS uint64_t corJitFlags; }; -static const GUID JITEEVersionIdentifier = { /* 164b4e4f-21f6-4d05-b560-3728395404f2 */ - 0x164b4e4f, - 0x21f6, - 0x4d05, - { 0xb5, 0x60, 0x37, 0x28, 0x39, 0x54, 0x04, 0xf2 } +static const GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */ + 0xa5eec3a4, + 0x4176, + 0x43a7, + {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49} }; class Jit diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index de55a1913441..3312004c73ea 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -530,65 +530,65 @@ FCFuncStart(gDelegateFuncs) FCFuncEnd() FCFuncStart(gMathFuncs) - FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::Abs, CORINFO_INTRINSIC_Abs) - FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMSingle::Abs, CORINFO_INTRINSIC_Abs) - FCIntrinsic("Acos", COMDouble::Acos, CORINFO_INTRINSIC_Acos) - FCIntrinsic("Acosh", COMDouble::Acosh, CORINFO_INTRINSIC_Acosh) - FCIntrinsic("Asin", COMDouble::Asin, CORINFO_INTRINSIC_Asin) - FCIntrinsic("Asinh", COMDouble::Asinh, CORINFO_INTRINSIC_Asinh) - FCIntrinsic("Atan", COMDouble::Atan, CORINFO_INTRINSIC_Atan) - FCIntrinsic("Atanh", COMDouble::Atanh, CORINFO_INTRINSIC_Atanh) - FCIntrinsic("Atan2", COMDouble::Atan2, CORINFO_INTRINSIC_Atan2) - FCIntrinsic("Cbrt", COMDouble::Cbrt, CORINFO_INTRINSIC_Cbrt) - FCIntrinsic("Ceiling", COMDouble::Ceil, CORINFO_INTRINSIC_Ceiling) - FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos) - FCIntrinsic("Cosh", COMDouble::Cosh, CORINFO_INTRINSIC_Cosh) - FCIntrinsic("Exp", COMDouble::Exp, CORINFO_INTRINSIC_Exp) - FCIntrinsic("Floor", COMDouble::Floor, CORINFO_INTRINSIC_Floor) + FCFuncElementSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::Abs) + FCFuncElementSig("Abs", &gsig_SM_Flt_RetFlt, COMSingle::Abs) + FCFuncElement("Acos", COMDouble::Acos) + FCFuncElement("Acosh", COMDouble::Acosh) + FCFuncElement("Asin", COMDouble::Asin) + FCFuncElement("Asinh", COMDouble::Asinh) + FCFuncElement("Atan", COMDouble::Atan) + FCFuncElement("Atanh", COMDouble::Atanh) + FCFuncElement("Atan2", COMDouble::Atan2) + FCFuncElement("Cbrt", COMDouble::Cbrt) + FCFuncElement("Ceiling", COMDouble::Ceil) + FCFuncElement("Cos", COMDouble::Cos) + FCFuncElement("Cosh", COMDouble::Cosh) + FCFuncElement("Exp", COMDouble::Exp) + FCFuncElement("Floor", COMDouble::Floor) FCFuncElement("FMod", COMDouble::FMod) FCFuncElement("FusedMultiplyAdd", COMDouble::FusedMultiplyAdd) FCFuncElement("ILogB", COMDouble::ILogB) FCFuncElement("Log", COMDouble::Log) FCFuncElement("Log2", COMDouble::Log2) - FCIntrinsic("Log10", COMDouble::Log10, CORINFO_INTRINSIC_Log10) + FCFuncElement("Log10", COMDouble::Log10) FCFuncElement("ModF", COMDouble::ModF) - FCIntrinsic("Pow", COMDouble::Pow, CORINFO_INTRINSIC_Pow) + FCFuncElement("Pow", COMDouble::Pow) FCFuncElement("ScaleB", COMDouble::ScaleB) - FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin) - FCIntrinsic("Sinh", COMDouble::Sinh, CORINFO_INTRINSIC_Sinh) - FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt) - FCIntrinsic("Tan", COMDouble::Tan, CORINFO_INTRINSIC_Tan) - FCIntrinsic("Tanh", COMDouble::Tanh, CORINFO_INTRINSIC_Tanh) + FCFuncElement("Sin", COMDouble::Sin) + FCFuncElement("Sinh", COMDouble::Sinh) + FCFuncElement("Sqrt", COMDouble::Sqrt) + FCFuncElement("Tan", COMDouble::Tan) + FCFuncElement("Tanh", COMDouble::Tanh) FCFuncEnd() FCFuncStart(gMathFFuncs) - FCIntrinsic("Acos", COMSingle::Acos, CORINFO_INTRINSIC_Acos) - FCIntrinsic("Acosh", COMSingle::Acosh, CORINFO_INTRINSIC_Acosh) - FCIntrinsic("Asin", COMSingle::Asin, CORINFO_INTRINSIC_Asin) - FCIntrinsic("Asinh", COMSingle::Asinh, CORINFO_INTRINSIC_Asinh) - FCIntrinsic("Atan", COMSingle::Atan, CORINFO_INTRINSIC_Atan) - FCIntrinsic("Atanh", COMSingle::Atanh, CORINFO_INTRINSIC_Atanh) - FCIntrinsic("Atan2", COMSingle::Atan2, CORINFO_INTRINSIC_Atan2) - FCIntrinsic("Cbrt", COMSingle::Cbrt, CORINFO_INTRINSIC_Cbrt) - FCIntrinsic("Ceiling", COMSingle::Ceil, CORINFO_INTRINSIC_Ceiling) - FCIntrinsic("Cos", COMSingle::Cos, CORINFO_INTRINSIC_Cos) - FCIntrinsic("Cosh", COMSingle::Cosh, CORINFO_INTRINSIC_Cosh) - FCIntrinsic("Exp", COMSingle::Exp, CORINFO_INTRINSIC_Exp) - FCIntrinsic("Floor", COMSingle::Floor, CORINFO_INTRINSIC_Floor) + FCFuncElement("Acos", COMSingle::Acos) + FCFuncElement("Acosh", COMSingle::Acosh) + FCFuncElement("Asin", COMSingle::Asin) + FCFuncElement("Asinh", COMSingle::Asinh) + FCFuncElement("Atan", COMSingle::Atan) + FCFuncElement("Atanh", COMSingle::Atanh) + FCFuncElement("Atan2", COMSingle::Atan2) + FCFuncElement("Cbrt", COMSingle::Cbrt) + FCFuncElement("Ceiling", COMSingle::Ceil) + FCFuncElement("Cos", COMSingle::Cos) + FCFuncElement("Cosh", COMSingle::Cosh) + FCFuncElement("Exp", COMSingle::Exp) + FCFuncElement("Floor", COMSingle::Floor) FCFuncElement("FMod", COMSingle::FMod) FCFuncElement("FusedMultiplyAdd", COMSingle::FusedMultiplyAdd) FCFuncElement("ILogB", COMSingle::ILogB) FCFuncElement("Log", COMSingle::Log) FCFuncElement("Log2", COMSingle::Log2) - FCIntrinsic("Log10", COMSingle::Log10, CORINFO_INTRINSIC_Log10) + FCFuncElement("Log10", COMSingle::Log10) FCFuncElement("ModF", COMSingle::ModF) - FCIntrinsic("Pow", COMSingle::Pow, CORINFO_INTRINSIC_Pow) + FCFuncElement("Pow", COMSingle::Pow) FCFuncElement("ScaleB", COMSingle::ScaleB) - FCIntrinsic("Sin", COMSingle::Sin, CORINFO_INTRINSIC_Sin) - FCIntrinsic("Sinh", COMSingle::Sinh, CORINFO_INTRINSIC_Sinh) - FCIntrinsic("Sqrt", COMSingle::Sqrt, CORINFO_INTRINSIC_Sqrt) - FCIntrinsic("Tan", COMSingle::Tan, CORINFO_INTRINSIC_Tan) - FCIntrinsic("Tanh", COMSingle::Tanh, CORINFO_INTRINSIC_Tanh) + FCFuncElement("Sin", COMSingle::Sin) + FCFuncElement("Sinh", COMSingle::Sinh) + FCFuncElement("Sqrt", COMSingle::Sqrt) + FCFuncElement("Tan", COMSingle::Tan) + FCFuncElement("Tanh", COMSingle::Tanh) FCFuncEnd() FCFuncStart(gThreadFuncs) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index 203196851cc1..ea45f3e59ded 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -2219,12 +2219,13 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF #if defined(TARGET_X86) || defined(TARGET_AMD64) else if (strcmp(namespaceName, "System") == 0) { - if ((strcmp(className, "Math") == 0) || (strcmp(className, "MathF") == 0)) + if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0) { // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. // However, we don't know the ISAs the target machine supports so we should // fallback to the method call implementation instead. - fTreatAsRegularMethodCall = strcmp(methodName, "Round") == 0; + fTreatAsRegularMethodCall = strcmp(methodName, "Round") == 0 || strcmp(methodName, "Ceiling") == 0 || + strcmp(methodName, "Floor") == 0; } } else if (strcmp(namespaceName, "System.Numerics") == 0) @@ -3991,19 +3992,7 @@ void ZapInfo::expandRawHandleIntrinsic( CorInfoIntrinsics ZapInfo::getIntrinsicID(CORINFO_METHOD_HANDLE method, bool * pMustExpand) { - CorInfoIntrinsics intrinsicID = m_pEEJitInfo->getIntrinsicID(method, pMustExpand); - -#if defined(TARGET_X86) || defined(TARGET_AMD64) - if ((intrinsicID == CORINFO_INTRINSIC_Ceiling) || (intrinsicID == CORINFO_INTRINSIC_Floor)) - { - // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. - // However, we don't know the ISAs the target machine supports so we should - // fallback to the method call implementation instead. - intrinsicID = CORINFO_INTRINSIC_Illegal; - } -#endif // defined(TARGET_X86) || defined(TARGET_AMD64) - - return intrinsicID; + return m_pEEJitInfo->getIntrinsicID(method, pMustExpand); } bool ZapInfo::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) From f6aca9ee46bc03302447353fff963023386a09eb Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 24 Jul 2020 18:02:32 +0200 Subject: [PATCH 032/755] Post #35606 cleanup (#39891) * Post #35606 cleanup --- docs/workflow/building/libraries/webassembly-instructions.md | 4 ++-- src/libraries/restore/runtime/runtime.depproj | 2 +- src/mono/wasm/Makefile | 2 +- src/mono/wasm/wasm.targets | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/workflow/building/libraries/webassembly-instructions.md b/docs/workflow/building/libraries/webassembly-instructions.md index c3195a30665e..c7059cd8269e 100644 --- a/docs/workflow/building/libraries/webassembly-instructions.md +++ b/docs/workflow/building/libraries/webassembly-instructions.md @@ -91,7 +91,7 @@ The WebAssembly implementation files are built and made available in the artifac For Linux and MacOSX: ```bash -./dotnet.sh build /p:Configuration=Debug|Release /p:TargetArchitecture=wasm /p:TargetOS=Browser src/libraries/src.proj /t:NativeBinPlace +./dotnet.sh build /p:Configuration=Debug|Release /p:TargetArchitecture=wasm /p:TargetOS=Browser src/libraries/src.proj /t:BuildWasmRuntimes ``` __Note__: A `Debug` build sets the following environment variables by default. When built from the command line this way the `Configuration` value is case sensitive. @@ -155,4 +155,4 @@ container: registry: mcr ``` -Open a PR request with the new image. \ No newline at end of file +Open a PR request with the new image. diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj index 92ebdb6d285e..b433ff319213 100644 --- a/src/libraries/restore/runtime/runtime.depproj +++ b/src/libraries/restore/runtime/runtime.depproj @@ -75,7 +75,7 @@ + DestinationSubDirectory="cross/" /> diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 2562217a9354..636ff21d20c2 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -101,7 +101,7 @@ $(eval $(call InterpBuildTemplate,$(EMCC_RELEASE_FLAGS),$(MONO_LIBS))) endif build: - EMSDK_PATH=$(PWD)/emsdk $(DOTNET) build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(TOP)/src/libraries/src.proj /t:NativeBinPlace + EMSDK_PATH=$(PWD)/emsdk $(DOTNET) build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(TOP)/src/libraries/src.proj /t:BuildWasmRuntimes clean-emsdk: $(RM) -rf $(EMSDK_LOCAL_PATH) diff --git a/src/mono/wasm/wasm.targets b/src/mono/wasm/wasm.targets index be87c207b15d..e3210dbc72e9 100644 --- a/src/mono/wasm/wasm.targets +++ b/src/mono/wasm/wasm.targets @@ -32,6 +32,7 @@ OutputPath="$(WasmPInvokeTablePath)" /> + From 5d1af65dc66d289d64e54814a4d5e91412b75fe4 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Fri, 24 Jul 2020 09:25:05 -0700 Subject: [PATCH 033/755] Fix ActivitySource.StartActivity when start time is provided (#39884) --- .../src/System/Diagnostics/Activity.cs | 2 +- .../tests/ActivitySourceTests.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index 5cb992426c36..d842a0c7dabe 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -986,7 +986,7 @@ internal static Activity CreateAndStart(ActivitySource source, string name, Acti } } - activity.StartTimeUtc = startTime == default ? DateTime.UtcNow : startTime.DateTime; + activity.StartTimeUtc = startTime == default ? DateTime.UtcNow : startTime.UtcDateTime; activity.IsAllDataRequested = request == ActivityDataRequest.AllData || request == ActivityDataRequest.AllDataAndRecorded; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs index 2f3be9de4957..5b22f1638161 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs @@ -323,12 +323,15 @@ public void TestActivityCreationProperties() attributes.Add(new KeyValuePair("tag2", "tagValue2")); attributes.Add(new KeyValuePair("tag3", "tagValue3")); - using (Activity activity = source.StartActivity("a1", ActivityKind.Client, ctx, attributes, links)) + DateTimeOffset startTime = DateTimeOffset.UtcNow; + + using (Activity activity = source.StartActivity("a1", ActivityKind.Client, ctx, attributes, links, startTime)) { Assert.NotNull(activity); Assert.Equal("a1", activity.OperationName); Assert.Equal("a1", activity.DisplayName); Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal(startTime, activity.StartTimeUtc); Assert.Equal(ctx.TraceId, activity.TraceId); Assert.Equal(ctx.SpanId, activity.ParentSpanId); From 960ac2b93bea7dc7bf2b694aea05f82ec2155e0a Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Fri, 24 Jul 2020 10:21:25 -0700 Subject: [PATCH 034/755] New fix for duplicate methods in the AltJit jit-diff output (#39751) --- src/coreclr/src/zap/zapinfo.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index ea45f3e59ded..08c143dc0eb6 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -496,12 +496,22 @@ void ZapInfo::CompileMethod() m_pImage->m_stats->m_ilCodeSize += m_currentMethodInfo.ILCodeSize; } - CorJitResult res = CORJIT_SKIPPED; + CorJitResult res = CORJIT_SKIPPED; // FAILED() returns true for this value BYTE *pCode; ULONG cCode; + bool doNormalCompile = true; #ifdef ALLOW_SXS_JIT_NGEN + + // Only retry the JIT compilation when we have a different JIT to run + // Often we see both COMPlus_AltJIT and COMPlus_AltJitNgen set + // which results in both JIT compilers set to the same altjit + // + doNormalCompile = (m_zapper->m_alternateJit != m_zapper->m_pJitCompiler); + + // Compile this method using the AltJitNgen compiler + // if (m_zapper->m_alternateJit) { res = m_zapper->m_alternateJit->compileMethod( this, @@ -509,23 +519,27 @@ void ZapInfo::CompileMethod() CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, &pCode, &cCode); - if (FAILED(res)) + + // The above compileMethod call will typically return CORJIT_SKIPPED + if (doNormalCompile && FAILED(res)) { // We will fall back to the "main" JIT on failure. ResetForJitRetry(); } } + #endif // ALLOW_SXS_JIT_NGEN - if (FAILED(res)) + // Compile this method using the normal JIT compiler + // + if (doNormalCompile && FAILED(res)) { ICorJitCompiler * pCompiler = m_zapper->m_pJitCompiler; res = pCompiler->compileMethod(this, - &m_currentMethodInfo, - CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, - &pCode, - &cCode); - + &m_currentMethodInfo, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, + &pCode, + &cCode); if (FAILED(res)) { ThrowExceptionForJitResult(res); From 384ef03826bfbb7da4720103b6befa1f0a9e5eb8 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Fri, 24 Jul 2020 10:59:16 -0700 Subject: [PATCH 035/755] Jit: fix some sources of x64 chk/rel diffs (#39888) Break IGs for perfscores the same way in chk and rel. Also, fix the xarch peephole to work across extended IGs. Closes #39845. --- src/coreclr/src/jit/codegenlinear.cpp | 2 -- src/coreclr/src/jit/emitxarch.cpp | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index 5ce369b52424..cf0d1cd149a0 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -344,7 +344,6 @@ void CodeGen::genCodeForBBlist() needLabel = true; } -#if defined(DEBUG) || defined(LATE_DISASM) // We also want to start a new Instruction group by calling emitAddLabel below, // when we need accurate bbWeights for this block in the emitter. We force this // whenever our previous block was a BBJ_COND and it has a different weight than us. @@ -356,7 +355,6 @@ void CodeGen::genCodeForBBlist() { needLabel = true; } -#endif // DEBUG || LATE_DISASM if (needLabel) { diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 1938efb9ed44..5d0efd05cba4 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -163,8 +163,10 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) bool emitter::AreUpper32BitsZero(regNumber reg) { - // Don't look back across IG boundaries (possible control flow) - if (emitCurIGinsCnt == 0) + // If there are no instructions in this IG, we can look back at + // the previous IG's instructions if this IG is an extension. + // + if ((emitCurIGinsCnt == 0) && ((emitCurIG->igFlags & IGF_EXTEND) == 0)) { return false; } From 7abd11409c7baf1babe38e82c551167294e8a13d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 24 Jul 2020 12:30:37 -0700 Subject: [PATCH 036/755] Update to unified Alpine build image version (#39903) Update our Alpine build image so we can unify for a single image for our builds. Fixes #2030 --- eng/pipelines/common/platform-matrix.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index b4f802024006..a7a3a167004c 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -86,11 +86,7 @@ jobs: archType: x64 platform: Linux_musl_x64 container: - # alpine coreclr cmake errors on newer builds - ${{ if eq(parameters.runtimeFlavor, 'mono') }}: - image: alpine-3.9-WithNode-0fc54a3-20200131134036 - ${{ if eq(parameters.runtimeFlavor, 'coreclr') }}: - image: alpine-3.9-WithNode-0fc54a3-20190918214015 + image: alpine-3.9-WithNode-20200602002639-0fc54a3 registry: mcr jobParameters: runtimeFlavor: ${{ parameters.runtimeFlavor }} From 36657793513070913cc7e95589a712aad3e8228f Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Fri, 24 Jul 2020 13:19:43 -0700 Subject: [PATCH 037/755] Fix GC Poll inlining. (#39881) * Don't inline GC polls in cold basic blocks. * Allow GC poll inlining in basic blocks with `BBF_LOOP_PREHEADER` or `BBF_RETLESS_CALL` set. This fixes one of the assert seen in https://github.com/dotnet/runtime/pull/39474#issuecomment-662033060 Contributes to resolving #39726. --- src/coreclr/src/jit/flowgraph.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 65c9af9e8f2c..f8500bf52d75 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -3699,6 +3699,18 @@ PhaseStatus Compiler::fgInsertGCPolls() // We don't want to deal with all the outgoing edges of a switch block. pollType = GCPOLL_CALL; } + else if ((block->bbFlags & BBF_COLD) != 0) + { +#ifdef DEBUG + if (verbose) + { + printf("Selecting CALL poll in block " FMT_BB " because it is a cold block\n", block->bbNum); + } +#endif // DEBUG + + // We don't want to split a cold block. + pollType = GCPOLL_CALL; + } BasicBlock* curBasicBlock = fgCreateGCPoll(pollType, block); createdPollBlocks |= (block != curBasicBlock); @@ -4141,9 +4153,12 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) // We are allowed to split loops and we need to keep a few other flags... // - noway_assert((originalFlags & (BBF_SPLIT_NONEXIST & ~(BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1))) == 0); - top->bbFlags = originalFlags & (~BBF_SPLIT_LOST | BBF_GC_SAFE_POINT); - bottom->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT); + noway_assert((originalFlags & (BBF_SPLIT_NONEXIST & + ~(BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_LOOP_PREHEADER | + BBF_RETLESS_CALL))) == 0); + top->bbFlags = originalFlags & (~(BBF_SPLIT_LOST | BBF_LOOP_PREHEADER | BBF_RETLESS_CALL) | BBF_GC_SAFE_POINT); + bottom->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT | BBF_LOOP_PREHEADER | + BBF_RETLESS_CALL); bottom->inheritWeight(top); poll->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT); From 43d558387cc0d48e45f9c1ca960f912c425c1fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 24 Jul 2020 22:31:59 +0200 Subject: [PATCH 038/755] Remove setting ICUCORE for macOS in System.Globalization.Native CMake config (#39900) Follow-up to #39833. We don't link against ICU on macOS but load it via `dlopen()` at runtime and compilation uses headers from homebrew. That means `HAVE_SET_MAX_VARIABLE` and `HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS` will always be defined and we don't need the ICUCORE variable. * PR feedback Co-authored-by: Adeel Mujahid --- .../Unix/System.Globalization.Native/CMakeLists.txt | 7 +------ .../Unix/System.Globalization.Native/configure.cmake | 8 ++------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt index f71af8ada58e..37e2574b481c 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt @@ -23,12 +23,7 @@ if(CLR_CMAKE_TARGET_UNIX) endif() if(CLR_CMAKE_TARGET_OSX) - find_library(ICUCORE icucore) - if(ICUCORE STREQUAL ICUCORE-NOTFOUND) - message(FATAL_ERROR "Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.") - return() - endif() - add_definitions(-DOSX_ICU_LIBRARY_PATH=\"/usr/lib/libicucore.dylib\") + add_definitions(-DOSX_ICU_LIBRARY_PATH="/usr/lib/libicucore.dylib") add_definitions(-DU_DISABLE_RENAMING) else() find_library(ICUUC icuuc) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/configure.cmake b/src/libraries/Native/Unix/System.Globalization.Native/configure.cmake index f0042b1a59c4..76fac2b7b7e9 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/configure.cmake +++ b/src/libraries/Native/Unix/System.Globalization.Native/configure.cmake @@ -1,4 +1,4 @@ -if(CLR_CMAKE_TARGET_ANDROID) +if(CLR_CMAKE_TARGET_ANDROID OR CLR_CMAKE_TARGET_OSX) set(HAVE_SET_MAX_VARIABLE 1) set(HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS 1) else() @@ -13,11 +13,7 @@ else() int main(void) { enum UDateFormatSymbolType e = UDAT_STANDALONE_SHORTER_WEEKDAYS; } " HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS) - if(CLR_CMAKE_TARGET_OSX) - set(CMAKE_REQUIRED_LIBRARIES ${ICUCORE}) - else() - set(CMAKE_REQUIRED_LIBRARIES ${ICUUC} ${ICUI18N}) - endif() + set(CMAKE_REQUIRED_LIBRARIES ${ICUUC} ${ICUI18N}) check_symbol_exists( ucol_setMaxVariable From 557c7aff0d63fbb1bf687be215ec1726625abc2a Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 24 Jul 2020 14:45:48 -0700 Subject: [PATCH 039/755] Fix lcl fld addr. (#39424) * Add a repro test. * Small ref. Combine long chains of `addr->OperGet() == GT_* ||` with `GT_LCL_VAR_ADDR` using `OperIs` to simplify future changes. * Add an assert that would fire in the repro test. `emitter::emitHandleMemOp` has special logic for contained `memBase` and but the last block does not expect a contained node. A contained node doesn't produce a register so it is not correct to use result of `GetRegNum()` from a contained node as a valid register. However, adding an assert to `GetRegNum()` that `!this->isContained` is a bigger task that is out of this PR. * Assert that `LCL_FLD_ADDR` is not contained in `genPutArgStk(Split)` We have contained `LCL_VAR_ADDR` support there but make sure that contained `LCL_FLD_ADDR` can't reach it. * Contain `GT_LCL_FLD_ADDR` under HW_INTRINSIC. This is an additional optimization that makes future changes simpler. * Add contained checks. In all these places we expect `LCL_VAR_ADDR` to be contained. If we had gotten a `LCL_VAR_ADDR` that is not contained we would have instantiated `LCL_VAR_ADDR` twice: in the register and the parent instruction. The register value would have been unused. * Support `FLD_ADDR` where `LCL_ADDR` is supported. However, fire an assert if we think that this path is unreachable for now. * Delete asserts in the reachable blocks. We have coverage for this asserts in the following tests: hwintrinsic 478: Ssse3_ro instr 11645: Runtime_39403 instr 1028 : Aes_ro hwintrinsic 716: pmi of Microsoft.Diagnostics.Tracing.TraceEvent * Review response. * Add repro cases. Delete the rest `assert(!"don't expect GT_LCL_FLD_ADDR");`. * Use `GetLclOffs` from `LclVarCommon`. * missed file. --- src/coreclr/src/jit/codegenarmarch.cpp | 8 + src/coreclr/src/jit/codegenxarch.cpp | 4 +- src/coreclr/src/jit/emitxarch.cpp | 41 ++-- .../src/jit/hwintrinsiccodegenxarch.cpp | 16 +- src/coreclr/src/jit/instr.cpp | 10 +- src/coreclr/src/jit/lowerxarch.cpp | 10 +- .../JitBlue/Runtime_39403/Runtime_39403.cs | 43 ++++ .../Runtime_39403/Runtime_39403.csproj | 13 ++ .../JitBlue/Runtime_39424/Runtime_39424.il | 196 ++++++++++++++++++ .../Runtime_39424/Runtime_39424.ilproj | 24 +++ 10 files changed, 330 insertions(+), 35 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.il create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.ilproj diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 45319861754c..a359156ab2cb 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -815,11 +815,15 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) // so update 'source' to point this GT_LCL_VAR_ADDR node // and continue to the codegen for the LCL_VAR node below // + assert(addrNode->isContained()); varNode = addrNode->AsLclVarCommon(); addrNode = nullptr; } else // addrNode is used { + // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays, + // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead. + assert(!addrNode->isContained()); // Generate code to load the address that we need into a register genConsumeAddress(addrNode); addrReg = addrNode->GetRegNum(); @@ -1253,6 +1257,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) if (varNode != nullptr) { + assert(varNode->isContained()); srcVarNum = varNode->GetLclNum(); assert(srcVarNum < compiler->lvaCount); @@ -1270,6 +1275,9 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) else // addrNode is used { assert(addrNode != nullptr); + // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays, + // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead. + assert(!addrNode->isContained()); // Generate code to load the address that we need into a register genConsumeAddress(addrNode); diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index ed1a67b7ca5b..c66d25c483c9 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -6934,9 +6934,11 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) switch (memBase->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(memBase->isContained()); varNum = memBase->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = memBase->AsLclVarCommon()->GetLclOffs(); // Ensure that all the GenTreeIndir values are set to their defaults. assert(memBase->GetRegNum() == REG_NA); diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 5d0efd05cba4..f21b1170eb83 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -2958,24 +2958,27 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, } else { + regNumber amBaseReg = REG_NA; if (memBase != nullptr) { - id->idAddr()->iiaAddrMode.amBaseReg = memBase->GetRegNum(); - } - else - { - id->idAddr()->iiaAddrMode.amBaseReg = REG_NA; + assert(!memBase->isContained()); + amBaseReg = memBase->GetRegNum(); + assert(amBaseReg != REG_NA); } + regNumber amIndxReg = REG_NA; if (indir->HasIndex()) { - id->idAddr()->iiaAddrMode.amIndxReg = indir->Index()->GetRegNum(); - } - else - { - id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; + GenTree* index = indir->Index(); + assert(!index->isContained()); + amIndxReg = index->GetRegNum(); + assert(amIndxReg != REG_NA); } - id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(indir->Scale()); + + assert((amBaseReg != REG_NA) || (amIndxReg != REG_NA) || (indir->Offset() != 0)); // At least one should be set. + id->idAddr()->iiaAddrMode.amBaseReg = amBaseReg; + id->idAddr()->iiaAddrMode.amIndxReg = amIndxReg; + id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(indir->Scale()); id->idInsFmt(emitMapFmtForIns(fmt, ins)); @@ -3045,11 +3048,7 @@ void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, G 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(); emitIns_R_S(ins, attr, dstReg, varNode->GetLclNum(), offset); // Updating variable liveness after instruction was emitted @@ -3290,9 +3289,11 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G switch (memBase->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(memBase->isContained()); varNum = memBase->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = memBase->AsLclVarCommon()->GetLclOffs(); // Ensure that all the GenTreeIndir values are set to their defaults. assert(!memIndir->HasIndex()); @@ -3603,8 +3604,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI { GenTree* addr = storeInd->Addr(); addr = addr->gtSkipReloadOrCopy(); - assert(addr->OperGet() == GT_LCL_VAR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA || - addr->OperGet() == GT_CLS_VAR_ADDR || addr->OperGet() == GT_CNS_INT); + assert(addr->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_LEA, GT_CLS_VAR_ADDR, GT_CNS_INT)); instrDesc* id = nullptr; UNATIVE_OFFSET sz; @@ -3683,8 +3683,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI { GenTree* addr = storeInd->Addr(); addr = addr->gtSkipReloadOrCopy(); - assert(addr->OperGet() == GT_LCL_VAR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_CLS_VAR_ADDR || - addr->OperGet() == GT_LEA || addr->OperGet() == GT_CNS_INT); + assert(addr->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_LEA, GT_CNS_INT)); ssize_t offset = 0; if (addr->OperGet() != GT_CLS_VAR_ADDR) diff --git a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp index 574e8c48d15f..ddca579f34ab 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp @@ -469,9 +469,11 @@ void CodeGen::genHWIntrinsic_R_RM( switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } @@ -698,9 +700,11 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } @@ -861,9 +865,11 @@ void CodeGen::genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins) switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } @@ -986,9 +992,11 @@ void CodeGen::genHWIntrinsic_R_R_R_RM( switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } diff --git a/src/coreclr/src/jit/instr.cpp b/src/coreclr/src/jit/instr.cpp index a13887baa0f6..d6f4c98f6b94 100644 --- a/src/coreclr/src/jit/instr.cpp +++ b/src/coreclr/src/jit/instr.cpp @@ -478,7 +478,7 @@ void CodeGen::inst_IV_handle(instruction ins, int val) void CodeGen::inst_set_SV_var(GenTree* tree) { #ifdef DEBUG - assert(tree && (tree->gtOper == GT_LCL_VAR || tree->gtOper == GT_LCL_VAR_ADDR || tree->gtOper == GT_STORE_LCL_VAR)); + assert((tree != nullptr) && tree->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_STORE_LCL_VAR)); assert(tree->AsLclVarCommon()->GetLclNum() < compiler->lvaCount); GetEmitter()->emitVarRefOffs = tree->AsLclVar()->gtLclILoffs; @@ -1019,9 +1019,11 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } @@ -1146,9 +1148,11 @@ void CodeGen::inst_RV_RV_TT( switch (addr->OperGet()) { case GT_LCL_VAR_ADDR: + case GT_LCL_FLD_ADDR: { + assert(addr->isContained()); varNum = addr->AsLclVarCommon()->GetLclNum(); - offset = 0; + offset = addr->AsLclVarCommon()->GetLclOffs(); break; } diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 052abaf890df..5952db77f919 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -3439,8 +3439,7 @@ bool Lowering::IsRMWMemOpRootedAtStoreInd(GenTree* tree, GenTree** outIndirCandi assert(storeInd->IsRMWStatusUnknown()); // Early out if indirDst is not one of the supported memory operands. - if (indirDst->OperGet() != GT_LEA && indirDst->OperGet() != GT_LCL_VAR && indirDst->OperGet() != GT_LCL_VAR_ADDR && - indirDst->OperGet() != GT_CLS_VAR_ADDR && indirDst->OperGet() != GT_CNS_INT) + if (!indirDst->OperIs(GT_LEA, GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_CNS_INT)) { storeInd->SetRMWStatus(STOREIND_RMW_UNSUPPORTED_ADDR); return false; @@ -4452,14 +4451,13 @@ bool Lowering::LowerRMWMemOp(GenTreeIndir* storeInd) } else { - assert(indirCandidateChild->OperGet() == GT_LCL_VAR || indirCandidateChild->OperGet() == GT_LCL_VAR_ADDR || - indirCandidateChild->OperGet() == GT_CLS_VAR_ADDR || indirCandidateChild->OperGet() == GT_CNS_INT); + assert(indirCandidateChild->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_CNS_INT)); // If it is a GT_LCL_VAR, it still needs the reg to hold the address. // We would still need a reg for GT_CNS_INT if it doesn't fit within addressing mode base. // For GT_CLS_VAR_ADDR, we don't need a reg to hold the address, because field address value is known at jit // time. Also, we don't need a reg for GT_CLS_VAR_ADDR. - if (indirCandidateChild->OperGet() == GT_LCL_VAR_ADDR || indirCandidateChild->OperGet() == GT_CLS_VAR_ADDR) + if (indirCandidateChild->OperIs(GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR)) { indirDst->SetContained(); } @@ -5138,7 +5136,7 @@ void Lowering::ContainCheckHWIntrinsicAddr(GenTreeHWIntrinsic* node, GenTree* ad { assert((addr->TypeGet() == TYP_I_IMPL) || (addr->TypeGet() == TYP_BYREF)); TryCreateAddrMode(addr, true); - if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LEA) || + if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA) || (addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))) && IsSafeToContainMem(node, addr)) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.cs b/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.cs new file mode 100644 index 000000000000..032f73d83221 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics; +using System.Runtime.CompilerServices; + +// The test was showing silence bad codegen for a `LclFldAddr` node under HWINSTRINSIC(IND). + +class Runtime_39403 +{ + struct Container + { + public Vector Vector; + public int Integer; + } + + static Vector DoAThingByRef(ref Vector s) + { + return s + Vector.Zero; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe Vector TestLclFldAddr() + { + Container container = default; + return DoAThingByRef(ref container.Vector); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe Vector TestLclVarAddr() + { + Container container = default; + return DoAThingByRef(ref Unsafe.As>(ref container)); + } + + public static int Main() + { + Vector v1 = TestLclFldAddr(); + Vector v2 = TestLclVarAddr(); + System.Diagnostics.Debug.Assert(v1 == v2); + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.csproj new file mode 100644 index 000000000000..5d49e8d49736 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39403/Runtime_39403.csproj @@ -0,0 +1,13 @@ + + + Exe + + + + True + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.il b/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.il new file mode 100644 index 000000000000..ab35b013505e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.il @@ -0,0 +1,196 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + + +// The test was showing some rare cases of `IND(LCL_FLD_ADDR)` under HW intrinsic nodes. + +.assembly extern System.Runtime {} +.assembly extern System.Runtime.Intrinsics {} +.assembly extern System.Runtime.Extensions {} +.assembly extern System.Numerics.Vectors {} +.assembly extern System.Numerics.Extensions {} +.assembly extern System.Runtime.CompilerServices.Unsafe {} + +.assembly Runtime_39424.exe {} + +.class private auto ansi beforefieldinit Runtime_39424 + extends [System.Runtime]System.Object +{ + .class sequential ansi sealed nested private beforefieldinit Container + extends [System.Runtime]System.ValueType + { + .field public valuetype [System.Numerics.Vectors]System.Numerics.Vector`1 Vector + .field public float64 Double + } // end of class Container + + .method private hidebysig static float64 + TestLclFldAddrIntrinsicsRound(float64 d) cil managed noinlining + { + // Code size 30 (0x1e) + .maxstack 2 + .locals init (valuetype Runtime_39424/Container V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj Runtime_39424/Container + IL_0008: ldloca.s V_0 + IL_000a: ldarg.0 + IL_000b: stfld float64 Runtime_39424/Container::Double + IL_0010: ldloca.s V_0 + IL_0012: ldflda float64 Runtime_39424/Container::Double + IL_0017: volatile. ldind.r8 + IL_0018: call float64 [System.Runtime.Extensions]System.Math::Round(float64) + IL_001d: ret + } // end of method Runtime_39424::TestLclFldAddrIntrinsicsRound + + .class sequential ansi sealed nested private beforefieldinit Vector128Wrapped + extends [System.Runtime]System.ValueType + { + .field public int8 i1 + .field public int8 i2 + .field public int8 i3 + .field public int8 i4 + .field public valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 'vector' + } // end of class Vector128Wrapped + + + .class sequential ansi sealed nested private beforefieldinit Vector128WrappedDouble + extends [System.Runtime]System.ValueType + { + .field private bool i1 + .field private bool i2 + .field private bool i3 + .field private bool i4 + .field public valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 'vector' + } // end of class Vector128WrappedDouble + + .method private hidebysig static float64 + TestLclFldAddrIntrinsicsSSE41_BlendVariable(float64 d) cil managed noinlining + { + // Code size 78 (0x4e) + .maxstack 3 + .locals init (valuetype Runtime_39424/Vector128Wrapped V_0, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1& V_1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 V_2) + IL_0000: call bool [System.Runtime.Intrinsics]System.Runtime.Intrinsics.X86.Sse41::get_IsSupported() + IL_0005: brfalse.s IL_0044 + + IL_0007: ldc.i4.1 + IL_0008: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(int32) + IL_000d: ldloca.s V_0 + IL_000f: initobj Runtime_39424/Vector128Wrapped + IL_0015: ldloca.s V_0 + IL_0017: ldc.i4.2 + IL_0018: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(int32) + IL_001d: stfld valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 Runtime_39424/Vector128Wrapped::'vector' + IL_002a: ldc.i4.3 + IL_002b: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(int32) + IL_0030: stloc.2 + IL_0022: ldloca.s V_0 + IL_0024: ldflda valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 Runtime_39424/Vector128Wrapped::'vector' + IL_0032: volatile. ldobj valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 + IL_0037: ldloc.2 + IL_0038: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.X86.Sse41::BlendVariable(valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1) + IL_003d: call !!0 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::ToScalar(valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1) + IL_0042: conv.r8 + IL_0043: ret + + IL_0044: ldc.r8 100. + IL_004d: ret + } // end of method Runtime_39424::TestLclFldAddrIntrinsicsSSE41_BlendVariable + + .method private hidebysig static float64 + TestLclFldAddrIntrinsicsFMA_MulipluAddScalar() cil managed noinlining + { + // Code size 101 (0x65) + .maxstack 3 + .locals init (valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 V_0, + valuetype Runtime_39424/Vector128WrappedDouble V_1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1& V_2) + IL_0000: call bool [System.Runtime.Intrinsics]System.Runtime.Intrinsics.X86.Fma::get_IsSupported() + IL_0005: brfalse.s IL_005b + + IL_0007: ldc.r8 1. + IL_0010: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(float64) + IL_0015: ldc.r8 3. + IL_001e: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(float64) + IL_0023: stloc.0 + IL_0024: ldloca.s V_1 + IL_0026: initobj Runtime_39424/Vector128WrappedDouble + IL_002c: ldloca.s V_1 + IL_002e: ldc.r8 2. + IL_0037: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::Create(float64) + IL_003c: stfld valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 Runtime_39424/Vector128WrappedDouble::'vector' + IL_0049: ldloc.0 + IL_0041: ldloca.s V_1 + IL_0043: ldflda valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 Runtime_39424/Vector128WrappedDouble::'vector' + IL_004b: ldobj valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 + IL_0050: call valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.X86.Fma::MultiplyAddScalar(valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1, + valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1) + IL_0055: call !!0 [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128::ToScalar(valuetype [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Vector128`1) + IL_005a: ret + + IL_005b: ldc.r8 100. + IL_0064: ret + } // end of method Runtime_39424::TestLclFldAddrIntrinsicsFMA_MulipluAddScalar + + + .class sequential ansi sealed nested private beforefieldinit IntsWrapped + extends [System.Runtime]System.ValueType + { + .field public int32 i1 + .field public int32 i2 + .field public int32 i3 + .field public int32 i4 + .field public int32 i5 + } // end of class IntsWrapped + + .method public hidebysig static int32 TestLclFldAddr_BinOp(int32 a) cil managed noinlining + { + // Code size 21 (0x15) + .maxstack 2 + .locals init (valuetype Runtime_39424/IntsWrapped V_0, + int32& V_1) + IL_0000: ldloca.s V_0 + IL_0002: initobj Runtime_39424/IntsWrapped + IL_0010: ldarg.0 + IL_0008: ldloca.s V_0 + IL_000a: ldflda int32 Runtime_39424/IntsWrapped::i4 + IL_0012: volatile. ldind.i4 + IL_0013: add + IL_0014: ret + } // end of method Runtime_39424::TestLclFldAddr_BinOp + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldc.r8 1. + IL_0009: call float64 Runtime_39424::TestLclFldAddrIntrinsicsRound(float64) + IL_000e: pop + IL_0010: ldc.r8 2. + IL_0011: call float64 Runtime_39424::TestLclFldAddrIntrinsicsSSE41_BlendVariable(float64) + IL_0012: pop + IL_0013: call float64 Runtime_39424::TestLclFldAddrIntrinsicsFMA_MulipluAddScalar() + IL_0014: pop + ldc.i4.1 + call int32 Runtime_39424::TestLclFldAddr_BinOp(int32) + pop + + IL_0015: ldc.i4.s 100 + IL_0016: ret + } // end of method Runtime_39424::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [System.Runtime]System.Object::.ctor() + IL_0006: ret + } // end of method Runtime_39424::.ctor + +} // end of class Runtime_39424 \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.ilproj b/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.ilproj new file mode 100644 index 000000000000..da6159dc88d6 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39424/Runtime_39424.ilproj @@ -0,0 +1,24 @@ + + + Exe + 1 + + + None + True + + + + + + + + + + From 7ec5302874ecbc2bc3cf580d006b4d1b3fbc6e7c Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Fri, 24 Jul 2020 15:17:43 -0700 Subject: [PATCH 040/755] Ensure CoreCLR pkgproj include packaging props (#39906) Since these projects don't directly consume the nupkg they didn't automatically get props when we added it. --- src/coreclr/src/.nuget/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/.nuget/Directory.Build.props b/src/coreclr/src/.nuget/Directory.Build.props index 1a8f5c0d7414..02ba072c4b88 100644 --- a/src/coreclr/src/.nuget/Directory.Build.props +++ b/src/coreclr/src/.nuget/Directory.Build.props @@ -3,6 +3,9 @@ + + + From e856fbfc1e1cd84508bbdfa5ec75b90ff94eacf7 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 24 Jul 2020 15:29:24 -0700 Subject: [PATCH 041/755] Delete redundant MSVC compiler options (#39901) --- eng/native/configurecompiler.cmake | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 9d1b88f08011..51a58fc06f61 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -19,9 +19,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/configureoptimization.cmake) # Initialize Cmake compiler flags and other variables #----------------------------------------------------- -if(MSVC) - add_compile_options(/Zi /FC /Zc:strictStrings) -elseif (CLR_CMAKE_HOST_UNIX) +if (CLR_CMAKE_HOST_UNIX) add_compile_options(-g) add_compile_options(-Wall) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -417,25 +415,20 @@ endif(CLR_CMAKE_HOST_UNIX) if (MSVC) # Compile options for targeting windows - # The following options are set by the razzle build add_compile_options(/TP) # compile all files as C++ add_compile_options(/nologo) # Suppress Startup Banner add_compile_options(/W3) # set warning level to 3 add_compile_options(/WX) # treat warnings as errors add_compile_options(/Oi) # enable intrinsics add_compile_options(/Oy-) # disable suppressing of the creation of frame pointers on the call stack for quicker function calls - add_compile_options(/U_MT) # undefine the predefined _MT macro - add_compile_options(/GF) # enable read-only string pooling add_compile_options(/Gm-) # disable minimal rebuild add_compile_options(/Zp8) # pack structs on 8-byte boundary add_compile_options(/Gy) # separate functions for linker - add_compile_options(/Zc:wchar_t-) # C++ language conformance: wchar_t is NOT the native type, but a typedef - add_compile_options(/Zc:forScope) # C++ language conformance: enforce Standard C++ for scoping rules set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") # disable C++ RTTI add_compile_options(/FC) # use full pathnames in diagnostics add_compile_options(/MP) # Build with Multiple Processes (number of processes equal to the number of processors) - add_compile_options(/GS) # Buffer Security Check add_compile_options(/Zm200) # Specify Precompiled Header Memory Allocation Limit of 150MB + add_compile_options(/Zc:strictStrings) # Disable string-literal to char* or wchar_t* conversion add_compile_options(/wd4960 /wd4961 /wd4603 /wd4627 /wd4838 /wd4456 /wd4457 /wd4458 /wd4459 /wd4091 /we4640) From 8782d4ba80564f170286b1700e53028ccfb7355f Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 24 Jul 2020 15:48:32 -0700 Subject: [PATCH 042/755] Fix issues with JitStressRange (#39754) * Add 10 when digit is [a-fA-F] in ConfigMethodRange::InitRanges in utils.cpp * Zero out compMethodHashPrivate earlier in Compiler::compInit() in compiler.cpp --- src/coreclr/src/jit/compiler.cpp | 8 ++++---- src/coreclr/src/jit/utils.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index c78ee4477e0d..cb129b36c584 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -1764,6 +1764,10 @@ void Compiler::compInit(ArenaAllocator* pAlloc, info.compPerfScore = 0.0; #endif // defined(DEBUG) || defined(LATE_DISASM) +#if defined(DEBUG) || defined(INLINE_DATA) + info.compMethodHashPrivate = 0; +#endif // defined(DEBUG) || defined(INLINE_DATA) + #ifdef DEBUG // Opt-in to jit stress based on method hash ranges. // @@ -5287,10 +5291,6 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, verbose = compIsForInlining() ? impInlineInfo->InlinerCompiler->verbose : false; #endif -#if defined(DEBUG) || defined(INLINE_DATA) - info.compMethodHashPrivate = 0; -#endif // defined(DEBUG) || defined(INLINE_DATA) - #if FUNC_INFO_LOGGING LPCWSTR tmpJitFuncInfoFilename = JitConfig.JitFuncInfoFile(); diff --git a/src/coreclr/src/jit/utils.cpp b/src/coreclr/src/jit/utils.cpp index 4477ceb16295..36e901a0acc4 100644 --- a/src/coreclr/src/jit/utils.cpp +++ b/src/coreclr/src/jit/utils.cpp @@ -767,11 +767,11 @@ void ConfigMethodRange::InitRanges(const WCHAR* rangeStr, unsigned capacity) } else if ((L'A' <= *p) && (*p <= L'F')) { - n = (*p++) - L'A'; + n = (*p++) - L'A' + 10; } else if ((L'a' <= *p) && (*p <= L'f')) { - n = (*p++) - L'a'; + n = (*p++) - L'a' + 10; } int j = 16 * i + n; From ca9547949d8d9612d3dcff1babb001112b36fd93 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 24 Jul 2020 16:11:53 -0700 Subject: [PATCH 043/755] AnsiParser improvement (#39729) --- .../src/AnsiParser.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParser.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParser.cs index 665093b40866..bf2ee5f99c90 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParser.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Runtime.CompilerServices; namespace Microsoft.Extensions.Logging.Console { @@ -47,6 +48,7 @@ public void Parse(string message) { int startIndex = -1; int length = 0; + int escapeCode; ConsoleColor? foreground = null; ConsoleColor? background = null; var span = message.AsSpan(); @@ -59,12 +61,10 @@ public void Parse(string message) { if (span[i + 3] == 'm') { -#if NETCOREAPP - if (ushort.TryParse(span.Slice(i + 2, length: 1), out ushort escapeCode)) -#else - if (ushort.TryParse(span.Slice(i + 2, length: 1).ToString(), out ushort escapeCode)) -#endif + // Example: \x1B[1m + if (IsDigit(span[i + 2])) { + escapeCode = (int)(span[i + 2] - '0'); if (startIndex != -1) { _onParseWrite(message, startIndex, length, background, foreground); @@ -79,12 +79,10 @@ public void Parse(string message) } else if (span.Length >= i + 5 && span[i + 4] == 'm') { -#if NETCOREAPP - if (ushort.TryParse(span.Slice(i + 2, length: 2), out ushort escapeCode)) -#else - if (ushort.TryParse(span.Slice(i + 2, length: 2).ToString(), out ushort escapeCode)) -#endif + // Example: \x1B[40m + if (IsDigit(span[i + 2]) && IsDigit(span[i + 3])) { + escapeCode = (int)(span[i + 2] - '0') * 10 + (int)(span[i + 3] - '0'); if (startIndex != -1) { _onParseWrite(message, startIndex, length, background, foreground); @@ -128,6 +126,9 @@ public void Parse(string message) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsDigit(char c) => (uint)(c - '0') <= ('9' - '0'); + internal const string DefaultForegroundColor = "\x1B[39m\x1B[22m"; // reset to default foreground color internal const string DefaultBackgroundColor = "\x1B[49m"; // reset to the background color From 0e5614c1bcef4c744295c8ee4ddcd94a9ec8025a Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Sat, 25 Jul 2020 01:18:45 +0200 Subject: [PATCH 044/755] Nullable: System.Xml, part 5 (XmlDocument) (#39691) * Nullable: System.Xml, part 5 (XmlDocument) * apply feedback --- .../System/Xml/BinaryXml/XmlBinaryReader.cs | 4 +- .../src/System/Xml/Core/IDtdParser.cs | 2 +- .../src/System/Xml/Core/IRemovableWriter.cs | 2 +- .../Xml/Core/IValidationEventHandling.cs | 2 +- .../src/System/Xml/Core/QueryOutputWriter.cs | 2 +- .../System/Xml/Core/QueryOutputWriterV1.cs | 2 +- .../Xml/Core/ValidatingReaderNodeData.cs | 23 +- .../System/Xml/Core/XmlAsyncCheckReader.cs | 38 +-- .../System/Xml/Core/XmlAsyncCheckWriter.cs | 43 +-- .../System/Xml/Core/XmlAutoDetectWriter.cs | 48 ++-- .../System/Xml/Core/XmlCharCheckingReader.cs | 2 +- .../Xml/Core/XmlCharCheckingReaderAsync.cs | 4 +- .../System/Xml/Core/XmlCharCheckingWriter.cs | 79 +++-- .../Xml/Core/XmlCharCheckingWriterAsync.cs | 42 ++- .../src/System/Xml/Core/XmlRawWriterAsync.cs | 4 +- .../src/System/Xml/Core/XmlReader.cs | 6 +- .../src/System/Xml/Core/XmlSubtreeReader.cs | 4 +- .../src/System/Xml/Core/XmlTextReader.cs | 6 +- .../src/System/Xml/Core/XmlTextReaderImpl.cs | 10 +- .../src/System/Xml/Core/XmlTextWriter.cs | 2 +- .../System/Xml/Core/XmlValidatingReader.cs | 28 +- .../Xml/Core/XmlValidatingReaderImpl.cs | 127 ++++---- .../Xml/Core/XmlValidatingReaderImplAsync.cs | 11 +- .../System/Xml/Core/XmlWellFormedWriter.cs | 2 +- .../Xml/Core/XmlWellFormedWriterAsync.cs | 13 +- .../Xml/Core/XmlWellFormedWriterHelpers.cs | 42 ++- .../Core/XmlWellFormedWriterHelpersAsync.cs | 5 +- .../src/System/Xml/Core/XmlWrappingReader.cs | 4 +- .../src/System/Xml/Core/XmlWrappingWriter.cs | 25 +- .../System/Xml/Core/XmlWrappingWriterAsync.cs | 8 +- .../src/System/Xml/Core/XmlWriterAsync.cs | 8 +- .../src/System/Xml/Core/XmlWriterSettings.cs | 29 +- .../src/System/Xml/Core/XsdCachingReader.cs | 88 +++--- .../System/Xml/Core/XsdCachingReaderAsync.cs | 6 +- .../System/Xml/Core/XsdValidatingReader.cs | 2 +- .../System/Xml/Dom/DocumentSchemaValidator.cs | 210 +++++++------- .../src/System/Xml/Dom/DocumentXmlWriter.cs | 93 +++--- .../src/System/Xml/Dom/DomNameTable.cs | 6 +- .../src/System/Xml/Dom/XPathNodeList.cs | 11 +- .../src/System/Xml/Dom/XmlAttribute.cs | 58 ++-- .../System/Xml/Dom/XmlAttributeCollection.cs | 45 +-- .../src/System/Xml/Dom/XmlCDataSection.cs | 21 +- .../src/System/Xml/Dom/XmlCharacterData.cs | 53 ++-- .../src/System/Xml/Dom/XmlChildEnumerator.cs | 3 +- .../src/System/Xml/Dom/XmlChildNodes.cs | 10 +- .../src/System/Xml/Dom/XmlComment.cs | 7 +- .../src/System/Xml/Dom/XmlDeclaration.cs | 24 +- .../src/System/Xml/Dom/XmlDocument.cs | 228 ++++++++------- .../src/System/Xml/Dom/XmlDocumentFragment.cs | 20 +- .../src/System/Xml/Dom/XmlDocumentType.cs | 23 +- .../src/System/Xml/Dom/XmlDomTextWriter.cs | 17 +- .../src/System/Xml/Dom/XmlElement.cs | 87 +++--- .../src/System/Xml/Dom/XmlElementList.cs | 67 +++-- .../src/System/Xml/Dom/XmlEntity.cs | 21 +- .../src/System/Xml/Dom/XmlEntityReference.cs | 15 +- .../System/Xml/Dom/XmlEventChangedAction.cs | 1 + .../src/System/Xml/Dom/XmlImplementation.cs | 1 + .../src/System/Xml/Dom/XmlLinkedNode.cs | 19 +- .../src/System/Xml/Dom/XmlLoader.cs | 185 ++++++------ .../src/System/Xml/Dom/XmlName.cs | 41 +-- .../Dom/XmlNamedNodeMap.SmallXmlNodeList.cs | 21 +- .../src/System/Xml/Dom/XmlNamedNodemap.cs | 40 +-- .../src/System/Xml/Dom/XmlNode.cs | 270 ++++++++++-------- .../System/Xml/Dom/XmlNodeChangedEventArgs.cs | 23 +- .../Xml/Dom/XmlNodeChangedEventHandler.cs | 1 + .../src/System/Xml/Dom/XmlNodeList.cs | 5 +- .../src/System/Xml/Dom/XmlNodeReader.cs | 158 +++++----- .../src/System/Xml/Dom/XmlNotation.cs | 11 +- .../Xml/Dom/XmlProcessingInstruction.cs | 11 +- .../Xml/Dom/XmlSignificantWhiteSpace.cs | 22 +- .../src/System/Xml/Dom/XmlText.cs | 34 ++- .../System/Xml/Dom/XmlUnspecifiedAttribute.cs | 15 +- .../src/System/Xml/Dom/XmlWhitespace.cs | 24 +- .../Xml/Resolvers/XmlPreloadedResolver.cs | 32 ++- .../src/System/Xml/Schema/BaseValidator.cs | 8 +- .../src/System/Xml/Schema/DtdParser.cs | 4 +- .../src/System/Xml/Schema/DtdValidator.cs | 2 +- .../src/System/Xml/Schema/Parser.cs | 5 +- .../src/System/Xml/Schema/XdrValidator.cs | 4 +- .../System/Xml/Schema/XmlSchemaCollection.cs | 2 +- .../Schema/XmlSchemaValidationException.cs | 2 +- .../System/Xml/Schema/XmlSchemaValidator.cs | 14 +- .../src/System/Xml/Schema/XsdValidator.cs | 3 +- .../src/System/Xml/XmlCharType.cs | 4 +- .../src/System/Xml/XmlConvert.cs | 4 +- 85 files changed, 1542 insertions(+), 1166 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs index 664014a754e4..c7d02fafc839 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs @@ -670,7 +670,7 @@ public override int AttributeCount } } - public override string? GetAttribute(string name, string ns) + public override string? GetAttribute(string name, string? ns) { if (ScanState.XmlText == _state) { @@ -721,7 +721,7 @@ public override string GetAttribute(int i) } } - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { if (ScanState.XmlText == _state) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs index c9ddb2b57804..3f771d8f91a6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs @@ -10,6 +10,6 @@ namespace System.Xml internal partial interface IDtdParser { IDtdInfo ParseInternalDtd(IDtdParserAdapter adapter, bool saveInternalSubset); - IDtdInfo ParseFreeFloatingDtd(string baseUri, string docTypeName, string publicId, string systemId, string internalSubset, IDtdParserAdapter adapter); + IDtdInfo ParseFreeFloatingDtd(string baseUri, string docTypeName, string? publicId, string? systemId, string? internalSubset, IDtdParserAdapter adapter); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs index b3e837f56cac..c74dc5235133 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs @@ -17,6 +17,6 @@ namespace System.Xml /// internal interface IRemovableWriter { - OnRemoveWriter OnRemoveWriterEvent { get; set; } + OnRemoveWriter? OnRemoveWriterEvent { get; set; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs index a19645a8fbb1..57ce91b8a129 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs @@ -10,7 +10,7 @@ namespace System.Xml internal interface IValidationEventHandling { // This is a ValidationEventHandler, but it is not strongly typed due to dependencies on System.Xml.Schema - object EventHandler { get; } + object? EventHandler { get; } // The exception is XmlSchemaException, but it is not strongly typed due to dependencies on System.Xml.Schema void SendEvent(Exception exception, XmlSeverityType severity); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs index 9c631ed9d5a3..6cced37f2300 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs @@ -31,7 +31,7 @@ internal class QueryOutputWriter : XmlRawWriter private readonly bool _checkWellFormedDoc; private bool _hasDocElem; private bool _inAttr; - private readonly string _systemId, _publicId; + private readonly string? _systemId, _publicId; private int _depth; public QueryOutputWriter(XmlRawWriter writer, XmlWriterSettings settings) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs index 8dd3f70992b2..527c893952fd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs @@ -29,7 +29,7 @@ internal class QueryOutputWriterV1 : XmlWriter private readonly BitStack? _bitsCData; private readonly XmlQualifiedName? _qnameCData; private bool _outputDocType, _inAttr; - private readonly string _systemId, _publicId; + private readonly string? _systemId, _publicId; public QueryOutputWriterV1(XmlWriter writer, XmlWriterSettings settings) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidatingReaderNodeData.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidatingReaderNodeData.cs index 89c7c608ca78..c58e0ec9f40b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidatingReaderNodeData.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidatingReaderNodeData.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. +#nullable enable using System; using System.IO; using System.Text; @@ -8,6 +9,7 @@ using System.Xml.Schema; using System.Diagnostics; using System.Globalization; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -16,12 +18,12 @@ internal class ValidatingReaderNodeData private string _localName; private string _namespaceUri; private string _prefix; - private string _nameWPrefix; + private string? _nameWPrefix; private string _rawValue; - private string _originalStringValue; // Original value + private string? _originalStringValue; // Original value private int _depth; - private AttributePSVIInfo _attributePSVIInfo; //Used only for default attributes + private AttributePSVIInfo? _attributePSVIInfo; //Used only for default attributes private XmlNodeType _nodeType; private int _lineNo; @@ -86,6 +88,7 @@ public string GetAtomizedNameWPrefix(XmlNameTable nameTable) _nameWPrefix = nameTable.Add(string.Concat(_prefix, ":", _localName)); } } + return _nameWPrefix; } @@ -113,7 +116,7 @@ public string RawValue } } - public string OriginalStringValue + public string? OriginalStringValue { get { @@ -137,7 +140,7 @@ public XmlNodeType NodeType } } - public AttributePSVIInfo AttInfo + public AttributePSVIInfo? AttInfo { get { @@ -165,6 +168,10 @@ public int LinePosition } } + [MemberNotNull(nameof(_localName))] + [MemberNotNull(nameof(_prefix))] + [MemberNotNull(nameof(_namespaceUri))] + [MemberNotNull(nameof(_rawValue))] internal void Clear(XmlNodeType nodeType) { _nodeType = nodeType; @@ -172,10 +179,12 @@ internal void Clear(XmlNodeType nodeType) _prefix = string.Empty; _namespaceUri = string.Empty; _rawValue = string.Empty; + if (_attributePSVIInfo != null) { _attributePSVIInfo.Reset(); } + _nameWPrefix = null; _lineNo = 0; _linePos = 0; @@ -187,7 +196,7 @@ internal void SetLineInfo(int lineNo, int linePos) _linePos = linePos; } - internal void SetLineInfo(IXmlLineInfo lineInfo) + internal void SetLineInfo(IXmlLineInfo? lineInfo) { if (lineInfo != null) { @@ -210,7 +219,7 @@ internal void SetItemData(string value) SetItemData(value, value); } - internal void SetItemData(string value, string originalStringValue) + internal void SetItemData(string value, string? originalStringValue) { _rawValue = value; _originalStringValue = originalStringValue; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckReader.cs index 1531deab96ac..752e156d1a23 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckReader.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -64,7 +65,7 @@ public override XmlReaderSettings Settings { get { - XmlReaderSettings settings = _coreReader.Settings; + XmlReaderSettings? settings = _coreReader.Settings; if (null != settings) { settings = settings.Clone(); @@ -151,7 +152,7 @@ public override int Depth } } - public override string BaseURI + public override string? BaseURI { get { @@ -205,7 +206,7 @@ public override string XmlLang } } - public override IXmlSchemaInfo SchemaInfo + public override IXmlSchemaInfo? SchemaInfo { get { @@ -418,13 +419,13 @@ public override int AttributeCount } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { CheckAsync(); return _coreReader.GetAttribute(name); } - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { CheckAsync(); return _coreReader.GetAttribute(name, namespaceURI); @@ -445,7 +446,7 @@ public override string this[int i] } } - public override string this[string name] + public override string? this[string name] { get { @@ -460,7 +461,7 @@ public override bool MoveToAttribute(string name) return _coreReader.MoveToAttribute(name); } - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { CheckAsync(); return _coreReader.MoveToAttribute(name, ns); @@ -541,7 +542,7 @@ public override XmlNameTable NameTable } } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { CheckAsync(); return _coreReader.LookupNamespace(prefix); @@ -754,7 +755,7 @@ protected override void Dispose(bool disposing) _coreReader.Dispose(); } - internal override XmlNamespaceManager NamespaceManager + internal override XmlNamespaceManager? NamespaceManager { get { @@ -763,7 +764,7 @@ internal override XmlNamespaceManager NamespaceManager } } - internal override IDtdInfo DtdInfo + internal override IDtdInfo? DtdInfo { get { @@ -930,12 +931,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return _readerAsIXmlNamespaceResolver.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _readerAsIXmlNamespaceResolver.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _readerAsIXmlNamespaceResolver.LookupPrefix(namespaceName); } @@ -992,12 +993,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return _readerAsIXmlNamespaceResolver.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _readerAsIXmlNamespaceResolver.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _readerAsIXmlNamespaceResolver.LookupPrefix(namespaceName); } @@ -1014,7 +1015,6 @@ public XmlAsyncCheckReaderWithLineInfoNSSchema(XmlReader reader) _readerAsIXmlSchemaInfo = (IXmlSchemaInfo)reader; } - #region IXmlSchemaInfo members XmlSchemaValidity IXmlSchemaInfo.Validity @@ -1041,7 +1041,7 @@ bool IXmlSchemaInfo.IsNil } } - XmlSchemaSimpleType IXmlSchemaInfo.MemberType + XmlSchemaSimpleType? IXmlSchemaInfo.MemberType { get { @@ -1049,7 +1049,7 @@ XmlSchemaSimpleType IXmlSchemaInfo.MemberType } } - XmlSchemaType IXmlSchemaInfo.SchemaType + XmlSchemaType? IXmlSchemaInfo.SchemaType { get { @@ -1057,7 +1057,7 @@ XmlSchemaType IXmlSchemaInfo.SchemaType } } - XmlSchemaElement IXmlSchemaInfo.SchemaElement + XmlSchemaElement? IXmlSchemaInfo.SchemaElement { get { @@ -1065,7 +1065,7 @@ XmlSchemaElement IXmlSchemaInfo.SchemaElement } } - XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute + XmlSchemaAttribute? IXmlSchemaInfo.SchemaAttribute { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckWriter.cs index 666fd5487a17..84990c82955e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAsyncCheckWriter.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. +#nullable enable using System.Threading.Tasks; using System.Xml.XPath; @@ -38,7 +39,7 @@ public override XmlWriterSettings Settings { get { - XmlWriterSettings settings = _coreWriter.Settings; + XmlWriterSettings? settings = _coreWriter.Settings; if (null != settings) { @@ -74,13 +75,13 @@ public override void WriteEndDocument() _coreWriter.WriteEndDocument(); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { CheckAsync(); _coreWriter.WriteDocType(name, pubid, sysid, subset); } - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { CheckAsync(); _coreWriter.WriteStartElement(prefix, localName, ns); @@ -98,7 +99,7 @@ public override void WriteFullEndElement() _coreWriter.WriteFullEndElement(); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { CheckAsync(); _coreWriter.WriteStartAttribute(prefix, localName, ns); @@ -110,19 +111,19 @@ public override void WriteEndAttribute() _coreWriter.WriteEndAttribute(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { CheckAsync(); _coreWriter.WriteCData(text); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { CheckAsync(); _coreWriter.WriteComment(text); } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { CheckAsync(); _coreWriter.WriteProcessingInstruction(name, text); @@ -140,13 +141,13 @@ public override void WriteCharEntity(char ch) _coreWriter.WriteCharEntity(ch); } - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { CheckAsync(); _coreWriter.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { CheckAsync(); _coreWriter.WriteString(text); @@ -209,7 +210,7 @@ public override void Flush() _coreWriter.Flush(); } - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { CheckAsync(); return _coreWriter.LookupPrefix(ns); @@ -224,7 +225,7 @@ public override XmlSpace XmlSpace } } - public override string XmlLang + public override string? XmlLang { get { @@ -245,7 +246,7 @@ public override void WriteName(string name) _coreWriter.WriteName(name); } - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { CheckAsync(); _coreWriter.WriteQualifiedName(localName, ns); @@ -257,7 +258,7 @@ public override void WriteValue(object value) _coreWriter.WriteValue(value); } - public override void WriteValue(string value) + public override void WriteValue(string? value) { CheckAsync(); _coreWriter.WriteValue(value); @@ -368,7 +369,7 @@ public override Task WriteEndDocumentAsync() return task; } - public override Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset) + public override Task WriteDocTypeAsync(string name, string? pubid, string? sysid, string? subset) { CheckAsync(); var task = _coreWriter.WriteDocTypeAsync(name, pubid, sysid, subset); @@ -376,7 +377,7 @@ public override Task WriteDocTypeAsync(string name, string pubid, string sysid, return task; } - public override Task WriteStartElementAsync(string prefix, string localName, string ns) + public override Task WriteStartElementAsync(string? prefix, string localName, string? ns) { CheckAsync(); var task = _coreWriter.WriteStartElementAsync(prefix, localName, ns); @@ -400,7 +401,7 @@ public override Task WriteFullEndElementAsync() return task; } - protected internal override Task WriteStartAttributeAsync(string prefix, string localName, string ns) + protected internal override Task WriteStartAttributeAsync(string? prefix, string localName, string? ns) { CheckAsync(); var task = _coreWriter.WriteStartAttributeAsync(prefix, localName, ns); @@ -416,7 +417,7 @@ protected internal override Task WriteEndAttributeAsync() return task; } - public override Task WriteCDataAsync(string text) + public override Task WriteCDataAsync(string? text) { CheckAsync(); var task = _coreWriter.WriteCDataAsync(text); @@ -424,7 +425,7 @@ public override Task WriteCDataAsync(string text) return task; } - public override Task WriteCommentAsync(string text) + public override Task WriteCommentAsync(string? text) { CheckAsync(); var task = _coreWriter.WriteCommentAsync(text); @@ -456,7 +457,7 @@ public override Task WriteCharEntityAsync(char ch) return task; } - public override Task WriteWhitespaceAsync(string ws) + public override Task WriteWhitespaceAsync(string? ws) { CheckAsync(); var task = _coreWriter.WriteWhitespaceAsync(ws); @@ -464,7 +465,7 @@ public override Task WriteWhitespaceAsync(string ws) return task; } - public override Task WriteStringAsync(string text) + public override Task WriteStringAsync(string? text) { CheckAsync(); var task = _coreWriter.WriteStringAsync(text); @@ -544,7 +545,7 @@ public override Task WriteNameAsync(string name) return task; } - public override Task WriteQualifiedNameAsync(string localName, string ns) + public override Task WriteQualifiedNameAsync(string localName, string? ns) { CheckAsync(); var task = _coreWriter.WriteQualifiedNameAsync(localName, ns); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs index c4cf2e9da9ca..c3aa8c0d97bd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml { using System; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; using System.Xml; @@ -17,12 +19,12 @@ namespace System.Xml /// internal class XmlAutoDetectWriter : XmlRawWriter, IRemovableWriter { - private XmlRawWriter _wrapped; - private OnRemoveWriter _onRemove; + private XmlRawWriter? _wrapped; + private OnRemoveWriter? _onRemove; private readonly XmlWriterSettings _writerSettings; private readonly XmlEventCache _eventCache; // Cache up events until first StartElement is encountered - private readonly TextWriter _textWriter; - private readonly Stream _strm; + private readonly TextWriter? _textWriter; + private readonly Stream? _strm; //----------------------------------------------- // Constructors @@ -59,7 +61,7 @@ public XmlAutoDetectWriter(Stream strm, XmlWriterSettings writerSettings) /// /// This writer will raise this event once it has determined whether to replace itself with the Html or Xml writer. /// - public OnRemoveWriter OnRemoveWriterEvent + public OnRemoveWriter? OnRemoveWriterEvent { get { return _onRemove; } set { _onRemove = value; } @@ -75,26 +77,27 @@ public override XmlWriterSettings Settings get { return _writerSettings; } } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { EnsureWrappedWriter(XmlOutputMethod.Xml); _wrapped.WriteDocType(name, pubid, sysid, subset); } - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { if (_wrapped == null) { // This is the first time WriteStartElement has been called, so create the Xml or Html writer - if (ns.Length == 0 && IsHtmlTag(localName)) + if (ns!.Length == 0 && IsHtmlTag(localName)) CreateWrappedWriter(XmlOutputMethod.Html); else CreateWrappedWriter(XmlOutputMethod.Xml); } + _wrapped.WriteStartElement(prefix, localName, ns); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { EnsureWrappedWriter(XmlOutputMethod.Xml); _wrapped.WriteStartAttribute(prefix, localName, ns); @@ -106,7 +109,7 @@ public override void WriteEndAttribute() _wrapped.WriteEndAttribute(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { if (TextBlockCreatesWriter(text)) _wrapped.WriteCData(text); @@ -114,7 +117,7 @@ public override void WriteCData(string text) _eventCache.WriteCData(text); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { if (_wrapped == null) _eventCache.WriteComment(text); @@ -122,7 +125,7 @@ public override void WriteComment(string text) _wrapped.WriteComment(text); } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { if (_wrapped == null) _eventCache.WriteProcessingInstruction(name, text); @@ -130,7 +133,7 @@ public override void WriteProcessingInstruction(string name, string text) _wrapped.WriteProcessingInstruction(name, text); } - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { if (_wrapped == null) _eventCache.WriteWhitespace(ws); @@ -138,7 +141,7 @@ public override void WriteWhitespace(string ws) _wrapped.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (TextBlockCreatesWriter(text)) _wrapped.WriteString(text); @@ -214,7 +217,7 @@ public override void WriteValue(object value) _wrapped.WriteValue(value); } - public override void WriteValue(string value) + public override void WriteValue(string? value) { EnsureWrappedWriter(XmlOutputMethod.Xml); _wrapped.WriteValue(value); @@ -272,7 +275,7 @@ public override void WriteValue(long value) // XmlRawWriter interface //----------------------------------------------- - internal override IXmlNamespaceResolver NamespaceResolver + internal override IXmlNamespaceResolver? NamespaceResolver { get { @@ -331,7 +334,7 @@ internal override bool SupportsNamespaceDeclarationInChunks { get { - return _wrapped.SupportsNamespaceDeclarationInChunks; + return _wrapped!.SupportsNamespaceDeclarationInChunks; } } @@ -343,7 +346,7 @@ internal override void WriteStartNamespaceDeclaration(string prefix) internal override void WriteEndNamespaceDeclaration() { - _wrapped.WriteEndNamespaceDeclaration(); + _wrapped!.WriteEndNamespaceDeclaration(); } //----------------------------------------------- @@ -376,6 +379,7 @@ private static bool IsHtmlTag(string tagName) /// /// If a wrapped writer has not yet been created, create one. /// + [MemberNotNull(nameof(_wrapped))] private void EnsureWrappedWriter(XmlOutputMethod outMethod) { if (_wrapped == null) @@ -387,7 +391,8 @@ private void EnsureWrappedWriter(XmlOutputMethod outMethod) /// force the creation of a wrapped writer. Otherwise, create a wrapped writer if one has not yet been /// created and return true. /// - private bool TextBlockCreatesWriter(string textBlock) + [MemberNotNullWhen(true, nameof(_wrapped))] + private bool TextBlockCreatesWriter(string? textBlock) { if (_wrapped == null) { @@ -407,6 +412,7 @@ private bool TextBlockCreatesWriter(string textBlock) /// /// Create either the Html or Xml writer and send any cached events to it. /// + [MemberNotNull(nameof(_wrapped))] private void CreateWrappedWriter(XmlOutputMethod outMethod) { Debug.Assert(_wrapped == null); @@ -422,9 +428,9 @@ private void CreateWrappedWriter(XmlOutputMethod outMethod) _writerSettings.ReadOnly = true; if (_textWriter != null) - _wrapped = ((XmlWellFormedWriter)XmlWriter.Create(_textWriter, _writerSettings)).RawWriter; + _wrapped = ((XmlWellFormedWriter)XmlWriter.Create(_textWriter, _writerSettings)).RawWriter!; else - _wrapped = ((XmlWellFormedWriter)XmlWriter.Create(_strm, _writerSettings)).RawWriter; + _wrapped = ((XmlWellFormedWriter)XmlWriter.Create(_strm!, _writerSettings)).RawWriter!; // Send cached events to the new writer _eventCache.EndEvents(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReader.cs index 7dadd488d0df..ca0ce55d013b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReader.cs @@ -119,7 +119,7 @@ public override bool MoveToAttribute(string name) return base.reader.MoveToAttribute(name); } - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { if (_state == State.InReadBinary) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReaderAsync.cs index 387d182dc21c..68f79ba17a16 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingReaderAsync.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. +#nullable enable using System; using System.Xml; using System.Diagnostics; @@ -162,8 +163,7 @@ public override async Task ReadAsync() ValidateQName(base.reader.Name); CheckCharacters(base.reader.Value); - string str; - str = base.reader.GetAttribute("SYSTEM"); + string? str = base.reader.GetAttribute("SYSTEM"); if (str != null) { CheckCharacters(str); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriter.cs index e8f8fad07073..2fa82a671869 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriter.cs @@ -1,12 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.IO; using System.Text; using System.Xml.Schema; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -50,30 +52,33 @@ public override XmlWriterSettings Settings { get { - XmlWriterSettings s = base.writer.Settings; + XmlWriterSettings? s = base.writer.Settings; s = (s != null) ? (XmlWriterSettings)s.Clone() : new XmlWriterSettings(); if (_checkValues) { s.CheckCharacters = true; } + if (_replaceNewLines) { s.NewLineHandling = NewLineHandling.Replace; s.NewLineChars = _newLineChars; } + s.ReadOnly = true; return s; } } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { if (_checkNames) { ValidateQName(name); } + if (_checkValues) { if (pubid != null) @@ -84,25 +89,29 @@ public override void WriteDocType(string name, string pubid, string sysid, strin throw XmlConvert.CreateInvalidCharException(pubid, i); } } + if (sysid != null) { CheckCharacters(sysid); } + if (subset != null) { CheckCharacters(subset); } } + if (_replaceNewLines) { sysid = ReplaceNewLines(sysid); pubid = ReplaceNewLines(pubid); subset = ReplaceNewLines(subset); } + writer.WriteDocType(name, pubid, sysid, subset); } - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { if (_checkNames) { @@ -110,6 +119,7 @@ public override void WriteStartElement(string prefix, string localName, string n { throw new ArgumentException(SR.Xml_EmptyLocalName); } + ValidateNCName(localName); if (prefix != null && prefix.Length > 0) @@ -117,10 +127,11 @@ public override void WriteStartElement(string prefix, string localName, string n ValidateNCName(prefix); } } + writer.WriteStartElement(prefix, localName, ns); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { if (_checkNames) { @@ -128,6 +139,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { throw new ArgumentException(SR.Xml_EmptyLocalName); } + ValidateNCName(localName); if (prefix != null && prefix.Length > 0) @@ -135,10 +147,11 @@ public override void WriteStartAttribute(string prefix, string localName, string ValidateNCName(prefix); } } + writer.WriteStartAttribute(prefix, localName, ns); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { if (text != null) { @@ -146,10 +159,12 @@ public override void WriteCData(string text) { CheckCharacters(text); } + if (_replaceNewLines) { text = ReplaceNewLines(text); } + int i; while ((i = text.IndexOf("]]>", StringComparison.Ordinal)) >= 0) { @@ -160,7 +175,7 @@ public override void WriteCData(string text) writer.WriteCData(text); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { if (text != null) { @@ -169,20 +184,23 @@ public override void WriteComment(string text) CheckCharacters(text); text = InterleaveInvalidChars(text, '-', '-'); } + if (_replaceNewLines) { text = ReplaceNewLines(text); } } + writer.WriteComment(text); } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { if (_checkNames) { ValidateNCName(name); } + if (text != null) { if (_checkValues) @@ -190,11 +208,13 @@ public override void WriteProcessingInstruction(string name, string text) CheckCharacters(text); text = InterleaveInvalidChars(text, '?', '>'); } + if (_replaceNewLines) { text = ReplaceNewLines(text); } } + writer.WriteProcessingInstruction(name, text); } @@ -204,15 +224,17 @@ public override void WriteEntityRef(string name) { ValidateQName(name); } + writer.WriteEntityRef(name); } - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { if (ws == null) { ws = string.Empty; } + // "checkNames" is intentional here; if false, the whitespace is checked in XmlWellformedWriter if (_checkNames) { @@ -222,14 +244,16 @@ public override void WriteWhitespace(string ws) throw new ArgumentException(SR.Format(SR.Xml_InvalidWhitespaceCharacter, XmlException.BuildCharExceptionArgs(ws, i))); } } + if (_replaceNewLines) { ws = ReplaceNewLines(ws); } + writer.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (text != null) { @@ -242,6 +266,7 @@ public override void WriteString(string text) text = ReplaceNewLines(text); } } + writer.WriteString(text); } @@ -273,15 +298,17 @@ public override void WriteChars(char[] buffer, int index, int count) { CheckCharacters(buffer, index, count); } + if (_replaceNewLines && WriteState != WriteState.Attribute) { - string text = ReplaceNewLines(buffer, index, count); + string? text = ReplaceNewLines(buffer, index, count); if (text != null) { WriteString(text); return; } } + writer.WriteChars(buffer, index, count); } @@ -293,8 +320,10 @@ public override void WriteNmToken(string name) { throw new ArgumentException(SR.Xml_EmptyName); } + XmlConvert.VerifyNMTOKEN(name); } + writer.WriteNmToken(name); } @@ -304,15 +333,17 @@ public override void WriteName(string name) { XmlConvert.VerifyQName(name, ExceptionType.XmlException); } + writer.WriteName(name); } - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { if (_checkNames) { ValidateNCName(localName); } + writer.WriteQualifiedName(localName, ns); } @@ -349,6 +380,7 @@ private void ValidateQName(string name) { throw new ArgumentException(SR.Xml_EmptyName); } + int colonPos; int len = ValidateNames.ParseQName(name, 0, out colonPos); if (len != name.Length) @@ -358,14 +390,15 @@ private void ValidateQName(string name) } } - private string ReplaceNewLines(string str) + [return: NotNullIfNotNull("str")] + private string? ReplaceNewLines(string? str) { if (str == null) { return null; } - StringBuilder sb = null; + StringBuilder? sb = null; int start = 0; int i; for (i = 0; i < str.Length; i++) @@ -396,10 +429,12 @@ private string ReplaceNewLines(string str) i++; continue; } + if (sb == null) { sb = new StringBuilder(str.Length + 5); } + sb.Append(str, start, i - start); i++; } @@ -409,10 +444,12 @@ private string ReplaceNewLines(string str) { continue; } + if (sb == null) { sb = new StringBuilder(str.Length + 5); } + sb.Append(str, start, i - start); } } @@ -435,14 +472,14 @@ private string ReplaceNewLines(string str) } } - private string ReplaceNewLines(char[] data, int offset, int len) + private string? ReplaceNewLines(char[]? data, int offset, int len) { if (data == null) { return null; } - StringBuilder sb = null; + StringBuilder? sb = null; int start = offset; int endPos = offset + len; int i; @@ -453,16 +490,19 @@ private string ReplaceNewLines(char[] data, int offset, int len) { continue; } + if (ch == '\n') { if (_newLineChars == "\n") { continue; } + if (sb == null) { sb = new StringBuilder(len + 5); } + sb.Append(data, start, i - start); } else if (ch == '\r') @@ -474,10 +514,12 @@ private string ReplaceNewLines(char[] data, int offset, int len) i++; continue; } + if (sb == null) { sb = new StringBuilder(len + 5); } + sb.Append(data, start, i - start); i++; } @@ -487,10 +529,12 @@ private string ReplaceNewLines(char[] data, int offset, int len) { continue; } + if (sb == null) { sb = new StringBuilder(len + 5); } + sb.Append(data, start, i - start); } } @@ -498,6 +542,7 @@ private string ReplaceNewLines(char[] data, int offset, int len) { continue; } + sb.Append(_newLineChars); start = i + 1; } @@ -518,7 +563,7 @@ private string ReplaceNewLines(char[] data, int offset, int len) // Any "?>" in PI value must be replaced with "? >". private string InterleaveInvalidChars(string text, char invChar1, char invChar2) { - StringBuilder sb = null; + StringBuilder? sb = null; int start = 0; int i; for (i = 0; i < text.Length; i++) @@ -533,6 +578,7 @@ private string InterleaveInvalidChars(string text, char invChar1, char invChar2) { sb = new StringBuilder(text.Length + 5); } + sb.Append(text, start, i - start); sb.Append(' '); start = i; @@ -551,6 +597,7 @@ private string InterleaveInvalidChars(string text, char invChar1, char invChar2) { sb.Append(' '); } + return sb.ToString(); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriterAsync.cs index 722d1d7226cb..4b5a0e961fbf 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlCharCheckingWriterAsync.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. +#nullable enable using System; using System.IO; using System.Text; @@ -17,12 +18,13 @@ namespace System.Xml // internal partial class XmlCharCheckingWriter : XmlWrappingWriter { - public override Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset) + public override Task WriteDocTypeAsync(string name, string? pubid, string? sysid, string? subset) { if (_checkNames) { ValidateQName(name); } + if (_checkValues) { if (pubid != null) @@ -33,25 +35,29 @@ public override Task WriteDocTypeAsync(string name, string pubid, string sysid, throw XmlConvert.CreateInvalidCharException(pubid, i); } } + if (sysid != null) { CheckCharacters(sysid); } + if (subset != null) { CheckCharacters(subset); } } + if (_replaceNewLines) { sysid = ReplaceNewLines(sysid); pubid = ReplaceNewLines(pubid); subset = ReplaceNewLines(subset); } + return writer.WriteDocTypeAsync(name, pubid, sysid, subset); } - public override Task WriteStartElementAsync(string prefix, string localName, string ns) + public override Task WriteStartElementAsync(string? prefix, string localName, string? ns) { if (_checkNames) { @@ -59,6 +65,7 @@ public override Task WriteStartElementAsync(string prefix, string localName, str { throw new ArgumentException(SR.Xml_EmptyLocalName); } + ValidateNCName(localName); if (prefix != null && prefix.Length > 0) @@ -69,7 +76,7 @@ public override Task WriteStartElementAsync(string prefix, string localName, str return writer.WriteStartElementAsync(prefix, localName, ns); } - protected internal override Task WriteStartAttributeAsync(string prefix, string localName, string ns) + protected internal override Task WriteStartAttributeAsync(string? prefix, string localName, string? ns) { if (_checkNames) { @@ -77,6 +84,7 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string { throw new ArgumentException(SR.Xml_EmptyLocalName); } + ValidateNCName(localName); if (prefix != null && prefix.Length > 0) @@ -84,10 +92,11 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string ValidateNCName(prefix); } } + return writer.WriteStartAttributeAsync(prefix, localName, ns); } - public override async Task WriteCDataAsync(string text) + public override async Task WriteCDataAsync(string? text) { if (text != null) { @@ -95,10 +104,12 @@ public override async Task WriteCDataAsync(string text) { CheckCharacters(text); } + if (_replaceNewLines) { text = ReplaceNewLines(text); } + int i; while ((i = text.IndexOf("]]>", StringComparison.Ordinal)) >= 0) { @@ -106,10 +117,11 @@ public override async Task WriteCDataAsync(string text) text = text.Substring(i + 2); } } + await writer.WriteCDataAsync(text).ConfigureAwait(false); } - public override Task WriteCommentAsync(string text) + public override Task WriteCommentAsync(string? text) { if (text != null) { @@ -132,6 +144,7 @@ public override Task WriteProcessingInstructionAsync(string name, string text) { ValidateNCName(name); } + if (text != null) { if (_checkValues) @@ -144,7 +157,8 @@ public override Task WriteProcessingInstructionAsync(string name, string text) text = ReplaceNewLines(text); } } - return writer.WriteProcessingInstructionAsync(name, text); + + return writer.WriteProcessingInstructionAsync(name, text!); } public override Task WriteEntityRefAsync(string name) @@ -156,12 +170,13 @@ public override Task WriteEntityRefAsync(string name) return writer.WriteEntityRefAsync(name); } - public override Task WriteWhitespaceAsync(string ws) + public override Task WriteWhitespaceAsync(string? ws) { if (ws == null) { ws = string.Empty; } + // "checkNames" is intentional here; if false, the whitespace is checked in XmlWellformedWriter if (_checkNames) { @@ -171,14 +186,16 @@ public override Task WriteWhitespaceAsync(string ws) throw new ArgumentException(SR.Format(SR.Xml_InvalidWhitespaceCharacter, XmlException.BuildCharExceptionArgs(ws, i))); } } + if (_replaceNewLines) { ws = ReplaceNewLines(ws); } + return writer.WriteWhitespaceAsync(ws); } - public override Task WriteStringAsync(string text) + public override Task WriteStringAsync(string? text) { if (text != null) { @@ -186,11 +203,13 @@ public override Task WriteStringAsync(string text) { CheckCharacters(text); } + if (_replaceNewLines && WriteState != WriteState.Attribute) { text = ReplaceNewLines(text); } } + return writer.WriteStringAsync(text); } @@ -222,14 +241,16 @@ public override Task WriteCharsAsync(char[] buffer, int index, int count) { CheckCharacters(buffer, index, count); } + if (_replaceNewLines && WriteState != WriteState.Attribute) { - string text = ReplaceNewLines(buffer, index, count); + string? text = ReplaceNewLines(buffer, index, count); if (text != null) { return WriteStringAsync(text); } } + return writer.WriteCharsAsync(buffer, index, count); } @@ -255,12 +276,13 @@ public override Task WriteNameAsync(string name) return writer.WriteNameAsync(name); } - public override Task WriteQualifiedNameAsync(string localName, string ns) + public override Task WriteQualifiedNameAsync(string localName, string? ns) { if (_checkNames) { ValidateNCName(localName); } + return writer.WriteQualifiedNameAsync(localName, ns); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs index 7456b4457e16..fe8091cc64eb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs @@ -107,7 +107,7 @@ public override Task WriteQualifiedNameAsync(string localName, string? ns) } // Forward call to WriteString(string). - public override Task WriteCDataAsync(string text) + public override Task WriteCDataAsync(string? text) { return WriteStringAsync(text); } @@ -126,7 +126,7 @@ public override Task WriteSurrogateCharEntityAsync(char lowChar, char highChar) } // Forward call to WriteString(string). - public override Task WriteWhitespaceAsync(string ws) + public override Task WriteWhitespaceAsync(string? ws) { return WriteStringAsync(ws); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs index 258f4b5bcb54..36abf85f126c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs @@ -620,7 +620,7 @@ public virtual object ReadElementContentAs(Type returnType, IXmlNamespaceResolve public abstract string? GetAttribute(string name); // Gets the value of the attribute with the LocalName and NamespaceURI - public abstract string? GetAttribute(string name, string namespaceURI); + public abstract string? GetAttribute(string name, string? namespaceURI); // Gets the value of the attribute with the specified index. public abstract string GetAttribute(int i); @@ -644,7 +644,7 @@ public virtual string? this[string name] } // Gets the value of the attribute with the LocalName and NamespaceURI - public virtual string? this[string name, string namespaceURI] + public virtual string? this[string name, string? namespaceURI] { get { @@ -656,7 +656,7 @@ public virtual string? this[string name] public abstract bool MoveToAttribute(string name); // Moves to the attribute with the specified LocalName and NamespaceURI. - public abstract bool MoveToAttribute(string name, string ns); + public abstract bool MoveToAttribute(string name, string? ns); // Moves to the attribute with the specified index. public virtual void MoveToAttribute(int i) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs index 5d7f5dbf79f2..d00bc27d68c6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs @@ -265,7 +265,7 @@ public override int AttributeCount return null; } - public override string? GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { if (!InAttributeActiveState) { @@ -334,7 +334,7 @@ public override bool MoveToAttribute(string name) return false; } - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { if (!InAttributeActiveState) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs index 5e1b4d9e003d..48598298580f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs @@ -83,13 +83,13 @@ public XmlTextReader(string url, TextReader input, XmlNameTable nt) _impl.OuterReader = this; } - public XmlTextReader(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context) + public XmlTextReader(Stream xmlFragment, XmlNodeType fragType, XmlParserContext? context) { _impl = new XmlTextReaderImpl(xmlFragment, fragType, context); _impl.OuterReader = this; } - public XmlTextReader(string xmlFragment, XmlNodeType fragType, XmlParserContext context) + public XmlTextReader(string xmlFragment, XmlNodeType fragType, XmlParserContext? context) { _impl = new XmlTextReaderImpl(xmlFragment, fragType, context); _impl.OuterReader = this; @@ -203,7 +203,7 @@ public override bool MoveToAttribute(string name) return _impl.MoveToAttribute(name); } - public override bool MoveToAttribute(string localName, string namespaceURI) + public override bool MoveToAttribute(string localName, string? namespaceURI) { return _impl.MoveToAttribute(localName, namespaceURI); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index 4a959c251118..32c82f72dc7e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -506,7 +506,7 @@ internal XmlTextReaderImpl(string? url, TextReader input, XmlNameTable nt) : thi // Initializes a new instance of XmlTextReaderImpl class for parsing fragments with the specified stream, fragment type and parser context // This constructor is used when creating XmlTextReaderImpl for V1 XmlTextReader // SxS: The method resolves URI but does not expose the resolved value up the stack hence Resource Exposure scope is None. - internal XmlTextReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context) + internal XmlTextReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserContext? context) : this((context != null && context.NameTable != null) ? context.NameTable : new NameTable()) { Encoding? enc = (context != null) ? context.Encoding : null; @@ -529,7 +529,7 @@ internal XmlTextReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserCo // Initializes a new instance of XmlTextRreaderImpl class for parsing fragments with the specified string, fragment type and parser context // This constructor is used when creating XmlTextReaderImpl for V1 XmlTextReader - internal XmlTextReaderImpl(string xmlFragment, XmlNodeType fragType, XmlParserContext context) + internal XmlTextReaderImpl(string xmlFragment, XmlNodeType fragType, XmlParserContext? context) : this(null == context || null == context.NameTable ? new NameTable() : context.NameTable) { if (xmlFragment == null) @@ -556,7 +556,7 @@ internal XmlTextReaderImpl(string xmlFragment, XmlNodeType fragType, XmlParserCo // "innerXml" of an XmlDecl is. This internal function is required by DOM. When(if) we handle/allow // all nodetypes in InnerXml then we should support them as part of fragment constructor as well. // Until then, this internal function will have to do. - internal XmlTextReaderImpl(string xmlFragment, XmlParserContext context) + internal XmlTextReaderImpl(string xmlFragment, XmlParserContext? context) : this(null == context || null == context.NameTable ? new NameTable() : context.NameTable) { InitStringInput((context == null) ? string.Empty : context.BaseURI, Encoding.Unicode, string.Concat("")); @@ -821,7 +821,7 @@ private void FinishInitTextReader() // Initializes a new instance of the XmlTextReaderImpl class for fragment parsing. // This constructor is used by XmlBinaryReader for nested text XML - internal XmlTextReaderImpl(string xmlFragment, XmlParserContext context, XmlReaderSettings settings) + internal XmlTextReaderImpl(string xmlFragment, XmlParserContext? context, XmlReaderSettings settings) : this(null, settings, context) { Debug.Assert(xmlFragment != null); @@ -9247,7 +9247,7 @@ internal void SetDtdInfo(IDtdInfo newDtdInfo) // Validation support // - internal IValidationEventHandling ValidationEventHandling + internal IValidationEventHandling? ValidationEventHandling { set { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs index 38e7b8640ad8..a50f7dafc3dd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs @@ -293,7 +293,7 @@ public XmlTextWriter(Stream w, Encoding? encoding) : this() } // Creates an instance of the XmlTextWriter class using the specified file. - public XmlTextWriter(string filename, Encoding encoding) + public XmlTextWriter(string filename, Encoding? encoding) : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), encoding) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReader.cs index c0c9b77fa40e..a3911c8e47ba 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReader.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. +#nullable enable using System; using System.IO; using System.Text; @@ -17,6 +18,7 @@ public class XmlValidatingReader : XmlReader, IXmlLineInfo, IXmlNamespaceResolve // Member fields // private readonly XmlValidatingReaderImpl _impl; + // // Constructors // @@ -32,6 +34,7 @@ public XmlValidatingReader(string xmlFragment, XmlNodeType fragType, XmlParserCo { throw new ArgumentNullException(nameof(xmlFragment)); } + _impl = new XmlValidatingReaderImpl(xmlFragment, fragType, context); _impl.OuterReader = this; } @@ -89,7 +92,7 @@ public override int Depth get { return _impl.Depth; } } - public override string BaseURI + public override string? BaseURI { get { return _impl.BaseURI; } } @@ -123,12 +126,12 @@ public override string XmlLang public override int AttributeCount { get { return _impl.AttributeCount; } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { return _impl.GetAttribute(name); } - public override string GetAttribute(string localName, string namespaceURI) + public override string? GetAttribute(string localName, string? namespaceURI) { return _impl.GetAttribute(localName, namespaceURI); } @@ -143,7 +146,7 @@ public override bool MoveToAttribute(string name) return _impl.MoveToAttribute(name); } - public override bool MoveToAttribute(string localName, string namespaceURI) + public override bool MoveToAttribute(string localName, string? namespaceURI) { return _impl.MoveToAttribute(localName, namespaceURI); } @@ -198,13 +201,14 @@ public override XmlNameTable NameTable get { return _impl.NameTable; } } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { - string ns = _impl.LookupNamespace(prefix); + string? ns = _impl.LookupNamespace(prefix); if (ns != null && ns.Length == 0) { ns = null; } + return ns; } @@ -269,12 +273,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return _impl.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _impl.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _impl.LookupPrefix(namespaceName); } @@ -288,7 +292,7 @@ public event ValidationEventHandler ValidationEventHandler remove { _impl.ValidationEventHandler -= value; } } - public object SchemaType + public object? SchemaType { get { return _impl.SchemaType; } } @@ -326,12 +330,12 @@ public bool Namespaces set { _impl.Namespaces = value; } } - public object ReadTypedValue() + public object? ReadTypedValue() { return _impl.ReadTypedValue(); } - public Encoding Encoding + public Encoding? Encoding { get { return _impl.Encoding; } } @@ -343,7 +347,7 @@ internal XmlValidatingReaderImpl Impl get { return _impl; } } - internal override IDtdInfo DtdInfo + internal override IDtdInfo? DtdInfo { get { return _impl.DtdInfo; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs index e8a69444016f..239b854adba7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.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. +#nullable enable using System; using System.IO; using System.Text; @@ -10,6 +11,7 @@ using System.Globalization; using System.Collections.Generic; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -35,7 +37,7 @@ internal class ValidationEventHandling : IValidationEventHandling { // Fields private readonly XmlValidatingReaderImpl _reader; - private ValidationEventHandler _eventHandler; + private ValidationEventHandler? _eventHandler; // Constructor internal ValidationEventHandling(XmlValidatingReaderImpl reader) @@ -45,7 +47,7 @@ internal ValidationEventHandling(XmlValidatingReaderImpl reader) // IValidationEventHandling interface #region IValidationEventHandling interface - object IValidationEventHandling.EventHandler + object? IValidationEventHandling.EventHandler { get { return _eventHandler; } } @@ -81,7 +83,7 @@ internal void RemoveHandler(ValidationEventHandler handler) // core text reader private readonly XmlReader _coreReader; private readonly XmlTextReaderImpl _coreReaderImpl; - private readonly IXmlNamespaceResolver _coreReaderNSResolver; + private readonly IXmlNamespaceResolver? _coreReaderNSResolver; // validation private ValidationType _validationType; @@ -99,10 +101,10 @@ internal void RemoveHandler(ValidationEventHandler handler) private readonly ValidationEventHandling _eventHandling; // misc - private readonly XmlParserContext _parserContext; + private readonly XmlParserContext? _parserContext; // helper for Read[Element]ContentAs{Base64,BinHex} methods - private ReadContentAsBinaryHelper _readBinaryHelper; + private ReadContentAsBinaryHelper? _readBinaryHelper; // Outer XmlReader exposed to the user - either XmlValidatingReader or XmlValidatingReaderImpl (when created via XmlReader.Create). // Virtual methods called from within XmlValidatingReaderImpl must be called on the outer reader so in case the user overrides @@ -116,27 +118,30 @@ internal void RemoveHandler(ValidationEventHandler handler) // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader internal XmlValidatingReaderImpl(XmlReader reader) { - XmlAsyncCheckReader asyncCheckReader = reader as XmlAsyncCheckReader; + XmlAsyncCheckReader? asyncCheckReader = reader as XmlAsyncCheckReader; if (asyncCheckReader != null) { reader = asyncCheckReader.CoreReader; } + _outerReader = this; _coreReader = reader; _coreReaderNSResolver = reader as IXmlNamespaceResolver; - _coreReaderImpl = reader as XmlTextReaderImpl; + _coreReaderImpl = (reader as XmlTextReaderImpl)!; if (_coreReaderImpl == null) { - XmlTextReader tr = reader as XmlTextReader; + XmlTextReader? tr = reader as XmlTextReader; if (tr != null) { _coreReaderImpl = tr.Impl; } } + if (_coreReaderImpl == null) { throw new ArgumentException(SR.Arg_ExpectingXmlTextReader, nameof(reader)); } + _coreReaderImpl.EntityHandling = EntityHandling.ExpandEntities; _coreReaderImpl.XmlValidatingReaderCompatibilityMode = true; _processIdentityConstraints = true; @@ -152,18 +157,17 @@ internal XmlValidatingReaderImpl(XmlReader reader) _validationType = ValidationType.Auto; SetupValidation(ValidationType.Auto); #pragma warning restore 618 - } // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified string, fragment type and parser context // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning. - internal XmlValidatingReaderImpl(string xmlFragment, XmlNodeType fragType, XmlParserContext context) + internal XmlValidatingReaderImpl(string xmlFragment, XmlNodeType fragType, XmlParserContext? context) : this(new XmlTextReader(xmlFragment, fragType, context)) { - if (_coreReader.BaseURI.Length > 0) + if (_coreReader.BaseURI!.Length > 0) { - _validator.BaseUri = GetResolver().ResolveUri(null, _coreReader.BaseURI); + _validator.BaseUri = GetResolver()!.ResolveUri(null, _coreReader.BaseURI); } if (context != null) @@ -176,12 +180,12 @@ internal XmlValidatingReaderImpl(string xmlFragment, XmlNodeType fragType, XmlPa // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified stream, fragment type and parser context // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning. - internal XmlValidatingReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context) + internal XmlValidatingReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserContext? context) : this(new XmlTextReader(xmlFragment, fragType, context)) { - if (_coreReader.BaseURI.Length > 0) + if (_coreReader.BaseURI!.Length > 0) { - _validator.BaseUri = GetResolver().ResolveUri(null, _coreReader.BaseURI); + _validator.BaseUri = GetResolver()!.ResolveUri(null, _coreReader.BaseURI); } if (context != null) @@ -193,28 +197,31 @@ internal XmlValidatingReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlPa // Initializes a new instance of XmlValidatingReaderImpl class with the specified arguments. // This constructor is used when creating XmlValidatingReaderImpl reader via "XmlReader.Create(..)" - internal XmlValidatingReaderImpl(XmlReader reader, ValidationEventHandler settingsEventHandler, bool processIdentityConstraints) + internal XmlValidatingReaderImpl(XmlReader reader, ValidationEventHandler? settingsEventHandler, bool processIdentityConstraints) { - XmlAsyncCheckReader asyncCheckReader = reader as XmlAsyncCheckReader; + XmlAsyncCheckReader? asyncCheckReader = reader as XmlAsyncCheckReader; if (asyncCheckReader != null) { reader = asyncCheckReader.CoreReader; } + _outerReader = this; _coreReader = reader; - _coreReaderImpl = reader as XmlTextReaderImpl; + _coreReaderImpl = (reader as XmlTextReaderImpl)!; if (_coreReaderImpl == null) { - XmlTextReader tr = reader as XmlTextReader; + XmlTextReader? tr = reader as XmlTextReader; if (tr != null) { _coreReaderImpl = tr.Impl; } } + if (_coreReaderImpl == null) { throw new ArgumentException(SR.Arg_ExpectingXmlTextReader, nameof(reader)); } + _coreReaderImpl.XmlValidatingReaderCompatibilityMode = true; _coreReaderNSResolver = reader as IXmlNamespaceResolver; _processIdentityConstraints = processIdentityConstraints; @@ -243,11 +250,11 @@ internal XmlValidatingReaderImpl(XmlReader reader, ValidationEventHandler settin // XmlReader members // // Returns the current settings of the reader - public override XmlReaderSettings Settings + public override XmlReaderSettings? Settings { get { - XmlReaderSettings settings; + XmlReaderSettings? settings; if (_coreReaderImpl.V1Compat) { settings = null; @@ -256,6 +263,7 @@ public override XmlReaderSettings Settings { settings = _coreReader.Settings; } + if (settings != null) { settings = settings.Clone(); @@ -264,11 +272,13 @@ public override XmlReaderSettings Settings { settings = new XmlReaderSettings(); } + settings.ValidationType = ValidationType.DTD; if (!_processIdentityConstraints) { settings.ValidationFlags &= ~XmlSchemaValidationFlags.ProcessIdentityConstraints; } + settings.ReadOnly = true; return settings; } @@ -347,7 +357,7 @@ public override int Depth } // Returns the base URI of the current node. - public override string BaseURI + public override string? BaseURI { get { @@ -428,7 +438,7 @@ public override XmlNameTable NameTable } // Returns encoding of the XML document - internal Encoding Encoding + internal Encoding? Encoding { get { @@ -446,13 +456,13 @@ public override int AttributeCount } // Returns value of an attribute with the specified Name - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { return _coreReader.GetAttribute(name); } // Returns value of an attribute with the specified LocalName and NamespaceURI - public override string GetAttribute(string localName, string namespaceURI) + public override string? GetAttribute(string localName, string? namespaceURI) { return _coreReader.GetAttribute(localName, namespaceURI); } @@ -475,7 +485,7 @@ public override bool MoveToAttribute(string name) } // Moves to an attribute with the specified LocalName and NamespceURI - public override bool MoveToAttribute(string localName, string namespaceURI) + public override bool MoveToAttribute(string localName, string? namespaceURI) { if (!_coreReader.MoveToAttribute(localName, namespaceURI)) { @@ -565,7 +575,7 @@ public override bool Read() goto case ParsingFunction.Read; case ParsingFunction.InReadBinaryContent: _parsingFunction = ParsingFunction.Read; - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); goto case ParsingFunction.Read; default: Debug.Fail($"Unexpected parsing function {_parsingFunction}"); @@ -581,7 +591,7 @@ public override void Close() } // Returns NamespaceURI associated with the specified prefix in the current namespace scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return _coreReaderImpl.LookupNamespace(prefix); } @@ -592,7 +602,7 @@ public override bool ReadAttributeValue() if (_parsingFunction == ParsingFunction.InReadBinaryContent) { _parsingFunction = ParsingFunction.Read; - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); } if (!_coreReader.ReadAttributeValue()) { @@ -627,7 +637,7 @@ public override int ReadContentAsBase64(byte[] buffer, int index, int count) _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBase64(buffer, index, count); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -651,7 +661,7 @@ public override int ReadContentAsBinHex(byte[] buffer, int index, int count) _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBinHex(buffer, index, count); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -675,7 +685,7 @@ public override int ReadElementContentAsBase64(byte[] buffer, int index, int cou _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBase64(buffer, index, count); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -699,7 +709,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBinHex(buffer, index, count); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -791,12 +801,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return this.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return this.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return this.LookupPrefix(namespaceName); } @@ -804,12 +814,12 @@ string IXmlNamespaceResolver.LookupPrefix(string namespaceName) // Internal IXmlNamespaceResolver methods internal IDictionary GetNamespacesInScope(XmlNamespaceScope scope) { - return _coreReaderNSResolver.GetNamespacesInScope(scope); + return _coreReaderNSResolver!.GetNamespacesInScope(scope); } - internal string LookupPrefix(string namespaceName) + internal string? LookupPrefix(string namespaceName) { - return _coreReaderNSResolver.LookupPrefix(namespaceName); + return _coreReaderNSResolver!.LookupPrefix(namespaceName); } // @@ -829,17 +839,18 @@ internal event ValidationEventHandler ValidationEventHandler } // returns the schema type of the current node - internal object SchemaType + internal object? SchemaType { get { if (_validationType != ValidationType.None) { - XmlSchemaType schemaTypeObj = _coreReaderImpl.InternalSchemaType as XmlSchemaType; + XmlSchemaType? schemaTypeObj = _coreReaderImpl.InternalSchemaType as XmlSchemaType; if (schemaTypeObj != null && schemaTypeObj.QualifiedName.Namespace == XmlReservedNs.NsXs) { return schemaTypeObj.Datatype; } + return _coreReaderImpl.InternalSchemaType; } else @@ -932,7 +943,7 @@ internal bool Namespaces } // Returns typed value of the current node (based on the type specified by schema) - public object ReadTypedValue() + public object? ReadTypedValue() { if (_validationType == ValidationType.None) { @@ -948,7 +959,8 @@ public object ReadTypedValue() { return null; } - XmlSchemaDatatype dtype = (SchemaType is XmlSchemaDatatype) ? (XmlSchemaDatatype)SchemaType : ((XmlSchemaType)SchemaType).Datatype; + + XmlSchemaDatatype? dtype = (SchemaType is XmlSchemaDatatype) ? (XmlSchemaDatatype)SchemaType : ((XmlSchemaType)SchemaType).Datatype; if (dtype != null) { if (!_outerReader.IsEmptyElement) @@ -959,6 +971,7 @@ public object ReadTypedValue() { throw new InvalidOperationException(SR.Xml_InvalidOperation); } + XmlNodeType type = _outerReader.NodeType; if (type != XmlNodeType.CDATA && type != XmlNodeType.Text && type != XmlNodeType.Whitespace && type != XmlNodeType.SignificantWhitespace && @@ -967,6 +980,7 @@ public object ReadTypedValue() break; } } + if (_outerReader.NodeType != XmlNodeType.EndElement) { throw new XmlException(SR.Xml_InvalidNodeType, _outerReader.NodeType.ToString()); @@ -1016,7 +1030,7 @@ private void ParseDtdFromParserContext() private void ValidateDtd() { - IDtdInfo dtdInfo = _coreReaderImpl.DtdInfo; + IDtdInfo? dtdInfo = _coreReaderImpl.DtdInfo; if (dtdInfo != null) { switch (_validationType) @@ -1043,26 +1057,28 @@ private void ResolveEntityInternally() } // SxS: This method resolves an Uri but does not expose it to caller. It's OK to suppress the SxS warning. + [MemberNotNull(nameof(_validator))] private void SetupValidation(ValidationType valType) { - _validator = BaseValidator.CreateInstance(valType, this, _schemaCollection, _eventHandling, _processIdentityConstraints); + _validator = BaseValidator.CreateInstance(valType, this, _schemaCollection, _eventHandling, _processIdentityConstraints)!; - XmlResolver resolver = GetResolver(); + XmlResolver? resolver = GetResolver(); _validator.XmlResolver = resolver; - if (_outerReader.BaseURI.Length > 0) + if (_outerReader.BaseURI!.Length > 0) { _validator.BaseUri = (resolver == null) ? new Uri(_outerReader.BaseURI, UriKind.RelativeOrAbsolute) : resolver.ResolveUri(null, _outerReader.BaseURI); } + _coreReaderImpl.ValidationEventHandling = (_validationType == ValidationType.None) ? null : _eventHandling; } - private static XmlResolver s_tempResolver; + private static XmlResolver? s_tempResolver; // This is needed because we can't have the setter for XmlResolver public and with internal getter. - private XmlResolver GetResolver() + private XmlResolver? GetResolver() { - XmlResolver tempResolver = _coreReaderImpl.GetResolver(); + XmlResolver? tempResolver = _coreReaderImpl.GetResolver(); if (tempResolver == null && !_coreReaderImpl.IsResolverSet) { @@ -1117,7 +1133,7 @@ internal BaseValidator Validator } } - internal override XmlNamespaceManager NamespaceManager + internal override XmlNamespaceManager? NamespaceManager { get { @@ -1133,7 +1149,7 @@ internal bool StandAlone } } - internal object SchemaTypeObject + internal object? SchemaTypeObject { set { @@ -1141,7 +1157,7 @@ internal object SchemaTypeObject } } - internal object TypedValueObject + internal object? TypedValueObject { get { @@ -1158,24 +1174,25 @@ internal bool AddDefaultAttribute(SchemaAttDef attdef) return _coreReaderImpl.AddDefaultAttributeNonDtd(attdef); } - internal override IDtdInfo DtdInfo + internal override IDtdInfo? DtdInfo { get { return _coreReaderImpl.DtdInfo; } } internal void ValidateDefaultAttributeOnUse(IDtdDefaultAttributeInfo defaultAttribute, XmlTextReaderImpl coreReader) { - SchemaAttDef attdef = defaultAttribute as SchemaAttDef; + SchemaAttDef? attdef = defaultAttribute as SchemaAttDef; if (attdef == null) { return; } - SchemaInfo schemaInfo = coreReader.DtdInfo as SchemaInfo; + SchemaInfo? schemaInfo = coreReader.DtdInfo as SchemaInfo; if (schemaInfo == null) { return; } + DtdValidator.CheckDefaultValue(attdef, schemaInfo, _eventHandling, coreReader.BaseURI); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImplAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImplAsync.cs index 7f23a0959cb3..3b917610d63e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImplAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImplAsync.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. +#nullable enable using System; using System.IO; using System.Text; @@ -63,7 +64,7 @@ public override async Task ReadAsync() goto case ParsingFunction.Read; case ParsingFunction.InReadBinaryContent: _parsingFunction = ParsingFunction.Read; - await _readBinaryHelper.FinishAsync().ConfigureAwait(false); + await _readBinaryHelper!.FinishAsync().ConfigureAwait(false); goto case ParsingFunction.Read; default: Debug.Fail($"Unexpected parsing function {_parsingFunction}"); @@ -88,7 +89,7 @@ public override async Task ReadContentAsBase64Async(byte[] buffer, int inde _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = await _readBinaryHelper.ReadContentAsBase64Async(buffer, index, count).ConfigureAwait(false); + int readCount = await _readBinaryHelper!.ReadContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -112,7 +113,7 @@ public override async Task ReadContentAsBinHexAsync(byte[] buffer, int inde _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = await _readBinaryHelper.ReadContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); + int readCount = await _readBinaryHelper!.ReadContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -136,7 +137,7 @@ public override async Task ReadElementContentAsBase64Async(byte[] buffer, i _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = await _readBinaryHelper.ReadElementContentAsBase64Async(buffer, index, count).ConfigureAwait(false); + int readCount = await _readBinaryHelper!.ReadElementContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; @@ -160,7 +161,7 @@ public override async Task ReadElementContentAsBinHexAsync(byte[] buffer, i _parsingFunction = ParsingFunction.Read; // call to the helper - int readCount = await _readBinaryHelper.ReadElementContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); + int readCount = await _readBinaryHelper!.ReadElementContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // setup parsingFunction _parsingFunction = ParsingFunction.InReadBinaryContent; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs index 1487069cc910..738ff3c7c3a3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs @@ -1343,7 +1343,7 @@ public override XmlSpace XmlSpace } } - public override string XmlLang + public override string? XmlLang { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterAsync.cs index c5ca77b776fe..75248f3b4737 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterAsync.cs @@ -770,7 +770,7 @@ private async Task WriteEndAttributeAsync_SepcialAtt() } } - public override async Task WriteCDataAsync(string text) + public override async Task WriteCDataAsync(string? text) { try { @@ -778,6 +778,7 @@ public override async Task WriteCDataAsync(string text) { text = string.Empty; } + await AdvanceStateAsync(Token.CData).ConfigureAwait(false); await _writer.WriteCDataAsync(text).ConfigureAwait(false); } @@ -788,7 +789,7 @@ public override async Task WriteCDataAsync(string text) } } - public override async Task WriteCommentAsync(string text) + public override async Task WriteCommentAsync(string? text) { try { @@ -796,6 +797,7 @@ public override async Task WriteCommentAsync(string text) { text = string.Empty; } + await AdvanceStateAsync(Token.Comment).ConfigureAwait(false); await _writer.WriteCommentAsync(text).ConfigureAwait(false); } @@ -938,7 +940,7 @@ public override async Task WriteSurrogateCharEntityAsync(char lowChar, char high } } - public override async Task WriteWhitespaceAsync(string ws) + public override async Task WriteWhitespaceAsync(string? ws) { try { @@ -946,6 +948,7 @@ public override async Task WriteWhitespaceAsync(string ws) { ws = string.Empty; } + if (!XmlCharType.Instance.IsOnlyWhitespace(ws)) { throw new ArgumentException(SR.Xml_NonWhitespace); @@ -968,7 +971,7 @@ public override async Task WriteWhitespaceAsync(string ws) } } - public override Task WriteStringAsync(string text) + public override Task WriteStringAsync(string? text) { try { @@ -1460,6 +1463,7 @@ private async Task StartElementContentAsync_WithNS() await _nsStack[i].WriteDeclAsync(_writer, _rawWriter).ConfigureAwait(false); } } + if (_rawWriter != null) { _rawWriter.StartElementContent(); @@ -1477,6 +1481,7 @@ private Task StartElementContentAsync() { _rawWriter.StartElementContent(); } + return Task.CompletedTask; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpers.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpers.cs index de07e0ec772e..09ab72796797 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpers.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpers.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Text; using System.Diagnostics; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -26,12 +28,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp { throw new NotImplementedException(); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _wfWriter.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _wfWriter.LookupPrefix(namespaceName); } @@ -44,7 +46,7 @@ private partial struct ElementScope internal string localName; internal string namespaceUri; internal XmlSpace xmlSpace; - internal string xmlLang; + internal string? xmlLang; internal void Set(string prefix, string localName, string namespaceUri, int prevNSTop) { @@ -90,7 +92,7 @@ internal void Set(string prefix, string namespaceUri, NamespaceKind kind) this.prevNsIndex = -1; } - internal void WriteDecl(XmlWriter writer, XmlRawWriter rawWriter) + internal void WriteDecl(XmlWriter writer, XmlRawWriter? rawWriter) { Debug.Assert(kind == NamespaceKind.NeedToWrite); if (null != rawWriter) @@ -107,6 +109,7 @@ internal void WriteDecl(XmlWriter writer, XmlRawWriter rawWriter) { writer.WriteStartAttribute("xmlns", prefix, XmlReservedNs.NsXmlNs); } + writer.WriteString(namespaceUri); writer.WriteEndAttribute(); } @@ -164,8 +167,13 @@ private class Item internal ItemType type; internal object data; - internal Item() { } + internal Item(ItemType type, object data) + { + Set(type, data); + } + [MemberNotNull(nameof(type))] + [MemberNotNull(nameof(data))] internal void Set(ItemType type, object data) { this.type = type; @@ -188,8 +196,8 @@ internal BufferChunk(char[] buffer, int index, int count) } private StringBuilder _stringValue = new StringBuilder(); - private string _singleStringValue; // special-case for a single WriteString call - private Item[] _items; + private string? _singleStringValue; // special-case for a single WriteString call + private Item[]? _items; private int _firstItem; private int _lastItem = -1; @@ -344,7 +352,7 @@ internal void Replay(XmlWriter writer) BufferChunk bufChunk; for (int i = _firstItem; i <= _lastItem; i++) { - Item item = _items[i]; + Item item = _items![i]; switch (item.type) { case ItemType.EntityRef: @@ -408,7 +416,7 @@ internal void Trim() int i = _firstItem; while (i == _firstItem && i <= _lastItem) { - Item item = _items[i]; + Item item = _items![i]; switch (item.type) { case ItemType.Whitespace: @@ -433,11 +441,13 @@ internal void Trim() bufChunk.index++; bufChunk.count--; } + if (bufChunk.index == endIndex) { // no characters left -> move the firstItem index to exclude it from the Replay _firstItem++; } + break; } i++; @@ -447,7 +457,7 @@ internal void Trim() i = _lastItem; while (i == _lastItem && i >= _firstItem) { - Item item = _items[i]; + Item item = _items![i]; switch (item.type) { case ItemType.Whitespace: @@ -470,13 +480,16 @@ internal void Trim() { bufChunk.count--; } + if (bufChunk.count == 0) { // no characters left -> move the lastItem index to exclude it from the Replay _lastItem--; } + break; } + i--; } } @@ -513,11 +526,16 @@ private void AddItem(ItemType type, object data) Array.Copy(_items, newItems, newItemIndex); _items = newItems; } + if (_items[newItemIndex] == null) { - _items[newItemIndex] = new Item(); + _items[newItemIndex] = new Item(type, data); + } + else + { + _items[newItemIndex].Set(type, data); } - _items[newItemIndex].Set(type, data); + _lastItem = newItemIndex; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpersAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpersAsync.cs index ff243e0025ef..9b70772408c5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpersAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriterHelpersAsync.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. +#nullable enable using System; using System.Text; using System.Diagnostics; @@ -27,7 +28,7 @@ internal Task WriteFullEndElementAsync(XmlRawWriter rawWriter) private partial struct Namespace { - internal async Task WriteDeclAsync(XmlWriter writer, XmlRawWriter rawWriter) + internal async Task WriteDeclAsync(XmlWriter writer, XmlRawWriter? rawWriter) { Debug.Assert(kind == NamespaceKind.NeedToWrite); if (null != rawWriter) @@ -63,7 +64,7 @@ internal async Task ReplayAsync(XmlWriter writer) BufferChunk bufChunk; for (int i = _firstItem; i <= _lastItem; i++) { - Item item = _items[i]; + Item item = _items![i]; switch (item.type) { case ItemType.EntityRef: diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingReader.cs index 68d844c51a66..62636bdeef7b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingReader.cs @@ -61,7 +61,7 @@ internal XmlWrappingReader(XmlReader baseReader) return reader.GetAttribute(name); } - public override string? GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { return reader.GetAttribute(name, namespaceURI); } @@ -76,7 +76,7 @@ public override bool MoveToAttribute(string name) return reader.MoveToAttribute(name); } - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { return reader.MoveToAttribute(name, ns); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriter.cs index 217447edeadd..3f334dcfdae0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriter.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. +#nullable enable using System; using System.Xml.Schema; using System.Collections; @@ -27,10 +28,10 @@ internal XmlWrappingWriter(XmlWriter baseWriter) // // XmlWriter implementation // - public override XmlWriterSettings Settings { get { return writer.Settings; } } + public override XmlWriterSettings? Settings { get { return writer.Settings; } } public override WriteState WriteState { get { return writer.WriteState; } } public override XmlSpace XmlSpace { get { return writer.XmlSpace; } } - public override string XmlLang { get { return writer.XmlLang; } } + public override string? XmlLang { get { return writer.XmlLang; } } public override void WriteStartDocument() @@ -48,12 +49,12 @@ public override void WriteEndDocument() writer.WriteEndDocument(); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { writer.WriteDocType(name, pubid, sysid, subset); } - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { writer.WriteStartElement(prefix, localName, ns); } @@ -68,7 +69,7 @@ public override void WriteFullEndElement() writer.WriteFullEndElement(); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { writer.WriteStartAttribute(prefix, localName, ns); } @@ -78,17 +79,17 @@ public override void WriteEndAttribute() writer.WriteEndAttribute(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { writer.WriteCData(text); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { writer.WriteComment(text); } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { writer.WriteProcessingInstruction(name, text); } @@ -103,12 +104,12 @@ public override void WriteCharEntity(char ch) writer.WriteCharEntity(ch); } - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { writer.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { writer.WriteString(text); } @@ -148,7 +149,7 @@ public override void Flush() writer.Flush(); } - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { return writer.LookupPrefix(ns); } @@ -158,7 +159,7 @@ public override void WriteValue(object value) writer.WriteValue(value); } - public override void WriteValue(string value) + public override void WriteValue(string? value) { writer.WriteValue(value); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriterAsync.cs index 53dcf5860f2f..46c2d673390d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWrappingWriterAsync.cs @@ -59,12 +59,12 @@ protected internal override Task WriteEndAttributeAsync() return writer.WriteEndAttributeAsync(); } - public override Task WriteCDataAsync(string text) + public override Task WriteCDataAsync(string? text) { return writer.WriteCDataAsync(text); } - public override Task WriteCommentAsync(string text) + public override Task WriteCommentAsync(string? text) { return writer.WriteCommentAsync(text); } @@ -84,12 +84,12 @@ public override Task WriteCharEntityAsync(char ch) return writer.WriteCharEntityAsync(ch); } - public override Task WriteWhitespaceAsync(string ws) + public override Task WriteWhitespaceAsync(string? ws) { return writer.WriteWhitespaceAsync(ws); } - public override Task WriteStringAsync(string text) + public override Task WriteStringAsync(string? text) { return writer.WriteStringAsync(text); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs index 22baf19d7c97..b35c292262e0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs @@ -107,14 +107,14 @@ protected internal virtual Task WriteEndAttributeAsync() // Writes out a ; block containing the specified text. - public virtual Task WriteCDataAsync(string text) + public virtual Task WriteCDataAsync(string? text) { throw new NotImplementedException(); } // Writes out a comment ; containing the specified text. - public virtual Task WriteCommentAsync(string text) + public virtual Task WriteCommentAsync(string? text) { throw new NotImplementedException(); } @@ -142,14 +142,14 @@ public virtual Task WriteCharEntityAsync(char ch) // Writes out the given whitespace. - public virtual Task WriteWhitespaceAsync(string ws) + public virtual Task WriteWhitespaceAsync(string? ws) { throw new NotImplementedException(); } // Writes out the specified text content. - public virtual Task WriteStringAsync(string text) + public virtual Task WriteStringAsync(string? text) { throw new NotImplementedException(); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs index f0ff98e5a39e..5cde9f0b3323 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; #if !HIDE_XSL using System.Xml.Xsl.Runtime; @@ -72,9 +74,9 @@ public sealed class XmlWriterSettings private List _cdataSections = new List(); private bool _doNotEscapeUriAttributes; private bool _mergeCDataSections; - private string _mediaType; - private string _docTypeSystem; - private string _docTypePublic; + private string? _mediaType; + private string? _docTypeSystem; + private string? _docTypePublic; private XmlStandalone _standalone; private bool _autoXmlDecl; @@ -113,6 +115,7 @@ public Encoding Encoding { return _encoding; } + [MemberNotNull(nameof(_encoding))] set { CheckReadOnly(nameof(Encoding)); @@ -149,6 +152,7 @@ public NewLineHandling NewLineHandling { throw new ArgumentOutOfRangeException(nameof(value)); } + _newLineHandling = value; } } @@ -160,6 +164,7 @@ public string NewLineChars { return _newLineChars; } + [MemberNotNull(nameof(_newLineChars))] set { CheckReadOnly(nameof(NewLineChars)); @@ -168,6 +173,7 @@ public string NewLineChars { throw new ArgumentNullException(nameof(value)); } + _newLineChars = value; } } @@ -193,6 +199,7 @@ public string IndentChars { return _indentChars; } + [MemberNotNull(nameof(_indentChars))] set { CheckReadOnly(nameof(IndentChars)); @@ -201,6 +208,7 @@ public string IndentChars { throw new ArgumentNullException(nameof(value)); } + _indentChars = value; } } @@ -326,7 +334,7 @@ public void Reset() // can now be set independently of each other. public XmlWriterSettings Clone() { - XmlWriterSettings clonedSettings = MemberwiseClone() as XmlWriterSettings; + XmlWriterSettings clonedSettings = (MemberwiseClone() as XmlWriterSettings)!; // Deep clone shared settings that are not immutable clonedSettings._cdataSections = new List(_cdataSections); @@ -376,7 +384,7 @@ internal bool MergeCDataSections } // Used in Html writer when writing Meta element. Null denotes the default media type. - internal string MediaType + internal string? MediaType { get { @@ -390,7 +398,7 @@ internal string MediaType } // System Id in doc-type declaration. Null denotes the absence of the system Id. - internal string DocTypeSystem + internal string? DocTypeSystem { get { @@ -404,7 +412,7 @@ internal string DocTypeSystem } // Public Id in doc-type declaration. Null denotes the absence of the public Id. - internal string DocTypePublic + internal string? DocTypePublic { get { @@ -483,7 +491,7 @@ internal XmlWriter CreateWriter(string outputFileName) newSettings.CloseOutput = true; } - FileStream fs = null; + FileStream? fs = null; try { // open file stream @@ -705,6 +713,9 @@ private void CheckReadOnly(string propertyName) // // Private methods // + [MemberNotNull(nameof(_encoding))] + [MemberNotNull(nameof(_newLineChars))] + [MemberNotNull(nameof(_indentChars))] private void Initialize() { _encoding = Encoding.UTF8; @@ -736,7 +747,7 @@ private void Initialize() private XmlWriter AddConformanceWrapper(XmlWriter baseWriter) { ConformanceLevel confLevel = ConformanceLevel.Auto; - XmlWriterSettings baseWriterSettings = baseWriter.Settings; + XmlWriterSettings? baseWriterSettings = baseWriter.Settings; bool checkValues = false; bool checkNames = false; bool replaceNewLines = false; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReader.cs index ade65358775e..119604e0b847 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReader.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. +#nullable enable using System.IO; using System.Text; using System.Xml.Schema; @@ -8,6 +9,7 @@ using System.Diagnostics; using System.Globalization; using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -29,7 +31,7 @@ private enum CachingReaderState private ValidatingReaderNodeData[] _contentEvents; private ValidatingReaderNodeData[] _attributeEvents; - private ValidatingReaderNodeData _cachedNode; + private ValidatingReaderNodeData? _cachedNode; private CachingReaderState _cacheState; private int _contentIndex; @@ -45,17 +47,17 @@ private enum CachingReaderState private bool _readAhead; //Lineinfo - private readonly IXmlLineInfo _lineInfo; + private readonly IXmlLineInfo? _lineInfo; //ReadAttributeValue TextNode - private ValidatingReaderNodeData _textNode; + private ValidatingReaderNodeData? _textNode; //Constants private const int InitialAttributeCount = 8; private const int InitialContentCount = 4; //Constructor - internal XsdCachingReader(XmlReader reader, IXmlLineInfo lineInfo, CachingEventHandler handlerMethod) + internal XsdCachingReader(XmlReader reader, IXmlLineInfo? lineInfo, CachingEventHandler handlerMethod) { _coreReader = reader; _lineInfo = lineInfo; @@ -65,6 +67,7 @@ internal XsdCachingReader(XmlReader reader, IXmlLineInfo lineInfo, CachingEventH Init(); } + [MemberNotNull(nameof(_coreReaderNameTable))] private void Init() { _coreReaderNameTable = _coreReader.NameTable; @@ -92,7 +95,7 @@ internal void Reset(XmlReader reader) } // Settings - public override XmlReaderSettings Settings + public override XmlReaderSettings? Settings { get { @@ -107,7 +110,7 @@ public override XmlNodeType NodeType { get { - return _cachedNode.NodeType; + return _cachedNode!.NodeType; } } @@ -116,7 +119,7 @@ public override string Name { get { - return _cachedNode.GetAtomizedNameWPrefix(_coreReaderNameTable); + return _cachedNode!.GetAtomizedNameWPrefix(_coreReaderNameTable); } } @@ -125,7 +128,7 @@ public override string LocalName { get { - return _cachedNode.LocalName; + return _cachedNode!.LocalName; } } @@ -134,7 +137,7 @@ public override string NamespaceURI { get { - return _cachedNode.Namespace; + return _cachedNode!.Namespace; } } @@ -143,7 +146,7 @@ public override string Prefix { get { - return _cachedNode.Prefix; + return _cachedNode!.Prefix; } } @@ -152,7 +155,7 @@ public override bool HasValue { get { - return XmlReader.HasValueInternal(_cachedNode.NodeType); + return XmlReader.HasValueInternal(_cachedNode!.NodeType); } } @@ -161,7 +164,7 @@ public override string Value { get { - return _returnOriginalStringValues ? _cachedNode.OriginalStringValue : _cachedNode.RawValue; + return _returnOriginalStringValues ? _cachedNode!.OriginalStringValue! : _cachedNode!.RawValue; } } @@ -170,12 +173,12 @@ public override int Depth { get { - return _cachedNode.Depth; + return _cachedNode!.Depth; } } // Gets the base URI of the current node. - public override string BaseURI + public override string? BaseURI { get { @@ -241,7 +244,7 @@ public override int AttributeCount } // Gets the value of the attribute with the specified Name. - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { int i; if (!name.Contains(':')) @@ -252,23 +255,25 @@ public override string GetAttribute(string name) { i = GetAttributeIndexWithPrefix(name); } + return (i >= 0) ? _attributeEvents[i].RawValue : null; } // Gets the value of the attribute with the specified LocalName and NamespaceURI. - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { namespaceURI = (namespaceURI == null) ? string.Empty : _coreReaderNameTable.Get(namespaceURI); - name = _coreReaderNameTable.Get(name); + string? atomizedName = _coreReaderNameTable.Get(name); ValidatingReaderNodeData attribute; for (int i = 0; i < _attributeCount; i++) { attribute = _attributeEvents[i]; - if (Ref.Equal(attribute.LocalName, name) && Ref.Equal(attribute.Namespace, namespaceURI)) + if (Ref.Equal(attribute.LocalName, atomizedName) && Ref.Equal(attribute.Namespace, namespaceURI)) { return attribute.RawValue; } } + return null; } @@ -279,6 +284,7 @@ public override string GetAttribute(int i) { throw new ArgumentOutOfRangeException(nameof(i)); } + return _attributeEvents[i].RawValue; } @@ -292,7 +298,7 @@ public override string this[int i] } // Gets the value of the attribute with the specified LocalName and NamespaceURI. - public override string this[string name, string namespaceURI] + public override string? this[string name, string? namespaceURI] { get { @@ -326,15 +332,15 @@ public override bool MoveToAttribute(string name) } // Moves to the attribute with the specified LocalName and NamespaceURI - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { ns = (ns == null) ? string.Empty : _coreReaderNameTable.Get(ns); - name = _coreReaderNameTable.Get(name); + string? atomizedName = _coreReaderNameTable.Get(name); ValidatingReaderNodeData attribute; for (int i = 0; i < _attributeCount; i++) { attribute = _attributeEvents[i]; - if (Ref.Equal(attribute.LocalName, name) && + if (Ref.Equal(attribute.LocalName, atomizedName) && Ref.Equal(attribute.Namespace, ns)) { _currentAttrIndex = i; @@ -342,6 +348,7 @@ public override bool MoveToAttribute(string name, string ns) return true; } } + return false; } @@ -382,10 +389,11 @@ public override bool MoveToNextAttribute() // Moves to the element that contains the current attribute node. public override bool MoveToElement() { - if (_cacheState != CachingReaderState.Replay || _cachedNode.NodeType != XmlNodeType.Attribute) + if (_cacheState != CachingReaderState.Replay || _cachedNode!.NodeType != XmlNodeType.Attribute) { return false; } + _currentContentIndex = 0; _currentAttrIndex = -1; Read(); @@ -402,7 +410,7 @@ public override bool Read() goto case CachingReaderState.Record; case CachingReaderState.Record: - ValidatingReaderNodeData recordedNode = null; + ValidatingReaderNodeData? recordedNode = null; if (_coreReader.Read()) { switch (_coreReader.NodeType) @@ -466,7 +474,7 @@ public override bool Read() } } - internal ValidatingReaderNodeData RecordTextNode(string textValue, string originalStringValue, int depth, int lineNo, int linePos) + internal ValidatingReaderNodeData RecordTextNode(string textValue, string? originalStringValue, int depth, int lineNo, int linePos) { ValidatingReaderNodeData textNode = AddContent(XmlNodeType.Text); textNode.SetItemData(textValue, originalStringValue); @@ -475,7 +483,7 @@ internal ValidatingReaderNodeData RecordTextNode(string textValue, string origin return textNode; } - internal void SwitchTextNodeAndEndElement(string textValue, string originalStringValue) + internal void SwitchTextNodeAndEndElement(string textValue, string? originalStringValue) { Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement || (_coreReader.NodeType == XmlNodeType.Element && _coreReader.IsEmptyElement)); @@ -536,7 +544,7 @@ public override ReadState ReadState public override void Skip() { //Skip on caching reader should move to the end of the subtree, past all cached events - switch (_cachedNode.NodeType) + switch (_cachedNode!.NodeType) { case XmlNodeType.Element: if (_coreReader.NodeType != XmlNodeType.EndElement && !_readAhead) @@ -571,7 +579,7 @@ public override XmlNameTable NameTable } // Resolves a namespace prefix in the current element's scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return _coreReader.LookupNamespace(prefix); } @@ -586,10 +594,11 @@ public override void ResolveEntity() public override bool ReadAttributeValue() { Debug.Assert(_cacheState == CachingReaderState.Replay); - if (_cachedNode.NodeType != XmlNodeType.Attribute) + if (_cachedNode!.NodeType != XmlNodeType.Attribute) { return false; } + _cachedNode = CreateDummyTextNode(_cachedNode.RawValue, _cachedNode.Depth + 1); return true; } @@ -607,7 +616,7 @@ int IXmlLineInfo.LineNumber { get { - return _cachedNode.LineNumber; + return _cachedNode!.LineNumber; } } @@ -615,7 +624,7 @@ int IXmlLineInfo.LinePosition { get { - return _cachedNode.LinePosition; + return _cachedNode!.LinePosition; } } @@ -633,7 +642,7 @@ internal XmlReader GetCoreReader() return _coreReader; } - internal IXmlLineInfo GetLineInfo() + internal IXmlLineInfo? GetLineInfo() { return _lineInfo; } @@ -716,16 +725,17 @@ private void RecordAttributes() private int GetAttributeIndexWithoutPrefix(string name) { - name = _coreReaderNameTable.Get(name); - if (name == null) + string? atomizedName = _coreReaderNameTable.Get(name); + if (atomizedName == null) { return -1; } + ValidatingReaderNodeData attribute; for (int i = 0; i < _attributeCount; i++) { attribute = _attributeEvents[i]; - if (Ref.Equal(attribute.LocalName, name) && attribute.Prefix.Length == 0) + if (Ref.Equal(attribute.LocalName, atomizedName) && attribute.Prefix.Length == 0) { return i; } @@ -735,8 +745,8 @@ private int GetAttributeIndexWithoutPrefix(string name) private int GetAttributeIndexWithPrefix(string name) { - name = _coreReaderNameTable.Get(name); - if (name == null) + string? atomizedName = _coreReaderNameTable.Get(name); + if (atomizedName == null) { return -1; } @@ -744,11 +754,12 @@ private int GetAttributeIndexWithPrefix(string name) for (int i = 0; i < _attributeCount; i++) { attribute = _attributeEvents[i]; - if (Ref.Equal(attribute.GetAtomizedNameWPrefix(_coreReaderNameTable), name)) + if (Ref.Equal(attribute.GetAtomizedNameWPrefix(_coreReaderNameTable), atomizedName)) { return i; } } + return -1; } @@ -758,6 +769,7 @@ private ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int { _textNode = new ValidatingReaderNodeData(XmlNodeType.Text); } + _textNode.Depth = depth; _textNode.RawValue = attributeValue; return _textNode; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReaderAsync.cs index 914e5ffb277f..9abcb8104bd4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdCachingReaderAsync.cs @@ -21,11 +21,11 @@ public override Task GetValueAsync() { if (_returnOriginalStringValues) { - return Task.FromResult(_cachedNode.OriginalStringValue); + return Task.FromResult(_cachedNode!.OriginalStringValue!); } else { - return Task.FromResult(_cachedNode.RawValue); + return Task.FromResult(_cachedNode!.RawValue); } } @@ -107,7 +107,7 @@ public override async Task ReadAsync() public override async Task SkipAsync() { //Skip on caching reader should move to the end of the subtree, past all cached events - switch (_cachedNode.NodeType) + switch (_cachedNode!.NodeType) { case XmlNodeType.Element: if (_coreReader.NodeType != XmlNodeType.EndElement && !_readAhead) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs index a6ce8d9fbaa4..cc0b4053e85d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs @@ -1135,7 +1135,7 @@ public override int AttributeCount } // Gets the value of the attribute with the specified LocalName and NamespaceURI. - public override string? GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { string? attValue = _coreReader.GetAttribute(name, namespaceURI); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs index deb041cebb6d..a7c1c2d3b462 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs @@ -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. +#nullable enable using System; using System.Text; using System.Collections; @@ -18,31 +19,31 @@ namespace System.Xml { internal sealed class DocumentSchemaValidator : IXmlNamespaceResolver { - private XmlSchemaValidator _validator; + private XmlSchemaValidator? _validator; private readonly XmlSchemaSet _schemas; private readonly XmlNamespaceManager _nsManager; private readonly XmlNameTable _nameTable; //Attributes - private ArrayList _defaultAttributes; + private ArrayList? _defaultAttributes; private readonly XmlValueGetter _nodeValueGetter; - private XmlSchemaInfo _attributeSchemaInfo; + private XmlSchemaInfo? _attributeSchemaInfo; //Element PSVI - private XmlSchemaInfo _schemaInfo; + private XmlSchemaInfo? _schemaInfo; //Event Handler - private readonly ValidationEventHandler _eventHandler; + private readonly ValidationEventHandler? _eventHandler; private readonly ValidationEventHandler _internalEventHandler; //Store nodes - private XmlNode _startNode; - private XmlNode _currentNode; + private XmlNode? _startNode; + private XmlNode? _currentNode; private readonly XmlDocument _document; //List of nodes for partial validation tree walk - private XmlNode[] _nodeSequenceToValidate; + private XmlNode?[]? _nodeSequenceToValidate; private bool _isPartialTreeValid; private bool _psviAugmentation; @@ -54,7 +55,7 @@ internal sealed class DocumentSchemaValidator : IXmlNamespaceResolver private readonly string _xsiType; private readonly string _xsiNil; - public DocumentSchemaValidator(XmlDocument ownerDocument, XmlSchemaSet schemas, ValidationEventHandler eventHandler) + public DocumentSchemaValidator(XmlDocument ownerDocument, XmlSchemaSet schemas, ValidationEventHandler? eventHandler) { _schemas = schemas; _eventHandler = eventHandler; @@ -84,7 +85,7 @@ public bool PsviAugmentation public bool Validate(XmlNode nodeToValidate) { - XmlSchemaObject partialValidationType = null; + XmlSchemaObject? partialValidationType = null; XmlSchemaValidationFlags validationFlags = XmlSchemaValidationFlags.AllowXmlAttributes; Debug.Assert(nodeToValidate.SchemaInfo != null); @@ -100,7 +101,7 @@ public bool Validate(XmlNode nodeToValidate) case XmlNodeType.Element: //Validate children of this element IXmlSchemaInfo schemaInfo = nodeToValidate.SchemaInfo; - XmlSchemaElement schemaElement = schemaInfo.SchemaElement; + XmlSchemaElement? schemaElement = schemaInfo.SchemaElement; if (schemaElement != null) { if (!schemaElement.RefName.IsEmpty) @@ -120,14 +121,14 @@ public bool Validate(XmlNode nodeToValidate) if (partialValidationType == null) { //Validated against xs:any with pc= lax or skip or undeclared / not validated element - if (nodeToValidate.ParentNode.NodeType == XmlNodeType.Document) + if (nodeToValidate.ParentNode!.NodeType == XmlNodeType.Document) { //If this is the documentElement and it has not been validated at all nodeToValidate = nodeToValidate.ParentNode; } else { - partialValidationType = FindSchemaInfo(nodeToValidate as XmlElement); + partialValidationType = FindSchemaInfo((nodeToValidate as XmlElement)!); if (partialValidationType == null) { throw new XmlSchemaValidationException(SR.XmlDocument_NoNodeSchemaInfo, null, nodeToValidate); @@ -142,7 +143,7 @@ public bool Validate(XmlNode nodeToValidate) partialValidationType = nodeToValidate.SchemaInfo.SchemaAttribute; if (partialValidationType == null) { //Validated against xs:anyAttribute with pc = lax or skip / undeclared attribute - partialValidationType = FindSchemaInfo(nodeToValidate as XmlAttribute); + partialValidationType = FindSchemaInfo((nodeToValidate as XmlAttribute)!); if (partialValidationType == null) { throw new XmlSchemaValidationException(SR.XmlDocument_NoNodeSchemaInfo, null, nodeToValidate); @@ -164,7 +165,7 @@ public bool Validate(XmlNode nodeToValidate) _attributeSchemaInfo = new XmlSchemaInfo(); } ValidateNode(nodeToValidate); - _validator.EndValidation(); + _validator!.EndValidation(); return _isValid; } @@ -173,7 +174,7 @@ public IDictionary GetNamespacesInScope(XmlNamespaceScope scope) IDictionary dictionary = _nsManager.GetNamespacesInScope(scope); if (scope != XmlNamespaceScope.Local) { - XmlNode node = _startNode; + XmlNode? node = _startNode; while (node != null) { switch (node.NodeType) @@ -221,23 +222,25 @@ public IDictionary GetNamespacesInScope(XmlNamespaceScope scope) return dictionary; } - public string LookupNamespace(string prefix) + public string? LookupNamespace(string prefix) { - string namespaceName = _nsManager.LookupNamespace(prefix); + string? namespaceName = _nsManager.LookupNamespace(prefix); if (namespaceName == null) { - namespaceName = _startNode.GetNamespaceOfPrefixStrict(prefix); + namespaceName = _startNode!.GetNamespaceOfPrefixStrict(prefix); } + return namespaceName; } - public string LookupPrefix(string namespaceName) + public string? LookupPrefix(string namespaceName) { - string prefix = _nsManager.LookupPrefix(namespaceName); + string? prefix = _nsManager.LookupPrefix(namespaceName); if (prefix == null) { - prefix = _startNode.GetPrefixOfNamespaceStrict(namespaceName); + prefix = _startNode!.GetPrefixOfNamespaceStrict(namespaceName); } + return prefix; } @@ -245,15 +248,16 @@ private IXmlNamespaceResolver NamespaceResolver { get { - if ((object)_startNode == (object)_document) + if ((object?)_startNode == (object?)_document) { return _nsManager; } + return this; } } - private void CreateValidator(XmlSchemaObject partialValidationType, XmlSchemaValidationFlags validationFlags) + private void CreateValidator(XmlSchemaObject? partialValidationType, XmlSchemaValidationFlags validationFlags) { _validator = new XmlSchemaValidator(_nameTable, _schemas, NamespaceResolver, validationFlags); _validator.SourceUri = XmlConvert.ToUri(_document.BaseURI); @@ -277,20 +281,22 @@ private void ValidateNode(XmlNode node) switch (_currentNode.NodeType) { case XmlNodeType.Document: - XmlElement docElem = ((XmlDocument)node).DocumentElement; + XmlElement? docElem = ((XmlDocument)node).DocumentElement; if (docElem == null) { throw new InvalidOperationException(SR.Format(SR.Xml_InvalidXmlDocument, SR.Xdom_NoRootEle)); } + ValidateNode(docElem); break; case XmlNodeType.DocumentFragment: case XmlNodeType.EntityReference: - for (XmlNode child = node.FirstChild; child != null; child = child.NextSibling) + for (XmlNode? child = node.FirstChild; child != null; child = child.NextSibling) { ValidateNode(child); } + break; case XmlNodeType.Element: @@ -298,8 +304,8 @@ private void ValidateNode(XmlNode node) break; case XmlNodeType.Attribute: //Top-level attribute - XmlAttribute attr = _currentNode as XmlAttribute; - _validator.ValidateAttribute(attr.LocalName, attr.NamespaceURI, _nodeValueGetter, _attributeSchemaInfo); + XmlAttribute attr = (_currentNode as XmlAttribute)!; + _validator!.ValidateAttribute(attr.LocalName, attr.NamespaceURI, _nodeValueGetter, _attributeSchemaInfo); if (_psviAugmentation) { attr.XmlName = _document.AddAttrXmlName(attr.Prefix, attr.LocalName, attr.NamespaceURI, _attributeSchemaInfo); @@ -307,16 +313,16 @@ private void ValidateNode(XmlNode node) break; case XmlNodeType.Text: - _validator.ValidateText(_nodeValueGetter); + _validator!.ValidateText(_nodeValueGetter); break; case XmlNodeType.CDATA: - _validator.ValidateText(_nodeValueGetter); + _validator!.ValidateText(_nodeValueGetter); break; case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - _validator.ValidateWhitespace(_nodeValueGetter); + _validator!.ValidateWhitespace(_nodeValueGetter); break; case XmlNodeType.Comment: @@ -331,15 +337,15 @@ private void ValidateNode(XmlNode node) private void ValidateElement() { _nsManager.PushScope(); - XmlElement elementNode = _currentNode as XmlElement; + XmlElement? elementNode = _currentNode as XmlElement; Debug.Assert(elementNode != null); XmlAttributeCollection attributes = elementNode.Attributes; - XmlAttribute attr = null; + XmlAttribute? attr = null; //Find Xsi attributes that need to be processed before validating the element - string xsiNil = null; - string xsiType = null; + string? xsiNil = null; + string? xsiType = null; for (int i = 0; i < attributes.Count; i++) { @@ -365,15 +371,17 @@ private void ValidateElement() _nsManager.AddNamespace(attr.Prefix.Length == 0 ? string.Empty : attr.LocalName, attr.Value); } } - _validator.ValidateElement(elementNode.LocalName, elementNode.NamespaceURI, _schemaInfo, xsiType, xsiNil, null, null); + + _validator!.ValidateElement(elementNode.LocalName, elementNode.NamespaceURI, _schemaInfo, xsiType, xsiNil, null, null); ValidateAttributes(elementNode); - _validator.ValidateEndOfAttributes(_schemaInfo); + _validator!.ValidateEndOfAttributes(_schemaInfo); //If element has children, drill down - for (XmlNode child = elementNode.FirstChild; child != null; child = child.NextSibling) + for (XmlNode? child = elementNode.FirstChild; child != null; child = child.NextSibling) { ValidateNode(child); } + //Validate end of element _currentNode = elementNode; //Reset current Node for validation call back _validator.ValidateEndElement(_schemaInfo); @@ -381,9 +389,9 @@ private void ValidateElement() if (_psviAugmentation) { elementNode.XmlName = _document.AddXmlName(elementNode.Prefix, elementNode.LocalName, elementNode.NamespaceURI, _schemaInfo); - if (_schemaInfo.IsDefault) + if (_schemaInfo!.IsDefault) { //the element has a default value - XmlText textNode = _document.CreateTextNode(_schemaInfo.SchemaElement.ElementDecl.DefaultValueRaw); + XmlText textNode = _document.CreateTextNode(_schemaInfo.SchemaElement!.ElementDecl!.DefaultValueRaw); elementNode.AppendChild(textNode); } } @@ -394,7 +402,7 @@ private void ValidateElement() private void ValidateAttributes(XmlElement elementNode) { XmlAttributeCollection attributes = elementNode.Attributes; - XmlAttribute attr = null; + XmlAttribute? attr = null; for (int i = 0; i < attributes.Count; i++) { @@ -404,7 +412,7 @@ private void ValidateAttributes(XmlElement elementNode) { //Do not validate namespace decls continue; } - _validator.ValidateAttribute(attr.LocalName, attr.NamespaceURI, _nodeValueGetter, _attributeSchemaInfo); + _validator!.ValidateAttribute(attr.LocalName, attr.NamespaceURI, _nodeValueGetter, _attributeSchemaInfo); if (_psviAugmentation) { attr.XmlName = _document.AddAttrXmlName(attr.Prefix, attr.LocalName, attr.NamespaceURI, _attributeSchemaInfo); @@ -422,21 +430,20 @@ private void ValidateAttributes(XmlElement elementNode) { _defaultAttributes.Clear(); } - _validator.GetUnspecifiedDefaultAttributes(_defaultAttributes); - XmlSchemaAttribute schemaAttribute = null; + _validator!.GetUnspecifiedDefaultAttributes(_defaultAttributes); XmlQualifiedName attrQName; attr = null; for (int i = 0; i < _defaultAttributes.Count; i++) { - schemaAttribute = _defaultAttributes[i] as XmlSchemaAttribute; + XmlSchemaAttribute schemaAttribute = (_defaultAttributes[i] as XmlSchemaAttribute)!; attrQName = schemaAttribute.QualifiedName; Debug.Assert(schemaAttribute != null); attr = _document.CreateDefaultAttribute(GetDefaultPrefix(attrQName.Namespace), attrQName.Name, attrQName.Namespace); SetDefaultAttributeSchemaInfo(schemaAttribute); attr.XmlName = _document.AddAttrXmlName(attr.Prefix, attr.LocalName, attr.NamespaceURI, _attributeSchemaInfo); - attr.AppendChild(_document.CreateTextNode(schemaAttribute.AttDef.DefaultValueRaw)); + attr.AppendChild(_document.CreateTextNode(schemaAttribute.AttDef!.DefaultValueRaw)); attributes.Append(attr); - XmlUnspecifiedAttribute defAttr = attr as XmlUnspecifiedAttribute; + XmlUnspecifiedAttribute? defAttr = attr as XmlUnspecifiedAttribute; if (defAttr != null) { defAttr.SetSpecified(false); @@ -455,20 +462,20 @@ private void SetDefaultAttributeSchemaInfo(XmlSchemaAttribute schemaAttribute) _attributeSchemaInfo.SchemaAttribute = schemaAttribute; //Get memberType for default attribute - SchemaAttDef attributeDef = schemaAttribute.AttDef; + SchemaAttDef attributeDef = schemaAttribute.AttDef!; if (attributeDef.Datatype.Variety == XmlSchemaDatatypeVariety.Union) { - XsdSimpleValue simpleValue = attributeDef.DefaultValueTyped as XsdSimpleValue; + XsdSimpleValue? simpleValue = attributeDef.DefaultValueTyped as XsdSimpleValue; Debug.Assert(simpleValue != null); _attributeSchemaInfo.MemberType = simpleValue.XmlType; } _attributeSchemaInfo.Validity = XmlSchemaValidity.Valid; } - private string GetDefaultPrefix(string attributeNS) + private string? GetDefaultPrefix(string attributeNS) { IDictionary namespaceDecls = NamespaceResolver.GetNamespacesInScope(XmlNamespaceScope.All); - string defaultPrefix = null; + string? defaultPrefix = null; string defaultNS; attributeNS = _nameTable.Add(attributeNS); //atomize ns @@ -484,43 +491,44 @@ private string GetDefaultPrefix(string attributeNS) } } } + return defaultPrefix; } - private object GetNodeValue() + private object? GetNodeValue() { - return _currentNode.Value; + return _currentNode!.Value; } //Code for finding type during partial validation - private XmlSchemaObject FindSchemaInfo(XmlElement elementToValidate) + private XmlSchemaObject? FindSchemaInfo(XmlElement elementToValidate) { _isPartialTreeValid = true; - Debug.Assert(elementToValidate.ParentNode.NodeType != XmlNodeType.Document); //Handle if it is the documentElement separately + Debug.Assert(elementToValidate.ParentNode!.NodeType != XmlNodeType.Document); //Handle if it is the documentElement separately //Create nodelist to navigate down again XmlNode currentNode = elementToValidate; - IXmlSchemaInfo parentSchemaInfo = null; + IXmlSchemaInfo? parentSchemaInfo = null; int nodeIndex = 0; //Check common case of parent node first - XmlNode parentNode = currentNode.ParentNode; + XmlNode? parentNode = currentNode.ParentNode; do { - parentSchemaInfo = parentNode.SchemaInfo; + parentSchemaInfo = parentNode!.SchemaInfo; if (parentSchemaInfo.SchemaElement != null || parentSchemaInfo.SchemaType != null) { break; //Found ancestor with schemaInfo } CheckNodeSequenceCapacity(nodeIndex); - _nodeSequenceToValidate[nodeIndex++] = parentNode; + _nodeSequenceToValidate![nodeIndex++] = parentNode; parentNode = parentNode.ParentNode; } while (parentNode != null); if (parentNode == null) { //Did not find any type info all the way to the root, currentNode is Document || DocumentFragment nodeIndex = nodeIndex - 1; //Subtract the one for document and set the node to null - _nodeSequenceToValidate[nodeIndex] = null; + _nodeSequenceToValidate![nodeIndex] = null; return GetTypeFromAncestors(elementToValidate, null, nodeIndex); } else @@ -528,8 +536,8 @@ private XmlSchemaObject FindSchemaInfo(XmlElement elementToValidate) //Start validating down from the parent or ancestor that has schema info and shallow validate all previous siblings //to correctly ascertain particle for current node CheckNodeSequenceCapacity(nodeIndex); - _nodeSequenceToValidate[nodeIndex++] = parentNode; - XmlSchemaObject ancestorSchemaObject = parentSchemaInfo.SchemaElement; + _nodeSequenceToValidate![nodeIndex++] = parentNode; + XmlSchemaObject? ancestorSchemaObject = parentSchemaInfo.SchemaElement; if (ancestorSchemaObject == null) { ancestorSchemaObject = parentSchemaInfo.SchemaType; @@ -563,23 +571,24 @@ private void CheckNodeSequenceCapacity(int currentIndex) } } - private XmlSchemaAttribute FindSchemaInfo(XmlAttribute attributeToValidate) + private XmlSchemaAttribute? FindSchemaInfo(XmlAttribute attributeToValidate) { - XmlElement parentElement = attributeToValidate.OwnerElement; - XmlSchemaObject schemaObject = FindSchemaInfo(parentElement); - XmlSchemaComplexType elementSchemaType = GetComplexType(schemaObject); + XmlElement parentElement = attributeToValidate.OwnerElement!; + XmlSchemaObject? schemaObject = FindSchemaInfo(parentElement); + XmlSchemaComplexType? elementSchemaType = GetComplexType(schemaObject); if (elementSchemaType == null) { return null; } + XmlQualifiedName attName = new XmlQualifiedName(attributeToValidate.LocalName, attributeToValidate.NamespaceURI); - XmlSchemaAttribute schemaAttribute = elementSchemaType.AttributeUses[attName] as XmlSchemaAttribute; + XmlSchemaAttribute? schemaAttribute = elementSchemaType.AttributeUses[attName] as XmlSchemaAttribute; if (schemaAttribute == null) { - XmlSchemaAnyAttribute anyAttribute = elementSchemaType.AttributeWildcard; + XmlSchemaAnyAttribute? anyAttribute = elementSchemaType.AttributeWildcard; if (anyAttribute != null) { - if (anyAttribute.NamespaceList.Allows(attName)) + if (anyAttribute.NamespaceList!.Allows(attName)) { //Match wildcard against global attribute schemaAttribute = _schemas.GlobalAttributes[attName] as XmlSchemaAttribute; } @@ -588,7 +597,7 @@ private XmlSchemaAttribute FindSchemaInfo(XmlAttribute attributeToValidate) return schemaAttribute; } - private XmlSchemaObject GetTypeFromAncestors(XmlElement elementToValidate, XmlSchemaObject ancestorType, int ancestorsCount) + private XmlSchemaObject? GetTypeFromAncestors(XmlElement elementToValidate, XmlSchemaObject? ancestorType, int ancestorsCount) { //schemaInfo is currentNode's schemaInfo _validator = CreateTypeFinderValidator(ancestorType); @@ -600,8 +609,8 @@ private XmlSchemaObject GetTypeFromAncestors(XmlElement elementToValidate, XmlSc bool ancestorHasWildCard = AncestorTypeHasWildcard(ancestorType); for (int i = startIndex; i >= 0; i--) { - XmlNode node = _nodeSequenceToValidate[i]; - XmlElement currentElement = node as XmlElement; + XmlNode node = _nodeSequenceToValidate![i]!; + XmlElement currentElement = (node as XmlElement)!; ValidateSingleElement(currentElement, false, _schemaInfo); if (!ancestorHasWildCard) { //store type if ancestor does not have wildcard in its content model @@ -613,7 +622,7 @@ private XmlSchemaObject GetTypeFromAncestors(XmlElement elementToValidate, XmlSc _validator.ValidateEndOfAttributes(null); if (i > 0) { - ValidateChildrenTillNextAncestor(node, _nodeSequenceToValidate[i - 1]); + ValidateChildrenTillNextAncestor(node, _nodeSequenceToValidate[i - 1]!); } else { //i == 0 @@ -621,11 +630,11 @@ private XmlSchemaObject GetTypeFromAncestors(XmlElement elementToValidate, XmlSc } } - Debug.Assert(_nodeSequenceToValidate[0] == elementToValidate.ParentNode); + Debug.Assert(_nodeSequenceToValidate![0] == elementToValidate.ParentNode); //validate element whose type is needed, ValidateSingleElement(elementToValidate, false, _schemaInfo); - XmlSchemaObject schemaInfoFound = null; + XmlSchemaObject? schemaInfoFound = null; if (_schemaInfo.SchemaElement != null) { schemaInfoFound = _schemaInfo.SchemaElement; @@ -651,24 +660,26 @@ private XmlSchemaObject GetTypeFromAncestors(XmlElement elementToValidate, XmlSc return schemaInfoFound; } - private bool AncestorTypeHasWildcard(XmlSchemaObject ancestorType) + private bool AncestorTypeHasWildcard(XmlSchemaObject? ancestorType) { - XmlSchemaComplexType ancestorSchemaType = GetComplexType(ancestorType); + XmlSchemaComplexType? ancestorSchemaType = GetComplexType(ancestorType); if (ancestorType != null) { - return ancestorSchemaType.HasWildCard; + return ancestorSchemaType!.HasWildCard; } + return false; } - private XmlSchemaComplexType GetComplexType(XmlSchemaObject schemaObject) + private XmlSchemaComplexType? GetComplexType(XmlSchemaObject? schemaObject) { if (schemaObject == null) { return null; } - XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement; - XmlSchemaComplexType complexType = null; + + XmlSchemaElement? schemaElement = schemaObject as XmlSchemaElement; + XmlSchemaComplexType? complexType = null; if (schemaElement != null) { complexType = schemaElement.ElementSchemaType as XmlSchemaComplexType; @@ -677,20 +688,21 @@ private XmlSchemaComplexType GetComplexType(XmlSchemaObject schemaObject) { complexType = schemaObject as XmlSchemaComplexType; } + return complexType; } - private void ValidateSingleElement(XmlElement elementNode, bool skipToEnd, XmlSchemaInfo newSchemaInfo) + private void ValidateSingleElement(XmlElement elementNode, bool skipToEnd, XmlSchemaInfo? newSchemaInfo) { _nsManager.PushScope(); Debug.Assert(elementNode != null); XmlAttributeCollection attributes = elementNode.Attributes; - XmlAttribute attr = null; + XmlAttribute? attr = null; //Find Xsi attributes that need to be processed before validating the element - string xsiNil = null; - string xsiType = null; + string? xsiNil = null; + string? xsiType = null; for (int i = 0; i < attributes.Count; i++) { @@ -716,19 +728,20 @@ private void ValidateSingleElement(XmlElement elementNode, bool skipToEnd, XmlSc _nsManager.AddNamespace(attr.Prefix.Length == 0 ? string.Empty : attr.LocalName, attr.Value); } } - _validator.ValidateElement(elementNode.LocalName, elementNode.NamespaceURI, newSchemaInfo, xsiType, xsiNil, null, null); + + _validator!.ValidateElement(elementNode.LocalName, elementNode.NamespaceURI, newSchemaInfo, xsiType, xsiNil, null, null); //Validate end of element if (skipToEnd) { - _validator.ValidateEndOfAttributes(newSchemaInfo); - _validator.SkipToEndElement(newSchemaInfo); + _validator!.ValidateEndOfAttributes(newSchemaInfo); + _validator!.SkipToEndElement(newSchemaInfo); _nsManager.PopScope(); //Pop current namespace scope } } private void ValidateChildrenTillNextAncestor(XmlNode parentNode, XmlNode childToStopAt) { - XmlNode child; + XmlNode? child; for (child = parentNode.FirstChild; child != null; child = child.NextSibling) { @@ -736,6 +749,7 @@ private void ValidateChildrenTillNextAncestor(XmlNode parentNode, XmlNode childT { break; } + switch (child.NodeType) { case XmlNodeType.EntityReference: @@ -743,17 +757,17 @@ private void ValidateChildrenTillNextAncestor(XmlNode parentNode, XmlNode childT break; case XmlNodeType.Element: //Flat validation, do not drill down into children - ValidateSingleElement(child as XmlElement, true, null); + ValidateSingleElement((child as XmlElement)!, true, null); break; case XmlNodeType.Text: case XmlNodeType.CDATA: - _validator.ValidateText(child.Value); + _validator!.ValidateText(child.Value!); break; case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - _validator.ValidateWhitespace(child.Value); + _validator!.ValidateWhitespace(child.Value!); break; case XmlNodeType.Comment: @@ -761,13 +775,14 @@ private void ValidateChildrenTillNextAncestor(XmlNode parentNode, XmlNode childT break; default: - throw new InvalidOperationException(SR.Format(SR.Xml_UnexpectedNodeType, _currentNode.NodeType)); + throw new InvalidOperationException(SR.Format(SR.Xml_UnexpectedNodeType, _currentNode!.NodeType)); } } + Debug.Assert(child == childToStopAt); } - private XmlSchemaValidator CreateTypeFinderValidator(XmlSchemaObject partialValidationType) + private XmlSchemaValidator CreateTypeFinderValidator(XmlSchemaObject? partialValidationType) { XmlSchemaValidator findTypeValidator = new XmlSchemaValidator(_document.NameTable, _document.Schemas, _nsManager, XmlSchemaValidationFlags.None); findTypeValidator.ValidationEventHandler += new ValidationEventHandler(TypeFinderCallBack); @@ -779,10 +794,11 @@ private XmlSchemaValidator CreateTypeFinderValidator(XmlSchemaObject partialVali { //If we walked up to the root and no schemaInfo was there, start validating from root findTypeValidator.Initialize(); } + return findTypeValidator; } - private void TypeFinderCallBack(object sender, ValidationEventArgs arg) + private void TypeFinderCallBack(object? sender, ValidationEventArgs arg) { if (arg.Severity == XmlSeverityType.Error) { @@ -790,13 +806,13 @@ private void TypeFinderCallBack(object sender, ValidationEventArgs arg) } } - private void InternalValidationCallBack(object sender, ValidationEventArgs arg) + private void InternalValidationCallBack(object? sender, ValidationEventArgs arg) { if (arg.Severity == XmlSeverityType.Error) { _isValid = false; } - XmlSchemaValidationException ex = arg.Exception as XmlSchemaValidationException; + XmlSchemaValidationException? ex = arg.Exception as XmlSchemaValidationException; Debug.Assert(ex != null); ex.SetSourceObject(_currentNode); if (_eventHandler != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs index ee8b229b33f0..8012cea5dfa3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -57,13 +58,13 @@ private enum Method private readonly DocumentXmlWriterType _type; // writer type private readonly XmlNode _start; // context node private readonly XmlDocument _document; // context document - private XmlNamespaceManager _namespaceManager; // context namespace manager + private XmlNamespaceManager? _namespaceManager; // context namespace manager private State _state; // current state - private XmlNode _write; // current node + private XmlNode? _write; // current node private readonly List _fragment; // top level node cache private readonly XmlWriterSettings _settings; // wrapping writer settings - private DocumentXPathNavigator _navigator; // context for replace - private XmlNode _end; // context for replace + private DocumentXPathNavigator? _navigator; // context for replace + private XmlNode? _end; // context for replace public DocumentXmlWriter(DocumentXmlWriterType type, XmlNode start, XmlDocument document) { @@ -81,7 +82,7 @@ public DocumentXmlWriter(DocumentXmlWriterType type, XmlNode start, XmlDocument _settings.ReadOnly = true; } - public XmlNamespaceManager NamespaceManager + public XmlNamespaceManager? NamespaceManager { set { @@ -97,7 +98,7 @@ public override XmlWriterSettings Settings } } - public DocumentXPathNavigator Navigator + public DocumentXPathNavigator? Navigator { set { @@ -126,9 +127,9 @@ internal override void WriteXmlDeclaration(XmlStandalone standalone) internal override void WriteXmlDeclaration(string xmldecl) { VerifyState(Method.WriteXmlDeclaration); - string version, encoding, standalone; + string? version, encoding, standalone; XmlLoader.ParseXmlDeclarationValue(xmldecl, out version, out encoding, out standalone); - XmlNode node = _document.CreateXmlDeclaration(version, encoding, standalone); + XmlNode node = _document.CreateXmlDeclaration(version!, encoding, standalone); AddChild(node, _write); } @@ -147,14 +148,14 @@ public override void WriteEndDocument() VerifyState(Method.WriteEndDocument); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { VerifyState(Method.WriteDocType); XmlNode node = _document.CreateDocumentType(name, pubid, sysid, subset); AddChild(node, _write); } - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { VerifyState(Method.WriteStartElement); XmlNode node = _document.CreateElement(prefix, localName, ns); @@ -169,6 +170,7 @@ public override void WriteEndElement() { throw new InvalidOperationException(); } + _write = _write.ParentNode; } @@ -180,11 +182,12 @@ internal override void WriteEndElement(string prefix, string localName, string n public override void WriteFullEndElement() { VerifyState(Method.WriteFullEndElement); - XmlElement elem = _write as XmlElement; + XmlElement? elem = _write as XmlElement; if (elem == null) { throw new InvalidOperationException(); } + elem.IsEmpty = false; _write = elem.ParentNode; } @@ -199,7 +202,7 @@ internal override void StartElementContent() // nop } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { VerifyState(Method.WriteStartAttribute); XmlAttribute attr = _document.CreateAttribute(prefix, localName, ns); @@ -210,16 +213,18 @@ public override void WriteStartAttribute(string prefix, string localName, string public override void WriteEndAttribute() { VerifyState(Method.WriteEndAttribute); - XmlAttribute attr = _write as XmlAttribute; + XmlAttribute? attr = _write as XmlAttribute; if (attr == null) { throw new InvalidOperationException(); } + if (!attr.HasChildNodes) { XmlNode node = _document.CreateTextNode(string.Empty); AddChild(node, attr); } + _write = attr.OwnerElement; } @@ -250,6 +255,7 @@ internal override void WriteStartNamespaceDeclaration(string prefix) { attr = _document.CreateAttribute(_document.strXmlns, prefix, _document.strReservedXmlns); } + AddAttribute(attr, _write); _write = attr; } @@ -257,20 +263,22 @@ internal override void WriteStartNamespaceDeclaration(string prefix) internal override void WriteEndNamespaceDeclaration() { VerifyState(Method.WriteEndNamespaceDeclaration); - XmlAttribute attr = _write as XmlAttribute; + XmlAttribute? attr = _write as XmlAttribute; if (attr == null) { throw new InvalidOperationException(); } + if (!attr.HasChildNodes) { XmlNode node = _document.CreateTextNode(string.Empty); AddChild(node, attr); } + _write = attr.OwnerElement; } - public override void WriteCData(string text) + public override void WriteCData(string? text) { VerifyState(Method.WriteCData); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); @@ -278,7 +286,7 @@ public override void WriteCData(string text) AddChild(node, _write); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { VerifyState(Method.WriteComment); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); @@ -286,11 +294,11 @@ public override void WriteComment(string text) AddChild(node, _write); } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { VerifyState(Method.WriteProcessingInstruction); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); - XmlNode node = _document.CreateProcessingInstruction(name, text); + XmlNode node = _document.CreateProcessingInstruction(name, text!); AddChild(node, _write); } @@ -307,7 +315,7 @@ public override void WriteCharEntity(char ch) WriteString(char.ToString(ch)); } - public override void WriteWhitespace(string text) + public override void WriteWhitespace(string? text) { VerifyState(Method.WriteWhitespace); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); @@ -318,7 +326,7 @@ public override void WriteWhitespace(string text) } } - public override void WriteString(string text) + public override void WriteString(string? text) { VerifyState(Method.WriteString); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); @@ -363,15 +371,17 @@ internal override void Close(WriteState currentState) switch (_type) { case DocumentXmlWriterType.InsertSiblingAfter: - XmlNode parent = _start.ParentNode; + XmlNode? parent = _start.ParentNode; if (parent == null) { throw new InvalidOperationException(SR.Xpn_MissingParent); } + for (int i = _fragment.Count - 1; i >= 0; i--) { parent.InsertAfter(_fragment[i], _start); } + break; case DocumentXmlWriterType.InsertSiblingBefore: parent = _start.ParentNode; @@ -379,22 +389,26 @@ internal override void Close(WriteState currentState) { throw new InvalidOperationException(SR.Xpn_MissingParent); } + for (int i = 0; i < _fragment.Count; i++) { parent.InsertBefore(_fragment[i], _start); } + break; case DocumentXmlWriterType.PrependChild: for (int i = _fragment.Count - 1; i >= 0; i--) { _start.PrependChild(_fragment[i]); } + break; case DocumentXmlWriterType.AppendChild: for (int i = 0; i < _fragment.Count; i++) { _start.AppendChild(_fragment[i]); } + break; case DocumentXmlWriterType.AppendAttribute: CloseWithAppendAttribute(); @@ -404,6 +418,7 @@ internal override void Close(WriteState currentState) { throw new InvalidOperationException(SR.Xpn_NoContent); } + CloseWithReplaceToFollowingSibling(); break; } @@ -416,12 +431,12 @@ internal override void Close(WriteState currentState) private void CloseWithAppendAttribute() { - XmlElement elem = _start as XmlElement; + XmlElement? elem = _start as XmlElement; Debug.Assert(elem != null); XmlAttributeCollection attrs = elem.Attributes; for (int i = 0; i < _fragment.Count; i++) { - XmlAttribute attr = _fragment[i] as XmlAttribute; + XmlAttribute? attr = _fragment[i] as XmlAttribute; Debug.Assert(attr != null); int offset = attrs.FindNodeOffsetNS(attr); if (offset != -1 @@ -432,7 +447,7 @@ private void CloseWithAppendAttribute() } for (int i = 0; i < _fragment.Count; i++) { - XmlAttribute attr = _fragment[i] as XmlAttribute; + XmlAttribute? attr = _fragment[i] as XmlAttribute; Debug.Assert(attr != null); attrs.Append(attr); } @@ -440,11 +455,12 @@ private void CloseWithAppendAttribute() private void CloseWithReplaceToFollowingSibling() { - XmlNode parent = _start.ParentNode; + XmlNode? parent = _start.ParentNode; if (parent == null) { throw new InvalidOperationException(SR.Xpn_MissingParent); } + if (_start != _end) { if (!DocumentXPathNavigator.IsFollowingSibling(_start, _end)) @@ -455,15 +471,18 @@ private void CloseWithReplaceToFollowingSibling() { throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly); } + DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling, _end); } + XmlNode fragment0 = _fragment[0]; parent.ReplaceChild(fragment0, _start); for (int i = _fragment.Count - 1; i >= 1; i--) { parent.InsertAfter(_fragment[i], fragment0); } - _navigator.ResetPosition(fragment0); + + _navigator!.ResetPosition(fragment0); } public override void Flush() @@ -473,20 +492,20 @@ public override void Flush() IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope) { - return _namespaceManager.GetNamespacesInScope(scope); + return _namespaceManager!.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { - return _namespaceManager.LookupNamespace(prefix); + return _namespaceManager!.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { - return _namespaceManager.LookupPrefix(namespaceName); + return _namespaceManager!.LookupPrefix(namespaceName); } - private void AddAttribute(XmlAttribute attr, XmlNode parent) + private void AddAttribute(XmlAttribute attr, XmlNode? parent) { if (parent == null) { @@ -494,16 +513,17 @@ private void AddAttribute(XmlAttribute attr, XmlNode parent) } else { - XmlElement elem = parent as XmlElement; + XmlElement? elem = parent as XmlElement; if (elem == null) { throw new InvalidOperationException(); } + elem.Attributes.Append(attr); } } - private void AddChild(XmlNode node, XmlNode parent) + private void AddChild(XmlNode node, XmlNode? parent) { if (parent == null) { @@ -523,11 +543,12 @@ private State StartState() { case DocumentXmlWriterType.InsertSiblingAfter: case DocumentXmlWriterType.InsertSiblingBefore: - XmlNode parent = _start.ParentNode; + XmlNode? parent = _start.ParentNode; if (parent != null) { nodeType = parent.NodeType; } + if (nodeType == XmlNodeType.Document) { return State.Prolog; @@ -536,6 +557,7 @@ private State StartState() { return State.Fragment; } + break; case DocumentXmlWriterType.PrependChild: case DocumentXmlWriterType.AppendChild: @@ -548,6 +570,7 @@ private State StartState() { return State.Fragment; } + break; case DocumentXmlWriterType.AppendAttribute: return State.Attribute; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DomNameTable.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DomNameTable.cs index 593cae97e43d..6e1879545377 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DomNameTable.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DomNameTable.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.Schema; @@ -26,7 +27,7 @@ public DomNameTable(XmlDocument document) Debug.Assert((_entries.Length & _mask) == 0); // entries.Length must be a power of two } - public XmlName GetName(string prefix, string localName, string ns, IXmlSchemaInfo schemaInfo) + public XmlName? GetName(string? prefix, string localName, string? ns, IXmlSchemaInfo? schemaInfo) { if (prefix == null) { @@ -56,7 +57,7 @@ public XmlName GetName(string prefix, string localName, string ns, IXmlSchemaInf return null; } - public XmlName AddName(string prefix, string localName, string ns, IXmlSchemaInfo schemaInfo) + public XmlName AddName(string? prefix, string localName, string? ns, IXmlSchemaInfo? schemaInfo) { if (prefix == null) { @@ -118,6 +119,7 @@ private void Grow() name = tmp; } } + _entries = newEntries; _mask = newMask; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs index ccc26c0fd8dc..520267634f86 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.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. +#nullable enable namespace System.Xml { using System.Xml.XPath; @@ -10,14 +11,14 @@ namespace System.Xml internal class XPathNodeList : XmlNodeList { - private readonly List _list; + private readonly List _list; private readonly XPathNodeIterator _nodeIterator; private bool _done; public XPathNodeList(XPathNodeIterator nodeIterator) { _nodeIterator = nodeIterator; - _list = new List(); + _list = new List(); _done = false; } @@ -62,7 +63,7 @@ internal int ReadUntil(int index) return count; } - public override XmlNode Item(int index) + public override XmlNode? Item(int index) { if (_list.Count <= index) { @@ -72,6 +73,7 @@ public override XmlNode Item(int index) { return null; } + return _list[index]; } @@ -111,7 +113,7 @@ public bool MoveNext() return _valid; } - public object Current + public object? Current { get { @@ -119,6 +121,7 @@ public object Current { return _list[_index]; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttribute.cs index a8d6230e8763..24e11bda6ed9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttribute.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Xml.Schema; using System.Xml.XPath; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -13,7 +15,7 @@ namespace System.Xml public class XmlAttribute : XmlNode { private XmlName _name; - private XmlLinkedNode _lastChild; + private XmlLinkedNode? _lastChild; internal XmlAttribute(XmlName name, XmlDocument doc) : base(doc) { @@ -35,7 +37,7 @@ internal int LocalNameHash get { return _name.HashCode; } } - protected internal XmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc) + protected internal XmlAttribute(string? prefix, string localName, string? namespaceURI, XmlDocument doc) : this(doc.AddAttrXmlName(prefix, localName, namespaceURI, null), doc) { } @@ -58,7 +60,7 @@ public override XmlNode CloneNode(bool deep) } // Gets the parent of this node (for nodes that can have parents). - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { return null; } } @@ -104,10 +106,11 @@ public override XmlDocument OwnerDocument } // Gets or sets the value of the node. + [AllowNull] public override string Value { get { return InnerText; } - set { InnerText = value; } //use InnerText which has perf optimization + set { InnerText = value!; } //use InnerText which has perf optimization } public override IXmlSchemaInfo SchemaInfo @@ -140,18 +143,19 @@ internal bool PrepareOwnerElementInElementIdAttrMap() XmlDocument ownerDocument = OwnerDocument; if (ownerDocument.DtdSchemaInfo != null) { // DTD exists - XmlElement ownerElement = OwnerElement; + XmlElement? ownerElement = OwnerElement; if (ownerElement != null) { return ownerElement.Attributes.PrepareParentInElementIdAttrMap(Prefix, LocalName); } } + return false; } internal void ResetOwnerElementInElementIdAttrMap(string oldInnerText) { - XmlElement ownerElement = OwnerElement; + XmlElement? ownerElement = OwnerElement; if (ownerElement != null) { ownerElement.Attributes.ResetParentInElementIdAttrMap(oldInnerText, InnerText); @@ -166,7 +170,7 @@ internal override bool IsContainer //the function is provided only at Load time to speed up Load process internal override XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc) { - XmlNodeChangedEventArgs args = doc.GetInsertEventArgsForLoad(newChild, this); + XmlNodeChangedEventArgs? args = doc.GetInsertEventArgsForLoad(newChild, this); if (args != null) doc.BeforeEvent(args); @@ -202,7 +206,7 @@ internal override XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc) return newNode; } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { return _lastChild; } set { _lastChild = value; } @@ -219,12 +223,12 @@ public virtual bool Specified get { return true; } } - public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) + public override XmlNode? InsertBefore(XmlNode newChild, XmlNode? refChild) { - XmlNode node; + XmlNode? node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.InsertBefore(newChild, refChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -232,15 +236,16 @@ public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) { node = base.InsertBefore(newChild, refChild); } + return node; } - public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) + public override XmlNode? InsertAfter(XmlNode newChild, XmlNode? refChild) { - XmlNode node; + XmlNode? node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.InsertAfter(newChild, refChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -248,6 +253,7 @@ public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) { node = base.InsertAfter(newChild, refChild); } + return node; } @@ -256,7 +262,7 @@ public override XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild) XmlNode node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.ReplaceChild(newChild, oldChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -272,7 +278,7 @@ public override XmlNode RemoveChild(XmlNode oldChild) XmlNode node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.RemoveChild(oldChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -283,12 +289,12 @@ public override XmlNode RemoveChild(XmlNode oldChild) return node; } - public override XmlNode PrependChild(XmlNode newChild) + public override XmlNode? PrependChild(XmlNode newChild) { - XmlNode node; + XmlNode? node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.PrependChild(newChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -296,15 +302,16 @@ public override XmlNode PrependChild(XmlNode newChild) { node = base.PrependChild(newChild); } + return node; } - public override XmlNode AppendChild(XmlNode newChild) + public override XmlNode? AppendChild(XmlNode newChild) { - XmlNode node; + XmlNode? node; if (PrepareOwnerElementInElementIdAttrMap()) { - string innerText = InnerText; + string? innerText = InnerText; node = base.AppendChild(newChild); ResetOwnerElementInElementIdAttrMap(innerText); } @@ -312,13 +319,14 @@ public override XmlNode AppendChild(XmlNode newChild) { node = base.AppendChild(newChild); } + return node; } // DOM Level 2 // Gets the XmlElement node that contains this attribute. - public virtual XmlElement OwnerElement + public virtual XmlElement? OwnerElement { get { @@ -348,7 +356,7 @@ public override void WriteTo(XmlWriter w) // Saves all the children of the node to the specified XmlWriter. public override void WriteContentTo(XmlWriter w) { - for (XmlNode node = FirstChild; node != null; node = node.NextSibling) + for (XmlNode? node = FirstChild; node != null; node = node.NextSibling) { node.WriteTo(w); } @@ -364,7 +372,7 @@ public override string BaseURI } } - internal override void SetParent(XmlNode node) + internal override void SetParent(XmlNode? node) { this.parentNode = node; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttributeCollection.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttributeCollection.cs index 6273f18640c5..b2fd07dfb225 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttributeCollection.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlAttributeCollection.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -32,7 +34,7 @@ public XmlAttribute this[int i] // Gets the attribute with the specified name. [System.Runtime.CompilerServices.IndexerName("ItemOf")] - public XmlAttribute this[string name] + public XmlAttribute? this[string name] { get { @@ -55,7 +57,7 @@ public XmlAttribute this[string name] // Gets the attribute with the specified LocalName and NamespaceUri. [System.Runtime.CompilerServices.IndexerName("ItemOf")] - public XmlAttribute this[string localName, string namespaceURI] + public XmlAttribute? this[string localName, string? namespaceURI] { get { @@ -90,6 +92,7 @@ internal int FindNodeOffset(XmlAttribute node) return i; } } + return -1; } @@ -109,7 +112,8 @@ internal int FindNodeOffsetNS(XmlAttribute node) } // Adds a XmlNode using its Name property - public override XmlNode SetNamedItem(XmlNode node) + [return: NotNullIfNotNull("node")] + public override XmlNode? SetNamedItem(XmlNode? node) { if (node == null) return null; @@ -170,7 +174,7 @@ public XmlAttribute Append(XmlAttribute node) } // Inserts the specified attribute immediately before the specified reference attribute. - public XmlAttribute InsertBefore(XmlAttribute newNode, XmlAttribute refNode) + public XmlAttribute InsertBefore(XmlAttribute newNode, XmlAttribute? refNode) { if (newNode == refNode) return newNode; @@ -199,7 +203,7 @@ public XmlAttribute InsertBefore(XmlAttribute newNode, XmlAttribute refNode) } // Inserts the specified attribute immediately after the specified reference attribute. - public XmlAttribute InsertAfter(XmlAttribute newNode, XmlAttribute refNode) + public XmlAttribute InsertAfter(XmlAttribute newNode, XmlAttribute? refNode) { if (newNode == refNode) return newNode; @@ -228,7 +232,7 @@ public XmlAttribute InsertAfter(XmlAttribute newNode, XmlAttribute refNode) } // Removes the specified attribute node from the map. - public XmlAttribute Remove(XmlAttribute node) + public XmlAttribute? Remove(XmlAttribute? node) { int cNodes = nodes.Count; for (int offset = 0; offset < cNodes; offset++) @@ -239,11 +243,12 @@ public XmlAttribute Remove(XmlAttribute node) return node; } } + return null; } // Removes the attribute node with the specified index from the map. - public XmlAttribute RemoveAt(int i) + public XmlAttribute? RemoveAt(int i) { if (i < 0 || i >= Count) return null; @@ -315,26 +320,28 @@ internal override XmlNode RemoveNodeAt(int i) Debug.Assert(retNode is XmlAttribute); RemoveParentFromElementIdAttrMap((XmlAttribute)retNode); // after remove the attribute, we need to check if a default attribute node should be created and inserted into the tree - XmlAttribute defattr = parent.OwnerDocument.GetDefaultAttribute((XmlElement)parent, retNode.Prefix, retNode.LocalName, retNode.NamespaceURI); + XmlAttribute? defattr = parent.OwnerDocument!.GetDefaultAttribute((XmlElement)parent, retNode.Prefix, retNode.LocalName, retNode.NamespaceURI); if (defattr != null) InsertNodeAt(i, defattr); + return retNode; } internal void Detach(XmlAttribute attr) { - attr.OwnerElement.Attributes.Remove(attr); + attr.OwnerElement!.Attributes.Remove(attr); } //insert the parent element node into the map internal void InsertParentIntoElementIdAttrMap(XmlAttribute attr) { - XmlElement parentElem = parent as XmlElement; + XmlElement? parentElem = parent as XmlElement; if (parentElem != null) { if (parent.OwnerDocument == null) return; - XmlName attrname = parent.OwnerDocument.GetIDInfoByElement(parentElem.XmlName); + + XmlName? attrname = parent.OwnerDocument.GetIDInfoByElement(parentElem.XmlName); if (attrname != null && attrname.Prefix == attr.XmlName.Prefix && attrname.LocalName == attr.XmlName.LocalName) { parent.OwnerDocument.AddElementWithId(attr.Value, parentElem); //add the element into the hashtable @@ -345,12 +352,13 @@ internal void InsertParentIntoElementIdAttrMap(XmlAttribute attr) //remove the parent element node from the map when the ID attribute is removed internal void RemoveParentFromElementIdAttrMap(XmlAttribute attr) { - XmlElement parentElem = parent as XmlElement; + XmlElement? parentElem = parent as XmlElement; if (parentElem != null) { if (parent.OwnerDocument == null) return; - XmlName attrname = parent.OwnerDocument.GetIDInfoByElement(parentElem.XmlName); + + XmlName? attrname = parent.OwnerDocument.GetIDInfoByElement(parentElem.XmlName); if (attrname != null && attrname.Prefix == attr.XmlName.Prefix && attrname.LocalName == attr.XmlName.LocalName) { parent.OwnerDocument.RemoveElementWithId(attr.Value, parentElem); //remove the element from the hashtable @@ -375,25 +383,26 @@ internal int RemoveDuplicateAttribute(XmlAttribute attr) internal bool PrepareParentInElementIdAttrMap(string attrPrefix, string attrLocalName) { - XmlElement parentElem = parent as XmlElement; + XmlElement? parentElem = parent as XmlElement; Debug.Assert(parentElem != null); - XmlDocument doc = parent.OwnerDocument; + XmlDocument? doc = parent.OwnerDocument; Debug.Assert(doc != null); //The returned attrname if not null is the name with namespaceURI being set to string.Empty //Because DTD doesn't support namespaceURI so all comparisons are based on no namespaceURI (string.Empty); - XmlName attrname = doc.GetIDInfoByElement(parentElem.XmlName); + XmlName? attrname = doc.GetIDInfoByElement(parentElem.XmlName); if (attrname != null && attrname.Prefix == attrPrefix && attrname.LocalName == attrLocalName) { return true; } + return false; } internal void ResetParentInElementIdAttrMap(string oldVal, string newVal) { - XmlElement parentElem = parent as XmlElement; + XmlElement? parentElem = parent as XmlElement; Debug.Assert(parentElem != null); - XmlDocument doc = parent.OwnerDocument; + XmlDocument? doc = parent.OwnerDocument; Debug.Assert(doc != null); doc.RemoveElementWithId(oldVal, parentElem); //add the element into the hashtable doc.AddElementWithId(newVal, parentElem); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCDataSection.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCDataSection.cs index b2f52d52186d..86f65d649bc9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCDataSection.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCDataSection.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -10,7 +11,7 @@ namespace System.Xml // interpreted as markup language. public class XmlCDataSection : XmlCharacterData { - protected internal XmlCDataSection(string data, XmlDocument doc) : base(data, doc) + protected internal XmlCDataSection(string? data, XmlDocument doc) : base(data, doc) { } @@ -19,7 +20,7 @@ public override string Name { get { - return OwnerDocument.strCDataSectionName; + return OwnerDocument!.strCDataSectionName; } } @@ -28,7 +29,7 @@ public override string LocalName { get { - return OwnerDocument.strCDataSectionName; + return OwnerDocument!.strCDataSectionName; } } @@ -41,11 +42,11 @@ public override XmlNodeType NodeType } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { - switch (parentNode.NodeType) + switch (parentNode!.NodeType) { case XmlNodeType.Document: return null; @@ -53,11 +54,12 @@ public override XmlNode ParentNode case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - XmlNode parent = parentNode.parentNode; + XmlNode parent = parentNode.parentNode!; while (parent.IsText) { - parent = parent.parentNode; + parent = parent.parentNode!; } + return parent; default: return parentNode; @@ -100,14 +102,15 @@ internal override bool IsText } } - public override XmlNode PreviousText + public override XmlNode? PreviousText { get { - if (parentNode.IsText) + if (parentNode != null && parentNode.IsText) { return parentNode; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCharacterData.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCharacterData.cs index c03e0e290e36..f5d7f610c5d3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCharacterData.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlCharacterData.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text; using System.Xml.XPath; @@ -10,16 +12,16 @@ namespace System.Xml // Provides text-manipulation methods that are used by several classes. public abstract class XmlCharacterData : XmlLinkedNode { - private string _data; + private string? _data; //base(doc) will throw exception if doc is null. - protected internal XmlCharacterData(string data, XmlDocument doc) : base(doc) + protected internal XmlCharacterData(string? data, XmlDocument doc) : base(doc) { _data = data; } // Gets or sets the value of the node. - public override string Value + public override string? Value { get { return Data; } set { Data = value; } @@ -29,11 +31,12 @@ public override string Value // all its children. public override string InnerText { - get { return Value; } + get { return Value!; } set { Value = value; } } // Contains this node's data. + [AllowNull] public virtual string Data { get @@ -50,8 +53,8 @@ public virtual string Data set { - XmlNode parent = ParentNode; - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, value, XmlNodeChangedAction.Change); + XmlNode? parent = ParentNode; + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, value, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); @@ -86,20 +89,21 @@ public virtual string Substring(int offset, int count) { count = len - offset; } - return _data.Substring(offset, count); + + return _data!.Substring(offset, count); } return string.Empty; } // Appends the specified string to the end of the character // data of the node. - public virtual void AppendData(string strData) + public virtual void AppendData(string? strData) { - XmlNode parent = ParentNode; + XmlNode? parent = ParentNode; int capacity = _data != null ? _data.Length : 0; if (strData != null) capacity += strData.Length; string newValue = new StringBuilder(capacity).Append(_data).Append(strData).ToString(); - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); @@ -111,13 +115,13 @@ public virtual void AppendData(string strData) } // Insert the specified string at the specified character offset. - public virtual void InsertData(int offset, string strData) + public virtual void InsertData(int offset, string? strData) { - XmlNode parent = ParentNode; + XmlNode? parent = ParentNode; int capacity = _data != null ? _data.Length : 0; if (strData != null) capacity += strData.Length; string newValue = new StringBuilder(capacity).Append(_data).Insert(offset, strData).ToString(); - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); @@ -142,8 +146,8 @@ public virtual void DeleteData(int offset, int count) } string newValue = new StringBuilder(_data).Remove(offset, count).ToString(); - XmlNode parent = ParentNode; - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); + XmlNode? parent = ParentNode; + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); @@ -156,7 +160,7 @@ public virtual void DeleteData(int offset, int count) // Replace the specified number of characters starting at the specified offset with the // specified string. - public virtual void ReplaceData(int offset, int count, string strData) + public virtual void ReplaceData(int offset, int count, string? strData) { int len = _data != null ? _data.Length : 0; if (len > 0) @@ -170,8 +174,8 @@ public virtual void ReplaceData(int offset, int count, string strData) StringBuilder temp = new StringBuilder(_data).Remove(offset, count); string newValue = temp.Insert(offset, strData).ToString(); - XmlNode parent = ParentNode; - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); + XmlNode? parent = ParentNode; + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, newValue, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); @@ -182,7 +186,7 @@ public virtual void ReplaceData(int offset, int count, string strData) AfterEvent(args); } - internal bool CheckOnData(string data) + internal bool CheckOnData(string? data) { return XmlCharType.Instance.IsOnlyWhitespace(data); } @@ -194,10 +198,11 @@ internal bool DecideXPNodeTypeForTextNodes(XmlNode node, ref XPathNodeType xnt) //changes according to the siblings nodetype and will contain the correct //nodetype when it returns. - Debug.Assert(XmlDocument.IsTextNode(node.NodeType) || (node.ParentNode != null && node.ParentNode.NodeType == XmlNodeType.EntityReference)); - while (node != null) + XmlNode? n = node; + Debug.Assert(XmlDocument.IsTextNode(n.NodeType) || (n.ParentNode != null && n.ParentNode.NodeType == XmlNodeType.EntityReference)); + while (n != null) { - switch (node.NodeType) + switch (n.NodeType) { case XmlNodeType.Whitespace: break; @@ -209,7 +214,7 @@ internal bool DecideXPNodeTypeForTextNodes(XmlNode node, ref XPathNodeType xnt) xnt = XPathNodeType.Text; return false; case XmlNodeType.EntityReference: - if (!DecideXPNodeTypeForTextNodes(node.FirstChild, ref xnt)) + if (!DecideXPNodeTypeForTextNodes(n.FirstChild!, ref xnt)) { return false; } @@ -217,7 +222,7 @@ internal bool DecideXPNodeTypeForTextNodes(XmlNode node, ref XPathNodeType xnt) default: return false; } - node = node.NextSibling; + n = n.NextSibling; } return true; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildEnumerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildEnumerator.cs index a5011a9de6dc..463b96689ca3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildEnumerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildEnumerator.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. +#nullable enable using System.Collections; namespace System.Xml @@ -8,7 +9,7 @@ namespace System.Xml internal sealed class XmlChildEnumerator : IEnumerator { internal XmlNode container; - internal XmlNode child; + internal XmlNode? child; internal bool isFirst; internal XmlChildEnumerator(XmlNode container) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildNodes.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildNodes.cs index 39bf493c2281..865f5b13b420 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildNodes.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlChildNodes.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. +#nullable enable using System.Collections; namespace System.Xml @@ -14,16 +15,18 @@ public XmlChildNodes(XmlNode container) _container = container; } - public override XmlNode Item(int i) + public override XmlNode? Item(int i) { // Out of range indexes return a null XmlNode if (i < 0) return null; - for (XmlNode n = _container.FirstChild; n != null; n = n.NextSibling, i--) + + for (XmlNode? n = _container.FirstChild; n != null; n = n.NextSibling, i--) { if (i == 0) return n; } + return null; } @@ -32,10 +35,11 @@ public override int Count get { int c = 0; - for (XmlNode n = _container.FirstChild; n != null; n = n.NextSibling) + for (XmlNode? n = _container.FirstChild; n != null; n = n.NextSibling) { c++; } + return c; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlComment.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlComment.cs index 2f5252476a5b..d9ea593dc87b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlComment.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlComment.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -9,20 +10,20 @@ namespace System.Xml // Represents the content of an XML comment. public class XmlComment : XmlCharacterData { - protected internal XmlComment(string comment, XmlDocument doc) : base(comment, doc) + protected internal XmlComment(string? comment, XmlDocument doc) : base(comment, doc) { } // Gets the name of the node. public override string Name { - get { return OwnerDocument.strCommentName; } + get { return OwnerDocument!.strCommentName; } } // Gets the name of the current node without the namespace prefix. public override string LocalName { - get { return OwnerDocument.strCommentName; } + get { return OwnerDocument!.strCommentName; } } // Gets the type of the current node. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs index b4e9251448ae..4544ca733cb7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -17,7 +19,7 @@ public class XmlDeclaration : XmlLinkedNode private string _encoding; private string _standalone; - protected internal XmlDeclaration(string version, string encoding, string standalone, XmlDocument doc) : base(doc) + protected internal XmlDeclaration(string version, string? encoding, string? standalone, XmlDocument doc) : base(doc) { if (!IsValidXmlVersion(version)) throw new ArgumentException(SR.Xdom_Version); @@ -34,21 +36,26 @@ protected internal XmlDeclaration(string version, string encoding, string standa public string Version { get { return _version; } + [MemberNotNull(nameof(_version))] internal set { _version = value; } } // Specifies the value of the encoding attribute, as for // + [AllowNull] public string Encoding { get { return _encoding; } + [MemberNotNull(nameof(_encoding))] set { _encoding = ((value == null) ? string.Empty : value); } } // Specifies the value of the standalone attribute. + [AllowNull] public string Standalone { get { return _standalone; } + [MemberNotNull(nameof(_standalone))] set { if (value == null) @@ -60,10 +67,10 @@ public string Standalone } } - public override string Value + public override string? Value { get { return InnerText; } - set { InnerText = value; } + set { InnerText = value!; } } @@ -89,17 +96,18 @@ public override string InnerText strb.Append(Standalone); strb.Append('"'); } + return StringBuilderCache.GetStringAndRelease(strb); } set { - string tempVersion = null; - string tempEncoding = null; - string tempStandalone = null; + string? tempVersion = null; + string? tempEncoding = null; + string? tempStandalone = null; string orgEncoding = this.Encoding; string orgStandalone = this.Standalone; - string orgVersion = this.Version; + string? orgVersion = this.Version; XmlLoader.ParseXmlDeclarationValue(value, out tempVersion, out tempEncoding, out tempStandalone); @@ -107,7 +115,7 @@ public override string InnerText { if (tempVersion != null && !IsValidXmlVersion(tempVersion)) throw new ArgumentException(SR.Xdom_Version); - Version = tempVersion; + Version = tempVersion!; if (tempEncoding != null) Encoding = tempEncoding; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs index 7ced05fdb205..a254bee81f1d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs @@ -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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -12,6 +13,7 @@ using System.Security; using System.Globalization; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -72,24 +74,24 @@ private static readonly (string key, int hash)[] s_nameTableSeeds = new[] private readonly XmlImplementation _implementation; private readonly DomNameTable _domNameTable; // hash table of XmlName - private XmlLinkedNode _lastChild; - private XmlNamedNodeMap _entities; - private Hashtable _htElementIdMap; - private Hashtable _htElementIDAttrDecl; //key: id; object: the ArrayList of the elements that have the same id (connected or disconnected) - private SchemaInfo _schemaInfo; - private XmlSchemaSet _schemas; // schemas associated with the cache + private XmlLinkedNode? _lastChild; + private XmlNamedNodeMap? _entities; + private Hashtable? _htElementIdMap; + private Hashtable? _htElementIDAttrDecl; //key: id; object: the ArrayList of the elements that have the same id (connected or disconnected) + private SchemaInfo? _schemaInfo; + private XmlSchemaSet? _schemas; // schemas associated with the cache private bool _reportValidity; //This variable represents the actual loading status. Since, IsLoading will //be manipulated sometimes for adding content to EntityReference this variable //has been added which would always represent the loading status of document. private bool _actualLoadingStatus; - private XmlNodeChangedEventHandler _onNodeInsertingDelegate; - private XmlNodeChangedEventHandler _onNodeInsertedDelegate; - private XmlNodeChangedEventHandler _onNodeRemovingDelegate; - private XmlNodeChangedEventHandler _onNodeRemovedDelegate; - private XmlNodeChangedEventHandler _onNodeChangingDelegate; - private XmlNodeChangedEventHandler _onNodeChangedDelegate; + private XmlNodeChangedEventHandler? _onNodeInsertingDelegate; + private XmlNodeChangedEventHandler? _onNodeInsertedDelegate; + private XmlNodeChangedEventHandler? _onNodeRemovingDelegate; + private XmlNodeChangedEventHandler? _onNodeRemovedDelegate; + private XmlNodeChangedEventHandler? _onNodeChangingDelegate; + private XmlNodeChangedEventHandler? _onNodeChangedDelegate; // false if there are no ent-ref present, true if ent-ref nodes are or were present (i.e. if all ent-ref were removed, the doc will not clear this flag) internal bool fEntRefNodesPresent; @@ -118,11 +120,11 @@ private static readonly (string key, int hash)[] s_nameTableSeeds = new[] internal string baseURI; - private XmlResolver _resolver; + private XmlResolver? _resolver; internal bool bSetResolver; internal object objLock; - private XmlAttribute _namespaceXml; + private XmlAttribute? _namespaceXml; internal static EmptyEnumerator EmptyEnumerator = new EmptyEnumerator(); internal static IXmlSchemaInfo NotKnownSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.NotKnown); @@ -194,7 +196,7 @@ protected internal XmlDocument(XmlImplementation imp) : base() } } - internal SchemaInfo DtdSchemaInfo + internal SchemaInfo? DtdSchemaInfo { get { return _schemaInfo; } set { _schemaInfo = value; } @@ -210,7 +212,7 @@ internal static void CheckName(string name) } } - internal XmlName AddXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) + internal XmlName AddXmlName(string? prefix, string localName, string? namespaceURI, IXmlSchemaInfo? schemaInfo) { XmlName n = _domNameTable.AddName(prefix, localName, namespaceURI, schemaInfo); Debug.Assert((prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix)); @@ -219,16 +221,16 @@ internal XmlName AddXmlName(string prefix, string localName, string namespaceURI return n; } - internal XmlName GetXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) + internal XmlName? GetXmlName(string? prefix, string localName, string? namespaceURI, IXmlSchemaInfo? schemaInfo) { - XmlName n = _domNameTable.GetName(prefix, localName, namespaceURI, schemaInfo); + XmlName? n = _domNameTable.GetName(prefix, localName, namespaceURI, schemaInfo); Debug.Assert(n == null || ((prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix))); Debug.Assert(n == null || n.LocalName == localName); Debug.Assert(n == null || ((namespaceURI == null) ? (n.NamespaceURI.Length == 0) : (n.NamespaceURI == namespaceURI))); return n; } - internal XmlName AddAttrXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) + internal XmlName AddAttrXmlName(string? prefix, string localName, string? namespaceURI, IXmlSchemaInfo? schemaInfo) { XmlName xmlName = AddXmlName(prefix, localName, namespaceURI, schemaInfo); Debug.Assert((prefix == null) ? (xmlName.Prefix.Length == 0) : (prefix == xmlName.Prefix)); @@ -262,20 +264,20 @@ internal bool AddIdInfo(XmlName eleName, XmlName attrName) return false; } - private XmlName GetIDInfoByElement_(XmlName eleName) + private XmlName? GetIDInfoByElement_(XmlName eleName) { //When XmlDocument is getting the IDAttribute for a given element, //we need only compare the prefix and localname of element.XmlName with //the registered htElementIDAttrDecl. - XmlName newName = GetXmlName(eleName.Prefix, eleName.LocalName, string.Empty, null); + XmlName? newName = GetXmlName(eleName.Prefix, eleName.LocalName, string.Empty, null); if (newName != null) { - return (XmlName)(_htElementIDAttrDecl[newName]); + return (XmlName?)(_htElementIDAttrDecl![newName]); } return null; } - internal XmlName GetIDInfoByElement(XmlName eleName) + internal XmlName? GetIDInfoByElement(XmlName eleName) { if (_htElementIDAttrDecl == null) return null; @@ -283,7 +285,7 @@ internal XmlName GetIDInfoByElement(XmlName eleName) return GetIDInfoByElement_(eleName); } - private WeakReference GetElement(ArrayList elementList, XmlElement elem) + private WeakReference? GetElement(ArrayList elementList, XmlElement elem) { ArrayList gcElemRefs = new ArrayList(); foreach (WeakReference elemRef in elementList) @@ -293,7 +295,7 @@ private WeakReference GetElement(ArrayList elementList, XmlElement elem) gcElemRefs.Add(elemRef); else { - if ((XmlElement)(elemRef.Target) == elem) + if ((XmlElement?)(elemRef.Target) == elem) return elemRef; } } @@ -316,7 +318,7 @@ internal void AddElementWithId(string id, XmlElement elem) else { // there are other element(s) that has the same id - ArrayList elementList = (ArrayList)(_htElementIdMap[id]); + ArrayList elementList = (ArrayList)(_htElementIdMap[id]!); if (GetElement(elementList, elem) == null) elementList.Add(new WeakReference(elem)); } @@ -326,8 +328,8 @@ internal void RemoveElementWithId(string id, XmlElement elem) { if (_htElementIdMap != null && _htElementIdMap.Contains(id)) { - ArrayList elementList = (ArrayList)(_htElementIdMap[id]); - WeakReference elemRef = GetElement(elementList, elem); + ArrayList elementList = (ArrayList)(_htElementIdMap[id]!); + WeakReference? elemRef = GetElement(elementList, elem); if (elemRef != null) { elementList.Remove(elemRef); @@ -355,24 +357,24 @@ public override XmlNodeType NodeType get { return XmlNodeType.Document; } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { return null; } } // Gets the node for the DOCTYPE declaration. - public virtual XmlDocumentType DocumentType + public virtual XmlDocumentType? DocumentType { - get { return (XmlDocumentType)FindChild(XmlNodeType.DocumentType); } + get { return (XmlDocumentType?)FindChild(XmlNodeType.DocumentType); } } - internal virtual XmlDeclaration Declaration + internal virtual XmlDeclaration? Declaration { get { if (HasChildNodes) { - XmlDeclaration dec = FirstChild as XmlDeclaration; + XmlDeclaration? dec = FirstChild as XmlDeclaration; return dec; } return null; @@ -398,9 +400,9 @@ public override string LocalName } // Gets the root XmlElement for the document. - public XmlElement DocumentElement + public XmlElement? DocumentElement { - get { return (XmlElement)FindChild(XmlNodeType.Element); } + get { return (XmlElement?)FindChild(XmlNodeType.Element); } } internal override bool IsContainer @@ -408,14 +410,14 @@ internal override bool IsContainer get { return true; } } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { return _lastChild; } set { _lastChild = value; } } // Gets the XmlDocument that contains this node. - public override XmlDocument OwnerDocument + public override XmlDocument? OwnerDocument { get { return null; } } @@ -447,7 +449,7 @@ internal bool HasSetResolver get { return bSetResolver; } } - internal XmlResolver GetResolver() + internal XmlResolver? GetResolver() { return _resolver; } @@ -460,7 +462,7 @@ public virtual XmlResolver XmlResolver if (!bSetResolver) bSetResolver = true; - XmlDocumentType dtd = this.DocumentType; + XmlDocumentType? dtd = this.DocumentType; if (dtd != null) { dtd.DtdSchemaInfo = null; @@ -498,12 +500,12 @@ internal override bool IsValidChildType(XmlNodeType type) } // the function examines all the siblings before the refNode // if any of the nodes has type equals to "nt", return true; otherwise, return false; - private bool HasNodeTypeInPrevSiblings(XmlNodeType nt, XmlNode refNode) + private bool HasNodeTypeInPrevSiblings(XmlNodeType nt, XmlNode? refNode) { if (refNode == null) return false; - XmlNode node = null; + XmlNode? node = null; if (refNode.ParentNode != null) node = refNode.ParentNode.FirstChild; while (node != null) @@ -519,9 +521,9 @@ private bool HasNodeTypeInPrevSiblings(XmlNodeType nt, XmlNode refNode) // the function examines all the siblings after the refNode // if any of the nodes has the type equals to "nt", return true; otherwise, return false; - private bool HasNodeTypeInNextSiblings(XmlNodeType nt, XmlNode refNode) + private bool HasNodeTypeInNextSiblings(XmlNodeType nt, XmlNode? refNode) { - XmlNode node = refNode; + XmlNode? node = refNode; while (node != null) { if (node.NodeType == nt) @@ -531,7 +533,7 @@ private bool HasNodeTypeInNextSiblings(XmlNodeType nt, XmlNode refNode) return false; } - internal override bool CanInsertBefore(XmlNode newChild, XmlNode refChild) + internal override bool CanInsertBefore(XmlNode newChild, XmlNode? refChild) { if (refChild == null) refChild = FirstChild; @@ -574,7 +576,7 @@ internal override bool CanInsertBefore(XmlNode newChild, XmlNode refChild) return false; } - internal override bool CanInsertAfter(XmlNode newChild, XmlNode refChild) + internal override bool CanInsertAfter(XmlNode newChild, XmlNode? refChild) { if (refChild == null) refChild = LastChild; @@ -633,20 +635,20 @@ internal void SetDefaultNamespace(string prefix, string localName, ref string na } // Creates a XmlCDataSection containing the specified data. - public virtual XmlCDataSection CreateCDataSection(string data) + public virtual XmlCDataSection CreateCDataSection(string? data) { fCDataNodesPresent = true; return new XmlCDataSection(data, this); } // Creates an XmlComment containing the specified data. - public virtual XmlComment CreateComment(string data) + public virtual XmlComment CreateComment(string? data) { return new XmlComment(data, this); } // Returns a new XmlDocumentType object. - public virtual XmlDocumentType CreateDocumentType(string name, string publicId, string systemId, string internalSubset) + public virtual XmlDocumentType CreateDocumentType(string name, string? publicId, string? systemId, string? internalSubset) { return new XmlDocumentType(name, publicId, systemId, internalSubset, this); } @@ -669,8 +671,8 @@ public XmlElement CreateElement(string name) internal void AddDefaultAttributes(XmlElement elem) { - SchemaInfo schInfo = DtdSchemaInfo; - SchemaElementDecl ed = GetSchemaElementDecl(elem); + SchemaInfo? schInfo = DtdSchemaInfo; + SchemaElementDecl? ed = GetSchemaElementDecl(elem); if (ed != null && ed.AttDefs != null) { foreach (KeyValuePair attrDefs in ed.AttDefs) @@ -683,7 +685,7 @@ internal void AddDefaultAttributes(XmlElement elem) string attrPrefix; string attrLocalname = attdef.Name.Name; string attrNamespaceURI = string.Empty; - if (schInfo.SchemaType == SchemaType.DTD) + if (schInfo!.SchemaType == SchemaType.DTD) { attrPrefix = attdef.Name.Namespace; } @@ -699,15 +701,15 @@ internal void AddDefaultAttributes(XmlElement elem) } } - private SchemaElementDecl GetSchemaElementDecl(XmlElement elem) + private SchemaElementDecl? GetSchemaElementDecl(XmlElement elem) { - SchemaInfo schInfo = DtdSchemaInfo; + SchemaInfo? schInfo = DtdSchemaInfo; if (schInfo != null) { //build XmlQualifiedName used to identify the element schema declaration XmlQualifiedName qname = new XmlQualifiedName(elem.LocalName, schInfo.SchemaType == SchemaType.DTD ? elem.Prefix : elem.NamespaceURI); //get the schema info for the element - SchemaElementDecl elemDecl; + SchemaElementDecl? elemDecl; if (schInfo.ElementDecls.TryGetValue(qname, out elemDecl)) { return elemDecl; @@ -724,7 +726,7 @@ private XmlAttribute PrepareDefaultAttribute(SchemaAttDef attdef, string attrPre //parsing the default value for the default attribute defattr.InnerXml = attdef.DefaultValueRaw; //during the expansion of the tree, the flag could be set to true, we need to set it back. - XmlUnspecifiedAttribute unspAttr = defattr as XmlUnspecifiedAttribute; + XmlUnspecifiedAttribute? unspAttr = defattr as XmlUnspecifiedAttribute; if (unspAttr != null) { unspAttr.SetSpecified(false); @@ -746,32 +748,32 @@ public virtual XmlProcessingInstruction CreateProcessingInstruction(string targe } // Creates a XmlDeclaration node with the specified values. - public virtual XmlDeclaration CreateXmlDeclaration(string version, string encoding, string standalone) + public virtual XmlDeclaration CreateXmlDeclaration(string version, string? encoding, string? standalone) { return new XmlDeclaration(version, encoding, standalone, this); } // Creates an XmlText with the specified text. - public virtual XmlText CreateTextNode(string text) + public virtual XmlText CreateTextNode(string? text) { return new XmlText(text, this); } // Creates a XmlSignificantWhitespace node. - public virtual XmlSignificantWhitespace CreateSignificantWhitespace(string text) + public virtual XmlSignificantWhitespace CreateSignificantWhitespace(string? text) { return new XmlSignificantWhitespace(text, this); } - public override XPathNavigator CreateNavigator() + public override XPathNavigator? CreateNavigator() { return CreateNavigator(this); } - protected internal virtual XPathNavigator CreateNavigator(XmlNode node) + protected internal virtual XPathNavigator? CreateNavigator(XmlNode node) { XmlNodeType nodeType = node.NodeType; - XmlNode parent; + XmlNode? parent; XmlNodeType parentType; switch (nodeType) @@ -806,7 +808,7 @@ protected internal virtual XPathNavigator CreateNavigator(XmlNode node) } while (parent != null); } - node = NormalizeText(node); + node = NormalizeText(node)!; break; case XmlNodeType.Whitespace: parent = node.ParentNode; @@ -831,7 +833,7 @@ protected internal virtual XPathNavigator CreateNavigator(XmlNode node) } while (parent != null); } - node = NormalizeText(node); + node = NormalizeText(node)!; break; default: break; @@ -853,9 +855,11 @@ internal static bool IsTextNode(XmlNodeType nt) } } - private XmlNode NormalizeText(XmlNode n) + private XmlNode? NormalizeText(XmlNode node) { - XmlNode retnode = null; + XmlNode? retnode = null; + XmlNode? n = node; + while (IsTextNode(n.NodeType)) { retnode = n; @@ -887,16 +891,18 @@ private XmlNode NormalizeText(XmlNode n) if (n == null) break; + while (n.NodeType == XmlNodeType.EntityReference) { - n = n.LastChild; + n = n.LastChild!; } } + return retnode; } // Creates a XmlWhitespace node. - public virtual XmlWhitespace CreateWhitespace(string text) + public virtual XmlWhitespace CreateWhitespace(string? text) { return new XmlWhitespace(text, this); } @@ -912,7 +918,7 @@ public virtual XmlNodeList GetElementsByTagName(string name) // Creates an XmlAttribute with the specified LocalName // and NamespaceURI. - public XmlAttribute CreateAttribute(string qualifiedName, string namespaceURI) + public XmlAttribute CreateAttribute(string qualifiedName, string? namespaceURI) { string prefix = string.Empty; string localName = string.Empty; @@ -923,7 +929,7 @@ public XmlAttribute CreateAttribute(string qualifiedName, string namespaceURI) // Creates an XmlElement with the specified LocalName and // NamespaceURI. - public XmlElement CreateElement(string qualifiedName, string namespaceURI) + public XmlElement CreateElement(string qualifiedName, string? namespaceURI) { string prefix = string.Empty; string localName = string.Empty; @@ -939,16 +945,16 @@ public virtual XmlNodeList GetElementsByTagName(string localName, string namespa } // Returns the XmlElement with the specified ID. - public virtual XmlElement GetElementById(string elementId) + public virtual XmlElement? GetElementById(string elementId) { if (_htElementIdMap != null) { - ArrayList elementList = (ArrayList)(_htElementIdMap[elementId]); + ArrayList? elementList = (ArrayList?)(_htElementIdMap[elementId]); if (elementList != null) { foreach (WeakReference elemRef in elementList) { - XmlElement elem = (XmlElement)elemRef.Target; + XmlElement? elem = (XmlElement?)elemRef.Target; if (elem != null && elem.IsConnected()) return elem; @@ -966,14 +972,14 @@ public virtual XmlNode ImportNode(XmlNode node, bool deep) private XmlNode ImportNodeInternal(XmlNode node, bool deep) { - XmlNode newNode = null; - if (node == null) { throw new InvalidOperationException(SR.Xdom_Import_NullNode); } else { + XmlNode newNode; + switch (node.NodeType) { case XmlNodeType.Element: @@ -996,7 +1002,7 @@ private XmlNode ImportNodeInternal(XmlNode node, bool deep) newNode = CreateComment(node.Value); break; case XmlNodeType.ProcessingInstruction: - newNode = CreateProcessingInstruction(node.Name, node.Value); + newNode = CreateProcessingInstruction(node.Name, node.Value!); break; case XmlNodeType.XmlDeclaration: XmlDeclaration decl = (XmlDeclaration)node; @@ -1032,25 +1038,25 @@ private XmlNode ImportNodeInternal(XmlNode node, bool deep) default: throw new InvalidOperationException(SR.Format(CultureInfo.InvariantCulture, SR.Xdom_Import, node.NodeType)); } - } - return newNode; + return newNode; + } } private void ImportAttributes(XmlNode fromElem, XmlNode toElem) { - int cAttr = fromElem.Attributes.Count; + int cAttr = fromElem.Attributes!.Count; for (int iAttr = 0; iAttr < cAttr; iAttr++) { if (fromElem.Attributes[iAttr].Specified) - toElem.Attributes.SetNamedItem(ImportNodeInternal(fromElem.Attributes[iAttr], true)); + toElem.Attributes!.SetNamedItem(ImportNodeInternal(fromElem.Attributes[iAttr], true)); } } private void ImportChildren(XmlNode fromNode, XmlNode toNode, bool deep) { Debug.Assert(toNode.NodeType != XmlNodeType.EntityReference); - for (XmlNode n = fromNode.FirstChild; n != null; n = n.NextSibling) + for (XmlNode? n = fromNode.FirstChild; n != null; n = n.NextSibling) { toNode.AppendChild(ImportNodeInternal(n, deep)); } @@ -1067,17 +1073,17 @@ public XmlNameTable NameTable // Creates a XmlAttribute with the specified Prefix, LocalName, // and NamespaceURI. - public virtual XmlAttribute CreateAttribute(string prefix, string localName, string namespaceURI) + public virtual XmlAttribute CreateAttribute(string? prefix, string localName, string? namespaceURI) { return new XmlAttribute(AddAttrXmlName(prefix, localName, namespaceURI, null), this); } - protected internal virtual XmlAttribute CreateDefaultAttribute(string prefix, string localName, string namespaceURI) + protected internal virtual XmlAttribute CreateDefaultAttribute(string? prefix, string localName, string? namespaceURI) { return new XmlUnspecifiedAttribute(prefix, localName, namespaceURI, this); } - public virtual XmlElement CreateElement(string prefix, string localName, string namespaceURI) + public virtual XmlElement CreateElement(string? prefix, string localName, string? namespaceURI) { XmlElement elem = new XmlElement(AddXmlName(prefix, localName, namespaceURI, null), true, this); if (!IsLoading) @@ -1123,7 +1129,7 @@ internal bool ActualLoadingStatus // Creates a XmlNode with the specified XmlNodeType, Prefix, Name, and NamespaceURI. - public virtual XmlNode CreateNode(XmlNodeType type, string prefix, string name, string namespaceURI) + public virtual XmlNode CreateNode(XmlNodeType type, string? prefix, string name, string? namespaceURI) { switch (type) { @@ -1179,23 +1185,23 @@ public virtual XmlNode CreateNode(XmlNodeType type, string prefix, string name, // Creates an XmlNode with the specified node type, Name, and // NamespaceURI. - public virtual XmlNode CreateNode(string nodeTypeString, string name, string namespaceURI) + public virtual XmlNode CreateNode(string nodeTypeString, string name, string? namespaceURI) { return CreateNode(ConvertToNodeType(nodeTypeString), name, namespaceURI); } // Creates an XmlNode with the specified XmlNodeType, Name, and // NamespaceURI. - public virtual XmlNode CreateNode(XmlNodeType type, string name, string namespaceURI) + public virtual XmlNode CreateNode(XmlNodeType type, string name, string? namespaceURI) { return CreateNode(type, null, name, namespaceURI); } // Creates an XmlNode object based on the information in the XmlReader. // The reader must be positioned on a node or attribute. - public virtual XmlNode ReadNode(XmlReader reader) + public virtual XmlNode? ReadNode(XmlReader reader) { - XmlNode node = null; + XmlNode? node = null; try { IsLoading = true; @@ -1206,6 +1212,7 @@ public virtual XmlNode ReadNode(XmlReader reader) { IsLoading = false; } + return node; } @@ -1361,7 +1368,7 @@ public virtual void LoadXml(string xml) } //TextEncoding is the one from XmlDeclaration if there is any - internal Encoding TextEncoding + internal Encoding? TextEncoding { get { @@ -1377,6 +1384,7 @@ internal Encoding TextEncoding } } + [AllowNull] public override string InnerText { set @@ -1445,14 +1453,14 @@ public virtual void Save(TextWriter writer) //that of textwriter's encoding public virtual void Save(XmlWriter w) { - XmlNode n = this.FirstChild; + XmlNode? n = this.FirstChild; if (n == null) return; if (w.WriteState == WriteState.Start) { if (n is XmlDeclaration) { - if (Standalone.Length == 0) + if (Standalone!.Length == 0) w.WriteStartDocument(); else if (Standalone == "yes") w.WriteStartDocument(true); @@ -1492,12 +1500,12 @@ public override void WriteContentTo(XmlWriter xw) } } - public void Validate(ValidationEventHandler validationEventHandler) + public void Validate(ValidationEventHandler? validationEventHandler) { Validate(validationEventHandler, this); } - public void Validate(ValidationEventHandler validationEventHandler, XmlNode nodeToValidate) + public void Validate(ValidationEventHandler? validationEventHandler, XmlNode nodeToValidate) { if (_schemas == null || _schemas.Count == 0) { //Should we error @@ -1592,7 +1600,7 @@ public event XmlNodeChangedEventHandler NodeChanged } } - internal override XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParent, string oldValue, string newValue, XmlNodeChangedAction action) + internal override XmlNodeChangedEventArgs? GetEventArgs(XmlNode node, XmlNode? oldParent, XmlNode? newParent, string? oldValue, string? newValue, XmlNodeChangedAction action) { _reportValidity = false; @@ -1620,13 +1628,13 @@ internal override XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode old return new XmlNodeChangedEventArgs(node, oldParent, newParent, oldValue, newValue, action); } - internal XmlNodeChangedEventArgs GetInsertEventArgsForLoad(XmlNode node, XmlNode newParent) + internal XmlNodeChangedEventArgs? GetInsertEventArgsForLoad(XmlNode node, XmlNode newParent) { if (_onNodeInsertingDelegate == null && _onNodeInsertedDelegate == null) { return null; } - string nodeValue = node.Value; + string? nodeValue = node.Value; return new XmlNodeChangedEventArgs(node, null, newParent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); } @@ -1682,10 +1690,10 @@ internal override void AfterEvent(XmlNodeChangedEventArgs args) // If so, return the newly created default attribute (with children tree); // Otherwise, return null. - internal XmlAttribute GetDefaultAttribute(XmlElement elem, string attrPrefix, string attrLocalname, string attrNamespaceURI) + internal XmlAttribute? GetDefaultAttribute(XmlElement elem, string attrPrefix, string attrLocalname, string attrNamespaceURI) { - SchemaInfo schInfo = DtdSchemaInfo; - SchemaElementDecl ed = GetSchemaElementDecl(elem); + SchemaInfo? schInfo = DtdSchemaInfo; + SchemaElementDecl? ed = GetSchemaElementDecl(elem); if (ed != null && ed.AttDefs != null) { foreach (KeyValuePair attrDefs in ed.AttDefs) @@ -1696,7 +1704,7 @@ internal XmlAttribute GetDefaultAttribute(XmlElement elem, string attrPrefix, st { if (attdef.Name.Name == attrLocalname) { - if ((schInfo.SchemaType == SchemaType.DTD && attdef.Name.Namespace == attrPrefix) || + if ((schInfo!.SchemaType == SchemaType.DTD && attdef.Name.Namespace == attrPrefix) || (schInfo.SchemaType != SchemaType.DTD && attdef.Name.Namespace == attrNamespaceURI)) { //find a def attribute with the same name, build a default attribute and return @@ -1710,46 +1718,46 @@ internal XmlAttribute GetDefaultAttribute(XmlElement elem, string attrPrefix, st return null; } - internal string Version + internal string? Version { get { - XmlDeclaration decl = Declaration; + XmlDeclaration? decl = Declaration; if (decl != null) return decl.Version; return null; } } - internal string Encoding + internal string? Encoding { get { - XmlDeclaration decl = Declaration; + XmlDeclaration? decl = Declaration; if (decl != null) return decl.Encoding; return null; } } - internal string Standalone + internal string? Standalone { get { - XmlDeclaration decl = Declaration; + XmlDeclaration? decl = Declaration; if (decl != null) return decl.Standalone; return null; } } - internal XmlEntity GetEntityNode(string name) + internal XmlEntity? GetEntityNode(string name) { if (DocumentType != null) { XmlNamedNodeMap entites = DocumentType.Entities; if (entites != null) - return (XmlEntity)(entites.GetNamedItem(name)); + return (XmlEntity?)(entites.GetNamedItem(name)); } return null; } @@ -1760,7 +1768,7 @@ public override IXmlSchemaInfo SchemaInfo { if (_reportValidity) { - XmlElement documentElement = DocumentElement; + XmlElement? documentElement = DocumentElement; if (documentElement != null) { switch (documentElement.SchemaInfo.Validity) @@ -1796,7 +1804,7 @@ internal override XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc) if (!CanInsertAfter(newChild, LastChild)) throw new InvalidOperationException(SR.Xdom_Node_Insert_Location); - XmlNodeChangedEventArgs args = GetInsertEventArgsForLoad(newChild, this); + XmlNodeChangedEventArgs? args = GetInsertEventArgsForLoad(newChild, this); if (args != null) BeforeEvent(args); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentFragment.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentFragment.cs index 9010ff103dcb..ae0345450628 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentFragment.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentFragment.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -43,25 +44,26 @@ namespace System.Xml // such as insertBefore() and appendChild(). public class XmlDocumentFragment : XmlNode { - private XmlLinkedNode _lastChild; + private XmlLinkedNode? _lastChild; protected internal XmlDocumentFragment(XmlDocument ownerDocument) : base() { if (ownerDocument == null) throw new ArgumentException(SR.Xdom_Node_Null_Doc); + parentNode = ownerDocument; } // Gets the name of the node. public override string Name { - get { return OwnerDocument.strDocumentFragmentName; } + get { return OwnerDocument!.strDocumentFragmentName; } } // Gets the name of the current node without the namespace prefix. public override string LocalName { - get { return OwnerDocument.strDocumentFragmentName; } + get { return OwnerDocument!.strDocumentFragmentName; } } // Gets the type of the current node. @@ -71,7 +73,7 @@ public override XmlNodeType NodeType } // Gets the parent of this node (for nodes that can have parents). - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { return null; } } @@ -81,7 +83,7 @@ public override XmlDocument OwnerDocument { get { - return (XmlDocument)parentNode; + return (XmlDocument)parentNode!; } } @@ -118,7 +120,7 @@ internal override bool IsContainer get { return true; } } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { return _lastChild; } set { _lastChild = value; } @@ -140,7 +142,7 @@ internal override bool IsValidChildType(XmlNodeType type) case XmlNodeType.XmlDeclaration: //if there is an XmlDeclaration node, it has to be the first node; - XmlNode firstNode = FirstChild; + XmlNode? firstNode = FirstChild; if (firstNode == null || firstNode.NodeType != XmlNodeType.XmlDeclaration) return true; else @@ -149,7 +151,7 @@ internal override bool IsValidChildType(XmlNodeType type) return false; } } - internal override bool CanInsertAfter(XmlNode newChild, XmlNode refChild) + internal override bool CanInsertAfter(XmlNode newChild, XmlNode? refChild) { Debug.Assert(newChild != null); //should be checked that newChild is not null before this function call if (newChild.NodeType == XmlNodeType.XmlDeclaration) @@ -165,7 +167,7 @@ internal override bool CanInsertAfter(XmlNode newChild, XmlNode refChild) return true; } - internal override bool CanInsertBefore(XmlNode newChild, XmlNode refChild) + internal override bool CanInsertBefore(XmlNode newChild, XmlNode? refChild) { Debug.Assert(newChild != null); //should be checked that newChild is not null before this function call if (newChild.NodeType == XmlNodeType.XmlDeclaration) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs index 9601322214b3..ab166f91a00e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.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. +#nullable enable using System.Diagnostics; using System.Xml.Schema; @@ -10,17 +11,17 @@ namespace System.Xml public class XmlDocumentType : XmlLinkedNode { private readonly string _name; - private readonly string _publicId; - private readonly string _systemId; - private readonly string _internalSubset; + private readonly string? _publicId; + private readonly string? _systemId; + private readonly string? _internalSubset; private bool _namespaces; - private XmlNamedNodeMap _entities; - private XmlNamedNodeMap _notations; + private XmlNamedNodeMap? _entities; + private XmlNamedNodeMap? _notations; // parsed DTD - private SchemaInfo _schemaInfo; + private SchemaInfo? _schemaInfo; - protected internal XmlDocumentType(string name, string publicId, string systemId, string internalSubset, XmlDocument doc) : base(doc) + protected internal XmlDocumentType(string name, string? publicId, string? systemId, string? internalSubset, XmlDocument doc) : base(doc) { _name = name; _publicId = publicId; @@ -104,21 +105,21 @@ public XmlNamedNodeMap Notations // // Gets the value of the public identifier on the DOCTYPE declaration. - public string PublicId + public string? PublicId { get { return _publicId; } } // Gets the value of // the system identifier on the DOCTYPE declaration. - public string SystemId + public string? SystemId { get { return _systemId; } } // Gets the entire value of the DTD internal subset // on the DOCTYPE declaration. - public string InternalSubset + public string? InternalSubset { get { return _internalSubset; } } @@ -141,7 +142,7 @@ public override void WriteContentTo(XmlWriter w) // Intentionally do nothing } - internal SchemaInfo DtdSchemaInfo + internal SchemaInfo? DtdSchemaInfo { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDomTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDomTextWriter.cs index 72ebd83447d0..9697b4945b30 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDomTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDomTextWriter.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. +#nullable enable using System.IO; using System.Text; @@ -11,11 +12,11 @@ namespace System.Xml // This is not possible with XmlTextWriter. But this class inherits XmlTextWriter. internal class XmlDOMTextWriter : XmlTextWriter { - public XmlDOMTextWriter(Stream w, Encoding encoding) : base(w, encoding) + public XmlDOMTextWriter(Stream w, Encoding? encoding) : base(w, encoding) { } - public XmlDOMTextWriter(string filename, Encoding encoding) : base(filename, encoding) + public XmlDOMTextWriter(string filename, Encoding? encoding) : base(filename, encoding) { } @@ -25,20 +26,20 @@ public XmlDOMTextWriter(TextWriter w) : base(w) // Overrides the baseclass implementation so that emptystring prefixes do // do not fail if namespace is not specified. - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { - if ((ns.Length == 0) && (prefix.Length != 0)) - prefix = ""; + if (string.IsNullOrEmpty(ns) && !string.IsNullOrEmpty(prefix)) + prefix = string.Empty; base.WriteStartElement(prefix, localName, ns); } // Overrides the baseclass implementation so that emptystring prefixes do // do not fail if namespace is not specified. - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { - if ((ns.Length == 0) && (prefix.Length != 0)) - prefix = ""; + if (string.IsNullOrEmpty(ns) && !string.IsNullOrEmpty(prefix)) + prefix = string.Empty; base.WriteStartAttribute(prefix, localName, ns); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs index 97250574574f..1715d66ab828 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.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. +#nullable enable using System; using System.Xml.Schema; using System.Xml.XPath; @@ -14,8 +15,8 @@ namespace System.Xml public class XmlElement : XmlLinkedNode { private XmlName _name; - private XmlAttributeCollection _attributes; - private XmlLinkedNode _lastChild; // == this for empty elements otherwise it is the last child + private XmlAttributeCollection? _attributes; + private XmlLinkedNode? _lastChild; // == this for empty elements otherwise it is the last child internal XmlElement(XmlName name, bool empty, XmlDocument doc) : base(doc) { @@ -28,6 +29,7 @@ internal XmlElement(XmlName name, bool empty, XmlDocument doc) : base(doc) } if (name.LocalName.Length == 0) throw new ArgumentException(SR.Xdom_Empty_LocalName); + _name = name; if (empty) { @@ -35,7 +37,7 @@ internal XmlElement(XmlName name, bool empty, XmlDocument doc) : base(doc) } } - protected internal XmlElement(string prefix, string localName, string namespaceURI, XmlDocument doc) + protected internal XmlElement(string prefix, string localName, string? namespaceURI, XmlDocument doc) : this(doc.AddXmlName(prefix, localName, namespaceURI, null), true, doc) { } @@ -63,7 +65,7 @@ public override XmlNode CloneNode(bool deep) foreach (XmlAttribute attr in Attributes) { XmlAttribute newAttr = (XmlAttribute)(attr.CloneNode(true)); - XmlUnspecifiedAttribute unspecAttr = newAttr as XmlUnspecifiedAttribute; + XmlUnspecifiedAttribute? unspecAttr = newAttr as XmlUnspecifiedAttribute; if (unspecAttr != null && attr.Specified == false) { unspecAttr.SetSpecified(false); @@ -71,6 +73,7 @@ public override XmlNode CloneNode(bool deep) element.Attributes.InternalAppendAttribute(newAttr); } } + if (deep) element.CopyChildren(doc, this, deep); @@ -108,7 +111,7 @@ public override XmlNodeType NodeType get { return XmlNodeType.Element; } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { @@ -133,7 +136,7 @@ internal override bool IsContainer //the function is provided only at Load time to speed up Load process internal override XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc) { - XmlNodeChangedEventArgs args = doc.GetInsertEventArgsForLoad(newChild, this); + XmlNodeChangedEventArgs? args = doc.GetInsertEventArgsForLoad(newChild, this); if (args != null) doc.BeforeEvent(args); @@ -198,13 +201,12 @@ public bool IsEmpty } } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { return _lastChild == this ? null : _lastChild; } - set { _lastChild = value; @@ -267,9 +269,10 @@ public virtual bool HasAttributes // Returns the value for the attribute with the specified name. public virtual string GetAttribute(string name) { - XmlAttribute attr = GetAttributeNode(name); + XmlAttribute? attr = GetAttributeNode(name); if (attr != null) return attr.Value; + return string.Empty; } @@ -277,7 +280,7 @@ public virtual string GetAttribute(string name) // with the specified name. public virtual void SetAttribute(string name, string value) { - XmlAttribute attr = GetAttributeNode(name); + XmlAttribute? attr = GetAttributeNode(name); if (attr == null) { attr = OwnerDocument.CreateAttribute(name); @@ -298,7 +301,7 @@ public virtual void RemoveAttribute(string name) } // Returns the XmlAttribute with the specified name. - public virtual XmlAttribute GetAttributeNode(string name) + public virtual XmlAttribute? GetAttributeNode(string name) { if (HasAttributes) return Attributes[name]; @@ -310,14 +313,15 @@ public virtual XmlAttribute SetAttributeNode(XmlAttribute newAttr) { if (newAttr.OwnerElement != null) throw new InvalidOperationException(SR.Xdom_Attr_InUse); + return (XmlAttribute)Attributes.SetNamedItem(newAttr); } // Removes the specified XmlAttribute. - public virtual XmlAttribute RemoveAttributeNode(XmlAttribute oldAttr) + public virtual XmlAttribute? RemoveAttributeNode(XmlAttribute oldAttr) { if (HasAttributes) - return (XmlAttribute)Attributes.Remove(oldAttr); + return (XmlAttribute?)Attributes.Remove(oldAttr); return null; } @@ -333,19 +337,20 @@ public virtual XmlNodeList GetElementsByTagName(string name) // // Returns the value for the attribute with the specified LocalName and NamespaceURI. - public virtual string GetAttribute(string localName, string namespaceURI) + public virtual string GetAttribute(string localName, string? namespaceURI) { - XmlAttribute attr = GetAttributeNode(localName, namespaceURI); + XmlAttribute? attr = GetAttributeNode(localName, namespaceURI); if (attr != null) return attr.Value; + return string.Empty; } // Sets the value of the attribute with the specified name // and namespace. - public virtual string SetAttribute(string localName, string namespaceURI, string value) + public virtual string SetAttribute(string localName, string? namespaceURI, string value) { - XmlAttribute attr = GetAttributeNode(localName, namespaceURI); + XmlAttribute? attr = GetAttributeNode(localName, namespaceURI); if (attr == null) { attr = OwnerDocument.CreateAttribute(string.Empty, localName, namespaceURI); @@ -361,13 +366,13 @@ public virtual string SetAttribute(string localName, string namespaceURI, string } // Removes an attribute specified by LocalName and NamespaceURI. - public virtual void RemoveAttribute(string localName, string namespaceURI) + public virtual void RemoveAttribute(string localName, string? namespaceURI) { RemoveAttributeNode(localName, namespaceURI); } // Returns the XmlAttribute with the specified LocalName and NamespaceURI. - public virtual XmlAttribute GetAttributeNode(string localName, string namespaceURI) + public virtual XmlAttribute? GetAttributeNode(string localName, string? namespaceURI) { if (HasAttributes) return Attributes[localName, namespaceURI]; @@ -375,26 +380,28 @@ public virtual XmlAttribute GetAttributeNode(string localName, string namespaceU } // Adds the specified XmlAttribute. - public virtual XmlAttribute SetAttributeNode(string localName, string namespaceURI) + public virtual XmlAttribute SetAttributeNode(string localName, string? namespaceURI) { - XmlAttribute attr = GetAttributeNode(localName, namespaceURI); + XmlAttribute? attr = GetAttributeNode(localName, namespaceURI); if (attr == null) { attr = OwnerDocument.CreateAttribute(string.Empty, localName, namespaceURI); Attributes.InternalAppendAttribute(attr); } + return attr; } // Removes the XmlAttribute specified by LocalName and NamespaceURI. - public virtual XmlAttribute RemoveAttributeNode(string localName, string namespaceURI) + public virtual XmlAttribute? RemoveAttributeNode(string localName, string? namespaceURI) { if (HasAttributes) { - XmlAttribute attr = GetAttributeNode(localName, namespaceURI); + XmlAttribute? attr = GetAttributeNode(localName, namespaceURI); Attributes.Remove(attr); return attr; } + return null; } @@ -413,7 +420,7 @@ public virtual bool HasAttribute(string name) // Determines whether the current node has the specified // attribute from the specified namespace. - public virtual bool HasAttribute(string localName, string namespaceURI) + public virtual bool HasAttribute(string localName, string? namespaceURI) { return GetAttributeNode(localName, namespaceURI) != null; } @@ -444,10 +451,11 @@ public override void WriteTo(XmlWriter w) } // This method is copied from System.Xml.Linq.ElementWriter.WriteElement but adapted to DOM - private static void WriteElementTo(XmlWriter writer, XmlElement e) + private static void WriteElementTo(XmlWriter writer, XmlElement el) { + XmlElement? e = el; XmlNode root = e; - XmlNode n = e; + XmlNode? n = e; while (true) { e = n as XmlElement; @@ -480,15 +488,18 @@ private static void WriteElementTo(XmlWriter writer, XmlElement e) // Use virtual dispatch (might recurse) n.WriteTo(writer); } + // Go back to the parent after writing the last child - while (n != root && n == n.ParentNode.LastChild) + while (n != root && n == n.ParentNode!.LastChild) { n = n.ParentNode; Debug.Assert(n != null); writer.WriteFullEndElement(); } + if (n == root) break; + n = n.NextSibling; Debug.Assert(n != null); } @@ -513,17 +524,18 @@ private void WriteStartElement(XmlWriter w) // Saves all the children of the node to the specified XmlWriter. public override void WriteContentTo(XmlWriter w) { - for (XmlNode node = FirstChild; node != null; node = node.NextSibling) + for (XmlNode? node = FirstChild; node != null; node = node.NextSibling) { node.WriteTo(w); } } // Removes the attribute node with the specified index from the attribute collection. - public virtual XmlNode RemoveAttributeAt(int i) + public virtual XmlNode? RemoveAttributeAt(int i) { if (HasAttributes) - return _attributes.RemoveAt(i); + return _attributes!.RemoveAt(i); + return null; } @@ -532,7 +544,7 @@ public virtual void RemoveAllAttributes() { if (HasAttributes) { - _attributes.RemoveAll(); + _attributes!.RemoveAll(); } } @@ -585,7 +597,7 @@ public override string InnerText } set { - XmlLinkedNode linkedNode = LastNode; + XmlLinkedNode? linkedNode = LastNode; if (linkedNode != null && //there is one child linkedNode.NodeType == XmlNodeType.Text && //which is text node linkedNode.next == linkedNode) // and it is the only child @@ -601,18 +613,19 @@ public override string InnerText } } - public override XmlNode NextSibling + public override XmlNode? NextSibling { get { if (this.parentNode != null && this.parentNode.LastNode != this) return next; + return null; } } - internal override void SetParent(XmlNode node) + internal override void SetParent(XmlNode? node) { this.parentNode = node; } @@ -621,13 +634,15 @@ internal override void SetParent(XmlNode node) internal override string XPLocalName { get { return LocalName; } } - internal override string GetXPAttribute(string localName, string ns) + internal override string? GetXPAttribute(string localName, string ns) { if (ns == OwnerDocument.strReservedXmlns) return null; - XmlAttribute attr = GetAttributeNode(localName, ns); + + XmlAttribute? attr = GetAttributeNode(localName, ns); if (attr != null) return attr.Value; + return string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs index 3892576db3c4..02211d6d21aa 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs @@ -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. +#nullable enable using System.Collections; using System.Diagnostics; @@ -8,12 +9,12 @@ namespace System.Xml { internal class XmlElementList : XmlNodeList { - private readonly string _asterisk; + private readonly string _asterisk = null!; private int _changeCount; //recording the total number that the dom tree has been changed ( insertion and deletion ) //the member vars below are saved for further reconstruction - private readonly string _name; //only one of 2 string groups will be initialized depends on which constructor is called. - private string _localName; - private string _namespaceURI; + private readonly string? _name; //only one of 2 string groups will be initialized depends on which constructor is called. + private string? _localName; + private string? _namespaceURI; private readonly XmlNode _rootNode; // the member vars below serves the optimization of accessing of the elements in the list private int _curInd; // -1 means the starting point for a new search round @@ -22,7 +23,7 @@ internal class XmlElementList : XmlNodeList private bool _atomized; //whether the localname and namespaceuri are atomized private int _matchCount; // cached list count. -1 means it needs reconstruction - private WeakReference _listener; // XmlElementListListener + private WeakReference? _listener; // XmlElementListListener private XmlElementList(XmlNode parent) { @@ -50,11 +51,12 @@ internal void ConcurrencyCheck(XmlNodeChangedEventArgs args) if (_atomized == false) { XmlNameTable nameTable = _rootNode.Document.NameTable; - _localName = nameTable.Add(_localName); - _namespaceURI = nameTable.Add(_namespaceURI); + _localName = nameTable.Add(_localName!); + _namespaceURI = nameTable.Add(_namespaceURI!); _atomized = true; } - if (IsMatch(args.Node)) + + if (IsMatch(args.Node!)) { _changeCount++; _curInd = -1; @@ -62,6 +64,7 @@ internal void ConcurrencyCheck(XmlNodeChangedEventArgs args) if (args.Action == XmlNodeChangedAction.Insert) _empty = false; } + _matchCount = -1; } @@ -91,6 +94,7 @@ internal XmlElementList(XmlNode parent, string localName, string namespaceURI) : _localName = localName; _namespaceURI = namespaceURI; } + _name = null; } @@ -100,11 +104,11 @@ internal int ChangeCount } // return the next element node that is in PreOrder - private XmlNode NextElemInPreOrder(XmlNode curNode) + private XmlNode? NextElemInPreOrder(XmlNode curNode) { Debug.Assert(curNode != null); //For preorder walking, first try its child - XmlNode retNode = curNode.FirstChild; + XmlNode? retNode = curNode.FirstChild; if (retNode == null) { //if no child, the next node forward will the be the NextSibling of the first ancestor which has NextSibling @@ -127,11 +131,11 @@ private XmlNode NextElemInPreOrder(XmlNode curNode) } // return the previous element node that is in PreOrder - private XmlNode PrevElemInPreOrder(XmlNode curNode) + private XmlNode? PrevElemInPreOrder(XmlNode curNode) { Debug.Assert(curNode != null); //For preorder walking, the previous node will be the right-most node in the tree of PreviousSibling of the curNode - XmlNode retNode = curNode.PreviousSibling; + XmlNode? retNode = curNode.PreviousSibling; // so if the PreviousSibling is not null, going through the tree down to find the right-most node while (retNode != null) { @@ -172,10 +176,10 @@ private bool IsMatch(XmlNode curNode) return false; } - private XmlNode GetMatchingNode(XmlNode n, bool bNext) + private XmlNode? GetMatchingNode(XmlNode n, bool bNext) { Debug.Assert(n != null); - XmlNode node = n; + XmlNode? node = n; do { if (bNext) @@ -186,21 +190,22 @@ private XmlNode GetMatchingNode(XmlNode n, bool bNext) return node; } - private XmlNode GetNthMatchingNode(XmlNode n, bool bNext, int nCount) + private XmlNode? GetNthMatchingNode(XmlNode n, bool bNext, int nCount) { Debug.Assert(n != null); - XmlNode node = n; + XmlNode? node = n; for (int ind = 0; ind < nCount; ind++) { node = GetMatchingNode(node, bNext); if (node == null) return null; } + return node; } //the function is for the enumerator to find out the next available matching element node - public XmlNode GetNextNode(XmlNode n) + public XmlNode? GetNextNode(XmlNode? n) { if (_empty == true) return null; @@ -208,7 +213,7 @@ public XmlNode GetNextNode(XmlNode n) return GetMatchingNode(node, true); } - public override XmlNode Item(int index) + public override XmlNode? Item(int index) { if (_rootNode == null || index < 0) return null; @@ -221,13 +226,15 @@ public override XmlNode Item(int index) bool bForward = (nDiff > 0); if (nDiff < 0) nDiff = -nDiff; - XmlNode node; + + XmlNode? node; if ((node = GetNthMatchingNode(_curElem, bForward, nDiff)) != null) { _curInd = index; _curElem = node; return _curElem; } + return null; } @@ -237,21 +244,25 @@ public override int Count { if (_empty == true) return 0; + if (_matchCount < 0) { int currMatchCount = 0; int currChangeCount = _changeCount; - XmlNode node = _rootNode; + XmlNode? node = _rootNode; while ((node = GetMatchingNode(node, true)) != null) { currMatchCount++; } + if (currChangeCount != _changeCount) { return currMatchCount; } + _matchCount = currMatchCount; } + return _matchCount; } } @@ -259,7 +270,8 @@ public override int Count public override IEnumerator GetEnumerator() { if (_empty == true) - return new XmlEmptyElementListEnumerator(this); ; + return new XmlEmptyElementListEnumerator(this); + return new XmlElementListEnumerator(this); } @@ -273,11 +285,12 @@ protected virtual void Dispose(bool disposing) { if (_listener != null) { - XmlElementListListener listener = (XmlElementListListener)_listener.Target; + XmlElementListListener? listener = (XmlElementListListener?)_listener.Target; if (listener != null) { listener.Unregister(); } + _listener = null; } } @@ -286,7 +299,7 @@ protected virtual void Dispose(bool disposing) internal class XmlElementListEnumerator : IEnumerator { private readonly XmlElementList _list; - private XmlNode _curElem; + private XmlNode? _curElem; private int _changeCount; //save the total number that the dom tree has been changed ( insertion and deletion ) when this enumerator is created public XmlElementListEnumerator(XmlElementList list) @@ -317,7 +330,7 @@ public void Reset() _changeCount = _list.ChangeCount; } - public object Current + public object? Current { get { return _curElem; } } @@ -338,7 +351,7 @@ public void Reset() { } - public object Current + public object? Current { get { return null; } } @@ -346,7 +359,7 @@ public object Current internal class XmlElementListListener { - private WeakReference _elemList; + private WeakReference? _elemList; private readonly XmlDocument _doc; private readonly XmlNodeChangedEventHandler _nodeChangeHandler; @@ -365,7 +378,7 @@ private void OnListChanged(object sender, XmlNodeChangedEventArgs args) { if (_elemList != null) { - XmlElementList el = (XmlElementList)_elemList.Target; + XmlElementList? el = (XmlElementList?)_elemList.Target; if (null != el) { el.ConcurrencyCheck(args); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntity.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntity.cs index cc8523fb3db0..636bae90881d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntity.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntity.cs @@ -1,20 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml { // Represents a parsed or unparsed entity in the XML document. public class XmlEntity : XmlNode { - private readonly string _publicId; - private readonly string _systemId; - private readonly string _notationName; + private readonly string? _publicId; + private readonly string? _systemId; + private readonly string? _notationName; private readonly string _name; - private string _baseURI; - private XmlLinkedNode _lastChild; + private string _baseURI = string.Empty; + private XmlLinkedNode? _lastChild; private bool _childrenFoliating; - internal XmlEntity(string name, string strdata, string publicId, string systemId, string notationName, XmlDocument doc) : base(doc) + internal XmlEntity(string name, string? strdata, string? publicId, string? systemId, string? notationName, XmlDocument doc) : base(doc) { _name = doc.NameTable.Add(name); _publicId = publicId; @@ -71,7 +72,7 @@ internal override bool IsContainer get { return true; } } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { @@ -106,20 +107,20 @@ public override XmlNodeType NodeType } // Gets the value of the public identifier on the entity declaration. - public string PublicId + public string? PublicId { get { return _publicId; } } // Gets the value of the system identifier on the entity declaration. - public string SystemId + public string? SystemId { get { return _systemId; } } // Gets the name of the optional NDATA attribute on the // entity declaration. - public string NotationName + public string? NotationName { get { return _notationName; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntityReference.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntityReference.cs index 0d73a247a1af..59d7c595e886 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntityReference.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEntityReference.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. +#nullable enable using System.Diagnostics; namespace System.Xml @@ -30,7 +31,7 @@ namespace System.Xml public class XmlEntityReference : XmlLinkedNode { private readonly string _name; - private XmlLinkedNode _lastChild; + private XmlLinkedNode? _lastChild; protected internal XmlEntityReference(string name, XmlDocument doc) : base(doc) { @@ -41,6 +42,7 @@ protected internal XmlEntityReference(string name, XmlDocument doc) : base(doc) throw new ArgumentException(SR.Xdom_InvalidCharacter_EntityReference); } } + _name = doc.NameTable.Add(name); doc.fEntRefNodesPresent = true; } @@ -58,7 +60,7 @@ public override string LocalName } // Gets or sets the value of the node. - public override string Value + public override string? Value { get { @@ -103,7 +105,7 @@ internal override bool IsContainer get { return true; } } - internal override void SetParent(XmlNode node) + internal override void SetParent(XmlNode? node) { base.SetParent(node); if (LastNode == null && node != null && node != OwnerDocument) @@ -119,7 +121,7 @@ internal override void SetParentForLoad(XmlNode node) this.SetParent(node); } - internal override XmlLinkedNode LastNode + internal override XmlLinkedNode? LastNode { get { @@ -174,7 +176,7 @@ public override string BaseURI { get { - return OwnerDocument.BaseURI; + return OwnerDocument!.BaseURI; } } @@ -197,7 +199,7 @@ internal string ChildBaseURI get { //get the associate entity and return its baseUri - XmlEntity ent = OwnerDocument.GetEntityNode(_name); + XmlEntity? ent = OwnerDocument!.GetEntityNode(_name); if (ent != null) { if (!string.IsNullOrEmpty(ent.SystemId)) @@ -205,6 +207,7 @@ internal string ChildBaseURI else return ent.BaseURI; } + return string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEventChangedAction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEventChangedAction.cs index 1cf0a0c7fe00..59c2540fce2a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEventChangedAction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlEventChangedAction.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. +#nullable enable namespace System.Xml { // Specifies the type of node change diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlImplementation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlImplementation.cs index 395c4ef29bb8..5dfbecc1f156 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlImplementation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlImplementation.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. +#nullable enable namespace System.Xml { // Provides methods for performing operations that are independent of any diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLinkedNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLinkedNode.cs index 7a88926f3366..41ae4635e1d0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLinkedNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLinkedNode.cs @@ -1,12 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml { // Gets the node immediately preceding or following this node. public abstract class XmlLinkedNode : XmlNode { - internal XmlLinkedNode next; + internal XmlLinkedNode? next; internal XmlLinkedNode(XmlDocument doc) : base(doc) { @@ -14,40 +15,44 @@ internal XmlLinkedNode(XmlDocument doc) : base(doc) } // Gets the node immediately preceding this node. - public override XmlNode PreviousSibling + public override XmlNode? PreviousSibling { get { - XmlNode parent = ParentNode; + XmlNode? parent = ParentNode; if (parent != null) { - XmlNode node = parent.FirstChild; + XmlNode? node = parent.FirstChild; while (node != null) { - XmlNode nextSibling = node.NextSibling; + XmlNode? nextSibling = node.NextSibling; if (nextSibling == this) { break; } + node = nextSibling; } + return node; } + return null; } } // Gets the node immediately following this node. - public override XmlNode NextSibling + public override XmlNode? NextSibling { get { - XmlNode parent = ParentNode; + XmlNode? parent = ParentNode; if (parent != null) { if (next != parent.FirstChild) return next; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLoader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLoader.cs index 71191ddd154f..05e28484d449 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLoader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlLoader.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. +#nullable enable using System.IO; using System.Diagnostics; using System.Globalization; @@ -12,11 +13,10 @@ namespace System.Xml { internal class XmlLoader { - private XmlDocument _doc; - private XmlReader _reader; + private XmlDocument? _doc; + private XmlReader? _reader; private bool _preserveWhitespace; - public XmlLoader() { } @@ -38,7 +38,7 @@ internal void Load(XmlDocument doc, XmlReader reader, bool preserveWhitespace) throw new ArgumentException(SR.Xdom_Load_NoDocument); if (reader == null) throw new ArgumentException(SR.Xdom_Load_NoReader); - doc.SetBaseURI(reader.BaseURI); + doc.SetBaseURI(reader.BaseURI!); if (reader.Settings != null && reader.Settings.ValidationType == ValidationType.Schema) { @@ -57,7 +57,7 @@ private void LoadDocSequence(XmlDocument parentDoc) { Debug.Assert(_reader != null); Debug.Assert(parentDoc != null); - XmlNode node = null; + XmlNode? node = null; while ((node = LoadNode(true)) != null) { parentDoc.AppendChildForLoad(node, parentDoc); @@ -66,7 +66,7 @@ private void LoadDocSequence(XmlDocument parentDoc) } } - internal XmlNode ReadCurrentNode(XmlDocument doc, XmlReader reader) + internal XmlNode? ReadCurrentNode(XmlDocument doc, XmlReader reader) { _doc = doc; _reader = reader; @@ -83,7 +83,7 @@ internal XmlNode ReadCurrentNode(XmlDocument doc, XmlReader reader) } if (reader.ReadState == ReadState.Interactive) { - XmlNode n = LoadNode(true); + XmlNode n = LoadNode(true)!; // Move to the next node if (n.NodeType != XmlNodeType.Attribute) @@ -91,23 +91,24 @@ internal XmlNode ReadCurrentNode(XmlDocument doc, XmlReader reader) return n; } + return null; } - private XmlNode LoadNode(bool skipOverWhitespace) + private XmlNode? LoadNode(bool skipOverWhitespace) { - XmlReader r = _reader; - XmlNode parent = null; - XmlElement element; - IXmlSchemaInfo schemaInfo; + XmlReader r = _reader!; + XmlNode? parent = null; + XmlElement? element; + IXmlSchemaInfo? schemaInfo; do { - XmlNode node = null; + XmlNode? node = null; switch (r.NodeType) { case XmlNodeType.Element: bool fEmptyElement = r.IsEmptyElement; - element = _doc.CreateElement(r.Prefix, r.LocalName, r.NamespaceURI); + element = _doc!.CreateElement(r.Prefix, r.LocalName, r.NamespaceURI); element.IsEmpty = fEmptyElement; if (r.MoveToFirstAttribute()) @@ -155,7 +156,7 @@ private XmlNode LoadNode(bool skipOverWhitespace) element = parent as XmlElement; if (element != null) { - element.XmlName = _doc.AddXmlName(element.Prefix, element.LocalName, element.NamespaceURI, schemaInfo); + element.XmlName = _doc!.AddXmlName(element.Prefix, element.LocalName, element.NamespaceURI, schemaInfo); } } if (parent.ParentNode == null) @@ -178,17 +179,17 @@ private XmlNode LoadNode(bool skipOverWhitespace) break; case XmlNodeType.Text: - node = _doc.CreateTextNode(r.Value); + node = _doc!.CreateTextNode(r.Value); break; case XmlNodeType.SignificantWhitespace: - node = _doc.CreateSignificantWhitespace(r.Value); + node = _doc!.CreateSignificantWhitespace(r.Value); break; case XmlNodeType.Whitespace: if (_preserveWhitespace) { - node = _doc.CreateWhitespace(r.Value); + node = _doc!.CreateWhitespace(r.Value); break; } else if (parent == null && !skipOverWhitespace) @@ -201,7 +202,7 @@ private XmlNode LoadNode(bool skipOverWhitespace) continue; } case XmlNodeType.CDATA: - node = _doc.CreateCDataSection(r.Value); + node = _doc!.CreateCDataSection(r.Value); break; @@ -210,11 +211,11 @@ private XmlNode LoadNode(bool skipOverWhitespace) break; case XmlNodeType.ProcessingInstruction: - node = _doc.CreateProcessingInstruction(r.Name, r.Value); + node = _doc!.CreateProcessingInstruction(r.Name, r.Value); break; case XmlNodeType.Comment: - node = _doc.CreateComment(r.Value); + node = _doc!.CreateComment(r.Value); break; case XmlNodeType.DocumentType: @@ -228,7 +229,7 @@ private XmlNode LoadNode(bool skipOverWhitespace) Debug.Assert(node != null); if (parent != null) { - parent.AppendChildForLoad(node, _doc); + parent.AppendChildForLoad(node, _doc!); } else { @@ -245,12 +246,13 @@ private XmlNode LoadNode(bool skipOverWhitespace) parent = parent.ParentNode; } } + return parent; } private XmlAttribute LoadAttributeNode() { - Debug.Assert(_reader.NodeType == XmlNodeType.Attribute); + Debug.Assert(_reader!.NodeType == XmlNodeType.Attribute); XmlReader r = _reader; if (r.IsDefault) @@ -258,12 +260,13 @@ private XmlAttribute LoadAttributeNode() return LoadDefaultAttribute(); } - XmlAttribute attr = _doc.CreateAttribute(r.Prefix, r.LocalName, r.NamespaceURI); - IXmlSchemaInfo schemaInfo = r.SchemaInfo; + XmlAttribute attr = _doc!.CreateAttribute(r.Prefix, r.LocalName, r.NamespaceURI); + IXmlSchemaInfo? schemaInfo = r.SchemaInfo; if (schemaInfo != null) { attr.XmlName = _doc.AddAttrXmlName(attr.Prefix, attr.LocalName, attr.NamespaceURI, schemaInfo); } + while (r.ReadAttributeValue()) { XmlNode node; @@ -289,6 +292,7 @@ private XmlAttribute LoadAttributeNode() default: throw UnexpectedNodeType(r.NodeType); } + Debug.Assert(node != null); attr.AppendChildForLoad(node, _doc); } @@ -298,11 +302,11 @@ private XmlAttribute LoadAttributeNode() private XmlAttribute LoadDefaultAttribute() { - Debug.Assert(_reader.IsDefault); + Debug.Assert(_reader!.IsDefault); XmlReader r = _reader; - XmlAttribute attr = _doc.CreateDefaultAttribute(r.Prefix, r.LocalName, r.NamespaceURI); - IXmlSchemaInfo schemaInfo = r.SchemaInfo; + XmlAttribute attr = _doc!.CreateDefaultAttribute(r.Prefix, r.LocalName, r.NamespaceURI); + IXmlSchemaInfo? schemaInfo = r.SchemaInfo; if (schemaInfo != null) { attr.XmlName = _doc.AddAttrXmlName(attr.Prefix, attr.LocalName, attr.NamespaceURI, schemaInfo); @@ -310,7 +314,7 @@ private XmlAttribute LoadDefaultAttribute() LoadAttributeValue(attr, false); - XmlUnspecifiedAttribute defAttr = attr as XmlUnspecifiedAttribute; + XmlUnspecifiedAttribute? defAttr = attr as XmlUnspecifiedAttribute; // If user overrides CreateDefaultAttribute, then attr will NOT be a XmlUnspecifiedAttribute instance. if (defAttr != null) defAttr.SetSpecified(false); @@ -320,19 +324,19 @@ private XmlAttribute LoadDefaultAttribute() private void LoadAttributeValue(XmlNode parent, bool direct) { - XmlReader r = _reader; + XmlReader r = _reader!; while (r.ReadAttributeValue()) { XmlNode node; switch (r.NodeType) { case XmlNodeType.Text: - node = direct ? new XmlText(r.Value, _doc) : _doc.CreateTextNode(r.Value); + node = direct ? new XmlText(r.Value, _doc!) : _doc!.CreateTextNode(r.Value); break; case XmlNodeType.EndEntity: return; case XmlNodeType.EntityReference: - node = direct ? new XmlEntityReference(_reader.LocalName, _doc) : _doc.CreateEntityReference(_reader.LocalName); + node = direct ? new XmlEntityReference(_reader!.LocalName, _doc!) : _doc!.CreateEntityReference(_reader!.LocalName); if (r.CanResolveEntity) { r.ResolveEntity(); @@ -341,7 +345,7 @@ private void LoadAttributeValue(XmlNode parent, bool direct) // if the reader does not present any children for the ent-ref if (node.FirstChild == null) { - node.AppendChildForLoad(direct ? new XmlText(string.Empty) : _doc.CreateTextNode(string.Empty), _doc); + node.AppendChildForLoad(direct ? new XmlText(string.Empty) : _doc!.CreateTextNode(string.Empty), _doc!); } } break; @@ -349,42 +353,42 @@ private void LoadAttributeValue(XmlNode parent, bool direct) throw UnexpectedNodeType(r.NodeType); } Debug.Assert(node != null); - parent.AppendChildForLoad(node, _doc); + parent.AppendChildForLoad(node, _doc!); } return; } private XmlEntityReference LoadEntityReferenceNode(bool direct) { - Debug.Assert(_reader.NodeType == XmlNodeType.EntityReference); - XmlEntityReference eref = direct ? new XmlEntityReference(_reader.Name, _doc) : _doc.CreateEntityReference(_reader.Name); + Debug.Assert(_reader!.NodeType == XmlNodeType.EntityReference); + XmlEntityReference eref = direct ? new XmlEntityReference(_reader.Name, _doc!) : _doc!.CreateEntityReference(_reader.Name); if (_reader.CanResolveEntity) { _reader.ResolveEntity(); while (_reader.Read() && _reader.NodeType != XmlNodeType.EndEntity) { - XmlNode node = direct ? LoadNodeDirect() : LoadNode(false); + XmlNode? node = direct ? LoadNodeDirect() : LoadNode(false); if (node != null) { - eref.AppendChildForLoad(node, _doc); + eref.AppendChildForLoad(node, _doc!); } } // Code internally relies on the fact that an EntRef nodes has at least one child (even an empty text node). Ensure that this holds true, // if the reader does not present any children for the ent-ref if (eref.LastChild == null) - eref.AppendChildForLoad(_doc.CreateTextNode(string.Empty), _doc); + eref.AppendChildForLoad(_doc!.CreateTextNode(string.Empty), _doc); } return eref; } private XmlDeclaration LoadDeclarationNode() { - Debug.Assert(_reader.NodeType == XmlNodeType.XmlDeclaration); + Debug.Assert(_reader!.NodeType == XmlNodeType.XmlDeclaration); //parse data - string version = null; - string encoding = null; - string standalone = null; + string? version = null; + string? encoding = null; + string? standalone = null; // Try first to use the reader to get the xml decl "attributes". Since not all readers are required to support this, it is possible to have // implementations that do nothing @@ -412,15 +416,15 @@ private XmlDeclaration LoadDeclarationNode() if (version == null) ParseXmlDeclarationValue(_reader.Value, out version, out encoding, out standalone); - return _doc.CreateXmlDeclaration(version, encoding, standalone); + return _doc!.CreateXmlDeclaration(version!, encoding, standalone); } private XmlDocumentType LoadDocumentTypeNode() { - Debug.Assert(_reader.NodeType == XmlNodeType.DocumentType); + Debug.Assert(_reader!.NodeType == XmlNodeType.DocumentType); - string publicId = null; - string systemId = null; + string? publicId = null; + string? systemId = null; string internalSubset = _reader.Value; string localName = _reader.LocalName; while (_reader.MoveToNextAttribute()) @@ -436,9 +440,9 @@ private XmlDocumentType LoadDocumentTypeNode() } } - XmlDocumentType dtNode = _doc.CreateDocumentType(localName, publicId, systemId, internalSubset); + XmlDocumentType dtNode = _doc!.CreateDocumentType(localName, publicId, systemId, internalSubset); - IDtdInfo dtdInfo = _reader.DtdInfo; + IDtdInfo? dtdInfo = _reader.DtdInfo; if (dtdInfo != null) LoadDocumentType(dtdInfo, dtNode); else @@ -454,18 +458,18 @@ private XmlDocumentType LoadDocumentTypeNode() // because we do not want to let users extend these (if we would allow this, XmlDataDocument would have a problem, because // they do not know that those nodes should not be mapped). It can be also used for an optimized load path when if the // XmlDocument is not extended if XmlDocumentType and XmlDeclaration handling is added. - private XmlNode LoadNodeDirect() + private XmlNode? LoadNodeDirect() { - XmlReader r = _reader; - XmlNode parent = null; + XmlReader r = _reader!; + XmlNode? parent = null; do { - XmlNode node = null; + XmlNode? node = null; switch (r.NodeType) { case XmlNodeType.Element: - bool fEmptyElement = _reader.IsEmptyElement; - XmlElement element = new XmlElement(_reader.Prefix, _reader.LocalName, _reader.NamespaceURI, _doc); + bool fEmptyElement = _reader!.IsEmptyElement; + XmlElement element = new XmlElement(_reader.Prefix, _reader.LocalName, _reader.NamespaceURI, _doc!); element.IsEmpty = fEmptyElement; if (_reader.MoveToFirstAttribute()) @@ -481,7 +485,7 @@ private XmlNode LoadNodeDirect() // recursively load all children. if (!fEmptyElement) { - parent.AppendChildForLoad(element, _doc); + parent!.AppendChildForLoad(element, _doc!); parent = element; continue; } @@ -492,11 +496,12 @@ private XmlNode LoadNodeDirect() } case XmlNodeType.EndElement: - Debug.Assert(parent.NodeType == XmlNodeType.Element); + Debug.Assert(parent!.NodeType == XmlNodeType.Element); if (parent.ParentNode == null) { return parent; } + parent = parent.ParentNode; continue; @@ -512,13 +517,13 @@ private XmlNode LoadNodeDirect() break; case XmlNodeType.SignificantWhitespace: - node = new XmlSignificantWhitespace(_reader.Value, _doc); + node = new XmlSignificantWhitespace(_reader!.Value, _doc!); break; case XmlNodeType.Whitespace: if (_preserveWhitespace) { - node = new XmlWhitespace(_reader.Value, _doc); + node = new XmlWhitespace(_reader!.Value, _doc!); } else { @@ -527,29 +532,29 @@ private XmlNode LoadNodeDirect() break; case XmlNodeType.Text: - node = new XmlText(_reader.Value, _doc); + node = new XmlText(_reader!.Value, _doc!); break; case XmlNodeType.CDATA: - node = new XmlCDataSection(_reader.Value, _doc); + node = new XmlCDataSection(_reader!.Value, _doc!); break; case XmlNodeType.ProcessingInstruction: - node = new XmlProcessingInstruction(_reader.Name, _reader.Value, _doc); + node = new XmlProcessingInstruction(_reader!.Name, _reader.Value, _doc!); break; case XmlNodeType.Comment: - node = new XmlComment(_reader.Value, _doc); + node = new XmlComment(_reader!.Value, _doc!); break; default: - throw UnexpectedNodeType(_reader.NodeType); + throw UnexpectedNodeType(_reader!.NodeType); } Debug.Assert(node != null); if (parent != null) { - parent.AppendChildForLoad(node, _doc); + parent.AppendChildForLoad(node, _doc!); } else { @@ -563,18 +568,18 @@ private XmlNode LoadNodeDirect() private XmlAttribute LoadAttributeNodeDirect() { - XmlReader r = _reader; + XmlReader r = _reader!; XmlAttribute attr; if (r.IsDefault) { - XmlUnspecifiedAttribute defattr = new XmlUnspecifiedAttribute(r.Prefix, r.LocalName, r.NamespaceURI, _doc); + XmlUnspecifiedAttribute defattr = new XmlUnspecifiedAttribute(r.Prefix, r.LocalName, r.NamespaceURI, _doc!); LoadAttributeValue(defattr, true); defattr.SetSpecified(false); return defattr; } else { - attr = new XmlAttribute(r.Prefix, r.LocalName, r.NamespaceURI, _doc); + attr = new XmlAttribute(r.Prefix, r.LocalName, r.NamespaceURI, _doc!); LoadAttributeValue(attr, true); return attr; } @@ -582,7 +587,7 @@ private XmlAttribute LoadAttributeNodeDirect() internal void ParseDocumentType(XmlDocumentType dtNode) { - XmlDocument doc = dtNode.OwnerDocument; + XmlDocument doc = dtNode.OwnerDocument!; //if xmlresolver is set on doc, use that one, otherwise use the default one being created by xmlvalidatingreader if (doc.HasSetResolver) ParseDocumentType(dtNode, true, doc.GetResolver()); @@ -590,10 +595,10 @@ internal void ParseDocumentType(XmlDocumentType dtNode) ParseDocumentType(dtNode, false, null); } - private void ParseDocumentType(XmlDocumentType dtNode, bool bUseResolver, XmlResolver resolver) + private void ParseDocumentType(XmlDocumentType dtNode, bool bUseResolver, XmlResolver? resolver) { _doc = dtNode.OwnerDocument; - XmlParserContext pc = new XmlParserContext(null, new XmlNamespaceManager(_doc.NameTable), null, null, null, null, _doc.BaseURI, string.Empty, XmlSpace.None); + XmlParserContext pc = new XmlParserContext(null, new XmlNamespaceManager(_doc!.NameTable), null, null, null, null, _doc.BaseURI, string.Empty, XmlSpace.None); XmlTextReaderImpl tr = new XmlTextReaderImpl("", XmlNodeType.Element, pc); tr.Namespaces = dtNode.ParseWithNamespaces; if (bUseResolver) @@ -610,7 +615,7 @@ private void ParseDocumentType(XmlDocumentType dtNode, bool bUseResolver, XmlRes private void LoadDocumentType(IDtdInfo dtdInfo, XmlDocumentType dtNode) { - SchemaInfo schInfo = dtdInfo as SchemaInfo; + SchemaInfo? schInfo = dtdInfo as SchemaInfo; if (schInfo == null) { throw new XmlException(SR.Xml_InternalError, string.Empty); @@ -620,7 +625,7 @@ private void LoadDocumentType(IDtdInfo dtdInfo, XmlDocumentType dtNode) if (schInfo != null) { //set the schema information into the document - _doc.DtdSchemaInfo = schInfo; + _doc!.DtdSchemaInfo = schInfo; // Notation hashtable if (schInfo.Notations != null) @@ -677,11 +682,11 @@ private void LoadDocumentType(IDtdInfo dtdInfo, XmlDocumentType dtNode) } #pragma warning restore 618 - private XmlParserContext GetContext(XmlNode node) + private XmlParserContext GetContext(XmlNode? node) { - string lang = null; + string? lang = null; XmlSpace spaceMode = XmlSpace.None; - XmlDocumentType docType = _doc.DocumentType; + XmlDocumentType? docType = _doc!.DocumentType; string baseURI = _doc.BaseURI; //constructing xmlnamespace HashSet prefixes = new HashSet(); @@ -692,7 +697,7 @@ private XmlParserContext GetContext(XmlNode node) // Process all xmlns, xmlns:prefix, xml:space and xml:lang attributes while (node != null && node != _doc) { - XmlElement element = node as XmlElement; + XmlElement? element = node as XmlElement; if (element != null && element.HasAttributes) { mgr.PushScope(); @@ -725,6 +730,7 @@ private XmlParserContext GetContext(XmlNode node) } } } + node = node.ParentNode; } return new XmlParserContext( @@ -758,7 +764,7 @@ internal XmlNamespaceManager ParsePartialContent(XmlNode parentNode, string inne if (nt == XmlNodeType.Entity) { - XmlNode node = null; + XmlNode? node = null; while (_reader.Read() && (node = LoadNodeDirect()) != null) { parentNode.AppendChildForLoad(node, _doc); @@ -766,19 +772,21 @@ internal XmlNamespaceManager ParsePartialContent(XmlNode parentNode, string inne } else { - XmlNode node = null; + XmlNode? node = null; while (_reader.Read() && (node = LoadNode(true)) != null) { parentNode.AppendChildForLoad(node, _doc); } } + _doc.IsLoading = bOrigLoading; } finally { _reader.Close(); } - return pc.NamespaceManager; + + return pc.NamespaceManager!; } internal void LoadInnerXmlElement(XmlElement node, string innerxmltext) @@ -807,9 +815,9 @@ private void RemoveDuplicateNamespace(XmlElement elem, XmlNamespaceManager mgr, for (int i = cAttrs - 1; i >= 0; --i) { XmlAttribute attr = attrs[i]; - if (attr.Prefix == _doc.strXmlns) + if (attr.Prefix == _doc!.strXmlns) { - string nsUri = mgr.LookupNamespace(attr.LocalName); + string? nsUri = mgr.LookupNamespace(attr.LocalName); if (nsUri != null) { if (attr.Value == nsUri) @@ -844,14 +852,15 @@ private void RemoveDuplicateNamespace(XmlElement elem, XmlNamespaceManager mgr, } } //now recursively remove the duplicate attributes on the children - XmlNode child = elem.FirstChild; + XmlNode? child = elem.FirstChild; while (child != null) { - XmlElement childElem = child as XmlElement; + XmlElement? childElem = child as XmlElement; if (childElem != null) RemoveDuplicateNamespace(childElem, mgr, true); child = child.NextSibling; } + mgr.PopScope(); } @@ -871,7 +880,7 @@ internal void ExpandEntityReference(XmlEntityReference eref) { //when the ent ref is not associated w/ an entity, append an empty string text node as child _doc = eref.OwnerDocument; - bool bOrigLoadingState = _doc.IsLoading; + bool bOrigLoadingState = _doc!.IsLoading; _doc.IsLoading = true; switch (eref.Name) { @@ -939,7 +948,7 @@ private XmlReader CreateInnerXmlReader(string xmlFragment, XmlNodeType nt, XmlPa } Debug.Assert(tr.EntityHandling == EntityHandling.ExpandCharEntities); - XmlDocumentType dtdNode = doc.DocumentType; + XmlDocumentType? dtdNode = doc.DocumentType; if (dtdNode != null) { tr.Namespaces = dtdNode.ParseWithNamespaces; @@ -968,12 +977,12 @@ private XmlReader CreateInnerXmlReader(string xmlFragment, XmlNodeType nt, XmlPa } #pragma warning restore 618 - internal static void ParseXmlDeclarationValue(string strValue, out string version, out string encoding, out string standalone) + internal static void ParseXmlDeclarationValue(string strValue, out string? version, out string? encoding, out string? standalone) { version = null; encoding = null; standalone = null; - XmlTextReaderImpl tempreader = new XmlTextReaderImpl(strValue, (XmlParserContext)null); + XmlTextReaderImpl tempreader = new XmlTextReaderImpl(strValue, (XmlParserContext?)null); try { tempreader.Read(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlName.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlName.cs index eeefd61f1988..504245a91df7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlName.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlName.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. +#nullable enable namespace System.Xml { using System.Text; @@ -12,12 +13,12 @@ internal class XmlName : IXmlSchemaInfo private readonly string _prefix; private readonly string _localName; private readonly string _ns; - private string _name; + private string? _name; private readonly int _hashCode; internal XmlDocument ownerDoc; internal XmlName next; - public static XmlName Create(string prefix, string localName, string ns, int hashCode, XmlDocument ownerDoc, XmlName next, IXmlSchemaInfo schemaInfo) + public static XmlName Create(string prefix, string localName, string ns, int hashCode, XmlDocument ownerDoc, XmlName next, IXmlSchemaInfo? schemaInfo) { if (schemaInfo == null) { @@ -139,7 +140,7 @@ public virtual bool IsNil } } - public virtual XmlSchemaSimpleType MemberType + public virtual XmlSchemaSimpleType? MemberType { get { @@ -147,7 +148,7 @@ public virtual XmlSchemaSimpleType MemberType } } - public virtual XmlSchemaType SchemaType + public virtual XmlSchemaType? SchemaType { get { @@ -155,7 +156,7 @@ public virtual XmlSchemaType SchemaType } } - public virtual XmlSchemaElement SchemaElement + public virtual XmlSchemaElement? SchemaElement { get { @@ -163,7 +164,7 @@ public virtual XmlSchemaElement SchemaElement } } - public virtual XmlSchemaAttribute SchemaAttribute + public virtual XmlSchemaAttribute? SchemaAttribute { get { @@ -171,7 +172,7 @@ public virtual XmlSchemaAttribute SchemaAttribute } } - public virtual bool Equals(IXmlSchemaInfo schemaInfo) + public virtual bool Equals(IXmlSchemaInfo? schemaInfo) { return schemaInfo == null; } @@ -190,9 +191,9 @@ public static int GetHashCode(string name) internal sealed class XmlNameEx : XmlName { private byte _flags; - private readonly XmlSchemaSimpleType _memberType; - private readonly XmlSchemaType _schemaType; - private readonly object _decl; + private readonly XmlSchemaSimpleType? _memberType; + private readonly XmlSchemaType? _schemaType; + private readonly object? _decl; // flags // 0,1 : Validity @@ -211,7 +212,7 @@ internal XmlNameEx(string prefix, string localName, string ns, int hashCode, Xml _schemaType = schemaInfo.SchemaType; _decl = schemaInfo.SchemaElement != null ? (object)schemaInfo.SchemaElement - : (object)schemaInfo.SchemaAttribute; + : (object?)schemaInfo.SchemaAttribute; } public override XmlSchemaValidity Validity @@ -238,7 +239,7 @@ public override bool IsNil } } - public override XmlSchemaSimpleType MemberType + public override XmlSchemaSimpleType? MemberType { get { @@ -246,7 +247,7 @@ public override XmlSchemaSimpleType MemberType } } - public override XmlSchemaType SchemaType + public override XmlSchemaType? SchemaType { get { @@ -254,7 +255,7 @@ public override XmlSchemaType SchemaType } } - public override XmlSchemaElement SchemaElement + public override XmlSchemaElement? SchemaElement { get { @@ -262,7 +263,7 @@ public override XmlSchemaElement SchemaElement } } - public override XmlSchemaAttribute SchemaAttribute + public override XmlSchemaAttribute? SchemaAttribute { get { @@ -287,16 +288,16 @@ public void SetIsNil(bool value) else _flags = (byte)(_flags & ~IsNilBit); } - public override bool Equals(IXmlSchemaInfo schemaInfo) + public override bool Equals(IXmlSchemaInfo? schemaInfo) { if (schemaInfo != null && schemaInfo.Validity == (XmlSchemaValidity)(_flags & ValidityMask) && schemaInfo.IsDefault == ((_flags & IsDefaultBit) != 0) && schemaInfo.IsNil == ((_flags & IsNilBit) != 0) - && (object)schemaInfo.MemberType == (object)_memberType - && (object)schemaInfo.SchemaType == (object)_schemaType - && (object)schemaInfo.SchemaElement == (object)(_decl as XmlSchemaElement) - && (object)schemaInfo.SchemaAttribute == (object)(_decl as XmlSchemaAttribute)) + && (object?)schemaInfo.MemberType == (object?)_memberType + && (object?)schemaInfo.SchemaType == (object?)_schemaType + && (object?)schemaInfo.SchemaElement == (object?)(_decl as XmlSchemaElement) + && (object?)schemaInfo.SchemaAttribute == (object?)(_decl as XmlSchemaAttribute)) { return true; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodeMap.SmallXmlNodeList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodeMap.SmallXmlNodeList.cs index 6c738e031aaf..a57403419940 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodeMap.SmallXmlNodeList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodeMap.SmallXmlNodeList.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections; using System.Collections.Generic; +using System.Diagnostics; namespace System.Xml { @@ -16,7 +18,7 @@ internal struct SmallXmlNodeList // object. // Otherwise, field is an List. Once the field upgrades to an List, it // never degrades back, even if all elements are removed. - private object _field; + private object? _field; public int Count { @@ -25,7 +27,7 @@ public int Count if (_field == null) return 0; - List list = _field as List; + List? list = _field as List; if (list != null) return list.Count; @@ -40,7 +42,7 @@ public object this[int index] if (_field == null) throw new ArgumentOutOfRangeException(nameof(index)); - List list = _field as List; + List? list = _field as List; if (list != null) return list[index]; @@ -57,10 +59,11 @@ public void Add(object value) { if (value == null) { + Debug.Fail("Null was added to the collection which didn't expect it"); // If a single null value needs to be stored, then // upgrade to an ArrayList List temp = new List(); - temp.Add(null); + temp.Add(null!); _field = temp; } else @@ -69,7 +72,7 @@ public void Add(object value) return; } - List list = _field as List; + List? list = _field as List; if (list != null) { list.Add(value); @@ -88,7 +91,7 @@ public void RemoveAt(int index) if (_field == null) throw new ArgumentOutOfRangeException(nameof(index)); - List list = _field as List; + List? list = _field as List; if (list != null) { list.RemoveAt(index); @@ -111,7 +114,7 @@ public void Insert(int index, object value) return; } - List list = _field as List; + List? list = _field as List; if (list != null) { list.Insert(index, value); @@ -156,6 +159,7 @@ public object Current { throw new InvalidOperationException(); } + return _loneValue; } } @@ -167,6 +171,7 @@ public bool MoveNext() _position = 0; return true; } + _position = 1; return false; } @@ -184,7 +189,7 @@ public IEnumerator GetEnumerator() return XmlDocument.EmptyEnumerator; } - List list = _field as List; + List? list = _field as List; if (list != null) { return list.GetEnumerator(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodemap.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodemap.cs index 2ffb6900ff65..54b0c64ce4a3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodemap.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNamedNodemap.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. +#nullable enable using System.Collections; namespace System.Xml @@ -17,16 +18,17 @@ internal XmlNamedNodeMap(XmlNode parent) } // Retrieves a XmlNode specified by name. - public virtual XmlNode GetNamedItem(string name) + public virtual XmlNode? GetNamedItem(string name) { int offset = FindNodeOffset(name); if (offset >= 0) return (XmlNode)nodes[offset]; + return null; } // Adds a XmlNode using its Name property - public virtual XmlNode SetNamedItem(XmlNode node) + public virtual XmlNode? SetNamedItem(XmlNode? node) { if (node == null) return null; @@ -44,13 +46,14 @@ public virtual XmlNode SetNamedItem(XmlNode node) } // Removes the node specified by name. - public virtual XmlNode RemoveNamedItem(string name) + public virtual XmlNode? RemoveNamedItem(string name) { int offset = FindNodeOffset(name); if (offset >= 0) { return RemoveNodeAt(offset); } + return null; } @@ -64,7 +67,7 @@ public virtual int Count } // Retrieves the node at the specified index in this XmlNamedNodeMap. - public virtual XmlNode Item(int index) + public virtual XmlNode? Item(int index) { if (index < 0 || index >= nodes.Count) return null; @@ -83,22 +86,24 @@ public virtual XmlNode Item(int index) // // Retrieves a node specified by LocalName and NamespaceURI. - public virtual XmlNode GetNamedItem(string localName, string namespaceURI) + public virtual XmlNode? GetNamedItem(string localName, string? namespaceURI) { int offset = FindNodeOffset(localName, namespaceURI); if (offset >= 0) return (XmlNode)nodes[offset]; + return null; } // Removes a node specified by local name and namespace URI. - public virtual XmlNode RemoveNamedItem(string localName, string namespaceURI) + public virtual XmlNode? RemoveNamedItem(string localName, string? namespaceURI) { int offset = FindNodeOffset(localName, namespaceURI); if (offset >= 0) { return RemoveNodeAt(offset); } + return null; } @@ -121,7 +126,7 @@ internal int FindNodeOffset(string name) return -1; } - internal int FindNodeOffset(string localName, string namespaceURI) + internal int FindNodeOffset(string localName, string? namespaceURI) { int c = this.Count; for (int i = 0; i < c; i++) @@ -137,13 +142,14 @@ internal int FindNodeOffset(string localName, string namespaceURI) internal virtual XmlNode AddNode(XmlNode node) { - XmlNode oldParent; + XmlNode? oldParent; if (node.NodeType == XmlNodeType.Attribute) oldParent = ((XmlAttribute)node).OwnerElement; else oldParent = node.ParentNode; - string nodeValue = node.Value; - XmlNodeChangedEventArgs args = parent.GetEventArgs(node, oldParent, parent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); + + string? nodeValue = node.Value; + XmlNodeChangedEventArgs? args = parent.GetEventArgs(node, oldParent, parent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); if (args != null) parent.BeforeEvent(args); @@ -159,17 +165,19 @@ internal virtual XmlNode AddNode(XmlNode node) internal virtual XmlNode AddNodeForLoad(XmlNode node, XmlDocument doc) { - XmlNodeChangedEventArgs args = doc.GetInsertEventArgsForLoad(node, parent); + XmlNodeChangedEventArgs? args = doc.GetInsertEventArgsForLoad(node, parent); if (args != null) { doc.BeforeEvent(args); } + nodes.Add(node); node.SetParent(parent); if (args != null) { doc.AfterEvent(args); } + return node; } @@ -177,8 +185,8 @@ internal virtual XmlNode RemoveNodeAt(int i) { XmlNode oldNode = (XmlNode)nodes[i]; - string oldNodeValue = oldNode.Value; - XmlNodeChangedEventArgs args = parent.GetEventArgs(oldNode, parent, null, oldNodeValue, oldNodeValue, XmlNodeChangedAction.Remove); + string? oldNodeValue = oldNode.Value; + XmlNodeChangedEventArgs? args = parent.GetEventArgs(oldNode, parent, null, oldNodeValue, oldNodeValue, XmlNodeChangedAction.Remove); if (args != null) parent.BeforeEvent(args); @@ -201,14 +209,14 @@ internal XmlNode ReplaceNodeAt(int i, XmlNode node) internal virtual XmlNode InsertNodeAt(int i, XmlNode node) { - XmlNode oldParent; + XmlNode? oldParent; if (node.NodeType == XmlNodeType.Attribute) oldParent = ((XmlAttribute)node).OwnerElement; else oldParent = node.ParentNode; - string nodeValue = node.Value; - XmlNodeChangedEventArgs args = parent.GetEventArgs(node, oldParent, parent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); + string? nodeValue = node.Value; + XmlNodeChangedEventArgs? args = parent.GetEventArgs(node, oldParent, parent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); if (args != null) parent.BeforeEvent(args); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs index a2e7c57a2e38..75e429ee2ac1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs @@ -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. +#nullable enable using System; using System.IO; using System.Collections; @@ -10,6 +11,7 @@ using System.Xml.XPath; using MS.Internal.Xml.XPath; using System.Globalization; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -17,7 +19,7 @@ namespace System.Xml [DebuggerDisplay("{debuggerDisplayProxy}")] public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable { - internal XmlNode parentNode; //this pointer is reused to save the userdata information, need to prevent internal user access the pointer directly. + internal XmlNode? parentNode; //this pointer is reused to save the userdata information, need to prevent internal user access the pointer directly. internal XmlNode() { @@ -27,61 +29,66 @@ internal XmlNode(XmlDocument doc) { if (doc == null) throw new ArgumentException(SR.Xdom_Node_Null_Doc); + this.parentNode = doc; } - public virtual XPathNavigator CreateNavigator() + public virtual XPathNavigator? CreateNavigator() { - XmlDocument thisAsDoc = this as XmlDocument; + XmlDocument? thisAsDoc = this as XmlDocument; if (thisAsDoc != null) { return thisAsDoc.CreateNavigator(this); } - XmlDocument doc = OwnerDocument; + + XmlDocument? doc = OwnerDocument; Debug.Assert(doc != null); return doc.CreateNavigator(this); } // Selects the first node that matches the xpath expression - public XmlNode SelectSingleNode(string xpath) + public XmlNode? SelectSingleNode(string xpath) { - XmlNodeList list = SelectNodes(xpath); + XmlNodeList? list = SelectNodes(xpath); // SelectNodes returns null for certain node types return list != null ? list[0] : null; } // Selects the first node that matches the xpath expression and given namespace context. - public XmlNode SelectSingleNode(string xpath, XmlNamespaceManager nsmgr) + public XmlNode? SelectSingleNode(string xpath, XmlNamespaceManager nsmgr) { - XPathNavigator xn = (this).CreateNavigator(); + XPathNavigator? xn = (this).CreateNavigator(); //if the method is called on node types like DocType, Entity, XmlDeclaration, //the navigator returned is null. So just return null from here for those node types. if (xn == null) return null; + XPathExpression exp = xn.Compile(xpath); exp.SetContext(nsmgr); return new XPathNodeList(xn.Select(exp))[0]; } // Selects all nodes that match the xpath expression - public XmlNodeList SelectNodes(string xpath) + public XmlNodeList? SelectNodes(string xpath) { - XPathNavigator n = (this).CreateNavigator(); + XPathNavigator? n = (this).CreateNavigator(); //if the method is called on node types like DocType, Entity, XmlDeclaration, //the navigator returned is null. So just return null from here for those node types. if (n == null) return null; + return new XPathNodeList(n.Select(xpath)); } // Selects all nodes that match the xpath expression and given namespace context. - public XmlNodeList SelectNodes(string xpath, XmlNamespaceManager nsmgr) + public XmlNodeList? SelectNodes(string xpath, XmlNamespaceManager nsmgr) { - XPathNavigator xn = (this).CreateNavigator(); + XPathNavigator? xn = (this).CreateNavigator(); //if the method is called on node types like DocType, Entity, XmlDeclaration, //the navigator returned is null. So just return null from here for those node types. if (xn == null) return null; + XPathExpression exp = xn.Compile(xpath); exp.SetContext(nsmgr); return new XPathNodeList(xn.Select(exp)); @@ -94,7 +101,7 @@ public abstract string Name } // Gets or sets the value of the node. - public virtual string Value + public virtual string? Value { get { return null; } set { throw new InvalidOperationException(SR.Format(CultureInfo.InvariantCulture, SR.Xdom_Node_SetVal, NodeType.ToString())); } @@ -107,7 +114,7 @@ public abstract XmlNodeType NodeType } // Gets the parent of this node (for nodes that can have parents). - public virtual XmlNode ParentNode + public virtual XmlNode? ParentNode { get { @@ -119,21 +126,23 @@ public virtual XmlNode ParentNode } // Linear lookup through the children of the document - XmlLinkedNode firstChild = parentNode.FirstChild as XmlLinkedNode; + XmlLinkedNode? firstChild = parentNode.FirstChild as XmlLinkedNode; if (firstChild != null) { - XmlLinkedNode node = firstChild; + XmlLinkedNode? node = firstChild; do { if (node == this) { return parentNode; } + node = node.next; } while (node != null && node != firstChild); } + return null; } } @@ -145,26 +154,26 @@ public virtual XmlNodeList ChildNodes } // Gets the node immediately preceding this node. - public virtual XmlNode PreviousSibling + public virtual XmlNode? PreviousSibling { get { return null; } } // Gets the node immediately following this node. - public virtual XmlNode NextSibling + public virtual XmlNode? NextSibling { get { return null; } } // Gets a XmlAttributeCollection containing the attributes // of this node. - public virtual XmlAttributeCollection Attributes + public virtual XmlAttributeCollection? Attributes { get { return null; } } // Gets the XmlDocument that contains this node. - public virtual XmlDocument OwnerDocument + public virtual XmlDocument? OwnerDocument { get { @@ -176,11 +185,11 @@ public virtual XmlDocument OwnerDocument } // Gets the first child of this node. - public virtual XmlNode FirstChild + public virtual XmlNode? FirstChild { get { - XmlLinkedNode linkedNode = LastNode; + XmlLinkedNode? linkedNode = LastNode; if (linkedNode != null) return linkedNode.next; @@ -189,7 +198,7 @@ public virtual XmlNode FirstChild } // Gets the last child of this node. - public virtual XmlNode LastChild + public virtual XmlNode? LastChild { get { return LastNode; } } @@ -199,7 +208,7 @@ internal virtual bool IsContainer get { return false; } } - internal virtual XmlLinkedNode LastNode + internal virtual XmlLinkedNode? LastNode { get { return null; } set { } @@ -207,7 +216,7 @@ internal virtual XmlLinkedNode LastNode internal bool AncestorNode(XmlNode node) { - XmlNode n = this.ParentNode; + XmlNode? n = this.ParentNode; while (n != null && n != this) { @@ -222,14 +231,14 @@ internal bool AncestorNode(XmlNode node) //trace to the top to find out its parent node. internal bool IsConnected() { - XmlNode parent = ParentNode; + XmlNode? parent = ParentNode; while (parent != null && !(parent.NodeType == XmlNodeType.Document)) parent = parent.ParentNode; return parent != null; } // Inserts the specified node immediately before the specified reference node. - public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) + public virtual XmlNode? InsertBefore(XmlNode newChild, XmlNode? refChild) { if (this == newChild || AncestorNode(newChild)) throw new ArgumentException(SR.Xdom_Node_Insert_Child); @@ -246,8 +255,8 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) if (newChild == refChild) return newChild; - XmlDocument childDoc = newChild.OwnerDocument; - XmlDocument thisDoc = OwnerDocument; + XmlDocument? childDoc = newChild.OwnerDocument; + XmlDocument? thisDoc = OwnerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException(SR.Xdom_Node_Insert_Context); @@ -260,8 +269,8 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) // special case for doc-fragment. if (newChild.NodeType == XmlNodeType.DocumentFragment) { - XmlNode first = newChild.FirstChild; - XmlNode node = first; + XmlNode? first = newChild.FirstChild; + XmlNode? node = first; if (node != null) { newChild.RemoveChild(node); @@ -269,6 +278,7 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) // insert the rest of the children after this one. InsertAfter(newChild, node); } + return first; } @@ -278,8 +288,8 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) XmlLinkedNode newNode = (XmlLinkedNode)newChild; XmlLinkedNode refNode = (XmlLinkedNode)refChild; - string newChildValue = newChild.Value; - XmlNodeChangedEventArgs args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); + string? newChildValue = newChild.Value; + XmlNodeChangedEventArgs? args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); if (args != null) BeforeEvent(args); @@ -287,7 +297,7 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) if (refNode == FirstChild) { newNode.next = refNode; - LastNode.next = newNode; + LastNode!.next = newNode; newNode.SetParent(this); if (newNode.IsText) @@ -300,7 +310,7 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) } else { - XmlLinkedNode prevNode = (XmlLinkedNode)refNode.PreviousSibling; + XmlLinkedNode prevNode = (XmlLinkedNode)refNode.PreviousSibling!; newNode.next = refNode; prevNode.next = newNode; @@ -343,7 +353,7 @@ public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) } // Inserts the specified node immediately after the specified reference node. - public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) + public virtual XmlNode? InsertAfter(XmlNode newChild, XmlNode? refChild) { if (this == newChild || AncestorNode(newChild)) throw new ArgumentException(SR.Xdom_Node_Insert_Child); @@ -360,8 +370,8 @@ public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) if (newChild == refChild) return newChild; - XmlDocument childDoc = newChild.OwnerDocument; - XmlDocument thisDoc = OwnerDocument; + XmlDocument? childDoc = newChild.OwnerDocument; + XmlDocument? thisDoc = OwnerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException(SR.Xdom_Node_Insert_Context); @@ -375,11 +385,11 @@ public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) if (newChild.NodeType == XmlNodeType.DocumentFragment) { XmlNode last = refChild; - XmlNode first = newChild.FirstChild; - XmlNode node = first; + XmlNode? first = newChild.FirstChild; + XmlNode? node = first; while (node != null) { - XmlNode next = node.NextSibling; + XmlNode? next = node.NextSibling; newChild.RemoveChild(node); InsertAfter(node, last); last = node; @@ -394,8 +404,8 @@ public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) XmlLinkedNode newNode = (XmlLinkedNode)newChild; XmlLinkedNode refNode = (XmlLinkedNode)refChild; - string newChildValue = newChild.Value; - XmlNodeChangedEventArgs args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); + string? newChildValue = newChild.Value; + XmlNodeChangedEventArgs? args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); if (args != null) BeforeEvent(args); @@ -417,7 +427,7 @@ public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) } else { - XmlLinkedNode nextNode = refNode.next; + XmlLinkedNode nextNode = refNode.next!; newNode.next = nextNode; refNode.next = newNode; @@ -463,9 +473,9 @@ public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) // Replaces the child node oldChild with newChild node. public virtual XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild) { - XmlNode nextNode = oldChild.NextSibling; + XmlNode? nextNode = oldChild.NextSibling; RemoveChild(oldChild); - XmlNode node = InsertBefore(newChild, nextNode); + XmlNode? node = InsertBefore(newChild, nextNode); return oldChild; } @@ -480,13 +490,13 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) XmlLinkedNode oldNode = (XmlLinkedNode)oldChild; - string oldNodeValue = oldNode.Value; - XmlNodeChangedEventArgs args = GetEventArgs(oldNode, this, null, oldNodeValue, oldNodeValue, XmlNodeChangedAction.Remove); + string? oldNodeValue = oldNode.Value; + XmlNodeChangedEventArgs? args = GetEventArgs(oldNode, this, null, oldNodeValue, oldNodeValue, XmlNodeChangedAction.Remove); if (args != null) BeforeEvent(args); - XmlLinkedNode lastNode = LastNode; + XmlLinkedNode? lastNode = LastNode; if (oldNode == FirstChild) { @@ -498,7 +508,7 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) } else { - XmlLinkedNode nextNode = oldNode.next; + XmlLinkedNode nextNode = oldNode.next!; if (nextNode.IsText) { @@ -508,7 +518,7 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) } } - lastNode.next = nextNode; + lastNode!.next = nextNode; oldNode.next = null; oldNode.SetParent(null); } @@ -517,7 +527,7 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) { if (oldNode == lastNode) { - XmlLinkedNode prevNode = (XmlLinkedNode)oldNode.PreviousSibling; + XmlLinkedNode prevNode = (XmlLinkedNode)oldNode.PreviousSibling!; prevNode.next = oldNode.next; LastNode = prevNode; oldNode.next = null; @@ -525,8 +535,8 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) } else { - XmlLinkedNode prevNode = (XmlLinkedNode)oldNode.PreviousSibling; - XmlLinkedNode nextNode = oldNode.next; + XmlLinkedNode prevNode = (XmlLinkedNode)oldNode.PreviousSibling!; + XmlLinkedNode nextNode = oldNode.next!; if (nextNode.IsText) { @@ -556,15 +566,15 @@ public virtual XmlNode RemoveChild(XmlNode oldChild) } // Adds the specified node to the beginning of the list of children of this node. - public virtual XmlNode PrependChild(XmlNode newChild) + public virtual XmlNode? PrependChild(XmlNode newChild) { return InsertBefore(newChild, FirstChild); } // Adds the specified node to the end of the list of children of this node. - public virtual XmlNode AppendChild(XmlNode newChild) + public virtual XmlNode? AppendChild(XmlNode newChild) { - XmlDocument thisDoc = OwnerDocument; + XmlDocument? thisDoc = OwnerDocument; if (thisDoc == null) { thisDoc = this as XmlDocument; @@ -578,22 +588,23 @@ public virtual XmlNode AppendChild(XmlNode newChild) if (newChild.ParentNode != null) newChild.ParentNode.RemoveChild(newChild); - XmlDocument childDoc = newChild.OwnerDocument; + XmlDocument? childDoc = newChild.OwnerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException(SR.Xdom_Node_Insert_Context); // special case for doc-fragment. if (newChild.NodeType == XmlNodeType.DocumentFragment) { - XmlNode first = newChild.FirstChild; - XmlNode node = first; + XmlNode? first = newChild.FirstChild; + XmlNode? node = first; while (node != null) { - XmlNode next = node.NextSibling; + XmlNode? next = node.NextSibling; newChild.RemoveChild(node); AppendChild(node); node = next; } + return first; } @@ -604,13 +615,13 @@ public virtual XmlNode AppendChild(XmlNode newChild) if (!CanInsertAfter(newChild, LastChild)) throw new InvalidOperationException(SR.Xdom_Node_Insert_Location); - string newChildValue = newChild.Value; - XmlNodeChangedEventArgs args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); + string? newChildValue = newChild.Value; + XmlNodeChangedEventArgs? args = GetEventArgs(newChild, newChild.ParentNode, this, newChildValue, newChildValue, XmlNodeChangedAction.Insert); if (args != null) BeforeEvent(args); - XmlLinkedNode refNode = LastNode; + XmlLinkedNode? refNode = LastNode; XmlLinkedNode newNode = (XmlLinkedNode)newChild; if (refNode == null) @@ -644,12 +655,12 @@ public virtual XmlNode AppendChild(XmlNode newChild) //the function is provided only at Load time to speed up Load process internal virtual XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc) { - XmlNodeChangedEventArgs args = doc.GetInsertEventArgsForLoad(newChild, this); + XmlNodeChangedEventArgs? args = doc.GetInsertEventArgsForLoad(newChild, this); if (args != null) doc.BeforeEvent(args); - XmlLinkedNode refNode = LastNode; + XmlLinkedNode? refNode = LastNode; XmlLinkedNode newNode = (XmlLinkedNode)newChild; if (refNode == null) @@ -685,12 +696,12 @@ internal virtual bool IsValidChildType(XmlNodeType type) return false; } - internal virtual bool CanInsertBefore(XmlNode newChild, XmlNode refChild) + internal virtual bool CanInsertBefore(XmlNode newChild, XmlNode? refChild) { return true; } - internal virtual bool CanInsertAfter(XmlNode newChild, XmlNode refChild) + internal virtual bool CanInsertAfter(XmlNode newChild, XmlNode? refChild) { return true; } @@ -706,7 +717,7 @@ public virtual bool HasChildNodes internal virtual void CopyChildren(XmlDocument doc, XmlNode container, bool deep) { - for (XmlNode child = container.FirstChild; child != null; child = child.NextSibling) + for (XmlNode? child = container.FirstChild; child != null; child = child.NextSibling) { AppendChildForLoad(child.CloneNode(deep), doc); } @@ -721,11 +732,11 @@ internal virtual void CopyChildren(XmlDocument doc, XmlNode container, bool deep // are no adjacent XmlText nodes. public virtual void Normalize() { - XmlNode firstChildTextLikeNode = null; + XmlNode? firstChildTextLikeNode = null; StringBuilder sb = StringBuilderCache.Acquire(); - for (XmlNode crtChild = this.FirstChild; crtChild != null;) + for (XmlNode? crtChild = this.FirstChild; crtChild != null;) { - XmlNode nextChild = crtChild.NextSibling; + XmlNode? nextChild = crtChild.NextSibling; switch (crtChild.NodeType) { case XmlNodeType.Text: @@ -733,7 +744,7 @@ public virtual void Normalize() case XmlNodeType.SignificantWhitespace: { sb.Append(crtChild.Value); - XmlNode winner = NormalizeWinner(firstChildTextLikeNode, crtChild); + XmlNode? winner = NormalizeWinner(firstChildTextLikeNode, crtChild); if (winner == firstChildTextLikeNode) { this.RemoveChild(crtChild); @@ -744,6 +755,7 @@ public virtual void Normalize() this.RemoveChild(firstChildTextLikeNode); firstChildTextLikeNode = crtChild; } + break; } case XmlNodeType.Element: @@ -758,6 +770,7 @@ public virtual void Normalize() firstChildTextLikeNode.Value = sb.ToString(); firstChildTextLikeNode = null; } + sb.Remove(0, sb.Length); break; } @@ -770,7 +783,7 @@ public virtual void Normalize() StringBuilderCache.Release(sb); } - private XmlNode NormalizeWinner(XmlNode firstNode, XmlNode secondNode) + private XmlNode? NormalizeWinner(XmlNode? firstNode, XmlNode secondNode) { //first node has the priority if (firstNode == null) @@ -834,12 +847,12 @@ public virtual bool IsReadOnly { get { - XmlDocument doc = OwnerDocument; + XmlDocument? doc = OwnerDocument; return HasReadOnlyParent(this); } } - internal static bool HasReadOnlyParent(XmlNode n) + internal static bool HasReadOnlyParent(XmlNode? n) { while (n != null) { @@ -886,7 +899,7 @@ public IEnumerator GetEnumerator() private void AppendChildText(StringBuilder builder) { - for (XmlNode child = FirstChild; child != null; child = child.NextSibling) + for (XmlNode? child = FirstChild; child != null; child = child.NextSibling) { if (child.FirstChild == null) { @@ -907,7 +920,7 @@ public virtual string InnerText { get { - XmlNode fc = FirstChild; + XmlNode? fc = FirstChild; if (fc == null) { return string.Empty; @@ -921,9 +934,10 @@ public virtual string InnerText case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - return fc.Value; + return fc.Value!; } } + StringBuilder builder = StringBuilderCache.Acquire(); AppendChildText(builder); return StringBuilderCache.GetStringAndRelease(builder); @@ -931,7 +945,7 @@ public virtual string InnerText set { - XmlNode firstChild = FirstChild; + XmlNode? firstChild = FirstChild; if (firstChild != null //there is one child && firstChild.NextSibling == null // and exactly one && firstChild.NodeType == XmlNodeType.Text)//which is a text node @@ -942,7 +956,7 @@ public virtual string InnerText else { RemoveAll(); - AppendChild(OwnerDocument.CreateTextNode(value)); + AppendChild(OwnerDocument!.CreateTextNode(value)); } } } @@ -1002,7 +1016,7 @@ public virtual string BaseURI { get { - XmlNode curNode = this.ParentNode; //save one while loop since if going to here, the nodetype of this node can't be document, entity and entityref + XmlNode? curNode = this.ParentNode; //save one while loop since if going to here, the nodetype of this node can't be document, entity and entityref while (curNode != null) { XmlNodeType nt = curNode.NodeType; @@ -1030,8 +1044,8 @@ public virtual string BaseURI // of the current node. public virtual void RemoveAll() { - XmlNode child = FirstChild; - XmlNode sibling = null; + XmlNode? child = FirstChild; + XmlNode? sibling = null; while (child != null) { @@ -1047,7 +1061,7 @@ internal XmlDocument Document { if (NodeType == XmlNodeType.Document) return (XmlDocument)this; - return OwnerDocument; + return OwnerDocument!; } } @@ -1056,20 +1070,22 @@ internal XmlDocument Document // the namespace URI in the declaration. public virtual string GetNamespaceOfPrefix(string prefix) { - string namespaceName = GetNamespaceOfPrefixStrict(prefix); - return namespaceName != null ? namespaceName : string.Empty; + string? namespaceName = GetNamespaceOfPrefixStrict(prefix); + return namespaceName ?? string.Empty; } - internal string GetNamespaceOfPrefixStrict(string prefix) + internal string? GetNamespaceOfPrefixStrict(string prefix) { XmlDocument doc = Document; + string? pref = prefix; + if (doc != null) { - prefix = doc.NameTable.Get(prefix); - if (prefix == null) + pref = doc.NameTable.Get(pref); + if (pref == null) return null; - XmlNode node = this; + XmlNode? node = this; while (node != null) { if (node.NodeType == XmlNodeType.Element) @@ -1078,7 +1094,7 @@ internal string GetNamespaceOfPrefixStrict(string prefix) if (elem.HasAttributes) { XmlAttributeCollection attrs = elem.Attributes; - if (prefix.Length == 0) + if (pref.Length == 0) { for (int iAttr = 0; iAttr < attrs.Count; iAttr++) { @@ -1099,19 +1115,19 @@ internal string GetNamespaceOfPrefixStrict(string prefix) XmlAttribute attr = attrs[iAttr]; if (Ref.Equal(attr.Prefix, doc.strXmlns)) { - if (Ref.Equal(attr.LocalName, prefix)) + if (Ref.Equal(attr.LocalName, pref)) { return attr.Value; // found xmlns:prefix } } - else if (Ref.Equal(attr.Prefix, prefix)) + else if (Ref.Equal(attr.Prefix, pref)) { return attr.NamespaceURI; // found prefix:attr } } } } - if (Ref.Equal(node.Prefix, prefix)) + if (Ref.Equal(node.Prefix, pref)) { return node.NamespaceURI; } @@ -1126,15 +1142,16 @@ internal string GetNamespaceOfPrefixStrict(string prefix) node = node.ParentNode; } } - if (Ref.Equal(doc.strXml, prefix)) + if (Ref.Equal(doc.strXml, pref)) { // xmlns:xml return doc.strReservedXml; } - else if (Ref.Equal(doc.strXmlns, prefix)) + else if (Ref.Equal(doc.strXmlns, pref)) { // xmlns:xmlns return doc.strReservedXmlns; } } + return null; } @@ -1143,18 +1160,18 @@ internal string GetNamespaceOfPrefixStrict(string prefix) // the prefix defined in that declaration. public virtual string GetPrefixOfNamespace(string namespaceURI) { - string prefix = GetPrefixOfNamespaceStrict(namespaceURI); + string? prefix = GetPrefixOfNamespaceStrict(namespaceURI); return prefix != null ? prefix : string.Empty; } - internal string GetPrefixOfNamespaceStrict(string namespaceURI) + internal string? GetPrefixOfNamespaceStrict(string namespaceURI) { XmlDocument doc = Document; if (doc != null) { namespaceURI = doc.NameTable.Add(namespaceURI); - XmlNode node = this; + XmlNode? node = this; while (node != null) { if (node.NodeType == XmlNodeType.Element) @@ -1214,39 +1231,42 @@ internal string GetPrefixOfNamespaceStrict(string namespaceURI) return doc.strXmlns; } } + return null; } // Retrieves the first child element with the specified name. - public virtual XmlElement this[string name] + public virtual XmlElement? this[string name] { get { - for (XmlNode n = FirstChild; n != null; n = n.NextSibling) + for (XmlNode? n = FirstChild; n != null; n = n.NextSibling) { if (n.NodeType == XmlNodeType.Element && n.Name == name) return (XmlElement)n; } + return null; } } // Retrieves the first child element with the specified LocalName and // NamespaceURI. - public virtual XmlElement this[string localname, string ns] + public virtual XmlElement? this[string localname, string ns] { get { - for (XmlNode n = FirstChild; n != null; n = n.NextSibling) + for (XmlNode? n = FirstChild; n != null; n = n.NextSibling) { if (n.NodeType == XmlNodeType.Element && n.LocalName == localname && n.NamespaceURI == ns) return (XmlElement)n; } + return null; } } - internal virtual void SetParent(XmlNode node) + internal virtual void SetParent(XmlNode? node) { if (node == null) { @@ -1278,21 +1298,22 @@ internal static void SplitName(string name, out string prefix, out string localN } } - internal virtual XmlNode FindChild(XmlNodeType type) + internal virtual XmlNode? FindChild(XmlNodeType type) { - for (XmlNode child = FirstChild; child != null; child = child.NextSibling) + for (XmlNode? child = FirstChild; child != null; child = child.NextSibling) { if (child.NodeType == type) { return child; } } + return null; } - internal virtual XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParent, string oldValue, string newValue, XmlNodeChangedAction action) + internal virtual XmlNodeChangedEventArgs? GetEventArgs(XmlNode node, XmlNode? oldParent, XmlNode? newParent, string? oldValue, string? newValue, XmlNodeChangedAction action) { - XmlDocument doc = OwnerDocument; + XmlDocument? doc = OwnerDocument; if (doc != null) { if (!doc.IsLoading) @@ -1300,29 +1321,31 @@ internal virtual XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode oldP if (((newParent != null && newParent.IsReadOnly) || (oldParent != null && oldParent.IsReadOnly))) throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly); } + return doc.GetEventArgs(node, oldParent, newParent, oldValue, newValue, action); } + return null; } internal virtual void BeforeEvent(XmlNodeChangedEventArgs args) { if (args != null) - OwnerDocument.BeforeEvent(args); + OwnerDocument!.BeforeEvent(args); } internal virtual void AfterEvent(XmlNodeChangedEventArgs args) { if (args != null) - OwnerDocument.AfterEvent(args); + OwnerDocument!.AfterEvent(args); } internal virtual XmlSpace XmlSpace { get { - XmlNode node = this; - XmlElement elem = null; + XmlNode? node = this; + XmlElement? elem = null; do { elem = node as XmlElement; @@ -1339,9 +1362,10 @@ internal virtual XmlSpace XmlSpace break; } } + node = node.ParentNode; - } - while (node != null); + } while (node != null); + return XmlSpace.None; } } @@ -1350,8 +1374,8 @@ internal virtual string XmlLang { get { - XmlNode node = this; - XmlElement elem = null; + XmlNode? node = this; + XmlElement? elem = null; do { elem = node as XmlElement; @@ -1360,8 +1384,10 @@ internal virtual string XmlLang if (elem.HasAttribute("xml:lang")) return elem.GetAttribute("xml:lang"); } + node = node.ParentNode; } while (node != null); + return string.Empty; } } @@ -1382,7 +1408,7 @@ internal virtual string XPLocalName } } - internal virtual string GetXPAttribute(string localName, string namespaceURI) + internal virtual string? GetXPAttribute(string localName, string namespaceURI) { return string.Empty; } @@ -1395,7 +1421,7 @@ internal virtual bool IsText } } - public virtual XmlNode PreviousText + public virtual XmlNode? PreviousText { get { @@ -1443,7 +1469,7 @@ public override string ToString() break; case XmlNodeType.Attribute: case XmlNodeType.ProcessingInstruction: - result += ", Name=\"" + _node.Name + "\", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_node.Value) + "\""; + result += ", Name=\"" + _node.Name + "\", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_node.Value!) + "\""; break; case XmlNodeType.Text: case XmlNodeType.CDATA: @@ -1451,11 +1477,11 @@ public override string ToString() case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: case XmlNodeType.XmlDeclaration: - result += ", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_node.Value) + "\""; + result += ", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_node.Value!) + "\""; break; case XmlNodeType.DocumentType: XmlDocumentType documentType = (XmlDocumentType)_node; - result += ", Name=\"" + documentType.Name + "\", SYSTEM=\"" + documentType.SystemId + "\", PUBLIC=\"" + documentType.PublicId + "\", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(documentType.InternalSubset) + "\""; + result += ", Name=\"" + documentType.Name + "\", SYSTEM=\"" + documentType.SystemId + "\", PUBLIC=\"" + documentType.PublicId + "\", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(documentType.InternalSubset!) + "\""; break; default: break; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventArgs.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventArgs.cs index 6ab108ff5264..d89ed2ffb1e4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventArgs.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventArgs.cs @@ -1,18 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml { public class XmlNodeChangedEventArgs : EventArgs { private readonly XmlNodeChangedAction _action; - private readonly XmlNode _node; - private readonly XmlNode _oldParent; - private readonly XmlNode _newParent; - private readonly string _oldValue; - private readonly string _newValue; + private readonly XmlNode? _node; + private readonly XmlNode? _oldParent; + private readonly XmlNode? _newParent; + private readonly string? _oldValue; + private readonly string? _newValue; - public XmlNodeChangedEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParent, string oldValue, string newValue, XmlNodeChangedAction action) + public XmlNodeChangedEventArgs(XmlNode? node, XmlNode? oldParent, XmlNode? newParent, string? oldValue, string? newValue, XmlNodeChangedAction action) { _node = node; _oldParent = oldParent; @@ -24,14 +25,14 @@ public XmlNodeChangedEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParen public XmlNodeChangedAction Action { get { return _action; } } - public XmlNode Node { get { return _node; } } + public XmlNode? Node { get { return _node; } } - public XmlNode OldParent { get { return _oldParent; } } + public XmlNode? OldParent { get { return _oldParent; } } - public XmlNode NewParent { get { return _newParent; } } + public XmlNode? NewParent { get { return _newParent; } } - public string OldValue { get { return _oldValue; } } + public string? OldValue { get { return _oldValue; } } - public string NewValue { get { return _newValue; } } + public string? NewValue { get { return _newValue; } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventHandler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventHandler.cs index b63ac819cf4f..d106ceacf243 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventHandler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeChangedEventHandler.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. +#nullable enable namespace System.Xml { public delegate void XmlNodeChangedEventHandler(object sender, XmlNodeChangedEventArgs e); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeList.cs index 2c14561a41ce..0565f5203a92 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeList.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. +#nullable enable using System.Collections; namespace System.Xml @@ -9,7 +10,7 @@ namespace System.Xml public abstract class XmlNodeList : IEnumerable, IDisposable { // Retrieves a node at the given index. - public abstract XmlNode Item(int index); + public abstract XmlNode? Item(int index); // Gets the number of nodes in this XmlNodeList. public abstract int Count { get; } @@ -20,7 +21,7 @@ public abstract class XmlNodeList : IEnumerable, IDisposable // Retrieves a node at the given index. [System.Runtime.CompilerServices.IndexerName("ItemOf")] - public virtual XmlNode this[int i] { get { return Item(i); } } + public virtual XmlNode? this[int i] { get { return Item(i); } } void IDisposable.Dispose() { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs index 4ed38db85abf..b3a255cd4679 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs @@ -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. +#nullable enable namespace System.Xml { using System; @@ -15,7 +16,7 @@ namespace System.Xml internal class XmlNodeReaderNavigator { private XmlNode _curNode; - private XmlNode _elemNode; + private XmlNode? _elemNode; private XmlNode _logNode; private int _attrIndex; private int _logAttrIndex; @@ -45,10 +46,10 @@ internal class XmlNodeReaderNavigator internal struct VirtualAttribute { - internal string name; - internal string value; + internal string? name; + internal string? value; - internal VirtualAttribute(string name, string value) + internal VirtualAttribute(string? name, string? value) { this.name = name; this.value = value; @@ -89,7 +90,8 @@ public XmlNodeReaderNavigator(XmlNode node) if (nt == XmlNodeType.Document) _doc = (XmlDocument)_curNode; else - _doc = node.OwnerDocument; + _doc = node.OwnerDocument!; + _nameTable = _doc.NameTable; _nAttrInd = -1; //initialize the caching variables @@ -134,9 +136,9 @@ public string Name { Debug.Assert(_nAttrInd >= 0 && _nAttrInd < AttributeCount); if (_curNode.NodeType == XmlNodeType.XmlDeclaration) - return decNodeAttributes[_nAttrInd].name; + return decNodeAttributes[_nAttrInd].name!; else - return docTypeNodeAttributes[_nAttrInd].name; + return docTypeNodeAttributes[_nAttrInd].name!; } } if (IsLocalNameEmpty(_curNode.NodeType)) @@ -225,7 +227,7 @@ public string Value //See comments in HasValue get { - string retValue = null; + string? retValue = null; XmlNodeType nt = _curNode.NodeType; if (_nAttrInd != -1) { @@ -233,9 +235,9 @@ public string Value Debug.Assert(nt == XmlNodeType.XmlDeclaration || nt == XmlNodeType.DocumentType); Debug.Assert(_nAttrInd >= 0 && _nAttrInd < AttributeCount); if (_curNode.NodeType == XmlNodeType.XmlDeclaration) - return decNodeAttributes[_nAttrInd].value; + return decNodeAttributes[_nAttrInd].value!; else - return docTypeNodeAttributes[_nAttrInd].value; + return docTypeNodeAttributes[_nAttrInd].value!; } if (nt == XmlNodeType.DocumentType) retValue = ((XmlDocumentType)_curNode).InternalSubset; //in this case nav.Value will be null @@ -321,7 +323,7 @@ public int AttributeCount return ((XmlElement)_curNode).Attributes.Count; else if (nt == XmlNodeType.Attribute || (_bOnAttrVal && nt != XmlNodeType.XmlDeclaration && nt != XmlNodeType.DocumentType)) - return _elemNode.Attributes.Count; + return _elemNode!.Attributes!.Count; else if (nt == XmlNodeType.XmlDeclaration) { if (_nDeclarationAttrCount != -1) @@ -352,7 +354,7 @@ private void CheckIndexCondition(int attributeIndex) private void InitDecAttr() { int i = 0; - string strTemp = _doc.Version; + string? strTemp = _doc.Version; if (strTemp != null && strTemp.Length != 0) { decNodeAttributes[i].name = strVersion; @@ -376,7 +378,7 @@ private void InitDecAttr() _nDeclarationAttrCount = i; } - public string GetDeclarationAttr(XmlDeclaration decl, string name) + public string? GetDeclarationAttr(XmlDeclaration decl, string name) { //PreCondition: curNode is pointing at Declaration node or one of its virtual attributes if (name == strVersion) @@ -388,7 +390,7 @@ public string GetDeclarationAttr(XmlDeclaration decl, string name) return null; } - public string GetDeclarationAttr(int i) + public string? GetDeclarationAttr(int i) { if (_nDeclarationAttrCount == -1) InitDecAttr(); @@ -410,19 +412,21 @@ public int GetDecAttrInd(string name) private void InitDocTypeAttr() { int i = 0; - XmlDocumentType docType = _doc.DocumentType; + XmlDocumentType? docType = _doc.DocumentType; if (docType == null) { _nDocTypeAttrCount = 0; return; } - string strTemp = docType.PublicId; + + string? strTemp = docType.PublicId; if (strTemp != null) { docTypeNodeAttributes[i].name = strPublicID; docTypeNodeAttributes[i].value = strTemp; i++; } + strTemp = docType.SystemId; if (strTemp != null) { @@ -430,10 +434,11 @@ private void InitDocTypeAttr() docTypeNodeAttributes[i].value = strTemp; i++; } + _nDocTypeAttrCount = i; } - public string GetDocumentTypeAttr(XmlDocumentType docType, string name) + public string? GetDocumentTypeAttr(XmlDocumentType docType, string name) { //PreCondition: nav is pointing at DocumentType node or one of its virtual attributes if (name == strPublicID) @@ -443,7 +448,7 @@ public string GetDocumentTypeAttr(XmlDocumentType docType, string name) return null; } - public string GetDocumentTypeAttr(int i) + public string? GetDocumentTypeAttr(int i) { if (_nDocTypeAttrCount == -1) InitDocTypeAttr(); @@ -462,37 +467,37 @@ public int GetDocTypeAttrInd(string name) return -1; } - private string GetAttributeFromElement(XmlElement elem, string name) + private string? GetAttributeFromElement(XmlElement elem, string name) { - XmlAttribute attr = elem.GetAttributeNode(name); + XmlAttribute? attr = elem.GetAttributeNode(name); if (attr != null) return attr.Value; return null; } - public string GetAttribute(string name) + public string? GetAttribute(string name) { if (_bCreatedOnAttribute) return null; return _curNode.NodeType switch { - XmlNodeType.Element => GetAttributeFromElement((XmlElement)_curNode, name), - XmlNodeType.Attribute => GetAttributeFromElement((XmlElement)_elemNode, name), + XmlNodeType.Element => GetAttributeFromElement((XmlElement)_curNode!, name), + XmlNodeType.Attribute => GetAttributeFromElement((XmlElement)_elemNode!, name), XmlNodeType.XmlDeclaration => GetDeclarationAttr((XmlDeclaration)_curNode, name), XmlNodeType.DocumentType => GetDocumentTypeAttr((XmlDocumentType)_curNode, name), _ => null, }; } - private string GetAttributeFromElement(XmlElement elem, string name, string ns) + private string? GetAttributeFromElement(XmlElement elem, string name, string? ns) { - XmlAttribute attr = elem.GetAttributeNode(name, ns); + XmlAttribute? attr = elem.GetAttributeNode(name, ns); if (attr != null) return attr.Value; return null; } - public string GetAttribute(string name, string ns) + public string? GetAttribute(string name, string ns) { if (_bCreatedOnAttribute) return null; @@ -500,14 +505,14 @@ public string GetAttribute(string name, string ns) return _curNode.NodeType switch { XmlNodeType.Element => GetAttributeFromElement((XmlElement)_curNode, name, ns), - XmlNodeType.Attribute => GetAttributeFromElement((XmlElement)_elemNode, name, ns), + XmlNodeType.Attribute => GetAttributeFromElement((XmlElement)_elemNode!, name, ns), XmlNodeType.XmlDeclaration => (ns.Length == 0) ? GetDeclarationAttr((XmlDeclaration)_curNode, name) : null, XmlNodeType.DocumentType => (ns.Length == 0) ? GetDocumentTypeAttr((XmlDocumentType)_curNode, name) : null, _ => null, }; } - public string GetAttribute(int attributeIndex) + public string? GetAttribute(int attributeIndex) { if (_bCreatedOnAttribute) return null; @@ -518,7 +523,7 @@ public string GetAttribute(int attributeIndex) return ((XmlElement)_curNode).Attributes[attributeIndex].Value; case XmlNodeType.Attribute: CheckIndexCondition(attributeIndex); - return ((XmlElement)_elemNode).Attributes[attributeIndex].Value; + return ((XmlElement)_elemNode!).Attributes[attributeIndex].Value; case XmlNodeType.XmlDeclaration: { CheckIndexCondition(attributeIndex); @@ -576,9 +581,10 @@ public void ResetToAttribute(ref int level) } else { - while (_curNode.NodeType != XmlNodeType.Attribute && ((_curNode = _curNode.ParentNode) != null)) + while (_curNode.NodeType != XmlNodeType.Attribute && ((_curNode = _curNode.ParentNode!) != null)) level--; } + _bOnAttrVal = false; } } @@ -606,7 +612,7 @@ public void ResetMove(ref int level, ref XmlNodeType nt) ResetToAttribute(ref level); if (_curNode.NodeType == XmlNodeType.Attribute) { - _curNode = ((XmlAttribute)_curNode).OwnerElement; + _curNode = ((XmlAttribute)_curNode).OwnerElement!; _attrIndex = -1; level--; nt = XmlNodeType.Element; @@ -621,7 +627,7 @@ public bool MoveToAttribute(string name) } private bool MoveToAttributeFromElement(XmlElement elem, string name, string ns) { - XmlAttribute attr = null; + XmlAttribute? attr = null; if (ns.Length == 0) attr = elem.GetAttributeNode(name); else @@ -648,7 +654,7 @@ public bool MoveToAttribute(string name, string namespaceURI) if (nt == XmlNodeType.Element) return MoveToAttributeFromElement((XmlElement)_curNode, name, namespaceURI); else if (nt == XmlNodeType.Attribute) - return MoveToAttributeFromElement((XmlElement)_elemNode, name, namespaceURI); + return MoveToAttributeFromElement((XmlElement)_elemNode!, name, namespaceURI); else if (nt == XmlNodeType.XmlDeclaration && namespaceURI.Length == 0) { if ((_nAttrInd = GetDecAttrInd(name)) != -1) @@ -672,7 +678,7 @@ public void MoveToAttribute(int attributeIndex) { if (_bCreatedOnAttribute) return; - XmlAttribute attr = null; + XmlAttribute? attr = null; switch (_curNode.NodeType) { case XmlNodeType.Element: @@ -687,7 +693,7 @@ public void MoveToAttribute(int attributeIndex) break; case XmlNodeType.Attribute: CheckIndexCondition(attributeIndex); - attr = ((XmlElement)_elemNode).Attributes[attributeIndex]; + attr = ((XmlElement)_elemNode!).Attributes[attributeIndex]; if (attr != null) { _curNode = (XmlNode)attr; @@ -709,7 +715,7 @@ public bool MoveToNextAttribute(ref int level) XmlNodeType nt = _curNode.NodeType; if (nt == XmlNodeType.Attribute) { - if (_attrIndex >= (_elemNode.Attributes.Count - 1)) + if (_attrIndex >= (_elemNode!.Attributes!.Count - 1)) return false; else { @@ -719,7 +725,7 @@ public bool MoveToNextAttribute(ref int level) } else if (nt == XmlNodeType.Element) { - if (_curNode.Attributes.Count > 0) + if (_curNode.Attributes!.Count > 0) { level++; _elemNode = _curNode; @@ -759,7 +765,7 @@ public bool MoveToNextAttribute(ref int level) public bool MoveToParent() { - XmlNode parent = _curNode.ParentNode; + XmlNode? parent = _curNode.ParentNode; if (parent != null) { _curNode = parent; @@ -772,7 +778,7 @@ public bool MoveToParent() public bool MoveToFirstChild() { - XmlNode firstChild = _curNode.FirstChild; + XmlNode? firstChild = _curNode.FirstChild; if (firstChild != null) { _curNode = firstChild; @@ -780,12 +786,13 @@ public bool MoveToFirstChild() _attrIndex = -1; return true; } + return false; } private bool MoveToNextSibling(XmlNode node) { - XmlNode nextSibling = node.NextSibling; + XmlNode? nextSibling = node.NextSibling; if (nextSibling != null) { _curNode = nextSibling; @@ -793,6 +800,7 @@ private bool MoveToNextSibling(XmlNode node) _attrIndex = -1; return true; } + return false; } @@ -801,7 +809,7 @@ public bool MoveToNext() if (_curNode.NodeType != XmlNodeType.Attribute) return MoveToNextSibling(_curNode); else - return MoveToNextSibling(_elemNode); + return MoveToNextSibling(_elemNode!); } public bool MoveToElement() @@ -832,7 +840,7 @@ public bool MoveToElement() return false; } - public string LookupNamespace(string prefix) + public string? LookupNamespace(string prefix) { if (_bCreatedOnAttribute) return null; @@ -855,7 +863,7 @@ public string LookupNamespace(string prefix) attrName = "xmlns:" + prefix; // walk up the XmlNode parent chain, looking for the xmlns attribute - XmlNode node = _curNode; + XmlNode? node = _curNode; while (node != null) { if (node.NodeType == XmlNodeType.Element) @@ -863,7 +871,7 @@ public string LookupNamespace(string prefix) XmlElement elem = (XmlElement)node; if (elem.HasAttributes) { - XmlAttribute attr = elem.GetAttributeNode(attrName); + XmlAttribute? attr = elem.GetAttributeNode(attrName); if (attr != null) { return attr.Value; @@ -884,7 +892,7 @@ public string LookupNamespace(string prefix) return null; } - internal string DefaultLookupNamespace(string prefix) + internal string? DefaultLookupNamespace(string prefix) { if (!_bCreatedOnAttribute) { @@ -904,7 +912,7 @@ internal string DefaultLookupNamespace(string prefix) return null; } - internal string LookupPrefix(string namespaceName) + internal string? LookupPrefix(string namespaceName) { if (_bCreatedOnAttribute || namespaceName == null) { @@ -923,7 +931,7 @@ internal string LookupPrefix(string namespaceName) return string.Empty; } // walk up the XmlNode parent chain, looking for the xmlns attribute with namespaceName value - XmlNode node = _curNode; + XmlNode? node = _curNode; while (node != null) { if (node.NodeType == XmlNodeType.Element) @@ -961,8 +969,10 @@ internal string LookupPrefix(string namespaceName) node = ((XmlAttribute)node).OwnerElement; continue; } + node = node.ParentNode; } + return null; } @@ -973,7 +983,7 @@ internal IDictionary GetNamespacesInScope(XmlNamespaceScope scop return dict; // walk up the XmlNode parent chain and add all namespace declarations to the dictionary - XmlNode node = _curNode; + XmlNode? node = _curNode; while (node != null) { if (node.NodeType == XmlNodeType.Element) @@ -989,7 +999,7 @@ internal IDictionary GetNamespacesInScope(XmlNamespaceScope scop { if (!dict.ContainsKey(string.Empty)) { - dict.Add(_nameTable.Add(string.Empty), _nameTable.Add(a.Value)); + dict.Add(_nameTable.Add(string.Empty), _nameTable.Add(a.Value!)); } } else if (a.Prefix == "xmlns") @@ -997,7 +1007,7 @@ internal IDictionary GetNamespacesInScope(XmlNamespaceScope scop string localName = a.LocalName; if (!dict.ContainsKey(localName)) { - dict.Add(_nameTable.Add(localName), _nameTable.Add(a.Value)); + dict.Add(_nameTable.Add(localName), _nameTable.Add(a.Value!)); } } } @@ -1012,6 +1022,7 @@ internal IDictionary GetNamespacesInScope(XmlNamespaceScope scop node = ((XmlAttribute)node).OwnerElement; continue; } + node = node.ParentNode; }; @@ -1045,7 +1056,7 @@ public bool ReadAttributeValue(ref int level, ref bool bResolveEntity, ref XmlNo } if (_curNode.NodeType == XmlNodeType.Attribute) { - XmlNode firstChild = _curNode.FirstChild; + XmlNode? firstChild = _curNode.FirstChild; if (firstChild != null) { _curNode = firstChild; @@ -1057,13 +1068,13 @@ public bool ReadAttributeValue(ref int level, ref bool bResolveEntity, ref XmlNo } else if (_bOnAttrVal) { - XmlNode nextSibling = null; + XmlNode? nextSibling = null; if (_curNode.NodeType == XmlNodeType.EntityReference && bResolveEntity) { //going down to ent ref node - _curNode = _curNode.FirstChild; - nt = _curNode.NodeType; + _curNode = _curNode.FirstChild!; Debug.Assert(_curNode != null); + nt = _curNode.NodeType; level++; bResolveEntity = false; return true; @@ -1072,7 +1083,7 @@ public bool ReadAttributeValue(ref int level, ref bool bResolveEntity, ref XmlNo nextSibling = _curNode.NextSibling; if (nextSibling == null) { - XmlNode parentNode = _curNode.ParentNode; + XmlNode? parentNode = _curNode.ParentNode; //Check if its parent is entity ref node is sufficient, because in this senario, ent ref node can't have more than 1 level of children that are not other ent ref nodes if (parentNode != null && parentNode.NodeType == XmlNodeType.EntityReference) { @@ -1119,7 +1130,7 @@ public class XmlNodeReader : XmlReader, IXmlNamespaceResolver private bool _bStartFromDocument; private bool _bInReadBinary; - private ReadContentAsBinaryHelper _readBinaryHelper; + private ReadContentAsBinaryHelper? _readBinaryHelper; // Creates an instance of the XmlNodeReader class using the specified XmlNode. @@ -1129,6 +1140,7 @@ public XmlNodeReader(XmlNode node) { throw new ArgumentNullException(nameof(node)); } + _readerNav = new XmlNodeReaderNavigator(node); _curDepth = 0; @@ -1290,7 +1302,7 @@ public override string XmlLang } } - public override IXmlSchemaInfo SchemaInfo + public override IXmlSchemaInfo? SchemaInfo { get { @@ -1318,7 +1330,7 @@ public override int AttributeCount } // Gets the value of the attribute with the specified name. - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { //if not on Attribute, only element node could have attributes if (!IsInReadingStates()) @@ -1327,7 +1339,7 @@ public override string GetAttribute(string name) } // Gets the value of the attribute with the specified name and namespace. - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string? namespaceURI) { //if not on Attribute, only element node could have attributes if (!IsInReadingStates()) @@ -1343,7 +1355,7 @@ public override string GetAttribute(int attributeIndex) throw new ArgumentOutOfRangeException(nameof(attributeIndex)); //CheckIndexCondition( i ); //Debug.Assert( nav.NodeType == XmlNodeType.Element ); - return _readerNav.GetAttribute(attributeIndex); + return _readerNav.GetAttribute(attributeIndex)!; } // Moves to the attribute with the specified name. @@ -1367,7 +1379,7 @@ public override bool MoveToAttribute(string name) } // Moves to the attribute with the specified name and namespace. - public override bool MoveToAttribute(string name, string namespaceURI) + public override bool MoveToAttribute(string name, string? namespaceURI) { if (!IsInReadingStates()) return false; @@ -1743,11 +1755,11 @@ public override XmlNameTable NameTable } // Resolves a namespace prefix in the current element's scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { if (!IsInReadingStates()) return null; - string ns = _readerNav.LookupNamespace(prefix); + string? ns = _readerNav.LookupNamespace(prefix); if (ns != null && ns.Length == 0) { return null; @@ -1802,7 +1814,7 @@ public override int ReadContentAsBase64(byte[] buffer, int index, int count) _bInReadBinary = false; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBase64(buffer, index, count); // turn on bInReadBinary in again and return _bInReadBinary = true; @@ -1826,7 +1838,7 @@ public override int ReadContentAsBinHex(byte[] buffer, int index, int count) _bInReadBinary = false; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBinHex(buffer, index, count); // turn on bInReadBinary in again and return _bInReadBinary = true; @@ -1850,7 +1862,7 @@ public override int ReadElementContentAsBase64(byte[] buffer, int index, int cou _bInReadBinary = false; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBase64(buffer, index, count); // turn on bInReadBinary in again and return _bInReadBinary = true; @@ -1874,7 +1886,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou _bInReadBinary = false; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBinHex(buffer, index, count); // turn on bInReadBinary in again and return _bInReadBinary = true; @@ -1884,7 +1896,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou private void FinishReadBinary() { _bInReadBinary = false; - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); } // @@ -1896,27 +1908,29 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return _readerNav.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _readerNav.LookupPrefix(namespaceName); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { if (!IsInReadingStates()) { return _readerNav.DefaultLookupNamespace(prefix); } - string ns = _readerNav.LookupNamespace(prefix); + + string? ns = _readerNav.LookupNamespace(prefix); if (ns != null) { ns = _readerNav.NameTable.Add(ns); } + return ns; } // DTD/Schema info used by XmlReader.GetDtdSchemaInfo() - internal override IDtdInfo DtdInfo + internal override IDtdInfo? DtdInfo { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNotation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNotation.cs index ed7d107dd06a..79ed84c14d35 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNotation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNotation.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. +#nullable enable namespace System.Xml { using System; @@ -9,11 +10,11 @@ namespace System.Xml // Contains a notation declared in the DTD or schema. public class XmlNotation : XmlNode { - private readonly string _publicId; - private readonly string _systemId; + private readonly string? _publicId; + private readonly string? _systemId; private readonly string _name; - internal XmlNotation(string name, string publicId, string systemId, XmlDocument doc) : base(doc) + internal XmlNotation(string name, string? publicId, string? systemId, XmlDocument doc) : base(doc) { _name = doc.NameTable.Add(name); _publicId = publicId; @@ -58,14 +59,14 @@ public override bool IsReadOnly } // Gets the value of the public identifier on the notation declaration. - public string PublicId + public string? PublicId { get { return _publicId; } } // Gets the value of // the system identifier on the notation declaration. - public string SystemId + public string? SystemId { get { return _systemId; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlProcessingInstruction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlProcessingInstruction.cs index 6fc679fafe8a..89e36be95503 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlProcessingInstruction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlProcessingInstruction.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.XPath; namespace System.Xml @@ -37,14 +39,15 @@ public override string LocalName } // Gets or sets the value of the node. + [AllowNull] public override string Value { get { return _data; } - set { Data = value; } //use Data instead of data so that event will be fired + set { Data = value!; } //use Data instead of data so that event will be fired } // Gets the target of the processing instruction. - public string Target + public string? Target { get { return _target; } } @@ -56,8 +59,8 @@ public string Data get { return _data; } set { - XmlNode parent = ParentNode; - XmlNodeChangedEventArgs args = GetEventArgs(this, parent, parent, _data, value, XmlNodeChangedAction.Change); + XmlNode? parent = ParentNode; + XmlNodeChangedEventArgs? args = GetEventArgs(this, parent, parent, _data, value, XmlNodeChangedAction.Change); if (args != null) BeforeEvent(args); _data = value; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlSignificantWhiteSpace.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlSignificantWhiteSpace.cs index a7ba3c8d74e4..dd9995d57f31 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlSignificantWhiteSpace.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlSignificantWhiteSpace.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -9,7 +10,7 @@ namespace System.Xml // Represents the text content of an element or attribute. public class XmlSignificantWhitespace : XmlCharacterData { - protected internal XmlSignificantWhitespace(string strData, XmlDocument doc) : base(strData, doc) + protected internal XmlSignificantWhitespace(string? strData, XmlDocument doc) : base(strData, doc) { if (!doc.IsLoading && !base.CheckOnData(strData)) throw new ArgumentException(SR.Xdom_WS_Char); @@ -20,7 +21,7 @@ public override string Name { get { - return OwnerDocument.strSignificantWhitespaceName; + return OwnerDocument!.strSignificantWhitespaceName; } } @@ -29,7 +30,7 @@ public override string LocalName { get { - return OwnerDocument.strSignificantWhitespaceName; + return OwnerDocument!.strSignificantWhitespaceName; } } @@ -42,11 +43,11 @@ public override XmlNodeType NodeType } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { - switch (parentNode.NodeType) + switch (parentNode!.NodeType) { case XmlNodeType.Document: return base.ParentNode; @@ -54,10 +55,10 @@ public override XmlNode ParentNode case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - XmlNode parent = parentNode.parentNode; + XmlNode parent = parentNode.parentNode!; while (parent.IsText) { - parent = parent.parentNode; + parent = parent.parentNode!; } return parent; default: @@ -73,7 +74,7 @@ public override XmlNode CloneNode(bool deep) return OwnerDocument.CreateSignificantWhitespace(Data); } - public override string Value + public override string? Value { get { @@ -119,14 +120,15 @@ internal override bool IsText } } - public override XmlNode PreviousText + public override XmlNode? PreviousText { get { - if (parentNode.IsText) + if (parentNode != null && parentNode.IsText) { return parentNode; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlText.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlText.cs index 9a0bf27ca65b..db4533514d0a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlText.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlText.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.XPath; namespace System.Xml @@ -9,11 +11,11 @@ namespace System.Xml // Represents the text content of an element or attribute. public class XmlText : XmlCharacterData { - internal XmlText(string strData) : this(strData, null) + internal XmlText(string? strData) : this(strData, null!) // always throws ArgumentNullException { } - protected internal XmlText(string strData, XmlDocument doc) : base(strData, doc) + protected internal XmlText(string? strData, XmlDocument doc) : base(strData, doc) { } @@ -22,7 +24,7 @@ public override string Name { get { - return OwnerDocument.strTextName; + return OwnerDocument!.strTextName; } } @@ -31,7 +33,7 @@ public override string LocalName { get { - return OwnerDocument.strTextName; + return OwnerDocument!.strTextName; } } @@ -44,11 +46,11 @@ public override XmlNodeType NodeType } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { - switch (parentNode.NodeType) + switch (parentNode!.NodeType) { case XmlNodeType.Document: return null; @@ -56,11 +58,12 @@ public override XmlNode ParentNode case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - XmlNode parent = parentNode.parentNode; + XmlNode parent = parentNode.parentNode!; while (parent.IsText) { - parent = parent.parentNode; + parent = parent.parentNode!; } + return parent; default: return parentNode; @@ -75,7 +78,7 @@ public override XmlNode CloneNode(bool deep) return OwnerDocument.CreateTextNode(Data); } - public override string Value + public override string? Value { get { @@ -85,10 +88,10 @@ public override string Value set { Data = value; - XmlNode parent = parentNode; + XmlNode? parent = parentNode; if (parent != null && parent.NodeType == XmlNodeType.Attribute) { - XmlUnspecifiedAttribute attr = parent as XmlUnspecifiedAttribute; + XmlUnspecifiedAttribute? attr = parent as XmlUnspecifiedAttribute; if (attr != null && !attr.Specified) { attr.SetSpecified(true); @@ -101,7 +104,7 @@ public override string Value // both in the tree as siblings. public virtual XmlText SplitText(int offset) { - XmlNode parentNode = this.ParentNode; + XmlNode? parentNode = this.ParentNode; int length = this.Length; if (offset > length) throw new ArgumentOutOfRangeException(nameof(offset)); @@ -112,7 +115,7 @@ public virtual XmlText SplitText(int offset) int count = length - offset; string splitData = Substring(offset, count); DeleteData(offset, count); - XmlText newTextNode = OwnerDocument.CreateTextNode(splitData); + XmlText newTextNode = OwnerDocument!.CreateTextNode(splitData); parentNode.InsertAfter(newTextNode, this); return newTextNode; } @@ -145,14 +148,15 @@ internal override bool IsText } } - public override XmlNode PreviousText + public override XmlNode? PreviousText { get { - if (parentNode.IsText) + if (parentNode != null && parentNode.IsText) { return parentNode; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlUnspecifiedAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlUnspecifiedAttribute.cs index 07e8f9f9c162..205d1d8a4271 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlUnspecifiedAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlUnspecifiedAttribute.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. +#nullable enable namespace System.Xml { internal class XmlUnspecifiedAttribute : XmlAttribute @@ -8,7 +9,7 @@ internal class XmlUnspecifiedAttribute : XmlAttribute private bool _fSpecified; - protected internal XmlUnspecifiedAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc) + protected internal XmlUnspecifiedAttribute(string? prefix, string localName, string? namespaceURI, XmlDocument doc) : base(prefix, localName, namespaceURI, doc) { } @@ -38,16 +39,16 @@ public override string InnerText } } - public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) + public override XmlNode? InsertBefore(XmlNode newChild, XmlNode? refChild) { - XmlNode node = base.InsertBefore(newChild, refChild); + XmlNode? node = base.InsertBefore(newChild, refChild); _fSpecified = true; return node; } - public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) + public override XmlNode? InsertAfter(XmlNode newChild, XmlNode? refChild) { - XmlNode node = base.InsertAfter(newChild, refChild); + XmlNode? node = base.InsertAfter(newChild, refChild); _fSpecified = true; return node; } @@ -66,9 +67,9 @@ public override XmlNode RemoveChild(XmlNode oldChild) return node; } - public override XmlNode AppendChild(XmlNode newChild) + public override XmlNode? AppendChild(XmlNode newChild) { - XmlNode node = base.AppendChild(newChild); + XmlNode? node = base.AppendChild(newChild); _fSpecified = true; return node; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlWhitespace.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlWhitespace.cs index ecdcd9172e3c..7f9509cd3d56 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlWhitespace.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlWhitespace.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.XPath; namespace System.Xml @@ -9,7 +11,7 @@ namespace System.Xml // Represents the text content of an element or attribute. public class XmlWhitespace : XmlCharacterData { - protected internal XmlWhitespace(string strData, XmlDocument doc) : base(strData, doc) + protected internal XmlWhitespace(string? strData, XmlDocument doc) : base(strData, doc) { if (!doc.IsLoading && !base.CheckOnData(strData)) throw new ArgumentException(SR.Xdom_WS_Char); @@ -20,7 +22,7 @@ public override string Name { get { - return OwnerDocument.strNonSignificantWhitespaceName; + return OwnerDocument!.strNonSignificantWhitespaceName; } } @@ -29,7 +31,7 @@ public override string LocalName { get { - return OwnerDocument.strNonSignificantWhitespaceName; + return OwnerDocument!.strNonSignificantWhitespaceName; } } @@ -42,11 +44,11 @@ public override XmlNodeType NodeType } } - public override XmlNode ParentNode + public override XmlNode? ParentNode { get { - switch (parentNode.NodeType) + switch (parentNode!.NodeType) { case XmlNodeType.Document: return base.ParentNode; @@ -54,10 +56,10 @@ public override XmlNode ParentNode case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: - XmlNode parent = parentNode.parentNode; + XmlNode parent = parentNode.parentNode!; while (parent.IsText) { - parent = parent.parentNode; + parent = parent.parentNode!; } return parent; default: @@ -66,13 +68,12 @@ public override XmlNode ParentNode } } - public override string Value + public override string? Value { get { return Data; } - set { if (CheckOnData(value)) @@ -119,14 +120,15 @@ internal override bool IsText } } - public override XmlNode PreviousText + public override XmlNode? PreviousText { get { - if (parentNode.IsText) + if (parentNode != null && parentNode.IsText) { return parentNode; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Resolvers/XmlPreloadedResolver.cs b/src/libraries/System.Private.Xml/src/System/Xml/Resolvers/XmlPreloadedResolver.cs index d5cf08b98930..e09c29c3b236 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Resolvers/XmlPreloadedResolver.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Resolvers/XmlPreloadedResolver.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. +#nullable enable using System.IO; using System.Xml; using System.Net; @@ -34,15 +35,16 @@ internal virtual TextReader AsTextReader() } // Returns true for types that are supported for this preloaded data; Stream must always be supported - internal virtual bool SupportsType(Type type) + internal virtual bool SupportsType(Type? type) { if (type == null || type == typeof(Stream)) { return true; } + return false; } - }; + } // // XmlKnownDtdData class @@ -63,7 +65,7 @@ internal XmlKnownDtdData(string publicId, string systemId, string resourceName) internal override Stream AsStream() { Assembly asm = GetType().Assembly; - return asm.GetManifestResourceStream(_resourceName); + return asm.GetManifestResourceStream(_resourceName)!; } } @@ -110,12 +112,13 @@ internal override TextReader AsTextReader() return new StringReader(_str); } - internal override bool SupportsType(Type type) + internal override bool SupportsType(Type? type) { if (type == typeof(TextReader)) { return true; } + return base.SupportsType(type); } } @@ -123,7 +126,7 @@ internal override bool SupportsType(Type type) // // Fields // - private readonly XmlResolver _fallbackResolver; + private readonly XmlResolver? _fallbackResolver; private readonly Dictionary _mappings; private readonly XmlKnownDtds _preloadedDtds; @@ -156,17 +159,17 @@ public XmlPreloadedResolver(XmlKnownDtds preloadedDtds) { } - public XmlPreloadedResolver(XmlResolver fallbackResolver) + public XmlPreloadedResolver(XmlResolver? fallbackResolver) : this(fallbackResolver, XmlKnownDtds.All, null) { } - public XmlPreloadedResolver(XmlResolver fallbackResolver, XmlKnownDtds preloadedDtds) + public XmlPreloadedResolver(XmlResolver? fallbackResolver, XmlKnownDtds preloadedDtds) : this(fallbackResolver, preloadedDtds, null) { } - public XmlPreloadedResolver(XmlResolver fallbackResolver, XmlKnownDtds preloadedDtds, IEqualityComparer uriComparer) + public XmlPreloadedResolver(XmlResolver? fallbackResolver, XmlKnownDtds preloadedDtds, IEqualityComparer? uriComparer) { _fallbackResolver = fallbackResolver; _mappings = new Dictionary(16, uriComparer); @@ -186,7 +189,7 @@ public XmlPreloadedResolver(XmlResolver fallbackResolver, XmlKnownDtds preloaded } } - public override Uri ResolveUri(Uri baseUri, string relativeUri) + public override Uri ResolveUri(Uri? baseUri, string? relativeUri) { // 1) special-case well-known public IDs // 2) To make FxCop happy we need to use StartsWith() overload that takes StringComparison -> @@ -216,23 +219,25 @@ public override Uri ResolveUri(Uri baseUri, string relativeUri) } } } + return base.ResolveUri(baseUri, relativeUri); } - public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) + public override object? GetEntity(Uri absoluteUri, string? role, Type? ofObjectToReturn) { if (absoluteUri == null) { throw new ArgumentNullException(nameof(absoluteUri)); } - PreloadedData data; + PreloadedData? data; if (!_mappings.TryGetValue(absoluteUri, out data)) { if (_fallbackResolver != null) { return _fallbackResolver.GetEntity(absoluteUri, role, ofObjectToReturn); } + throw new XmlException(SR.Format(SR.Xml_CannotResolveUrl, absoluteUri)); } @@ -261,14 +266,14 @@ public override ICredentials Credentials } } - public override bool SupportsType(Uri absoluteUri, Type type) + public override bool SupportsType(Uri absoluteUri, Type? type) { if (absoluteUri == null) { throw new ArgumentNullException(nameof(absoluteUri)); } - PreloadedData data; + PreloadedData? data; if (!_mappings.TryGetValue(absoluteUri, out data)) { if (_fallbackResolver != null) @@ -291,6 +296,7 @@ public void Add(Uri uri, byte[] value) { throw new ArgumentNullException(nameof(value)); } + Add(uri, new ByteArrayChunk(value, 0, value.Length)); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs index b6b2a59e4826..17a51af17bbd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs @@ -16,7 +16,7 @@ namespace System.Xml.Schema internal class BaseValidator { private readonly XmlSchemaCollection? _schemaCollection; - private readonly IValidationEventHandling _eventHandling; + private readonly IValidationEventHandling? _eventHandling; private readonly XmlNameTable _nameTable; private SchemaNames? _schemaNames; private readonly PositionInfo _positionInfo; @@ -45,7 +45,7 @@ public BaseValidator(BaseValidator other) elementName = other.elementName; } - public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection? schemaCollection, IValidationEventHandling eventHandling) + public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection? schemaCollection, IValidationEventHandling? eventHandling) { Debug.Assert(schemaCollection == null || schemaCollection.NameTable == reader.NameTable); this.reader = reader; @@ -110,9 +110,9 @@ public Uri? BaseUri set { _baseUri = value; } } - public ValidationEventHandler EventHandler + public ValidationEventHandler? EventHandler { - get { return (ValidationEventHandler)_eventHandling.EventHandler; } + get { return (ValidationEventHandler?)_eventHandling!.EventHandler; } } public SchemaInfo? SchemaInfo diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdParser.cs index f83c30d759ea..ba8515296c36 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdParser.cs @@ -269,7 +269,7 @@ private void Initialize(IDtdParserAdapter readerAdapter) _freeFloatingDtd = false; } - private void InitializeFreeFloatingDtd(string baseUri, string docTypeName, string publicId, string systemId, string internalSubset, IDtdParserAdapter adapter) + private void InitializeFreeFloatingDtd(string baseUri, string docTypeName, string? publicId, string? systemId, string? internalSubset, IDtdParserAdapter adapter) { Initialize(adapter); @@ -340,7 +340,7 @@ IDtdInfo IDtdParser.ParseInternalDtd(IDtdParserAdapter adapter, bool saveInterna return _schemaInfo; } - IDtdInfo IDtdParser.ParseFreeFloatingDtd(string baseUri, string docTypeName, string publicId, string systemId, string internalSubset, IDtdParserAdapter adapter) + IDtdInfo IDtdParser.ParseFreeFloatingDtd(string baseUri, string docTypeName, string? publicId, string? systemId, string? internalSubset, IDtdParserAdapter adapter) { InitializeFreeFloatingDtd(baseUri, docTypeName, publicId, systemId, internalSubset, adapter); Parse(false); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdValidator.cs index f725bad36533..a385ee2cb132 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/DtdValidator.cs @@ -566,7 +566,7 @@ public static void CheckDefaultValue( SchemaAttDef attdef, SchemaInfo sinfo, IValidationEventHandling eventHandling, - string baseUriStr + string? baseUriStr ) { try diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Parser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Parser.cs index a70e1e3344ea..967afd56e2c4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Parser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Parser.cs @@ -247,13 +247,14 @@ public bool ParseReaderNode() XmlNode[] markup = new XmlNode[list.Count]; for (int i = 0; i < list.Count; i++) { - markup[i] = list[i]; + markup[i] = list[i]!; } _builder!.ProcessMarkup(markup); _namespaceManager!.PopScope(); _builder.EndChildren(); } + _markupDepth = int.MaxValue; } else @@ -405,7 +406,7 @@ private XmlAttribute CreateXmlNsAttribute(string prefix, string value) XmlAttribute attr; if (prefix.Length == 0) { - attr = _dummyDocument.CreateAttribute(string.Empty, _xmlns, XmlReservedNs.NsXmlNs); + attr = _dummyDocument.CreateAttribute(string.Empty, _xmlns!, XmlReservedNs.NsXmlNs); } else { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XdrValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XdrValidator.cs index b9f8875eebbc..a5df534b04bc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XdrValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XdrValidator.cs @@ -31,7 +31,7 @@ internal XdrValidator(BaseValidator validator) : base(validator) Init(); } - internal XdrValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling) : base(reader, schemaCollection, eventHandling) + internal XdrValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling? eventHandling) : base(reader, schemaCollection, eventHandling) { Init(); } @@ -42,7 +42,7 @@ internal XdrValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schema [MemberNotNull(nameof(_attPresence))] private void Init() { - _nsManager = reader.NamespaceManager; + _nsManager = reader.NamespaceManager!; if (_nsManager == null) { _nsManager = new XmlNamespaceManager(NameTable); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs index 0c6aeacd2b9c..707de039376f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs @@ -83,7 +83,7 @@ public event ValidationEventHandler ValidationEventHandler remove { _validationEventHandler -= value; } } - internal XmlResolver XmlResolver + internal XmlResolver? XmlResolver { set { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidationException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidationException.cs index fccacd3d1b1f..993aa858936c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidationException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidationException.cs @@ -69,7 +69,7 @@ public object? SourceObject get { return _sourceNodeObject; } } - protected internal void SetSourceObject(object sourceObject) + protected internal void SetSourceObject(object? sourceObject) { _sourceNodeObject = sourceObject; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs index 386f0a28f9d2..5b993c86b1e5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs @@ -17,7 +17,7 @@ namespace System.Xml.Schema { - public delegate object XmlValueGetter(); + public delegate object? XmlValueGetter(); [Flags] public enum XmlSchemaValidationFlags @@ -677,7 +677,7 @@ public void ValidateElement(string localName, string namespaceUri, XmlSchemaInfo object attValue; if (attributeValueGetter != null) { - attValue = attributeValueGetter(); + attValue = attributeValueGetter()!; } else { @@ -821,7 +821,7 @@ private void ValidateText(string? elementStringValue, XmlValueGetter? elementVal case XmlSchemaContentType.TextOnly: if (elementValueGetter != null) { - SaveTextValue(elementValueGetter()); + SaveTextValue(elementValueGetter()!); } else { @@ -830,7 +830,7 @@ private void ValidateText(string? elementStringValue, XmlValueGetter? elementVal break; case XmlSchemaContentType.ElementOnly: - string textValue = elementValueGetter != null ? elementValueGetter().ToString()! : elementStringValue!; + string textValue = elementValueGetter != null ? elementValueGetter()!.ToString()! : elementStringValue!; if (_xmlCharType.IsOnlyWhitespace(textValue)) { break; @@ -852,7 +852,7 @@ private void ValidateText(string? elementStringValue, XmlValueGetter? elementVal { if (elementValueGetter != null) { - SaveTextValue(elementValueGetter()); + SaveTextValue(elementValueGetter()!); } else { @@ -905,7 +905,7 @@ private void ValidateWhitespace(string? elementStringValue, XmlValueGetter? elem case XmlSchemaContentType.TextOnly: if (elementValueGetter != null) { - SaveTextValue(elementValueGetter()); + SaveTextValue(elementValueGetter()!); } else { @@ -918,7 +918,7 @@ private void ValidateWhitespace(string? elementStringValue, XmlValueGetter? elem { if (elementValueGetter != null) { - SaveTextValue(elementValueGetter()); + SaveTextValue(elementValueGetter()!); } else { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs index 241a501668c9..2191857f29a2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs @@ -68,12 +68,13 @@ internal XsdValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schema [MemberNotNull(nameof(_xsdSchema))] private void Init() { - _nsManager = reader.NamespaceManager; + _nsManager = reader.NamespaceManager!; if (_nsManager == null) { _nsManager = new XmlNamespaceManager(NameTable); _bManageNamespaces = true; } + _validationStack = new HWStack(STACK_INCREMENT); textValue = new StringBuilder(); _attPresence = new Hashtable(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs index 9498b6ae9d25..82cfb9dce680 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlCharType.cs @@ -203,13 +203,13 @@ internal static void SplitSurrogateChar(int combinedChar, out char lowChar, out highChar = (char)(SurHighStart + v / 1024); } - internal bool IsOnlyWhitespace(string str) + internal bool IsOnlyWhitespace(string? str) { return IsOnlyWhitespaceWithPos(str) == -1; } // Character checking on strings - internal int IsOnlyWhitespaceWithPos(string str) + internal int IsOnlyWhitespaceWithPos(string? str) { if (str != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs index f777c49e5c62..83268d4a8a8e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs @@ -1474,12 +1474,12 @@ private static unsafe long DoubleToInt64Bits(double value) return *((long*)&value); } - internal static void VerifyCharData(string data, ExceptionType exceptionType) + internal static void VerifyCharData(string? data, ExceptionType exceptionType) { VerifyCharData(data, exceptionType, exceptionType); } - internal static void VerifyCharData(string data, ExceptionType invCharExceptionType, ExceptionType invSurrogateExceptionType) + internal static void VerifyCharData(string? data, ExceptionType invCharExceptionType, ExceptionType invSurrogateExceptionType) { if (data == null || data.Length == 0) { From 90989b46a1f3791dd57d6ae87578fe22d699c106 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 24 Jul 2020 17:12:19 -0700 Subject: [PATCH 045/755] Fix issue in type equivalence involving arrays (#39914) - Fix issue where single dimensional arrays and multidimensional arrays of rank 1 are considered equivalent --- src/coreclr/src/vm/methodtable.cpp | 8 +++ .../typeequivalence/simple/Simple.cs | 69 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index dee047519ee9..6c687345da16 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -1375,6 +1375,14 @@ BOOL MethodTable::IsEquivalentTo_Worker(MethodTable *pOtherMT COMMA_INDEBUG(Type if (!pOtherMT->IsArray() || GetRank() != pOtherMT->GetRank()) return FALSE; + if (IsMultiDimArray() != pOtherMT->IsMultiDimArray()) + { + // A non-multidimensional array is not equivalent to an SzArray. + // This case is handling the case of a Rank 1 multidimensional array + // when compared to a normal array. + return FALSE; + } + // arrays of structures have their own unshared MTs and will take this path return (GetArrayElementTypeHandle().IsEquivalentTo(pOtherMT->GetArrayElementTypeHandle() COMMA_INDEBUG(&newVisited))); } diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.cs b/src/tests/baseservices/typeequivalence/simple/Simple.cs index 4454281731a4..9b0a63ecf2d1 100644 --- a/src/tests/baseservices/typeequivalence/simple/Simple.cs +++ b/src/tests/baseservices/typeequivalence/simple/Simple.cs @@ -149,6 +149,71 @@ private static void CallSparseInterface() Assert.AreEqual(input * 18, sparseType.MultiplyBy18(input)); } + private static void TestArrayEquivalence() + { + Console.WriteLine($"{nameof(TestArrayEquivalence)}"); + var inAsm = EmptyType.Create(); + var otherAsm = EmptyType2.Create(); + + Type inAsmInterfaceType = inAsm.GetType().GetInterface(nameof(IEmptyType)); + Type otherAsmInterfaceType = otherAsm.GetType().GetInterface(nameof(IEmptyType)); + + Assert.IsTrue(inAsmInterfaceType.MakeArrayType().IsEquivalentTo(otherAsmInterfaceType.MakeArrayType())); + Assert.IsTrue(inAsmInterfaceType.MakeArrayType(1).IsEquivalentTo(otherAsmInterfaceType.MakeArrayType(1))); + Assert.IsTrue(inAsmInterfaceType.MakeArrayType(2).IsEquivalentTo(otherAsmInterfaceType.MakeArrayType(2))); + + Assert.IsFalse(inAsmInterfaceType.MakeArrayType().IsEquivalentTo(otherAsmInterfaceType.MakeArrayType(1))); + Assert.IsFalse(inAsmInterfaceType.MakeArrayType(1).IsEquivalentTo(otherAsmInterfaceType.MakeArrayType(2))); + } + + private static void TestByRefEquivalence() + { + Console.WriteLine($"{nameof(TestByRefEquivalence)}"); + var inAsm = EmptyType.Create(); + var otherAsm = EmptyType2.Create(); + + Type inAsmInterfaceType = inAsm.GetType().GetInterface(nameof(IEmptyType)); + Type otherAsmInterfaceType = otherAsm.GetType().GetInterface(nameof(IEmptyType)); + + Assert.IsTrue(inAsmInterfaceType.MakeByRefType().IsEquivalentTo(otherAsmInterfaceType.MakeByRefType())); + } + + interface IGeneric + { + void Method(T input); + } + + class Generic : IGeneric + { + public void Method(V input) + { + } + } + + private static void TestGenericClassNonEquivalence() + { + Console.WriteLine($"{nameof(TestGenericClassNonEquivalence)}"); + var inAsm = EmptyType.Create(); + var otherAsm = EmptyType2.Create(); + + Type inAsmInterfaceType = inAsm.GetType().GetInterface(nameof(IEmptyType)); + Type otherAsmInterfaceType = otherAsm.GetType().GetInterface(nameof(IEmptyType)); + + Assert.IsFalse(typeof(Generic<>).MakeGenericType(inAsmInterfaceType).IsEquivalentTo(typeof(Generic<>).MakeGenericType(otherAsmInterfaceType))); + } + + private static void TestGenericInterfaceEquivalence() + { + Console.WriteLine($"{nameof(TestGenericInterfaceEquivalence)}"); + var inAsm = EmptyType.Create(); + var otherAsm = EmptyType2.Create(); + + Type inAsmInterfaceType = inAsm.GetType().GetInterface(nameof(IEmptyType)); + Type otherAsmInterfaceType = otherAsm.GetType().GetInterface(nameof(IEmptyType)); + + Assert.IsTrue(typeof(IGeneric<>).MakeGenericType(inAsmInterfaceType).IsEquivalentTo(typeof(IGeneric<>).MakeGenericType(otherAsmInterfaceType))); + } + public static int Main(string[] noArgs) { try @@ -157,6 +222,10 @@ public static int Main(string[] noArgs) ValidateTypeInstanceEquality(); InterfaceTypesMethodOperations(); CallSparseInterface(); + TestByRefEquivalence(); + TestArrayEquivalence(); + TestGenericClassNonEquivalence(); + TestGenericInterfaceEquivalence(); } catch (Exception e) { From f3f23b4bde8b0a449d57ef600d99560ac97a784e Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 24 Jul 2020 18:26:56 -0700 Subject: [PATCH 046/755] Avoid using DateTime - Switch to DateTimeOffset (#39916) --- .../src/JsonConsoleFormatter.cs | 4 ++-- .../src/SimpleConsoleFormatter.cs | 8 ++++---- .../src/SystemdConsoleFormatter.cs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs index 68aa95a92504..418350e892eb 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs @@ -45,8 +45,8 @@ public override void Write(in LogEntry logEntry, IExternalScopeP var timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - var dateTime = FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; - timestamp = dateTime.ToString(timestampFormat); + DateTimeOffset dateTimeOffset = FormatterOptions.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; + timestamp = dateTimeOffset.ToString(timestampFormat); } writer.WriteString("Timestamp", timestamp); writer.WriteNumber(nameof(logEntry.EventId), eventId); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs index f9452ed204fd..f5b0571bc537 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs @@ -53,8 +53,8 @@ public override void Write(in LogEntry logEntry, IExternalScopeP string timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - DateTime dateTime = GetCurrentDateTime(); - timestamp = dateTime.ToString(timestampFormat); + DateTimeOffset dateTimeOffset = GetCurrentDateTime(); + timestamp = dateTimeOffset.ToString(timestampFormat); } if (timestamp != null) { @@ -126,9 +126,9 @@ static void WriteReplacing(TextWriter writer, string oldValue, string newValue, } } - private DateTime GetCurrentDateTime() + private DateTimeOffset GetCurrentDateTime() { - return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return FormatterOptions.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; } private static string GetLogLevelString(LogLevel logLevel) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs index 0140adf51356..1916dd2fa049 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs @@ -57,8 +57,8 @@ public override void Write(in LogEntry logEntry, IExternalScopeP string timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - DateTime dateTime = GetCurrentDateTime(); - textWriter.Write(dateTime.ToString(timestampFormat)); + DateTimeOffset dateTimeOffset = GetCurrentDateTime(); + textWriter.Write(dateTimeOffset.ToString(timestampFormat)); } // category and event id @@ -96,9 +96,9 @@ static void WriteReplacingNewLine(TextWriter writer, string message) } } - private DateTime GetCurrentDateTime() + private DateTimeOffset GetCurrentDateTime() { - return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return FormatterOptions.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; } private static string GetSyslogSeverityString(LogLevel logLevel) From 13fa14e35ac0b94d4935477950122dea0bf419a8 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 24 Jul 2020 20:31:58 -0700 Subject: [PATCH 047/755] Fix CanCastTo behavior (#39915) * Fix missing cases in CanCastTo * Update issues.targets to start running the previously broken tests --- .../tools/Common/TypeSystem/Common/CastingHelper.cs | 11 +++++++++++ src/coreclr/tests/issues.targets | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs index d10a2dc0fec2..e10782ef0ad9 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs @@ -166,6 +166,17 @@ private static bool CanCastToInternal(this TypeDesc thisType, TypeDesc otherType case TypeFlags.SzArray: return ((ArrayType)thisType).CanCastArrayTo(otherType, protect); + case TypeFlags.ByRef: + case TypeFlags.Pointer: + if (otherType.Category == thisType.Category) + { + return ((ParameterizedType)thisType).CanCastParamTo(((ParameterizedType)otherType).ParameterType, protect); + } + return false; + + case TypeFlags.FunctionPointer: + return false; + default: Debug.Assert(thisType.IsDefType); return thisType.CanCastToClassOrInterface(otherType, protect); diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index c6c0b0120466..e33de4df6132 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -923,12 +923,6 @@ https://github.com/dotnet/runtime/issues/38260 - - https://github.com/dotnet/runtime/issues/32725 - - - https://github.com/dotnet/runtime/issues/32725 - https://github.com/dotnet/runtime/issues/7597 @@ -953,9 +947,6 @@ https://github.com/dotnet/runtime/issues/35724 - - https://github.com/dotnet/runtime/issues/32725 - Not compatible with crossgen2 From b179d69b24b45732537e5170f360851ce4dc1ab3 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Fri, 24 Jul 2020 20:55:49 -0700 Subject: [PATCH 048/755] Fix `fgUpdateChangedFlowGraph`. (#39878) `fgComputeDoms` has an assumption that the flow graph has no unreachable blocks. It's checked with this assert: https://github.com/dotnet/runtime/blob/ad325b014124b1adb9306abf95fdac85e3f7f2f4/src/coreclr/src/jit/flowgraph.cpp#L2342 This assert fired when testing #39474 (`Convert Math{F}.CoreCLR methods from FCall to QCall`) when we are updating the flow graph after inserting GC polls. This change switches `fgUpdateChangedFlowGraph` to call `fgComputeReachability`, which both removes unreachable blocks and calls `fgComputeDoms`. pin-icount reported a 0.0043% throughput improvement, which is within noise level. --- src/coreclr/src/jit/flowgraph.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index f8500bf52d75..f09c0e71fe06 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -1875,8 +1875,7 @@ void Compiler::fgUpdateChangedFlowGraph() fgComputePreds(); fgComputeEnterBlocksSet(); - fgComputeReachabilitySets(); - fgComputeDoms(); + fgComputeReachability(); } /***************************************************************************** From 6ca600396ee2e80e8bf93c72c2b5439aadc86073 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 24 Jul 2020 21:01:54 -0700 Subject: [PATCH 049/755] MacOS managed debugging perf fix (#39804) * MacOS managed debugging perf fix This PR adds PAL_OpenProcessMemory, PAL_ReadProcessMemory and PAL_CloseProcessMemory that encapsulate the remote read memory functions for both MacOS and Linux. The DBI code that reads memory using the runtime IPC messages to use these new functions and fallback to the IPC message if the open fails. On MacOS, this won't have any affect on VSCode performance until vsdbg/vsdbgui are signed with the "com.apple.security.cs.debugger" entitlement. Sample entitlements.plist file: ``` com.apple.security.cs.debugger ``` Example of locally signing with entitlement command: codesign -s --entitlements entitlements.plist Fix FreeBSD build. Remove FEATURE_DATATARGET4 for macOS so managed debugging uses faster OOP unwind for HelpMethodFrames --- src/coreclr/clrdefinitions.cmake | 5 +- src/coreclr/src/debug/createdump/main.cpp | 23 +-- .../src/debug/di/shimremotedatatarget.cpp | 18 +- .../dlls/mscordac/mscordac_unixexports.src | 3 + src/coreclr/src/pal/inc/pal.h | 26 +++ src/coreclr/src/pal/src/debug/debug.cpp | 184 ++++++++++++++++++ src/coreclr/src/pal/src/map/map.cpp | 2 +- 7 files changed, 227 insertions(+), 34 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 7be0a6915051..b717c10d840a 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -30,7 +30,6 @@ if (CLR_CMAKE_TARGET_UNIX) if(CLR_CMAKE_TARGET_OSX) add_definitions(-D_XOPEN_SOURCE) - add_definitions(-DFEATURE_DATATARGET4) endif(CLR_CMAKE_TARGET_OSX) if (CLR_CMAKE_TARGET_ARCH_AMD64) @@ -173,9 +172,9 @@ set(FEATURE_READYTORUN 1) add_compile_definitions($<$>>:FEATURE_REJIT>) -if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX AND NOT CLR_CMAKE_TARGET_OSX) +if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX) add_definitions(-DFEATURE_REMOTE_PROC_MEM) -endif (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX AND NOT CLR_CMAKE_TARGET_OSX) +endif (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX) if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DFEATURE_STUBS_AS_IL) diff --git a/src/coreclr/src/debug/createdump/main.cpp b/src/coreclr/src/debug/createdump/main.cpp index 626175c2903c..66b197611910 100644 --- a/src/coreclr/src/debug/createdump/main.cpp +++ b/src/coreclr/src/debug/createdump/main.cpp @@ -35,6 +35,7 @@ int __cdecl main(const int argc, const char* argv[]) MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | MiniDumpWithTokenInformation); + const char* dumpType = "minidump with heap"; const char* dumpPathTemplate = nullptr; int exitCode = 0; int pid = 0; @@ -60,11 +61,13 @@ int __cdecl main(const int argc, const char* argv[]) } else if ((strcmp(*argv, "-n") == 0) || (strcmp(*argv, "--normal") == 0)) { + dumpType = "minidump"; minidumpType = (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithThreadInfo); } else if ((strcmp(*argv, "-h") == 0) || (strcmp(*argv, "--withheap") == 0)) { + dumpType = "minidump with heap"; minidumpType = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory | MiniDumpWithDataSegs | MiniDumpWithHandleData | @@ -75,11 +78,13 @@ int __cdecl main(const int argc, const char* argv[]) } else if ((strcmp(*argv, "-t") == 0) || (strcmp(*argv, "--triage") == 0)) { + dumpType = "triage minidump"; minidumpType = (MINIDUMP_TYPE)(MiniDumpFilterTriage | MiniDumpWithThreadInfo); } else if ((strcmp(*argv, "-u") == 0) || (strcmp(*argv, "--full") == 0)) { + dumpType = "full dump"; minidumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithDataSegs | MiniDumpWithHandleData | @@ -122,24 +127,6 @@ int __cdecl main(const int argc, const char* argv[]) snprintf(dumpPath, MAX_LONGPATH, dumpPathTemplate, pid); - const char* dumpType = "minidump"; - switch (minidumpType) - { - case MiniDumpWithPrivateReadWriteMemory: - dumpType = "minidump with heap"; - break; - - case MiniDumpFilterTriage: - dumpType = "triage minidump"; - break; - - case MiniDumpWithFullMemory: - dumpType = "full dump"; - break; - - default: - break; - } printf("Writing %s to file %s\n", dumpType, (char*)dumpPath); if (CreateDump(dumpPath, pid, minidumpType)) diff --git a/src/coreclr/src/debug/di/shimremotedatatarget.cpp b/src/coreclr/src/debug/di/shimremotedatatarget.cpp index 38bf162e430f..9a01508e2115 100644 --- a/src/coreclr/src/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/src/debug/di/shimremotedatatarget.cpp @@ -68,7 +68,7 @@ class ShimRemoteDataTarget : public ShimDataTarget DbgTransportTarget * m_pProxy; DbgTransportSession * m_pTransport; #ifdef FEATURE_REMOTE_PROC_MEM - int m_fd; // /proc//mem handle + DWORD m_memoryHandle; // PAL_ReadProcessMemory handle or UINT32_MAX if fallback #endif }; @@ -106,9 +106,7 @@ ShimRemoteDataTarget::ShimRemoteDataTarget(DWORD processId, m_pContinueStatusChangedUserData = NULL; #ifdef FEATURE_REMOTE_PROC_MEM - char memPath[128]; - _snprintf_s(memPath, sizeof(memPath), sizeof(memPath), "/proc/%lu/mem", m_processId); - m_fd = _open(memPath, 0); // O_RDONLY + PAL_OpenProcessMemory(m_processId, &m_memoryHandle); #endif } @@ -135,11 +133,8 @@ ShimRemoteDataTarget::~ShimRemoteDataTarget() void ShimRemoteDataTarget::Dispose() { #ifdef FEATURE_REMOTE_PROC_MEM - if (m_fd != -1) - { - _close(m_fd); - m_fd = -1; - } + PAL_CloseProcessMemory(m_memoryHandle); + m_memoryHandle = UINT32_MAX; #endif if (m_pTransport != NULL) { @@ -269,10 +264,9 @@ ShimRemoteDataTarget::ReadVirtual( HRESULT hr = S_OK; #ifdef FEATURE_REMOTE_PROC_MEM - if (m_fd != -1) + if (m_memoryHandle != UINT32_MAX) { - read = _pread(m_fd, pBuffer, cbRequestSize, (ULONG64)address); - if (read == (size_t)-1) + if (!PAL_ReadProcessMemory(m_memoryHandle, (ULONG64)address, pBuffer, cbRequestSize, &read)) { hr = E_FAIL; } diff --git a/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src b/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src index 29c010b9e849..31dd9ea4875e 100644 --- a/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src +++ b/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src @@ -43,6 +43,9 @@ nativeStringResourceTable_mscorrc #PAL_InitializeDLL #PAL_TerminateEx #PAL_IsDebuggerPresent +#PAL_OpenProcessMemory +#PAL_CloseProcessMemory +#PAL_ReadProcessMemory #PAL_ProbeMemory #PAL_Random #PAL_memcpy diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index df658c546905..fd56fc90c353 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -511,6 +511,32 @@ PAL_Random( IN OUT LPVOID lpBuffer, IN DWORD dwLength); +PALIMPORT +BOOL +PALAPI +PAL_OpenProcessMemory( + IN DWORD processId, + OUT DWORD* pHandle +); + +PALIMPORT +VOID +PALAPI +PAL_CloseProcessMemory( + IN DWORD handle +); + +PALIMPORT +BOOL +PALAPI +PAL_ReadProcessMemory( + IN DWORD handle, + IN ULONG64 address, + IN LPVOID buffer, + IN SIZE_T size, + OUT SIZE_T* numberOfBytesRead +); + PALIMPORT BOOL PALAPI diff --git a/src/coreclr/src/pal/src/debug/debug.cpp b/src/coreclr/src/pal/src/debug/debug.cpp index b58b2fe587e1..7e7e36820058 100644 --- a/src/coreclr/src/pal/src/debug/debug.cpp +++ b/src/coreclr/src/pal/src/debug/debug.cpp @@ -62,6 +62,11 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do #include #endif // HAVE_PROCFS_H +#ifdef __APPLE__ +#include +#include +#endif // __APPLE__ + #if HAVE_MACH_EXCEPTIONS #include "../exception/machexception.h" #endif // HAVE_MACH_EXCEPTIONS @@ -69,6 +74,7 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do using namespace CorUnix; extern "C" void DBG_DebugBreak_End(); +extern size_t OffsetWithinPage(off_t addr); #if HAVE_PROCFS_CTL #define CTL_ATTACH "attach" @@ -541,6 +547,184 @@ SetThreadContext( return ret; } +/*++ +Function: + PAL_OpenProcessMemory + +Abstract + Creates the handle for PAL_ReadProcessMemory. + +Parameter + processId : process id to read memory + pHandle : returns a platform specific handle or UINT32_MAX if failed + +Return + true successful, false invalid process id or not supported. +--*/ +BOOL +PALAPI +PAL_OpenProcessMemory( + IN DWORD processId, + OUT DWORD* pHandle +) +{ + ENTRY("PAL_OpenProcessMemory(pid=%d)\n", processId); + _ASSERTE(pHandle != nullptr); + *pHandle = UINT32_MAX; +#ifdef __APPLE__ + mach_port_name_t port; + kern_return_t result = ::task_for_pid(mach_task_self(), (int)processId, &port); + if (result != KERN_SUCCESS) + { + ERROR("task_for_pid(%d) FAILED %x %s\n", processId, result, mach_error_string(result)); + LOGEXIT("PAL_OpenProcessMemory FALSE\n"); + return FALSE; + } + *pHandle = port; +#else + char memPath[128]; + _snprintf_s(memPath, sizeof(memPath), sizeof(memPath), "/proc/%lu/mem", processId); + + int fd = open(memPath, O_RDONLY); + if (fd == -1) + { + ERROR("open(%s) FAILED %d (%s)\n", memPath, errno, strerror(errno)); + LOGEXIT("PAL_OpenProcessMemory FALSE\n"); + return FALSE; + } + *pHandle = fd; +#endif + LOGEXIT("PAL_OpenProcessMemory TRUE\n"); + return TRUE; +} + +/*++ +Function: + PAL_CloseProcessMemory + +Abstract + Closes the PAL_OpenProcessMemory handle. + +Parameter + handle : from PAL_OpenProcessMemory + +Return + none +--*/ +VOID +PALAPI +PAL_CloseProcessMemory( + IN DWORD handle +) +{ + ENTRY("PAL_CloseProcessMemory(handle=%x)\n", handle); + if (handle != UINT32_MAX) + { +#ifdef __APPLE__ + kern_return_t result = ::mach_port_deallocate(mach_task_self(), (mach_port_name_t)handle); + if (result != KERN_SUCCESS) + { + ERROR("mach_port_deallocate FAILED %x %s\n", result, mach_error_string(result)); + } +#else + close(handle); +#endif + } + LOGEXIT("PAL_CloseProcessMemory\n"); +} + +/*++ +Function: + PAL_ReadProcessMemory + +Abstract + Reads process memory. + +Parameter + handle : from PAL_OpenProcessMemory + address : address of memory to read + buffer : buffer to read memory to + size : number of bytes to read + numberOfBytesRead: number of bytes read (optional) + +Return + true read memory is successful, false if not. +--*/ +BOOL +PALAPI +PAL_ReadProcessMemory( + IN DWORD handle, + IN ULONG64 address, + IN LPVOID buffer, + IN SIZE_T size, + OUT SIZE_T* numberOfBytesRead) +{ + ENTRY("PAL_ReadProcessMemory(handle=%x, address=%p buffer=%p size=%d)\n", handle, (void*)address, buffer, size); + _ASSERTE(handle != 0); + _ASSERTE(numberOfBytesRead != nullptr); + BOOL result = TRUE; + size_t read = 0; +#ifdef __APPLE__ + vm_map_t task = (vm_map_t)handle; + + // vm_read_overwrite usually requires that the address be page-aligned + // and the size be a multiple of the page size. We can't differentiate + // between the cases in which that's required and those in which it + // isn't, so we do it all the time. + const size_t pageSize = GetVirtualPageSize(); + vm_address_t addressAligned = ALIGN_DOWN(address, pageSize); + size_t offset = OffsetWithinPage(address); + size_t bytesToRead; + + char *data = (char*)malloc(pageSize); + if (data == nullptr) + { + ERROR("malloc(%d) FAILED\n", pageSize); + result = FALSE; + goto exit; + } + + while (size > 0) + { + vm_size_t bytesRead; + + bytesToRead = pageSize - offset; + if (bytesToRead > size) + { + bytesToRead = size; + } + bytesRead = pageSize; + kern_return_t result = ::vm_read_overwrite(task, addressAligned, pageSize, (vm_address_t)data, &bytesRead); + if (result != KERN_SUCCESS || bytesRead != pageSize) + { + ERROR("vm_read_overwrite failed for %d bytes from %p: %x %s\n", pageSize, (void*)addressAligned, result, mach_error_string(result)); + result = FALSE; + goto exit; + } + memcpy((LPSTR)buffer + read , data + offset, bytesToRead); + addressAligned = addressAligned + pageSize; + read += bytesToRead; + size -= bytesToRead; + offset = 0; + } + +exit: + if (data != nullptr) + { + free(data); + } +#else + read = pread(handle, buffer, size, address); + if (read == (size_t)-1) + { + result = FALSE; + } +#endif + *numberOfBytesRead = read; + LOGEXIT("PAL_ReadProcessMemory result=%d bytes read=%d\n", result, read); + return result; +} + /*++ Function: PAL_ProbeMemory diff --git a/src/coreclr/src/pal/src/map/map.cpp b/src/coreclr/src/pal/src/map/map.cpp index 75405c7407c8..0cbaef5521d0 100644 --- a/src/coreclr/src/pal/src/map/map.cpp +++ b/src/coreclr/src/pal/src/map/map.cpp @@ -2137,7 +2137,7 @@ MAPRecordMapping( return palError; } -static size_t OffsetWithinPage(off_t addr) +size_t OffsetWithinPage(off_t addr) { return addr & (GetVirtualPageSize() - 1); } From 5ff4db1a5d22efb02300457d9a7a3154a7a5b0cb Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Sat, 25 Jul 2020 11:11:14 -0700 Subject: [PATCH 050/755] Add linker annotation to LazyDebugView to avoid warnings (#39899) In reality this is only to get rid of the warnings, the class is never instatiated by the managed code, so the annotation has no effect on including more code. When in debugger the class is instatiated with the same T of an existing Lazy which has the same annotation, so the T will always fulfill the annotation's requirements. --- src/libraries/System.Private.CoreLib/src/System/Lazy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Lazy.cs b/src/libraries/System.Private.CoreLib/src/System/Lazy.cs index 918682fa86ce..4fcfbc9070bf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Lazy.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Lazy.cs @@ -508,7 +508,7 @@ internal T ValueForDebugDisplay /// A debugger view of the Lazy<T> to surface additional debugging properties and /// to ensure that the Lazy<T> does not become initialized if it was not already. - internal sealed class LazyDebugView + internal sealed class LazyDebugView<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> { // The Lazy object being viewed. private readonly Lazy _lazy; From b9bb619edf57aebf3a5204b75ddaff80a00bb3f9 Mon Sep 17 00:00:00 2001 From: Hugh Bellamy Date: Sat, 25 Jul 2020 19:28:58 +0100 Subject: [PATCH 051/755] Remove CoreMangLib duplicate tests (#36612) * Cleanup duplicated Type tests * Baseline mono test failures --- .../tests/System/Type/TypePropertyTests.cs | 359 +++++++++++----- .../tests/System/Type/TypeTests.cs | 184 +++++++-- .../system/type/TypeGetArrayRank.csproj | 14 - .../system/type/TypeGetElementType.csproj | 14 - .../type/TypeGetGenericTypeDefinition.csproj | 14 - .../system/type/TypeHasElementTypeImpl.csproj | 14 - .../system/type/TypeIsByRefImpl.csproj | 14 - .../system/type/TypeIsPointerImpl.csproj | 14 - .../system/type/TypeMakeArrayType1.csproj | 14 - .../system/type/TypeMakeArrayType2.csproj | 14 - .../system/type/TypeMakeByRefType.csproj | 14 - .../system/type/TypeMakePointerType.csproj | 14 - .../system/type/typegetarrayrank.cs | 198 --------- .../system/type/typegetelementtype.cs | Bin 5722 -> 0 bytes .../type/typegetgenerictypedefinition.cs | 126 ------ .../system/type/typehaselementtypeimpl.cs | 120 ------ .../system/type/typeisbyrefimpl.cs | 100 ----- .../system/type/typeispointerimpl.cs | 194 --------- .../system/type/typemakearraytype1.cs | 237 ----------- .../system/type/typemakearraytype2.cs | 384 ------------------ .../system/type/typemakebyreftype.cs | 215 ---------- .../system/type/typemakepointertype.cs | 182 --------- 22 files changed, 406 insertions(+), 2033 deletions(-) delete mode 100644 src/tests/CoreMangLib/system/type/TypeGetArrayRank.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeGetElementType.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeGetGenericTypeDefinition.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeHasElementTypeImpl.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeIsByRefImpl.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeIsPointerImpl.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeMakeArrayType1.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeMakeArrayType2.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeMakeByRefType.csproj delete mode 100644 src/tests/CoreMangLib/system/type/TypeMakePointerType.csproj delete mode 100644 src/tests/CoreMangLib/system/type/typegetarrayrank.cs delete mode 100644 src/tests/CoreMangLib/system/type/typegetelementtype.cs delete mode 100644 src/tests/CoreMangLib/system/type/typegetgenerictypedefinition.cs delete mode 100644 src/tests/CoreMangLib/system/type/typehaselementtypeimpl.cs delete mode 100644 src/tests/CoreMangLib/system/type/typeisbyrefimpl.cs delete mode 100644 src/tests/CoreMangLib/system/type/typeispointerimpl.cs delete mode 100644 src/tests/CoreMangLib/system/type/typemakearraytype1.cs delete mode 100644 src/tests/CoreMangLib/system/type/typemakearraytype2.cs delete mode 100644 src/tests/CoreMangLib/system/type/typemakebyreftype.cs delete mode 100644 src/tests/CoreMangLib/system/type/typemakepointertype.cs diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs index 2904696e0b8a..75935d27bb0d 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs @@ -10,6 +10,8 @@ public abstract class TypePropertyTestBase { public abstract Type CreateType(); + public virtual int? ArrayRank => null; + public abstract TypeAttributes Attributes { get; } public virtual Type BaseType => typeof(object); @@ -28,6 +30,8 @@ public abstract class TypePropertyTestBase public virtual Type[] GenericTypeArguments => new Type[0]; + public virtual Type GenericTypeDefinition => null; + public virtual bool HasElementType => false; public virtual bool IsArray => false; @@ -90,7 +94,7 @@ public void Attributes_Get_ReturnsExpected() Assert.Equal((Attributes & TypeAttributes.Import) != 0, t.IsImport); Assert.Equal((Attributes & TypeAttributes.Sealed) != 0, t.IsSealed); Assert.Equal((Attributes & TypeAttributes.SpecialName) != 0, t.IsSpecialName); - Assert.Equal((Attributes & TypeAttributes.Serializable) != 0 || t.IsEnum, t.IsSerializable); + Assert.Equal((Attributes & TypeAttributes.Serializable) != 0 || t.IsEnum || t == typeof(Delegate), t.IsSerializable); Assert.Equal((Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !t.IsValueType, t.IsClass); Assert.Equal((Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface, t.IsInterface); @@ -149,6 +153,19 @@ public void GenericTypeArguments_Get_ReturnsExpected() Assert.Equal(GenericTypeArguments, CreateType().GenericTypeArguments); } + [Fact] + public void GetGenericTypeDefinition_Invoke_ReturnsExpected() + { + if (GenericTypeDefinition != null) + { + Assert.Equal(GenericTypeDefinition, CreateType().GetGenericTypeDefinition()); + } + else + { + Assert.Throws(() => CreateType().GetGenericTypeDefinition()); + } + } + [Fact] public void GenericParameterAttributes_Get_ReturnsExpected() { @@ -175,6 +192,19 @@ public void GenericParameterPosition_Get_ReturnsExpected() } } + [Fact] + public void GetArrayRank_Invoke_ReturnsExpected() + { + if (ArrayRank != null) + { + Assert.Equal(ArrayRank, CreateType().GetArrayRank()); + } + else + { + AssertExtensions.Throws(null, () => CreateType().GetArrayRank()); + } + } + [Fact] public void GetElementType_Invoke_ReturnsExpected() { @@ -393,17 +423,14 @@ public abstract class EnumTypeTestBase : StructTypeTestBase public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; public override Type BaseType => typeof(Enum); - } - public class ByteTests : PrimitiveTypeTestBase + // Primitives + public class StringTypeTests : ClassTypeTestBase { - public override Type CreateType() => typeof(byte); - } + public override Type CreateType() => typeof(string); - public class ByteEnumTests : EnumTypeTestBase - { - public override Type CreateType() => typeof(ByteEnum); + public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; } public class SByteTests : PrimitiveTypeTestBase @@ -411,19 +438,9 @@ public class SByteTests : PrimitiveTypeTestBase public override Type CreateType() => typeof(sbyte); } - public class SByteEnumTests : EnumTypeTestBase - { - public override Type CreateType() => typeof(SByteEnum); - } - - public class UShortTests : PrimitiveTypeTestBase - { - public override Type CreateType() => typeof(ushort); - } - - public class UShortEnumTests : EnumTypeTestBase + public class ByteTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(UShortEnum); + public override Type CreateType() => typeof(byte); } public class ShortTests : PrimitiveTypeTestBase @@ -431,19 +448,9 @@ public class ShortTests : PrimitiveTypeTestBase public override Type CreateType() => typeof(short); } - public class ShortEnumTests : EnumTypeTestBase - { - public override Type CreateType() => typeof(ShortEnum); - } - - public class UIntTests : PrimitiveTypeTestBase - { - public override Type CreateType() => typeof(uint); - } - - public class UIntEnumTests : EnumTypeTestBase + public class UShortTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(UIntEnum); + public override Type CreateType() => typeof(ushort); } public class IntTests : PrimitiveTypeTestBase @@ -451,19 +458,9 @@ public class IntTests : PrimitiveTypeTestBase public override Type CreateType() => typeof(int); } - public class IntEnumTests : EnumTypeTestBase - { - public override Type CreateType() => typeof(IntEnum); - } - - public class ULongTests : PrimitiveTypeTestBase - { - public override Type CreateType() => typeof(ulong); - } - - public class ULongEnumTests : EnumTypeTestBase + public class UIntTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(ULongEnum); + public override Type CreateType() => typeof(uint); } public class LongTests : PrimitiveTypeTestBase @@ -471,29 +468,29 @@ public class LongTests : PrimitiveTypeTestBase public override Type CreateType() => typeof(long); } - public class LongEnumTests : EnumTypeTestBase + public class ULongTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(LongEnum); + public override Type CreateType() => typeof(ulong); } - public class DoubleTests : PrimitiveTypeTestBase + public class CharTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(double); + public override Type CreateType() => typeof(char); } - public class FloatTests : PrimitiveTypeTestBase + public class BoolTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(float); + public override Type CreateType() => typeof(bool); } - public class BoolTests : PrimitiveTypeTestBase + public class FloatTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(bool); + public override Type CreateType() => typeof(float); } - public class CharTests : PrimitiveTypeTestBase + public class DoubleTests : PrimitiveTypeTestBase { - public override Type CreateType() => typeof(char); + public override Type CreateType() => typeof(double); } public class IntPtrTests : PrimitiveTypeTestBase @@ -506,7 +503,12 @@ public class UIntPtrTests : PrimitiveTypeTestBase public override Type CreateType() => typeof(UIntPtr); } - public class ObjectTests : ClassTypeTestBase + public class VoidTests : StructTypeTestBase + { + public override Type CreateType() => typeof(void); + } + + public class ObjectTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(object); @@ -515,13 +517,29 @@ public class ObjectTests : ClassTypeTestBase public override Type BaseType => null; } - public class ValueTypeTests : ClassTypeTestBase + public class ArrayTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(Array); + + public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; + } + + public class ValueTypeTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(ValueType); public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; } + public class DelegateTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(Delegate); + + public override TypeAttributes Attributes => PlatformDetection.IsMonoRuntime + ? TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit + : TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit; + } + public class EnumTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(Enum); @@ -531,67 +549,76 @@ public class EnumTypeTests : ClassTypeTestBase public override Type BaseType => typeof(ValueType); } - public class VoidTests : StructTypeTestBase + // Primitives enums + public class SByteEnumTests : EnumTypeTestBase { - public override Type CreateType() => typeof(void); + public override Type CreateType() => typeof(SByteEnum); } - public class IntRefTests : TypePropertyTestBase + public class ByteEnumTests : EnumTypeTestBase { - public override Type CreateType() => typeof(int).MakeByRefType(); - - public override TypeAttributes Attributes => TypeAttributes.Class; - - public override Type BaseType => null; - - public override bool IsByRef => true; + public override Type CreateType() => typeof(ByteEnum); + } - public override bool IsTypeDefinition => false; + public class Int16EnumTests : EnumTypeTestBase + { + public override Type CreateType() => typeof(Int16Enum); + } - public override bool HasElementType => true; + public class UInt16EnumTests : EnumTypeTestBase + { + public override Type CreateType() => typeof(UInt16Enum); + } - public override Type ElementType => typeof(int); + public class Int32EnumTests : EnumTypeTestBase + { + public override Type CreateType() => typeof(Int32Enum); } - public class IntPointerTests : TypePropertyTestBase + public class UInt32EnumTests : EnumTypeTestBase { - public override Type CreateType() => typeof(int).MakePointerType(); + public override Type CreateType() => typeof(UInt32Enum); + } - public override TypeAttributes Attributes => TypeAttributes.Class; + public class Int64EnumTests : EnumTypeTestBase + { + public override Type CreateType() => typeof(Int64Enum); + } - public override Type BaseType => null; + public class UInt64EnumTests : EnumTypeTestBase + { + public override Type CreateType() => typeof(UInt64Enum); + } - public override bool IsPointer => true; + // Arrays, pointers. + public class StringArrayTests : ArrayTypeTestBase + { + public override Type CreateType() => typeof(string[]); - public override bool IsTypeDefinition => false; + public override int? ArrayRank => 1; - public override bool HasElementType => true; + public override Type ElementType => typeof(string); - public override Type ElementType => typeof(int); + public override bool IsSZArray => true; } public class IntArrayTests : ArrayTypeTestBase { public override Type CreateType() => typeof(int[]); - public override Type ElementType => typeof(int); - - public override bool IsSZArray => true; - } - - public class MultidimensionalIntArrayTests : ArrayTypeTestBase - { - public override Type CreateType() => typeof(int[,]); + public override int? ArrayRank => 1; public override Type ElementType => typeof(int); - public override bool IsVariableBoundArray => true; + public override bool IsSZArray => true; } public class ArrayOfArrayTests : ArrayTypeTestBase { public override Type CreateType() => typeof(int[][]); + public override int? ArrayRank => 1; + public override Type ElementType => typeof(int[]); public override bool IsSZArray => true; @@ -601,6 +628,8 @@ public class NestedArrayTests : ArrayTypeTestBase { public override Type CreateType() => typeof(Outside.Inside[]); + public override int? ArrayRank => 1; + public override Type ElementType => typeof(Outside.Inside); public override bool IsSZArray => true; @@ -610,36 +639,83 @@ public class GenericNestedArrayTests : ArrayTypeTestBase { public override Type CreateType() => typeof(Outside.Inside[]); + public override int? ArrayRank => 1; + public override Type ElementType => typeof(Outside.Inside); public override bool IsSZArray => true; } - public class ArrayTypeTests : ClassTypeTestBase + public class NonSzIntArrayTests : ArrayTypeTestBase { - public override Type CreateType() => typeof(Array); + public override Type CreateType() => typeof(int).MakeArrayType(1); - public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; + public override int? ArrayRank => 1; + + public override Type ElementType => typeof(int); + + public override bool IsVariableBoundArray => true; } - public class NonGenericClassTests : ClassTypeTestBase + public class MultidimensionalIntArrayTests : ArrayTypeTestBase { - public override Type CreateType() => typeof(NonGenericClass); + public override Type CreateType() => typeof(int[,]); + + public override int? ArrayRank => 2; + + public override Type ElementType => typeof(int); + + public override bool IsVariableBoundArray => true; } - public class NonGenericSubClassOfNonGenericTests : ClassTypeTestBase + public class IntPointerTests : TypePropertyTestBase { - public override Type CreateType() => typeof(NonGenericSubClassOfNonGeneric); + public override Type CreateType() => typeof(int).MakePointerType(); - public override Type BaseType => typeof(NonGenericClass); + public override TypeAttributes Attributes => TypeAttributes.Class; + + public override Type BaseType => null; + + public override bool IsPointer => true; + + public override bool IsTypeDefinition => false; + + public override bool HasElementType => true; + + public override Type ElementType => typeof(int); } - public class TypedReferenceTypeTests : StructTypeTestBase + public class IntRefTests : TypePropertyTestBase { - public override Type CreateType() => typeof(TypedReference); + public override Type CreateType() => typeof(int).MakeByRefType(); + + public override TypeAttributes Attributes => TypeAttributes.Class; + + public override Type BaseType => null; + + public override bool IsByRef => true; + + public override bool IsTypeDefinition => false; + + public override bool HasElementType => true; + + public override Type ElementType => typeof(int); + } + + // Classes, structs, interfaces, enums + public class NonGenericClassTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(NonGenericClass); + } + + public class NonGenericSubClassOfNonGenericTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(NonGenericSubClassOfNonGeneric); + + public override Type BaseType => typeof(NonGenericClass); } - public class GenericClass1Tests : ClassTypeTestBase + public class GenericClass1TypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(GenericClass); @@ -650,9 +726,11 @@ public class GenericClass1Tests : ClassTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericClass<>); } - public class GenericClass2Tests : ClassTypeTestBase + public class GenericClass2TypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(GenericClass); @@ -663,9 +741,11 @@ public class GenericClass2Tests : ClassTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(int), typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericClass<,>); } - public class OpenGenericClassTests : ClassTypeTestBase + public class OpenGenericClassTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(GenericClass<>); @@ -674,9 +754,28 @@ public class OpenGenericClassTests : ClassTypeTestBase public override bool IsGenericType => true; public override bool IsGenericTypeDefinition => true; + + public override Type GenericTypeDefinition => typeof(GenericClass<>); + } + + public class OpenGenericNestedClassTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(GenericClass<>).MakeGenericType(typeof(GenericClass<>)); + + public override bool ContainsGenericParameters => true; + + public override bool IsConstructedGenericType => true; + + public override bool IsGenericType => true; + + public override bool IsTypeDefinition => false; + + public override Type[] GenericTypeArguments => new Type[] { typeof(GenericClass<>) }; + + public override Type GenericTypeDefinition => typeof(GenericClass<>); } - public class NonGenericSubClassOfGenericTests : ClassTypeTestBase + public class NonGenericSubClassOfGenericTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(NonGenericSubClassOfGeneric); @@ -704,6 +803,8 @@ public class GenericStruct1Tests : StructTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericStruct<>); } public class GenericStruct2Tests : StructTypeTestBase @@ -717,6 +818,8 @@ public class GenericStruct2Tests : StructTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(int), typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericStruct<,>); } public class NonGenericInterfaceTests : InterfaceTypeTestBase @@ -735,6 +838,8 @@ public class GenericInterface1Tests : InterfaceTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericInterface<>); } public class GenericInterface2Tests : InterfaceTypeTestBase @@ -748,6 +853,15 @@ public class GenericInterface2Tests : InterfaceTypeTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(int), typeof(string) }; + + public override Type GenericTypeDefinition => typeof(GenericInterface<,>); + } + + public class AbstractClassTypeTests : ClassTypeTestBase + { + public override Type CreateType() => typeof(AbstractClass); + + public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit; } public class OpenGenericInterfaceTests : InterfaceTypeTestBase @@ -759,6 +873,8 @@ public class OpenGenericInterfaceTests : InterfaceTypeTestBase public override bool IsGenericType => true; public override bool IsGenericTypeDefinition => true; + + public override Type GenericTypeDefinition => typeof(GenericInterface<>); } public class NonGenericNestedTests : TypePropertyTestBase @@ -785,6 +901,8 @@ public class GenericNestedTests : TypePropertyTestBase public override bool IsTypeDefinition => false; public override Type[] GenericTypeArguments => new Type[] { typeof(int), typeof(double) }; + + public override Type GenericTypeDefinition => typeof(Outside<>.Inside<>); } public class OpenGenericNestedTests : TypePropertyTestBase @@ -800,6 +918,8 @@ public class OpenGenericNestedTests : TypePropertyTestBase public override bool IsGenericType => true; public override bool IsGenericTypeDefinition => true; + + public override Type GenericTypeDefinition => typeof(Outside<>.Inside<>); } public class GenericTypeParameter1Of1Tests : TypePropertyTestBase @@ -939,7 +1059,7 @@ public class GenericMethodParameter2Of2Tests : TypePropertyTestBase public override int? GenericParameterPosition => 1; } - public class MarshalByRefObjectTests : ClassTypeTestBase + public class MarshalByRefObjectTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(MarshalByRefObject); @@ -949,7 +1069,7 @@ public class MarshalByRefObjectTests : ClassTypeTestBase public override bool IsMarshalByRef => false; } - public class ContextBoundObjectTests : ClassTypeTestBase + public class ContextBoundObjectTypeTests : ClassTypeTestBase { public override Type CreateType() => typeof(ContextBoundObject); @@ -962,19 +1082,38 @@ public class ContextBoundObjectTests : ClassTypeTestBase public override bool IsContextful => false; } - public enum ByteEnum : byte { } + // By-Ref types. + public class TypedReferenceTypeTests : StructTypeTestBase + { + public override Type CreateType() => typeof(TypedReference); + } - public enum SByteEnum : sbyte { } + public class ArgIteratorTypeTests : StructTypeTestBase + { + public override Type CreateType() => typeof(ArgIterator); - public enum UShortEnum : ushort { } + public override TypeAttributes Attributes => PlatformDetection.IsMonoRuntime + ? TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit + : TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit; + } - public enum ShortEnum : short { } + public class RuntimeArgumentHandleTypeTests : StructTypeTestBase + { + public override Type CreateType() => typeof(RuntimeArgumentHandle); + } - public enum UIntEnum : uint { } + public class SpanIntTypeTests : StructTypeTestBase + { + public override Type CreateType() => typeof(Span); + + public override Type[] GenericTypeArguments => new Type[] { typeof(int) }; - public enum IntEnum : int { } + public override bool IsConstructedGenericType => true; - public enum ULongEnum : ulong { } + public override bool IsGenericType => true; - public enum LongEnum : long { } + public override bool IsTypeDefinition => false; + + public override Type GenericTypeDefinition => typeof(Span<>); + } } diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs index 05236cc36cb7..40df667733da 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs @@ -174,23 +174,6 @@ public void GetTypeFromDefaultHandle() Assert.Null(Type.GetTypeFromHandle(default(RuntimeTypeHandle))); } - [Theory] - [InlineData(typeof(int[]), 1)] - [InlineData(typeof(int[,,]), 3)] - public void GetArrayRank_Get_ReturnsExpected(Type t, int expected) - { - Assert.Equal(expected, t.GetArrayRank()); - } - - [Theory] - [InlineData(typeof(int))] - [InlineData(typeof(IList))] - [InlineData(typeof(IList<>))] - public void GetArrayRank_NonArrayType_ThrowsArgumentException(Type t) - { - AssertExtensions.Throws(null, () => t.GetArrayRank()); - } - public static IEnumerable MakeArrayType_TestData() { return new object[][] @@ -346,23 +329,170 @@ public void MakeArrayType_InvalidArrayRank_ThrowsTypeLoadException(int rank) Assert.Throws(() => t.MakeArrayType(rank)); } + public static IEnumerable MakeByRefType_TestData() + { + return new object[][] + { + // Primitives + new object[] { typeof(string) }, + new object[] { typeof(sbyte) }, + new object[] { typeof(byte) }, + new object[] { typeof(short) }, + new object[] { typeof(ushort) }, + new object[] { typeof(int) }, + new object[] { typeof(uint) }, + new object[] { typeof(long) }, + new object[] { typeof(ulong) }, + new object[] { typeof(char) }, + new object[] { typeof(bool) }, + new object[] { typeof(float) }, + new object[] { typeof(double) }, + new object[] { typeof(IntPtr) }, + new object[] { typeof(UIntPtr) }, + new object[] { typeof(void) }, + + // Primitives enums + new object[] { typeof(SByteEnum) }, + new object[] { typeof(ByteEnum) }, + new object[] { typeof(Int16Enum) }, + new object[] { typeof(UInt16Enum) }, + new object[] { typeof(Int32Enum) }, + new object[] { typeof(UInt32Enum) }, + new object[] { typeof(Int64Enum) }, + new object[] { typeof(UInt64Enum) }, + + // Array, pointers + new object[] { typeof(string[]) }, + new object[] { typeof(int[]) }, + new object[] { typeof(int*) }, + + // Classes, structs, interfaces, enums + new object[] { typeof(NonGenericClass) }, + new object[] { typeof(GenericClass) }, + new object[] { typeof(NonGenericStruct) }, + new object[] { typeof(GenericStruct) }, + new object[] { typeof(NonGenericInterface) }, + new object[] { typeof(GenericInterface) }, + new object[] { typeof(AbstractClass) }, + new object[] { typeof(StaticClass) }, + + // Generic types. + new object[] { typeof(GenericClass<>) }, + new object[] { typeof(GenericClass<>).MakeGenericType(typeof(GenericClass<>)) }, + new object[] { typeof(GenericClass<>).GetTypeInfo().GetGenericArguments()[0] }, + + // By-Ref Like. + new object[] { typeof(TypedReference) }, + new object[] { typeof(ArgIterator) }, + new object[] { typeof(RuntimeArgumentHandle) }, + new object[] { typeof(Span) }, + }; + } + [Theory] - [InlineData(typeof(int))] + [MemberData(nameof(MakeByRefType_TestData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/37489", TestRuntimes.Mono)] public void MakeByRefType_Invoke_ReturnsExpected(Type t) { - Type tRef1 = t.MakeByRefType(); - Type tRef2 = t.MakeByRefType(); + Type tPointer = t.MakeByRefType(); + Assert.Equal(tPointer, t.MakeByRefType()); + + Assert.True(tPointer.IsByRef); + Assert.False(tPointer.IsPointer); + Assert.True(tPointer.HasElementType); + Assert.Equal(t, tPointer.GetElementType()); + + Assert.Equal(t.ToString() + "&", tPointer.ToString()); + } + + [Fact] + public void MakeByRefType_ByRef_ThrowsTypeLoadException() + { + Type t = typeof(int).MakeByRefType(); + Assert.Throws(() => t.MakeByRefType()); + } - Assert.Equal(tRef1, tRef2); + public static IEnumerable MakePointerType_TestData() + { + return new object[][] + { + // Primitives + new object[] { typeof(string) }, + new object[] { typeof(sbyte) }, + new object[] { typeof(byte) }, + new object[] { typeof(short) }, + new object[] { typeof(ushort) }, + new object[] { typeof(int) }, + new object[] { typeof(uint) }, + new object[] { typeof(long) }, + new object[] { typeof(ulong) }, + new object[] { typeof(char) }, + new object[] { typeof(bool) }, + new object[] { typeof(float) }, + new object[] { typeof(double) }, + new object[] { typeof(IntPtr) }, + new object[] { typeof(UIntPtr) }, + new object[] { typeof(void) }, - Assert.True(tRef1.IsByRef); - Assert.True(tRef1.HasElementType); + // Primitives enums + new object[] { typeof(SByteEnum) }, + new object[] { typeof(ByteEnum) }, + new object[] { typeof(Int16Enum) }, + new object[] { typeof(UInt16Enum) }, + new object[] { typeof(Int32Enum) }, + new object[] { typeof(UInt32Enum) }, + new object[] { typeof(Int64Enum) }, + new object[] { typeof(UInt64Enum) }, - Assert.Equal(t, tRef1.GetElementType()); + // Array, pointers + new object[] { typeof(string[]) }, + new object[] { typeof(int[]) }, + new object[] { typeof(int*) }, - string s1 = t.ToString(); - string s2 = tRef1.ToString(); - Assert.Equal(s2, s1 + "&"); + // Classes, structs, interfaces, enums + new object[] { typeof(NonGenericClass) }, + new object[] { typeof(GenericClass) }, + new object[] { typeof(NonGenericStruct) }, + new object[] { typeof(GenericStruct) }, + new object[] { typeof(NonGenericInterface) }, + new object[] { typeof(GenericInterface) }, + new object[] { typeof(AbstractClass) }, + new object[] { typeof(StaticClass) }, + + // Generic types. + new object[] { typeof(GenericClass<>) }, + new object[] { typeof(GenericClass<>).MakeGenericType(typeof(GenericClass<>)) }, + new object[] { typeof(GenericClass<>).GetTypeInfo().GetGenericArguments()[0] }, + + // ByRef Like. + new object[] { typeof(TypedReference) }, + new object[] { typeof(ArgIterator) }, + new object[] { typeof(RuntimeArgumentHandle) }, + new object[] { typeof(Span) }, + }; + } + + [Theory] + [MemberData(nameof(MakePointerType_TestData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/37489", TestRuntimes.Mono)] + public void MakePointerType_Invoke_ReturnsExpected(Type t) + { + Type tPointer = t.MakePointerType(); + Assert.Equal(tPointer, t.MakePointerType()); + + Assert.False(tPointer.IsByRef); + Assert.True(tPointer.IsPointer); + Assert.True(tPointer.HasElementType); + Assert.Equal(t, tPointer.GetElementType()); + + Assert.Equal(t.ToString() + "*", tPointer.ToString()); + } + + [Fact] + public void MakePointerType_ByRef_ThrowsTypeLoadException() + { + Type t = typeof(int).MakeByRefType(); + Assert.Throws(() => t.MakePointerType()); } [Theory] diff --git a/src/tests/CoreMangLib/system/type/TypeGetArrayRank.csproj b/src/tests/CoreMangLib/system/type/TypeGetArrayRank.csproj deleted file mode 100644 index 10004f1d8a1f..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeGetArrayRank.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeGetElementType.csproj b/src/tests/CoreMangLib/system/type/TypeGetElementType.csproj deleted file mode 100644 index 9f95260229e6..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeGetElementType.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeGetGenericTypeDefinition.csproj b/src/tests/CoreMangLib/system/type/TypeGetGenericTypeDefinition.csproj deleted file mode 100644 index e0bafc969d83..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeGetGenericTypeDefinition.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeHasElementTypeImpl.csproj b/src/tests/CoreMangLib/system/type/TypeHasElementTypeImpl.csproj deleted file mode 100644 index 9a01d617ea1e..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeHasElementTypeImpl.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeIsByRefImpl.csproj b/src/tests/CoreMangLib/system/type/TypeIsByRefImpl.csproj deleted file mode 100644 index 739b412a869c..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeIsByRefImpl.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeIsPointerImpl.csproj b/src/tests/CoreMangLib/system/type/TypeIsPointerImpl.csproj deleted file mode 100644 index 1524477668da..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeIsPointerImpl.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeMakeArrayType1.csproj b/src/tests/CoreMangLib/system/type/TypeMakeArrayType1.csproj deleted file mode 100644 index de53648d9d28..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeMakeArrayType1.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeMakeArrayType2.csproj b/src/tests/CoreMangLib/system/type/TypeMakeArrayType2.csproj deleted file mode 100644 index 86bc83c948ec..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeMakeArrayType2.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeMakeByRefType.csproj b/src/tests/CoreMangLib/system/type/TypeMakeByRefType.csproj deleted file mode 100644 index 1bddcb982a90..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeMakeByRefType.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/TypeMakePointerType.csproj b/src/tests/CoreMangLib/system/type/TypeMakePointerType.csproj deleted file mode 100644 index daf22f11ce3c..000000000000 --- a/src/tests/CoreMangLib/system/type/TypeMakePointerType.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Exe - true - BuildAndRun - 1 - - - - - - - - diff --git a/src/tests/CoreMangLib/system/type/typegetarrayrank.cs b/src/tests/CoreMangLib/system/type/typegetarrayrank.cs deleted file mode 100644 index e6d06ced1eb1..000000000000 --- a/src/tests/CoreMangLib/system/type/typegetarrayrank.cs +++ /dev/null @@ -1,198 +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; - -public class TypeGetArrayRank -{ - #region Private Variables - private const int c_DEFAULT_ARRAY_DIMENSION = 2; - #endregion - - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - - TestLibrary.TestFramework.LogInformation("[Negative]"); - retVal = NegTest1() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - int size = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest1: Get rank of an one dimension array"); - - try - { - // Do not make a large array - size = TestLibrary.Generator.GetByte(-55); - - int[] array = new int[size]; - for (int i = 0; i < size; ++i) - { - array[i] = TestLibrary.Generator.GetInt32(-55); - } - - Type type = array.GetType(); - int rank = type.GetArrayRank(); - if (rank != 1) - { - TestLibrary.TestFramework.LogError("001", "Get rank of an one dimension array returns " + rank.ToString()); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e + "; with size = " + size); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - int size = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest2: Get rank of an multiple dimensions array"); - - try - { - // Do not make a large array - size = TestLibrary.Generator.GetByte(-55); - - int[,] array = new int[c_DEFAULT_ARRAY_DIMENSION, size]; - for (int i = 0; i < c_DEFAULT_ARRAY_DIMENSION; ++i) - { - for (int j = 0; j < size; ++j) - { - array[i, j] = TestLibrary.Generator.GetInt32(-55); - } - } - - Type type = array.GetType(); - int rank = type.GetArrayRank(); - if (rank != c_DEFAULT_ARRAY_DIMENSION) - { - TestLibrary.TestFramework.LogError("003", "Get rank of an multiple dimensions array returns " + rank.ToString()); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpected exception: " + e + "; with size = " + size); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - int size = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest3: Get rank of an multiple dimensions jagged array"); - - try - { - // Do not make a large array - size = TestLibrary.Generator.GetByte(-55); - - int[][] array = new int[size][]; - - for (int i = 0; i < size; ++i) - { - int subArrayLength = TestLibrary.Generator.GetByte(-55); - int[] subArray = new int[subArrayLength]; - - for (int j = 0; j < subArrayLength; ++j) - { - subArray[j] = TestLibrary.Generator.GetInt32(-55); - } - - array[i] = subArray; - } - - Type type = array.GetType(); - int rank = type.GetArrayRank(); - if (rank != 1) - { - TestLibrary.TestFramework.LogError("005", "Get rank of an multiple dimensions jagged array returns " + rank.ToString()); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - - #region Nagetive Test Cases - public bool NegTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("NegTest1: Check ArgumentException will be thrown"); - - try - { - Type t1 = typeof(Exception); - - int returnObject = t1.GetArrayRank(); - TestLibrary.TestFramework.LogError("101", "ArgumentException is not thrown when calling typeof(Exception).GetArrayRank()"); - retVal = false; - } - catch (ArgumentException) - { - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("102", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeGetArrayRank test = new TypeGetArrayRank(); - - TestLibrary.TestFramework.BeginTestCase("TypeGetArrayRank"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} diff --git a/src/tests/CoreMangLib/system/type/typegetelementtype.cs b/src/tests/CoreMangLib/system/type/typegetelementtype.cs deleted file mode 100644 index 3cef304309cf19b695a2b2460e315da3d416cdce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5722 zcmd^DT~8BH5S?ce|HIk`Q=(be;**LAl0rx@F@U}pA82iB724V^Vm1DC^_)9QcQ3uW z-ByT-Y0BM?J0ExE%$zAdf1Jxi`ZAE7L~o41b)=No)NC= zvIc4TooQMR>KZ|R%X!|0L>pHp*f+to=_<2B3*Vfb2on7G`WQov2emW0Db^Qw#%p>> z4JPYrvZq!2sOD`XTd*}id@it7(Mu0Ci{_23$I!yl9pEG_%?Wk&xM^coD+L%=U65R zO;~<6vzj1Iu$v!N0T^3kJR-KIbOW8)PAK_||^)a%PB5GskiX@Q@e8R~1 z?qS-z@1U}n={(-;-R+L?E@HfoI$1Wx)#9ts&PUbnKrQ5bh}cI#%;)98S;*uS0k44| zYGWr!frfMBG>n5)YGV;z-vF^g;Hd9V{28|2mc(`5W0f|~5?A+;+{Y)vS%`2wU-(4% z9U1{&Ut=YGR#SQHzWw!HI;d z$XQ5xEs<+_6M1}@2kWYuLCu)4SOnR8COKz)fM#Zrc^%+ti0NnqOPpFXyX0HVaTia< z_~`Q#dn0I=;;&(&?Rq+Q=xjod$>vk=b#ccc(xzVSENo|yAO3TaMyj8EOYPi0dY;IW4|U9ynReCshdFspv{v^sQ9)5bzg zS+2~d1aj<;S8eDdY5R+3D~p!xWVZCQjZ4jTpCC(R^XXz6HaA6bFJ~pjT>S~iV6W$N zlzA{8?=?gyR6%x%azxlJtBYmoP1&O9FhtC=$~c!KSed(8X>3?OL?0#Zm0;aGw3Vnd zp3ppJ-O%sbCSj{T8HHlz?=ZQxtAaLqGbh|8x;blL1TXY=7Ecn+L3!-2GvZuzLsv!=yUbyekElL|B8|G~LB+2j!$MppG{F|W%ayb2zd z;oQbw%DKd&GPN=~rz-34H^IUd=N)u+`)>!iDu3_)r$B$xXYUvD$~<@FSuxXO{AK%B z(R_2PXjy20A-2%hI5D3V^jbr4xH9amt(Jr9;JeLP?=71J{uJMZD*fN(xks~D-%g%m Xwlq8bud#NnR~UA)DyEc=`%KR-pC&6L diff --git a/src/tests/CoreMangLib/system/type/typegetgenerictypedefinition.cs b/src/tests/CoreMangLib/system/type/typegetgenerictypedefinition.cs deleted file mode 100644 index 3a08a902e151..000000000000 --- a/src/tests/CoreMangLib/system/type/typegetgenerictypedefinition.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Globalization; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; - -/// -///Type.GetGenericTypeDefinition() -/// -public class TypeGetGenericTypeDefinition -{ - public static int Main() - { - TypeGetGenericTypeDefinition tggtd = new TypeGetGenericTypeDefinition(); - TestLibrary.TestFramework.BeginTestCase("TypeGetGenericTypeDefinition"); - if (tggtd.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } - - public bool RunTests() - { - bool retVal = true; - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - TestLibrary.TestFramework.LogInformation("[Negtive]"); - retVal = NegTest1() && retVal; - - return retVal; - } - #region PositiveTesting - public bool PosTest1() - { - bool retVal = true; - Type tpA; - Type ActualResult; - TestLibrary.TestFramework.BeginScenario("PosTest1: the current type's definition has one generic param"); - try - { - tpA = typeof(Derived2); - ActualResult = tpA.GetGenericTypeDefinition(); - if(ActualResult != typeof(Derived2<>)) - { - TestLibrary.TestFramework.LogError("001","the ActualResult is not the ExpectResult"); - retVal = false; - } - } - catch(Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpect exception:" + e); - retVal = false; - } - return retVal; - } - public bool PosTest2() - { - bool retVal = true; - Type tpA; - Type tpB; - Type ActualResult1; - Type ActualResult2; - TestLibrary.TestFramework.BeginScenario("PosTest2: the current type has the same type argument"); - try - { - tpA = typeof(Derived2); - tpB = typeof(Derived2); - ActualResult1 = tpA.GetGenericTypeDefinition(); - ActualResult2 = tpB.GetGenericTypeDefinition(); - if (ActualResult1 != typeof(Derived2<>) || ActualResult2 != ActualResult1) - { - TestLibrary.TestFramework.LogError("003", "the ActualResult is not the ExpectResult"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpect exception:" + e); - retVal = false; - } - return retVal; - } - #endregion - #region NegativeTest - public bool NegTest1() - { - bool retVal = true; - Type tpA; - Type ActualResult; - TestLibrary.TestFramework.BeginScenario("NegTest1: the current object is not generic type"); - - try - { - tpA = typeof(Derived); - ActualResult = tpA.GetGenericTypeDefinition(); - retVal = false; - } - catch (InvalidOperationException) { } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("N001", "Unexpect exception:" + e); - retVal = false; - } - return retVal; - - } - #endregion - #region UsingForTesting - public class Base { } - public class Derived : Base { } - public class Derived2 : Base { } - public class G { } - #endregion -} - diff --git a/src/tests/CoreMangLib/system/type/typehaselementtypeimpl.cs b/src/tests/CoreMangLib/system/type/typehaselementtypeimpl.cs deleted file mode 100644 index c345afdf7e19..000000000000 --- a/src/tests/CoreMangLib/system/type/typehaselementtypeimpl.cs +++ /dev/null @@ -1,120 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Globalization; -using System.Reflection; -using System.Collections; -/// -///HasElementTypeImpl -/// -public class TypeHasElementTypeImpl -{ - public static int Main() - { - TypeHasElementTypeImpl TypeHasElementTypeImpl = new TypeHasElementTypeImpl(); - - TestLibrary.TestFramework.BeginTestCase("TypeHasElementTypeImpl"); - if (TypeHasElementTypeImpl.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } - - public bool RunTests() - { - bool retVal = true; - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - return retVal; - } - // Returns true if the expected result is right - // Returns false if the expected result is wrong - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: The Type is an array "); - try - { - int[] myArray = new int[5]; - if (!myArray.GetType().HasElementType) - { - TestLibrary.TestFramework.LogError("001", "HasElementType should return false." ); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - retVal = false; - } - return retVal; - } - // Returns true if the expected result is right - // Returns false if the expected result is wrong - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest2: The Type is IntPtr "); - try - { - IntPtr myInt=new IntPtr(5); - if (myInt.GetType().HasElementType) - { - TestLibrary.TestFramework.LogError("001", "HasElementType should return false."); - retVal = false; - } - - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - retVal = false; - } - return retVal; - } - // Returns true if the expected result is right - // Returns false if the expected result is wrong - public bool PosTest3() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest3: The Type is reference type"); - try - { - TestClass myInstance = new TestClass(); - if (myInstance.GetType().HasElementType) - { - TestLibrary.TestFramework.LogError("001", "HasElementType should return false."); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - retVal = false; - } - return retVal; - } - private void MyMethod(ref TestClass myTest) - { - - } - -} - -public class TestClass -{ - -} diff --git a/src/tests/CoreMangLib/system/type/typeisbyrefimpl.cs b/src/tests/CoreMangLib/system/type/typeisbyrefimpl.cs deleted file mode 100644 index 1a3c5acb641a..000000000000 --- a/src/tests/CoreMangLib/system/type/typeisbyrefimpl.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Globalization; -using System.Reflection; -using System.Collections; -/// -///IsByRefImpl -/// -public class TypeIsByRefImpl -{ - public static int Main() - { - TypeIsByRefImpl TypeIsByRefImpl = new TypeIsByRefImpl(); - - TestLibrary.TestFramework.BeginTestCase("TypeIsByRefImpl"); - if (TypeIsByRefImpl.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } - - public bool RunTests() - { - bool retVal = true; - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - return retVal; - } - // Returns true if the expected result is right - // Returns false if the expected result is wrong - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: override isByRefImpl and Only these type which BaseType is BaseClass Return true ,TestClass as test object "); - try - { - TestClass myobject = new TestClass(); - if (myobject.GetType().IsByRef) - { - TestLibrary.TestFramework.LogError("001", "TestClass is not Passed by reference."); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - retVal = false; - } - return retVal; - } - - // Returns true if the expected result is right - // Returns false if the expected result is wrong - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: override isByRefImpl and Only these type which BaseType is BaseClass Return true ,TestClass1 as test object "); - try - { - TestClass1 myobject = new TestClass1(); - if (myobject.GetType().IsByRef) - { - TestLibrary.TestFramework.LogError("003", "TestClass1 is not Passed by reference."); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpected exception: " + e); - retVal = false; - } - return retVal; - } - - -} -public class BaseClass -{ - -} -public class TestClass : BaseClass -{ - -} -public class TestClass1 -{ - -} diff --git a/src/tests/CoreMangLib/system/type/typeispointerimpl.cs b/src/tests/CoreMangLib/system/type/typeispointerimpl.cs deleted file mode 100644 index 42456f7ffb66..000000000000 --- a/src/tests/CoreMangLib/system/type/typeispointerimpl.cs +++ /dev/null @@ -1,194 +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; - -public struct TestGenericType2 -{ - public void TestMethod() - { - } -} - -/// -/// IsPointerImpl -/// -public class TypeIsPointerImpl -{ - #region Private Fields - private const int c_MIN_STRING_LENGTH = 1; - private const int c_MAX_STRING_LENGTH = 128; - #endregion - - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - retVal = PosTest4() && retVal; - - TestLibrary.TestFramework.LogInformation("[Negative]"); - retVal = NegTest1() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: IsPointerImpl should return false for value type"); - - try - { - int obj = TestLibrary.Generator.GetInt32(-55); - Type type = obj.GetType(); - - if (type.IsPointer) - { - TestLibrary.TestFramework.LogError("001", "IsPointerImpl returns true for value type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest2: IsPointerImpl should return false for reference type"); - - try - { - String obj = TestLibrary.Generator.GetString(-55, false, c_MIN_STRING_LENGTH, c_MAX_STRING_LENGTH); - Type type = obj.GetType(); - - if (type.IsPointer) - { - TestLibrary.TestFramework.LogError("003", "IsPointerImpl returns true for reference type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest3: IsPointerImpl should return false for IntPtr"); - - try - { - Type type = typeof(IntPtr); - - if (type.IsPointer) - { - TestLibrary.TestFramework.LogError("005", "IsPointerImpl returns true for IntPtr"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest4() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest4: IsPointerImpl should return true for a pointer type"); - - try - { - Type type = typeof(int*); - - if (!type.IsPointer) - { - TestLibrary.TestFramework.LogError("007", "IsPointerImpl returns false for a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("008", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - - #region Nagetive Test Cases - public bool NegTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("NegTest1: IsPointerImpl should return true for type contains generic member"); - - try - { - Type type = typeof(TestGenericType2*); - if (!type.IsPointer) - { - TestLibrary.TestFramework.LogError("101", "IsPointerImpl returns false for type contains generic member"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("102", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeIsPointerImpl test = new TypeIsPointerImpl(); - - TestLibrary.TestFramework.BeginTestCase("TypeIsPointerImpl"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} diff --git a/src/tests/CoreMangLib/system/type/typemakearraytype1.cs b/src/tests/CoreMangLib/system/type/typemakearraytype1.cs deleted file mode 100644 index 4b3178f241fb..000000000000 --- a/src/tests/CoreMangLib/system/type/typemakearraytype1.cs +++ /dev/null @@ -1,237 +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; - -/// -/// MakeArrayType() -/// -public class TypeMakeArrayType1 -{ - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - retVal = PosTest4() && retVal; - retVal = PosTest5() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: Call MakeArrayType for reference type"); - - try - { - Type type = typeof(String); - Type arrayType = type.MakeArrayType(); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("001", "Call MakeArrayType for reference type does not make a array type"); - retVal = false; - break; - } - - if (arrayType.GetArrayRank() != 1) - { - TestLibrary.TestFramework.LogError("002", "Call MakeArrayType for reference type does not make a one dimension array type"); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("003", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest2: Call MakeArrayType for value type"); - - try - { - Type type = typeof(Int32); - Type arrayType = type.MakeArrayType(); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("004", "Call MakeArrayType for value type does not make a array type"); - retVal = false; - break; - } - - if (arrayType.GetArrayRank() != 1) - { - TestLibrary.TestFramework.LogError("005", "Call MakeArrayType for value type does not make a one dimension array type"); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest3: Call MakeArrayType for pointer type"); - - try - { - Type type = typeof(char *); - Type arrayType = type.MakeArrayType(); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("007", "Call MakeArrayType for pointer type does not make a array type"); - retVal = false; - break; - } - - if (arrayType.GetArrayRank() != 1) - { - TestLibrary.TestFramework.LogError("008", "Call MakeArrayType for pointer type does not make a one dimension array type"); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("009", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest4() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest4: Call MakeArrayType for value array type"); - - try - { - Type type = typeof(int[]); - Type arrayType = type.MakeArrayType(); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("010", "Call MakeArrayType for value array type does not make a array type"); - retVal = false; - break; - } - - if (arrayType.GetArrayRank() != 1) - { - TestLibrary.TestFramework.LogError("011", "Call MakeArrayType for value array type does not make a one dimension array type"); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("012", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest5() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest5: Call MakeArrayType for reference array type"); - - try - { - Type type = typeof(String[]); - Type arrayType = type.MakeArrayType(); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("013", "Call MakeArrayType for reference array type does not make a array type"); - retVal = false; - break; - } - - if (arrayType.GetArrayRank() != 1) - { - TestLibrary.TestFramework.LogError("014", "Call MakeArrayType for reference array type does not make a one dimension array type"); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("015", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeMakeArrayType1 test = new TypeMakeArrayType1(); - - TestLibrary.TestFramework.BeginTestCase("TypeMakeArrayType1"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} diff --git a/src/tests/CoreMangLib/system/type/typemakearraytype2.cs b/src/tests/CoreMangLib/system/type/typemakearraytype2.cs deleted file mode 100644 index 22dcaa7fa68a..000000000000 --- a/src/tests/CoreMangLib/system/type/typemakearraytype2.cs +++ /dev/null @@ -1,384 +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; - -/// -/// MakeArrayType(System.Int32) -/// -public class TypeMakeArrayType2 -{ - #region Private Members - private const int c_DEFAULT_MULTIPLE_ARRAY_DIMENSION = 4; - #endregion - - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - retVal = PosTest4() && retVal; - retVal = PosTest5() && retVal; - retVal = PosTest6() && retVal; - - TestLibrary.TestFramework.LogInformation("[Negative]"); - retVal = NegTest1() && retVal; - retVal = NegTest2() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest1: Call MakeArrayType to make 1 dimension value type array"); - - try - { - desiredDimension = 1; - Type type = typeof(Int32); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("001", "Call MakeArrayType for value type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("002", "Call MakeArrayType for value type does not make a one dimension array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("003", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest2: Call MakeArrayType to make multiple dimensions value type array"); - - try - { - desiredDimension = c_DEFAULT_MULTIPLE_ARRAY_DIMENSION; - Type type = typeof(Int32); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("004", "Call MakeArrayType for value type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("005", "Call MakeArrayType for value type does not make a one dimension array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest3: Call MakeArrayType to make multiple dimensions reference type array"); - - try - { - desiredDimension = c_DEFAULT_MULTIPLE_ARRAY_DIMENSION; - Type type = typeof(String); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("007", "Call MakeArrayType for reference type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("008", "Call MakeArrayType for reference type does not make a multiple dimensions array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("009", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest4() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest4: Call MakeArrayType to make multiple dimensions pointer type array"); - - try - { - desiredDimension = c_DEFAULT_MULTIPLE_ARRAY_DIMENSION; - Type type = typeof(char *); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("010", "Call MakeArrayType for pointer type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("011", "Call MakeArrayType for pointer type does not make a multiple dimensions array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("012", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest5() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest5: Call MakeArrayType to make multiple dimensions reference array type array"); - - try - { - desiredDimension = c_DEFAULT_MULTIPLE_ARRAY_DIMENSION; - Type type = typeof(String[]); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("013", "Call MakeArrayType for reference array type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("014", "Call MakeArrayType for reference array type does not make a multiple dimensions array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("015", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest6() - { - bool retVal = true; - int desiredDimension = 0; - - TestLibrary.TestFramework.BeginScenario("PosTest6: Call MakeArrayType to make multiple dimensions value array type array"); - - try - { - desiredDimension = c_DEFAULT_MULTIPLE_ARRAY_DIMENSION; - Type type = typeof(int[]); - Type arrayType = type.MakeArrayType(desiredDimension); - - do - { - if (!arrayType.IsArray) - { - TestLibrary.TestFramework.LogError("016", "Call MakeArrayType for value array type does not make a array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - retVal = false; - break; - } - - int actualDimension = arrayType.GetArrayRank(); - if (actualDimension != desiredDimension) - { - TestLibrary.TestFramework.LogError("017", "Call MakeArrayType for value array type does not make a multiple dimensions array type"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString() + "; actualDimension = " + actualDimension.ToString()); - retVal = false; - break; - } - } while (false); - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("018", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] desiredDimension = " + desiredDimension.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - - #region Nagetive Test Cases - public bool NegTest1() - { - bool retVal = true; - int rank = 0; - - TestLibrary.TestFramework.BeginScenario("NegTest1: IndexOutOfRangeException will be thrown when rank is invalid"); - - try - { - rank = TestLibrary.Generator.GetByte(-55); - if (rank > 0) - rank = 0 - rank; - - Type type = typeof(Object); - Type arrayType = type.MakeArrayType(rank); - - TestLibrary.TestFramework.LogError("101", "IndexOutOfRangeException is not thrown when rank is invalid"); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] rank = " + rank.ToString()); - retVal = false; - } - catch (IndexOutOfRangeException) - { - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("102", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation("[LOCAL VARIABLES] rank = " + rank.ToString()); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool NegTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("NegTest2: IndexOutOfRangeException will be thrown when rank is 0"); - - try - { - - Type type = typeof(Object); - Type arrayType = type.MakeArrayType(0); - - TestLibrary.TestFramework.LogError("103", "IndexOutOfRangeException is not thrown when rank is 0"); - retVal = false; - } - catch (IndexOutOfRangeException) - { - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("104", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeMakeArrayType2 test = new TypeMakeArrayType2(); - - TestLibrary.TestFramework.BeginTestCase("TypeMakeArrayType2"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} diff --git a/src/tests/CoreMangLib/system/type/typemakebyreftype.cs b/src/tests/CoreMangLib/system/type/typemakebyreftype.cs deleted file mode 100644 index 698c5790d558..000000000000 --- a/src/tests/CoreMangLib/system/type/typemakebyreftype.cs +++ /dev/null @@ -1,215 +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; - -/// -/// MakeByRefType() -/// -public class TypeMakeByRefType -{ - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - retVal = PosTest4() && retVal; - retVal = PosTest5() && retVal; - - TestLibrary.TestFramework.LogInformation("[Negative]"); - retVal = NegTest1() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: Call MakeByRefType for reference type"); - - try - { - Type type = typeof(String); - Type refType = type.MakeByRefType(); - - if (!refType.IsByRef) - { - TestLibrary.TestFramework.LogError("001", "Call MakeByRefType for reference type does not make a byref type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest2: Call MakeByRefType for value type"); - - try - { - Type type = typeof(int); - Type refType = type.MakeByRefType(); - - if (!refType.IsByRef) - { - TestLibrary.TestFramework.LogError("003", "Call MakeByRefType for value type does not make a byref type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest3: Call MakeByRefType for value array type"); - - try - { - Type type = typeof(int[]); - Type refType = type.MakeByRefType(); - - if (!refType.IsByRef) - { - TestLibrary.TestFramework.LogError("005", "Call MakeByRefType for value array type does not make a byref type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest4() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest4: Call MakeByRefType for reference array type"); - - try - { - Type type = typeof(String[]); - Type refType = type.MakeByRefType(); - - if (!refType.IsByRef) - { - TestLibrary.TestFramework.LogError("007", "Call MakeByRefType for reference array type does not make a byref type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("008", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest5() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest5: Call MakeByRefType for pointer type"); - - try - { - Type type = typeof(char *); - Type refType = type.MakeByRefType(); - - if (!refType.IsByRef) - { - TestLibrary.TestFramework.LogError("009", "Call MakeByRefType for pointer type does not make a byref type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("010", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - - #region Nagetive Test Cases - public bool NegTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("NegTest1: TypeLoadException will be thrown when calling MakeByRefType for ByRef type"); - - try - { - Type type = typeof(Object); - type = type.MakeByRefType(); - Type refType = type.MakeByRefType(); - - TestLibrary.TestFramework.LogError("101", "TypeLoadException is not thrown when calling MakeByRefType for ByRef type"); - retVal = false; - } - catch (TypeLoadException) - { - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("102", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeMakeByRefType test = new TypeMakeByRefType(); - - TestLibrary.TestFramework.BeginTestCase("TypeMakeByRefType"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} diff --git a/src/tests/CoreMangLib/system/type/typemakepointertype.cs b/src/tests/CoreMangLib/system/type/typemakepointertype.cs deleted file mode 100644 index 56e83f4f9554..000000000000 --- a/src/tests/CoreMangLib/system/type/typemakepointertype.cs +++ /dev/null @@ -1,182 +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; - -/// -/// MakePointerType -/// -public class TypeMakePointerType -{ - #region Public Methods - public bool RunTests() - { - bool retVal = true; - - TestLibrary.TestFramework.LogInformation("[Positive]"); - retVal = PosTest1() && retVal; - retVal = PosTest2() && retVal; - retVal = PosTest3() && retVal; - retVal = PosTest4() && retVal; - retVal = PosTest5() && retVal; - - return retVal; - } - - #region Positive Test Cases - public bool PosTest1() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest1: Call MakePointerType for a value type"); - - try - { - Type type = typeof(int); - Type pointerType = type.MakePointerType(); - - if (!pointerType.IsPointer) - { - TestLibrary.TestFramework.LogError("001", "Call MakePointerType for a value type does not make a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("002", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest2() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest2: Call MakePointerType for a reference type"); - - try - { - Type type = typeof(String); - Type pointerType = type.MakePointerType(); - - if (!pointerType.IsPointer) - { - TestLibrary.TestFramework.LogError("003", "Call MakePointerType for a reference type does not make a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("004", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest3() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest3: Call MakePointerType for a value array type"); - - try - { - Type type = typeof(int[]); - Type pointerType = type.MakePointerType(); - - if (!pointerType.IsPointer) - { - TestLibrary.TestFramework.LogError("005", "Call MakePointerType for a value array type does not make a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("006", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest4() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest4: Call MakePointerType for a reference array type"); - - try - { - Type type = typeof(String[]); - Type pointerType = type.MakePointerType(); - - if (!pointerType.IsPointer) - { - TestLibrary.TestFramework.LogError("007", "Call MakePointerType for a reference array type does not make a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("008", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - - public bool PosTest5() - { - bool retVal = true; - - TestLibrary.TestFramework.BeginScenario("PosTest5: Call MakePointerType for a pointer type"); - - try - { - Type type = typeof(char *); - Type pointerType = type.MakePointerType(); - - if (!pointerType.IsPointer) - { - TestLibrary.TestFramework.LogError("009", "Call MakePointerType for a pointer type does not make a pointer type"); - retVal = false; - } - } - catch (Exception e) - { - TestLibrary.TestFramework.LogError("010", "Unexpected exception: " + e); - TestLibrary.TestFramework.LogInformation(e.StackTrace); - retVal = false; - } - - return retVal; - } - #endregion - #endregion - - public static int Main() - { - TypeMakePointerType test = new TypeMakePointerType(); - - TestLibrary.TestFramework.BeginTestCase("TypeMakePointerType"); - - if (test.RunTests()) - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("PASS"); - return 100; - } - else - { - TestLibrary.TestFramework.EndTestCase(); - TestLibrary.TestFramework.LogInformation("FAIL"); - return 0; - } - } -} From 8e0324910669c1e8267b55abc8f814e2c6665a94 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Sat, 25 Jul 2020 11:30:34 -0700 Subject: [PATCH 052/755] Address slowdowns in type loader performance (#39841) --- src/coreclr/src/debug/daccess/nidump.cpp | 2 +- src/coreclr/src/vm/class.cpp | 168 ++++++++++++---------- src/coreclr/src/vm/class.h | 28 +++- src/coreclr/src/vm/method.cpp | 45 ++++-- src/coreclr/src/vm/method.hpp | 39 ++--- src/coreclr/src/vm/method.inl | 5 +- src/coreclr/src/vm/methodtablebuilder.cpp | 16 +++ src/coreclr/src/vm/methodtablebuilder.h | 9 +- src/coreclr/src/vm/methodtablebuilder.inl | 13 +- src/coreclr/src/vm/siginfo.cpp | 2 +- 10 files changed, 209 insertions(+), 118 deletions(-) diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp index 5a0bbfd81006..06a6fffee157 100644 --- a/src/coreclr/src/debug/daccess/nidump.cpp +++ b/src/coreclr/src/debug/daccess/nidump.cpp @@ -7996,7 +7996,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) InstantiatedMethodDesc, METHODDESCS ); #ifdef FEATURE_COMINTEROP - if (imd->IMD_HasComPlusCallInfo()) + if (imd->IsGenericComPlusCall()) { PTR_ComPlusCallInfo compluscall = imd->IMD_GetComPlusCallInfo(); DumpComPlusCallInfo( compluscall, METHODDESCS ); diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 8e18a47059f9..7a243ca786b1 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -1184,107 +1184,127 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) return; // Step 1: Validate compatibility of return types on overriding methods - - for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) + if (pMT->GetClass()->HasCovariantOverride() && (!pMT->GetModule()->IsReadyToRun() || !pMT->GetModule()->GetReadyToRunInfo()->SkipTypeValidation())) { - MethodDesc* pMD = pMT->GetMethodDescForSlot(i); - MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); + for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) + { + if (pMT->GetRestoredSlot(i) == pParentMT->GetRestoredSlot(i)) + { + // The real check is that the MethodDesc's must not match, but a simple VTable check will + // work most of the time, and is far faster than the GetMethodDescForSlot method. + _ASSERTE(pMT->GetMethodDescForSlot(i) == pParentMT->GetMethodDescForSlot(i)); + continue; + } + MethodDesc* pMD = pMT->GetMethodDescForSlot(i); + MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); - if (pMD == pParentMD) - continue; + if (pMD == pParentMD) + continue; - if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking()) - continue; + if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking()) + continue; - // If the bit is not set on this method, but we reach here because it's been set on the method at the same slot on - // the base type, set the bit for the current method to ensure any future overriding method down the chain gets checked. - if (!pMD->RequiresCovariantReturnTypeChecking()) - pMD->SetRequiresCovariantReturnTypeChecking(); + // If the bit is not set on this method, but we reach here because it's been set on the method at the same slot on + // the base type, set the bit for the current method to ensure any future overriding method down the chain gets checked. + if (!pMD->RequiresCovariantReturnTypeChecking()) + pMD->SetRequiresCovariantReturnTypeChecking(); - // The context used to load the return type of the parent method has to use the generic method arguments - // of the overriding method, otherwise the type comparison below will not work correctly - SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation()); - MetaSig methodSig1(pParentMD); - TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); + // The context used to load the return type of the parent method has to use the generic method arguments + // of the overriding method, otherwise the type comparison below will not work correctly + SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation()); + MetaSig methodSig1(pParentMD); + TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); - SigTypeContext context2(pMD); - MetaSig methodSig2(pMD); - TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); + SigTypeContext context2(pMD); + MetaSig methodSig2(pMD); + TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); - if (!IsCompatibleWith(hType1, hType2)) - { - SString strAssemblyName; - pMD->GetAssembly()->GetDisplayName(strAssemblyName); + if (!IsCompatibleWith(hType1, hType2)) + { + SString strAssemblyName; + pMD->GetAssembly()->GetDisplayName(strAssemblyName); - SString strInvalidTypeName; - TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); + SString strInvalidTypeName; + TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); - SString strInvalidMethodName; - TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); + SString strInvalidMethodName; + TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); - SString strParentMethodName; - TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); + SString strParentMethodName; + TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); - COMPlusThrow( - kTypeLoadException, - IDS_CLASSLOAD_MI_BADRETURNTYPE, - strInvalidMethodName, - strInvalidTypeName, - strAssemblyName, - strParentMethodName); + COMPlusThrow( + kTypeLoadException, + IDS_CLASSLOAD_MI_BADRETURNTYPE, + strInvalidMethodName, + strInvalidTypeName, + strAssemblyName, + strParentMethodName); + } } } // Step 2: propate overriding MethodImpls to applicable vtable slots if the declaring method has the attribute - MethodTable::MethodDataWrapper hMTData(MethodTable::GetMethodData(pMT, FALSE)); - - for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) + if (pMT->GetClass()->HasVTableMethodImpl()) { - MethodDesc* pMD = pMT->GetMethodDescForSlot(i); - MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); - if (pMD == pParentMD) - continue; - - // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op - if (!pMD->IsMethodImpl()) - continue; + MethodTable::MethodDataWrapper hMTData(MethodTable::GetMethodData(pMT, FALSE)); - // Search if the attribute has been applied on this vtable slot, either by the current MethodImpl, or by a previous - // MethodImpl somewhere in the base type hierarchy. - bool foundAttribute = false; - MethodTable* pCurrentMT = pMT; - while (!foundAttribute && pCurrentMT != NULL && i < pCurrentMT->GetNumVirtuals()) + for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) { - MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(i); + if (pMT->GetRestoredSlot(i) == pParentMT->GetRestoredSlot(i)) + { + // The real check is that the MethodDesc's must not match, but a simple VTable check will + // work most of the time, and is far faster than the GetMethodDescForSlot method. + _ASSERTE(pMT->GetMethodDescForSlot(i) == pParentMT->GetMethodDescForSlot(i)); + continue; + } + + MethodDesc* pMD = pMT->GetMethodDescForSlot(i); + MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); + if (pMD == pParentMD) + continue; // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op - if (pCurrentMD->IsMethodImpl()) + if (!pMD->IsMethodImpl()) + continue; + + // Search if the attribute has been applied on this vtable slot, either by the current MethodImpl, or by a previous + // MethodImpl somewhere in the base type hierarchy. + bool foundAttribute = false; + MethodTable* pCurrentMT = pMT; + while (!foundAttribute && pCurrentMT != NULL && i < pCurrentMT->GetNumVirtuals()) { - BYTE* pVal = NULL; - ULONG cbVal = 0; - if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::PreserveBaseOverridesAttribute, (const void**)&pVal, &cbVal) == S_OK) - foundAttribute = true; - } + MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(i); - pCurrentMT = pCurrentMT->GetParentMethodTable(); - } + // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op + if (pCurrentMD->IsMethodImpl()) + { + BYTE* pVal = NULL; + ULONG cbVal = 0; + if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::PreserveBaseOverridesAttribute, (const void**)&pVal, &cbVal) == S_OK) + foundAttribute = true; + } - if (!foundAttribute) - continue; + pCurrentMT = pCurrentMT->GetParentMethodTable(); + } - // Search for any vtable slot still pointing at the parent method, and update it with the current overriding method - for (WORD j = i; j < pParentMT->GetNumVirtuals(); j++) - { - MethodDesc* pCurrentMD = pMT->GetMethodDescForSlot(j); - if (pCurrentMD == pParentMD) + if (!foundAttribute) + continue; + + // Search for any vtable slot still pointing at the parent method, and update it with the current overriding method + for (WORD j = i; j < pParentMT->GetNumVirtuals(); j++) { - // This is a vtable slot that needs to be updated to the new overriding method because of the - // presence of the attribute. - pMT->SetSlot(j, pMT->GetSlot(i)); - _ASSERT(pMT->GetMethodDescForSlot(j) == pMD); + MethodDesc* pCurrentMD = pMT->GetMethodDescForSlot(j); + if (pCurrentMD == pParentMD) + { + // This is a vtable slot that needs to be updated to the new overriding method because of the + // presence of the attribute. + pMT->SetSlot(j, pMT->GetSlot(i)); + _ASSERT(pMT->GetMethodDescForSlot(j) == pMD); - hMTData->UpdateImplMethodDesc(pMD, j); + hMTData->UpdateImplMethodDesc(pMD, j); + } } } } diff --git a/src/coreclr/src/vm/class.h b/src/coreclr/src/vm/class.h index 98a59dbba182..179a082199a3 100644 --- a/src/coreclr/src/vm/class.h +++ b/src/coreclr/src/vm/class.h @@ -1158,6 +1158,30 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! } #endif // FEATURE_COMINTEROP + inline void SetHasVTableMethodImpl() + { + LIMITED_METHOD_CONTRACT; + m_VMFlags |= VMFLAG_VTABLEMETHODIMPL; + } + + inline BOOL HasVTableMethodImpl() + { + LIMITED_METHOD_CONTRACT; + return (m_VMFlags & VMFLAG_VTABLEMETHODIMPL); + } + + inline void SetHasCovariantOverride() + { + LIMITED_METHOD_CONTRACT; + m_VMFlags |= VMFLAG_COVARIANTOVERRIDE; + } + + inline BOOL HasCovariantOverride() + { + LIMITED_METHOD_CONTRACT; + return (m_VMFlags & VMFLAG_COVARIANTOVERRIDE); + } + #ifdef _DEBUG inline DWORD IsDestroyed() { @@ -1691,8 +1715,8 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! VMFLAG_HASCOCLASSATTRIB = 0x01000000, VMFLAG_COMEVENTITFMASK = 0x02000000, // class is a special COM event interface #endif // FEATURE_COMINTEROP - // unused = 0x04000000, - // unused = 0x08000000, + VMFLAG_VTABLEMETHODIMPL = 0x04000000, // class uses MethodImpl to override virtual function defined on class + VMFLAG_COVARIANTOVERRIDE = 0x08000000, // class has a covariant override // This one indicates that the fields of the valuetype are // not tightly packed and is used to check whether we can diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index 9c247d6284a0..72d01593b1fd 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -83,7 +83,7 @@ static_assert_no_msg((sizeof(DynamicMethodDesc) & MethodDesc::ALIGNMENT_MASK adjustment + sizeof(ComPlusCallMethodDesc), /* mcComInterOp */ \ adjustment + sizeof(DynamicMethodDesc) /* mcDynamic */ -const SIZE_T MethodDesc::s_ClassificationSizeTable[] = { +const BYTE MethodDesc::s_ClassificationSizeTable[] = { // This is the raw METHOD_DESC_SIZES(0), @@ -91,7 +91,24 @@ const SIZE_T MethodDesc::s_ClassificationSizeTable[] = { // We index using optional slot flags into it METHOD_DESC_SIZES(sizeof(NonVtableSlot)), METHOD_DESC_SIZES(sizeof(MethodImpl)), - METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(MethodImpl)) + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(MethodImpl)), + + METHOD_DESC_SIZES(sizeof(NativeCodeSlot)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(NativeCodeSlot)), + METHOD_DESC_SIZES(sizeof(MethodImpl) + sizeof(NativeCodeSlot)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(MethodImpl) + sizeof(NativeCodeSlot)), + +#ifdef FEATURE_COMINTEROP + METHOD_DESC_SIZES(sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(MethodImpl) + sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(MethodImpl) + sizeof(ComPlusCallInfo)), + + METHOD_DESC_SIZES(sizeof(NativeCodeSlot) + sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(NativeCodeSlot) + sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(MethodImpl) + sizeof(NativeCodeSlot) + sizeof(ComPlusCallInfo)), + METHOD_DESC_SIZES(sizeof(NonVtableSlot) + sizeof(MethodImpl) + sizeof(NativeCodeSlot) + sizeof(ComPlusCallInfo)) +#endif }; #ifndef FEATURE_COMINTEROP @@ -122,18 +139,22 @@ SIZE_T MethodDesc::SizeOf() { LIMITED_METHOD_DAC_CONTRACT; - SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot | mdcMethodImpl)]; + SIZE_T size = s_ClassificationSizeTable[m_wFlags & + (mdcClassification + | mdcHasNonVtableSlot + | mdcMethodImpl +#ifdef FEATURE_COMINTEROP + | mdcHasComPlusCallInfo +#endif + | mdcHasNativeCodeSlot)]; +#ifdef FEATURE_PREJIT if (HasNativeCodeSlot()) { - size += (*dac_cast(dac_cast(this) + size) & FIXUP_LIST_MASK) ? - (sizeof(NativeCodeSlot) + sizeof(FixupListSlot)) : sizeof(NativeCodeSlot); + size += (*dac_cast(GetAddrOfNativeCodeSlot()) & FIXUP_LIST_MASK) ? + sizeof(FixupListSlot) : 0; } - -#ifdef FEATURE_COMINTEROP - if (IsGenericComPlusCall()) - size += sizeof(ComPlusCallInfo); -#endif // FEATURE_COMINTEROP +#endif return size; } @@ -3696,11 +3717,11 @@ void MethodDesc::SaveChunk::SaveOneChunk(COUNT_T start, COUNT_T count, ULONG siz if (pMethodInfo->m_fHasNativeCodeSlot) { - pNewMD->m_bFlags2 |= enum_flag2_HasNativeCodeSlot; + pNewMD->m_wFlags |= mdcHasNativeCodeSlot; } else { - pNewMD->m_bFlags2 &= ~enum_flag2_HasNativeCodeSlot; + pNewMD->m_wFlags &= ~mdcHasNativeCodeSlot; } #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index 4103ec6e07e1..c19dcc73ddab 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -139,11 +139,18 @@ enum MethodDescClassification // where the function explicitly implements IInterface.foo() instead of foo(). mdcMethodImpl = 0x0010, - // Method is static - mdcStatic = 0x0020, + // Has slot for native code + mdcHasNativeCodeSlot = 0x0020, +#ifdef FEATURE_COMINTEROP + mdcHasComPlusCallInfo = 0x0040, +#else // unused = 0x0040, - // unused = 0x0080, +#endif + + // Method is static + mdcStatic = 0x0080, + // unused = 0x0100, // unused = 0x0200, @@ -1832,7 +1839,7 @@ class MethodDesc enum_flag2_HasPrecode = 0x02, // Precode has been allocated for this method enum_flag2_IsUnboxingStub = 0x04, - enum_flag2_HasNativeCodeSlot = 0x08, // Has slot for native code + // unused = 0x08, enum_flag2_IsJitIntrinsic = 0x10, // Jit may expand method as an intrinsic @@ -1881,13 +1888,13 @@ class MethodDesc inline BOOL HasNativeCodeSlot() { LIMITED_METHOD_DAC_CONTRACT; - return (m_bFlags2 & enum_flag2_HasNativeCodeSlot) != 0; + return (m_wFlags & mdcHasNativeCodeSlot) != 0; } inline void SetHasNativeCodeSlot() { LIMITED_METHOD_CONTRACT; - m_bFlags2 |= enum_flag2_HasNativeCodeSlot; + m_wFlags |= mdcHasNativeCodeSlot; } inline BOOL IsJitIntrinsic() @@ -1915,7 +1922,7 @@ class MethodDesc m_bFlags2 |= enum_flag2_RequiresCovariantReturnTypeChecking; } - static const SIZE_T s_ClassificationSizeTable[]; + static const BYTE s_ClassificationSizeTable[]; static SIZE_T GetBaseSize(DWORD classification) { @@ -3537,18 +3544,10 @@ class InstantiatedMethodDesc : public MethodDesc } #ifdef FEATURE_COMINTEROP - BOOL IMD_HasComPlusCallInfo() - { - LIMITED_METHOD_CONTRACT; - return ((m_wFlags2 & HasComPlusCallInfo) != 0); - } - void IMD_SetupGenericComPlusCall() { LIMITED_METHOD_CONTRACT; - m_wFlags2 |= InstantiatedMethodDesc::HasComPlusCallInfo; - IMD_GetComPlusCallInfo()->InitStackArgumentSize(); } @@ -3556,14 +3555,16 @@ class InstantiatedMethodDesc : public MethodDesc { LIMITED_METHOD_CONTRACT; - _ASSERTE(IMD_HasComPlusCallInfo()); - SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot | mdcMethodImpl)]; + _ASSERTE(IsGenericComPlusCall()); + SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot | mdcMethodImpl | mdcHasNativeCodeSlot)]; +#ifdef FEATURE_PREJIT if (HasNativeCodeSlot()) { - size += (*dac_cast(dac_cast(this) + size) & FIXUP_LIST_MASK) ? - (sizeof(NativeCodeSlot) + sizeof(FixupListSlot)) : sizeof(NativeCodeSlot); + size += (*dac_cast(GetAddrOfNativeCodeSlot()) & FIXUP_LIST_MASK) ? + sizeof(FixupListSlot) : 0; } +#endif return dac_cast(dac_cast(this) + size); } diff --git a/src/coreclr/src/vm/method.inl b/src/coreclr/src/vm/method.inl index d0d944d10e37..1175d2bd3aeb 100644 --- a/src/coreclr/src/vm/method.inl +++ b/src/coreclr/src/vm/method.inl @@ -133,11 +133,14 @@ inline BOOL MethodDesc::IsQCall() FORCEINLINE DWORD MethodDesc::IsGenericComPlusCall() { LIMITED_METHOD_CONTRACT; - return (mcInstantiated == GetClassification() && AsInstantiatedMethodDesc()->IMD_HasComPlusCallInfo()); + return m_wFlags & mdcHasComPlusCallInfo; } + inline void MethodDesc::SetupGenericComPlusCall() { LIMITED_METHOD_CONTRACT; + m_wFlags |= mdcHasComPlusCallInfo; + AsInstantiatedMethodDesc()->IMD_SetupGenericComPlusCall(); } #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 21976325935c..82a4b5003d2e 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -2410,6 +2410,7 @@ MethodTableBuilder::EnumerateMethodImpls() compatibleSignatures = TRUE; bmtMetaData->rgMethodImplTokens[i].fRequiresCovariantReturnTypeChecking = true; + bmtMetaData->fHasCovariantOverride = true; } } @@ -5589,6 +5590,19 @@ MethodTableBuilder::ProcessMethodImpls() { STANDARD_VM_CONTRACT; + if (bmtMetaData->fHasCovariantOverride) + { + GetHalfBakedClass()->SetHasCovariantOverride(); + } + if (GetParentMethodTable() != NULL) + { + EEClass* parentClass = GetParentMethodTable()->GetClass(); + if (parentClass->HasCovariantOverride()) + GetHalfBakedClass()->SetHasCovariantOverride(); + if (parentClass->HasVTableMethodImpl()) + GetHalfBakedClass()->SetHasVTableMethodImpl(); + } + if (bmtMethod->dwNumberMethodImpls == 0) return; @@ -5680,6 +5694,7 @@ MethodTableBuilder::ProcessMethodImpls() } Substitution *pDeclSubst = &bmtMetaData->pMethodDeclSubsts[m]; + MethodTable * pDeclMT = NULL; MethodSignature declSig(GetModule(), szName, pSig, cbSig, NULL); @@ -5784,6 +5799,7 @@ MethodTableBuilder::ProcessMethodImpls() } else { + GetHalfBakedClass()->SetHasVTableMethodImpl(); declMethod = FindDeclMethodOnClassInHierarchy(it, pDeclMT, declSig); } diff --git a/src/coreclr/src/vm/methodtablebuilder.h b/src/coreclr/src/vm/methodtablebuilder.h index 34a040c4530c..def6ab9d389e 100644 --- a/src/coreclr/src/vm/methodtablebuilder.h +++ b/src/coreclr/src/vm/methodtablebuilder.h @@ -2006,6 +2006,8 @@ class MethodTableBuilder MethodImplTokenPair *rgMethodImplTokens; Substitution *pMethodDeclSubsts; // Used to interpret generic variables in the interface of the declaring type + bool fHasCovariantOverride; + //----------------------------------------------------------------------------------------- inline bmtMetaDataInfo() { LIMITED_METHOD_CONTRACT; memset((void *)this, NULL, sizeof(*this)); } }; // struct bmtMetaDataInfo @@ -2282,10 +2284,11 @@ class MethodTableBuilder class DeclaredMethodIterator { private: - MethodTableBuilder &m_mtb; - int m_idx; // not SLOT_INDEX? + const int m_numDeclaredMethods; + bmtMDMethod ** const m_declaredMethods; + int m_idx; // not SLOT_INDEX? #ifdef _DEBUG - bmtMDMethod * m_debug_pMethod; + bmtMDMethod * m_debug_pMethod; #endif public: diff --git a/src/coreclr/src/vm/methodtablebuilder.inl b/src/coreclr/src/vm/methodtablebuilder.inl index 2d13e783fd51..78424be5d14f 100644 --- a/src/coreclr/src/vm/methodtablebuilder.inl +++ b/src/coreclr/src/vm/methodtablebuilder.inl @@ -15,7 +15,10 @@ //*************************************************************************************** inline MethodTableBuilder::DeclaredMethodIterator::DeclaredMethodIterator( - MethodTableBuilder &mtb) : m_mtb(mtb), m_idx(-1) + MethodTableBuilder &mtb) : + m_numDeclaredMethods((int)mtb.NumDeclaredMethods()), + m_declaredMethods(mtb.bmtMethod->m_rgDeclaredMethods), + m_idx(-1) { LIMITED_METHOD_CONTRACT; } @@ -24,7 +27,7 @@ inline MethodTableBuilder::DeclaredMethodIterator::DeclaredMethodIterator( inline int MethodTableBuilder::DeclaredMethodIterator::CurrentIndex() { LIMITED_METHOD_CONTRACT; - CONSISTENCY_CHECK_MSG(0 <= m_idx && m_idx < (int)m_mtb.NumDeclaredMethods(), + CONSISTENCY_CHECK_MSG(0 <= m_idx && m_idx < m_numDeclaredMethods, "Invalid iterator state."); return m_idx; } @@ -33,7 +36,7 @@ inline int MethodTableBuilder::DeclaredMethodIterator::CurrentIndex() inline BOOL MethodTableBuilder::DeclaredMethodIterator::Next() { LIMITED_METHOD_CONTRACT; - if (m_idx + 1 >= (int)m_mtb.NumDeclaredMethods()) + if (m_idx + 1 >= m_numDeclaredMethods) return FALSE; m_idx++; INDEBUG(m_debug_pMethod = GetMDMethod();) @@ -55,7 +58,7 @@ inline BOOL MethodTableBuilder::DeclaredMethodIterator::Prev() inline void MethodTableBuilder::DeclaredMethodIterator::ResetToEnd() { LIMITED_METHOD_CONTRACT; - m_idx = (int)m_mtb.NumDeclaredMethods(); + m_idx = m_numDeclaredMethods; } //*************************************************************************************** @@ -130,7 +133,7 @@ MethodTableBuilder::DeclaredMethodIterator::GetMDMethod() const { LIMITED_METHOD_CONTRACT; _ASSERTE(FitsIn(m_idx)); // Review: m_idx should probably _be_ a SLOT_INDEX, but that asserts. - return (*m_mtb.bmtMethod)[static_cast(m_idx)]; + return m_declaredMethods[m_idx]; } //******************************************************************************* diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index ba2906f385ea..61bbbb8d0593 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -1288,7 +1288,7 @@ TypeHandle SigPointer::GetTypeHandleThrowing( pGenericTypeModule = pModule; } - TypeHandle genericType = psig.GetGenericInstType(pModule, fLoadTypes, level, pZapSigContext); + TypeHandle genericType = psig.GetGenericInstType(pModule, fLoadTypes, level < CLASS_LOAD_APPROXPARENTS ? level : CLASS_LOAD_APPROXPARENTS, pZapSigContext); if (genericType.IsNull()) { From 84eeebbdd1bbb5daaf768553e6126cffe2dc7b14 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Sat, 25 Jul 2020 11:33:55 -0700 Subject: [PATCH 053/755] [Arm64] Don't generate hardware intrinsic method bodies (#39753) * Don't generate hardware intrinsic method bodies on Arm64 in zapinfo.cpp * Treat Vector64 and Vector128 methods as intrinsics on Arm64 in zapinfo.cpp --- src/coreclr/src/zap/zapinfo.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index 08c143dc0eb6..e997efa396b1 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -450,7 +450,7 @@ void ZapInfo::CompileMethod() } #endif -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) if (methodAttribs & CORINFO_FLG_JIT_INTRINSIC) { // Skip generating hardware intrinsic method bodies. @@ -2164,15 +2164,17 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF // is because they often change the code they emit based on what ISAs are supported by the compiler, // but we don't know what the target machine will support. // - // Additionally, we make sure none of the hardware intrinsic method bodies (except ARM64) get pregenerated in crossgen + // Additionally, we make sure none of the hardware intrinsic method bodies get pregenerated in crossgen // (see ZapInfo::CompileMethod) but get JITted instead. The JITted method will have the correct // answer for the CPU the code is running on. - // For Arm64, AdvSimd/ArmBase is the baseline that is suported and hence we do pregenerate the method bodies - // of ARM64 harware intrinsic. - fTreatAsRegularMethodCall = (fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic); -#if !defined(TARGET_ARM64) - fTreatAsRegularMethodCall |= (!fIsPlatformHWIntrinsic && fIsHWIntrinsic); + fTreatAsRegularMethodCall = fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic; + +#if defined(TARGET_ARM64) + // On Arm64 AdvSimd ISA is required by CoreCLR, so we can expand Vector64 and Vector128 methods. + fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic && (strcmp(className, "Vector64`1") != 0) && (strcmp(className, "Vector128`1") != 0); +#else + fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic; #endif if (fIsPlatformHWIntrinsic) From b77b242c39a7af9e1161ea1e5402912c2f032db0 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Sat, 25 Jul 2020 20:34:14 +0200 Subject: [PATCH 054/755] Fix CoreLib path resolution (#39921) Fixes issue described in https://github.com/dotnet/runtime/pull/39891#issuecomment-663767530. --- src/mono/wasm/wasm.targets | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mono/wasm/wasm.targets b/src/mono/wasm/wasm.targets index e3210dbc72e9..9934c9a845fe 100644 --- a/src/mono/wasm/wasm.targets +++ b/src/mono/wasm/wasm.targets @@ -20,13 +20,16 @@ - - - - + + + + + + + From 7b1b7b2640ff2bcbb4c455878ad357a1a3360660 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Sat, 25 Jul 2020 11:39:57 -0700 Subject: [PATCH 055/755] Remove unused locals in System.Numerics.Tensors (#39578) --- .../tests/TensorArithmetic.cs | 24 ------------------- .../tests/TensorOperations.cs | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs b/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs index f904c8adbe34..6dae2ec68542 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs @@ -1231,7 +1231,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -1426,7 +1425,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -2610,7 +2608,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -2805,7 +2802,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -3870,7 +3866,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -4065,7 +4060,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -4946,7 +4940,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -5141,7 +5134,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -6022,7 +6014,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -6217,7 +6208,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -7217,7 +7207,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -7412,7 +7401,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -8596,7 +8584,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -8791,7 +8778,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -9975,7 +9961,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -10170,7 +10155,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -11354,7 +11338,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -11549,7 +11532,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -12726,7 +12708,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -12921,7 +12902,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -14069,7 +14049,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -14264,7 +14243,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; @@ -15412,7 +15390,6 @@ public void Decrement(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]--; @@ -15607,7 +15584,6 @@ public void Increment(DenseTensor tensor, DenseTensor result) { var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; for (int i = 0; i < resultSpan.Length; i++) { resultSpan[i]++; diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs b/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs index 0502151e4455..009ad006b88c 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs @@ -286,7 +286,7 @@ internal static Tensor And(Tensor tensor, T scalar) internal static void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) { - var resultDimensions = ValidateContractArgs(left, right, leftAxes, rightAxes, result); + ValidateContractArgs(left, right, leftAxes, rightAxes, result); TensorArithmetic.Instance.Contract(left, right, leftAxes, rightAxes, result); } From f8e92ecfdd329d1f0c4a1ccc1ae494282d9a3050 Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Mon, 27 Jul 2020 00:56:57 +0800 Subject: [PATCH 056/755] Use consistent access modifiers in AsnValueReader.cs --- .../Security/Cryptography/Asn1Reader/AsnValueReader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs index 06ac95d7f733..6e22b91fb368 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs @@ -34,7 +34,7 @@ internal Asn1Tag PeekTag() return Asn1Tag.Decode(_span, out _); } - public ReadOnlySpan PeekEncodedValue() + internal ReadOnlySpan PeekEncodedValue() { AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed); return _span.Slice(0, consumed); @@ -183,14 +183,14 @@ internal DateTimeOffset ReadUtcTime(Asn1Tag? expectedTag = default) return ret; } - public DateTimeOffset ReadGeneralizedTime(Asn1Tag? expectedTag = default) + internal DateTimeOffset ReadGeneralizedTime(Asn1Tag? expectedTag = default) { DateTimeOffset ret = AsnDecoder.ReadGeneralizedTime(_span, _ruleSet, out int consumed, expectedTag); _span = _span.Slice(consumed); return ret; } - public string ReadCharacterString(UniversalTagNumber encodingType, Asn1Tag? expectedTag = default) + internal string ReadCharacterString(UniversalTagNumber encodingType, Asn1Tag? expectedTag = default) { string ret = AsnDecoder.ReadCharacterString(_span, _ruleSet, encodingType, out int consumed, expectedTag); _span = _span.Slice(consumed); From b19d7980c6a0e1f03312c8c2033fcbd13822378f Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Mon, 27 Jul 2020 04:38:15 +1000 Subject: [PATCH 057/755] Mark Assembly.CodeBase / Assembly.EscapedCodeBase as obsolete (#31127) (#39261) --- docs/project/list-of-obsoletions.md | 1 + .../Common/src/System/Obsoletions.cs | 3 + .../Hosting/AssemblyCatalogTests.cs | 6 ++ .../Design/DesigntimeLicenseContext.cs | 69 +++++++++---------- .../IO/IsolatedStorage/Helper.Win32Unix.cs | 2 + .../ref/System.Reflection.Emit.cs | 3 +- ...stem.Reflection.MetadataLoadContext.csproj | 1 + .../TypeLoading/Assemblies/RoAssembly.cs | 6 ++ .../Tests/RestrictedApis/RestrictedApis.cs | 2 + .../System.Reflection/tests/AssemblyTests.cs | 2 + .../System.Runtime/ref/System.Runtime.cs | 2 + 11 files changed, 59 insertions(+), 38 deletions(-) diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md index 3b7d6696c62d..35bae5551e4d 100644 --- a/docs/project/list-of-obsoletions.md +++ b/docs/project/list-of-obsoletions.md @@ -24,3 +24,4 @@ Currently the identifiers `SYSLIB0001` through `SYSLIB0999` are carved out for o | __`SYSLIB0009`__ | The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException. | | __`SYSLIB0010`__ | This Remoting API is not supported and throws PlatformNotSupportedException. | | __`SYSLIB0011`__ | `BinaryFormatter` serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for recommended alternatives. | +| __`SYSLIB0012`__ | Use Location instead. | diff --git a/src/libraries/Common/src/System/Obsoletions.cs b/src/libraries/Common/src/System/Obsoletions.cs index a7c5582f7bd8..6b08f78ce491 100644 --- a/src/libraries/Common/src/System/Obsoletions.cs +++ b/src/libraries/Common/src/System/Obsoletions.cs @@ -39,5 +39,8 @@ internal static class Obsoletions internal const string BinaryFormatterMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information."; internal const string BinaryFormatterDiagId = "SYSLIB0011"; + + internal const string CodeBaseMessage = "Use Location instead."; + internal const string CodeBaseDiagId = "SYSLIB0012"; } } diff --git a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs index c8d43e7b10f7..333dd8e473bb 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs +++ b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs @@ -36,10 +36,12 @@ public class TestAssemblyFour { } public class AssemblyCatalogTestsHelper { +#pragma warning disable SYSLIB0012 protected string GetAttributedAssemblyCodeBase() { return Assembly.GetExecutingAssembly().CodeBase; } +#pragma warning restore SYSLIB0012 protected Assembly GetAttributedAssembly() { @@ -74,7 +76,9 @@ internal static void Constructor_ValueAsCodebaseArgument_ShouldSetAssemblyProper foreach (var e in expectations) { +#pragma warning disable SYSLIB0012 var catalog = catalogCreator(e.CodeBase); +#pragma warning restore SYSLIB0012 Assert.Same(e, catalog.Assembly); } @@ -694,6 +698,7 @@ public void Constructor8_NullReflectionContextArgument_ShouldThrowArgumentNull() }); } +#pragma warning disable SYSLIB0012 [Fact] public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() { @@ -702,6 +707,7 @@ public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() return new AssemblyCatalog(GetAttributedAssembly().CodeBase, new AssemblyCatalogTestsReflectionContext(), dO); }); } +#pragma warning restore SYSLIB0012 //========================================================================================================================================= // Test cases for Assemblies decorated with the CatalogDiscoveryAttribute diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs index a8d5bb856e98..c650b38372f7 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs @@ -77,16 +77,12 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) // try everything. foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { - // Though, I could not repro this, we seem to be hitting an AssemblyBuilder - // when walking through all the assemblies in the current app domain. This throws an - // exception on Assembly.CodeBase and we bail out. Catching exceptions here is not a - // bad thing. - if (asm.IsDynamic) + // Assemblies loaded in memory return empty string from Location. + string location = asm.Location; + if (location == string.Empty) continue; - // file://fullpath/foo.exe - string fileName = GetLocalPath(asm.EscapedCodeBase); - fileName = new FileInfo(fileName).Name; + string fileName = new FileInfo(location).Name; Stream s = asm.GetManifestResourceStream(fileName + ".licenses"); if (s == null) @@ -103,44 +99,43 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) } } } - else if (!resourceAssembly.IsDynamic) + else { - // EscapedCodeBase won't be supported by emitted assemblies anyway - string fileName; - - fileName = GetLocalPath(resourceAssembly.EscapedCodeBase); - - fileName = Path.GetFileName(fileName); - string licResourceName = fileName + ".licenses"; - - // First try the filename - Stream s = resourceAssembly.GetManifestResourceStream(licResourceName); - if (s == null) + string location = resourceAssembly.Location; + if (location != string.Empty) { - string resolvedName = null; - CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo; - string shortAssemblyName = resourceAssembly.GetName().Name; - // If the assembly has been renamed, we try our best to find a good match in the available resources - // by looking at the assembly name (which doesn't change even after a file rename) + ".exe.licenses" or + ".dll.licenses" - foreach (string existingName in resourceAssembly.GetManifestResourceNames()) + string fileName = Path.GetFileName(location); + string licResourceName = fileName + ".licenses"; + + // First try the filename + Stream s = resourceAssembly.GetManifestResourceStream(licResourceName); + if (s == null) { - if (comparer.Compare(existingName, licResourceName, CompareOptions.IgnoreCase) == 0 || - comparer.Compare(existingName, shortAssemblyName + ".exe.licenses", CompareOptions.IgnoreCase) == 0 || - comparer.Compare(existingName, shortAssemblyName + ".dll.licenses", CompareOptions.IgnoreCase) == 0) + string resolvedName = null; + CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo; + string shortAssemblyName = resourceAssembly.GetName().Name; + // If the assembly has been renamed, we try our best to find a good match in the available resources + // by looking at the assembly name (which doesn't change even after a file rename) + ".exe.licenses" or + ".dll.licenses" + foreach (string existingName in resourceAssembly.GetManifestResourceNames()) { - resolvedName = existingName; - break; + if (comparer.Compare(existingName, licResourceName, CompareOptions.IgnoreCase) == 0 || + comparer.Compare(existingName, shortAssemblyName + ".exe.licenses", CompareOptions.IgnoreCase) == 0 || + comparer.Compare(existingName, shortAssemblyName + ".dll.licenses", CompareOptions.IgnoreCase) == 0) + { + resolvedName = existingName; + break; + } + } + if (resolvedName != null) + { + s = resourceAssembly.GetManifestResourceStream(resolvedName); } } - if (resolvedName != null) + if (s != null) { - s = resourceAssembly.GetManifestResourceStream(resolvedName); + DesigntimeLicenseContextSerializer.Deserialize(s, fileName.ToUpperInvariant(), this); } } - if (s != null) - { - DesigntimeLicenseContextSerializer.Deserialize(s, fileName.ToUpperInvariant(), this); - } } } return (string)_savedLicenseKeys[type.AssemblyQualifiedName]; diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs index 692ddc1d7766..33e611115fa2 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs @@ -54,7 +54,9 @@ internal static void GetDefaultIdentityAndHash(out object identity, out string h throw new IsolatedStorageException(SR.IsolatedStorage_Init); AssemblyName assemblyName = assembly.GetName(); +#pragma warning disable SYSLIB0012 Uri codeBase = new Uri(assembly.CodeBase!); +#pragma warning restore SYSLIB0012 hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!; if (hash != null) 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 2031b7df5495..f5b245a5cee0 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -9,10 +9,11 @@ namespace System.Reflection.Emit public sealed partial class AssemblyBuilder : System.Reflection.Assembly { internal AssemblyBuilder() { } + [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public override string? CodeBase { get { throw null; } } public override System.Reflection.MethodInfo? EntryPoint { get { throw null; } } public override string? FullName { get { throw null; } } - [Obsolete("The Global Assembly Cache is not supported.", DiagnosticId = "SYSLIB0005", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ObsoleteAttribute("The Global Assembly Cache is not supported.", DiagnosticId = "SYSLIB0005", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public override bool GlobalAssemblyCache { get { throw null; } } public override long HostContext { get { throw null; } } public override string ImageRuntimeVersion { get { throw null; } } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj index 7e70cb22fd65..7cee55064298 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj @@ -144,6 +144,7 @@ + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index b15e44645def..ca133f247c7d 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -41,7 +41,13 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // Location and codebase public abstract override string Location { get; } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); // Custom Attributes diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs index c8418c5c0715..f154f0987723 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs @@ -14,8 +14,10 @@ public static void TestRestrictions() { Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); +#pragma warning disable SYSLIB0012 Assert.Throws(() => a.CodeBase); Assert.Throws(() => a.EscapedCodeBase); +#pragma warning restore SYSLIB0012 Assert.Throws(() => a.GetObjectData(null, default)); Assert.Throws(() => a.GetSatelliteAssembly(null)); Assert.Throws(() => a.GetSatelliteAssembly(null, null)); diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index e4033244fd9b..8f7384f685f6 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -464,11 +464,13 @@ public void Location_ExecutingAssembly_IsNotNull() Assert.NotNull(Helpers.ExecutingAssembly.Location); } +#pragma warning disable SYSLIB0012 [Fact] public void CodeBase() { Assert.NotEmpty(Helpers.ExecutingAssembly.CodeBase); } +#pragma warning restore SYSLIB0012 [Fact] public void ImageRuntimeVersion() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 212f8aa9feb6..a4a16a66064e 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -7564,10 +7564,12 @@ public AmbiguousMatchException(string? message, System.Exception? inner) { } public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable { protected Assembly() { } + [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public virtual string? CodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable CustomAttributes { get { throw null; } } public virtual System.Collections.Generic.IEnumerable DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } } + [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public virtual string EscapedCodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual string? FullName { get { throw null; } } From 0b164711c4df050566e23a1d0e89a22c08a832bd Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sun, 26 Jul 2020 11:39:41 -0700 Subject: [PATCH 058/755] Disable Microsoft.Extensions.Caching.Memory.CapacityTests.DoNotAddIfSizeOverflows (#39930) Issue: https://github.com/dotnet/runtime/issues/33993, https://github.com/dotnet/runtime/issues/39241 --- .../Microsoft.Extensions.Caching.Memory/tests/CapacityTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CapacityTests.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CapacityTests.cs index 4ea5c20c7113..e4d5ef489356 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CapacityTests.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CapacityTests.cs @@ -110,6 +110,7 @@ public void DoNotAddEntryIfItExceedsCapacity() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/33993")] public async Task DoNotAddIfSizeOverflows() { var cache = new MemoryCache(new MemoryCacheOptions { SizeLimit = long.MaxValue }); From ae067cbd3e8eefc1767f44d442f1daebbf0a0df0 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sun, 26 Jul 2020 20:46:59 -0700 Subject: [PATCH 059/755] Disable processinfo for ilasm round-trip testing (#39936) Issue: https://github.com/dotnet/runtime/issues/39935 --- src/tests/tracing/eventpipe/processinfo/processinfo.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj index 6d5ae5ccf18d..69e7a9fba00c 100644 --- a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj @@ -7,6 +7,10 @@ 0 true true + + true From 042645e061bcb7f88e2c01b3040e8980a3c81575 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sun, 26 Jul 2020 20:47:32 -0700 Subject: [PATCH 060/755] Disable reverseouter test under GCStress (#39937) Issue: https://github.com/dotnet/runtime/issues/38801 --- src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj index 2c10c6ed4653..f417b3704d45 100644 --- a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj +++ b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj @@ -7,9 +7,11 @@ 0 true true + + true - \ No newline at end of file + From d7bfb8ca0fd5a50acc1164d114343449a3f2c108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Mon, 27 Jul 2020 08:58:01 +0200 Subject: [PATCH 061/755] Mark the multifolder GC2 test as GC stress incompatible until fixed (#39942) --- src/tests/readytorun/multifolder/multifolder.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/readytorun/multifolder/multifolder.csproj b/src/tests/readytorun/multifolder/multifolder.csproj index 9c81a0173f69..fc439c5be9ea 100644 --- a/src/tests/readytorun/multifolder/multifolder.csproj +++ b/src/tests/readytorun/multifolder/multifolder.csproj @@ -2,6 +2,7 @@ exe BuildAndRun + true false 0 From ea96ee3d86366ba21a5919101f64cc093a762fce Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 27 Jul 2020 12:09:50 +0300 Subject: [PATCH 062/755] Annotate System.Data.{Odbc,OleDb} for nullability (#39597) * Annotate System.Data.Odbc for nullability * Annotate System.Data.OleDb for nullability * Suppress nullable warnings on netcoreapp < 3.0 * Mark System.Data.DataSetExtensions as null-annotated * Fix null-check bug in System.Data.OleDb --- .../Common/src/Interop/Interop.Odbc.cs | 20 +- .../System/Data/Common/AdapterUtil.Drivers.cs | 2 +- .../src/System/Data/Common/AdapterUtil.cs | 37 ++- .../Data/Common/BasicFieldNameLookup.cs | 10 +- .../Data/Common/DbConnectionOptions.Common.cs | 7 +- .../System/Data/Common/DbConnectionPoolKey.cs | 9 +- .../src/System/Data/Common/FieldNameLookup.cs | 2 +- .../System/Data/Common/MultipartIdentifier.cs | 2 - .../src/System/Data/Common/NameValuePair.cs | 3 - .../Data/ProviderBase/DbConnectionClosed.cs | 12 +- .../Data/ProviderBase/DbConnectionFactory.cs | 69 ++--- .../Data/ProviderBase/DbConnectionInternal.cs | 34 ++- .../ProviderBase/DbConnectionPoolGroup.cs | 20 +- .../Data/ProviderBase/DbMetaDataFactory.cs | 101 +++--- .../ProviderBase/DbReferenceCollection.cs | 11 +- src/libraries/Directory.Build.targets | 2 +- .../ref/System.Data.Common.cs | 10 +- .../System/Data/Common/DBCommandBuilder.cs | 10 +- .../src/System/Data/Common/DbDataAdapter.cs | 16 +- .../System/Data/Common/RowUpdatedEventArgs.cs | 6 +- .../src/System/Data/ConstraintCollection.cs | 2 +- .../src/System/Data/DataRow.cs | 2 +- .../src/System/Data/DataTable.cs | 12 +- .../System/Data/ProviderBase/SchemaMapping.cs | 2 +- .../src/System/Data/RecordManager.cs | 2 +- .../src/System/Data/Select.cs | 2 +- .../ref/System.Data.DataSetExtensions.csproj | 1 + .../src/System.Data.DataSetExtensions.csproj | 1 + .../System.Data.Odbc/ref/System.Data.Odbc.cs | 108 +++---- .../ref/System.Data.Odbc.csproj | 3 +- .../System/Data/Common/AdapterUtil.Odbc.cs | 20 +- .../System/Data/Common/DBConnectionString.cs | 66 ++-- .../System/Data/Common/DbConnectionOptions.cs | 42 +-- .../Data/Common/DbConnectionStringCommon.cs | 4 +- .../System/Data/Common/NameValuePermission.cs | 46 +-- .../System/Data/ProviderBase/DbBuffer.cs | 6 +- .../Data/ProviderBase/DbConnectionFactory.cs | 15 +- .../Data/ProviderBase/DbConnectionInternal.cs | 4 +- .../Data/ProviderBase/DbConnectionPool.cs | 72 ++--- .../DbConnectionPoolGroupProviderInfo.cs | 4 +- .../ProviderBase/DbConnectionPoolIdentity.cs | 2 +- .../src/System.Data.Odbc.csproj | 1 + .../src/System/Data/Odbc/DbDataRecord.cs | 31 +- .../src/System/Data/Odbc/Odbc32.cs | 6 +- .../src/System/Data/Odbc/OdbcCommand.cs | 176 +++++------ .../System/Data/Odbc/OdbcCommandBuilder.cs | 20 +- .../src/System/Data/Odbc/OdbcConnection.cs | 81 ++--- .../System/Data/Odbc/OdbcConnectionFactory.cs | 36 +-- .../System/Data/Odbc/OdbcConnectionHelper.cs | 33 +- .../System/Data/Odbc/OdbcConnectionOpen.cs | 6 +- .../Odbc/OdbcConnectionPoolProviderInfo.cs | 12 +- .../System/Data/Odbc/OdbcConnectionString.cs | 4 +- .../Data/Odbc/OdbcConnectionStringbuilder.cs | 12 +- .../src/System/Data/Odbc/OdbcDataAdapter.cs | 50 +-- .../src/System/Data/Odbc/OdbcDataReader.cs | 288 +++++++++--------- .../src/System/Data/Odbc/OdbcEnvironment.cs | 8 +- .../src/System/Data/Odbc/OdbcError.cs | 4 +- .../System/Data/Odbc/OdbcErrorCollection.cs | 2 +- .../src/System/Data/Odbc/OdbcException.cs | 2 +- .../src/System/Data/Odbc/OdbcHandle.cs | 8 +- .../System/Data/Odbc/OdbcMetaDataFactory.cs | 145 +++++---- .../src/System/Data/Odbc/OdbcParameter.cs | 98 +++--- .../Data/Odbc/OdbcParameterCollection.cs | 14 +- .../Odbc/OdbcParameterCollectionHelper.cs | 6 +- .../System/Data/Odbc/OdbcParameterHelper.cs | 53 ++-- .../System/Data/Odbc/OdbcRowUpdatingEvent.cs | 12 +- .../System/Data/Odbc/OdbcStatementHandle.cs | 16 +- .../src/System/Data/Odbc/OdbcTransaction.cs | 22 +- .../ref/System.Data.OleDb.cs | 106 +++---- .../ref/System.Data.OleDb.csproj | 1 + .../System.Data.OleDb/src/AdapterSwitches.cs | 4 +- .../System.Data.OleDb/src/ColumnBinding.cs | 41 +-- .../System.Data.OleDb/src/DbBindings.cs | 30 +- .../src/DbConnectionOptions.cs | 73 ++--- .../src/DbConnectionStringCommon.cs | 5 +- .../src/DbParameterHelper.cs | 32 +- .../System.Data.OleDb/src/DbPropSet.cs | 12 +- .../System.Data.OleDb/src/NativeMethods.cs | 2 +- .../System.Data.OleDb/src/OleDbCommand.cs | 176 +++++------ .../src/OleDbCommandBuilder.cs | 48 ++- .../System.Data.OleDb/src/OleDbConnection.cs | 88 +++--- .../src/OleDbConnectionFactory.cs | 35 +-- .../src/OleDbConnectionInternal.cs | 107 +++---- .../OleDbConnectionPoolGroupProviderInfo.cs | 6 +- .../src/OleDbConnectionString.cs | 62 ++-- .../src/OleDbConnectionStringBuilder.cs | 57 ++-- .../System.Data.OleDb/src/OleDbDataAdapter.cs | 76 ++--- .../System.Data.OleDb/src/OleDbDataReader.cs | 284 ++++++++--------- .../System.Data.OleDb/src/OleDbEnumerator.cs | 12 +- .../System.Data.OleDb/src/OleDbError.cs | 14 +- .../src/OleDbErrorCollection.cs | 6 +- .../System.Data.OleDb/src/OleDbException.cs | 12 +- .../src/OleDbInfoMessageEvent.cs | 2 +- .../src/OleDbMetaDataFactory.cs | 80 ++--- .../System.Data.OleDb/src/OleDbParameter.cs | 80 ++--- .../src/OleDbParameterCollection.cs | 10 +- .../src/OleDbParameterCollectionHelper.cs | 6 +- .../src/OleDbRowUpdatedEvent.cs | 6 +- .../src/OleDbRowUpdatingEvent.cs | 6 +- .../System.Data.OleDb/src/OleDbStruct.cs | 38 +-- .../System.Data.OleDb/src/OleDbTransaction.cs | 24 +- .../System.Data.OleDb/src/OleDbWrapper.cs | 54 ++-- .../System.Data.OleDb/src/OleDb_Enum.cs | 6 +- .../System.Data.OleDb/src/OleDb_Util.cs | 14 +- .../System.Data.OleDb/src/PropertyInfoSet.cs | 18 +- .../System.Data.OleDb/src/RowBinding.cs | 18 +- .../System.Data.OleDb/src/SafeHandles.cs | 12 +- .../src/System.Data.OleDb.csproj | 1 + .../src/System/Data/Common/AdapterUtil.cs | 65 ++-- .../System/Data/Common/DbConnectionPoolKey.cs | 10 +- .../src/System/Data/Common/FieldNameLookup.cs | 12 +- .../src/System/Data/Common/NameValuePair.cs | 10 +- .../src/System/Data/Common/SR.cs | 2 +- .../src/System/Data/ProviderBase/DbBuffer.cs | 2 +- .../Data/ProviderBase/DbConnectionClosed.cs | 12 +- .../Data/ProviderBase/DbConnectionFactory.cs | 64 ++-- .../Data/ProviderBase/DbConnectionHelper.cs | 38 +-- .../DbConnectionInternal.Shared.cs | 66 ++-- .../Data/ProviderBase/DbConnectionInternal.cs | 12 +- .../Data/ProviderBase/DbConnectionPool.cs | 90 +++--- .../ProviderBase/DbConnectionPoolCounters.cs | 38 +-- .../ProviderBase/DbConnectionPoolGroup.cs | 20 +- .../DbConnectionPoolGroupProviderInfo.cs | 4 +- .../ProviderBase/DbConnectionPoolIdentity.cs | 2 +- .../Data/ProviderBase/DbMetaDataFactory.cs | 104 +++---- .../ProviderBase/DbReferenceCollection.cs | 10 +- .../Data/ProviderBase/WrappedIUnknown.cs | 4 +- .../src/UnsafeNativeMethods.cs | 16 +- 128 files changed, 2104 insertions(+), 2086 deletions(-) diff --git a/src/libraries/Common/src/Interop/Interop.Odbc.cs b/src/libraries/Common/src/Interop/Interop.Odbc.cs index 591ce1cadeb3..4113c59e4fef 100644 --- a/src/libraries/Common/src/Interop/Interop.Odbc.cs +++ b/src/libraries/Common/src/Interop/Interop.Odbc.cs @@ -250,9 +250,9 @@ internal static partial class Odbc [DllImport(Interop.Libraries.Odbc32, CharSet = CharSet.Unicode)] internal static extern /*SQLRETURN*/ODBC32.RetCode SQLPrimaryKeysW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, - /*SQLCHAR* */string CatalogName, + /*SQLCHAR* */string? CatalogName, /*SQLSMALLINT*/short NameLen1, - /*SQLCHAR* */ string SchemaName, + /*SQLCHAR* */ string? SchemaName, /*SQLSMALLINT*/short NameLen2, /*SQLCHAR* */string TableName, /*SQLSMALLINT*/short NameLen3); @@ -260,13 +260,13 @@ internal static partial class Odbc [DllImport(Interop.Libraries.Odbc32, CharSet = CharSet.Unicode)] internal static extern /*SQLRETURN*/ODBC32.RetCode SQLProcedureColumnsW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, - /*SQLCHAR* */ string CatalogName, + /*SQLCHAR* */ string? CatalogName, /*SQLSMALLINT*/short NameLen1, - /*SQLCHAR* */ string SchemaName, + /*SQLCHAR* */ string? SchemaName, /*SQLSMALLINT*/short NameLen2, - /*SQLCHAR* */ string ProcName, + /*SQLCHAR* */ string? ProcName, /*SQLSMALLINT*/short NameLen3, - /*SQLCHAR* */ string ColumnName, + /*SQLCHAR* */ string? ColumnName, /*SQLSMALLINT*/short NameLen4); [DllImport(Interop.Libraries.Odbc32, CharSet = CharSet.Unicode)] @@ -347,9 +347,9 @@ internal static partial class Odbc internal static extern /*SQLRETURN*/ODBC32.RetCode SQLSpecialColumnsW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/ODBC32.SQL_SPECIALCOLS IdentifierType, - /*SQLCHAR* */string CatalogName, + /*SQLCHAR* */string? CatalogName, /*SQLSMALLINT*/short NameLen1, - /*SQLCHAR* */string SchemaName, + /*SQLCHAR* */string? SchemaName, /*SQLSMALLINT*/short NameLen2, /*SQLCHAR* */string TableName, /*SQLSMALLINT*/short NameLen3, @@ -359,9 +359,9 @@ internal static partial class Odbc [DllImport(Interop.Libraries.Odbc32, CharSet = CharSet.Unicode)] internal static extern /*SQLRETURN*/ODBC32.RetCode SQLStatisticsW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, - /*SQLCHAR* */string CatalogName, + /*SQLCHAR* */string? CatalogName, /*SQLSMALLINT*/short NameLen1, - /*SQLCHAR* */string SchemaName, + /*SQLCHAR* */string? SchemaName, /*SQLSMALLINT*/short NameLen2, /*SQLCHAR* */IntPtr TableName, // IntPtr instead of string because callee may mutate contents /*SQLSMALLINT*/short NameLen3, diff --git a/src/libraries/Common/src/System/Data/Common/AdapterUtil.Drivers.cs b/src/libraries/Common/src/System/Data/Common/AdapterUtil.Drivers.cs index 509aa984661e..4ee63ade204c 100644 --- a/src/libraries/Common/src/System/Data/Common/AdapterUtil.Drivers.cs +++ b/src/libraries/Common/src/System/Data/Common/AdapterUtil.Drivers.cs @@ -8,7 +8,7 @@ namespace System.Data.Common internal static partial class ADP { - internal static Timer UnsafeCreateTimer(TimerCallback callback, object state, int dueTime, int period) + internal static Timer UnsafeCreateTimer(TimerCallback callback, object? state, int dueTime, int period) { // Don't capture the current ExecutionContext and its AsyncLocals onto // a global timer causing them to live forever diff --git a/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs b/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs index c61589b75e5b..3675641903c3 100644 --- a/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs +++ b/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs @@ -1,13 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: Enable nullability as part of annotation System.Data.{Odbc,OleDb} -#nullable disable -#pragma warning disable CS8632 - using System.Collections; using System.Data.SqlTypes; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.CompilerServices; using System.Security; @@ -22,11 +19,11 @@ internal static partial class ADP { // NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (https://docs.microsoft.com/en-us/dotnet/framework/performance/sql-server-programming-and-host-protection-attributes) // Therefore we are lazily initializing these Tasks to avoid forcing customers to use the "UNSAFE" set when they are actually using no Async features - private static Task _trueTask; - internal static Task TrueTask => _trueTask ?? (_trueTask = Task.FromResult(true)); + private static Task? _trueTask; + internal static Task TrueTask => _trueTask ??= Task.FromResult(true); - private static Task _falseTask; - internal static Task FalseTask => _falseTask ?? (_falseTask = Task.FromResult(false)); + private static Task? _falseTask; + internal static Task FalseTask => _falseTask ??= Task.FromResult(false); internal const CompareOptions DefaultCompareOptions = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase; internal const int DefaultConnectionTimeout = DbConnectionStringDefaults.ConnectTimeout; @@ -51,14 +48,14 @@ internal static ArgumentException Argument(string error) return e; } - internal static ArgumentException Argument(string error, Exception inner) + internal static ArgumentException Argument(string error, Exception? inner) { ArgumentException e = new ArgumentException(error, inner); TraceExceptionAsReturnValue(e); return e; } - internal static ArgumentException Argument(string error, string parameter) + internal static ArgumentException Argument(string error, string? parameter) { ArgumentException e = new ArgumentException(error, parameter); TraceExceptionAsReturnValue(e); @@ -105,7 +102,7 @@ internal static InvalidCastException InvalidCast(string error) return InvalidCast(error, null); } - internal static InvalidCastException InvalidCast(string error, Exception inner) + internal static InvalidCastException InvalidCast(string error, Exception? inner) { InvalidCastException e = new InvalidCastException(error, inner); TraceExceptionAsReturnValue(e); @@ -135,7 +132,7 @@ internal static NotSupportedException NotSupported(string error) // the return value is true if the string was quoted and false if it was not // this allows the caller to determine if it is an error or not for the quotedString to not be quoted - internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, string quotedString, out string unquotedString) + internal static bool RemoveStringQuotes(string? quotePrefix, string? quoteSuffix, string? quotedString, out string? unquotedString) { int prefixLength = quotePrefix != null ? quotePrefix.Length : 0; int suffixLength = quoteSuffix != null ? quoteSuffix.Length : 0; @@ -164,7 +161,7 @@ internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, // is the prefix present? if (prefixLength > 0) { - if (!quotedString.StartsWith(quotePrefix, StringComparison.Ordinal)) + if (!quotedString.StartsWith(quotePrefix!, StringComparison.Ordinal)) { unquotedString = quotedString; return false; @@ -174,7 +171,7 @@ internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, // is the suffix present? if (suffixLength > 0) { - if (!quotedString.EndsWith(quoteSuffix, StringComparison.Ordinal)) + if (!quotedString.EndsWith(quoteSuffix!, StringComparison.Ordinal)) { unquotedString = quotedString; return false; @@ -224,7 +221,7 @@ internal static ArgumentException InvalidMultipartNameToManyParts(string propert return e; } - internal static void CheckArgumentNull(object value, string parameterName) + internal static void CheckArgumentNull([NotNull] object? value, string parameterName) { if (null == value) { @@ -290,7 +287,7 @@ internal static ArgumentException KeywordNotSupported(string keyword) { return Argument(SR.Format(SR.ADP_KeywordNotSupported, keyword)); } - internal static ArgumentException ConvertFailed(Type fromType, Type toType, Exception innerException) + internal static ArgumentException ConvertFailed(Type fromType, Type toType, Exception? innerException) { return ADP.Argument(SR.Format(SR.SqlConvert_ConvertFailed, fromType.FullName, toType.FullName), innerException); } @@ -302,7 +299,7 @@ internal static Exception InvalidConnectionOptionValue(string key) { return InvalidConnectionOptionValue(key, null); } - internal static Exception InvalidConnectionOptionValue(string key, Exception inner) + internal static Exception InvalidConnectionOptionValue(string key, Exception? inner) { return Argument(SR.Format(SR.ADP_InvalidConnectionOptionValue, key), inner); } @@ -480,15 +477,15 @@ internal static bool CompareInsensitiveInvariant(string? strvalue, string? strco internal static int DstCompare(string strA, string strB) => CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, ADP.DefaultCompareOptions); - internal static bool IsEmptyArray(string[] array) => (null == array) || (0 == array.Length); + internal static bool IsEmptyArray([NotNullWhen(false)] string?[]? array) => (null == array) || (0 == array.Length); - internal static bool IsNull(object value) + internal static bool IsNull(object? value) { if ((null == value) || (DBNull.Value == value)) { return true; } - INullable nullable = (value as INullable); + INullable? nullable = (value as INullable); return ((null != nullable) && nullable.IsNull); } diff --git a/src/libraries/Common/src/System/Data/Common/BasicFieldNameLookup.cs b/src/libraries/Common/src/System/Data/Common/BasicFieldNameLookup.cs index 4415ef3b8212..fbe4a2c7355e 100644 --- a/src/libraries/Common/src/System/Data/Common/BasicFieldNameLookup.cs +++ b/src/libraries/Common/src/System/Data/Common/BasicFieldNameLookup.cs @@ -11,13 +11,13 @@ namespace System.Data.ProviderBase internal class BasicFieldNameLookup { // Dictionary stores the index into the _fieldNames, match via case-sensitive - private Dictionary _fieldNameLookup; + private Dictionary? _fieldNameLookup; // original names for linear searches when exact matches fail private readonly string[] _fieldNames; // By default _compareInfo is set to InvariantCulture CompareInfo - private CompareInfo _compareInfo; + private CompareInfo? _compareInfo; public BasicFieldNameLookup(string[] fieldNames) { @@ -74,7 +74,7 @@ public int IndexOfName(string fieldName) int value; // via case sensitive search, first match with lowest ordinal matches - return _fieldNameLookup.TryGetValue(fieldName, out value) ? value : -1; + return _fieldNameLookup!.TryGetValue(fieldName, out value) ? value : -1; } public int IndexOf(string fieldName) @@ -85,7 +85,7 @@ public int IndexOf(string fieldName) } int index; // via case sensitive search, first match with lowest ordinal matches - if (!_fieldNameLookup.TryGetValue(fieldName, out index)) + if (!_fieldNameLookup!.TryGetValue(fieldName, out index)) { // via case insensitive search, first match with lowest ordinal matches index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase); @@ -116,7 +116,7 @@ private int LinearIndexOf(string fieldName, CompareOptions compareOptions) { if (0 == _compareInfo.Compare(fieldName, _fieldNames[i], compareOptions)) { - _fieldNameLookup[fieldName] = i; // add an exact match for the future + _fieldNameLookup![fieldName] = i; // add an exact match for the future return i; } } diff --git a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs index 83f6b892b689..fda8cc871d91 100644 --- a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs +++ b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: Remove this after System.Data.{Odbc,OleDb} are null-annotated -#nullable disable -#pragma warning disable CS8632 - using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -416,8 +412,7 @@ private static bool IsValueValidInternal(string? keyvalue) return true; } - // TODO: Annotate with [NotNullWhen(true)] when annotating System.Data.{Odbc,OleDb} - private static bool IsKeyNameValid(string? keyname) + private static bool IsKeyNameValid([NotNullWhen(true)] string? keyname) { if (null != keyname) { diff --git a/src/libraries/Common/src/System/Data/Common/DbConnectionPoolKey.cs b/src/libraries/Common/src/System/Data/Common/DbConnectionPoolKey.cs index a2cd4661611b..6c5a567cf7ad 100644 --- a/src/libraries/Common/src/System/Data/Common/DbConnectionPoolKey.cs +++ b/src/libraries/Common/src/System/Data/Common/DbConnectionPoolKey.cs @@ -1,18 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: Remove this after System.Data.{Odbc,OleDb} are null-annotated -#pragma warning disable CS8632 - namespace System.Data.Common { // DbConnectionPoolKey: Base class implementation of a key to connection pool groups // Only connection string is used as a key internal class DbConnectionPoolKey : ICloneable { - private string _connectionString; + private string? _connectionString; - internal DbConnectionPoolKey(string connectionString) + internal DbConnectionPoolKey(string? connectionString) { _connectionString = connectionString; } @@ -27,7 +24,7 @@ public virtual object Clone() return new DbConnectionPoolKey(this); } - internal virtual string ConnectionString + internal virtual string? ConnectionString { get { diff --git a/src/libraries/Common/src/System/Data/Common/FieldNameLookup.cs b/src/libraries/Common/src/System/Data/Common/FieldNameLookup.cs index 8e66d67458d6..7f5ab2cd9afb 100644 --- a/src/libraries/Common/src/System/Data/Common/FieldNameLookup.cs +++ b/src/libraries/Common/src/System/Data/Common/FieldNameLookup.cs @@ -33,7 +33,7 @@ public FieldNameLookup(IDataReader reader, int defaultLocaleID) : base(reader) //The compare info is specified by the server by specifying the default LocaleId. protected override CompareInfo GetCompareInfo() { - CompareInfo compareInfo = null; + CompareInfo? compareInfo = null; if (-1 != _defaultLocaleID) { compareInfo = CompareInfo.GetCompareInfo(_defaultLocaleID); diff --git a/src/libraries/Common/src/System/Data/Common/MultipartIdentifier.cs b/src/libraries/Common/src/System/Data/Common/MultipartIdentifier.cs index 3338928bda1f..0aaca592d071 100644 --- a/src/libraries/Common/src/System/Data/Common/MultipartIdentifier.cs +++ b/src/libraries/Common/src/System/Data/Common/MultipartIdentifier.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. -// TODO: Remove this after System.Data.{Odbc,OleDb} are null-annotated -#pragma warning disable CS8632 //------------------------------------------------------------------------------ using System.Text; diff --git a/src/libraries/Common/src/System/Data/Common/NameValuePair.cs b/src/libraries/Common/src/System/Data/Common/NameValuePair.cs index 435b998ef33b..09ec22615fca 100644 --- a/src/libraries/Common/src/System/Data/Common/NameValuePair.cs +++ b/src/libraries/Common/src/System/Data/Common/NameValuePair.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: Remove this after System.Data.{Odbc,OleDb} are null-annotated -#pragma warning disable CS8632 - using System.Diagnostics; namespace System.Data.Common diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionClosed.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionClosed.cs index 11cc51501e28..3a7844763225 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionClosed.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionClosed.cs @@ -27,12 +27,12 @@ internal override void CloseConnection(DbConnection owningObject, DbConnectionFa protected override void Deactivate() => ADP.ClosedConnectionError(); - protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) + protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string?[]? restrictions) => throw ADP.ClosedConnectionError(); protected override DbReferenceCollection CreateReferenceCollection() => throw ADP.ClosedConnectionError(); - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) => base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions); } @@ -42,7 +42,7 @@ protected DbConnectionBusy(ConnectionState state) : base(state, true, false) { } - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) => throw ADP.ConnectionAlreadyOpen(State); } @@ -81,10 +81,10 @@ internal override void CloseConnection(DbConnection owningObject, DbConnectionFa connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance); } - internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions); - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { if (retry == null || !retry.Task.IsCompleted) { @@ -131,7 +131,7 @@ private DbConnectionClosedPreviouslyOpened() : base(ConnectionState.Closed, true { } - internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions); } } diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionFactory.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionFactory.cs index 832006da95ca..5418b4ff8bba 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionFactory.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; @@ -22,8 +23,8 @@ internal abstract partial class DbConnectionFactory // s_pendingOpenNonPooled is an array of tasks used to throttle creation of non-pooled connections to // a maximum of Environment.ProcessorCount at a time. private static uint s_pendingOpenNonPooledNext; - private static readonly Task[] s_pendingOpenNonPooled = new Task[Environment.ProcessorCount]; - private static Task s_completedTask; + private static readonly Task[] s_pendingOpenNonPooled = new Task[Environment.ProcessorCount]; + private static Task? s_completedTask; protected DbConnectionFactory() { @@ -57,7 +58,7 @@ public void ClearPool(DbConnection connection) { ADP.CheckArgumentNull(connection, nameof(connection)); - DbConnectionPoolGroup poolGroup = GetConnectionPoolGroup(connection); + DbConnectionPoolGroup? poolGroup = GetConnectionPoolGroup(connection); if (null != poolGroup) { poolGroup.Clear(); @@ -69,7 +70,7 @@ public void ClearPool(DbConnectionPoolKey key) Debug.Assert(key != null, "key cannot be null"); ADP.CheckArgumentNull(key.ConnectionString, nameof(key) + "." + nameof(key.ConnectionString)); - DbConnectionPoolGroup poolGroup; + DbConnectionPoolGroup? poolGroup; Dictionary connectionPoolGroups = _connectionPoolGroups; if (connectionPoolGroups.TryGetValue(key, out poolGroup)) { @@ -77,22 +78,22 @@ public void ClearPool(DbConnectionPoolKey key) } } - internal virtual DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions) + internal virtual DbConnectionPoolProviderInfo? CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions) { return null; } - internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) + internal DbConnectionInternal? CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions? userOptions) { Debug.Assert(null != owningConnection, "null owningConnection?"); Debug.Assert(null != poolGroup, "null poolGroup?"); DbConnectionOptions connectionOptions = poolGroup.ConnectionOptions; - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo; + DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo!; DbConnectionPoolKey poolKey = poolGroup.PoolKey; - DbConnectionInternal newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions); + DbConnectionInternal? newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions); if (null != newConnection) { newConnection.MakeNonPooledObject(owningConnection); @@ -100,12 +101,12 @@ internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConne return newConnection; } - internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) + internal DbConnectionInternal? CreatePooledConnection(DbConnectionPool pool, DbConnection? owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions? userOptions) { Debug.Assert(null != pool, "null pool?"); - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo; + DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo!; - DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); + DbConnectionInternal? newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) { newConnection.MakePooledConnection(pool); @@ -113,7 +114,7 @@ internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbCo return newConnection; } - internal virtual DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions) + internal virtual DbConnectionPoolGroupProviderInfo? CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions) { return null; } @@ -125,12 +126,12 @@ private Timer CreatePruningTimer() => PruningDueTime, PruningPeriod); - protected DbConnectionOptions FindConnectionOptions(DbConnectionPoolKey key) + protected DbConnectionOptions? FindConnectionOptions(DbConnectionPoolKey key) { Debug.Assert(key != null, "key cannot be null"); if (!string.IsNullOrEmpty(key.ConnectionString)) { - DbConnectionPoolGroup connectionPoolGroup; + DbConnectionPoolGroup? connectionPoolGroup; Dictionary connectionPoolGroups = _connectionPoolGroups; if (connectionPoolGroups.TryGetValue(key, out connectionPoolGroup)) { @@ -140,13 +141,13 @@ protected DbConnectionOptions FindConnectionOptions(DbConnectionPoolKey key) return null; } - private static Task GetCompletedTask() + private static Task GetCompletedTask() { Debug.Assert(Monitor.IsEntered(s_pendingOpenNonPooled), $"Expected {nameof(s_pendingOpenNonPooled)} lock to be held."); - return s_completedTask ?? (s_completedTask = Task.FromResult(null)); + return s_completedTask ?? (s_completedTask = Task.FromResult(null)); } - private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup) + private DbConnectionPool? GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup) { // if poolgroup is disabled, it will be replaced with a new entry @@ -165,28 +166,28 @@ private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnecti if (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions)) { // reusing existing pool option in case user originally used SetConnectionPoolOptions - DbConnectionPoolGroupOptions poolOptions = connectionPoolGroup.PoolGroupOptions; + DbConnectionPoolGroupOptions? poolOptions = connectionPoolGroup.PoolGroupOptions; // get the string to hash on again - DbConnectionOptions connectionOptions = connectionPoolGroup.ConnectionOptions; + DbConnectionOptions? connectionOptions = connectionPoolGroup.ConnectionOptions; Debug.Assert(null != connectionOptions, "prevent expansion of connectionString"); - connectionPoolGroup = GetConnectionPoolGroup(connectionPoolGroup.PoolKey, poolOptions, ref connectionOptions); + connectionPoolGroup = GetConnectionPoolGroup(connectionPoolGroup.PoolKey, poolOptions, ref connectionOptions)!; Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup?"); SetConnectionPoolGroup(owningObject, connectionPoolGroup); } - DbConnectionPool connectionPool = connectionPoolGroup.GetConnectionPool(this); + DbConnectionPool? connectionPool = connectionPoolGroup.GetConnectionPool(this); return connectionPool; } - internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions) + internal DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions? poolOptions, ref DbConnectionOptions? userConnectionOptions) { if (string.IsNullOrEmpty(key.ConnectionString)) { - return (DbConnectionPoolGroup)null; + return null; } - DbConnectionPoolGroup connectionPoolGroup; + DbConnectionPoolGroup? connectionPoolGroup; Dictionary connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions))) { @@ -194,7 +195,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, D // our collection of pool entries, then we need to create a // new pool entry and add it to our collection. - DbConnectionOptions connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions); + DbConnectionOptions? connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions); if (null == connectionOptions) { throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing); @@ -225,7 +226,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, D connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup)) { - DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions); + DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions!); newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions); // build new dictionary with space for new connection string @@ -256,7 +257,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, D } - private void PruneConnectionPoolGroups(object state) + private void PruneConnectionPoolGroups(object? state) { // First, walk the pool release list and attempt to clear each // pool, when the pool is finally empty, we dispose of it. If the @@ -368,7 +369,7 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup) } } - protected virtual DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) + protected virtual DbConnectionInternal? CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningConnection, DbConnectionOptions? userOptions) { return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection); } @@ -379,7 +380,7 @@ internal DbMetaDataFactory GetMetaDataFactory(DbConnectionPoolGroup connectionPo // get the matadatafactory from the pool entry. If it does not already have one // create one and save it on the pool entry - DbMetaDataFactory metaDataFactory = connectionPoolGroup.MetaDataFactory; + DbMetaDataFactory? metaDataFactory = connectionPoolGroup.MetaDataFactory; // consider serializing this so we don't construct multiple metadata factories // if two threads happen to hit this at the same time. One will be GC'd @@ -403,15 +404,15 @@ protected virtual DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal i throw ADP.NotSupported(); } - protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection); + protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningConnection); - protected abstract DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous); + protected abstract DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions? previous); - protected abstract DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions options); + protected abstract DbConnectionPoolGroupOptions? CreateConnectionPoolGroupOptions(DbConnectionOptions options); - internal abstract DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection); + internal abstract DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnection connection); - internal abstract DbConnectionInternal GetInnerConnection(DbConnection connection); + internal abstract DbConnectionInternal? GetInnerConnection(DbConnection connection); internal abstract void PermissionDemand(DbConnection outerConnection); diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionInternal.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionInternal.cs index 4afa5d32351d..5c1c4c0034cd 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionInternal.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionInternal.cs @@ -21,8 +21,8 @@ internal abstract partial class DbConnectionInternal private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections) - private DbConnectionPool _connectionPool; // the pooler that the connection came from (Pooled connections only) - private DbReferenceCollection _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated + private DbConnectionPool? _connectionPool; // the pooler that the connection came from (Pooled connections only) + private DbReferenceCollection? _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated private int _pooledCount; // [usage must be thread safe] the number of times this object has been pushed into the pool less the number of times it's been popped (0 != inPool) private bool _connectionIsDoomed; // true when the connection should no longer be used. @@ -113,17 +113,17 @@ internal bool IsInPool } - protected internal object Owner + protected internal object? Owner { // We use a weak reference to the owning object so we can identify when - // it has been garbage collected without thowing exceptions. + // it has been garbage collected without throwing exceptions. get { return _owningObject.Target; } } - internal DbConnectionPool Pool + internal DbConnectionPool? Pool { get { @@ -131,7 +131,7 @@ internal DbConnectionPool Pool } } - protected internal DbReferenceCollection ReferenceCollection + protected internal DbReferenceCollection? ReferenceCollection { get { @@ -199,12 +199,12 @@ protected virtual void PrepareForCloseConnection() // By default, there is no preparation required } - protected virtual object ObtainAdditionalLocksForClose() + protected virtual object? ObtainAdditionalLocksForClose() { return null; // no additional locks in default implementation } - protected virtual void ReleaseAdditionalLocksForClose(object lockToken) + protected virtual void ReleaseAdditionalLocksForClose(object? lockToken) { // no additional locks in default implementation } @@ -218,6 +218,8 @@ protected virtual DbReferenceCollection CreateReferenceCollection() internal void DeactivateConnection() { + Debug.Assert(Pool != null); + // Internal method called from the connection pooler so we don't expose // the Deactivate method publicly. @@ -251,7 +253,7 @@ protected internal void DoomThisConnection() _connectionIsDoomed = true; } - protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) + protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string?[]? restrictions) { Debug.Assert(outerConnection != null, "outerConnection may not be null."); @@ -282,7 +284,7 @@ internal void MakePooledConnection(DbConnectionPool connectionPool) internal void NotifyWeakReference(int message) { - DbReferenceCollection referenceCollection = ReferenceCollection; + DbReferenceCollection? referenceCollection = ReferenceCollection; if (null != referenceCollection) { referenceCollection.Notify(message); @@ -302,22 +304,22 @@ internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionF /// override this and do the correct thing. // User code should either override DbConnectionInternal.Activate when it comes out of the pool // or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections - internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { throw ADP.ConnectionAlreadyOpen(State); } - internal virtual bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal virtual bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { throw ADP.MethodNotImplemented(); } - protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { // ?->Connecting: prevent set_ConnectionString during Open if (connectionFactory.SetInnerConnectionFrom(outerConnection, DbConnectionClosedConnecting.SingletonInstance, this)) { - DbConnectionInternal openConnection = null; + DbConnectionInternal? openConnection = null; try { connectionFactory.PermissionDemand(outerConnection); @@ -343,7 +345,7 @@ protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnect return true; } - internal void PrePush(object expectedOwner) + internal void PrePush(object? expectedOwner) { // Called by DbConnectionPool when we're about to be put into it's pool, we // take this opportunity to ensure ownership and pool counts are legit. @@ -412,7 +414,7 @@ internal void PostPop(object newOwner) internal void RemoveWeakReference(object value) { - DbReferenceCollection referenceCollection = ReferenceCollection; + DbReferenceCollection? referenceCollection = ReferenceCollection; if (null != referenceCollection) { referenceCollection.Remove(value); diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs index eb0f8ed4f154..26ee3b6515dd 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs @@ -34,8 +34,8 @@ internal sealed class DbConnectionPoolGroup private int _state; // see PoolGroupState* below - private DbConnectionPoolGroupProviderInfo _providerInfo; - private DbMetaDataFactory _metaDataFactory; + private DbConnectionPoolGroupProviderInfo? _providerInfo; + private DbMetaDataFactory? _metaDataFactory; // always lock this before changing _state, we don't want to move out of the 'Disabled' state // PoolGroupStateUninitialized = 0; @@ -63,7 +63,7 @@ internal DbConnectionPoolGroup(DbConnectionOptions connectionOptions, DbConnecti internal DbConnectionPoolKey PoolKey => _poolKey; - internal DbConnectionPoolGroupProviderInfo ProviderInfo + internal DbConnectionPoolGroupProviderInfo? ProviderInfo { get { @@ -74,7 +74,7 @@ internal DbConnectionPoolGroupProviderInfo ProviderInfo _providerInfo = value; if (null != value) { - _providerInfo.PoolGroup = this; + _providerInfo!.PoolGroup = this; } } } @@ -83,7 +83,7 @@ internal DbConnectionPoolGroupProviderInfo ProviderInfo internal DbConnectionPoolGroupOptions PoolGroupOptions => _poolGroupOptions; - internal DbMetaDataFactory MetaDataFactory + internal DbMetaDataFactory? MetaDataFactory { get { @@ -102,7 +102,7 @@ internal int Clear() // will return the number of connections in the group after clearing has finished // First, note the old collection and create a new collection to be used - ConcurrentDictionary oldPoolCollection = null; + ConcurrentDictionary? oldPoolCollection = null; lock (this) { if (_poolCollection.Count > 0) @@ -130,7 +130,7 @@ internal int Clear() return _poolCollection.Count; } - internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory) + internal DbConnectionPool? GetConnectionPool(DbConnectionFactory connectionFactory) { // When this method returns null it indicates that the connection // factory should not use pooling. @@ -138,10 +138,10 @@ internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactor // We don't support connection pooling on Win9x; // PoolGroupOptions will only be null when we're not supposed to pool // connections. - DbConnectionPool pool = null; + DbConnectionPool? pool = null; if (null != _poolGroupOptions) { - DbConnectionPoolIdentity currentIdentity = DbConnectionPoolIdentity.NoIdentity; + DbConnectionPoolIdentity? currentIdentity = DbConnectionPoolIdentity.NoIdentity; if (_poolGroupOptions.PoolByIdentity) { @@ -168,7 +168,7 @@ internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactor // Did someone already add it to the list? if (!_poolCollection.TryGetValue(currentIdentity, out pool)) { - DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions); + DbConnectionPoolProviderInfo? connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions); DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity, connectionPoolProviderInfo); if (MarkPoolGroupAsActive()) diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbMetaDataFactory.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbMetaDataFactory.cs index 614b11c7710d..3a12fa546dfa 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbMetaDataFactory.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbMetaDataFactory.cs @@ -37,7 +37,8 @@ public DbMetaDataFactory(Stream xmlStream, string serverVersion, string normaliz ADP.CheckArgumentNull(serverVersion, nameof(serverVersion)); ADP.CheckArgumentNull(normalizedServerVersion, nameof(normalizedServerVersion)); - LoadDataSetFromXml(xmlStream); + _metaDataCollectionsDataSet = new DataSet { Locale = CultureInfo.InvariantCulture }; + _metaDataCollectionsDataSet.ReadXml(xmlStream); _serverVersionString = serverVersion; _normalizedServerVersion = normalizedServerVersion; @@ -49,14 +50,14 @@ public DbMetaDataFactory(Stream xmlStream, string serverVersion, string normaliz protected string ServerVersionNormalized => _normalizedServerVersion; - protected DataTable CloneAndFilterCollection(string collectionName, string[] hiddenColumnNames) + protected DataTable CloneAndFilterCollection(string collectionName, string[]? hiddenColumnNames) { DataTable destinationTable; DataColumn[] filteredSourceColumns; DataColumnCollection destinationColumns; DataRow newRow; - DataTable sourceTable = _metaDataCollectionsDataSet.Tables[collectionName]; + DataTable? sourceTable = _metaDataCollectionsDataSet.Tables[collectionName]; if ((sourceTable == null) || (collectionName != sourceTable.TableName)) { @@ -94,27 +95,27 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - _normalizedServerVersion = null; - _serverVersionString = null; + _normalizedServerVersion = null!; + _serverVersionString = null!; _metaDataCollectionsDataSet.Dispose(); } } - private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restrictions, DbConnection connection) + private DataTable ExecuteCommand(DataRow requestedCollectionRow, string?[]? restrictions, DbConnection connection) { - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; - DataColumn populationStringColumn = metaDataCollectionsTable.Columns[_populationString]; - DataColumn numberOfRestrictionsColumn = metaDataCollectionsTable.Columns[_numberOfRestrictions]; - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[_collectionName]; + DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!; + DataColumn populationStringColumn = metaDataCollectionsTable.Columns[_populationString]!; + DataColumn numberOfRestrictionsColumn = metaDataCollectionsTable.Columns[_numberOfRestrictions]!; + DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[_collectionName]!; - DataTable resultTable = null; - DbCommand command = null; - DataTable schemaTable = null; + DataTable? resultTable = null; + DbCommand? command = null; + DataTable? schemaTable = null; Debug.Assert(requestedCollectionRow != null); - string sqlCommand = requestedCollectionRow[populationStringColumn, DataRowVersion.Current] as string; + string sqlCommand = (requestedCollectionRow[populationStringColumn, DataRowVersion.Current] as string)!; int numberOfRestrictions = (int)requestedCollectionRow[numberOfRestrictionsColumn, DataRowVersion.Current]; - string collectionName = requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string; + string collectionName = (requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string)!; if ((restrictions != null) && (restrictions.Length > numberOfRestrictions)) { @@ -145,7 +146,7 @@ private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restri command.Parameters.Add(restrictionParameter); } - DbDataReader reader = null; + DbDataReader? reader = null; try { try @@ -190,7 +191,7 @@ private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restri return resultTable; } - private DataColumn[] FilterColumns(DataTable sourceTable, string[] hiddenColumnNames, DataColumnCollection destinationColumns) + private DataColumn[] FilterColumns(DataTable sourceTable, string[]? hiddenColumnNames, DataColumnCollection destinationColumns) { int columnCount = 0; foreach (DataColumn sourceColumn in sourceTable.Columns) @@ -227,23 +228,23 @@ internal DataRow FindMetaDataCollectionRow(string collectionName) bool versionFailure; bool haveExactMatch; bool haveMultipleInexactMatches; - string candidateCollectionName; + string? candidateCollectionName; - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; + DataTable? metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; if (metaDataCollectionsTable == null) { throw ADP.InvalidXml(); } - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; + DataColumn? collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; if ((null == collectionNameColumn) || (typeof(string) != collectionNameColumn.DataType)) { throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, DbMetaDataColumnNames.CollectionName); } - DataRow requestedCollectionRow = null; - string exactCollectionName = null; + DataRow? requestedCollectionRow = null; + string? exactCollectionName = null; // find the requested collection versionFailure = false; @@ -316,8 +317,8 @@ internal DataRow FindMetaDataCollectionRow(string collectionName) private void FixUpVersion(DataTable dataSourceInfoTable) { Debug.Assert(dataSourceInfoTable.TableName == DbMetaDataCollectionNames.DataSourceInformation); - DataColumn versionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersion]; - DataColumn normalizedVersionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersionNormalized]; + DataColumn? versionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersion]; + DataColumn? normalizedVersionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersionNormalized]; if ((versionColumn == null) || (normalizedVersionColumn == null)) { @@ -340,14 +341,14 @@ private void FixUpVersion(DataTable dataSourceInfoTable) private string GetParameterName(string neededCollectionName, int neededRestrictionNumber) { - DataTable restrictionsTable = null; - DataColumnCollection restrictionColumns = null; - DataColumn collectionName = null; - DataColumn parameterName = null; - DataColumn restrictionName = null; - DataColumn restrictionNumber = null; + DataTable? restrictionsTable = null; + DataColumnCollection? restrictionColumns = null; + DataColumn? collectionName = null; + DataColumn? parameterName = null; + DataColumn? restrictionName = null; + DataColumn? restrictionNumber = null; - string result = null; + string? result = null; restrictionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; if (restrictionsTable != null) @@ -367,7 +368,7 @@ private string GetParameterName(string neededCollectionName, int neededRestricti throw ADP.MissingRestrictionColumn(); } - foreach (DataRow restriction in restrictionsTable.Rows) + foreach (DataRow restriction in restrictionsTable!.Rows) { if (((string)restriction[collectionName] == neededCollectionName) && @@ -388,27 +389,27 @@ private string GetParameterName(string neededCollectionName, int neededRestricti return result; } - public virtual DataTable GetSchema(DbConnection connection, string collectionName, string[] restrictions) + public virtual DataTable GetSchema(DbConnection connection, string collectionName, string?[]? restrictions) { Debug.Assert(_metaDataCollectionsDataSet != null); - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; - DataColumn populationMechanismColumn = metaDataCollectionsTable.Columns[_populationMechanism]; - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; - DataRow requestedCollectionRow = null; - DataTable requestedSchema = null; - string[] hiddenColumns; - string exactCollectionName = null; + DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!; + DataColumn populationMechanismColumn = metaDataCollectionsTable.Columns[_populationMechanism]!; + DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]!; + DataRow? requestedCollectionRow = null; + DataTable? requestedSchema = null; + string[]? hiddenColumns; + string? exactCollectionName = null; requestedCollectionRow = FindMetaDataCollectionRow(collectionName); - exactCollectionName = requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string; + exactCollectionName = (requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string)!; if (ADP.IsEmptyArray(restrictions) == false) { for (int i = 0; i < restrictions.Length; i++) { - if ((restrictions[i] != null) && (restrictions[i].Length > 4096)) + if ((restrictions[i]?.Length > 4096)) { // use a non-specific error because no new beta 2 error messages are allowed // TODO: will add a more descriptive error in RTM @@ -417,10 +418,9 @@ public virtual DataTable GetSchema(DbConnection connection, string collectionNam } } - string populationMechanism = requestedCollectionRow[populationMechanismColumn, DataRowVersion.Current] as string; + string populationMechanism = (requestedCollectionRow[populationMechanismColumn, DataRowVersion.Current] as string)!; switch (populationMechanism) { - case _dataTable: if (exactCollectionName == DbMetaDataCollectionNames.MetaDataCollections) { @@ -466,7 +466,7 @@ public virtual DataTable GetSchema(DbConnection connection, string collectionNam return requestedSchema; } - private bool IncludeThisColumn(DataColumn sourceColumn, string[] hiddenColumnNames) + private bool IncludeThisColumn(DataColumn sourceColumn, string[]? hiddenColumnNames) { bool result = true; @@ -499,14 +499,7 @@ private bool IncludeThisColumn(DataColumn sourceColumn, string[] hiddenColumnNam return result; } - private void LoadDataSetFromXml(Stream XmlStream) - { - _metaDataCollectionsDataSet = new DataSet(); - _metaDataCollectionsDataSet.Locale = System.Globalization.CultureInfo.InvariantCulture; - _metaDataCollectionsDataSet.ReadXml(XmlStream); - } - - protected virtual DataTable PrepareCollection(string collectionName, string[] restrictions, DbConnection connection) + protected virtual DataTable PrepareCollection(string collectionName, string?[]? restrictions, DbConnection connection) { throw ADP.NotSupported(); } @@ -515,7 +508,7 @@ private bool SupportedByCurrentVersion(DataRow requestedCollectionRow) { bool result = true; DataColumnCollection tableColumns = requestedCollectionRow.Table.Columns; - DataColumn versionColumn; + DataColumn? versionColumn; object version; // check the minimum version first diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs index b13b20ca26e7..1ccde6673ebc 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs @@ -6,6 +6,7 @@ //------------------------------------------------------------------------------ using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading; namespace System.Data.ProviderBase @@ -55,7 +56,7 @@ public int Tag } } - public object Target + public object? Target { get { @@ -136,6 +137,7 @@ protected void AddItem(object value, int tag) } } + [return: MaybeNull] internal T FindItem(int tag, Func filterMethod) where T : class { bool lockObtained = false; @@ -154,12 +156,11 @@ internal T FindItem(int tag, Func filterMethod) where T : class { // NOTE: Check if the returned value is null twice may seem wasteful, but this if for performance // Since checking for null twice is cheaper than calling both HasTarget and Target OR always attempting to typecast - object value = _items[counter].Target; + object? value = _items[counter].Target; if (value != null) { // Make sure the item has the correct type and passes the filtering - T tempItem = value as T; - if ((tempItem != null) && (filterMethod(tempItem))) + if (value is T tempItem && filterMethod(tempItem)) { return tempItem; } @@ -195,7 +196,7 @@ public void Notify(int message) { for (int index = 0; index <= _lastItemIndex; ++index) { - object value = _items[index].Target; // checks tag & gets target + object? value = _items[index].Target; // checks tag & gets target if (null != value) { NotifyItem(message, _items[index].Tag, value); diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 7fdfb48f2a97..95dae2669d8e 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -3,7 +3,7 @@ - $(NoWarn);nullable + $(NoWarn);nullable $(NoWarn);nullable diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index 5d70fda61ec0..a2f519c8c897 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -2079,8 +2079,8 @@ protected DbDataAdapter(System.Data.Common.DbDataAdapter adapter) { } public System.Data.Common.DbCommand? UpdateCommand { get { throw null; } set { } } protected virtual int AddToBatch(System.Data.IDbCommand command) { throw null; } protected virtual void ClearBatch() { } - protected virtual System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } - protected virtual System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + protected virtual System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + protected virtual System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } protected override void Dispose(bool disposing) { } protected virtual int ExecuteBatch() { throw null; } public override int Fill(System.Data.DataSet dataSet) { throw null; } @@ -2462,8 +2462,8 @@ public enum IdentifierCase } public partial class RowUpdatedEventArgs : System.EventArgs { - public RowUpdatedEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { } - public System.Data.IDbCommand Command { get { throw null; } } + public RowUpdatedEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { } + public System.Data.IDbCommand? Command { get { throw null; } } public System.Exception? Errors { get { throw null; } set { } } public int RecordsAffected { get { throw null; } } public System.Data.DataRow Row { get { throw null; } } @@ -2476,7 +2476,7 @@ public void CopyToRows(System.Data.DataRow[] array, int arrayIndex) { } } public partial class RowUpdatingEventArgs : System.EventArgs { - public RowUpdatingEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { } + public RowUpdatingEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { } protected virtual System.Data.IDbCommand? BaseCommand { get { throw null; } set { } } public System.Data.IDbCommand? Command { get { throw null; } set { } } public System.Exception? Errors { get { throw null; } set { } } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs index 72a5d8d51dad..3fe1c1af3b6a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs @@ -169,15 +169,15 @@ private void ApplyProviderSpecificFormat() { for (int i = 0; i < _baseParameterNames.Length; i++) { - if (_baseParameterNames[i] is { } baseParameterName) + if (_baseParameterNames[i] is string baseParameterName) { _baseParameterNames[i] = _dbCommandBuilder.GetParameterName(baseParameterName); } - if (_originalParameterNames[i] is { } originalParameterName) + if (_originalParameterNames[i] is string originalParameterName) { _originalParameterNames[i] = _dbCommandBuilder.GetParameterName(originalParameterName); } - if (_nullParameterNames[i] is { } nullParameterName) + if (_nullParameterNames[i] is string nullParameterName) { _nullParameterNames[i] = _dbCommandBuilder.GetParameterName(nullParameterName); } @@ -228,7 +228,7 @@ internal void GenerateMissingNames(DbSchemaRow?[] schemaRows) _baseParameterNames[i] = GetNextGenericParameterName(); _originalParameterNames[i] = GetNextGenericParameterName(); // don't bother generating an 'IsNull' name if it's not used - if (schemaRows[i] is { } schemaRow && schemaRow.AllowDBNull) + if (schemaRows[i] is DbSchemaRow schemaRow && schemaRow.AllowDBNull) { _nullParameterNames[i] = GetNextGenericParameterName(); } @@ -633,7 +633,7 @@ private void BuildCache(bool closeConnection, DataRow? dataRow, bool useColumnsF string[] srcColumnNames = new string[schemaRows.Length]; for (int i = 0; i < schemaRows.Length; ++i) { - if (schemaRows[i] is { } schemaRow) + if (schemaRows[i] is DbSchemaRow schemaRow) { srcColumnNames[i] = schemaRow.ColumnName; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataAdapter.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataAdapter.cs index e86beec59344..b1e417ec7d14 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataAdapter.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataAdapter.cs @@ -254,12 +254,12 @@ private void CloneFrom(DbDataAdapter from) return (IDbCommand?)((command is ICloneable) ? ((ICloneable)command).Clone() : null); } - protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new RowUpdatedEventArgs(dataRow, command, statementType, tableMapping); } - protected virtual RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected virtual RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new RowUpdatingEventArgs(dataRow, command, statementType, tableMapping); } @@ -1035,7 +1035,7 @@ protected virtual int Update(DataRow[] dataRows, DataTableMapping tableMapping) // TODO: the event may be raised with a null command, but only if the update, but only if // the update attempt fails (because no command was configured). We should not emit the // event in this case. - RowUpdatingEventArgs? rowUpdatingEvent = CreateRowUpdatingEvent(dataRow, dataCommand!, statementType, tableMapping); + RowUpdatingEventArgs? rowUpdatingEvent = CreateRowUpdatingEvent(dataRow, dataCommand, statementType, tableMapping); // this try/catch for any exceptions during the parameter initialization try @@ -1159,7 +1159,7 @@ protected virtual int Update(DataRow[] dataRows, DataTableMapping tableMapping) if (null != errors) { // TODO: See above comment on dataCommand being null - rowUpdatedEvent = CreateRowUpdatedEvent(dataRow, dataCommand!, StatementType.Batch, tableMapping); + rowUpdatedEvent = CreateRowUpdatedEvent(dataRow, dataCommand, StatementType.Batch, tableMapping); rowUpdatedEvent.Errors = errors; rowUpdatedEvent.Status = UpdateStatus.ErrorsOccurred; @@ -1182,7 +1182,7 @@ protected virtual int Update(DataRow[] dataRows, DataTableMapping tableMapping) } // TODO: See above comment on dataCommand being null - rowUpdatedEvent = CreateRowUpdatedEvent(dataRow, dataCommand!, statementType, tableMapping); + rowUpdatedEvent = CreateRowUpdatedEvent(dataRow, dataCommand, statementType, tableMapping); // this try/catch for any exceptions during the execution, population, output parameters try @@ -1280,8 +1280,8 @@ protected virtual int Update(DataRow[] dataRows, DataTableMapping tableMapping) if (1 != maxBatchCommands && 0 < commandCount) { // TODO: See above comment on dataCommand being null - // TODO: DataRow is null because we call AdapterInit below, which populars rows - RowUpdatedEventArgs rowUpdatedEvent = CreateRowUpdatedEvent(null!, dataCommand!, statementType, tableMapping); + // TODO: DataRow is null because we call AdapterInit below, which populates rows + RowUpdatedEventArgs rowUpdatedEvent = CreateRowUpdatedEvent(null!, dataCommand, statementType, tableMapping); try { @@ -1659,7 +1659,7 @@ private int UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCom DataRow row = batchCommands[i]._row; Debug.Assert(null != row, "null dataRow?"); - if (batchCommands[i]._errors is { } commandErrors) + if (batchCommands[i]._errors is Exception commandErrors) { // will exist if 0 == RecordsAffected string rowMsg = commandErrors.Message; if (string.IsNullOrEmpty(rowMsg)) diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/RowUpdatedEventArgs.cs b/src/libraries/System.Data.Common/src/System/Data/Common/RowUpdatedEventArgs.cs index a2ef4bf0ced6..261a68ad56cc 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/RowUpdatedEventArgs.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/RowUpdatedEventArgs.cs @@ -9,7 +9,7 @@ namespace System.Data.Common public class RowUpdatedEventArgs : EventArgs { - private readonly IDbCommand _command; + private readonly IDbCommand? _command; private StatementType _statementType; private readonly DataTableMapping _tableMapping; private Exception? _errors; @@ -20,7 +20,7 @@ public class RowUpdatedEventArgs : EventArgs private UpdateStatus _status; // UpdateStatus.Continue; /*0*/ private int _recordsAffected; - public RowUpdatedEventArgs(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + public RowUpdatedEventArgs(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { switch (statementType) { @@ -39,7 +39,7 @@ public RowUpdatedEventArgs(DataRow dataRow, IDbCommand command, StatementType st _tableMapping = tableMapping; } - public IDbCommand Command + public IDbCommand? Command { get { diff --git a/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs b/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs index 806bab3e90b0..aabcde99fe03 100644 --- a/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs +++ b/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs @@ -87,7 +87,7 @@ internal void Add(Constraint constraint, bool addUniqueWhenAddingForeign) } // It is an error if we find an equivalent constraint already in collection - if (FindConstraint(constraint) is { } matchedConstraint) + if (FindConstraint(constraint) is Constraint matchedConstraint) { throw ExceptionBuilder.DuplicateConstraint(matchedConstraint.ConstraintName); } diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRow.cs b/src/libraries/System.Data.Common/src/System/Data/DataRow.cs index 084cbd242f48..1a1c4d70f2b7 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRow.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRow.cs @@ -450,7 +450,7 @@ public object?[] ItemArray for (int i = 0; i < value.Length; ++i) { // Empty means don't change the row. - if (value[i] is { } item) + if (value[i] is object item) { // may throw exception if user removes column from table during event DataColumn column = _columns[i]; diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs index 851ac8900f70..ff8af676e92c 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs @@ -2431,8 +2431,8 @@ private DataTable CloneTo(DataTable clone, DataSet? cloneDS, bool skipExpression { if (foreign.Table == foreign.RelatedTable) { - if (foreign.Clone(clone) is { } clonedConstraint && - clone.Constraints.FindConstraint(clonedConstraint) is { } oldConstraint) + if (foreign.Clone(clone) is ForeignKeyConstraint clonedConstraint && + clone.Constraints.FindConstraint(clonedConstraint) is Constraint oldConstraint) { oldConstraint.ConstraintName = Constraints[j].ConstraintName; } @@ -2440,8 +2440,8 @@ private DataTable CloneTo(DataTable clone, DataSet? cloneDS, bool skipExpression } else if (unique != null) { - if (unique.Clone(clone) is { } clonedConstraint && - clone.Constraints.FindConstraint(clonedConstraint) is { } oldConstraint) + if (unique.Clone(clone) is UniqueConstraint clonedConstraint && + clone.Constraints.FindConstraint(clonedConstraint) is Constraint oldConstraint) { oldConstraint.ConstraintName = Constraints[j].ConstraintName; foreach (object key in clonedConstraint.ExtendedProperties.Keys) @@ -2462,7 +2462,7 @@ private DataTable CloneTo(DataTable clone, DataSet? cloneDS, bool skipExpression if (foreign != null) { if (foreign.Table == foreign.RelatedTable && - foreign.Clone(clone) is { } newforeign) + foreign.Clone(clone) is ForeignKeyConstraint newforeign) { // we cant make sure that we recieve a cloned FKC,since it depends if table and relatedtable be the same clone.Constraints.Add(newforeign); @@ -3375,7 +3375,7 @@ internal int NewRecordFromArray(object?[] value) { for (int i = 0; i < value.Length; i++) { - if (value[i] is { } v) + if (value[i] is object v) { _columnCollection[i][record] = v; } diff --git a/src/libraries/System.Data.Common/src/System/Data/ProviderBase/SchemaMapping.cs b/src/libraries/System.Data.Common/src/System/Data/ProviderBase/SchemaMapping.cs index 1fedea0de8b3..849908991e48 100644 --- a/src/libraries/System.Data.Common/src/System/Data/ProviderBase/SchemaMapping.cs +++ b/src/libraries/System.Data.Common/src/System/Data/ProviderBase/SchemaMapping.cs @@ -217,7 +217,7 @@ internal void ApplyToDataRow(DataRow dataRow) for (int i = 0; i < mapped.Length; ++i) { - if (mapped[i] is { } m) + if (mapped[i] is object m) { dataRow[i] = m; } diff --git a/src/libraries/System.Data.Common/src/System/Data/RecordManager.cs b/src/libraries/System.Data.Common/src/System/Data/RecordManager.cs index daa5cc158b14..dfffcc6e52c2 100644 --- a/src/libraries/System.Data.Common/src/System/Data/RecordManager.cs +++ b/src/libraries/System.Data.Common/src/System/Data/RecordManager.cs @@ -168,7 +168,7 @@ internal void Clear(bool clearAll) _freeRecordList.Capacity = _freeRecordList.Count + _table.Rows.Count; for (int record = 0; record < _recordCapacity; ++record) { - if (_rows[record] is { } row && row.rowID != -1) + if (_rows[record] is DataRow row && row.rowID != -1) { int tempRecord = record; FreeRecord(ref tempRecord); diff --git a/src/libraries/System.Data.Common/src/System/Data/Select.cs b/src/libraries/System.Data.Common/src/System/Data/Select.cs index 8dbd298e1bca..97fbb80c7b08 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Select.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Select.cs @@ -491,7 +491,7 @@ private void BuildLinearExpression() { if (!_candidateColumns[i].flag) { - if (_candidateColumns[i].expr is { } expr) + if (_candidateColumns[i].expr is BinaryNode expr) { _linearExpression = (_linearExpression == null ? _candidateColumns[i].expr : new BinaryNode(_table, Operators.And, expr, _linearExpression)); } diff --git a/src/libraries/System.Data.DataSetExtensions/ref/System.Data.DataSetExtensions.csproj b/src/libraries/System.Data.DataSetExtensions/ref/System.Data.DataSetExtensions.csproj index 08914f651d1b..d1d4624ffde4 100644 --- a/src/libraries/System.Data.DataSetExtensions/ref/System.Data.DataSetExtensions.csproj +++ b/src/libraries/System.Data.DataSetExtensions/ref/System.Data.DataSetExtensions.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent) + enable diff --git a/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj b/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj index e777c148ed64..3dd6d9ffcab9 100644 --- a/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj +++ b/src/libraries/System.Data.DataSetExtensions/src/System.Data.DataSetExtensions.csproj @@ -2,6 +2,7 @@ $(NetCoreAppCurrent) true + enable diff --git a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs index d755e6d29560..934b48caba6e 100644 --- a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs +++ b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs @@ -9,17 +9,18 @@ namespace System.Data.Odbc public sealed partial class OdbcCommand : System.Data.Common.DbCommand, System.ICloneable { public OdbcCommand() { } - public OdbcCommand(string cmdText) { } - public OdbcCommand(string cmdText, System.Data.Odbc.OdbcConnection connection) { } - public OdbcCommand(string cmdText, System.Data.Odbc.OdbcConnection connection, System.Data.Odbc.OdbcTransaction transaction) { } + public OdbcCommand(string? cmdText) { } + public OdbcCommand(string? cmdText, System.Data.Odbc.OdbcConnection? connection) { } + public OdbcCommand(string? cmdText, System.Data.Odbc.OdbcConnection? connection, System.Data.Odbc.OdbcTransaction? transaction) { } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string CommandText { get { throw null; } set { } } public override int CommandTimeout { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(System.Data.CommandType.Text)] public override System.Data.CommandType CommandType { get { throw null; } set { } } - public new System.Data.Odbc.OdbcConnection Connection { get { throw null; } set { } } - protected override System.Data.Common.DbConnection DbConnection { get { throw null; } set { } } + public new System.Data.Odbc.OdbcConnection? Connection { get { throw null; } set { } } + protected override System.Data.Common.DbConnection? DbConnection { get { throw null; } set { } } protected override System.Data.Common.DbParameterCollection DbParameterCollection { get { throw null; } } - protected override System.Data.Common.DbTransaction DbTransaction { get { throw null; } set { } } + protected override System.Data.Common.DbTransaction? DbTransaction { get { throw null; } set { } } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DefaultValueAttribute(true)] [System.ComponentModel.DesignOnlyAttribute(true)] @@ -29,7 +30,7 @@ public OdbcCommand(string cmdText, System.Data.Odbc.OdbcConnection connection, S public new System.Data.Odbc.OdbcParameterCollection Parameters { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] - public new System.Data.Odbc.OdbcTransaction Transaction { get { throw null; } set { } } + public new System.Data.Odbc.OdbcTransaction? Transaction { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(System.Data.UpdateRowSource.Both)] public override System.Data.UpdateRowSource UpdatedRowSource { get { throw null; } set { } } public override void Cancel() { } @@ -40,7 +41,7 @@ protected override void Dispose(bool disposing) { } public override int ExecuteNonQuery() { throw null; } public new System.Data.Odbc.OdbcDataReader ExecuteReader() { throw null; } public new System.Data.Odbc.OdbcDataReader ExecuteReader(System.Data.CommandBehavior behavior) { throw null; } - public override object ExecuteScalar() { throw null; } + public override object? ExecuteScalar() { throw null; } public override void Prepare() { } public void ResetCommandTimeout() { } object System.ICloneable.Clone() { throw null; } @@ -48,8 +49,8 @@ public void ResetCommandTimeout() { } public sealed partial class OdbcCommandBuilder : System.Data.Common.DbCommandBuilder { public OdbcCommandBuilder() { } - public OdbcCommandBuilder(System.Data.Odbc.OdbcDataAdapter adapter) { } - public new System.Data.Odbc.OdbcDataAdapter DataAdapter { get { throw null; } set { } } + public OdbcCommandBuilder(System.Data.Odbc.OdbcDataAdapter? adapter) { } + public new System.Data.Odbc.OdbcDataAdapter? DataAdapter { get { throw null; } set { } } protected override void ApplyParameterInfo(System.Data.Common.DbParameter parameter, System.Data.DataRow datarow, System.Data.StatementType statementType, bool whereClause) { } public static void DeriveParameters(System.Data.Odbc.OdbcCommand command) { } public new System.Data.Odbc.OdbcCommand GetDeleteCommand() { throw null; } @@ -70,8 +71,8 @@ protected override void SetRowUpdatingHandler(System.Data.Common.DbDataAdapter a public sealed partial class OdbcConnection : System.Data.Common.DbConnection, System.ICloneable { public OdbcConnection() { } - public OdbcConnection(string connectionString) { } - public override string ConnectionString { get { throw null; } set { } } + public OdbcConnection(string? connectionString) { } + public override string? ConnectionString { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(15)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public new int ConnectionTimeout { get { throw null; } set { } } @@ -89,7 +90,7 @@ public OdbcConnection(string connectionString) { } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public override System.Data.ConnectionState State { get { throw null; } } - public event System.Data.Odbc.OdbcInfoMessageEventHandler InfoMessage { add { } remove { } } + public event System.Data.Odbc.OdbcInfoMessageEventHandler? InfoMessage { add { } remove { } } protected override System.Data.Common.DbTransaction BeginDbTransaction(System.Data.IsolationLevel isolationLevel) { throw null; } public new System.Data.Odbc.OdbcTransaction BeginTransaction() { throw null; } public new System.Data.Odbc.OdbcTransaction BeginTransaction(System.Data.IsolationLevel isolevel) { throw null; } @@ -100,7 +101,7 @@ public override void Close() { } protected override void Dispose(bool disposing) { } public override System.Data.DataTable GetSchema() { throw null; } public override System.Data.DataTable GetSchema(string collectionName) { throw null; } - public override System.Data.DataTable GetSchema(string collectionName, string[] restrictionValues) { throw null; } + public override System.Data.DataTable GetSchema(string collectionName, string?[]? restrictionValues) { throw null; } public override void Open() { } public static void ReleaseObjectPool() { } object System.ICloneable.Clone() { throw null; } @@ -108,36 +109,37 @@ public static void ReleaseObjectPool() { } public sealed partial class OdbcConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder { public OdbcConnectionStringBuilder() { } - public OdbcConnectionStringBuilder(string connectionString) { } + public OdbcConnectionStringBuilder(string? connectionString) { } [System.ComponentModel.DisplayNameAttribute("Driver")] public string Driver { get { throw null; } set { } } [System.ComponentModel.DisplayNameAttribute("Dsn")] public string Dsn { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override object this[string keyword] { get { throw null; } set { } } public override System.Collections.ICollection Keys { get { throw null; } } public override void Clear() { } public override bool ContainsKey(string keyword) { throw null; } public override bool Remove(string keyword) { throw null; } - public override bool TryGetValue(string keyword, out object value) { throw null; } + public override bool TryGetValue(string keyword, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out object? value) { throw null; } } public sealed partial class OdbcDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable { public OdbcDataAdapter() { } - public OdbcDataAdapter(System.Data.Odbc.OdbcCommand selectCommand) { } - public OdbcDataAdapter(string selectCommandText, System.Data.Odbc.OdbcConnection selectConnection) { } - public OdbcDataAdapter(string selectCommandText, string selectConnectionString) { } - public new System.Data.Odbc.OdbcCommand DeleteCommand { get { throw null; } set { } } - public new System.Data.Odbc.OdbcCommand InsertCommand { get { throw null; } set { } } - public new System.Data.Odbc.OdbcCommand SelectCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.DeleteCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.InsertCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.SelectCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.UpdateCommand { get { throw null; } set { } } - public new System.Data.Odbc.OdbcCommand UpdateCommand { get { throw null; } set { } } - public event System.Data.Odbc.OdbcRowUpdatedEventHandler RowUpdated { add { } remove { } } - public event System.Data.Odbc.OdbcRowUpdatingEventHandler RowUpdating { add { } remove { } } - protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } - protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + public OdbcDataAdapter(System.Data.Odbc.OdbcCommand? selectCommand) { } + public OdbcDataAdapter(string? selectCommandText, System.Data.Odbc.OdbcConnection? selectConnection) { } + public OdbcDataAdapter(string? selectCommandText, string? selectConnectionString) { } + public new System.Data.Odbc.OdbcCommand? DeleteCommand { get { throw null; } set { } } + public new System.Data.Odbc.OdbcCommand? InsertCommand { get { throw null; } set { } } + public new System.Data.Odbc.OdbcCommand? SelectCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.DeleteCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.InsertCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.SelectCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.UpdateCommand { get { throw null; } set { } } + public new System.Data.Odbc.OdbcCommand? UpdateCommand { get { throw null; } set { } } + public event System.Data.Odbc.OdbcRowUpdatedEventHandler? RowUpdated { add { } remove { } } + public event System.Data.Odbc.OdbcRowUpdatingEventHandler? RowUpdating { add { } remove { } } + protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs value) { } protected override void OnRowUpdating(System.Data.Common.RowUpdatingEventArgs value) { } object System.ICloneable.Clone() { throw null; } @@ -156,9 +158,9 @@ public override void Close() { } protected override void Dispose(bool disposing) { } public override bool GetBoolean(int i) { throw null; } public override byte GetByte(int i) { throw null; } - public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) { throw null; } + public override long GetBytes(int i, long dataIndex, byte[]? buffer, int bufferIndex, int length) { throw null; } public override char GetChar(int i) { throw null; } - public override long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) { throw null; } + public override long GetChars(int i, long dataIndex, char[]? buffer, int bufferIndex, int length) { throw null; } public override string GetDataTypeName(int i) { throw null; } public System.DateTime GetDate(int i) { throw null; } public override System.DateTime GetDateTime(int i) { throw null; } @@ -247,28 +249,30 @@ public static partial class OdbcMetaDataColumnNames public sealed partial class OdbcParameter : System.Data.Common.DbParameter, System.Data.IDataParameter, System.Data.IDbDataParameter, System.ICloneable { public OdbcParameter() { } - public OdbcParameter(string name, System.Data.Odbc.OdbcType type) { } - public OdbcParameter(string name, System.Data.Odbc.OdbcType type, int size) { } + public OdbcParameter(string? name, System.Data.Odbc.OdbcType type) { } + public OdbcParameter(string? name, System.Data.Odbc.OdbcType type, int size) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public OdbcParameter(string parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object value) { } + public OdbcParameter(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object? value) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public OdbcParameter(string parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, byte precision, byte scale, string sourceColumn, System.Data.DataRowVersion sourceVersion, bool sourceColumnNullMapping, object value) { } - public OdbcParameter(string name, System.Data.Odbc.OdbcType type, int size, string sourcecolumn) { } - public OdbcParameter(string name, object value) { } + public OdbcParameter(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, byte precision, byte scale, string? sourceColumn, System.Data.DataRowVersion sourceVersion, bool sourceColumnNullMapping, object? value) { } + public OdbcParameter(string? name, System.Data.Odbc.OdbcType type, int size, string? sourcecolumn) { } + public OdbcParameter(string? name, object? value) { } public override System.Data.DbType DbType { get { throw null; } set { } } public override System.Data.ParameterDirection Direction { get { throw null; } set { } } public override bool IsNullable { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(System.Data.Odbc.OdbcType.NChar)] [System.Data.Common.DbProviderSpecificTypePropertyAttribute(true)] public System.Data.Odbc.OdbcType OdbcType { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string ParameterName { get { throw null; } set { } } public new byte Precision { get { throw null; } set { } } public new byte Scale { get { throw null; } set { } } public override int Size { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string SourceColumn { get { throw null; } set { } } public override bool SourceColumnNullMapping { get { throw null; } set { } } public override System.Data.DataRowVersion SourceVersion { get { throw null; } set { } } - public override object Value { get { throw null; } set { } } + public override object? Value { get { throw null; } set { } } public override void ResetDbType() { } public void ResetOdbcType() { } object System.ICloneable.Clone() { throw null; } @@ -290,15 +294,15 @@ internal OdbcParameterCollection() { } public override object SyncRoot { get { throw null; } } public System.Data.Odbc.OdbcParameter Add(System.Data.Odbc.OdbcParameter value) { throw null; } public override int Add(object value) { throw null; } - public System.Data.Odbc.OdbcParameter Add(string parameterName, System.Data.Odbc.OdbcType odbcType) { throw null; } - public System.Data.Odbc.OdbcParameter Add(string parameterName, System.Data.Odbc.OdbcType odbcType, int size) { throw null; } - public System.Data.Odbc.OdbcParameter Add(string parameterName, System.Data.Odbc.OdbcType odbcType, int size, string sourceColumn) { throw null; } + public System.Data.Odbc.OdbcParameter Add(string? parameterName, System.Data.Odbc.OdbcType odbcType) { throw null; } + public System.Data.Odbc.OdbcParameter Add(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size) { throw null; } + public System.Data.Odbc.OdbcParameter Add(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, string? sourceColumn) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("Add(String parameterName, Object value) has been deprecated. Use AddWithValue(String parameterName, Object value). https://go.microsoft.com/fwlink/?linkid=14202", false)] - public System.Data.Odbc.OdbcParameter Add(string parameterName, object value) { throw null; } + public System.Data.Odbc.OdbcParameter Add(string? parameterName, object? value) { throw null; } public override void AddRange(System.Array values) { } public void AddRange(System.Data.Odbc.OdbcParameter[] values) { } - public System.Data.Odbc.OdbcParameter AddWithValue(string parameterName, object value) { throw null; } + public System.Data.Odbc.OdbcParameter AddWithValue(string? parameterName, object? value) { throw null; } public override void Clear() { } public bool Contains(System.Data.Odbc.OdbcParameter value) { throw null; } public override bool Contains(object value) { throw null; } @@ -322,22 +326,22 @@ protected override void SetParameter(string parameterName, System.Data.Common.Db } public sealed partial class OdbcRowUpdatedEventArgs : System.Data.Common.RowUpdatedEventArgs { - public OdbcRowUpdatedEventArgs(System.Data.DataRow row, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } - public new System.Data.Odbc.OdbcCommand Command { get { throw null; } } + public OdbcRowUpdatedEventArgs(System.Data.DataRow row, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } + public new System.Data.Odbc.OdbcCommand? Command { get { throw null; } } } public delegate void OdbcRowUpdatedEventHandler(object sender, System.Data.Odbc.OdbcRowUpdatedEventArgs e); public sealed partial class OdbcRowUpdatingEventArgs : System.Data.Common.RowUpdatingEventArgs { - public OdbcRowUpdatingEventArgs(System.Data.DataRow row, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } - protected override System.Data.IDbCommand BaseCommand { get { throw null; } set { } } - public new System.Data.Odbc.OdbcCommand Command { get { throw null; } set { } } + public OdbcRowUpdatingEventArgs(System.Data.DataRow row, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } + protected override System.Data.IDbCommand? BaseCommand { get { throw null; } set { } } + public new System.Data.Odbc.OdbcCommand? Command { get { throw null; } set { } } } public delegate void OdbcRowUpdatingEventHandler(object sender, System.Data.Odbc.OdbcRowUpdatingEventArgs e); public sealed partial class OdbcTransaction : System.Data.Common.DbTransaction { internal OdbcTransaction() { } - public new System.Data.Odbc.OdbcConnection Connection { get { throw null; } } - protected override System.Data.Common.DbConnection DbConnection { get { throw null; } } + public new System.Data.Odbc.OdbcConnection? Connection { get { throw null; } } + protected override System.Data.Common.DbConnection? DbConnection { get { throw null; } } public override System.Data.IsolationLevel IsolationLevel { get { throw null; } } public override void Commit() { } protected override void Dispose(bool disposing) { } diff --git a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj index dec34df2a0f8..a36f4ed64a8b 100644 --- a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.csproj @@ -1,6 +1,7 @@ netstandard2.0;net461 + enable @@ -9,4 +10,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/AdapterUtil.Odbc.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/AdapterUtil.Odbc.cs index de295724ab8a..60eda2401f98 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/AdapterUtil.Odbc.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/AdapterUtil.Odbc.cs @@ -18,7 +18,7 @@ internal static string GetString(string value) return value; } - internal static string GetString(string format, params object[] args) + internal static string GetString(string format, params object?[] args) { return SR.Format(format, args); } @@ -59,7 +59,7 @@ internal static TimeoutException TimeoutException(string error) TraceExceptionAsReturnValue(e); return e; } - internal static InvalidOperationException InvalidOperation(string error, Exception inner) + internal static InvalidOperationException InvalidOperation(string error, Exception? inner) { InvalidOperationException e = new InvalidOperationException(error, inner); TraceExceptionAsReturnValue(e); @@ -193,7 +193,7 @@ internal static InvalidOperationException InvalidDataDirectory() { return ADP.InvalidOperation(SR.GetString(SR.ADP_InvalidDataDirectory)); } - internal static ArgumentException InvalidKeyname(string parameterName) + internal static ArgumentException InvalidKeyname(string? parameterName) { return Argument(SR.GetString(SR.ADP_InvalidKey), parameterName); } @@ -272,7 +272,7 @@ internal static Exception OpenReaderExists() return OpenReaderExists(null); } - internal static Exception OpenReaderExists(Exception e) + internal static Exception OpenReaderExists(Exception? e) { return InvalidOperation(SR.GetString(SR.ADP_OpenReaderExists), e); } @@ -313,7 +313,7 @@ internal static InvalidOperationException QuotePrefixNotSet(string method) // // : ConnectionUtil // - internal static Exception ConnectionIsDisabled(Exception InnerException) + internal static Exception ConnectionIsDisabled(Exception? InnerException) { return InvalidOperation(SR.GetString(SR.ADP_ConnectionIsDisabled), InnerException); } @@ -367,7 +367,7 @@ internal static ArgumentException InvalidDataType(TypeCode typecode) } internal static ArgumentException UnknownDataType(Type dataType) { - return Argument(SR.GetString(SR.ADP_UnknownDataType, dataType.FullName)); + return Argument(SR.GetString(SR.ADP_UnknownDataType, dataType.FullName!)); } internal static ArgumentException DbTypeNotSupported(System.Data.DbType type, Type enumtype) { @@ -375,7 +375,7 @@ internal static ArgumentException DbTypeNotSupported(System.Data.DbType type, Ty } internal static ArgumentException UnknownDataTypeCode(Type dataType, TypeCode typeCode) { - return Argument(SR.GetString(SR.ADP_UnknownDataTypeCode, ((int)typeCode).ToString(CultureInfo.InvariantCulture), dataType.FullName)); + return Argument(SR.GetString(SR.ADP_UnknownDataTypeCode, ((int)typeCode).ToString(CultureInfo.InvariantCulture), dataType.FullName!)); } internal static ArgumentException InvalidOffsetValue(int value) { @@ -477,7 +477,7 @@ internal static Exception IncorrectNumberOfDataSourceInformationRows() return Argument(SR.GetString(SR.MDF_IncorrectNumberOfDataSourceInformationRows)); } - internal static ArgumentException InvalidRestrictionValue(string collectionName, string restrictionName, string restrictionValue) + internal static ArgumentException InvalidRestrictionValue(string collectionName, string restrictionName, string? restrictionValue) { return ADP.Argument(SR.GetString(SR.MDF_InvalidRestrictionValue, collectionName, restrictionName, restrictionValue)); } @@ -572,7 +572,7 @@ internal static Exception UnsupportedVersion(string collectionName) internal static readonly IntPtr PtrZero = new IntPtr(0); // IntPtr.Zero internal static readonly int PtrSize = IntPtr.Size; - internal static Delegate FindBuilder(MulticastDelegate mcd) + internal static Delegate? FindBuilder(MulticastDelegate mcd) { // V1.2.3300 if (null != mcd) { @@ -651,7 +651,7 @@ internal static string GetFullPath(string filename) return Path.GetFullPath(filename); } - internal static int StringLength(string inputString) + internal static int StringLength(string? inputString) { return ((null != inputString) ? inputString.Length : 0); } diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs index cf901dd7a13e..dba3fdbbc37e 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs @@ -26,17 +26,17 @@ private static class KEY private readonly string _encryptedUsersConnectionString; // hash of unique keys to values - private readonly Dictionary _parsetable; + private readonly Dictionary _parsetable; // a linked list of key/value and their length in _encryptedUsersConnectionString - private readonly NameValuePair _keychain; + private readonly NameValuePair? _keychain; // track the existance of "password" or "pwd" in the connection string // not used for anything anymore but must keep it set correct for V1.1 serialization private readonly bool _hasPassword; - private readonly string[] _restrictionValues; - private readonly string _restrictions; + private readonly string[]? _restrictionValues; + private readonly string? _restrictions; private readonly KeyRestrictionBehavior _behavior; @@ -44,7 +44,7 @@ private static class KEY #pragma warning disable CA1823 // this field is no longer used, hence the warning was disabled // however, it can not be removed or it will break serialization with V1.1 - private readonly string _encryptedActualConnectionString; + private readonly string? _encryptedActualConnectionString; #pragma warning restore CA1823 #pragma warning restore CS0169 @@ -56,13 +56,13 @@ internal DBConnectionString(string value, string restrictions, KeyRestrictionBeh } internal DBConnectionString(DbConnectionOptions connectionOptions) - : this(connectionOptions, (string)null, KeyRestrictionBehavior.AllowOnly, null, true) + : this(connectionOptions, null, KeyRestrictionBehavior.AllowOnly, null, true) { // used by DBDataPermission to convert from DbConnectionOptions to DBConnectionString // since backward compatability requires Everett level classes } - private DBConnectionString(DbConnectionOptions connectionOptions, string restrictions, KeyRestrictionBehavior behavior, Dictionary synonyms, bool mustCloneDictionary) + private DBConnectionString(DbConnectionOptions connectionOptions, string? restrictions, KeyRestrictionBehavior behavior, Dictionary? synonyms, bool mustCloneDictionary) { // used by DBDataPermission Debug.Assert(null != connectionOptions, "null connectionOptions"); switch (behavior) @@ -89,7 +89,7 @@ private DBConnectionString(DbConnectionOptions connectionOptions, string restric { // clone the hashtable to replace user's password/pwd value with "*" // we only need to clone if coming from DbConnectionOptions and password exists - _parsetable = new Dictionary(_parsetable); + _parsetable = new Dictionary(_parsetable); } // different than Everett in that instead of removing password/pwd from @@ -117,7 +117,7 @@ private DBConnectionString(DbConnectionOptions connectionOptions, string restric } } - private DBConnectionString(DBConnectionString connectionString, string[] restrictionValues, KeyRestrictionBehavior behavior) + private DBConnectionString(DBConnectionString connectionString, string[]? restrictionValues, KeyRestrictionBehavior behavior) { // used by intersect for two equal connection strings with different restrictions _encryptedUsersConnectionString = connectionString._encryptedUsersConnectionString; @@ -147,7 +147,7 @@ internal bool IsEmpty get { return (null == _keychain); } } - internal NameValuePair KeyChain + internal NameValuePair? KeyChain { get { return _keychain; } } @@ -156,10 +156,10 @@ internal string Restrictions { get { - string restrictions = _restrictions; + string? restrictions = _restrictions; if (null == restrictions) { - string[] restrictionValues = _restrictionValues; + string[]? restrictionValues = _restrictionValues; if ((null != restrictionValues) && (0 < restrictionValues.Length)) { StringBuilder builder = new StringBuilder(); @@ -184,9 +184,9 @@ internal string Restrictions } } - internal string this[string keyword] + internal string? this[string keyword] { - get { return (string)_parsetable[keyword]; } + get { return _parsetable[keyword]; } } internal bool ContainsKey(string keyword) @@ -194,10 +194,10 @@ internal bool ContainsKey(string keyword) return _parsetable.ContainsKey(keyword); } - internal DBConnectionString Intersect(DBConnectionString entry) + internal DBConnectionString Intersect(DBConnectionString? entry) { KeyRestrictionBehavior behavior = _behavior; - string[] restrictionValues = null; + string[]? restrictionValues = null; if (null == entry) { @@ -294,7 +294,7 @@ internal DBConnectionString Intersect(DBConnectionString entry) } [Conditional("DEBUG")] - private void ValidateCombinedSet(DBConnectionString componentSet, DBConnectionString combinedSet) + private void ValidateCombinedSet(DBConnectionString? componentSet, DBConnectionString combinedSet) { Debug.Assert(combinedSet != null, "The combined connection string should not be null"); if ((componentSet != null) && (combinedSet._restrictionValues != null) && (componentSet._restrictionValues != null)) @@ -362,7 +362,7 @@ internal bool IsSupersetOf(DBConnectionString entry) case KeyRestrictionBehavior.AllowOnly: // every key must either be in the resticted connection string or in the allowed keywords // keychain may contain duplicates, but it is better than GetEnumerator on _parsetable.Keys - for (NameValuePair current = entry.KeyChain; null != current; current = current.Next) + for (NameValuePair? current = entry.KeyChain; null != current; current = current.Next) { if (!ContainsKey(current.Name) && IsRestrictedKeyword(current.Name)) { @@ -390,9 +390,9 @@ internal bool IsSupersetOf(DBConnectionString entry) return true; } - private static string[] NewRestrictionAllowOnly(string[] allowonly, string[] preventusage) + private static string[]? NewRestrictionAllowOnly(string[] allowonly, string[] preventusage) { - List newlist = null; + List? newlist = null; for (int i = 0; i < allowonly.Length; ++i) { if (0 > Array.BinarySearch(preventusage, allowonly[i], StringComparer.Ordinal)) @@ -404,7 +404,7 @@ private static string[] NewRestrictionAllowOnly(string[] allowonly, string[] pre newlist.Add(allowonly[i]); } } - string[] restrictionValues = null; + string[]? restrictionValues = null; if (null != newlist) { restrictionValues = newlist.ToArray(); @@ -413,9 +413,9 @@ private static string[] NewRestrictionAllowOnly(string[] allowonly, string[] pre return restrictionValues; } - private static string[] NewRestrictionIntersect(string[] a, string[] b) + private static string[]? NewRestrictionIntersect(string[] a, string[] b) { - List newlist = null; + List? newlist = null; for (int i = 0; i < a.Length; ++i) { if (0 <= Array.BinarySearch(b, a[i], StringComparer.Ordinal)) @@ -427,7 +427,7 @@ private static string[] NewRestrictionIntersect(string[] a, string[] b) newlist.Add(a[i]); } } - string[] restrictionValues = null; + string[]? restrictionValues = null; if (newlist != null) { restrictionValues = newlist.ToArray(); @@ -462,7 +462,7 @@ private static string[] NoDuplicateUnion(string[] a, string[] b) return restrictionValues; } - private static string[] ParseRestrictions(string restrictions, Dictionary synonyms) + private static string[]? ParseRestrictions(string restrictions, Dictionary? synonyms) { List restrictionValues = new List(); StringBuilder buffer = new StringBuilder(restrictions.Length); @@ -473,7 +473,7 @@ private static string[] ParseRestrictions(string restrictions, Dictionary synonyms, bool useOdbcRules) + public DbConnectionOptions(string connectionString, Dictionary? synonyms, bool useOdbcRules) { _useOdbcRules = useOdbcRules; - _parsetable = new Dictionary(); + _parsetable = new Dictionary(); _usersConnectionString = ((null != connectionString) ? connectionString : ""); // first pass on parsing, initial syntax check @@ -79,16 +79,16 @@ internal bool HasBlankPassword { if (_parsetable.ContainsKey(KEY.Password)) { - return string.IsNullOrEmpty((string)_parsetable[KEY.Password]); + return string.IsNullOrEmpty(_parsetable[KEY.Password]); } else if (_parsetable.ContainsKey(SYNONYM.Pwd)) { - return string.IsNullOrEmpty((string)_parsetable[SYNONYM.Pwd]); // MDAC 83097 + return string.IsNullOrEmpty(_parsetable[SYNONYM.Pwd]); // MDAC 83097 } else { - return ((_parsetable.ContainsKey(KEY.User_ID) && !string.IsNullOrEmpty((string)_parsetable[KEY.User_ID])) || (_parsetable.ContainsKey(SYNONYM.UID) && !string.IsNullOrEmpty((string)_parsetable[SYNONYM.UID]))); + return ((_parsetable.ContainsKey(KEY.User_ID) && !string.IsNullOrEmpty(_parsetable[KEY.User_ID])) || (_parsetable.ContainsKey(SYNONYM.UID) && !string.IsNullOrEmpty(_parsetable[SYNONYM.UID]))); } } return false; @@ -100,7 +100,7 @@ public bool IsEmpty get { return (null == _keyChain); } } - internal Dictionary Parsetable + internal Dictionary Parsetable { get { return _parsetable; } } @@ -110,12 +110,12 @@ public ICollection Keys get { return _parsetable.Keys; } } - public string this[string keyword] + public string? this[string keyword] { - get { return (string)_parsetable[keyword]; } + get { return _parsetable[keyword]; } } - internal static void AppendKeyValuePairBuilder(StringBuilder builder, string keyName, string keyValue, bool useOdbcRules) + internal static void AppendKeyValuePairBuilder(StringBuilder builder, string keyName, string? keyValue, bool useOdbcRules) { ADP.CheckArgumentNull(builder, nameof(builder)); ADP.CheckArgumentLength(keyName, nameof(keyName)); @@ -193,7 +193,7 @@ internal static void AppendKeyValuePairBuilder(StringBuilder builder, string key // same as Boolean, but with SSPI thrown in as valid yes public bool ConvertValueToIntegratedSecurity() { - object value = _parsetable[KEY.Integrated_Security]; + object? value = _parsetable[KEY.Integrated_Security]; if (null == value) { return false; @@ -223,7 +223,7 @@ internal bool ConvertValueToIntegratedSecurityInternal(string stringValue) public int ConvertValueToInt32(string keyName, int defaultValue) { - object value = _parsetable[keyName]; + object? value = _parsetable[keyName]; if (null == value) { return defaultValue; @@ -249,7 +249,7 @@ internal static int ConvertToInt32Internal(string keyname, string stringValue) public string ConvertValueToString(string keyName, string defaultValue) { - string value = (string)_parsetable[keyName]; + string? value = _parsetable[keyName]; return ((null != value) ? value : defaultValue); } @@ -262,16 +262,16 @@ public bool ContainsKey(string keyword) // * this method queries "DataDirectory" value from the current AppDomain. // This string is used for to replace "!DataDirectory!" values in the connection string, it is not considered as an "exposed resource". // * This method uses GetFullPath to validate that root path is valid, the result is not exposed out. - internal static string ExpandDataDirectory(string keyword, string value, ref string datadir) + internal static string? ExpandDataDirectory(string keyword, string? value, ref string? datadir) { - string fullPath = null; + string? fullPath = null; if ((null != value) && value.StartsWith(DataDirectory, StringComparison.OrdinalIgnoreCase)) { - string rootFolderPath = datadir; + string? rootFolderPath = datadir; if (null == rootFolderPath) { // find the replacement path - object rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory"); + object? rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory"); rootFolderPath = (rootFolderObject as string); if ((null != rootFolderObject) && (null == rootFolderPath)) { @@ -320,16 +320,16 @@ internal static string ExpandDataDirectory(string keyword, string value, ref str return fullPath; } - internal string ExpandDataDirectories(ref string filename, ref int position) + internal string? ExpandDataDirectories(ref string? filename, ref int position) { - string value = null; + string? value = null; StringBuilder builder = new StringBuilder(_usersConnectionString.Length); - string datadir = null; + string? datadir = null; int copyPosition = 0; bool expanded = false; - for (NameValuePair current = _keyChain; null != current; current = current.Next) + for (NameValuePair? current = _keyChain; null != current; current = current.Next) { value = current.Value; @@ -420,7 +420,7 @@ internal string ExpandKeyword(string keyword, string replacementValue) int copyPosition = 0; StringBuilder builder = new StringBuilder(_usersConnectionString.Length); - for (NameValuePair current = _keyChain; null != current; current = current.Next) + for (NameValuePair? current = _keyChain; null != current; current = current.Next) { if ((current.Name == keyword) && (current.Value == this[keyword])) { diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionStringCommon.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionStringCommon.cs index d133e16d0f94..7c7c32497976 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionStringCommon.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionStringCommon.cs @@ -155,7 +155,7 @@ internal static class DbConnectionStringBuilderUtil internal static bool ConvertToBoolean(object value) { Debug.Assert(null != value, "ConvertToBoolean(null)"); - string svalue = (value as string); + string? svalue = (value as string); if (null != svalue) { if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes")) @@ -194,7 +194,7 @@ internal static bool ConvertToBoolean(object value) internal static bool ConvertToIntegratedSecurity(object value) { Debug.Assert(null != value, "ConvertToIntegratedSecurity(null)"); - string svalue = (value as string); + string? svalue = (value as string); if (null != svalue) { if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes")) diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/NameValuePermission.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/NameValuePermission.cs index c57ae936b006..004fcd7832fa 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/NameValuePermission.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/NameValuePermission.cs @@ -11,23 +11,23 @@ internal sealed class NameValuePermission : IComparable // reused as both key and value nodes // key nodes link to value nodes // value nodes link to key nodes - private readonly string _value; + private readonly string? _value; // value node with (null != _restrictions) are allowed to match connection strings - private DBConnectionString _entry; + private DBConnectionString? _entry; - private NameValuePermission[] _tree; // with branches + private NameValuePermission[]? _tree; // with branches internal NameValuePermission() { // root node } - private NameValuePermission(string keyword) + private NameValuePermission(string? keyword) { _value = keyword; } - private NameValuePermission(string value, DBConnectionString entry) + private NameValuePermission(string? value, DBConnectionString? entry) { _value = value; _entry = entry; @@ -40,7 +40,7 @@ private NameValuePermission(NameValuePermission permit) _tree = permit._tree; if (null != _tree) { - NameValuePermission[] tree = (_tree.Clone() as NameValuePermission[]); + NameValuePermission[] tree = (_tree.Clone() as NameValuePermission[])!; for (int i = 0; i < tree.Length; ++i) { if (null != tree[i]) @@ -52,9 +52,9 @@ private NameValuePermission(NameValuePermission permit) } } - int IComparable.CompareTo(object a) + int IComparable.CompareTo(object? a) { - return StringComparer.Ordinal.Compare(_value, ((NameValuePermission)a)._value); + return StringComparer.Ordinal.Compare(_value, ((NameValuePermission?)a)?._value); } internal static void AddEntry(NameValuePermission kvtree, ArrayList entries, DBConnectionString entry) @@ -63,9 +63,9 @@ internal static void AddEntry(NameValuePermission kvtree, ArrayList entries, DBC if (null != entry.KeyChain) { - for (NameValuePair keychain = entry.KeyChain; null != keychain; keychain = keychain.Next) + for (NameValuePair? keychain = entry.KeyChain; null != keychain; keychain = keychain.Next) { - NameValuePermission kv; + NameValuePermission? kv; kv = kvtree.CheckKeyForValue(keychain.Name); if (null == kv) @@ -78,7 +78,7 @@ internal static void AddEntry(NameValuePermission kvtree, ArrayList entries, DBC kv = kvtree.CheckKeyForValue(keychain.Value); if (null == kv) { - DBConnectionString insertValue = ((null != keychain.Next) ? null : entry); + DBConnectionString? insertValue = ((null != keychain.Next) ? null : entry); kv = new NameValuePermission(keychain.Value, insertValue); kvtree.Add(kv); // add directly into live tree if (null != insertValue) @@ -105,7 +105,7 @@ internal static void AddEntry(NameValuePermission kvtree, ArrayList entries, DBC } else { // global restrictions, MDAC 84443 - DBConnectionString kentry = kvtree._entry; + DBConnectionString? kentry = kvtree._entry; if (null != kentry) { Debug.Assert(entries.Contains(kentry), "entries doesn't contain entry"); @@ -146,14 +146,14 @@ internal void Intersect(ArrayList entries, NameValuePermission target) int count = _tree.Length; for (int i = 0; i < _tree.Length; ++i) { - NameValuePermission kvtree = target.CheckKeyForValue(_tree[i]._value); + NameValuePermission? kvtree = target.CheckKeyForValue(_tree[i]._value); if (null != kvtree) { // does target tree contain our value _tree[i].Intersect(entries, kvtree); } else { - _tree[i] = null; + _tree[i] = null!; // Temporary, removed below --count; } } @@ -179,12 +179,12 @@ internal void Intersect(ArrayList entries, NameValuePermission target) private void Add(NameValuePermission permit) { - NameValuePermission[] tree = _tree; + NameValuePermission[]? tree = _tree; int length = ((null != tree) ? tree.Length : 0); NameValuePermission[] newtree = new NameValuePermission[1 + length]; for (int i = 0; i < newtree.Length - 1; ++i) { - newtree[i] = tree[i]; + newtree[i] = tree![i]; } newtree[length] = permit; Array.Sort(newtree); @@ -198,7 +198,7 @@ internal bool CheckValueForKeyPermit(DBConnectionString parsetable) return false; } bool hasMatch = false; - NameValuePermission[] keytree = _tree; // _tree won't mutate but Add will replace it + NameValuePermission[]? keytree = _tree; // _tree won't mutate but Add will replace it if (null != keytree) { hasMatch = parsetable.IsEmpty; // MDAC 86773 @@ -210,16 +210,16 @@ internal bool CheckValueForKeyPermit(DBConnectionString parsetable) NameValuePermission permitKey = keytree[i]; if (null != permitKey) { - string keyword = permitKey._value; + string keyword = permitKey._value!; #if DEBUG Debug.Assert(null == permitKey._entry, "key member has no restrictions"); #endif if (parsetable.ContainsKey(keyword)) { - string valueInQuestion = (string)parsetable[keyword]; + string? valueInQuestion = parsetable[keyword]; // keyword is restricted to certain values - NameValuePermission permitValue = permitKey.CheckKeyForValue(valueInQuestion); + NameValuePermission? permitValue = permitKey.CheckKeyForValue(valueInQuestion); if (null != permitValue) { //value does match - continue the chain down that branch @@ -248,7 +248,7 @@ internal bool CheckValueForKeyPermit(DBConnectionString parsetable) // partial chain match, either leaf-node by shorter chain or fail mid-chain if (null == _restrictions) } - DBConnectionString entry = _entry; + DBConnectionString? entry = _entry; if (null != entry) { // also checking !hasMatch is tempting, but wrong @@ -261,9 +261,9 @@ internal bool CheckValueForKeyPermit(DBConnectionString parsetable) return hasMatch; // mid-chain failure } - private NameValuePermission CheckKeyForValue(string keyInQuestion) + private NameValuePermission? CheckKeyForValue(string? keyInQuestion) { - NameValuePermission[] valuetree = _tree; // _tree won't mutate but Add will replace it + NameValuePermission[]? valuetree = _tree; // _tree won't mutate but Add will replace it if (null != valuetree) { for (int i = 0; i < valuetree.Length; ++i) diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs index 61b550a5e6b4..e885ac9380b6 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs @@ -60,7 +60,7 @@ internal string PtrToStringUni(int offset) Validate(offset, 2); Debug.Assert(0 == offset % ADP.PtrSize, "invalid alignment"); - string value = null; + string? value = null; bool mustRelease = false; try @@ -69,7 +69,7 @@ internal string PtrToStringUni(int offset) IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); value = Marshal.PtrToStringUni(ptr); - Validate(offset, (2 * (value.Length + 1))); + Validate(offset, (2 * (value!.Length + 1))); } finally { @@ -88,7 +88,7 @@ internal string PtrToStringUni(int offset, int length) Validate(offset, 2 * length); Debug.Assert(0 == offset % ADP.PtrSize, "invalid alignment"); - string value = null; + string? value = null; bool mustRelease = false; try diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionFactory.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionFactory.cs index 9b05f5b6d0e3..5e37564f0710 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionFactory.cs @@ -10,12 +10,12 @@ namespace System.Data.ProviderBase { internal abstract partial class DbConnectionFactory { - internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, out DbConnectionInternal connection) + internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource? retry, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection, out DbConnectionInternal? connection) { Debug.Assert(null != owningConnection, "null owningConnection?"); DbConnectionPoolGroup poolGroup; - DbConnectionPool connectionPool; + DbConnectionPool? connectionPool; connection = null; // Work around race condition with clearing the pool between GetConnectionPool obtaining pool @@ -32,7 +32,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour do { - poolGroup = GetConnectionPoolGroup(owningConnection); + poolGroup = GetConnectionPoolGroup(owningConnection)!; // Doing this on the callers thread is important because it looks up the WindowsIdentity from the thread. connectionPool = GetConnectionPool(owningConnection, poolGroup); if (null == connectionPool) @@ -40,7 +40,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour // If GetConnectionPool returns null, we can be certain that // this connection should not be pooled via DbConnectionPool // or have a disabled pool entry. - poolGroup = GetConnectionPoolGroup(owningConnection); // previous entry have been disabled + poolGroup = GetConnectionPoolGroup(owningConnection)!; // previous entry have been disabled if (retry != null) { @@ -76,6 +76,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour // now that we have an antecedent task, schedule our work when it is completed. // If it is a new slot or a completed task, this continuation will start right away. + // TODO: newTask needs to be over non-nullable DbConnection (see below), there may be a bug here newTask = s_pendingOpenNonPooled[idx].ContinueWith((_) => { var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions); @@ -85,10 +86,10 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour oldConnection.Dispose(); } return newConnection; - }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default); + }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default)!; // Place this new task in the slot so any future work will be queued behind it - s_pendingOpenNonPooled[idx] = newTask; + s_pendingOpenNonPooled[idx] = newTask!; } // Set up the timeout (if needed) @@ -108,7 +109,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour } else if (task.IsFaulted) { - retry.TrySetException(task.Exception.InnerException); + retry.TrySetException(task.Exception!.InnerException!); } else { diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionInternal.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionInternal.cs index 2ab7701a42f2..09d49bb131d6 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionInternal.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionInternal.cs @@ -79,12 +79,12 @@ internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFac // Lock to prevent race condition with cancellation lock (this) { - object lockToken = ObtainAdditionalLocksForClose(); + object? lockToken = ObtainAdditionalLocksForClose(); try { PrepareForCloseConnection(); - DbConnectionPool connectionPool = Pool; + DbConnectionPool? connectionPool = Pool; // The singleton closed classes won't have owners and diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPool.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPool.cs index 835dcf219aba..ab2d89be6121 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPool.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPool.cs @@ -22,7 +22,7 @@ private enum State private sealed class PendingGetConnection { - public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSource completion, DbConnectionOptions userOptions) + public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSource completion, DbConnectionOptions? userOptions) { DueTime = dueTime; Owner = owner; @@ -31,7 +31,7 @@ public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSour public long DueTime { get; private set; } public DbConnection Owner { get; private set; } public TaskCompletionSource Completion { get; private set; } - public DbConnectionOptions UserOptions { get; private set; } + public DbConnectionOptions? UserOptions { get; private set; } } @@ -97,12 +97,12 @@ internal WaitHandle[] GetHandles(bool withCreate) private static readonly Random s_random = new Random(5101977); // Value obtained from Dave Driver private readonly int _cleanupWait; - private readonly DbConnectionPoolIdentity _identity; + private readonly DbConnectionPoolIdentity? _identity; private readonly DbConnectionFactory _connectionFactory; private readonly DbConnectionPoolGroup _connectionPoolGroup; private readonly DbConnectionPoolGroupOptions _connectionPoolGroupOptions; - private readonly DbConnectionPoolProviderInfo _connectionPoolProviderInfo; + private readonly DbConnectionPoolProviderInfo? _connectionPoolProviderInfo; private State _state; @@ -117,13 +117,13 @@ internal WaitHandle[] GetHandles(bool withCreate) private int _waitCount; private readonly PoolWaitHandles _waitHandles; - private Exception _resError; + private Exception? _resError; private volatile bool _errorOccurred; private int _errorWait; - private Timer _errorTimer; + private Timer? _errorTimer; - private Timer _cleanupTimer; + private Timer? _cleanupTimer; private readonly List _objectList; @@ -135,7 +135,7 @@ internal DbConnectionPool( DbConnectionFactory connectionFactory, DbConnectionPoolGroup connectionPoolGroup, DbConnectionPoolIdentity identity, - DbConnectionPoolProviderInfo connectionPoolProviderInfo) + DbConnectionPoolProviderInfo? connectionPoolProviderInfo) { Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup"); @@ -220,7 +220,7 @@ private bool NeedToReplenish } } - internal DbConnectionPoolIdentity Identity + internal DbConnectionPoolIdentity? Identity { get { return _identity; } } @@ -251,7 +251,7 @@ internal DbConnectionPoolGroupOptions PoolGroupOptions get { return _connectionPoolGroupOptions; } } - internal DbConnectionPoolProviderInfo ProviderInfo + internal DbConnectionPoolProviderInfo? ProviderInfo { get { return _connectionPoolProviderInfo; } } @@ -266,7 +266,7 @@ private bool UsingIntegrateSecurity get { return (null != _identity && DbConnectionPoolIdentity.NoIdentity != _identity); } } - private void CleanupCallback(object state) + private void CleanupCallback(object? state) { // Called when the cleanup-timer ticks over. @@ -294,7 +294,7 @@ private void CleanupCallback(object state) if (_waitHandles.PoolSemaphore.WaitOne(0)) { // We obtained a objects from the semaphore. - DbConnectionInternal obj; + DbConnectionInternal? obj; if (_stackOld.TryPop(out obj)) { @@ -323,7 +323,7 @@ private void CleanupCallback(object state) { while (true) { - DbConnectionInternal obj; + DbConnectionInternal? obj; if (!_stackNew.TryPop(out obj)) break; @@ -345,7 +345,7 @@ private void CleanupCallback(object state) internal void Clear() { - DbConnectionInternal obj; + DbConnectionInternal? obj; // First, quickly doom everything. lock (_objectList) @@ -387,9 +387,9 @@ private Timer CreateCleanupTimer() _cleanupWait, _cleanupWait); - private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) + private DbConnectionInternal CreateObject(DbConnection? owningObject, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection) { - DbConnectionInternal newObj = null; + DbConnectionInternal? newObj = null; try { @@ -571,13 +571,13 @@ internal void DestroyObject(DbConnectionInternal obj) obj.Dispose(); } - private void ErrorCallback(object state) + private void ErrorCallback(object? state) { _errorOccurred = false; _waitHandles.ErrorEvent.Reset(); // the error state is cleaned, destroy the timer to avoid periodic invocation - Timer t = _errorTimer; + Timer? t = _errorTimer; _errorTimer = null; if (t != null) { @@ -588,14 +588,14 @@ private void ErrorCallback(object state) // TODO: move this to src/Common and integrate with SqlClient // Note: Odbc connections are not passing through this code - private Exception TryCloneCachedException() + private Exception? TryCloneCachedException() { return _resError; } private void WaitForPendingOpen() { - PendingGetConnection next; + PendingGetConnection? next; do { @@ -631,9 +631,9 @@ private void WaitForPendingOpen() delay = (uint)Math.Max(ADP.TimerRemainingMilliseconds(next.DueTime), 0); } - DbConnectionInternal connection = null; + DbConnectionInternal? connection = null; bool timeout = false; - Exception caughtException = null; + Exception? caughtException = null; try { @@ -675,7 +675,7 @@ private void WaitForPendingOpen() } while (!_pendingOpens.IsEmpty); } - internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource retry, DbConnectionOptions userOptions, out DbConnectionInternal connection) + internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource? retry, DbConnectionOptions? userOptions, out DbConnectionInternal? connection) { uint waitForMultipleObjectsTimeout = 0; bool allowCreate = false; @@ -728,9 +728,9 @@ internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSourceOptions used to create the new connection /// Inner connection that will be replaced /// A new inner connection that is attached to the - internal DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) + internal DbConnectionInternal? ReplaceConnection(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) { - DbConnectionInternal newConnection = UserCreateRequest(owningObject, userOptions, oldConnection); + DbConnectionInternal? newConnection = UserCreateRequest(owningObject, userOptions, oldConnection); if (newConnection != null) { @@ -907,9 +907,9 @@ internal DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbCon return newConnection; } - private DbConnectionInternal GetFromGeneralPool() + private DbConnectionInternal? GetFromGeneralPool() { - DbConnectionInternal obj = null; + DbConnectionInternal? obj = null; if (!_stackNew.TryPop(out obj)) { @@ -938,7 +938,7 @@ private DbConnectionInternal GetFromGeneralPool() return (obj); } - private void PoolCreateRequest(object state) + private void PoolCreateRequest(object? state) { // called by pooler to ensure pool requests are currently being satisfied - // creation mutex has not been obtained @@ -968,7 +968,7 @@ private void PoolCreateRequest(object state) // since either Open will fail or we will open a object for this pool that does // not belong in this pool. The side effect of this is that if using integrated // security min pool size cannot be guaranteed. - if (UsingIntegrateSecurity && !_identity.Equals(DbConnectionPoolIdentity.GetCurrent())) + if (UsingIntegrateSecurity && !_identity!.Equals(DbConnectionPoolIdentity.GetCurrent())) { return; } @@ -1147,7 +1147,7 @@ internal void Shutdown() _state = State.ShuttingDown; // deactivate timer callbacks - Timer t = _cleanupTimer; + Timer? t = _cleanupTimer; _cleanupTimer = null; if (null != t) { @@ -1156,15 +1156,15 @@ internal void Shutdown() } - private DbConnectionInternal UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection = null) + private DbConnectionInternal? UserCreateRequest(DbConnection owningObject, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection = null) { // called by user when they were not able to obtain a free object but // instead obtained creation mutex - DbConnectionInternal obj = null; + DbConnectionInternal? obj = null; if (ErrorOccurred) { - throw TryCloneCachedException(); + throw TryCloneCachedException()!; } else { diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs index 911720230d21..44c2fd1a379e 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs @@ -5,9 +5,9 @@ namespace System.Data.ProviderBase { internal class DbConnectionPoolGroupProviderInfo { - private DbConnectionPoolGroup _poolGroup; + private DbConnectionPoolGroup? _poolGroup; - internal DbConnectionPoolGroup PoolGroup + internal DbConnectionPoolGroup? PoolGroup { get { diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolIdentity.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolIdentity.cs index 7e1e6f9932dc..62112312ff01 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolIdentity.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbConnectionPoolIdentity.cs @@ -30,7 +30,7 @@ internal static DbConnectionPoolIdentity GetCurrent() throw new PlatformNotSupportedException(); } - public override bool Equals(object value) + public override bool Equals(object? value) { bool result = ((this == NoIdentity) || (this == value)); if (!result && (null != value)) diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index 8efc6e4c3553..b9c72520b7ea 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -4,6 +4,7 @@ $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent);netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;netstandard2.0;net461-Windows_NT true $(NoWarn);CA2249 + enable diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs index 65887bf7984c..7b4887893f62 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs @@ -9,9 +9,9 @@ internal DbSchemaInfo() { } - internal string _name; - internal string _typename; - internal Type _type; + internal string? _name; + internal string? _typename; + internal Type? _type; internal ODBC32.SQL_TYPE? _dbtype; } @@ -19,9 +19,9 @@ internal DbSchemaInfo() // Cache // // This is a on-demand cache, only caching what the user requests. - // The reational is that for ForwardOnly access (the default and LCD of drivers) + // The rationale is that for ForwardOnly access (the default and LCD of drivers) // we cannot obtain the data more than once, and even GetData(0) (to determine is-null) - // still obtains data for fixed lenght types. + // still obtains data for fixed length types. // So simple code like: // if (!rReader.IsDBNull(i)) @@ -39,8 +39,8 @@ internal sealed class DbCache //Data private readonly bool[] _isBadValue; - private DbSchemaInfo[] _schema; - private readonly object[] _values; + private DbSchemaInfo?[]? _schema; + private readonly object?[] _values; private readonly OdbcDataReader _record; internal int _count; internal bool _randomaccess = true; @@ -56,13 +56,13 @@ internal DbCache(OdbcDataReader record, int count) } //Accessor - internal object this[int i] + internal object? this[int i] { get { if (_isBadValue[i]) { - OverflowException innerException = (OverflowException)Values[i]; + OverflowException innerException = (OverflowException)Values[i]!; throw new OverflowException(innerException.Message, innerException); } return Values[i]; @@ -87,7 +87,7 @@ internal void InvalidateValue(int i) _isBadValue[i] = true; } - internal object[] Values + internal object?[] Values { get { @@ -95,7 +95,7 @@ internal object[] Values } } - internal object AccessIndex(int i) + internal object? AccessIndex(int i) { //Note: We could put this directly in this[i], instead of having an explicit overload. //However that means that EVERY access into the cache takes the hit of checking, so @@ -106,7 +106,7 @@ internal object AccessIndex(int i) // .... // return cache[i]; - object[] values = this.Values; + object?[] values = this.Values; if (_randomaccess) { //Random @@ -130,11 +130,8 @@ internal DbSchemaInfo GetSchema(int i) { _schema = new DbSchemaInfo[Count]; } - if (_schema[i] == null) - { - _schema[i] = new DbSchemaInfo(); - } - return _schema[i]; + + return _schema[i] ??= new DbSchemaInfo(); } internal void FlushValues() diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs index 1fed607d524d..6c326926ba57 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs @@ -116,7 +116,7 @@ internal static void TraceODBC(int level, string method, ODBC32.RetCode retcode) { } - internal static short ShortStringLength(string inputString) + internal static short ShortStringLength(string? inputString) { return checked((short)ADP.StringLength(inputString)); } @@ -716,14 +716,14 @@ internal enum SQL_SPECIALCOLUMNSET : short internal const short SQL_RESULT_COL = 3; // Helpers - internal static OdbcErrorCollection GetDiagErrors(string source, OdbcHandle hrHandle, RetCode retcode) + internal static OdbcErrorCollection GetDiagErrors(string? source, OdbcHandle hrHandle, RetCode retcode) { OdbcErrorCollection errors = new OdbcErrorCollection(); GetDiagErrors(errors, source, hrHandle, retcode); return errors; } - internal static void GetDiagErrors(OdbcErrorCollection errors, string source, OdbcHandle hrHandle, RetCode retcode) + internal static void GetDiagErrors(OdbcErrorCollection errors, string? source, OdbcHandle hrHandle, RetCode retcode) { Debug.Assert(retcode != ODBC32.RetCode.INVALID_HANDLE, "retcode must never be ODBC32.RetCode.INVALID_HANDLE"); if (RetCode.SUCCESS != retcode) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs index be558f4ac9dd..ad7b21c9a90e 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs @@ -4,6 +4,7 @@ using System.ComponentModel; //Component using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; // todo: @@ -20,21 +21,21 @@ public sealed class OdbcCommand : DbCommand, ICloneable private static int s_objectTypeCount; // Bid counter internal readonly int ObjectID = System.Threading.Interlocked.Increment(ref s_objectTypeCount); - private string _commandText; + private string? _commandText; private CommandType _commandType; private int _commandTimeout = ADP.DefaultCommandTimeout; private UpdateRowSource _updatedRowSource = UpdateRowSource.Both; private bool _designTimeInvisible; private bool _isPrepared; // true if the command is prepared - private OdbcConnection _connection; - private OdbcTransaction _transaction; + private OdbcConnection? _connection; + private OdbcTransaction? _transaction; - private WeakReference _weakDataReaderReference; + private WeakReference? _weakDataReaderReference; - private CMDWrapper _cmdWrapper; + private CMDWrapper? _cmdWrapper; - private OdbcParameterCollection _parameterCollection; // Parameter collection + private OdbcParameterCollection? _parameterCollection; // Parameter collection private ConnectionState _cmdState; @@ -43,20 +44,20 @@ public OdbcCommand() : base() GC.SuppressFinalize(this); } - public OdbcCommand(string cmdText) : this() + public OdbcCommand(string? cmdText) : this() { // note: arguments are assigned to properties so we do not have to trace them. // We still need to include them into the argument list of the definition! CommandText = cmdText; } - public OdbcCommand(string cmdText, OdbcConnection connection) : this() + public OdbcCommand(string? cmdText, OdbcConnection? connection) : this() { CommandText = cmdText; Connection = connection; } - public OdbcCommand(string cmdText, OdbcConnection connection, OdbcTransaction transaction) : this() + public OdbcCommand(string? cmdText, OdbcConnection? connection, OdbcTransaction? transaction) : this() { CommandText = cmdText; Connection = connection; @@ -83,7 +84,7 @@ private void DisposeDataReader() { if (null != _weakDataReaderReference) { - IDisposable reader = (IDisposable)_weakDataReaderReference.Target; + IDisposable? reader = (IDisposable?)_weakDataReaderReference.Target; if ((null != reader) && _weakDataReaderReference.IsAlive) { ((IDisposable)reader).Dispose(); @@ -95,11 +96,11 @@ private void DisposeDataReader() internal void DisconnectFromDataReaderAndConnection() { // get a reference to the datareader if it is alive - OdbcDataReader liveReader = null; + OdbcDataReader? liveReader = null; if (_weakDataReaderReference != null) { - OdbcDataReader reader; - reader = (OdbcDataReader)_weakDataReaderReference.Target; + OdbcDataReader? reader; + reader = (OdbcDataReader?)_weakDataReaderReference.Target; if (_weakDataReaderReference.IsAlive) { liveReader = reader; @@ -149,15 +150,16 @@ internal bool Canceling { get { - return _cmdWrapper.Canceling; + return _cmdWrapper!.Canceling; } } + [AllowNull] public override string CommandText { get { - string value = _commandText; + string? value = _commandText; return ((null != value) ? value : string.Empty); } set @@ -231,7 +233,7 @@ public override CommandType CommandType } } - public new OdbcConnection Connection + public new OdbcConnection? Connection { get { @@ -250,7 +252,7 @@ public override CommandType CommandType } } - protected override DbConnection DbConnection + protected override DbConnection? DbConnection { // V1.2.3300 get { @@ -258,7 +260,7 @@ protected override DbConnection DbConnection } set { - Connection = (OdbcConnection)value; + Connection = (OdbcConnection?)value; } } @@ -270,7 +272,7 @@ protected override DbParameterCollection DbParameterCollection } } - protected override DbTransaction DbTransaction + protected override DbTransaction? DbTransaction { // V1.2.3300 get { @@ -278,7 +280,7 @@ protected override DbTransaction DbTransaction } set { - Transaction = (OdbcTransaction)value; + Transaction = (OdbcTransaction?)value; } } @@ -332,7 +334,7 @@ internal bool HasParameters Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] - public new OdbcTransaction Transaction + public new OdbcTransaction? Transaction { get { @@ -379,7 +381,7 @@ public override UpdateRowSource UpdatedRowSource internal OdbcDescriptorHandle GetDescriptorHandle(ODBC32.SQL_ATTR attribute) { - return _cmdWrapper.GetDescriptorHandle(attribute); + return _cmdWrapper!.GetDescriptorHandle(attribute); } @@ -398,7 +400,7 @@ internal CMDWrapper GetStatementHandle() // if (_cmdWrapper == null) { - _cmdWrapper = new CMDWrapper(_connection); + _cmdWrapper = new CMDWrapper(_connection!); Debug.Assert(null != _connection, "GetStatementHandle without connection?"); _connection.AddWeakReference(this, OdbcReferenceCollection.CommandTag); @@ -431,11 +433,11 @@ internal CMDWrapper GetStatementHandle() public override void Cancel() { - CMDWrapper wrapper = _cmdWrapper; + CMDWrapper? wrapper = _cmdWrapper; if (null != wrapper) { wrapper.Canceling = true; - OdbcStatementHandle stmt = wrapper.StatementHandle; + OdbcStatementHandle? stmt = wrapper.StatementHandle; if (null != stmt) { lock (stmt) @@ -451,7 +453,7 @@ public override void Cancel() // don't fire info message events on cancel break; default: - throw wrapper.Connection.HandleErrorNoThrow(stmt, retcode); + throw wrapper.Connection.HandleErrorNoThrow(stmt, retcode)!; } } } @@ -488,7 +490,7 @@ internal bool RecoverFromConnection() private void CloseCommandWrapper() { - CMDWrapper wrapper = _cmdWrapper; + CMDWrapper? wrapper = _cmdWrapper; if (null != wrapper) { try @@ -560,7 +562,7 @@ public override int ExecuteNonQuery() return ExecuteReaderObject(behavior, ADP.ExecuteReader, true); } - internal OdbcDataReader ExecuteReaderFromSQLMethod(object[] methodArguments, + internal OdbcDataReader ExecuteReaderFromSQLMethod(object?[]? methodArguments, ODBC32.SQL_API method) { return ExecuteReaderObject(CommandBehavior.Default, method.ToString(), true, methodArguments, method); @@ -579,10 +581,10 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string meth private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, - object[] methodArguments, + object?[]? methodArguments, ODBC32.SQL_API odbcApiMethod) { // MDAC 68324 - OdbcDataReader localReader = null; + OdbcDataReader? localReader = null; try { DisposeDeadDataReader(); // this is a no-op if cmdState is not Fetching @@ -596,14 +598,14 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, ODBC32.RetCode retcode; - OdbcStatementHandle stmt = GetStatementHandle().StatementHandle; - _cmdWrapper.Canceling = false; + OdbcStatementHandle stmt = GetStatementHandle().StatementHandle!; + _cmdWrapper!.Canceling = false; if (null != _weakDataReaderReference) { if (_weakDataReaderReference.IsAlive) { - object target = _weakDataReaderReference.Target; + object? target = _weakDataReaderReference.Target; if (null != target && _weakDataReaderReference.IsAlive) { if (!((OdbcDataReader)target).IsClosed) @@ -617,7 +619,7 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, //Set command properties //Not all drivers support timeout. So fail silently if error - if (!Connection.ProviderInfo.NoQueryTimeout) + if (!Connection!.ProviderInfo.NoQueryTimeout) { TrySetStatementAttribute(stmt, ODBC32.SQL_ATTR.QUERY_TIMEOUT, @@ -668,12 +670,12 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, if (ODBC32.RetCode.SUCCESS != retcode) { - _connection.HandleError(stmt, retcode); + _connection!.HandleError(stmt, retcode); } } bool mustRelease = false; - CNativeBuffer parameterBuffer = _cmdWrapper._nativeParameterBuffer; + CNativeBuffer? parameterBuffer = _cmdWrapper._nativeParameterBuffer; try { @@ -727,7 +729,7 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, else { // any other returncode indicates an error - _connection.HandleError(stmt, retcode); + _connection!.HandleError(stmt, retcode); } } @@ -754,42 +756,42 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, break; case ODBC32.SQL_API.SQLTABLES: - retcode = stmt.Tables((string)methodArguments[0], //TableCatalog - (string)methodArguments[1], //TableSchema, - (string)methodArguments[2], //TableName - (string)methodArguments[3]); //TableType + retcode = stmt.Tables((string)methodArguments![0]!, //TableCatalog + (string)methodArguments[1]!, //TableSchema, + (string)methodArguments[2]!, //TableName + (string)methodArguments[3]!); //TableType break; case ODBC32.SQL_API.SQLCOLUMNS: - retcode = stmt.Columns((string)methodArguments[0], //TableCatalog - (string)methodArguments[1], //TableSchema - (string)methodArguments[2], //TableName - (string)methodArguments[3]); //ColumnName + retcode = stmt.Columns((string)methodArguments![0]!, //TableCatalog + (string)methodArguments[1]!, //TableSchema + (string)methodArguments[2]!, //TableName + (string)methodArguments[3]!); //ColumnName break; case ODBC32.SQL_API.SQLPROCEDURES: - retcode = stmt.Procedures((string)methodArguments[0], //ProcedureCatalog - (string)methodArguments[1], //ProcedureSchema - (string)methodArguments[2]); //procedureName + retcode = stmt.Procedures((string)methodArguments![0]!, //ProcedureCatalog + (string)methodArguments[1]!, //ProcedureSchema + (string)methodArguments[2]!); //procedureName break; case ODBC32.SQL_API.SQLPROCEDURECOLUMNS: - retcode = stmt.ProcedureColumns((string)methodArguments[0], //ProcedureCatalog - (string)methodArguments[1], //ProcedureSchema - (string)methodArguments[2], //procedureName - (string)methodArguments[3]); //columnName + retcode = stmt.ProcedureColumns((string)methodArguments![0]!, //ProcedureCatalog + (string)methodArguments[1]!, //ProcedureSchema + (string)methodArguments[2]!, //procedureName + (string)methodArguments[3]!); //columnName break; case ODBC32.SQL_API.SQLSTATISTICS: - retcode = stmt.Statistics((string)methodArguments[0], //TableCatalog - (string)methodArguments[1], //TableSchema - (string)methodArguments[2], //TableName - (short)methodArguments[3], //IndexTrpe - (short)methodArguments[4]); //Accuracy + retcode = stmt.Statistics((string)methodArguments![0]!, //TableCatalog + (string)methodArguments[1]!, //TableSchema + (string)methodArguments[2]!, //TableName + (short)methodArguments[3]!, //IndexTrpe + (short)methodArguments[4]!); //Accuracy break; case ODBC32.SQL_API.SQLGETTYPEINFO: - retcode = stmt.GetTypeInfo((short)methodArguments[0]); //SQL Type + retcode = stmt.GetTypeInfo((short)methodArguments![0]!); //SQL Type break; default: @@ -801,7 +803,7 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, //Note: Execute will return NO_DATA for Update/Delete non-row returning queries if ((ODBC32.RetCode.SUCCESS != retcode) && (ODBC32.RetCode.NO_DATA != retcode)) { - _connection.HandleError(stmt, retcode); + _connection!.HandleError(stmt, retcode); } } // end SchemaOnly } @@ -809,7 +811,7 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, { if (mustRelease) { - parameterBuffer.DangerousRelease(); + parameterBuffer!.DangerousRelease(); } } @@ -843,12 +845,12 @@ private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, } } } - return localReader; + return localReader!; } - public override object ExecuteScalar() + public override object? ExecuteScalar() { - object value = null; + object? value = null; using (IDataReader reader = ExecuteReaderObject(0, ADP.ExecuteScalar, false)) { if (reader.Read() && (0 < reader.FieldCount)) @@ -862,7 +864,7 @@ public override object ExecuteScalar() internal string GetDiagSqlState() { - return _cmdWrapper.GetDiagSqlState(); + return _cmdWrapper!.GetDiagSqlState(); } private void PropertyChanging() @@ -886,7 +888,7 @@ public override void Prepare() ValidateOpenConnection(ADP.Prepare); - if (0 != (ConnectionState.Fetching & _connection.InternalState)) + if (0 != (ConnectionState.Fetching & _connection!.InternalState)) { throw ADP.OpenReaderExists(); } @@ -899,7 +901,7 @@ public override void Prepare() DisposeDeadDataReader(); GetStatementHandle(); - OdbcStatementHandle stmt = _cmdWrapper.StatementHandle; + OdbcStatementHandle stmt = _cmdWrapper!.StatementHandle!; retcode = stmt.Prepare(CommandText); @@ -927,7 +929,7 @@ private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR if ((sqlState == "HYC00") || (sqlState == "HY092")) { - Connection.FlagUnsupportedStmtAttr(stmtAttribute); + Connection!.FlagUnsupportedStmtAttr(stmtAttribute); } else { @@ -939,7 +941,7 @@ private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR private void ValidateOpenConnection(string methodName) { // see if we have a connection - OdbcConnection connection = Connection; + OdbcConnection? connection = Connection; if (null == connection) { @@ -967,15 +969,15 @@ private void ValidateConnectionAndTransaction(string method) } internal sealed class CMDWrapper { - private OdbcStatementHandle _stmt; // hStmt - private OdbcStatementHandle _keyinfostmt; // hStmt for keyinfo + private OdbcStatementHandle? _stmt; // hStmt + private OdbcStatementHandle? _keyinfostmt; // hStmt for keyinfo - internal OdbcDescriptorHandle _hdesc; // hDesc + internal OdbcDescriptorHandle? _hdesc; // hDesc - internal CNativeBuffer _nativeParameterBuffer; // Native memory for internal memory management + internal CNativeBuffer? _nativeParameterBuffer; // Native memory for internal memory management // (Performance optimization) - internal CNativeBuffer _dataReaderBuf; // Reusable DataReader buffer + internal CNativeBuffer? _dataReaderBuf; // Reusable DataReader buffer private readonly OdbcConnection _connection; // Connection private bool _canceling; // true if the command is canceling @@ -1019,12 +1021,12 @@ internal bool HasBoundColumns } } - internal OdbcStatementHandle StatementHandle + internal OdbcStatementHandle? StatementHandle { get { return _stmt; } } - internal OdbcStatementHandle KeyInfoStatement + internal OdbcStatementHandle? KeyInfoStatement { get { @@ -1053,7 +1055,7 @@ internal void Dispose() } DisposeStatementHandle(); - CNativeBuffer buffer = _nativeParameterBuffer; + CNativeBuffer? buffer = _nativeParameterBuffer; _nativeParameterBuffer = null; if (null != buffer) { @@ -1065,7 +1067,7 @@ internal void Dispose() private void DisposeDescriptorHandle() { - OdbcDescriptorHandle handle = _hdesc; + OdbcDescriptorHandle? handle = _hdesc; if (null != handle) { _hdesc = null; @@ -1077,7 +1079,7 @@ internal void DisposeStatementHandle() DisposeKeyInfoStatementHandle(); DisposeDescriptorHandle(); - OdbcStatementHandle handle = _stmt; + OdbcStatementHandle? handle = _stmt; if (null != handle) { _stmt = null; @@ -1087,7 +1089,7 @@ internal void DisposeStatementHandle() internal void DisposeKeyInfoStatementHandle() { - OdbcStatementHandle handle = _keyinfostmt; + OdbcStatementHandle? handle = _keyinfostmt; if (null != handle) { _keyinfostmt = null; @@ -1099,7 +1101,7 @@ internal void FreeStatementHandle(ODBC32.STMT stmt) { DisposeDescriptorHandle(); - OdbcStatementHandle handle = _stmt; + OdbcStatementHandle? handle = _stmt; if (null != handle) { try @@ -1124,7 +1126,7 @@ internal void FreeStatementHandle(ODBC32.STMT stmt) internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt) { - OdbcStatementHandle handle = _keyinfostmt; + OdbcStatementHandle? handle = _keyinfostmt; if (null != handle) { try @@ -1149,10 +1151,10 @@ internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt) // internal OdbcDescriptorHandle GetDescriptorHandle(ODBC32.SQL_ATTR attribute) { - OdbcDescriptorHandle hdesc = _hdesc; - if (null == _hdesc) + OdbcDescriptorHandle? hdesc = _hdesc; + if (null == hdesc) { - _hdesc = hdesc = new OdbcDescriptorHandle(_stmt, attribute); + _hdesc = hdesc = new OdbcDescriptorHandle(_stmt!, attribute); } return hdesc; } @@ -1160,7 +1162,7 @@ internal OdbcDescriptorHandle GetDescriptorHandle(ODBC32.SQL_ATTR attribute) internal string GetDiagSqlState() { string sqlstate; - _stmt.GetDiagnosticField(out sqlstate); + _stmt!.GetDiagnosticField(out sqlstate); return sqlstate; } @@ -1170,10 +1172,10 @@ internal void StatementErrorHandler(ODBC32.RetCode retcode) { case ODBC32.RetCode.SUCCESS: case ODBC32.RetCode.SUCCESS_WITH_INFO: - _connection.HandleErrorNoThrow(_stmt, retcode); + _connection.HandleErrorNoThrow(_stmt!, retcode); break; default: - throw _connection.HandleErrorNoThrow(_stmt, retcode); + throw _connection.HandleErrorNoThrow(_stmt!, retcode)!; } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs index a855418b9e2f..55a1fd1c208e 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs @@ -14,12 +14,12 @@ public OdbcCommandBuilder() : base() GC.SuppressFinalize(this); } - public OdbcCommandBuilder(OdbcDataAdapter adapter) : this() + public OdbcCommandBuilder(OdbcDataAdapter? adapter) : this() { DataAdapter = adapter; } - public new OdbcDataAdapter DataAdapter + public new OdbcDataAdapter? DataAdapter { get { @@ -123,7 +123,7 @@ public static void DeriveParameters(OdbcCommand command) throw ADP.CommandTextRequired(ADP.DeriveParameters); } - OdbcConnection connection = command.Connection; + OdbcConnection? connection = command.Connection; if (null == connection) { @@ -166,7 +166,7 @@ private static OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnectio // following call ensures that the command has a statement handle allocated CMDWrapper cmdWrapper = command.GetStatementHandle(); - OdbcStatementHandle hstmt = cmdWrapper.StatementHandle; + OdbcStatementHandle hstmt = cmdWrapper.StatementHandle!; int cColsAffected; // maps an enforced 4-part qualified string as follows @@ -176,7 +176,7 @@ private static OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnectio // parts[3] = ProcedureName // string quote = connection.QuoteChar(ADP.DeriveParameters); - string[] parts = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quote, quote, '.', 4, true, SR.ODBC_ODBCCommandText, false); + string?[] parts = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quote, quote, '.', 4, true, SR.ODBC_ODBCCommandText, false); if (null == parts[3]) { // match Everett behavior, if the commandtext is nothing but whitespace set the command text to the whitespace parts[3] = command.CommandText; @@ -251,7 +251,7 @@ public override string QuoteIdentifier(string unquotedIdentifier) return QuoteIdentifier(unquotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */); } - public string QuoteIdentifier(string unquotedIdentifier, OdbcConnection connection) + public string QuoteIdentifier(string unquotedIdentifier, OdbcConnection? connection) { ADP.CheckArgumentNull(unquotedIdentifier, nameof(unquotedIdentifier)); @@ -306,11 +306,11 @@ public override string UnquoteIdentifier(string quotedIdentifier) return UnquoteIdentifier(quotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */); } - public string UnquoteIdentifier(string quotedIdentifier, OdbcConnection connection) + public string UnquoteIdentifier(string quotedIdentifier, OdbcConnection? connection) { ADP.CheckArgumentNull(quotedIdentifier, nameof(quotedIdentifier)); - // if the user has specificed a prefix use the user specified prefix and suffix + // if the user has specified a prefix use the user specified prefix and suffix // otherwise get them from the provider string quotePrefix = QuotePrefix; string quoteSuffix = QuoteSuffix; @@ -330,7 +330,7 @@ public string UnquoteIdentifier(string quotedIdentifier, OdbcConnection connecti quoteSuffix = quotePrefix; } - string unquotedIdentifier; + string? unquotedIdentifier; // by the ODBC spec "If the data source does not support quoted identifiers, a blank is returned." // So if a blank is returned the string is returned unchanged. Otherwise the returned string is used // to unquote the string @@ -344,7 +344,7 @@ public string UnquoteIdentifier(string quotedIdentifier, OdbcConnection connecti { unquotedIdentifier = quotedIdentifier; } - return unquotedIdentifier; + return unquotedIdentifier!; } } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs index 4b7ec8fa72de..9841dd779066 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs @@ -16,12 +16,12 @@ public sealed partial class OdbcConnection : DbConnection, ICloneable { private int _connectionTimeout = ADP.DefaultConnectionTimeout; - private OdbcInfoMessageEventHandler _infoMessageEventHandler; - private WeakReference _weakTransaction; + private OdbcInfoMessageEventHandler? _infoMessageEventHandler; + private WeakReference? _weakTransaction; - private OdbcConnectionHandle _connectionHandle; + private OdbcConnectionHandle? _connectionHandle; - public OdbcConnection(string connectionString) : this() + public OdbcConnection(string? connectionString) : this() { ConnectionString = connectionString; } @@ -32,7 +32,7 @@ private OdbcConnection(OdbcConnection connection) : this() _connectionTimeout = connection._connectionTimeout; } - internal OdbcConnectionHandle ConnectionHandle + internal OdbcConnectionHandle? ConnectionHandle { get { @@ -45,6 +45,7 @@ internal OdbcConnectionHandle ConnectionHandle } } + [AllowNull] public override string ConnectionString { get @@ -110,7 +111,7 @@ public override string DataSource // note: This will return an empty string if the driver keyword was used to connect // see ODBC3.0 Programmers Reference, SQLGetInfo // - return GetInfoStringUnhandled(ODBC32.SQL_INFO.SERVER_NAME, true); + return GetInfoStringUnhandled(ODBC32.SQL_INFO.SERVER_NAME, true)!; } return string.Empty; } @@ -145,7 +146,7 @@ internal OdbcConnectionPoolGroupProviderInfo ProviderInfo get { Debug.Assert(null != this.PoolGroup, "PoolGroup must never be null when accessing ProviderInfo"); - return (OdbcConnectionPoolGroupProviderInfo)this.PoolGroup.ProviderInfo; + return (OdbcConnectionPoolGroupProviderInfo)this.PoolGroup.ProviderInfo!; } } @@ -165,14 +166,14 @@ internal bool IsOpen } } - internal OdbcTransaction LocalTransaction + internal OdbcTransaction? LocalTransaction { get { - OdbcTransaction result = null; + OdbcTransaction? result = null; if (null != _weakTransaction) { - result = ((OdbcTransaction)_weakTransaction.Target); + result = ((OdbcTransaction?)_weakTransaction.Target); } return result; } @@ -200,7 +201,7 @@ public string Driver { if (ProviderInfo.DriverName == null) { - ProviderInfo.DriverName = GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME); + ProviderInfo.DriverName = GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME)!; } return ProviderInfo.DriverName; } @@ -237,7 +238,7 @@ internal bool IsV3Driver } } - public event OdbcInfoMessageEventHandler InfoMessage + public event OdbcInfoMessageEventHandler? InfoMessage { add { @@ -255,7 +256,7 @@ internal char EscapeChar(string method) if (!ProviderInfo.HasEscapeChar) { string escapeCharString; - escapeCharString = GetInfoStringUnhandled(ODBC32.SQL_INFO.SEARCH_PATTERN_ESCAPE); + escapeCharString = GetInfoStringUnhandled(ODBC32.SQL_INFO.SEARCH_PATTERN_ESCAPE)!; Debug.Assert((escapeCharString.Length <= 1), "Can't handle multichar quotes"); ProviderInfo.EscapeChar = (escapeCharString.Length == 1) ? escapeCharString[0] : QuoteChar(method)[0]; } @@ -268,7 +269,7 @@ internal string QuoteChar(string method) if (!ProviderInfo.HasQuoteChar) { string quoteCharString; - quoteCharString = GetInfoStringUnhandled(ODBC32.SQL_INFO.IDENTIFIER_QUOTE_CHAR); + quoteCharString = GetInfoStringUnhandled(ODBC32.SQL_INFO.IDENTIFIER_QUOTE_CHAR)!; Debug.Assert((quoteCharString.Length <= 1), "Can't handle multichar quotes"); ProviderInfo.QuoteChar = (1 == quoteCharString.Length) ? quoteCharString : "\0"; } @@ -287,11 +288,11 @@ internal string QuoteChar(string method) private void RollbackDeadTransaction() { - WeakReference weak = _weakTransaction; + WeakReference? weak = _weakTransaction; if ((null != weak) && !weak.IsAlive) { _weakTransaction = null; - ConnectionHandle.CompleteTransaction(ODBC32.SQL_ROLLBACK); + ConnectionHandle!.CompleteTransaction(ODBC32.SQL_ROLLBACK); } } @@ -315,7 +316,7 @@ object ICloneable.Clone() return clone; } - internal bool ConnectionIsAlive(Exception innerException) + internal bool ConnectionIsAlive(Exception? innerException) { if (IsOpen) { @@ -348,18 +349,18 @@ public override void Close() { InnerConnection.CloseConnection(this, ConnectionFactory); - OdbcConnectionHandle connectionHandle = _connectionHandle; + OdbcConnectionHandle? connectionHandle = _connectionHandle; if (null != connectionHandle) { _connectionHandle = null; // If there is a pending transaction, automatically rollback. - WeakReference weak = _weakTransaction; + WeakReference? weak = _weakTransaction; if (null != weak) { _weakTransaction = null; - IDisposable transaction = weak.Target as OdbcTransaction; + IDisposable? transaction = weak.Target as OdbcTransaction; if ((null != transaction) && weak.IsAlive) { transaction.Dispose(); @@ -379,7 +380,7 @@ internal string GetConnectAttrString(ODBC32.SQL_ATTR attribute) string value = ""; int cbActual = 0; byte[] buffer = new byte[100]; - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle? connectionHandle = ConnectionHandle; if (null != connectionHandle) { ODBC32.RetCode retcode = connectionHandle.GetConnectionAttribute(attribute, buffer, out cbActual); @@ -412,7 +413,7 @@ internal int GetConnectAttr(ODBC32.SQL_ATTR attribute, ODBC32.HANDLER handler) int retval = -1; int cbActual = 0; byte[] buffer = new byte[4]; - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle? connectionHandle = ConnectionHandle; if (null != connectionHandle) { ODBC32.RetCode retcode = connectionHandle.GetConnectionAttribute(attribute, buffer, out cbActual); @@ -442,7 +443,7 @@ internal int GetConnectAttr(ODBC32.SQL_ATTR attribute, ODBC32.HANDLER handler) private string GetDiagSqlState() { - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle connectionHandle = ConnectionHandle!; string sqlstate; connectionHandle.GetDiagnosticField(out sqlstate); return sqlstate; @@ -451,7 +452,7 @@ private string GetDiagSqlState() internal ODBC32.RetCode GetInfoInt16Unhandled(ODBC32.SQL_INFO info, out short resultValue) { byte[] buffer = new byte[2]; - ODBC32.RetCode retcode = ConnectionHandle.GetInfo1(info, buffer); + ODBC32.RetCode retcode = ConnectionHandle!.GetInfo1(info, buffer); resultValue = BitConverter.ToInt16(buffer, 0); return retcode; } @@ -459,7 +460,7 @@ internal ODBC32.RetCode GetInfoInt16Unhandled(ODBC32.SQL_INFO info, out short re internal ODBC32.RetCode GetInfoInt32Unhandled(ODBC32.SQL_INFO info, out int resultValue) { byte[] buffer = new byte[4]; - ODBC32.RetCode retcode = ConnectionHandle.GetInfo1(info, buffer); + ODBC32.RetCode retcode = ConnectionHandle!.GetInfo1(info, buffer); resultValue = BitConverter.ToInt32(buffer, 0); return retcode; } @@ -467,22 +468,22 @@ internal ODBC32.RetCode GetInfoInt32Unhandled(ODBC32.SQL_INFO info, out int resu private int GetInfoInt32Unhandled(ODBC32.SQL_INFO infotype) { byte[] buffer = new byte[4]; - ConnectionHandle.GetInfo1(infotype, buffer); + ConnectionHandle!.GetInfo1(infotype, buffer); return BitConverter.ToInt32(buffer, 0); } - internal string GetInfoStringUnhandled(ODBC32.SQL_INFO info) + internal string? GetInfoStringUnhandled(ODBC32.SQL_INFO info) { return GetInfoStringUnhandled(info, false); } - private string GetInfoStringUnhandled(ODBC32.SQL_INFO info, bool handleError) + private string? GetInfoStringUnhandled(ODBC32.SQL_INFO info, bool handleError) { //SQLGetInfo - string value = null; + string? value = null; short cbActual = 0; byte[] buffer = new byte[100]; - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle? connectionHandle = ConnectionHandle; if (null != connectionHandle) { ODBC32.RetCode retcode = connectionHandle.GetInfo2(info, buffer, out cbActual); @@ -499,7 +500,7 @@ private string GetInfoStringUnhandled(ODBC32.SQL_INFO info, bool handleError) } else if (handleError) { - this.HandleError(ConnectionHandle, retcode); + this.HandleError(connectionHandle, retcode); } } else if (handleError) @@ -510,7 +511,7 @@ private string GetInfoStringUnhandled(ODBC32.SQL_INFO info, bool handleError) } // non-throwing HandleError - internal Exception HandleErrorNoThrow(OdbcHandle hrHandle, ODBC32.RetCode retcode) + internal Exception? HandleErrorNoThrow(OdbcHandle hrHandle, ODBC32.RetCode retcode) { Debug.Assert(retcode != ODBC32.RetCode.INVALID_HANDLE, "retcode must never be ODBC32.RetCode.INVALID_HANDLE"); @@ -537,14 +538,14 @@ internal Exception HandleErrorNoThrow(OdbcHandle hrHandle, ODBC32.RetCode retcod e.Errors.SetSource(this.Driver); } ConnectionIsAlive(e); // this will close and throw if the connection is dead - return (Exception)e; + return e; } return null; } internal void HandleError(OdbcHandle hrHandle, ODBC32.RetCode retcode) { - Exception e = HandleErrorNoThrow(hrHandle, retcode); + Exception? e = HandleErrorNoThrow(hrHandle, retcode); switch (retcode) { case ODBC32.RetCode.SUCCESS: @@ -601,11 +602,11 @@ public static void ReleaseObjectPool() OdbcEnvironment.ReleaseObjectPool(); } - internal OdbcTransaction SetStateExecuting(string method, OdbcTransaction transaction) + internal OdbcTransaction? SetStateExecuting(string method, OdbcTransaction? transaction) { // MDAC 69003 if (null != _weakTransaction) { // transaction may exist - OdbcTransaction weak = (_weakTransaction.Target as OdbcTransaction); + OdbcTransaction? weak = (_weakTransaction.Target as OdbcTransaction); if (transaction != weak) { // transaction doesn't exist if (null == transaction) @@ -778,7 +779,7 @@ internal bool SQLGetFunctions(ODBC32.SQL_API odbcFunction) ODBC32.RetCode retcode; short fExists; Debug.Assert((short)odbcFunction != 0, "SQL_API_ALL_FUNCTIONS is not supported"); - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle? connectionHandle = ConnectionHandle; if (null != connectionHandle) { retcode = connectionHandle.GetFunctions(odbcFunction, out fExists); @@ -921,7 +922,7 @@ internal OdbcTransaction Open_BeginTransaction(IsolationLevel isolevel) }; //Start the transaction - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle connectionHandle = ConnectionHandle!; ODBC32.RetCode retcode = connectionHandle.BeginTransaction(ref isolevel); if (retcode == ODBC32.RetCode.ERROR) { @@ -948,7 +949,7 @@ internal void Open_ChangeDatabase(string value) RollbackDeadTransaction(); //Set the database - OdbcConnectionHandle connectionHandle = ConnectionHandle; + OdbcConnectionHandle connectionHandle = ConnectionHandle!; ODBC32.RetCode retcode = connectionHandle.SetConnectionAttribute3(ODBC32.SQL_ATTR.CURRENT_CATALOG, value, checked((int)value.Length * 2)); if (retcode != ODBC32.RetCode.SUCCESS) @@ -957,7 +958,7 @@ internal void Open_ChangeDatabase(string value) } } - internal string Open_GetServerVersion() + internal string? Open_GetServerVersion() { //SQLGetInfo - SQL_DBMS_VER return GetInfoStringUnhandled(ODBC32.SQL_INFO.DBMS_VER, true); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs index 0bdd4b432cd9..d9d35950a2e6 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs @@ -5,6 +5,7 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; namespace System.Data.Odbc @@ -26,20 +27,21 @@ public override DbProviderFactory ProviderFactory } } - protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) + protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningObject) { - DbConnectionInternal result = new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString); + // TODO: owningObject may actually be null (see DbConnectionPool.CreateObject), in which case this will throw... + DbConnectionInternal result = new OdbcConnectionOpen((owningObject as OdbcConnection)!, (options as OdbcConnectionString)!); return result; } - protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous) + protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions? previous) { Debug.Assert(!string.IsNullOrEmpty(connectionString), "empty connectionString"); OdbcConnectionString result = new OdbcConnectionString(connectionString, (null != previous)); return result; } - protected override DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) + protected override DbConnectionPoolGroupOptions? CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) { // At this time, the ODBC provider only supports native pooling so we // simply return NULL to indicate that. @@ -60,20 +62,20 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal Debug.Assert(odbcOuterConnection != null, "outer connection may not be null."); // get the DBMS Name - object driverName = null; - string stringValue = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME); + object? driverName = null; + string? stringValue = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME); if (stringValue != null) { driverName = stringValue; } - Stream XMLStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.Odbc.OdbcMetaData.xml"); + Stream? XMLStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.Odbc.OdbcMetaData.xml"); cacheMetaDataFactory = true; Debug.Assert(XMLStream != null, "XMLstream may not be null."); - string versionString = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DBMS_VER); + string versionString = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DBMS_VER)!; return new OdbcMetaDataFactory(XMLStream, versionString, @@ -81,9 +83,9 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal odbcOuterConnection); } - internal override DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection) + internal override DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnection? connection) { - OdbcConnection c = (connection as OdbcConnection); + OdbcConnection? c = (connection as OdbcConnection); if (null != c) { return c.PoolGroup; @@ -91,9 +93,9 @@ internal override DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection conn return null; } - internal override DbConnectionInternal GetInnerConnection(DbConnection connection) + internal override DbConnectionInternal? GetInnerConnection(DbConnection connection) { - OdbcConnection c = (connection as OdbcConnection); + OdbcConnection? c = (connection as OdbcConnection); if (null != c) { return c.InnerConnection; @@ -103,7 +105,7 @@ internal override DbConnectionInternal GetInnerConnection(DbConnection connectio internal override void PermissionDemand(DbConnection outerConnection) { - OdbcConnection c = (outerConnection as OdbcConnection); + OdbcConnection? c = (outerConnection as OdbcConnection); if (null != c) { c.PermissionDemand(); @@ -112,7 +114,7 @@ internal override void PermissionDemand(DbConnection outerConnection) internal override void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup) { - OdbcConnection c = (outerConnection as OdbcConnection); + OdbcConnection? c = (outerConnection as OdbcConnection); if (null != c) { c.PoolGroup = poolGroup; @@ -121,7 +123,7 @@ internal override void SetConnectionPoolGroup(DbConnection outerConnection, DbCo internal override void SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to) { - OdbcConnection c = (owningObject as OdbcConnection); + OdbcConnection? c = (owningObject as OdbcConnection); if (null != c) { c.SetInnerConnectionEvent(to); @@ -130,7 +132,7 @@ internal override void SetInnerConnectionEvent(DbConnection owningObject, DbConn internal override bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from) { - OdbcConnection c = (owningObject as OdbcConnection); + OdbcConnection? c = (owningObject as OdbcConnection); if (null != c) { return c.SetInnerConnectionFrom(to, from); @@ -140,7 +142,7 @@ internal override bool SetInnerConnectionFrom(DbConnection owningObject, DbConne internal override void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to) { - OdbcConnection c = (owningObject as OdbcConnection); + OdbcConnection? c = (owningObject as OdbcConnection); if (null != c) { c.SetInnerConnectionTo(to); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHelper.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHelper.cs index 90e755ecd37c..a84658b4b543 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHelper.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHelper.cs @@ -12,8 +12,8 @@ public sealed partial class OdbcConnection : DbConnection { private static readonly DbConnectionFactory s_connectionFactory = OdbcConnectionFactory.SingletonInstance; - private DbConnectionOptions _userConnectionOptions; - private DbConnectionPoolGroup _poolGroup; + private DbConnectionOptions? _userConnectionOptions; + private DbConnectionPoolGroup? _poolGroup; private DbConnectionInternal _innerConnection; private int _closeCount; @@ -60,11 +60,11 @@ internal DbConnectionFactory ConnectionFactory } } - internal DbConnectionOptions ConnectionOptions + internal DbConnectionOptions? ConnectionOptions { get { - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = PoolGroup; + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; return ((null != poolGroup) ? poolGroup.ConnectionOptions : null); } } @@ -72,11 +72,11 @@ internal DbConnectionOptions ConnectionOptions private string ConnectionString_Get() { bool hidePassword = InnerConnection.ShouldHidePassword; - DbConnectionOptions connectionOptions = UserConnectionOptions; + DbConnectionOptions? connectionOptions = UserConnectionOptions; return ((null != connectionOptions) ? connectionOptions.UsersConnectionString(hidePassword) : ""); } - private void ConnectionString_Set(string value) + private void ConnectionString_Set(string? value) { DbConnectionPoolKey key = new DbConnectionPoolKey(value); @@ -85,8 +85,8 @@ private void ConnectionString_Set(string value) private void ConnectionString_Set(DbConnectionPoolKey key) { - DbConnectionOptions connectionOptions = null; - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); + DbConnectionOptions? connectionOptions = null; + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); DbConnectionInternal connectionInternal = InnerConnection; bool flag = connectionInternal.AllowSetConnectionString; if (flag) @@ -113,7 +113,7 @@ internal DbConnectionInternal InnerConnection } } - internal System.Data.ProviderBase.DbConnectionPoolGroup PoolGroup + internal System.Data.ProviderBase.DbConnectionPoolGroup? PoolGroup { get { @@ -127,7 +127,7 @@ internal System.Data.ProviderBase.DbConnectionPoolGroup PoolGroup } - internal DbConnectionOptions UserConnectionOptions + internal DbConnectionOptions? UserConnectionOptions { get { @@ -152,9 +152,8 @@ internal void AddWeakReference(object value, int tag) protected override DbCommand CreateDbCommand() { - DbCommand command = null; DbProviderFactory providerFactory = ConnectionFactory.ProviderFactory; - command = providerFactory.CreateCommand(); + DbCommand command = providerFactory.CreateCommand()!; command.Connection = this; return command; } @@ -184,11 +183,11 @@ public override DataTable GetSchema(string collectionName) return this.GetSchema(collectionName, null); } - public override DataTable GetSchema(string collectionName, string[] restrictionValues) + public override DataTable GetSchema(string collectionName, string?[]? restrictionValues) { // NOTE: This is virtual because not all providers may choose to support // returning schema data - return InnerConnection.GetSchema(ConnectionFactory, PoolGroup, this, collectionName, restrictionValues); + return InnerConnection.GetSchema(ConnectionFactory, PoolGroup!, this, collectionName, restrictionValues); } internal void NotifyWeakReference(int message) @@ -199,13 +198,13 @@ internal void NotifyWeakReference(int message) internal void PermissionDemand() { Debug.Assert(DbConnectionClosedConnecting.SingletonInstance == _innerConnection, "not connecting"); - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = PoolGroup; - DbConnectionOptions connectionOptions = ((null != poolGroup) ? poolGroup.ConnectionOptions : null); + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; + DbConnectionOptions? connectionOptions = ((null != poolGroup) ? poolGroup.ConnectionOptions : null); if ((null == connectionOptions) || connectionOptions.IsEmpty) { throw ADP.NoConnectionString(); } - DbConnectionOptions userConnectionOptions = UserConnectionOptions; + DbConnectionOptions? userConnectionOptions = UserConnectionOptions; Debug.Assert(null != userConnectionOptions, "null UserConnectionOptions"); } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs index 2c6f7c71487e..008facb51311 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs @@ -19,7 +19,7 @@ internal OdbcConnection OuterConnection { get { - OdbcConnection outerConnection = (OdbcConnection)Owner; + OdbcConnection? outerConnection = (OdbcConnection?)Owner; if (null == outerConnection) throw ODBC.OpenConnectionNoOwner(); @@ -32,7 +32,9 @@ public override string ServerVersion { get { - return OuterConnection.Open_GetServerVersion(); + // TODO-NULLABLE: This seems like it returns null if the connection is open, whereas the docs say it should throw + // InvalidOperationException + return OuterConnection.Open_GetServerVersion()!; } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs index e498e9858585..b49f953fecdb 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs @@ -2,14 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Data.ProviderBase; +using System.Diagnostics; namespace System.Data.Odbc { internal sealed class OdbcConnectionPoolGroupProviderInfo : DbConnectionPoolGroupProviderInfo { - private string _driverName; - private string _driverVersion; - private string _quoteChar; + private string? _driverName; + private string? _driverVersion; + private string? _quoteChar; private char _escapeChar; private bool _hasQuoteChar; @@ -35,7 +36,7 @@ internal sealed class OdbcConnectionPoolGroupProviderInfo : DbConnectionPoolGrou // flags for unsupported Functions private bool _noSqlPrimaryKeys; - internal string DriverName + internal string? DriverName { get { @@ -47,7 +48,7 @@ internal string DriverName } } - internal string DriverVersion + internal string? DriverVersion { get { @@ -82,6 +83,7 @@ internal string QuoteChar { get { + Debug.Assert(_quoteChar != null, "QuoteChar getter called but no quote char was set"); return _quoteChar; } set diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs index e17edacb2322..74790e05ac1f 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs @@ -12,13 +12,13 @@ internal sealed class OdbcConnectionString : DbConnectionOptions // used by pooling classes so it is much easier to verify correctness // when not worried about the class being modified during execution - private readonly string _expandedConnectionString; + private readonly string? _expandedConnectionString; internal OdbcConnectionString(string connectionString, bool validate) : base(connectionString, null, true) { if (!validate) { - string filename = null; + string? filename = null; int position = 0; _expandedConnectionString = ExpandDataDirectories(ref filename, ref position); } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs index 877275e2b865..ae68e130447f 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Data.Odbc { @@ -30,16 +31,16 @@ private enum Keywords { DbConnectionStringKeywords.Dsn, Keywords.Dsn } }; - private string[] _knownKeywords; + private string[]? _knownKeywords; private string _dsn = DbConnectionStringDefaults.Dsn; private string _driver = DbConnectionStringDefaults.Driver; - public OdbcConnectionStringBuilder() : this((string)null) + public OdbcConnectionStringBuilder() : this(null) { } - public OdbcConnectionStringBuilder(string connectionString) : base(true) + public OdbcConnectionStringBuilder(string? connectionString) : base(true) { if (!string.IsNullOrEmpty(connectionString)) { @@ -47,6 +48,7 @@ public OdbcConnectionStringBuilder(string connectionString) : base(true) } } + [AllowNull] public override object this[string keyword] { get @@ -119,7 +121,7 @@ public override ICollection Keys { get { - string[] knownKeywords = _knownKeywords; + string[]? knownKeywords = _knownKeywords; if (null == knownKeywords) { knownKeywords = s_validKeywords; @@ -245,7 +247,7 @@ private void SetValue(string keyword, string value) base[keyword] = value; } - public override bool TryGetValue(string keyword, out object value) + public override bool TryGetValue(string keyword, [NotNullWhen(true)] out object? value) { ADP.CheckArgumentNull(keyword, nameof(keyword)); Keywords index; diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs index 2235d13909b1..29b6dcc149f7 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs @@ -10,24 +10,24 @@ public sealed class OdbcDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable private static readonly object s_eventRowUpdated = new object(); private static readonly object s_eventRowUpdating = new object(); - private OdbcCommand _deleteCommand, _insertCommand, _selectCommand, _updateCommand; + private OdbcCommand? _deleteCommand, _insertCommand, _selectCommand, _updateCommand; public OdbcDataAdapter() : base() { GC.SuppressFinalize(this); } - public OdbcDataAdapter(OdbcCommand selectCommand) : this() + public OdbcDataAdapter(OdbcCommand? selectCommand) : this() { SelectCommand = selectCommand; } - public OdbcDataAdapter(string selectCommandText, OdbcConnection selectConnection) : this() + public OdbcDataAdapter(string? selectCommandText, OdbcConnection? selectConnection) : this() { SelectCommand = new OdbcCommand(selectCommandText, selectConnection); } - public OdbcDataAdapter(string selectCommandText, string selectConnectionString) : this() + public OdbcDataAdapter(string? selectCommandText, string? selectConnectionString) : this() { OdbcConnection connection = new OdbcConnection(selectConnectionString); SelectCommand = new OdbcCommand(selectCommandText, connection); @@ -38,55 +38,55 @@ private OdbcDataAdapter(OdbcDataAdapter from) : base(from) GC.SuppressFinalize(this); } - public new OdbcCommand DeleteCommand + public new OdbcCommand? DeleteCommand { get { return _deleteCommand; } set { _deleteCommand = value; } } - IDbCommand IDbDataAdapter.DeleteCommand + IDbCommand? IDbDataAdapter.DeleteCommand { get { return _deleteCommand; } - set { _deleteCommand = (OdbcCommand)value; } + set { _deleteCommand = (OdbcCommand?)value; } } - public new OdbcCommand InsertCommand + public new OdbcCommand? InsertCommand { get { return _insertCommand; } set { _insertCommand = value; } } - IDbCommand IDbDataAdapter.InsertCommand + IDbCommand? IDbDataAdapter.InsertCommand { get { return _insertCommand; } - set { _insertCommand = (OdbcCommand)value; } + set { _insertCommand = (OdbcCommand?)value; } } - public new OdbcCommand SelectCommand + public new OdbcCommand? SelectCommand { get { return _selectCommand; } set { _selectCommand = value; } } - IDbCommand IDbDataAdapter.SelectCommand + IDbCommand? IDbDataAdapter.SelectCommand { get { return _selectCommand; } - set { _selectCommand = (OdbcCommand)value; } + set { _selectCommand = (OdbcCommand?)value; } } - public new OdbcCommand UpdateCommand + public new OdbcCommand? UpdateCommand { get { return _updateCommand; } set { _updateCommand = value; } } - IDbCommand IDbDataAdapter.UpdateCommand + IDbCommand? IDbDataAdapter.UpdateCommand { get { return _updateCommand; } - set { _updateCommand = (OdbcCommand)value; } + set { _updateCommand = (OdbcCommand?)value; } } - public event OdbcRowUpdatedEventHandler RowUpdated + public event OdbcRowUpdatedEventHandler? RowUpdated { add { @@ -98,18 +98,18 @@ public event OdbcRowUpdatedEventHandler RowUpdated } } - public event OdbcRowUpdatingEventHandler RowUpdating + public event OdbcRowUpdatingEventHandler? RowUpdating { add { - OdbcRowUpdatingEventHandler handler = (OdbcRowUpdatingEventHandler)Events[s_eventRowUpdating]; + OdbcRowUpdatingEventHandler? handler = (OdbcRowUpdatingEventHandler?)Events[s_eventRowUpdating]; // MDAC 58177, 64513 // prevent someone from registering two different command builders on the adapter by // silently removing the old one - if ((null != handler) && (value.Target is OdbcCommandBuilder)) + if ((null != handler) && (value!.Target is OdbcCommandBuilder)) { - OdbcRowUpdatingEventHandler d = (OdbcRowUpdatingEventHandler)ADP.FindBuilder(handler); + OdbcRowUpdatingEventHandler? d = (OdbcRowUpdatingEventHandler?)ADP.FindBuilder(handler); if (null != d) { Events.RemoveHandler(s_eventRowUpdating, d); @@ -129,19 +129,19 @@ object ICloneable.Clone() return new OdbcDataAdapter(this); } - protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new OdbcRowUpdatedEventArgs(dataRow, command, statementType, tableMapping); } - protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new OdbcRowUpdatingEventArgs(dataRow, command, statementType, tableMapping); } protected override void OnRowUpdated(RowUpdatedEventArgs value) { - OdbcRowUpdatedEventHandler handler = (OdbcRowUpdatedEventHandler)Events[s_eventRowUpdated]; + OdbcRowUpdatedEventHandler? handler = (OdbcRowUpdatedEventHandler?)Events[s_eventRowUpdated]; if ((null != handler) && (value is OdbcRowUpdatedEventArgs)) { handler(this, (OdbcRowUpdatedEventArgs)value); @@ -151,7 +151,7 @@ protected override void OnRowUpdated(RowUpdatedEventArgs value) protected override void OnRowUpdating(RowUpdatingEventArgs value) { - OdbcRowUpdatingEventHandler handler = (OdbcRowUpdatingEventHandler)Events[s_eventRowUpdating]; + OdbcRowUpdatingEventHandler? handler = (OdbcRowUpdatingEventHandler?)Events[s_eventRowUpdating]; if ((null != handler) && (value is OdbcRowUpdatingEventArgs)) { handler(this, (OdbcRowUpdatingEventArgs)value); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs index d66f5f28a6a0..87c0e9238ab2 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs @@ -15,12 +15,12 @@ namespace System.Data.Odbc { public sealed class OdbcDataReader : DbDataReader { - private OdbcCommand _command; + private OdbcCommand? _command; private int _recordAffected = -1; - private FieldNameLookup _fieldNameLookup; + private FieldNameLookup? _fieldNameLookup; - private DbCache _dataCache; + private DbCache? _dataCache; private enum HasRowsStatus { DontKnow = 0, @@ -51,10 +51,10 @@ private enum HasRowsStatus // the DataReader must not free the statement handle. this is done by the command // - private MetaData[] _metadata; - private DataTable _schemaTable; // MDAC 68336 + private MetaData[]? _metadata; + private DataTable? _schemaTable; // MDAC 68336 private readonly string _cmdText; // get a copy in case the command text on the command is changed ... - private CMDWrapper _cmdWrapper; + private CMDWrapper? _cmdWrapper; internal OdbcDataReader(OdbcCommand command, CMDWrapper cmdWrapper, CommandBehavior commandbehavior) { @@ -69,7 +69,7 @@ private CNativeBuffer Buffer { get { - CNativeBuffer value = _cmdWrapper._dataReaderBuf; + CNativeBuffer? value = _cmdWrapper!._dataReaderBuf; if (null == value) { Debug.Fail("object is disposed"); @@ -79,7 +79,7 @@ private CNativeBuffer Buffer } } - private OdbcConnection Connection + private OdbcConnection? Connection { get { @@ -94,7 +94,7 @@ private OdbcConnection Connection } } - internal OdbcCommand Command + internal OdbcCommand? Command { get { @@ -110,13 +110,13 @@ private OdbcStatementHandle StatementHandle { get { - return _cmdWrapper.StatementHandle; + return _cmdWrapper!.StatementHandle!; } } private OdbcStatementHandle KeyInfoStatementHandle { - get { return _cmdWrapper.KeyInfoStatement; } + get { return _cmdWrapper!.KeyInfoStatement!; } } internal bool IsBehavior(CommandBehavior behavior) @@ -178,7 +178,7 @@ public override int FieldCount ODBC32.RetCode retcode = this.FieldCountNoThrow(out cColsAffected); if (retcode != ODBC32.RetCode.SUCCESS) { - Connection.HandleError(StatementHandle, retcode); + Connection!.HandleError(StatementHandle, retcode); } } return ((null != _dataCache) ? _dataCache._count : 0); @@ -224,7 +224,7 @@ internal ODBC32.RetCode FieldCountNoThrow(out short cColsAffected) { // we need to search for the first hidden column // - if (!Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !Connection.ProviderInfo.NoSqlSoptSSHiddenColumns) + if (!Connection!.ProviderInfo.NoSqlSoptSSNoBrowseTable && !Connection.ProviderInfo.NoSqlSoptSSHiddenColumns) { for (int i = 0; i < cColsAffected; i++) { @@ -317,9 +317,9 @@ public override void Close() private void Close(bool disposing) { - Exception error = null; + Exception? error = null; - CMDWrapper wrapper = _cmdWrapper; + CMDWrapper? wrapper = _cmdWrapper; if (null != wrapper && wrapper.StatementHandle != null) { // disposing @@ -339,7 +339,7 @@ private void Close(bool disposing) { // Output Parameters are not guareenteed to be returned until all the data // from any restssets are read, so we do this after the above NextResult call(s) - _command.Parameters.GetOutputValues(_cmdWrapper); + _command.Parameters.GetOutputValues(_cmdWrapper!); } wrapper.FreeStatementHandle(ODBC32.STMT.CLOSE); _command.CloseFromDataReader(); @@ -407,7 +407,10 @@ public override string GetDataTypeName(int i) { info._typename = GetColAttributeStr(i, ODBC32.SQL_DESC.TYPE_NAME, ODBC32.SQL_COLUMN.TYPE_NAME, ODBC32.HANDLER.THROW); } +// TODO-NULLABLE: Behavior change probably needed here - when there's no data type, we mostly probably need to throw instead of returning null. +#nullable disable return info._typename; +#nullable enable } throw ADP.DataReaderNoData(); } @@ -545,7 +548,7 @@ internal object GetValue(int i, TypeMap typemap) //will work), and then query for a speicial SQLServer specific attribute. if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { int dummy; bool isNotDbNull = QueryFieldInfo(i, ODBC32.SQL_C.BINARY, out dummy); @@ -557,7 +560,7 @@ internal object GetValue(int i, TypeMap typemap) return GetValue(i, TypeMap.FromSqlType(subtype)); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); @@ -573,11 +576,11 @@ public override object GetValue(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { _dataCache[i] = GetValue(i, GetSqlType(i)); } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -601,7 +604,7 @@ private TypeMap GetSqlType(int i) //Note: Types are always returned (advertised) from ODBC as SQL_TYPEs, and //are always bound by the user as SQL_C types. TypeMap typeMap; - DbSchemaInfo info = _dataCache.GetSchema(i); + DbSchemaInfo info = _dataCache!.GetSchema(i); if (!info._dbtype.HasValue) { info._dbtype = unchecked((ODBC32.SQL_TYPE)(int)GetColAttribute(i, ODBC32.SQL_DESC.CONCISE_TYPE, ODBC32.SQL_COLUMN.TYPE, ODBC32.HANDLER.THROW)); @@ -617,14 +620,14 @@ private TypeMap GetSqlType(int i) { typeMap = TypeMap.FromSqlType(info._dbtype.Value); } - Connection.SetSupportedType(info._dbtype.Value); + Connection!.SetSupportedType(info._dbtype.Value); return typeMap; } public override bool IsDBNull(int i) { - // Note: ODBC SQLGetData doesn't allow retriving the column value twice. - // The reational is that for ForwardOnly access (the default and LCD of drivers) + // Note: ODBC SQLGetData doesn't allow retrieving the column value twice. + // The rationale is that for ForwardOnly access (the default and LCD of drivers) // we cannot obtain the data more than once, and even GetData(0) (to determine is-null) // still obtains data for fixed length types. @@ -650,7 +653,7 @@ public override bool IsDBNull(int i) // But, to minimize regressions, we will continue caching the fixed-size values (case 2), even with SequentialAccess // only in case of SequentialAccess with variable length data types (case 3), we will use GetData with zero length. - object cachedObj = _dataCache[i]; + object? cachedObj = _dataCache![i]; if (cachedObj != null) { // case 4 - if cached object was created before, use it @@ -686,14 +689,14 @@ private object internalGetByte(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.UTINYINT)) { _dataCache[i] = Buffer.ReadByte(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -706,14 +709,14 @@ private object internalGetChar(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.WCHAR)) { _dataCache[i] = Buffer.ReadChar(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -726,14 +729,14 @@ private object internalGetInt16(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.SSHORT)) { _dataCache[i] = Buffer.ReadInt16(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -746,14 +749,14 @@ private object internalGetInt32(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.SLONG)) { _dataCache[i] = Buffer.ReadInt32(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -773,7 +776,7 @@ private object internalGetInt64(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.WCHAR)) { @@ -781,7 +784,7 @@ private object internalGetInt64(int i) _dataCache[i] = long.Parse(value, CultureInfo.InvariantCulture); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -794,14 +797,14 @@ private object internalGetBoolean(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.BIT)) { _dataCache[i] = Buffer.MarshalToManaged(0, ODBC32.SQL_C.BIT, -1); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -814,14 +817,14 @@ private object internalGetFloat(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.REAL)) { _dataCache[i] = Buffer.ReadSingle(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -835,14 +838,14 @@ private object internalGetDate(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.TYPE_DATE)) { _dataCache[i] = Buffer.MarshalToManaged(0, ODBC32.SQL_C.TYPE_DATE, -1); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -856,14 +859,14 @@ private object internalGetDateTime(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.TYPE_TIMESTAMP)) { _dataCache[i] = Buffer.MarshalToManaged(0, ODBC32.SQL_C.TYPE_TIMESTAMP, -1); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -884,11 +887,11 @@ private object internalGetDecimal(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.WCHAR)) { - string s = null; + string? s = null; try { s = (string)Buffer.MarshalToManaged(0, ODBC32.SQL_C.WCHAR, ODBC32.SQL_NTS); @@ -901,7 +904,7 @@ private object internalGetDecimal(int i) } } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -914,14 +917,14 @@ private object internalGetDouble(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.DOUBLE)) { _dataCache[i] = Buffer.ReadDouble(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -935,14 +938,14 @@ private object internalGetGuid(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.GUID)) { _dataCache[i] = Buffer.ReadGuid(0); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -956,7 +959,7 @@ private object internalGetString(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { // Obtain _ALL_ the characters // Note: We can bind directly as WCHAR in ODBC and the DM will convert to and @@ -1049,7 +1052,7 @@ private object internalGetString(int i) _dataCache[i] = builder.ToString(); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -1063,14 +1066,14 @@ private object internalGetTime(int i) { if (_isRead) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { if (GetData(i, ODBC32.SQL_C.TYPE_TIME)) { _dataCache[i] = Buffer.MarshalToManaged(0, ODBC32.SQL_C.TYPE_TIME, -1); } } - return _dataCache[i]; + return _dataCache[i]!; } throw ADP.DataReaderNoData(); } @@ -1087,17 +1090,17 @@ private void SetCurrentRowColumnInfo(int row, int column) } } - public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) + public override long GetBytes(int i, long dataIndex, byte[]? buffer, int bufferIndex, int length) { return GetBytesOrChars(i, dataIndex, buffer, false /* bytes buffer */, bufferIndex, length); } - public override long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) + public override long GetChars(int i, long dataIndex, char[]? buffer, int bufferIndex, int length) { return GetBytesOrChars(i, dataIndex, buffer, true /* chars buffer */, bufferIndex, length); } // unify the implementation of GetChars and GetBytes to prevent code duplicate - private long GetBytesOrChars(int i, long dataIndex, Array buffer, bool isCharsBuffer, int bufferIndex, int length) + private long GetBytesOrChars(int i, long dataIndex, Array? buffer, bool isCharsBuffer, int bufferIndex, int length) { if (IsClosed) { @@ -1133,13 +1136,13 @@ private long GetBytesOrChars(int i, long dataIndex, Array buffer, bool isCharsBu // use the cache - preserve the original behavior to minimize regression risk // 4. sequential access, no cache: (fixed now) user reads the bytes/chars in sequential order (no cache) - object cachedObj = null; // The cached object (if there is one) + object? cachedObj = null; // The cached object (if there is one) // Get cached object, ensure the correct type using explicit cast, to preserve same behavior as before if (isCharsBuffer) - cachedObj = (string)_dataCache[i]; + cachedObj = (string?)_dataCache![i]; else - cachedObj = (byte[])_dataCache[i]; + cachedObj = (byte[]?)_dataCache![i]; bool isRandomAccess = !IsCommandBehavior(CommandBehavior.SequentialAccess); @@ -1354,7 +1357,7 @@ private long GetBytesOrChars(int i, long dataIndex, Array buffer, bool isCharsBu // fill the user's buffer (char[] or byte[], depending on isCharsBuffer) // if buffer is null, just skip the bytesOrCharsLength bytes or chars - private int readBytesOrCharsSequentialAccess(int i, Array buffer, bool isCharsBuffer, int bufferIndex, long bytesOrCharsLength) + private int readBytesOrCharsSequentialAccess(int i, Array? buffer, bool isCharsBuffer, int bufferIndex, long bytesOrCharsLength) { Debug.Assert(bufferIndex >= 0, "Negative buffer index"); Debug.Assert(bytesOrCharsLength >= 0, "Negative number of bytes or chars to read"); @@ -1477,7 +1480,7 @@ private int readBytesOrCharsSequentialAccess(int i, Array buffer, bool isCharsBu private object internalGetBytes(int i) { - if (_dataCache.AccessIndex(i) == null) + if (_dataCache!.AccessIndex(i) == null) { // Obtain _ALL_ the bytes... // The first time GetData returns the true length (so we have to min it). @@ -1536,7 +1539,7 @@ private object internalGetBytes(int i) _dataCache[i] = rgBytes; } } - return _dataCache[i]; + return _dataCache[i]!; } // GetColAttribute @@ -1555,7 +1558,7 @@ private SQLLEN GetColAttribute(int iColumn, ODBC32.SQL_DESC v3FieldId, ODBC32.SQ ODBC32.RetCode retcode; // protect against dead connection, dead or canceling command. - if ((Connection == null) || _cmdWrapper.Canceling) + if ((Connection == null) || _cmdWrapper!.Canceling) { return -1; } @@ -1578,7 +1581,7 @@ private SQLLEN GetColAttribute(int iColumn, ODBC32.SQL_DESC v3FieldId, ODBC32.SQ { if (retcode == ODBC32.RetCode.ERROR) { - if ("HY091" == Command.GetDiagSqlState()) + if ("HY091" == Command!.GetDiagSqlState()) { Connection.FlagUnsupportedColAttr(v3FieldId, v2FieldId); } @@ -1601,7 +1604,7 @@ private SQLLEN GetColAttribute(int iColumn, ODBC32.SQL_DESC v3FieldId, ODBC32.SQ // returns the stringvalue of the FieldIdentifier field of the column // or null if the string returned was empty or if the FieldIdentifier wasn't supported by the driver // - private string GetColAttributeStr(int i, ODBC32.SQL_DESC v3FieldId, ODBC32.SQL_COLUMN v2FieldId, ODBC32.HANDLER handler) + private string? GetColAttributeStr(int i, ODBC32.SQL_DESC v3FieldId, ODBC32.SQL_COLUMN v2FieldId, ODBC32.HANDLER handler) { ODBC32.RetCode retcode; short cchNameLength = 0; @@ -1609,10 +1612,10 @@ private string GetColAttributeStr(int i, ODBC32.SQL_DESC v3FieldId, ODBC32.SQL_C CNativeBuffer buffer = Buffer; buffer.WriteInt16(0, 0); - OdbcStatementHandle stmt = StatementHandle; + OdbcStatementHandle? stmt = StatementHandle; // protect against dead connection - if (Connection == null || _cmdWrapper.Canceling || stmt == null) + if (Connection == null || _cmdWrapper!.Canceling || stmt == null) { return ""; } @@ -1633,7 +1636,7 @@ private string GetColAttributeStr(int i, ODBC32.SQL_DESC v3FieldId, ODBC32.SQL_C { if (retcode == ODBC32.RetCode.ERROR) { - if ("HY091" == Command.GetDiagSqlState()) + if ("HY091" == Command!.GetDiagSqlState()) { Connection.FlagUnsupportedColAttr(v3FieldId, v2FieldId); } @@ -1651,12 +1654,12 @@ private string GetColAttributeStr(int i, ODBC32.SQL_DESC v3FieldId, ODBC32.SQL_C // todo: Another 3.0 only attribute that is guaranteed to fail on V2 driver. // need to special case this for V2 drivers. // - private string GetDescFieldStr(int i, ODBC32.SQL_DESC attribute, ODBC32.HANDLER handler) + private string? GetDescFieldStr(int i, ODBC32.SQL_DESC attribute, ODBC32.HANDLER handler) { int numericAttribute = 0; // protect against dead connection, dead or canceling command. - if ((Connection == null) || _cmdWrapper.Canceling) + if ((Connection == null) || _cmdWrapper!.Canceling) { return ""; } @@ -1684,7 +1687,7 @@ private string GetDescFieldStr(int i, ODBC32.SQL_DESC attribute, ODBC32.HANDLER { if (retcode == ODBC32.RetCode.ERROR) { - if ("HY091" == Command.GetDiagSqlState()) + if ("HY091" == Command!.GetDiagSqlState()) { Connection.FlagUnsupportedColAttr(attribute, (ODBC32.SQL_COLUMN)0); } @@ -1786,7 +1789,7 @@ private bool GetData(int i, ODBC32.SQL_C sqlctype, int cb, out int cbLengthOrInd // Thus, ignore NO_DATA for variable length data, but raise exception for fixed-size types if (sqlctype != ODBC32.SQL_C.WCHAR && sqlctype != ODBC32.SQL_C.BINARY) { - Connection.HandleError(StatementHandle, retcode); + Connection!.HandleError(StatementHandle, retcode); } if (cbActual == (IntPtr)ODBC32.SQL_NO_TOTAL) @@ -1797,7 +1800,7 @@ private bool GetData(int i, ODBC32.SQL_C sqlctype, int cb, out int cbLengthOrInd break; default: - Connection.HandleError(StatementHandle, retcode); + Connection!.HandleError(StatementHandle, retcode); break; } @@ -1810,7 +1813,7 @@ private bool GetData(int i, ODBC32.SQL_C sqlctype, int cb, out int cbLengthOrInd // Store the DBNull value in cache. Note that if we need to do it, because second call into the SQLGetData returns NO_DATA, which means // we already consumed the value (see above) and the NULL information is lost. By storing the null in cache, we avoid second call into the driver // for the same row/column. - _dataCache[i] = DBNull.Value; + _dataCache![i] = DBNull.Value; // the indicator is never -1 (and it should not actually be used if the data is DBNull) cbLengthOrIndicator = 0; return false; @@ -1864,7 +1867,7 @@ public override bool Read() switch (retcode) { case ODBC32.RetCode.SUCCESS_WITH_INFO: - Connection.HandleErrorNoThrow(StatementHandle, retcode); + Connection!.HandleErrorNoThrow(StatementHandle, retcode); _hasRows = HasRowsStatus.HasRows; _isRead = true; break; @@ -1880,11 +1883,11 @@ public override bool Read() } break; default: - Connection.HandleError(StatementHandle, retcode); + Connection!.HandleError(StatementHandle, retcode); break; } //Null out previous cached row values. - _dataCache.FlushValues(); + _dataCache!.FlushValues(); // if CommandBehavior == SingleRow we set _noMoreResults to true so that following reads will fail if (IsCommandBehavior(CommandBehavior.SingleRow)) @@ -1961,7 +1964,7 @@ private bool NextResult(bool disposing, bool allresults) _schemaTable = null; int loop = 0; // infinite loop protection, max out after 2000 consecutive failed results - OdbcErrorCollection errors = null; // SQLBU 342112 + OdbcErrorCollection? errors = null; // SQLBU 342112 do { _isValidResult = false; @@ -1971,7 +1974,7 @@ private bool NextResult(bool disposing, bool allresults) if (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO) { - Connection.HandleErrorNoThrow(StatementHandle, retcode); + Connection!.HandleErrorNoThrow(StatementHandle, retcode); } else if (!disposing && (retcode != ODBC32.RetCode.NO_DATA) && (ODBC32.RetCode.SUCCESS != retcode)) { @@ -2010,7 +2013,7 @@ private bool NextResult(bool disposing, bool allresults) if (null != errors) { Debug.Assert(!disposing, "errors while disposing"); - errors.SetSource(Connection.Driver); + errors.SetSource(Connection!.Driver); OdbcException exception = OdbcException.CreateException(errors, firstRetCode); Connection.ConnectionIsAlive(exception); throw exception; @@ -2022,7 +2025,7 @@ private void BuildMetaDataInfo() { int count = FieldCount; MetaData[] metaInfos = new MetaData[count]; - List qrytables; + List? qrytables; bool needkeyinfo = IsCommandBehavior(CommandBehavior.KeyInfo); bool isKeyColumn; bool isHidden; @@ -2094,7 +2097,7 @@ private void BuildMetaDataInfo() // Note: Following two attributes are SQL Server specific (hence _SS in the name) // SSS_WARNINGS_OFF - if (!Connection.ProviderInfo.NoSqlCASSColumnKey) + if (!Connection!.ProviderInfo.NoSqlCASSColumnKey) { isKeyColumn = GetColAttribute(i, (ODBC32.SQL_DESC)ODBC32.SQL_CA_SS.COLUMN_KEY, (ODBC32.SQL_COLUMN)(-1), ODBC32.HANDLER.IGNORE) == 1; if (isKeyColumn) @@ -2113,22 +2116,22 @@ private void BuildMetaDataInfo() if (Connection.IsV3Driver) { - if ((metaInfos[i].baseTableName == null) || (metaInfos[i].baseTableName.Length == 0)) + if (string.IsNullOrEmpty(metaInfos[i].baseTableName)) { // Driver didn't return the necessary information from GetColAttributeStr. // Try GetDescField() metaInfos[i].baseTableName = GetDescFieldStr(i, ODBC32.SQL_DESC.BASE_TABLE_NAME, ODBC32.HANDLER.IGNORE); } - if ((metaInfos[i].baseColumnName == null) || (metaInfos[i].baseColumnName.Length == 0)) + if (string.IsNullOrEmpty(metaInfos[i].baseColumnName)) { // Driver didn't return the necessary information from GetColAttributeStr. // Try GetDescField() metaInfos[i].baseColumnName = GetDescFieldStr(i, ODBC32.SQL_DESC.BASE_COLUMN_NAME, ODBC32.HANDLER.IGNORE); } } - if ((metaInfos[i].baseTableName != null) && !(qrytables.Contains(metaInfos[i].baseTableName))) + if ((metaInfos[i].baseTableName is string baseTableName) && !(qrytables!.Contains(baseTableName))) { - qrytables.Add(metaInfos[i].baseTableName); + qrytables.Add(baseTableName); } } @@ -2143,7 +2146,7 @@ private void BuildMetaDataInfo() // now loop over the hidden columns (if any) // SSS_WARNINGS_OFF - if (!Connection.ProviderInfo.NoSqlCASSColumnKey) + if (!Connection!.ProviderInfo.NoSqlCASSColumnKey) { for (int i = count; i < count + _hiddenColumns; i++) { @@ -2250,7 +2253,10 @@ public override DataTable GetSchemaTable() } if (_noMoreResults) { +// TODO-NULLABLE: Behavior change (https://github.com/dotnet/runtime/issues/509) +#nullable disable return null; // no more results +#nullable enable } if (null != _schemaTable) { @@ -2269,24 +2275,24 @@ public override DataTable GetSchemaTable() BuildMetaDataInfo(); } - DataColumn columnName = schematable.Columns["ColumnName"]; - DataColumn columnOrdinal = schematable.Columns["ColumnOrdinal"]; - DataColumn columnSize = schematable.Columns["ColumnSize"]; - DataColumn numericPrecision = schematable.Columns["NumericPrecision"]; - DataColumn numericScale = schematable.Columns["NumericScale"]; - DataColumn dataType = schematable.Columns["DataType"]; - DataColumn providerType = schematable.Columns["ProviderType"]; - DataColumn isLong = schematable.Columns["IsLong"]; - DataColumn allowDBNull = schematable.Columns["AllowDBNull"]; - DataColumn isReadOnly = schematable.Columns["IsReadOnly"]; - DataColumn isRowVersion = schematable.Columns["IsRowVersion"]; - DataColumn isUnique = schematable.Columns["IsUnique"]; - DataColumn isKey = schematable.Columns["IsKey"]; - DataColumn isAutoIncrement = schematable.Columns["IsAutoIncrement"]; - DataColumn baseSchemaName = schematable.Columns["BaseSchemaName"]; - DataColumn baseCatalogName = schematable.Columns["BaseCatalogName"]; - DataColumn baseTableName = schematable.Columns["BaseTableName"]; - DataColumn baseColumnName = schematable.Columns["BaseColumnName"]; + DataColumn columnName = schematable.Columns["ColumnName"]!; + DataColumn columnOrdinal = schematable.Columns["ColumnOrdinal"]!; + DataColumn columnSize = schematable.Columns["ColumnSize"]!; + DataColumn numericPrecision = schematable.Columns["NumericPrecision"]!; + DataColumn numericScale = schematable.Columns["NumericScale"]!; + DataColumn dataType = schematable.Columns["DataType"]!; + DataColumn providerType = schematable.Columns["ProviderType"]!; + DataColumn isLong = schematable.Columns["IsLong"]!; + DataColumn allowDBNull = schematable.Columns["AllowDBNull"]!; + DataColumn isReadOnly = schematable.Columns["IsReadOnly"]!; + DataColumn isRowVersion = schematable.Columns["IsRowVersion"]!; + DataColumn isUnique = schematable.Columns["IsUnique"]!; + DataColumn isKey = schematable.Columns["IsKey"]!; + DataColumn isAutoIncrement = schematable.Columns["IsAutoIncrement"]!; + DataColumn baseSchemaName = schematable.Columns["BaseSchemaName"]!; + DataColumn baseCatalogName = schematable.Columns["BaseCatalogName"]!; + DataColumn baseTableName = schematable.Columns["BaseTableName"]!; + DataColumn baseColumnName = schematable.Columns["BaseColumnName"]!; //Populate the rows (1 row for each column) @@ -2297,7 +2303,7 @@ public override DataTable GetSchemaTable() row[columnName] = GetName(i); //ColumnName row[columnOrdinal] = i; //ColumnOrdinal - row[columnSize] = unchecked((int)Math.Min(Math.Max(int.MinValue, _metadata[i].size.ToInt64()), int.MaxValue)); + row[columnSize] = unchecked((int)Math.Min(Math.Max(int.MinValue, _metadata![i].size.ToInt64()), int.MaxValue)); row[numericPrecision] = (short)_metadata[i].precision; row[numericScale] = (short)_metadata[i].scale; row[dataType] = _metadata[i].typemap._type; //DataType @@ -2328,6 +2334,8 @@ public override DataTable GetSchemaTable() internal int RetrieveKeyInfo(bool needkeyinfo, QualifiedTableName qualifiedTableName, bool quoted) { + Debug.Assert(_metadata != null); + ODBC32.RetCode retcode; string columnname; int ordinal; @@ -2350,13 +2358,13 @@ internal int RetrieveKeyInfo(bool needkeyinfo, QualifiedTableName qualifiedTable if (needkeyinfo) { - if (!Connection.ProviderInfo.NoSqlPrimaryKeys) + if (!Connection!.ProviderInfo.NoSqlPrimaryKeys) { // Get the primary keys retcode = KeyInfoStatementHandle.PrimaryKeys( qualifiedTableName.Catalog, qualifiedTableName.Schema, - qualifiedTableName.GetTable(quoted)); + qualifiedTableName.GetTable(quoted)!); if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)) { @@ -2419,7 +2427,7 @@ internal int RetrieveKeyInfo(bool needkeyinfo, QualifiedTableName qualifiedTable } else { - if ("IM001" == Command.GetDiagSqlState()) + if ("IM001" == Command!.GetDiagSqlState()) { Connection.ProviderInfo.NoSqlPrimaryKeys = true; } @@ -2436,7 +2444,7 @@ internal int RetrieveKeyInfo(bool needkeyinfo, QualifiedTableName qualifiedTable } // Get the special columns for version - retcode = KeyInfoStatementHandle.SpecialColumns(qualifiedTableName.GetTable(quoted)); + retcode = KeyInfoStatementHandle.SpecialColumns(qualifiedTableName.GetTable(quoted)!); if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)) { @@ -2496,6 +2504,8 @@ internal int RetrieveKeyInfo(bool needkeyinfo, QualifiedTableName qualifiedTable // Uses SQLStatistics to retrieve key information for a table private int RetrieveKeyInfoFromStatistics(QualifiedTableName qualifiedTableName, bool quoted) { + Debug.Assert(_metadata != null); + ODBC32.RetCode retcode; string columnname = string.Empty; string indexname = string.Empty; @@ -2514,7 +2524,7 @@ private int RetrieveKeyInfoFromStatistics(QualifiedTableName qualifiedTableName, // devnote: this test is already done by calling method ... // if (IsClosed) return; // protect against dead connection - string tablename1 = qualifiedTableName.GetTable(quoted); + string tablename1 = qualifiedTableName.GetTable(quoted)!; // Select only unique indexes retcode = KeyInfoStatementHandle.Statistics(tablename1); @@ -2670,7 +2680,7 @@ private int RetrieveKeyInfoFromStatistics(QualifiedTableName qualifiedTableName, } } // Unbind the columns - _cmdWrapper.FreeKeyInfoStatementHandle(ODBC32.STMT.UNBIND); + _cmdWrapper!.FreeKeyInfoStatementHandle(ODBC32.STMT.UNBIND); } finally { @@ -2694,12 +2704,12 @@ internal bool SameIndexColumn(string currentindexname, string indexname, int ord return false; } - internal int GetOrdinalFromBaseColName(string columnname) + internal int GetOrdinalFromBaseColName(string? columnname) { return GetOrdinalFromBaseColName(columnname, null); } - internal int GetOrdinalFromBaseColName(string columnname, string tablename) + internal int GetOrdinalFromBaseColName(string? columnname, string? tablename) { if (string.IsNullOrEmpty(columnname)) { @@ -2737,7 +2747,7 @@ internal int GetOrdinalFromBaseColName(string columnname, string tablename) // we can't handle multiple tablenames (JOIN) // only the first tablename will be returned - internal string GetTableNameFromCommandText() + internal string? GetTableNameFromCommandText() { if (_command == null) { @@ -2750,7 +2760,7 @@ internal string GetTableNameFromCommandText() } string tablename; int idx; - CStringTokenizer tokenstmt = new CStringTokenizer(localcmdtext, Connection.QuoteChar(ADP.GetSchemaTable)[0], Connection.EscapeChar(ADP.GetSchemaTable)); + CStringTokenizer tokenstmt = new CStringTokenizer(localcmdtext, Connection!.QuoteChar(ADP.GetSchemaTable)[0], Connection.EscapeChar(ADP.GetSchemaTable)); if (tokenstmt.StartsWith("select") == true) { @@ -2800,7 +2810,7 @@ internal void SetBaseTableNames(QualifiedTableName qualifiedTableName) for (int i = 0; i < count; i++) { - if (_metadata[i].baseTableName == null) + if (_metadata![i].baseTableName == null) { _metadata[i].baseTableName = qualifiedTableName.Table; _metadata[i].baseSchemaName = qualifiedTableName.Schema; @@ -2812,13 +2822,13 @@ internal void SetBaseTableNames(QualifiedTableName qualifiedTableName) internal sealed class QualifiedTableName { - private readonly string _catalogName; - private readonly string _schemaName; - private string _tableName; - private string _quotedTableName; + private readonly string? _catalogName; + private readonly string? _schemaName; + private string? _tableName; + private string? _quotedTableName; private readonly string _quoteChar; - internal string Catalog + internal string? Catalog { get { @@ -2826,7 +2836,7 @@ internal string Catalog } } - internal string Schema + internal string? Schema { get { @@ -2834,7 +2844,7 @@ internal string Schema } } - internal string Table + internal string? Table { get { @@ -2846,14 +2856,14 @@ internal string Table _tableName = UnQuote(value); } } - internal string QuotedTable + internal string? QuotedTable { get { return _quotedTableName; } } - internal string GetTable(bool flag) + internal string? GetTable(bool flag) { return (flag ? QuotedTable : Table); } @@ -2861,18 +2871,18 @@ internal QualifiedTableName(string quoteChar) { _quoteChar = quoteChar; } - internal QualifiedTableName(string quoteChar, string qualifiedname) + internal QualifiedTableName(string quoteChar, string? qualifiedname) { _quoteChar = quoteChar; - string[] names = ParseProcedureName(qualifiedname, quoteChar, quoteChar); + string?[] names = ParseProcedureName(qualifiedname, quoteChar, quoteChar); _catalogName = UnQuote(names[1]); _schemaName = UnQuote(names[2]); _quotedTableName = names[3]; _tableName = UnQuote(names[3]); } - private string UnQuote(string str) + private string? UnQuote(string? str) { if ((str != null) && (str.Length > 0)) { @@ -2893,7 +2903,7 @@ private string UnQuote(string str) // Note: copy-and pasted from internal DbCommandBuilder implementation // Note: Per definition (ODBC reference) the CatalogSeparator comes before and after the // catalog name, the SchemaSeparator is undefined. Does it come between Schema and Table? - internal static string[] ParseProcedureName(string name, string quotePrefix, string quoteSuffix) + internal static string?[] ParseProcedureName(string? name, string? quotePrefix, string? quoteSuffix) { // Procedure may consist of up to four parts: // 0) Server @@ -2906,7 +2916,7 @@ internal static string[] ParseProcedureName(string name, string quotePrefix, str // const string Separator = "."; - string[] qualifiers = new string[4]; + string?[] qualifiers = new string[4]; if (!string.IsNullOrEmpty(name)) { bool useQuotes = !string.IsNullOrEmpty(quotePrefix) && !string.IsNullOrEmpty(quoteSuffix); @@ -2917,8 +2927,10 @@ internal static string[] ParseProcedureName(string name, string quotePrefix, str int startPos = currentPos; // does the part begin with a quotePrefix? - if (useQuotes && (name.IndexOf(quotePrefix, currentPos, quotePrefix.Length, StringComparison.Ordinal) == currentPos)) + if (useQuotes && (name.IndexOf(quotePrefix!, currentPos, quotePrefix!.Length, StringComparison.Ordinal) == currentPos)) { + Debug.Assert(quotePrefix != null && quoteSuffix != null); + currentPos += quotePrefix.Length; // move past the quotePrefix // search for the quoteSuffix (or end of string) @@ -2978,7 +2990,7 @@ internal static string[] ParseProcedureName(string name, string quotePrefix, str private sealed class MetaData { internal int ordinal; - internal TypeMap typemap; + internal TypeMap typemap = null!; // Lazy-initialized internal SQLLEN size; internal byte precision; @@ -2992,10 +3004,10 @@ private sealed class MetaData internal bool isLong; internal bool isKeyColumn; - internal string baseSchemaName; - internal string baseCatalogName; - internal string baseTableName; - internal string baseColumnName; + internal string? baseSchemaName; + internal string? baseCatalogName; + internal string? baseTableName; + internal string? baseColumnName; } } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs index 76f363e30eff..f6c0538764f7 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs @@ -7,14 +7,14 @@ namespace System.Data.Odbc { internal sealed class OdbcEnvironment { - private static object s_globalEnvironmentHandle; + private static object? s_globalEnvironmentHandle; private static readonly object s_globalEnvironmentHandleLock = new object(); private OdbcEnvironment() { } // default const. internal static OdbcEnvironmentHandle GetGlobalEnvironmentHandle() { - OdbcEnvironmentHandle globalEnvironmentHandle = s_globalEnvironmentHandle as OdbcEnvironmentHandle; + OdbcEnvironmentHandle? globalEnvironmentHandle = s_globalEnvironmentHandle as OdbcEnvironmentHandle; if (null == globalEnvironmentHandle) { lock (s_globalEnvironmentHandleLock) @@ -32,10 +32,10 @@ internal static OdbcEnvironmentHandle GetGlobalEnvironmentHandle() internal static void ReleaseObjectPool() { - object globalEnvironmentHandle = Interlocked.Exchange(ref s_globalEnvironmentHandle, null); + object? globalEnvironmentHandle = Interlocked.Exchange(ref s_globalEnvironmentHandle, null); if (null != globalEnvironmentHandle) { - (globalEnvironmentHandle as OdbcEnvironmentHandle).Dispose(); // internally refcounted so will happen correctly + ((OdbcEnvironmentHandle)globalEnvironmentHandle).Dispose(); // internally refcounted so will happen correctly } } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs index 44a0f0171208..564089c69046 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs @@ -11,9 +11,9 @@ public sealed class OdbcError internal string _message; internal string _state; internal int _nativeerror; - internal string _source; + internal string? _source; - internal OdbcError(string source, string message, string state, int nativeerror) + internal OdbcError(string? source, string message, string state, int nativeerror) { _source = source; _message = message; diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs index 60bbf1b525f7..a94643cfba18 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs @@ -37,7 +37,7 @@ public OdbcError this[int i] { get { - return (OdbcError)_items[i]; + return (OdbcError)_items[i]!; } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs index 4725546e4072..7a2f87ef4e11 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs @@ -37,7 +37,7 @@ internal OdbcException(string message, OdbcErrorCollection errors) : base(messag private OdbcException(SerializationInfo si, StreamingContext sc) : base(si, sc) { // Ignoring ODBC32.RETCODE - _odbcErrors = (OdbcErrorCollection)si.GetValue("odbcErrors", typeof(OdbcErrorCollection)); + _odbcErrors = (OdbcErrorCollection)si.GetValue("odbcErrors", typeof(OdbcErrorCollection))!; HResult = HResults.OdbcException; } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs index 4936464cb100..77900ae013f1 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs @@ -12,9 +12,9 @@ namespace System.Data.Odbc internal abstract class OdbcHandle : SafeHandle { private readonly ODBC32.SQL_HANDLE _handleType; - private OdbcHandle _parentHandle; + private OdbcHandle? _parentHandle; - protected OdbcHandle(ODBC32.SQL_HANDLE handleType, OdbcHandle parentHandle) : base(IntPtr.Zero, true) + protected OdbcHandle(ODBC32.SQL_HANDLE handleType, OdbcHandle? parentHandle) : base(IntPtr.Zero, true) { _handleType = handleType; @@ -61,7 +61,7 @@ protected OdbcHandle(ODBC32.SQL_HANDLE handleType, OdbcHandle parentHandle) : ba else { // without a handle, ReleaseHandle may not be called - parentHandle.DangerousRelease(); + parentHandle!.DangerousRelease(); } break; } @@ -164,7 +164,7 @@ protected override bool ReleaseHandle() // If we ended up getting released, then we have to release // our reference on our parent. - OdbcHandle parentHandle = _parentHandle; + OdbcHandle? parentHandle = _parentHandle; _parentHandle = null; if (null != parentHandle) { diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs index f56a53cd6fe4..f8eefe7edb66 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs @@ -49,7 +49,7 @@ internal OdbcMetaDataFactory(Stream XMLStream, new SchemaFunctionName(OdbcMetaDataCollectionNames.Views, ODBC32.SQL_API.SQLTABLES)}; // verify the existance of the table in the data set - DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; + DataTable? metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; if (metaDataCollectionsTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.MetaDataCollections); @@ -59,7 +59,7 @@ internal OdbcMetaDataFactory(Stream XMLStream, metaDataCollectionsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.MetaDataCollections, null); // verify the existance of the table in the data set - DataTable restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; + DataTable? restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; if (restrictionsTable != null) { // copy the table filtering out any rows that don't apply to the current version of the provider @@ -72,13 +72,14 @@ internal OdbcMetaDataFactory(Stream XMLStream, // 3) the provider does not support the necessary odbc function - DataColumn populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism]; - DataColumn collectionName = metaDataCollectionsTable.Columns[_collectionName]; - DataColumn restrictionCollectionName = null; + DataColumn populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism]!; + DataColumn collectionName = metaDataCollectionsTable.Columns[_collectionName]!; + DataColumn? restrictionCollectionName = null; if (restrictionsTable != null) { restrictionCollectionName = restrictionsTable.Columns[_collectionName]; } + Debug.Assert(restrictionCollectionName != null); foreach (DataRow collection in metaDataCollectionsTable.Rows) { @@ -123,12 +124,12 @@ internal OdbcMetaDataFactory(Stream XMLStream, // replace the original table with the updated one metaDataCollectionsTable.AcceptChanges(); - CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]); + CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!); CollectionDataSet.Tables.Add(metaDataCollectionsTable); if (restrictionsTable != null) { - CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]); + CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]!); CollectionDataSet.Tables.Add(restrictionsTable); } } @@ -180,7 +181,7 @@ private DataTable DataTableFromDataReader(IDataReader reader, string tableName) private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcDataReader dataReader, OdbcConnection connection) { - DataTable schemaTable = null; + DataTable? schemaTable = null; // // Build a DataTable from the reader @@ -195,25 +196,25 @@ private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcData object[] getTypeInfoValues = new object[schemaTable.Rows.Count]; DataRow dataTypesRow; - DataColumn typeNameColumn = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName]; - DataColumn providerDbTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]; - DataColumn columnSizeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize]; - DataColumn createParametersColumn = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters]; - DataColumn dataTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.DataType]; - DataColumn isAutoIncermentableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable]; - DataColumn isCaseSensitiveColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive]; - DataColumn isFixedLengthColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength]; - DataColumn isFixedPrecisionScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale]; - DataColumn isLongColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]; - DataColumn isNullableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable]; - DataColumn isSearchableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable]; - DataColumn isSearchableWithLikeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]; - DataColumn isUnsignedColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned]; - DataColumn maximumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale]; - DataColumn minimumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale]; - DataColumn literalPrefixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix]; - DataColumn literalSuffixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix]; - DataColumn SQLTypeNameColumn = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType]; + DataColumn typeNameColumn = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName]!; + DataColumn providerDbTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]!; + DataColumn columnSizeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize]!; + DataColumn createParametersColumn = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters]!; + DataColumn dataTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.DataType]!; + DataColumn isAutoIncermentableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable]!; + DataColumn isCaseSensitiveColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive]!; + DataColumn isFixedLengthColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength]!; + DataColumn isFixedPrecisionScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale]!; + DataColumn isLongColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]!; + DataColumn isNullableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable]!; + DataColumn isSearchableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable]!; + DataColumn isSearchableWithLikeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]!; + DataColumn isUnsignedColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned]!; + DataColumn maximumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale]!; + DataColumn minimumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale]!; + DataColumn literalPrefixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix]!; + DataColumn literalSuffixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix]!; + DataColumn SQLTypeNameColumn = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType]!; const int indexTYPE_NAME = 0; @@ -234,7 +235,7 @@ private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcData const int SQL_DATE_V2 = 9; const int SQL_TIME_V2 = 10; - TypeMap typeMap; + TypeMap? typeMap; while (dataReader.Read()) @@ -247,11 +248,9 @@ private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcData dataTypesRow[typeNameColumn] = getTypeInfoValues[indexTYPE_NAME]; dataTypesRow[SQLTypeNameColumn] = getTypeInfoValues[indexDATA_TYPE]; - sqlType = (ODBC32.SQL_TYPE)(int)Convert.ChangeType(getTypeInfoValues[indexDATA_TYPE], - typeof(int), - (System.IFormatProvider)null); + sqlType = (ODBC32.SQL_TYPE)(int)Convert.ChangeType(getTypeInfoValues[indexDATA_TYPE], typeof(int), null); // if the driver is pre version 3 and it returned the v2 SQL_DATE or SQL_TIME types they need - // to be mapped to thier v3 equlivants + // to be mapped to their v3 equivalent if (connection.IsV3Driver == false) { if ((int)sqlType == SQL_DATE_V2) @@ -428,7 +427,7 @@ private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcData private DataTable DataTableFromDataReaderIndex(IDataReader reader, string tableName, - string restrictionIndexName) + string? restrictionIndexName) { // set up the column structure of the data table from the reader object[] values; @@ -499,7 +498,7 @@ private DataTable DataTableFromDataReaderProcedures(IDataReader reader, string t return resultTable; } - private void FillOutRestrictions(int restrictionsCount, string[] restrictions, object[] allRestrictions, string collectionName) + private void FillOutRestrictions(int restrictionsCount, string?[]? restrictions, object?[] allRestrictions, string collectionName) { Debug.Assert(allRestrictions.Length >= restrictionsCount); @@ -530,11 +529,11 @@ private void FillOutRestrictions(int restrictionsCount, string[] restrictions, o } - private DataTable GetColumnsCollection(string[] restrictions, OdbcConnection connection) + private DataTable GetColumnsCollection(string?[]? restrictions, OdbcConnection connection) { - OdbcCommand command = null; - OdbcDataReader dataReader = null; - DataTable resultTable = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; + DataTable? resultTable = null; const int columnsRestrictionsCount = 4; try @@ -563,7 +562,7 @@ private DataTable GetColumnsCollection(string[] restrictions, OdbcConnection con } - private DataTable GetDataSourceInformationCollection(string[] restrictions, + private DataTable GetDataSourceInformationCollection(string?[]? restrictions, OdbcConnection connection) { if (ADP.IsEmptyArray(restrictions) == false) @@ -572,7 +571,7 @@ private DataTable GetDataSourceInformationCollection(string[] restrictions, } // verify that the data source information table is in the data set - DataTable dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; + DataTable? dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; if (dataSourceInformationTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataSourceInformation); @@ -588,7 +587,7 @@ private DataTable GetDataSourceInformationCollection(string[] restrictions, } DataRow dataSourceInformation = dataSourceInformationTable.Rows[0]; - string stringValue; + string? stringValue; short int16Value; int int32Value; ODBC32.RetCode retcode; @@ -724,7 +723,7 @@ private DataTable GetDataSourceInformationCollection(string[] restrictions, } // build the QuotedIdentifierPattern using the quote prefix and suffix from the provider and - // assuming that the quote suffix is escaped via repetion (i.e " becomes "") + // assuming that the quote suffix is escaped via repetition (i.e " becomes "") stringValue = connection.QuoteChar(ADP.GetSchema); if (stringValue != null) @@ -733,7 +732,7 @@ private DataTable GetDataSourceInformationCollection(string[] restrictions, // quoted identifiers if (stringValue != " ") { - // only know how to build the parttern if the quote characters is 1 character + // only know how to build the pattern if the quote characters is 1 character // in all other cases just leave the field null if (stringValue.Length == 1) { @@ -782,7 +781,7 @@ private DataTable GetDataSourceInformationCollection(string[] restrictions, } - private DataTable GetDataTypesCollection(string[] restrictions, OdbcConnection connection) + private DataTable GetDataTypesCollection(string?[]? restrictions, OdbcConnection connection) { if (ADP.IsEmptyArray(restrictions) == false) { @@ -792,7 +791,7 @@ private DataTable GetDataTypesCollection(string[] restrictions, OdbcConnection c // verify the existance of the table in the data set - DataTable dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes]; + DataTable? dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes]; if (dataTypesTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataTypes); @@ -801,8 +800,8 @@ private DataTable GetDataTypesCollection(string[] restrictions, OdbcConnection c // copy the data table it dataTypesTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataTypes, null); - OdbcCommand command = null; - OdbcDataReader dataReader = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; object[] allArguments = new object[1]; allArguments[0] = ODBC32.SQL_ALL_TYPES; @@ -831,11 +830,11 @@ private DataTable GetDataTypesCollection(string[] restrictions, OdbcConnection c return dataTypesTable; } - private DataTable GetIndexCollection(string[] restrictions, OdbcConnection connection) + private DataTable GetIndexCollection(string?[]? restrictions, OdbcConnection connection) { - OdbcCommand command = null; - OdbcDataReader dataReader = null; - DataTable resultTable = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; + DataTable? resultTable = null; const int nativeRestrictionsCount = 5; const int indexRestrictionsCount = 4; const int indexOfTableName = 2; @@ -857,7 +856,7 @@ private DataTable GetIndexCollection(string[] restrictions, OdbcConnection conne dataReader = command.ExecuteReaderFromSQLMethod(allRestrictions, ODBC32.SQL_API.SQLSTATISTICS); - string indexName = null; + string? indexName = null; if (restrictions != null) { if (restrictions.Length >= indexOfIndexName + 1) @@ -885,11 +884,11 @@ private DataTable GetIndexCollection(string[] restrictions, OdbcConnection conne return resultTable; } - private DataTable GetProcedureColumnsCollection(string[] restrictions, OdbcConnection connection, bool isColumns) + private DataTable GetProcedureColumnsCollection(string?[]? restrictions, OdbcConnection connection, bool isColumns) { - OdbcCommand command = null; - OdbcDataReader dataReader = null; - DataTable resultTable = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; + DataTable? resultTable = null; const int procedureColumnsRestrictionsCount = 4; try @@ -928,18 +927,18 @@ private DataTable GetProcedureColumnsCollection(string[] restrictions, OdbcConne return resultTable; } - private DataTable GetProceduresCollection(string[] restrictions, OdbcConnection connection) + private DataTable GetProceduresCollection(string?[]? restrictions, OdbcConnection connection) { - OdbcCommand command = null; - OdbcDataReader dataReader = null; - DataTable resultTable = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; + DataTable? resultTable = null; const int columnsRestrictionsCount = 4; const int indexOfProcedureType = 3; try { command = GetCommand(connection); - string[] allRestrictions = new string[columnsRestrictionsCount]; + string?[] allRestrictions = new string[columnsRestrictionsCount]; FillOutRestrictions(columnsRestrictionsCount, restrictions, allRestrictions, OdbcMetaDataCollectionNames.Procedures); @@ -952,7 +951,7 @@ private DataTable GetProceduresCollection(string[] restrictions, OdbcConnection else { short procedureType; - if ((restrictions[indexOfProcedureType] == "SQL_PT_UNKNOWN") || + if ((restrictions![indexOfProcedureType] == "SQL_PT_UNKNOWN") || (restrictions[indexOfProcedureType] == "0" /*ODBC32.SQL_PROCEDURETYPE.UNKNOWN*/)) { procedureType = (short)ODBC32.SQL_PROCEDURETYPE.UNKNOWN; @@ -990,7 +989,7 @@ private DataTable GetProceduresCollection(string[] restrictions, OdbcConnection return resultTable; } - private DataTable GetReservedWordsCollection(string[] restrictions, OdbcConnection connection) + private DataTable GetReservedWordsCollection(string?[]? restrictions, OdbcConnection connection) { if (ADP.IsEmptyArray(restrictions) == false) { @@ -998,7 +997,7 @@ private DataTable GetReservedWordsCollection(string[] restrictions, OdbcConnecti } // verify the existance of the table in the data set - DataTable reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; + DataTable? reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; if (reservedWordsTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); @@ -1007,13 +1006,13 @@ private DataTable GetReservedWordsCollection(string[] restrictions, OdbcConnecti // copy the table filtering out any rows that don't apply to tho current version of the prrovider reservedWordsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.ReservedWords, null); - DataColumn reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord]; + DataColumn? reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord]; if (reservedWordColumn == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); } - string keywords = connection.GetInfoStringUnhandled(ODBC32.SQL_INFO.KEYWORDS); + string? keywords = connection.GetInfoStringUnhandled(ODBC32.SQL_INFO.KEYWORDS); if (null != keywords) { @@ -1031,11 +1030,11 @@ private DataTable GetReservedWordsCollection(string[] restrictions, OdbcConnecti return reservedWordsTable; } - private DataTable GetTablesCollection(string[] restrictions, OdbcConnection connection, bool isTables) + private DataTable GetTablesCollection(string?[]? restrictions, OdbcConnection connection, bool isTables) { - OdbcCommand command = null; - OdbcDataReader dataReader = null; - DataTable resultTable = null; + OdbcCommand? command = null; + OdbcDataReader? dataReader = null; + DataTable? resultTable = null; const int tablesRestrictionsCount = 3; const string includedTableTypesTables = "TABLE,SYSTEM TABLE"; const string includedTableTypesViews = "VIEW"; @@ -1081,7 +1080,7 @@ private DataTable GetTablesCollection(string[] restrictions, OdbcConnection conn } private bool IncludeIndexRow(object rowIndexName, - string restrictionIndexName, + string? restrictionIndexName, short rowIndexType) { // never include table statictics rows @@ -1112,9 +1111,9 @@ private DataTable NewDataTableFromReader(IDataReader reader, out object[] values return resultTable; } - protected override DataTable PrepareCollection(string collectionName, string[] restrictions, DbConnection connection) + protected override DataTable PrepareCollection(string collectionName, string?[]? restrictions, DbConnection connection) { - DataTable resultTable = null; + DataTable? resultTable = null; OdbcConnection odbcConnection = (OdbcConnection)connection; if (collectionName == OdbcMetaDataCollectionNames.Tables) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs index 23d65eb394a8..08c95dc69d08 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs @@ -5,6 +5,7 @@ using System.Data.Common; using System.Data.SqlTypes; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Text; @@ -32,10 +33,10 @@ public sealed partial class OdbcParameter : DbParameter, ICloneable, IDataParame // Bind: Bind may change _bindtype if the type is not supported through the driver // - private TypeMap _typemap; - private TypeMap _bindtype; + private TypeMap? _typemap; + private TypeMap? _bindtype; - private string _parameterName; + private string? _parameterName; private byte _precision; private byte _scale; private bool _hasScale; @@ -47,7 +48,7 @@ public sealed partial class OdbcParameter : DbParameter, ICloneable, IDataParame private int _boundScale; private IntPtr _boundBuffer; private IntPtr _boundIntbuffer; - private TypeMap _originalbindtype; // the original type in case we had to change the bindtype + private TypeMap? _originalbindtype; // the original type in case we had to change the bindtype // (e.g. decimal to string) private byte _internalPrecision; private bool _internalShouldSerializeSize; @@ -56,12 +57,12 @@ public sealed partial class OdbcParameter : DbParameter, ICloneable, IDataParame private byte _internalScale; private int _internalOffset; internal bool _internalUserSpecifiedType; - private object _internalValue; + private object? _internalValue; private int _preparedOffset; private int _preparedSize; private int _preparedBufferSize; - private object _preparedValue; + private object? _preparedValue; private int _preparedIntOffset; private int _preparedValueOffset; @@ -72,26 +73,26 @@ public OdbcParameter() : base() // uses System.Threading! } - public OdbcParameter(string name, object value) : this() + public OdbcParameter(string? name, object? value) : this() { ParameterName = name; Value = value; } - public OdbcParameter(string name, OdbcType type) : this() + public OdbcParameter(string? name, OdbcType type) : this() { ParameterName = name; OdbcType = type; } - public OdbcParameter(string name, OdbcType type, int size) : this() + public OdbcParameter(string? name, OdbcType type, int size) : this() { ParameterName = name; OdbcType = type; Size = size; } - public OdbcParameter(string name, OdbcType type, int size, string sourcecolumn) : this() + public OdbcParameter(string? name, OdbcType type, int size, string? sourcecolumn) : this() { ParameterName = name; OdbcType = type; @@ -101,16 +102,16 @@ public OdbcParameter(string name, OdbcType type, int size, string sourcecolumn) [EditorBrowsableAttribute(EditorBrowsableState.Advanced)] // MDAC 69508 - public OdbcParameter(string parameterName, + public OdbcParameter(string? parameterName, OdbcType odbcType, int size, ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, - string srcColumn, + string? srcColumn, DataRowVersion srcVersion, - object value + object? value ) : this() { // V1.0 everything this.ParameterName = parameterName; @@ -126,12 +127,12 @@ object value } [EditorBrowsableAttribute(EditorBrowsableState.Advanced)] // MDAC 69508 - public OdbcParameter(string parameterName, + public OdbcParameter(string? parameterName, OdbcType odbcType, int size, ParameterDirection parameterDirection, byte precision, byte scale, - string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, - object value) : this() + string? sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, + object? value) : this() { // V2.0 everything - round trip all browsable properties + precision/scale this.ParameterName = parameterName; this.OdbcType = odbcType; @@ -151,7 +152,7 @@ public override System.Data.DbType DbType { if (_userSpecifiedType) { - return _typemap._dbType; + return _typemap!._dbType; } return TypeMap._NVarChar._dbType; // default type } @@ -181,7 +182,7 @@ public OdbcType OdbcType { if (_userSpecifiedType) { - return _typemap._odbcType; + return _typemap!._odbcType; } return TypeMap._NVarChar._odbcType; // default type } @@ -219,11 +220,12 @@ internal bool UserSpecifiedType } } + [AllowNull] public override string ParameterName { // V1.2.3300, XXXParameter V1.0.3300 get { - string parameterName = _parameterName; + string? parameterName = _parameterName; return ((null != parameterName) ? parameterName : string.Empty); } set @@ -314,16 +316,16 @@ private bool ShouldSerializeScale(byte scale) } // returns the count of bytes for the data (ColumnSize argument to SqlBindParameter) - private int GetColumnSize(object value, int offset, int ordinal) + private int GetColumnSize(object? value, int offset, int ordinal) { - if ((ODBC32.SQL_C.NUMERIC == _bindtype._sql_c) && (0 != _internalPrecision)) + if ((ODBC32.SQL_C.NUMERIC == _bindtype!._sql_c) && (0 != _internalPrecision)) { return Math.Min((int)_internalPrecision, ADP.DecimalMaxPrecision); } int cch = _bindtype._columnSize; if (0 >= cch) { - if (ODBC32.SQL_C.NUMERIC == _typemap._sql_c) + if (ODBC32.SQL_C.NUMERIC == _typemap!._sql_c) { cch = 62; // (DecimalMaxPrecision+sign+terminator)*BytesPerUnicodeCharacter } @@ -414,9 +416,9 @@ private int GetColumnSize(object value, int offset, int ordinal) // Return the count of bytes for the data (size in bytes for the native buffer) // - private int GetValueSize(object value, int offset) + private int GetValueSize(object? value, int offset) { - if ((ODBC32.SQL_C.NUMERIC == _bindtype._sql_c) && (0 != _internalPrecision)) + if ((ODBC32.SQL_C.NUMERIC == _bindtype!._sql_c) && (0 != _internalPrecision)) { return Math.Min((int)_internalPrecision, ADP.DecimalMaxPrecision); } @@ -457,12 +459,12 @@ private int GetValueSize(object value, int offset) // return the count of bytes for the data, used for SQLBindParameter // - private int GetParameterSize(object value, int offset, int ordinal) + private int GetParameterSize(object? value, int offset, int ordinal) { - int ccb = _bindtype._bufferSize; + int ccb = _bindtype!._bufferSize; if (0 >= ccb) { - if (ODBC32.SQL_C.NUMERIC == _typemap._sql_c) + if (ODBC32.SQL_C.NUMERIC == _typemap!._sql_c) { ccb = 518; // _bindtype would be VarChar ([0-9]?{255} + '-' + '.') * 2 } @@ -529,7 +531,7 @@ private int GetParameterSize(object value, int offset, int ordinal) return ccb; } - private byte GetParameterPrecision(object value) + private byte GetParameterPrecision(object? value) { if (0 != _internalPrecision && value is decimal) { @@ -556,7 +558,7 @@ private byte GetParameterPrecision(object value) } - private byte GetParameterScale(object value) + private byte GetParameterScale(object? value) { // For any value that is not decimal simply return the Scale // @@ -618,11 +620,13 @@ internal void ClearBinding() internal void PrepareForBind(OdbcCommand command, short ordinal, ref int parameterBufferSize) { + Debug.Assert(command.Connection != null); + // make a snapshot of the current properties. Properties may change while we work on them // CopyParameterInternal(); - object value = ProcessAndGetParameterValue(); + object? value = ProcessAndGetParameterValue(); int offset = _internalOffset; int size = _internalSize; ODBC32.SQL_C sql_c_type; @@ -663,7 +667,7 @@ internal void PrepareForBind(OdbcCommand command, short ordinal, ref int paramet // type support verification for certain data types // - switch (_bindtype._sql_type) + switch (_bindtype!._sql_type) { case ODBC32.SQL_TYPE.DECIMAL: case ODBC32.SQL_TYPE.NUMERIC: @@ -703,7 +707,7 @@ internal void PrepareForBind(OdbcCommand command, short ordinal, ref int paramet case ODBC32.SQL_TYPE.WLONGVARCHAR: if (value is char) { - value = value.ToString(); + value = value.ToString()!; size = ((string)value).Length; offset = 0; } @@ -739,7 +743,7 @@ internal void PrepareForBind(OdbcCommand command, short ordinal, ref int paramet int lcid = System.Globalization.CultureInfo.CurrentCulture.LCID; CultureInfo culInfo = new CultureInfo(lcid); Encoding cpe = System.Text.Encoding.GetEncoding(culInfo.TextInfo.ANSICodePage); - value = cpe.GetBytes(value.ToString()); + value = cpe.GetBytes(value.ToString()!); size = ((byte[])value).Length; } } @@ -786,13 +790,15 @@ internal void PrepareForBind(OdbcCommand command, short ordinal, ref int paramet internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) { + Debug.Assert(command.Connection != null); + ODBC32.RetCode retcode; ODBC32.SQL_C sql_c_type = _prepared_Sql_C_Type; ODBC32.SQL_PARAM sqldirection = SqlDirectionFromParameterDirection(); int offset = _preparedOffset; int size = _preparedSize; - object value = _preparedValue; + object? value = _preparedValue; int cbValueSize = GetValueSize(value, offset); // count of bytes for the data int cchSize = GetColumnSize(value, offset, ordinal); // count of bytes for the data, used to allocate the buffer length byte precision = GetParameterPrecision(value); @@ -843,7 +849,7 @@ internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal if (!_hasChanged && (_boundSqlCType == sql_c_type) - && (_boundParameterType == _bindtype._sql_type) + && (_boundParameterType == _bindtype!._sql_type) && (_boundSize == cchSize) && (_boundScale == scale) && (_boundBuffer == valueBuffer.Handle) @@ -858,7 +864,7 @@ internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal ordinal, // Parameter Number (short)sqldirection, // InputOutputType sql_c_type, // ValueType - _bindtype._sql_type, // ParameterType + _bindtype!._sql_type, // ParameterType (IntPtr)cchSize, // ColumnSize (IntPtr)scale, // DecimalDigits valueBuffer, // ParameterValuePtr @@ -968,7 +974,7 @@ internal void GetOutputValue(CNativeBuffer parameterBuffer) } } - if ((typemap != _typemap) && (null != Value) && !Convert.IsDBNull(Value) && (Value.GetType() != _typemap._type)) + if ((typemap != _typemap) && (null != Value) && !Convert.IsDBNull(Value) && (Value.GetType() != _typemap!._type)) { Debug.Assert(ODBC32.SQL_C.NUMERIC == _typemap._sql_c, "unexpected"); Value = decimal.Parse((string)Value, System.Globalization.CultureInfo.CurrentCulture); @@ -977,9 +983,9 @@ internal void GetOutputValue(CNativeBuffer parameterBuffer) } } - private object ProcessAndGetParameterValue() + private object? ProcessAndGetParameterValue() { - object value = _internalValue; + object? value = _internalValue; if (_internalUserSpecifiedType) { if ((null != value) && !Convert.IsDBNull(value)) @@ -987,11 +993,11 @@ private object ProcessAndGetParameterValue() Type valueType = value.GetType(); if (!valueType.IsArray) { - if (valueType != _typemap._type) + if (valueType != _typemap!._type) { try { - value = Convert.ChangeType(value, _typemap._type, (System.IFormatProvider)null); + value = Convert.ChangeType(value, _typemap._type, null); } catch (Exception e) { @@ -1040,7 +1046,7 @@ private void PropertyTypeChanging() //CoercedValue = null; } - internal void SetInputValue(object value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer) + internal void SetInputValue(object? value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer) { //Handle any input params if ((ParameterDirection.Input == _internalDirection) || (ParameterDirection.InputOutput == _internalDirection)) { @@ -1105,7 +1111,7 @@ private ODBC32.SQL_PARAM SqlDirectionFromParameterDirection() } } - public override object Value + public override object? Value { // V1.2.3300, XXXParameter V1.0.3300 get { @@ -1118,17 +1124,17 @@ public override object Value } } - private byte ValuePrecision(object value) + private byte ValuePrecision(object? value) { return ValuePrecisionCore(value); } - private byte ValueScale(object value) + private byte ValueScale(object? value) { return ValueScaleCore(value); } - private int ValueSize(object value) + private int ValueSize(object? value) { return ValueSizeCore(value); } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollection.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollection.cs index b84fac386305..d86b6d323f26 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollection.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollection.cs @@ -63,29 +63,29 @@ public OdbcParameter Add(OdbcParameter value) [EditorBrowsableAttribute(EditorBrowsableState.Never)] [ObsoleteAttribute("Add(String parameterName, Object value) has been deprecated. Use AddWithValue(String parameterName, Object value). https://go.microsoft.com/fwlink/?linkid=14202", false)] // 79027 - public OdbcParameter Add(string parameterName, object value) + public OdbcParameter Add(string? parameterName, object? value) { // MDAC 59206 return Add(new OdbcParameter(parameterName, value)); } - public OdbcParameter AddWithValue(string parameterName, object value) + public OdbcParameter AddWithValue(string? parameterName, object? value) { // MDAC 79027 return Add(new OdbcParameter(parameterName, value)); } - public OdbcParameter Add(string parameterName, OdbcType odbcType) + public OdbcParameter Add(string? parameterName, OdbcType odbcType) { return Add(new OdbcParameter(parameterName, odbcType)); } - public OdbcParameter Add(string parameterName, OdbcType odbcType, int size) + public OdbcParameter Add(string? parameterName, OdbcType odbcType, int size) { return Add(new OdbcParameter(parameterName, odbcType, size)); } - public OdbcParameter Add(string parameterName, OdbcType odbcType, int size, string sourceColumn) + public OdbcParameter Add(string? parameterName, OdbcType odbcType, int size, string? sourceColumn) { return Add(new OdbcParameter(parameterName, odbcType, size, sourceColumn)); } @@ -102,7 +102,7 @@ internal void Bind(OdbcCommand command, CMDWrapper cmdWrapper, CNativeBuffer par { for (int i = 0; i < Count; ++i) { - this[i].Bind(cmdWrapper.StatementHandle, command, checked((short)(i + 1)), parameterBuffer, true); + this[i].Bind(cmdWrapper.StatementHandle!, command, checked((short)(i + 1)), parameterBuffer, true); } _rebindCollection = false; } @@ -160,7 +160,7 @@ internal void GetOutputValues(CMDWrapper cmdWrapper) // mdac 88542 - we will not read out the parameters if the collection has changed if (!_rebindCollection) { - CNativeBuffer parameterBuffer = cmdWrapper._nativeParameterBuffer; + CNativeBuffer parameterBuffer = cmdWrapper._nativeParameterBuffer!; for (int i = 0; i < Count; ++i) { this[i].GetOutputValue(parameterBuffer); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollectionHelper.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollectionHelper.cs index 668a4ae3cedb..671b50959b9e 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollectionHelper.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterCollectionHelper.cs @@ -10,7 +10,7 @@ namespace System.Data.Odbc { public sealed partial class OdbcParameterCollection : DbParameterCollection { - private List _items; + private List? _items; public override int Count { @@ -24,7 +24,7 @@ private List InnerList { get { - List items = _items; + List? items = _items; if (null == items) { @@ -297,7 +297,7 @@ private void Validate(int index, object value) throw ADP.ParameterNull(nameof(value), this, s_itemType); } - object parent = ((OdbcParameter)value).CompareExchangeParent(this, null); + object? parent = ((OdbcParameter)value).CompareExchangeParent(this, null); if (null != parent) { if (this != parent) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs index 0173da3e45db..60634ace1512 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs @@ -2,25 +2,26 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Data.Common; +using System.Diagnostics.CodeAnalysis; namespace System.Data.Odbc { public sealed partial class OdbcParameter : DbParameter { - private object _value; + private object? _value; - private object _parent; + private object? _parent; private ParameterDirection _direction; private int _size; private int _offset; - private string _sourceColumn; + private string? _sourceColumn; private DataRowVersion _sourceVersion; private bool _sourceColumnNullMapping; private bool _isNullable; - private object _coercedValue; + private object? _coercedValue; private OdbcParameter(OdbcParameter source) : this() // V1.2.3300, Clone { @@ -28,14 +29,13 @@ private OdbcParameter(OdbcParameter source) : this() // V1.2.3300, Clone source.CloneHelper(this); - ICloneable cloneable = (_value as ICloneable); - if (null != cloneable) + if (_value is ICloneable cloneable) { // MDAC 49322 _value = cloneable.Clone(); } } - private object CoercedValue + private object? CoercedValue { get { @@ -134,11 +134,12 @@ private bool ShouldSerializeSize() return (0 != _size); } + [AllowNull] public override string SourceColumn { get { - string sourceColumn = _sourceColumn; + string? sourceColumn = _sourceColumn; return ((null != sourceColumn) ? sourceColumn : string.Empty); } set @@ -195,9 +196,9 @@ private void CloneHelperCore(OdbcParameter destination) destination._isNullable = _isNullable; } - internal object CompareExchangeParent(object value, object comparand) + internal object? CompareExchangeParent(object? value, object? comparand) { - object parent = _parent; + object? parent = _parent; if (comparand == parent) { _parent = value; @@ -215,7 +216,7 @@ public override string ToString() return ParameterName; } - private byte ValuePrecisionCore(object value) + private byte ValuePrecisionCore(object? value) { if (value is decimal) { @@ -224,7 +225,7 @@ private byte ValuePrecisionCore(object value) return 0; } - private byte ValueScaleCore(object value) + private byte ValueScaleCore(object? value) { if (value is decimal) { @@ -233,29 +234,19 @@ private byte ValueScaleCore(object value) return 0; } - private int ValueSizeCore(object value) + private int ValueSizeCore(object? value) { if (!ADP.IsNull(value)) { - string svalue = (value as string); - if (null != svalue) + return value switch { - return svalue.Length; - } - byte[] bvalue = (value as byte[]); - if (null != bvalue) - { - return bvalue.Length; - } - char[] cvalue = (value as char[]); - if (null != cvalue) - { - return cvalue.Length; - } - if ((value is byte) || (value is char)) - { - return 1; - } + string svalue => svalue.Length, + byte[] bvalue => bvalue.Length, + char[] cvalue => cvalue.Length, + byte _ => 1, + char _ => 1, + _ => 0 + }; } return 0; } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcRowUpdatingEvent.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcRowUpdatingEvent.cs index 61da7ce32a4f..05f6e51b4c4a 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcRowUpdatingEvent.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcRowUpdatingEvent.cs @@ -19,12 +19,12 @@ namespace System.Data.Odbc ///////////////////////////////////////////////////////////////////////// public sealed class OdbcRowUpdatingEventArgs : RowUpdatingEventArgs { - public OdbcRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + public OdbcRowUpdatingEventArgs(DataRow row, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } - public new OdbcCommand Command + public new OdbcCommand? Command { get { return (base.Command as OdbcCommand); } set @@ -33,7 +33,7 @@ public OdbcRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType s } } - protected override IDbCommand BaseCommand + protected override IDbCommand? BaseCommand { get { return base.BaseCommand; } set { base.BaseCommand = (value as OdbcCommand); } @@ -46,14 +46,14 @@ protected override IDbCommand BaseCommand ///////////////////////////////////////////////////////////////////////// public sealed class OdbcRowUpdatedEventArgs : RowUpdatedEventArgs { - public OdbcRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + public OdbcRowUpdatedEventArgs(DataRow row, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } - public new OdbcCommand Command + public new OdbcCommand? Command { - get { return (OdbcCommand)base.Command; } + get { return (OdbcCommand?)base.Command; } } } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcStatementHandle.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcStatementHandle.cs index dba62ed20260..11d970c85188 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcStatementHandle.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcStatementHandle.cs @@ -62,7 +62,7 @@ public unsafe long ToInt64() internal sealed class OdbcStatementHandle : OdbcHandle { - internal OdbcStatementHandle(OdbcConnectionHandle connectionHandle) : base(ODBC32.SQL_HANDLE.STMT, connectionHandle) + internal OdbcStatementHandle(OdbcConnectionHandle? connectionHandle) : base(ODBC32.SQL_HANDLE.STMT, connectionHandle) { } @@ -215,7 +215,7 @@ internal ODBC32.RetCode Prepare(string commandText) return retcode; } - internal ODBC32.RetCode PrimaryKeys(string catalogName, string schemaName, string tableName) + internal ODBC32.RetCode PrimaryKeys(string? catalogName, string? schemaName, string tableName) { ODBC32.RetCode retcode = Interop.Odbc.SQLPrimaryKeysW(this, catalogName, ODBC.ShortStringLength(catalogName), // CatalogName @@ -242,10 +242,10 @@ internal ODBC32.RetCode Procedures(string procedureCatalog, return retcode; } - internal ODBC32.RetCode ProcedureColumns(string procedureCatalog, - string procedureSchema, - string procedureName, - string columnName) + internal ODBC32.RetCode ProcedureColumns(string? procedureCatalog, + string? procedureSchema, + string? procedureName, + string? columnName) { ODBC32.RetCode retcode = Interop.Odbc.SQLProcedureColumnsW(this, procedureCatalog, @@ -287,8 +287,8 @@ internal ODBC32.RetCode SpecialColumns(string quotedTable) return retcode; } - internal ODBC32.RetCode Statistics(string tableCatalog, - string tableSchema, + internal ODBC32.RetCode Statistics(string? tableCatalog, + string? tableSchema, string tableName, short unique, short accuracy) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcTransaction.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcTransaction.cs index 38ae74d0ca59..aceee7efbe49 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcTransaction.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcTransaction.cs @@ -7,9 +7,9 @@ namespace System.Data.Odbc { public sealed class OdbcTransaction : DbTransaction { - private OdbcConnection _connection; + private OdbcConnection? _connection; private IsolationLevel _isolevel = IsolationLevel.Unspecified; - private OdbcConnectionHandle _handle; + private OdbcConnectionHandle? _handle; internal OdbcTransaction(OdbcConnection connection, IsolationLevel isolevel, OdbcConnectionHandle handle) { @@ -18,7 +18,7 @@ internal OdbcTransaction(OdbcConnection connection, IsolationLevel isolevel, Odb _handle = handle; } - public new OdbcConnection Connection + public new OdbcConnection? Connection { // MDAC 66655 get { @@ -26,7 +26,7 @@ internal OdbcTransaction(OdbcConnection connection, IsolationLevel isolevel, Odb } } - protected override DbConnection DbConnection + protected override DbConnection? DbConnection { // MDAC 66655 get { @@ -38,7 +38,7 @@ public override IsolationLevel IsolationLevel { get { - OdbcConnection connection = _connection; + OdbcConnection? connection = _connection; if (null == connection) { throw ADP.TransactionZombied(this); @@ -67,7 +67,7 @@ public override IsolationLevel IsolationLevel public override void Commit() { - OdbcConnection connection = _connection; + OdbcConnection? connection = _connection; if (null == connection) { throw ADP.TransactionZombied(this); @@ -76,7 +76,7 @@ public override void Commit() connection.CheckState(ADP.CommitTransaction); // MDAC 68289 //Note: SQLEndTran success if not actually in a transaction, so we have to throw - //since the IDbTransaciton spec indicates this is an error for the managed packages + //since the IDbTransaction spec indicates this is an error for the managed packages if (null == _handle) { throw ODBC.NotInTransaction(); @@ -100,7 +100,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - OdbcConnectionHandle handle = _handle; + OdbcConnectionHandle? handle = _handle; _handle = null; if (null != handle) { @@ -112,7 +112,7 @@ protected override void Dispose(bool disposing) //don't throw an exception here, but trace it so it can be logged if (_connection != null) { - Exception e = _connection.HandleErrorNoThrow(handle, retcode); + Exception e = _connection.HandleErrorNoThrow(handle, retcode)!; ADP.TraceExceptionWithoutRethrow(e); } } @@ -141,7 +141,7 @@ protected override void Dispose(bool disposing) public override void Rollback() { - OdbcConnection connection = _connection; + OdbcConnection? connection = _connection; if (null == connection) { throw ADP.TransactionZombied(this); @@ -149,7 +149,7 @@ public override void Rollback() connection.CheckState(ADP.RollbackTransaction); // MDAC 68289 //Note: SQLEndTran success if not actually in a transaction, so we have to throw - //since the IDbTransaciton spec indicates this is an error for the managed packages + //since the IDbTransaction spec indicates this is an error for the managed packages if (null == _handle) { throw ODBC.NotInTransaction(); diff --git a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs index 76a78d3defd1..7ad5fdf0812d 100644 --- a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs +++ b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs @@ -9,21 +9,21 @@ namespace System.Data.OleDb public sealed partial class OleDbCommand : System.Data.Common.DbCommand, System.Data.IDbCommand, System.ICloneable, System.IDisposable { public OleDbCommand() { } - public OleDbCommand(string cmdText) { } - public OleDbCommand(string cmdText, System.Data.OleDb.OleDbConnection connection) { } - public OleDbCommand(string cmdText, System.Data.OleDb.OleDbConnection connection, System.Data.OleDb.OleDbTransaction transaction) { } + public OleDbCommand(string? cmdText) { } + public OleDbCommand(string? cmdText, System.Data.OleDb.OleDbConnection? connection) { } + public OleDbCommand(string? cmdText, System.Data.OleDb.OleDbConnection? connection, System.Data.OleDb.OleDbTransaction? transaction) { } [System.ComponentModel.DefaultValueAttribute("")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] - public override string CommandText { get { throw null; } set { } } + public override string? CommandText { get { throw null; } set { } } public override int CommandTimeout { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(System.Data.CommandType.Text)] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public override System.Data.CommandType CommandType { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbConnection Connection { get { throw null; } set { } } - protected override System.Data.Common.DbConnection DbConnection { get { throw null; } set { } } + public new System.Data.OleDb.OleDbConnection? Connection { get { throw null; } set { } } + protected override System.Data.Common.DbConnection? DbConnection { get { throw null; } set { } } protected override System.Data.Common.DbParameterCollection DbParameterCollection { get { throw null; } } - protected override System.Data.Common.DbTransaction DbTransaction { get { throw null; } set { } } + protected override System.Data.Common.DbTransaction? DbTransaction { get { throw null; } set { } } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DefaultValueAttribute(true)] [System.ComponentModel.DesignOnlyAttribute(true)] @@ -32,7 +32,7 @@ public OleDbCommand(string cmdText, System.Data.OleDb.OleDbConnection connection public new System.Data.OleDb.OleDbParameterCollection Parameters { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] - public new System.Data.OleDb.OleDbTransaction Transaction { get { throw null; } set { } } + public new System.Data.OleDb.OleDbTransaction? Transaction { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(System.Data.UpdateRowSource.Both)] public override System.Data.UpdateRowSource UpdatedRowSource { get { throw null; } set { } } public override void Cancel() { } @@ -44,7 +44,7 @@ protected override void Dispose(bool disposing) { } public override int ExecuteNonQuery() { throw null; } public new System.Data.OleDb.OleDbDataReader ExecuteReader() { throw null; } public new System.Data.OleDb.OleDbDataReader ExecuteReader(System.Data.CommandBehavior behavior) { throw null; } - public override object ExecuteScalar() { throw null; } + public override object? ExecuteScalar() { throw null; } public override void Prepare() { } public void ResetCommandTimeout() { } System.Data.IDataReader System.Data.IDbCommand.ExecuteReader() { throw null; } @@ -54,9 +54,9 @@ public void ResetCommandTimeout() { } public sealed partial class OleDbCommandBuilder : System.Data.Common.DbCommandBuilder { public OleDbCommandBuilder() { } - public OleDbCommandBuilder(System.Data.OleDb.OleDbDataAdapter adapter) { } + public OleDbCommandBuilder(System.Data.OleDb.OleDbDataAdapter? adapter) { } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbDataAdapter DataAdapter { get { throw null; } set { } } + public new System.Data.OleDb.OleDbDataAdapter? DataAdapter { get { throw null; } set { } } protected override void ApplyParameterInfo(System.Data.Common.DbParameter parameter, System.Data.DataRow datarow, System.Data.StatementType statementType, bool whereClause) { } public static void DeriveParameters(System.Data.OleDb.OleDbCommand command) { } public new System.Data.OleDb.OleDbCommand GetDeleteCommand() { throw null; } @@ -78,11 +78,12 @@ protected override void SetRowUpdatingHandler(System.Data.Common.DbDataAdapter a public sealed partial class OleDbConnection : System.Data.Common.DbConnection, System.Data.IDbConnection, System.ICloneable, System.IDisposable { public OleDbConnection() { } - public OleDbConnection(string connectionString) { } + public OleDbConnection(string? connectionString) { } [System.ComponentModel.DefaultValueAttribute("")] [System.ComponentModel.RecommendedAsConfigurableAttribute(true)] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] [System.ComponentModel.SettingsBindableAttribute(true)] + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string ConnectionString { get { throw null; } set { } } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public override int ConnectionTimeout { get { throw null; } } @@ -97,7 +98,7 @@ public OleDbConnection(string connectionString) { } [System.ComponentModel.BrowsableAttribute(false)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public override System.Data.ConnectionState State { get { throw null; } } - public event System.Data.OleDb.OleDbInfoMessageEventHandler InfoMessage { add { } remove { } } + public event System.Data.OleDb.OleDbInfoMessageEventHandler? InfoMessage { add { } remove { } } protected override System.Data.Common.DbTransaction BeginDbTransaction(System.Data.IsolationLevel isolationLevel) { throw null; } public new System.Data.OleDb.OleDbTransaction BeginTransaction() { throw null; } public new System.Data.OleDb.OleDbTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel) { throw null; } @@ -106,11 +107,11 @@ public override void Close() { } public new System.Data.OleDb.OleDbCommand CreateCommand() { throw null; } protected override System.Data.Common.DbCommand CreateDbCommand() { throw null; } protected override void Dispose(bool disposing) { } - public override void EnlistTransaction(System.Transactions.Transaction transaction) { } - public System.Data.DataTable GetOleDbSchemaTable(System.Guid schema, object[] restrictions) { throw null; } + public override void EnlistTransaction(System.Transactions.Transaction? transaction) { } + public System.Data.DataTable GetOleDbSchemaTable(System.Guid schema, object?[]? restrictions) { throw null; } public override System.Data.DataTable GetSchema() { throw null; } public override System.Data.DataTable GetSchema(string collectionName) { throw null; } - public override System.Data.DataTable GetSchema(string collectionName, string[] restrictionValues) { throw null; } + public override System.Data.DataTable GetSchema(string collectionName, string?[]? restrictionValues) { throw null; } public override void Open() { } public static void ReleaseObjectPool() { } public void ResetState() { } @@ -121,13 +122,14 @@ public void ResetState() { } public sealed partial class OleDbConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder { public OleDbConnectionStringBuilder() { } - public OleDbConnectionStringBuilder(string connectionString) { } + public OleDbConnectionStringBuilder(string? connectionString) { } [System.ComponentModel.DisplayNameAttribute("Data Source")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public string DataSource { get { throw null; } set { } } [System.ComponentModel.DisplayNameAttribute("File Name")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public string FileName { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override object this[string keyword] { get { throw null; } set { } } public override System.Collections.ICollection Keys { get { throw null; } } [System.ComponentModel.DisplayNameAttribute("Persist Security Info")] @@ -136,28 +138,28 @@ public OleDbConnectionStringBuilder(string connectionString) { } public override void Clear() { } public override bool ContainsKey(string keyword) { throw null; } public override bool Remove(string keyword) { throw null; } - public override bool TryGetValue(string keyword, out object value) { throw null; } + public override bool TryGetValue(string keyword, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out object? value) { throw null; } } public sealed partial class OleDbDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable { public OleDbDataAdapter() { } - public OleDbDataAdapter(System.Data.OleDb.OleDbCommand selectCommand) { } - public OleDbDataAdapter(string selectCommandText, System.Data.OleDb.OleDbConnection selectConnection) { } - public OleDbDataAdapter(string selectCommandText, string selectConnectionString) { } + public OleDbDataAdapter(System.Data.OleDb.OleDbCommand? selectCommand) { } + public OleDbDataAdapter(string? selectCommandText, System.Data.OleDb.OleDbConnection? selectConnection) { } + public OleDbDataAdapter(string? selectCommandText, string? selectConnectionString) { } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbCommand DeleteCommand { get { throw null; } set { } } + public new System.Data.OleDb.OleDbCommand? DeleteCommand { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbCommand InsertCommand { get { throw null; } set { } } + public new System.Data.OleDb.OleDbCommand? InsertCommand { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbCommand SelectCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.DeleteCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.InsertCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.SelectCommand { get { throw null; } set { } } - System.Data.IDbCommand System.Data.IDbDataAdapter.UpdateCommand { get { throw null; } set { } } + public new System.Data.OleDb.OleDbCommand? SelectCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.DeleteCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.InsertCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.SelectCommand { get { throw null; } set { } } + System.Data.IDbCommand? System.Data.IDbDataAdapter.UpdateCommand { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(null)] - public new System.Data.OleDb.OleDbCommand UpdateCommand { get { throw null; } set { } } - public event System.Data.OleDb.OleDbRowUpdatedEventHandler RowUpdated { add { } remove { } } - public event System.Data.OleDb.OleDbRowUpdatingEventHandler RowUpdating { add { } remove { } } + public new System.Data.OleDb.OleDbCommand? UpdateCommand { get { throw null; } set { } } + public event System.Data.OleDb.OleDbRowUpdatedEventHandler? RowUpdated { add { } remove { } } + public event System.Data.OleDb.OleDbRowUpdatingEventHandler? RowUpdating { add { } remove { } } protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } public int Fill(System.Data.DataSet dataSet, object ADODBRecordSet, string srcTable) { throw null; } @@ -180,9 +182,9 @@ internal OleDbDataReader() { } public override void Close() { } public override bool GetBoolean(int ordinal) { throw null; } public override byte GetByte(int ordinal) { throw null; } - public override long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length) { throw null; } + public override long GetBytes(int ordinal, long dataIndex, byte[]? buffer, int bufferIndex, int length) { throw null; } public override char GetChar(int ordinal) { throw null; } - public override long GetChars(int ordinal, long dataIndex, char[] buffer, int bufferIndex, int length) { throw null; } + public override long GetChars(int ordinal, long dataIndex, char[]? buffer, int bufferIndex, int length) { throw null; } public new System.Data.OleDb.OleDbDataReader GetData(int ordinal) { throw null; } public override string GetDataTypeName(int index) { throw null; } public override System.DateTime GetDateTime(int ordinal) { throw null; } @@ -259,7 +261,7 @@ internal OleDbInfoMessageEventArgs() { } public int ErrorCode { get { throw null; } } public System.Data.OleDb.OleDbErrorCollection Errors { get { throw null; } } public string Message { get { throw null; } } - public string Source { get { throw null; } } + public string? Source { get { throw null; } } public override string ToString() { throw null; } } public delegate void OleDbInfoMessageEventHandler(object sender, System.Data.OleDb.OleDbInfoMessageEventArgs e); @@ -319,12 +321,12 @@ public static partial class OleDbMetaDataColumnNames public sealed partial class OleDbParameter : System.Data.Common.DbParameter, System.Data.IDataParameter, System.Data.IDbDataParameter, System.ICloneable { public OleDbParameter() { } - public OleDbParameter(string name, System.Data.OleDb.OleDbType dataType) { } - public OleDbParameter(string name, System.Data.OleDb.OleDbType dataType, int size) { } - public OleDbParameter(string parameterName, System.Data.OleDb.OleDbType dbType, int size, System.Data.ParameterDirection direction, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object value) { } - public OleDbParameter(string parameterName, System.Data.OleDb.OleDbType dbType, int size, System.Data.ParameterDirection direction, byte precision, byte scale, string sourceColumn, System.Data.DataRowVersion sourceVersion, bool sourceColumnNullMapping, object value) { } - public OleDbParameter(string name, System.Data.OleDb.OleDbType dataType, int size, string srcColumn) { } - public OleDbParameter(string name, object value) { } + public OleDbParameter(string? name, System.Data.OleDb.OleDbType dataType) { } + public OleDbParameter(string? name, System.Data.OleDb.OleDbType dataType, int size) { } + public OleDbParameter(string? parameterName, System.Data.OleDb.OleDbType dbType, int size, System.Data.ParameterDirection direction, bool isNullable, byte precision, byte scale, string? srcColumn, System.Data.DataRowVersion srcVersion, object? value) { } + public OleDbParameter(string? parameterName, System.Data.OleDb.OleDbType dbType, int size, System.Data.ParameterDirection direction, byte precision, byte scale, string? sourceColumn, System.Data.DataRowVersion sourceVersion, bool sourceColumnNullMapping, object? value) { } + public OleDbParameter(string? name, System.Data.OleDb.OleDbType dataType, int size, string? srcColumn) { } + public OleDbParameter(string? name, object? value) { } public override System.Data.DbType DbType { get { throw null; } set { } } [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public override System.Data.ParameterDirection Direction { get { throw null; } set { } } @@ -332,18 +334,20 @@ public OleDbParameter(string name, object value) { } [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] [System.Data.Common.DbProviderSpecificTypePropertyAttribute(true)] public System.Data.OleDb.OleDbType OleDbType { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string ParameterName { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute((byte)0)] public new byte Precision { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute((byte)0)] public new byte Scale { get { throw null; } set { } } public override int Size { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public override string SourceColumn { get { throw null; } set { } } public override bool SourceColumnNullMapping { get { throw null; } set { } } public override System.Data.DataRowVersion SourceVersion { get { throw null; } set { } } [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] [System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.StringConverter))] - public override object Value { get { throw null; } set { } } + public override object? Value { get { throw null; } set { } } public override void ResetDbType() { } public void ResetOleDbType() { } object System.ICloneable.Clone() { throw null; } @@ -365,13 +369,13 @@ internal OleDbParameterCollection() { } public override object SyncRoot { get { throw null; } } public System.Data.OleDb.OleDbParameter Add(System.Data.OleDb.OleDbParameter value) { throw null; } public override int Add(object value) { throw null; } - public System.Data.OleDb.OleDbParameter Add(string parameterName, System.Data.OleDb.OleDbType oleDbType) { throw null; } - public System.Data.OleDb.OleDbParameter Add(string parameterName, System.Data.OleDb.OleDbType oleDbType, int size) { throw null; } - public System.Data.OleDb.OleDbParameter Add(string parameterName, System.Data.OleDb.OleDbType oleDbType, int size, string sourceColumn) { throw null; } - public System.Data.OleDb.OleDbParameter Add(string parameterName, object value) { throw null; } + public System.Data.OleDb.OleDbParameter Add(string? parameterName, System.Data.OleDb.OleDbType oleDbType) { throw null; } + public System.Data.OleDb.OleDbParameter Add(string? parameterName, System.Data.OleDb.OleDbType oleDbType, int size) { throw null; } + public System.Data.OleDb.OleDbParameter Add(string? parameterName, System.Data.OleDb.OleDbType oleDbType, int size, string? sourceColumn) { throw null; } + public System.Data.OleDb.OleDbParameter Add(string? parameterName, object? value) { throw null; } public override void AddRange(System.Array values) { } public void AddRange(System.Data.OleDb.OleDbParameter[] values) { } - public System.Data.OleDb.OleDbParameter AddWithValue(string parameterName, object value) { throw null; } + public System.Data.OleDb.OleDbParameter AddWithValue(string? parameterName, object? value) { throw null; } public override void Clear() { } public bool Contains(System.Data.OleDb.OleDbParameter value) { throw null; } public override bool Contains(object value) { throw null; } @@ -396,14 +400,14 @@ protected override void SetParameter(string parameterName, System.Data.Common.Db public sealed partial class OleDbRowUpdatedEventArgs : System.Data.Common.RowUpdatedEventArgs { public OleDbRowUpdatedEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } - public new System.Data.OleDb.OleDbCommand Command { get { throw null; } } + public new System.Data.OleDb.OleDbCommand? Command { get { throw null; } } } public delegate void OleDbRowUpdatedEventHandler(object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e); public sealed partial class OleDbRowUpdatingEventArgs : System.Data.Common.RowUpdatingEventArgs { public OleDbRowUpdatingEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } - protected override System.Data.IDbCommand BaseCommand { get { throw null; } set { } } - public new System.Data.OleDb.OleDbCommand Command { get { throw null; } set { } } + protected override System.Data.IDbCommand? BaseCommand { get { throw null; } set { } } + public new System.Data.OleDb.OleDbCommand? Command { get { throw null; } set { } } } public delegate void OleDbRowUpdatingEventHandler(object sender, System.Data.OleDb.OleDbRowUpdatingEventArgs e); public sealed partial class OleDbSchemaGuid @@ -450,8 +454,8 @@ public OleDbSchemaGuid() { } public sealed partial class OleDbTransaction : System.Data.Common.DbTransaction { internal OleDbTransaction() { } - public new System.Data.OleDb.OleDbConnection Connection { get { throw null; } } - protected override System.Data.Common.DbConnection DbConnection { get { throw null; } } + public new System.Data.OleDb.OleDbConnection? Connection { get { throw null; } } + protected override System.Data.Common.DbConnection? DbConnection { get { throw null; } } public override System.Data.IsolationLevel IsolationLevel { get { throw null; } } public System.Data.OleDb.OleDbTransaction Begin() { throw null; } public System.Data.OleDb.OleDbTransaction Begin(System.Data.IsolationLevel isolevel) { throw null; } diff --git a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj index 44d08a1f18d0..912dfa3acf23 100644 --- a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.csproj @@ -2,6 +2,7 @@ netstandard2.0;net461 $(NoWarn);0618 + enable diff --git a/src/libraries/System.Data.OleDb/src/AdapterSwitches.cs b/src/libraries/System.Data.OleDb/src/AdapterSwitches.cs index d8a0ac64092c..4ffe04c40f74 100644 --- a/src/libraries/System.Data.OleDb/src/AdapterSwitches.cs +++ b/src/libraries/System.Data.OleDb/src/AdapterSwitches.cs @@ -9,13 +9,13 @@ namespace System.Data.Common { internal static class AdapterSwitches { - private static TraceSwitch _dataSchema; + private static TraceSwitch? _dataSchema; internal static TraceSwitch DataSchema { get { - TraceSwitch dataSchema = _dataSchema; + TraceSwitch? dataSchema = _dataSchema; if (null == dataSchema) { _dataSchema = dataSchema = new TraceSwitch("Data.Schema", "Enable tracing for schema actions."); diff --git a/src/libraries/System.Data.OleDb/src/ColumnBinding.cs b/src/libraries/System.Data.OleDb/src/ColumnBinding.cs index 322e30c24cb3..34334156e3e1 100644 --- a/src/libraries/System.Data.OleDb/src/ColumnBinding.cs +++ b/src/libraries/System.Data.OleDb/src/ColumnBinding.cs @@ -19,14 +19,14 @@ internal sealed class ColumnBinding private readonly Bindings _bindings; // unique to this ColumnBinding - private readonly OleDbParameter _parameter; // output value + private readonly OleDbParameter? _parameter; // output value private readonly int _parameterChangeID; private readonly int _offsetStatus; private readonly int _offsetLength; private readonly int _offsetValue; // Delegate ad hoc created 'Marshal.GetIDispatchForObject' reflection object cache - private static Func s_getIDispatchForObject; + private static Func? s_getIDispatchForObject; private readonly int _ordinal; private readonly int _maxLen; @@ -42,15 +42,15 @@ internal sealed class ColumnBinding // unique per current input value private int _valueBindingOffset; private int _valueBindingSize; - internal StringMemHandle _sptr; + internal StringMemHandle? _sptr; private GCHandle _pinnedBuffer; // value is cached via property getters so the original may be released // for Value, ValueByteArray, ValueString, ValueVariant - private object _value; + private object? _value; internal ColumnBinding(OleDbDataReader dataReader, int index, int indexForAccessor, int indexWithinAccessor, - OleDbParameter parameter, RowBinding rowbinding, Bindings bindings, tagDBBINDING binding, int offset, + OleDbParameter? parameter, RowBinding rowbinding, Bindings bindings, tagDBBINDING binding, int offset, bool ifIRowsetElseIRow) { Debug.Assert(null != rowbinding, "null rowbinding"); @@ -123,7 +123,7 @@ private short DbType private Type ExpectedType { - get { return NativeDBType.FromDBType(DbType, false, false).dataType; } + get { return NativeDBType.FromDBType(DbType, false, false).dataType!; } } internal int Index @@ -203,7 +203,7 @@ internal void ResetValue() { _value = null; - StringMemHandle sptr = _sptr; + StringMemHandle? sptr = _sptr; _sptr = null; if (null != sptr) @@ -274,8 +274,8 @@ private void SetValueEmpty() internal object Value() { - object value = _value; - if (null == value) + object value; + if (null == _value) { switch (StatusValue()) { @@ -433,9 +433,9 @@ internal object Value() } _value = value; } - return value; + return _value!; } - internal void Value(object value) + internal void Value(object? value) { if (null == value) { @@ -663,7 +663,7 @@ private byte[] Value_ByRefBYTES() { Debug.Assert(((NativeDBType.BYREF | NativeDBType.BYTES) == DbType), "Value_ByRefBYTES"); Debug.Assert((DBStatus.S_OK == StatusValue()), "Value_ByRefBYTES"); - byte[] value = null; + byte[]? value = null; RowBinding bindings = RowBinding; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); @@ -948,7 +948,8 @@ internal OleDbDataReader Value_HCHAPTER() Debug.Assert(NativeDBType.HCHAPTER == DbType, "Value_HCHAPTER"); Debug.Assert(DBStatus.S_OK == StatusValue(), "Value_HCHAPTER"); - return DataReader().ResetChapter(IndexForAccessor, IndexWithinAccessor, RowBinding, ValueOffset); + // TODO-NULLABLE: This shouldn't return null + return DataReader().ResetChapter(IndexForAccessor, IndexWithinAccessor, RowBinding, ValueOffset)!; } private sbyte Value_I1() @@ -1042,15 +1043,15 @@ private void Value_IDISPATCH(object value) // lazy init reflection objects if (s_getIDispatchForObject == null) { - object delegateInstance = null; - MethodInfo mi = typeof(Marshal).GetMethod("GetIDispatchForObject", BindingFlags.Public | BindingFlags.Static); + object? delegateInstance = null; + MethodInfo? mi = typeof(Marshal).GetMethod("GetIDispatchForObject", BindingFlags.Public | BindingFlags.Static); if (mi == null) { throw new NotSupportedException(SR.PlatformNotSupported_GetIDispatchForObject); } Volatile.Write(ref delegateInstance, mi.CreateDelegate(typeof(Func))); s_getIDispatchForObject = delegateInstance as Func; - ptr = s_getIDispatchForObject(value); + ptr = s_getIDispatchForObject!(value); } RowBinding.WriteIntPtr(ValueOffset, ptr); } @@ -1272,7 +1273,7 @@ internal bool ValueBoolean() internal byte[] ValueByteArray() { - byte[] value = (byte[])_value; + byte[]? value = (byte[]?)_value; if (null == value) { switch (StatusValue()) @@ -1340,7 +1341,7 @@ internal byte ValueByte() internal OleDbDataReader ValueChapter() { - OleDbDataReader value = (OleDbDataReader)_value; + OleDbDataReader? value = (OleDbDataReader?)_value; if (null == value) { switch (StatusValue()) @@ -1605,7 +1606,7 @@ internal double ValueDouble() internal string ValueString() { - string value = (string)_value; + string? value = (string?)_value; if (null == value) { switch (StatusValue()) @@ -1652,7 +1653,7 @@ internal string ValueString() private object ValueVariant() { - object value = _value; + object? value = _value; if (null == value) { value = Value_VARIANT(); diff --git a/src/libraries/System.Data.OleDb/src/DbBindings.cs b/src/libraries/System.Data.OleDb/src/DbBindings.cs index 512985e4bbba..c38028128544 100644 --- a/src/libraries/System.Data.OleDb/src/DbBindings.cs +++ b/src/libraries/System.Data.OleDb/src/DbBindings.cs @@ -9,16 +9,16 @@ namespace System.Data.OleDb { internal sealed class Bindings { - private readonly tagDBPARAMBINDINFO[] _bindInfo; + private readonly tagDBPARAMBINDINFO[]? _bindInfo; private readonly tagDBBINDING[] _dbbindings; private readonly tagDBCOLUMNACCESS[] _dbcolumns; - private OleDbParameter[] _parameters; + private OleDbParameter[]? _parameters; private readonly int _collectionChangeID; - private OleDbDataReader _dataReader; - private ColumnBinding[] _columnBindings; - private RowBinding _rowBinding; + private OleDbDataReader? _dataReader; + private ColumnBinding[]? _columnBindings; + private RowBinding? _rowBinding; private int _index; private readonly int _count; @@ -53,7 +53,7 @@ internal Bindings(OleDbDataReader dataReader, bool ifIRowsetElseIRow, int count) _ifIRowsetElseIRow = ifIRowsetElseIRow; } - internal tagDBPARAMBINDINFO[] BindInfo + internal tagDBPARAMBINDINFO[]? BindInfo { get { return _bindInfo; } } @@ -84,7 +84,7 @@ internal OleDbParameter[] Parameters() return _parameters; } - internal RowBinding RowBinding() + internal RowBinding? RowBinding() { //Debug.Assert(null != _rowBinding, "null RowBinding"); return _rowBinding; @@ -102,7 +102,7 @@ internal IntPtr DataSourceType //get { return _bindInfo[_index].pwszDataSourceType; } set { - _bindInfo[_index].pwszDataSourceType = value; + _bindInfo![_index].pwszDataSourceType = value; } } internal IntPtr Name @@ -110,7 +110,7 @@ internal IntPtr Name //get { return _bindInfo[_index].pwszName; } set { - _bindInfo[_index].pwszName = value; + _bindInfo![_index].pwszName = value; } } internal IntPtr ParamSize @@ -125,7 +125,7 @@ internal IntPtr ParamSize } set { - _bindInfo[_index].ulParamSize = value; + _bindInfo![_index].ulParamSize = value; } } internal int Flags @@ -133,7 +133,7 @@ internal int Flags //get { return _bindInfo[_index].dwFlag; } set { - _bindInfo[_index].dwFlags = value; + _bindInfo![_index].dwFlags = value; } } @@ -246,7 +246,7 @@ internal byte Scale } } - internal int AllocateForAccessor(OleDbDataReader dataReader, int indexStart, int indexForAccessor) + internal int AllocateForAccessor(OleDbDataReader? dataReader, int indexStart, int indexForAccessor) { Debug.Assert(null == _rowBinding, "row binding already allocated"); Debug.Assert(null == _columnBindings, "column bindings already allocated"); @@ -283,7 +283,7 @@ internal void ApplyInputParameters() ColumnBinding[] columnBindings = this.ColumnBindings(); OleDbParameter[] parameters = this.Parameters(); - RowBinding().StartDataBlock(); + RowBinding()!.StartDataBlock(); for (int i = 0; i < parameters.Length; ++i) { if (ADP.IsDirection(parameters[i], ParameterDirection.Input)) @@ -345,7 +345,7 @@ internal bool AreParameterBindingsInvalid(OleDbParameterCollection collection) internal void CleanupBindings() { - RowBinding rowBinding = this.RowBinding(); + RowBinding? rowBinding = this.RowBinding(); if (null != rowBinding) { rowBinding.ResetValues(); @@ -384,7 +384,7 @@ public void Dispose() _dataReader = null; _columnBindings = null; - RowBinding rowBinding = _rowBinding; + RowBinding? rowBinding = _rowBinding; _rowBinding = null; if (null != rowBinding) { diff --git a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs index aa42ab2cb8a8..11c5e01bb4b5 100644 --- a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs +++ b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.Versioning; using System.Text; @@ -96,7 +97,7 @@ private static class SYNONYM private readonly string _usersConnectionString; private readonly Hashtable _parsetable; - internal readonly NameValuePair KeyChain; + internal readonly NameValuePair? KeyChain; internal readonly bool HasPasswordKeyword; internal readonly bool HasUserIdKeyword; @@ -117,14 +118,14 @@ private static class SYNONYM internal readonly bool UseOdbcRules; // called by derived classes that may cache based on connectionString - public DbConnectionOptions(string connectionString) + public DbConnectionOptions(string? connectionString) : this(connectionString, null, false) { } // synonyms hashtable is meant to be read-only translation of parsed string // keywords/synonyms to a known keyword string - public DbConnectionOptions(string connectionString, Hashtable synonyms, bool useOdbcRules) + public DbConnectionOptions(string? connectionString, Hashtable? synonyms, bool useOdbcRules) { UseOdbcRules = useOdbcRules; _parsetable = new Hashtable(); @@ -171,12 +172,12 @@ public bool IsEmpty get { return (null == KeyChain); } } - public string this[string keyword] + public string? this[string keyword] { - get { return (string)_parsetable[keyword]; } + get { return (string?)_parsetable[keyword]; } } - internal static void AppendKeyValuePairBuilder(StringBuilder builder, string keyName, string keyValue, bool useOdbcRules) + internal static void AppendKeyValuePairBuilder(StringBuilder builder, string keyName, string? keyValue, bool useOdbcRules) { ADP.CheckArgumentNull(builder, "builder"); ADP.CheckArgumentLength(keyName, "keyName"); @@ -251,7 +252,7 @@ internal static void AppendKeyValuePairBuilder(StringBuilder builder, string key public bool ConvertValueToBoolean(string keyName, bool defaultValue) { - object value = _parsetable[keyName]; + object? value = _parsetable[keyName]; if (null == value) { return defaultValue; @@ -281,7 +282,7 @@ internal static bool ConvertValueToBooleanInternal(string keyName, string string public int ConvertValueToInt32(string keyName, int defaultValue) { - object value = _parsetable[keyName]; + object? value = _parsetable[keyName]; if (null == value) { return defaultValue; @@ -305,9 +306,9 @@ internal static int ConvertToInt32Internal(string keyname, string stringValue) } } - public string ConvertValueToString(string keyName, string defaultValue) + public string? ConvertValueToString(string keyName, string? defaultValue) { - string value = (string)_parsetable[keyName]; + string? value = (string?)_parsetable[keyName]; return ((null != value) ? value : defaultValue); } @@ -330,16 +331,16 @@ protected internal virtual string Expand() // * this method queries "DataDirectory" value from the current AppDomain. // This string is used for to replace "!DataDirectory!" values in the connection string, it is not considered as an "exposed resource". // * This method uses GetFullPath to validate that root path is valid, the result is not exposed out. - internal static string ExpandDataDirectory(string keyword, string value, ref string datadir) + internal static string? ExpandDataDirectory(string keyword, string? value, ref string? datadir) { - string fullPath = null; + string? fullPath = null; if ((null != value) && value.StartsWith(DataDirectory, StringComparison.OrdinalIgnoreCase)) { - string rootFolderPath = datadir; + string? rootFolderPath = datadir; if (null == rootFolderPath) { // find the replacement path - object rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory"); + object? rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory"); rootFolderPath = (rootFolderObject as string); if ((null != rootFolderObject) && (null == rootFolderPath)) { @@ -388,16 +389,16 @@ internal static string ExpandDataDirectory(string keyword, string value, ref str return fullPath; } - internal string ExpandDataDirectories(ref string filename, ref int position) + internal string? ExpandDataDirectories(ref string? filename, ref int position) { - string value = null; + string? value = null; StringBuilder builder = new StringBuilder(_usersConnectionString.Length); - string datadir = null; + string? datadir = null; int copyPosition = 0; bool expanded = false; - for (NameValuePair current = KeyChain; null != current; current = current.Next) + for (NameValuePair? current = KeyChain; null != current; current = current.Next) { value = current.Value; @@ -481,11 +482,11 @@ internal string ExpandDataDirectories(ref string filename, ref int position) } [System.Diagnostics.Conditional("DEBUG")] - private static void DebugTraceKeyValuePair(string keyname, string keyvalue, Hashtable synonyms) + private static void DebugTraceKeyValuePair(string keyname, string? keyvalue, Hashtable? synonyms) { Debug.Assert(keyname == keyname.ToLowerInvariant(), "missing ToLower"); - string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); + string? realkeyname = ((null != synonyms) ? (string)synonyms[keyname]! : keyname); if ((KEY.Password != realkeyname) && (SYNONYM.Pwd != realkeyname)) { // don't trace passwords ever! if (null != keyvalue) @@ -543,7 +544,7 @@ private enum ParserState NullTermination, }; - internal static int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue) + internal static int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string? keyname, out string? keyvalue) { int startposition = currentPosition; @@ -747,7 +748,7 @@ internal static int GetKeyValuePair(string connectionString, int currentPosition return currentPosition; } - private static bool IsValueValidInternal(string keyvalue) + private static bool IsValueValidInternal(string? keyvalue) { if (null != keyvalue) { @@ -760,7 +761,7 @@ private static bool IsValueValidInternal(string keyvalue) return true; } - private static bool IsKeyNameValid(string keyname) + private static bool IsKeyNameValid([NotNullWhen(true)] string? keyname) { if (null != keyname) { @@ -774,7 +775,7 @@ private static bool IsKeyNameValid(string keyname) } #if DEBUG - private static Hashtable SplitConnectionString(string connectionString, Hashtable synonyms, bool firstKey) + private static Hashtable SplitConnectionString(string connectionString, Hashtable? synonyms, bool firstKey) { Hashtable parsetable = new Hashtable(); Regex parser = (firstKey ? ConnectionStringRegexOdbc : ConnectionStringRegex); @@ -795,7 +796,7 @@ private static Hashtable SplitConnectionString(string connectionString, Hashtabl foreach (Capture keypair in match.Groups[KeyIndex].Captures) { string keyname = (firstKey ? keypair.Value : keypair.Value.Replace("==", "=")).ToLowerInvariant(); - string keyvalue = keyvalues[indexValue++].Value; + string? keyvalue = keyvalues[indexValue++].Value; if (0 < keyvalue.Length) { if (!firstKey) @@ -819,7 +820,7 @@ private static Hashtable SplitConnectionString(string connectionString, Hashtabl } DebugTraceKeyValuePair(keyname, keyvalue, synonyms); - string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); + string? realkeyname = ((null != synonyms) ? (string)synonyms[keyname]! : keyname); if (!IsKeyNameValid(realkeyname)) { throw ADP.KeywordNotSupported(keyname); @@ -833,7 +834,7 @@ private static Hashtable SplitConnectionString(string connectionString, Hashtabl return parsetable; } - private static void ParseComparison(Hashtable parsetable, string connectionString, Hashtable synonyms, bool firstKey, Exception e) + private static void ParseComparison(Hashtable parsetable, string connectionString, Hashtable? synonyms, bool firstKey, Exception? e) { try { @@ -841,8 +842,8 @@ private static void ParseComparison(Hashtable parsetable, string connectionStrin foreach (DictionaryEntry entry in parsedvalues) { string keyname = (string)entry.Key; - string value1 = (string)entry.Value; - string value2 = (string)parsetable[keyname]; + string? value1 = (string?)entry.Value; + string? value2 = (string?)parsetable[keyname]; Debug.Assert(parsetable.Contains(keyname), "ParseInternal code vs. regex mismatch keyname <" + keyname + ">"); Debug.Assert(value1 == value2, "ParseInternal code vs. regex mismatch keyvalue <" + value1 + "> <" + value2 + ">"); } @@ -884,11 +885,11 @@ private static void ParseComparison(Hashtable parsetable, string connectionStrin } } #endif - private static NameValuePair ParseInternal(Hashtable parsetable, string connectionString, bool buildChain, Hashtable synonyms, bool firstKey) + private static NameValuePair? ParseInternal(Hashtable parsetable, string connectionString, bool buildChain, Hashtable? synonyms, bool firstKey) { Debug.Assert(null != connectionString, "null connectionstring"); StringBuilder buffer = new StringBuilder(); - NameValuePair localKeychain = null, keychain = null; + NameValuePair? localKeychain = null, keychain = null; #if DEBUG try { @@ -899,7 +900,7 @@ private static NameValuePair ParseInternal(Hashtable parsetable, string connecti { int startPosition = nextStartPosition; - string keyname, keyvalue; + string? keyname, keyvalue; nextStartPosition = GetKeyValuePair(connectionString, startPosition, buffer, firstKey, out keyname, out keyvalue); if (ADP.IsEmpty(keyname)) { @@ -912,7 +913,7 @@ private static NameValuePair ParseInternal(Hashtable parsetable, string connecti Debug.Assert(IsKeyNameValid(keyname), "ParseFailure, invalid keyname"); Debug.Assert(IsValueValidInternal(keyvalue), "parse failure, invalid keyvalue"); #endif - string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); + string? realkeyname = ((null != synonyms) ? (string)synonyms[keyname]! : keyname); if (!IsKeyNameValid(realkeyname)) { throw ADP.KeywordNotSupported(keyname); @@ -943,13 +944,13 @@ private static NameValuePair ParseInternal(Hashtable parsetable, string connecti return keychain; } - internal NameValuePair ReplacePasswordPwd(out string constr, bool fakePassword) + internal NameValuePair? ReplacePasswordPwd(out string constr, bool fakePassword) { bool expanded = false; int copyPosition = 0; - NameValuePair head = null, tail = null, next = null; + NameValuePair? head = null, tail = null, next = null; StringBuilder builder = new StringBuilder(_usersConnectionString.Length); - for (NameValuePair current = KeyChain; null != current; current = current.Next) + for (NameValuePair? current = KeyChain; null != current; current = current.Next) { if ((KEY.Password != current.Name) && (SYNONYM.Pwd != current.Name)) { diff --git a/src/libraries/System.Data.OleDb/src/DbConnectionStringCommon.cs b/src/libraries/System.Data.OleDb/src/DbConnectionStringCommon.cs index 9ee6aded022f..9477bb47b6cb 100644 --- a/src/libraries/System.Data.OleDb/src/DbConnectionStringCommon.cs +++ b/src/libraries/System.Data.OleDb/src/DbConnectionStringCommon.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Data.Common @@ -111,7 +112,7 @@ public K Current } } - object System.Collections.IEnumerator.Current + object? System.Collections.IEnumerator.Current { get { @@ -131,7 +132,7 @@ internal static class DbConnectionStringBuilderUtil internal static bool ConvertToBoolean(object value) { Debug.Assert(null != value, "ConvertToBoolean(null)"); - string svalue = (value as string); + string? svalue = (value as string); if (null != svalue) { if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes")) diff --git a/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs b/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs index a78b359f304a..a89572d1f606 100644 --- a/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs +++ b/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs @@ -3,24 +3,25 @@ using System.ComponentModel; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; namespace System.Data.OleDb { public sealed partial class OleDbParameter : DbParameter { // V1.2.3300 - private object _value; + private object? _value; - private object _parent; + private object? _parent; private ParameterDirection _direction; private int _size; - private string _sourceColumn; + private string? _sourceColumn; private DataRowVersion _sourceVersion; private bool _sourceColumnNullMapping; private bool _isNullable; - private object _coercedValue; + private object? _coercedValue; private OleDbParameter(OleDbParameter source) : this() { // V1.2.3300, Clone @@ -28,14 +29,14 @@ private OleDbParameter(OleDbParameter source) : this() source.CloneHelper(this); - ICloneable cloneable = (_value as ICloneable); + ICloneable? cloneable = (_value as ICloneable); if (null != cloneable) { _value = cloneable.Clone(); } } - private object CoercedValue + private object? CoercedValue { // V1.2.3300 get { @@ -134,11 +135,12 @@ private bool ShouldSerializeSize() return (0 != _size); } + [AllowNull] public override string SourceColumn { // V1.2.3300, XXXParameter V1.0.3300 get { - string sourceColumn = _sourceColumn; + string? sourceColumn = _sourceColumn; return ((null != sourceColumn) ? sourceColumn : string.Empty); } set @@ -200,13 +202,13 @@ internal void CopyTo(DbParameter destination) CloneHelper((OleDbParameter)destination); } - internal object CompareExchangeParent(object value, object comparand) + internal object? CompareExchangeParent(object? value, object? comparand) { // the interlock guarantees same parameter won't belong to multiple collections // at the same time, but to actually occur the user must really try // since we never declared thread safety, we don't care at this time //return System.Threading.Interlocked.CompareExchange(ref _parent, value, comparand); - object parent = _parent; + object? parent = _parent; if (comparand == parent) { _parent = value; @@ -224,7 +226,7 @@ public override string ToString() return ParameterName; } - private byte ValuePrecisionCore(object value) + private byte ValuePrecisionCore(object? value) { // V1.2.3300 if (value is decimal) { @@ -233,7 +235,7 @@ private byte ValuePrecisionCore(object value) return 0; } - private byte ValueScaleCore(object value) + private byte ValueScaleCore(object? value) { // V1.2.3300 if (value is decimal) { @@ -242,21 +244,21 @@ private byte ValueScaleCore(object value) return 0; } - private int ValueSizeCore(object value) + private int ValueSizeCore(object? value) { // V1.2.3300 if (!ADP.IsNull(value)) { - string svalue = (value as string); + string? svalue = (value as string); if (null != svalue) { return svalue.Length; } - byte[] bvalue = (value as byte[]); + byte[]? bvalue = (value as byte[]); if (null != bvalue) { return bvalue.Length; } - char[] cvalue = (value as char[]); + char[]? cvalue = (value as char[]); if (null != cvalue) { return cvalue.Length; diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index b4fb008c499f..30935b1c6f80 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -14,7 +14,7 @@ internal sealed class DBPropSet : SafeHandle private readonly int propertySetCount; // stores the exception with last error.HRESULT from IDBProperties.GetProperties - private Exception lastErrorFromProvider; + private Exception? lastErrorFromProvider; private DBPropSet() : base(IntPtr.Zero, true) { @@ -42,7 +42,7 @@ internal DBPropSet(int propertysetCount) : this() } } - internal DBPropSet(UnsafeNativeMethods.IDBProperties properties, PropertyIDSet propidset, out OleDbHResult hr) : this() + internal DBPropSet(UnsafeNativeMethods.IDBProperties properties, PropertyIDSet? propidset, out OleDbHResult hr) : this() { Debug.Assert(null != properties, "null IDBProperties"); @@ -60,7 +60,7 @@ internal DBPropSet(UnsafeNativeMethods.IDBProperties properties, PropertyIDSet p } } - internal DBPropSet(UnsafeNativeMethods.IRowsetInfo properties, PropertyIDSet propidset, out OleDbHResult hr) : this() + internal DBPropSet(UnsafeNativeMethods.IRowsetInfo properties, PropertyIDSet? propidset, out OleDbHResult hr) : this() { Debug.Assert(null != properties, "null IRowsetInfo"); @@ -78,7 +78,7 @@ internal DBPropSet(UnsafeNativeMethods.IRowsetInfo properties, PropertyIDSet pro } } - internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyIDSet propidset, out OleDbHResult hr) : this() + internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyIDSet? propidset, out OleDbHResult hr) : this() { Debug.Assert(null != properties, "null ICommandProperties"); @@ -99,7 +99,7 @@ internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyID private void SetLastErrorInfo(OleDbHResult lastErrorHr) { // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes - UnsafeNativeMethods.IErrorInfo errorInfo = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; string message = string.Empty; OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo @@ -172,7 +172,7 @@ internal ItagDBPROP[] GetPropertySet(int index, out Guid propertyset) } tagDBPROPSET propset = new tagDBPROPSET(); - ItagDBPROP[] properties = null; + ItagDBPROP[]? properties = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); diff --git a/src/libraries/System.Data.OleDb/src/NativeMethods.cs b/src/libraries/System.Data.OleDb/src/NativeMethods.cs index 871ae1bb7de9..6592ed5df3b5 100644 --- a/src/libraries/System.Data.OleDb/src/NativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/NativeMethods.cs @@ -27,7 +27,7 @@ internal interface ITransactionJoin int GetOptionsObject(IntPtr ppOptions); void JoinTransaction( - [In, MarshalAs(UnmanagedType.Interface)] object punkTransactionCoord, + [In, MarshalAs(UnmanagedType.Interface)] object? punkTransactionCoord, [In] int isoLevel, [In] int isoFlags, [In] IntPtr pOtherOptions); diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index ced289c042f7..329200e7f2ed 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -14,24 +15,24 @@ namespace System.Data.OleDb public sealed class OleDbCommand : DbCommand, ICloneable, IDbCommand { // command data - private string _commandText; + private string? _commandText; private CommandType _commandType; private int _commandTimeout = ADP.DefaultCommandTimeout; private UpdateRowSource _updatedRowSource = UpdateRowSource.Both; private bool _designTimeInvisible; - private OleDbConnection _connection; - private OleDbTransaction _transaction; + private OleDbConnection? _connection; + private OleDbTransaction? _transaction; - private OleDbParameterCollection _parameters; + private OleDbParameterCollection? _parameters; // native information - private UnsafeNativeMethods.ICommandText _icommandText; + private UnsafeNativeMethods.ICommandText? _icommandText; // if executing with a different CommandBehavior.KeyInfo behavior // original ICommandText must be released and a new ICommandText generated private CommandBehavior commandBehavior; - private Bindings _dbBindings; + private Bindings? _dbBindings; internal bool canceling; private bool _isPrepared; @@ -48,18 +49,18 @@ public OleDbCommand() : base() GC.SuppressFinalize(this); } - public OleDbCommand(string cmdText) : this() + public OleDbCommand(string? cmdText) : this() { CommandText = cmdText; } - public OleDbCommand(string cmdText, OleDbConnection connection) : this() + public OleDbCommand(string? cmdText, OleDbConnection? connection) : this() { CommandText = cmdText; Connection = connection; } - public OleDbCommand(string cmdText, OleDbConnection connection, OleDbTransaction transaction) : this() + public OleDbCommand(string? cmdText, OleDbConnection? connection, OleDbTransaction? transaction) : this() { CommandText = cmdText; Connection = connection; @@ -79,11 +80,11 @@ private OleDbCommand(OleDbCommand from) : this() OleDbParameterCollection parameters = Parameters; foreach (object parameter in from.Parameters) { - parameters.Add((parameter is ICloneable) ? (parameter as ICloneable).Clone() : parameter); + parameters.Add(parameter is ICloneable cloneableParameter ? cloneableParameter.Clone() : parameter); } } - private Bindings ParameterBindings + private Bindings? ParameterBindings { get { @@ -91,7 +92,7 @@ private Bindings ParameterBindings } set { - Bindings bindings = _dbBindings; + Bindings? bindings = _dbBindings; _dbBindings = value; if ((null != bindings) && (value != bindings)) { @@ -102,11 +103,12 @@ private Bindings ParameterBindings [DefaultValue("")] [RefreshProperties(RefreshProperties.All)] + [AllowNull] public override string CommandText { get { - string value = _commandText; + string? value = _commandText; return ((null != value) ? value : string.Empty); } set @@ -174,7 +176,7 @@ public override CommandType CommandType } [DefaultValue(null)] - public new OleDbConnection Connection + public new OleDbConnection? Connection { get { @@ -182,7 +184,7 @@ public override CommandType CommandType } set { - OleDbConnection connection = _connection; + OleDbConnection? connection = _connection; if (value != connection) { PropertyChanging(); @@ -200,7 +202,7 @@ public override CommandType CommandType private void ResetConnection() { - OleDbConnection connection = _connection; + OleDbConnection? connection = _connection; if (null != connection) { PropertyChanging(); @@ -214,7 +216,7 @@ private void ResetConnection() _connection = null; } - protected override DbConnection DbConnection + protected override DbConnection? DbConnection { // V1.2.3300 get { @@ -222,7 +224,7 @@ protected override DbConnection DbConnection } set { - Connection = (OleDbConnection)value; + Connection = (OleDbConnection?)value; } } @@ -234,7 +236,7 @@ protected override DbParameterCollection DbParameterCollection } } - protected override DbTransaction DbTransaction + protected override DbTransaction? DbTransaction { // V1.2.3300 get { @@ -242,7 +244,7 @@ protected override DbTransaction DbTransaction } set { - Transaction = (OleDbTransaction)value; + Transaction = (OleDbTransaction?)value; } } @@ -276,7 +278,7 @@ public override bool DesignTimeVisible { get { - OleDbParameterCollection value = _parameters; + OleDbParameterCollection? value = _parameters; if (null == value) { // delay the creation of the OleDbParameterCollection @@ -290,7 +292,7 @@ public override bool DesignTimeVisible private bool HasParameters() { - OleDbParameterCollection value = _parameters; + OleDbParameterCollection? value = _parameters; return (null != value) && (0 < value.Count); } @@ -298,13 +300,13 @@ private bool HasParameters() Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] - public new OleDbTransaction Transaction + public new OleDbTransaction? Transaction { get { // find the last non-zombied local transaction object, but not transactions // that may have been started after the current local transaction - OleDbTransaction transaction = _transaction; + OleDbTransaction? transaction = _transaction; while ((null != transaction) && (null == transaction.Connection)) { transaction = transaction.Parent; @@ -358,20 +360,20 @@ internal UnsafeNativeMethods.ICommandProperties ICommandProperties() } // optional interface, unsafe cast - private UnsafeNativeMethods.ICommandPrepare ICommandPrepare() + private UnsafeNativeMethods.ICommandPrepare? ICommandPrepare() { Debug.Assert(null != _icommandText, "ICommandPrepare: null ICommandText"); - return (_icommandText as UnsafeNativeMethods.ICommandPrepare); + return _icommandText as UnsafeNativeMethods.ICommandPrepare; } // optional interface, unsafe cast private UnsafeNativeMethods.ICommandWithParameters ICommandWithParameters() { Debug.Assert(null != _icommandText, "ICommandWithParameters: null ICommandText"); - UnsafeNativeMethods.ICommandWithParameters value = (_icommandText as UnsafeNativeMethods.ICommandWithParameters); + UnsafeNativeMethods.ICommandWithParameters? value = (_icommandText as UnsafeNativeMethods.ICommandWithParameters); if (null == value) { - throw ODB.NoProviderSupportForParameters(_connection.Provider, (Exception)null); + throw ODB.NoProviderSupportForParameters(_connection!.Provider, null); } return value; } @@ -385,7 +387,7 @@ private void CreateAccessor() // do this first in-case the command doesn't support parameters UnsafeNativeMethods.ICommandWithParameters commandWithParameters = ICommandWithParameters(); - OleDbParameterCollection collection = _parameters; + OleDbParameterCollection collection = _parameters!; OleDbParameter[] parameters = new OleDbParameter[collection.Count]; collection.CopyTo(parameters, 0); @@ -399,7 +401,7 @@ private void CreateAccessor() bindings.AllocateForAccessor(null, 0, 0); - ApplyParameterBindings(commandWithParameters, bindings.BindInfo); + ApplyParameterBindings(commandWithParameters, bindings.BindInfo!); UnsafeNativeMethods.IAccessor iaccessor = IAccessor(); OleDbHResult hr = bindings.CreateAccessor(iaccessor, ODB.DBACCESSOR_PARAMETERDATA); @@ -454,7 +456,7 @@ public override void Cancel() unchecked { _changeID++; } - UnsafeNativeMethods.ICommandText icmdtxt = _icommandText; + UnsafeNativeMethods.ICommandText? icmdtxt = _icommandText; if (null != icmdtxt) { OleDbHResult hr = OleDbHResult.S_OK; @@ -516,7 +518,7 @@ internal void CloseInternal() // may be called from either // OleDbDataReader.Close/Dispose // via OleDbCommand.Dispose or OleDbConnection.Close - internal void CloseFromDataReader(Bindings bindings) + internal void CloseFromDataReader(Bindings? bindings) { if (null != bindings) { @@ -541,7 +543,7 @@ private void CloseInternalCommand() this.commandBehavior = CommandBehavior.Default; _isPrepared = false; - UnsafeNativeMethods.ICommandText ict = Interlocked.Exchange(ref _icommandText, null); + UnsafeNativeMethods.ICommandText? ict = Interlocked.Exchange(ref _icommandText, null); if (null != ict) { lock (ict) @@ -554,7 +556,7 @@ private void CloseInternalCommand() private void CloseInternalParameters() { Debug.Assert(null != _connection, "no connection, CloseInternalParameters"); - Bindings bindings = _dbBindings; + Bindings? bindings = _dbBindings; _dbBindings = null; if (null != bindings) { @@ -606,7 +608,7 @@ IDataReader IDbCommand.ExecuteReader() public new OleDbDataReader ExecuteReader(CommandBehavior behavior) { _executeQuery = true; - return ExecuteReaderInternal(behavior, ADP.ExecuteReader); + return ExecuteReaderInternal(behavior, ADP.ExecuteReader)!; } IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior) @@ -619,10 +621,10 @@ protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) return ExecuteReader(behavior); } - private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string method) + private OleDbDataReader? ExecuteReaderInternal(CommandBehavior behavior, string method) { - OleDbDataReader dataReader = null; - OleDbException nextResultsFailure = null; + OleDbDataReader? dataReader = null; + OleDbException? nextResultsFailure = null; int state = ODB.InternalStateClosed; try { @@ -634,7 +636,7 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m behavior |= CommandBehavior.SingleResult; } - object executeResult; + object? executeResult; int resultType; switch (CommandType) @@ -657,7 +659,7 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m { try { - dataReader = new OleDbDataReader(_connection, this, 0, this.commandBehavior); + dataReader = new OleDbDataReader(_connection!, this, 0, this.commandBehavior); switch (resultType) { @@ -679,7 +681,7 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m { PrepareCommandText(2); } - OleDbDataReader.GenerateSchemaTable(dataReader, _icommandText, behavior); + OleDbDataReader.GenerateSchemaTable(dataReader, _icommandText!, behavior); break; default: Debug.Assert(false, "ExecuteReaderInternal: unknown result type"); @@ -687,7 +689,7 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m } executeResult = null; _hasDataReader = true; - _connection.AddWeakReference(dataReader, OleDbReferenceCollection.DataReaderTag); + _connection!.AddWeakReference(dataReader, OleDbReferenceCollection.DataReaderTag); // command stays in the executing state until the connection // has a datareader to track for it being closed @@ -713,10 +715,10 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m { if (ODB.ExecutedIMultipleResults == resultType) { - UnsafeNativeMethods.IMultipleResults multipleResults = (UnsafeNativeMethods.IMultipleResults)executeResult; + UnsafeNativeMethods.IMultipleResults? multipleResults = (UnsafeNativeMethods.IMultipleResults?)executeResult; // may cause a Connection.ResetState which closes connection - nextResultsFailure = OleDbDataReader.NextResults(multipleResults, _connection, this, out _recordsAffected); + nextResultsFailure = OleDbDataReader.NextResults(multipleResults, _connection!, this, out _recordsAffected); } } finally @@ -782,7 +784,7 @@ private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string m return dataReader; } - private int ExecuteCommand(CommandBehavior behavior, out object executeResult) + private int ExecuteCommand(CommandBehavior behavior, out object? executeResult) { if (InitializeCommand(behavior, false)) { @@ -802,19 +804,20 @@ private int ExecuteCommand(CommandBehavior behavior, out object executeResult) private int ExecuteCommandText(out object executeResult) { int retcode; - tagDBPARAMS dbParams = null; - RowBinding rowbinding = null; - Bindings bindings = ParameterBindings; + tagDBPARAMS? dbParams = null; + RowBinding? rowbinding = null; + Bindings? bindings = ParameterBindings; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { + // TODO-NULLABLE: Code below seems to assume that bindings will always be non-null if (null != bindings) { // parameters may be suppressed rowbinding = bindings.RowBinding(); - rowbinding.DangerousAddRef(ref mustRelease); + rowbinding!.DangerousAddRef(ref mustRelease); // bindings can't be released until after last rowset is released // that is when output parameters are populated @@ -826,24 +829,24 @@ private int ExecuteCommandText(out object executeResult) dbParams.cParamSets = 1; dbParams.hAccessor = rowbinding.DangerousGetAccessorHandle(); } - if ((0 == (CommandBehavior.SingleResult & this.commandBehavior)) && _connection.SupportMultipleResults()) + if ((0 == (CommandBehavior.SingleResult & this.commandBehavior)) && _connection!.SupportMultipleResults()) { - retcode = ExecuteCommandTextForMultpleResults(dbParams, out executeResult); + retcode = ExecuteCommandTextForMultpleResults(dbParams!, out executeResult); } else if (0 == (CommandBehavior.SingleRow & this.commandBehavior) || !_executeQuery) { - retcode = ExecuteCommandTextForSingleResult(dbParams, out executeResult); + retcode = ExecuteCommandTextForSingleResult(dbParams!, out executeResult); } else { - retcode = ExecuteCommandTextForSingleRow(dbParams, out executeResult); + retcode = ExecuteCommandTextForSingleRow(dbParams!, out executeResult); } } finally { if (mustRelease) { - rowbinding.DangerousRelease(); + rowbinding!.DangerousRelease(); } } return retcode; @@ -853,7 +856,7 @@ private int ExecuteCommandTextForMultpleResults(tagDBPARAMS dbParams, out object { Debug.Assert(0 == (CommandBehavior.SingleRow & this.commandBehavior), "SingleRow implies SingleResult"); OleDbHResult hr; - hr = _icommandText.Execute(ADP.PtrZero, ref ODB.IID_IMultipleResults, dbParams, out _recordsAffected, out executeResult); + hr = _icommandText!.Execute(ADP.PtrZero, ref ODB.IID_IMultipleResults, dbParams, out _recordsAffected, out executeResult); if (OleDbHResult.E_NOINTERFACE != hr) { @@ -871,11 +874,11 @@ private int ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, out object e // (Microsoft.Jet.OLEDB.4.0 returns 0 for recordsAffected instead of -1) if (_executeQuery) { - hr = _icommandText.Execute(ADP.PtrZero, ref ODB.IID_IRowset, dbParams, out _recordsAffected, out executeResult); + hr = _icommandText!.Execute(ADP.PtrZero, ref ODB.IID_IRowset, dbParams, out _recordsAffected, out executeResult); } else { - hr = _icommandText.Execute(ADP.PtrZero, ref ODB.IID_NULL, dbParams, out _recordsAffected, out executeResult); + hr = _icommandText!.Execute(ADP.PtrZero, ref ODB.IID_NULL, dbParams, out _recordsAffected, out executeResult); } ExecuteCommandTextErrorHandling(hr); return ODB.ExecutedIRowset; @@ -885,10 +888,10 @@ private int ExecuteCommandTextForSingleRow(tagDBPARAMS dbParams, out object exec { Debug.Assert(_executeQuery, "ExecuteNonQuery should always use ExecuteCommandTextForSingleResult"); - if (_connection.SupportIRow(this)) + if (_connection!.SupportIRow(this)) { OleDbHResult hr; - hr = _icommandText.Execute(ADP.PtrZero, ref ODB.IID_IRow, dbParams, out _recordsAffected, out executeResult); + hr = _icommandText!.Execute(ADP.PtrZero, ref ODB.IID_IRow, dbParams, out _recordsAffected, out executeResult); if (OleDbHResult.DB_E_NOTFOUND == hr) { @@ -907,7 +910,7 @@ private int ExecuteCommandTextForSingleRow(tagDBPARAMS dbParams, out object exec private void ExecuteCommandTextErrorHandling(OleDbHResult hr) { - Exception e = OleDbConnection.ProcessResults(hr, _connection, this); + Exception? e = OleDbConnection.ProcessResults(hr, _connection, this); if (null != e) { e = ExecuteCommandTextSpecialErrorHandling(hr, e); @@ -927,7 +930,7 @@ private Exception ExecuteCommandTextSpecialErrorHandling(OleDbHResult hr, Except Debug.Assert(null != e, "missing inner exception"); StringBuilder builder = new StringBuilder(); - ParameterBindings.ParameterStatus(builder); + ParameterBindings!.ParameterStatus(builder); e = ODB.CommandParameterStatus(builder.ToString(), e); } return e; @@ -940,11 +943,11 @@ public override int ExecuteNonQuery() return ADP.IntPtrToInt32(_recordsAffected); } - public override object ExecuteScalar() + public override object? ExecuteScalar() { - object value = null; + object? value = null; _executeQuery = true; - using (OleDbDataReader reader = ExecuteReaderInternal(CommandBehavior.Default, ADP.ExecuteScalar)) + using (OleDbDataReader reader = ExecuteReaderInternal(CommandBehavior.Default, ADP.ExecuteScalar)!) { if (reader.Read() && (0 < reader.FieldCount)) { @@ -954,14 +957,14 @@ public override object ExecuteScalar() return value; } - private int ExecuteTableDirect(CommandBehavior behavior, out object executeResult) + private int ExecuteTableDirect(CommandBehavior behavior, out object? executeResult) { this.commandBehavior = behavior; executeResult = null; OleDbHResult hr = OleDbHResult.S_OK; - StringMemHandle sptr = null; + StringMemHandle? sptr = null; bool mustReleaseStringHandle = false; RuntimeHelpers.PrepareConstrainedRegions(); @@ -978,9 +981,9 @@ private int ExecuteTableDirect(CommandBehavior behavior, out object executeResul tableID.eKind = ODB.DBKIND_NAME; tableID.ulPropid = sptr.DangerousGetHandle(); - using (IOpenRowsetWrapper iopenRowset = _connection.IOpenRowset()) + using (IOpenRowsetWrapper iopenRowset = _connection!.IOpenRowset()) { - using (DBPropSet propSet = CommandPropertySets()) + using (DBPropSet? propSet = CommandPropertySets()) { if (null != propSet) { @@ -1016,7 +1019,7 @@ private int ExecuteTableDirect(CommandBehavior behavior, out object executeResul { if (mustReleaseStringHandle) { - sptr.DangerousRelease(); + sptr!.DangerousRelease(); } } ProcessResults(hr); @@ -1118,7 +1121,7 @@ private string ExpandStoredProcedureToText(string sproctext) private void ParameterCleanup() { - Bindings bindings = ParameterBindings; + Bindings? bindings = ParameterBindings; if (null != bindings) { bindings.CleanupBindings(); @@ -1143,7 +1146,7 @@ private bool InitializeCommand(CommandBehavior behavior, bool throwifnotsupporte return false; } - if ((null != _dbBindings) && _dbBindings.AreParameterBindingsInvalid(_parameters)) + if ((null != _dbBindings) && _dbBindings.AreParameterBindingsInvalid(_parameters!)) { CloseInternalParameters(); } @@ -1163,7 +1166,7 @@ private bool InitializeCommand(CommandBehavior behavior, bool throwifnotsupporte string commandText = ExpandCommandText(); - hr = _icommandText.SetCommandText(ref ODB.DBGUID_DEFAULT, commandText); + hr = _icommandText!.SetCommandText(ref ODB.DBGUID_DEFAULT, commandText); if (hr < 0) { @@ -1199,7 +1202,7 @@ public override void Prepare() private void PrepareCommandText(int expectedExecutionCount) { - OleDbParameterCollection parameters = _parameters; + OleDbParameterCollection? parameters = _parameters; if (null != parameters) { foreach (OleDbParameter parameter in parameters) @@ -1213,7 +1216,7 @@ private void PrepareCommandText(int expectedExecutionCount) } } } - UnsafeNativeMethods.ICommandPrepare icommandPrepare = ICommandPrepare(); + UnsafeNativeMethods.ICommandPrepare? icommandPrepare = ICommandPrepare(); if (null != icommandPrepare) { OleDbHResult hr; @@ -1228,19 +1231,19 @@ private void PrepareCommandText(int expectedExecutionCount) private void ProcessResults(OleDbHResult hr) { - Exception e = OleDbConnection.ProcessResults(hr, _connection, this); + Exception? e = OleDbConnection.ProcessResults(hr, _connection, this); if (null != e) { throw e; } } private void ProcessResultsNoReset(OleDbHResult hr) { - Exception e = OleDbConnection.ProcessResults(hr, null, this); + Exception? e = OleDbConnection.ProcessResults(hr, null, this); if (null != e) { throw e; } } - internal object GetPropertyValue(Guid propertySet, int propertyID) + internal object? GetPropertyValue(Guid propertySet, int propertyID) { if (null != _icommandText) { @@ -1272,6 +1275,8 @@ internal object GetPropertyValue(Guid propertySet, int propertyID) private bool PropertiesOnCommand(bool throwNotSupported) { + Debug.Assert(_connection != null); + if (null != _icommandText) { return true; @@ -1279,10 +1284,7 @@ private bool PropertiesOnCommand(bool throwNotSupported) Debug.Assert(!_isPrepared, "null command isPrepared"); OleDbConnection connection = _connection; - if (null == connection) - { - connection.CheckStateOpen(ODB.Properties); - } + connection.CheckStateOpen(ODB.Properties); if (!_trackingForClose) { _trackingForClose = true; @@ -1299,7 +1301,7 @@ private bool PropertiesOnCommand(bool throwNotSupported) return false; } - using (DBPropSet propSet = CommandPropertySets()) + using (DBPropSet? propSet = CommandPropertySets()) { if (null != propSet) { @@ -1315,9 +1317,9 @@ private bool PropertiesOnCommand(bool throwNotSupported) return true; } - private DBPropSet CommandPropertySets() + private DBPropSet? CommandPropertySets() { - DBPropSet propSet = null; + DBPropSet? propSet = null; bool keyInfo = (0 != (CommandBehavior.KeyInfo & this.commandBehavior)); @@ -1351,9 +1353,9 @@ private DBPropSet CommandPropertySets() return propSet; } - internal Bindings TakeBindingOwnerShip() + internal Bindings? TakeBindingOwnerShip() { - Bindings bindings = _dbBindings; + Bindings? bindings = _dbBindings; _dbBindings = null; return bindings; } @@ -1382,7 +1384,7 @@ private void ValidateConnection(string method) private void ValidateConnectionAndTransaction(string method) { ValidateConnection(method); - _transaction = _connection.ValidateTransaction(Transaction, method); + _transaction = _connection!.ValidateTransaction(Transaction, method); this.canceling = false; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommandBuilder.cs b/src/libraries/System.Data.OleDb/src/OleDbCommandBuilder.cs index a421943730c9..7eeabb87487d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommandBuilder.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommandBuilder.cs @@ -15,13 +15,13 @@ public OleDbCommandBuilder() : base() GC.SuppressFinalize(this); } - public OleDbCommandBuilder(OleDbDataAdapter adapter) : this() + public OleDbCommandBuilder(OleDbDataAdapter? adapter) : this() { DataAdapter = adapter; } [DefaultValue(null)] - public new OleDbDataAdapter DataAdapter + public new OleDbDataAdapter? DataAdapter { get { @@ -122,7 +122,7 @@ public static void DeriveParameters(OleDbCommand command) { throw ADP.CommandTextRequired(ADP.DeriveParameters); } - OleDbConnection connection = command.Connection; + OleDbConnection? connection = command.Connection; if (null == connection) { throw ADP.ConnectionRequired(ADP.DeriveParameters); @@ -155,13 +155,13 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect string quotePrefix, quoteSuffix; connection.GetLiteralQuotes(ADP.DeriveParameters, out quotePrefix, out quoteSuffix); - object[] parsed = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quotePrefix, quoteSuffix, '.', 4, true, SR.OLEDB_OLEDBCommandText, false); + object?[] parsed = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quotePrefix, quoteSuffix, '.', 4, true, SR.OLEDB_OLEDBCommandText, false); if (null == parsed[3]) { throw ADP.NoStoredProcedureExists(command.CommandText); } - object[] restrictions = new object[4]; + object?[] restrictions = new object[4]; object value; // Parse returns an enforced 4 part array @@ -182,19 +182,19 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect //if (cmdConnection.IsServer_msdaora) { // restrictions[1] = Convert.ToString(cmdConnection.UserId).ToUpper(); //} - DataTable table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedure_Parameters, restrictions); + DataTable? table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedure_Parameters, restrictions); if (null != table) { DataColumnCollection columns = table.Columns; - DataColumn parameterName = null; - DataColumn parameterDirection = null; - DataColumn dataType = null; - DataColumn maxLen = null; - DataColumn numericPrecision = null; - DataColumn numericScale = null; - DataColumn backendtype = null; + DataColumn? parameterName = null; + DataColumn? parameterDirection = null; + DataColumn? dataType = null; + DataColumn? maxLen = null; + DataColumn? numericPrecision = null; + DataColumn? numericScale = null; + DataColumn? backendtype = null; int index = columns.IndexOf(ODB.PARAMETER_NAME); if (-1 != index) @@ -235,7 +235,7 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect if ((null != parameterName) && !dataRow.IsNull(parameterName, DataRowVersion.Default)) { // $CONSIDER - not trimming the @ from the beginning but to left the designer do that - parameter.ParameterName = Convert.ToString(dataRow[parameterName, DataRowVersion.Default], CultureInfo.InvariantCulture).TrimStart(new char[] { '@', ' ', ':' }); + parameter.ParameterName = Convert.ToString(dataRow[parameterName, DataRowVersion.Default], CultureInfo.InvariantCulture)!.TrimStart(new char[] { '@', ' ', ':' }); } if ((null != parameterDirection) && !dataRow.IsNull(parameterDirection, DataRowVersion.Default)) { @@ -271,7 +271,7 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect case OleDbType.VarBinary: case OleDbType.VarChar: case OleDbType.VarWChar: - value = dataRow[backendtype, DataRowVersion.Default]; + value = dataRow[backendtype!, DataRowVersion.Default]; if (value is string) { string backendtypename = ((string)value).ToLowerInvariant(); @@ -316,8 +316,8 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect } if ((0 == plist.Length) && connection.SupportSchemaRowset(OleDbSchemaGuid.Procedures)) { - restrictions = new object[4] { null, null, command.CommandText, null }; - table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions); + restrictions = new object?[4] { null, null, command.CommandText, null }; + table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions)!; if (0 == table.Rows.Count) { throw ADP.NoStoredProcedureExists(command.CommandText); @@ -326,8 +326,8 @@ private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnect } else if (connection.SupportSchemaRowset(OleDbSchemaGuid.Procedures)) { - object[] restrictions = new object[4] { null, null, command.CommandText, null }; - DataTable table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions); + object?[] restrictions = new object?[4] { null, null, command.CommandText, null }; + DataTable table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions)!; if (0 == table.Rows.Count) { throw ADP.NoStoredProcedureExists(command.CommandText); @@ -356,7 +356,7 @@ public override string QuoteIdentifier(string unquotedIdentifier) { return QuoteIdentifier(unquotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */); } - public string QuoteIdentifier(string unquotedIdentifier, OleDbConnection connection) + public string QuoteIdentifier(string unquotedIdentifier, OleDbConnection? connection) { ADP.CheckArgumentNull(unquotedIdentifier, "unquotedIdentifier"); @@ -406,7 +406,7 @@ public override string UnquoteIdentifier(string quotedIdentifier) return UnquoteIdentifier(quotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */); } - public string UnquoteIdentifier(string quotedIdentifier, OleDbConnection connection) + public string UnquoteIdentifier(string quotedIdentifier, OleDbConnection? connection) { ADP.CheckArgumentNull(quotedIdentifier, "quotedIdentifier"); @@ -435,13 +435,11 @@ public string UnquoteIdentifier(string quotedIdentifier, OleDbConnection connect } } - string unquotedIdentifier; + string? unquotedIdentifier; // ignoring the return value because it is acceptable for the quotedString to not be quoted in this // context. ADP.RemoveStringQuotes(quotePrefix, quoteSuffix, quotedIdentifier, out unquotedIdentifier); - return unquotedIdentifier; - + return unquotedIdentifier!; } - } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index fef98bef3407..06963692ec1d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -25,7 +25,7 @@ public sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConne { private static readonly object EventInfoMessage = new object(); - public OleDbConnection(string connectionString) : this() + public OleDbConnection(string? connectionString) : this() { ConnectionString = connectionString; } @@ -42,6 +42,7 @@ private OleDbConnection(OleDbConnection connection) : this() #pragma warning restore 618 SettingsBindable(true), RefreshProperties(RefreshProperties.All), + AllowNull ] public override string ConnectionString { @@ -55,9 +56,9 @@ public override string ConnectionString } } - private OleDbConnectionString OleDbConnectionStringValue + private OleDbConnectionString? OleDbConnectionStringValue { - get { return (OleDbConnectionString)ConnectionOptions; } + get { return (OleDbConnectionString?)ConnectionOptions; } } [ @@ -67,14 +68,14 @@ public override int ConnectionTimeout { get { - object value = null; + object? value = null; if (IsOpen) { value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_TIMEOUT); } else { - OleDbConnectionString constr = this.OleDbConnectionStringValue; + OleDbConnectionString? constr = this.OleDbConnectionStringValue; value = (null != constr) ? constr.ConnectTimeout : ADP.DefaultConnectionTimeout; } if (null != value) @@ -93,8 +94,8 @@ public override string Database { get { - OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions; - object value = (null != constr) ? constr.InitialCatalog : string.Empty; + OleDbConnectionString? constr = (OleDbConnectionString?)UserConnectionOptions; + object? value = (null != constr) ? constr.InitialCatalog : string.Empty; if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) { OleDbConnectionInternal connection = GetOpenConnection(); @@ -115,7 +116,7 @@ public override string Database value = (null != constr) ? constr.InitialCatalog : string.Empty; } } - return Convert.ToString(value, CultureInfo.InvariantCulture); + return Convert.ToString(value, CultureInfo.InvariantCulture)!; } } @@ -126,14 +127,14 @@ public override string DataSource { get { - OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions; - object value = (null != constr) ? constr.DataSource : string.Empty; + OleDbConnectionString? constr = (OleDbConnectionString?)UserConnectionOptions; + object? value = (null != constr) ? constr.DataSource : string.Empty; if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) { if (IsOpen) { value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_DATASOURCE); - if ((null == value) || ((value is string) && (0 == (value as string).Length))) + if ((null == value) || ((value is string) && (0 == (value as string)!.Length))) { value = GetDataSourceValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DATASOURCENAME); } @@ -144,7 +145,7 @@ public override string DataSource value = (null != constr) ? constr.DataSource : string.Empty; } } - return Convert.ToString(value, CultureInfo.InvariantCulture); + return Convert.ToString(value, CultureInfo.InvariantCulture)!; } } @@ -153,7 +154,7 @@ internal bool IsOpen get { return (null != GetOpenConnection()); } } - internal OleDbTransaction LocalTransaction + internal OleDbTransaction? LocalTransaction { set { @@ -174,8 +175,8 @@ public string Provider { get { - OleDbConnectionString constr = this.OleDbConnectionStringValue; - string value = ((null != constr) ? constr.ConvertValueToString(ODB.Provider, null) : null); + OleDbConnectionString? constr = this.OleDbConnectionStringValue; + string? value = ((null != constr) ? constr.ConvertValueToString(ODB.Provider, null) : null); return ((null != value) ? value : string.Empty); } } @@ -184,7 +185,8 @@ internal OleDbConnectionPoolGroupProviderInfo ProviderInfo { get { - return (OleDbConnectionPoolGroupProviderInfo)PoolGroup.ProviderInfo; + Debug.Assert(null != this.PoolGroup, "PoolGroup must never be null when accessing ProviderInfo"); + return (OleDbConnectionPoolGroupProviderInfo)PoolGroup!.ProviderInfo!; } } @@ -214,7 +216,7 @@ public void ResetState() { if (IsOpen) { - object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_CONNECTIONSTATUS); + object? value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_CONNECTIONSTATUS); if (value is int) { int connectionStatus = (int)value; @@ -238,7 +240,7 @@ public void ResetState() } } - public event OleDbInfoMessageEventHandler InfoMessage + public event OleDbInfoMessageEventHandler? InfoMessage { add { @@ -250,7 +252,7 @@ public event OleDbInfoMessageEventHandler InfoMessage } } - internal UnsafeNativeMethods.ICommandText ICommandText() + internal UnsafeNativeMethods.ICommandText? ICommandText() { Debug.Assert(null != GetOpenConnection(), "ICommandText closed"); return GetOpenConnection().ICommandText(); @@ -291,7 +293,7 @@ internal int QuotedIdentifierCase() Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString QuotedIdentifierCase"); int quotedIdentifierCase; - object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_QUOTEDIDENTIFIERCASE); + object? value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_QUOTEDIDENTIFIERCASE); if (value is int) {// not OleDbPropertyStatus quotedIdentifierCase = (int)value; @@ -379,15 +381,15 @@ protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLeve return transaction; } - internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) + internal object? GetDataSourcePropertyValue(Guid propertySet, int propertyID) { OleDbConnectionInternal connection = GetOpenConnection(); return connection.GetDataSourcePropertyValue(propertySet, propertyID); } - internal object GetDataSourceValue(Guid propertySet, int propertyID) + internal object? GetDataSourceValue(Guid propertySet, int propertyID) { - object value = GetDataSourcePropertyValue(propertySet, propertyID); + object? value = GetDataSourcePropertyValue(propertySet, propertyID); if ((value is OleDbPropertyStatus) || Convert.IsDBNull(value)) { value = null; @@ -398,7 +400,7 @@ internal object GetDataSourceValue(Guid propertySet, int propertyID) private OleDbConnectionInternal GetOpenConnection() { DbConnectionInternal innerConnection = InnerConnection; - return (innerConnection as OleDbConnectionInternal); + return (innerConnection as OleDbConnectionInternal)!; } internal void GetLiteralQuotes(string method, out string quotePrefix, out string quoteSuffix) @@ -407,27 +409,19 @@ internal void GetLiteralQuotes(string method, out string quotePrefix, out string OleDbConnectionPoolGroupProviderInfo info = ProviderInfo; if (info.HasQuoteFix) { - quotePrefix = info.QuotePrefix; - quoteSuffix = info.QuoteSuffix; + quotePrefix = info.QuotePrefix!; + quoteSuffix = info.QuoteSuffix!; } else { OleDbConnectionInternal connection = GetOpenConnection(); - quotePrefix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_PREFIX); - quoteSuffix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_SUFFIX); - if (null == quotePrefix) - { - quotePrefix = ""; - } - if (null == quoteSuffix) - { - quoteSuffix = quotePrefix; - } + quotePrefix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_PREFIX) ?? ""; + quoteSuffix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_SUFFIX) ?? ""; info.SetQuoteFix(quotePrefix, quoteSuffix); } } - public DataTable GetOleDbSchemaTable(Guid schema, object[] restrictions) + public DataTable? GetOleDbSchemaTable(Guid schema, object?[]? restrictions) { CheckStateOpen(ADP.GetOleDbSchemaTable); OleDbConnectionInternal connection = GetOpenConnection(); @@ -474,7 +468,7 @@ public DataTable GetOleDbSchemaTable(Guid schema, object[] restrictions) } } - internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) + internal DataTable? GetSchemaRowset(Guid schema, object?[] restrictions) { Debug.Assert(null != GetOpenConnection(), "GetSchemaRowset closed"); return GetOpenConnection().GetSchemaRowset(schema, restrictions); @@ -494,7 +488,7 @@ internal bool HasLiveReader(OleDbCommand cmd) internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) { - OleDbInfoMessageEventHandler handler = (OleDbInfoMessageEventHandler)Events[EventInfoMessage]; + OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; if (null != handler) { try @@ -522,7 +516,7 @@ public override void Open() // need to manually enlist in some cases, because // native OLE DB doesn't know about SysTx transactions. - if ((0 != (ODB.DBPROPVAL_OS_TXNENLISTMENT & ((OleDbConnectionString)(this.ConnectionOptions)).OleDbServices)) + if ((0 != (ODB.DBPROPVAL_OS_TXNENLISTMENT & ((OleDbConnectionString)(this.ConnectionOptions!)).OleDbServices)) && ADP.NeedManualEnlistment()) { GetOpenConnection().EnlistTransactionInternal(SysTx.Transaction.Current); @@ -541,7 +535,7 @@ internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, strin if (hr < 0) { - Exception e = OleDbConnection.ProcessResults(hr, null, this); + Exception? e = OleDbConnection.ProcessResults(hr, null, this); if (OleDbHResult.DB_E_ERRORSOCCURRED == hr) { StringBuilder builder = new StringBuilder(); @@ -552,7 +546,7 @@ internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, strin ODB.PropsetSetFailure(builder, description, dbprops[0].dwStatus); - e = ODB.PropsetSetFailure(builder.ToString(), e); + e = ODB.PropsetSetFailure(builder.ToString(), e!); } if (null != e) { @@ -572,12 +566,12 @@ internal bool SupportSchemaRowset(Guid schema) return GetOpenConnection().SupportSchemaRowset(schema); } - internal OleDbTransaction ValidateTransaction(OleDbTransaction transaction, string method) + internal OleDbTransaction? ValidateTransaction(OleDbTransaction? transaction, string method) { return GetOpenConnection().ValidateTransaction(transaction, method); } - internal static Exception ProcessResults(OleDbHResult hresult, OleDbConnection connection, object src) + internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) { if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) { @@ -586,8 +580,8 @@ internal static Exception ProcessResults(OleDbHResult hresult, OleDbConnection c } // ErrorInfo object is to be checked regardless the hresult returned by the function called - Exception e = null; - UnsafeNativeMethods.IErrorInfo errorInfo = null; + Exception? e = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) { @@ -643,7 +637,7 @@ public static void ReleaseObjectPool() OleDbConnectionFactory.SingletonInstance.ClearAllPools(); } - private static void ResetState(OleDbConnection connection) + private static void ResetState(OleDbConnection? connection) { if (null != connection) { diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs index a6ab9fda124e..9b1a7cd36642 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs @@ -31,13 +31,14 @@ public override DbProviderFactory ProviderFactory } } - protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) + protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningObject) { - DbConnectionInternal result = new OleDbConnectionInternal((OleDbConnectionString)options, (OleDbConnection)owningObject); + // TODO-NULLABLE: owningObject may actually be null (see DbConnectionPool.CreateObject), in which case this will throw... + DbConnectionInternal result = new OleDbConnectionInternal((OleDbConnectionString)options, (OleDbConnection)owningObject!); return result; } - protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous) + protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions? previous) { Debug.Assert(!ADP.IsEmpty(connectionString), "null connectionString"); OleDbConnectionString result = new OleDbConnectionString(connectionString, (null != previous)); @@ -50,17 +51,17 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal cacheMetaDataFactory = false; OleDbConnectionInternal oleDbInternalConnection = (OleDbConnectionInternal)internalConnection; - OleDbConnection oleDbOuterConnection = oleDbInternalConnection.Connection; + OleDbConnection? oleDbOuterConnection = oleDbInternalConnection.Connection; Debug.Assert(oleDbOuterConnection != null, "outer connection may not be null."); NameValueCollection settings = (NameValueCollection)ConfigurationManager.GetSection("system.data.oledb"); - Stream XMLStream = null; - string providerFileName = oleDbOuterConnection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_PROVIDERFILENAME) as string; + Stream? XMLStream = null; + string? providerFileName = oleDbOuterConnection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_PROVIDERFILENAME) as string; if (settings != null) { - string[] values = null; - string metaDataXML = null; + string[]? values = null; + string? metaDataXML = null; // first try to get the provider specific xml // if providerfilename is not supported we can't build the settings key needed to @@ -81,7 +82,7 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal // If there is new XML get it if (values != null) { - XMLStream = ADP.GetXmlStreamFromValues(values, metaDataXML); + XMLStream = ADP.GetXmlStreamFromValues(values, metaDataXML!); } } @@ -103,7 +104,7 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal oleDbInternalConnection.GetSchemaRowsetInformation()); } - protected override DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) + protected override DbConnectionPoolGroupOptions? CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) { return null; } @@ -113,9 +114,9 @@ internal override DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupPro return new OleDbConnectionPoolGroupProviderInfo(); } - internal override DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection) + internal override DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnection connection) { - OleDbConnection c = (connection as OleDbConnection); + OleDbConnection? c = (connection as OleDbConnection); if (null != c) { return c.PoolGroup; @@ -125,7 +126,7 @@ internal override DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection conn internal override void PermissionDemand(DbConnection outerConnection) { - OleDbConnection c = (outerConnection as OleDbConnection); + OleDbConnection? c = (outerConnection as OleDbConnection); if (null != c) { c.PermissionDemand(); @@ -134,7 +135,7 @@ internal override void PermissionDemand(DbConnection outerConnection) internal override void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup) { - OleDbConnection c = (outerConnection as OleDbConnection); + OleDbConnection? c = (outerConnection as OleDbConnection); if (null != c) { c.PoolGroup = poolGroup; @@ -143,7 +144,7 @@ internal override void SetConnectionPoolGroup(DbConnection outerConnection, DbCo internal override void SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to) { - OleDbConnection c = (owningObject as OleDbConnection); + OleDbConnection? c = (owningObject as OleDbConnection); if (null != c) { c.SetInnerConnectionEvent(to); @@ -152,7 +153,7 @@ internal override void SetInnerConnectionEvent(DbConnection owningObject, DbConn internal override bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from) { - OleDbConnection c = (owningObject as OleDbConnection); + OleDbConnection? c = (owningObject as OleDbConnection); if (null != c) { return c.SetInnerConnectionFrom(to, from); @@ -162,7 +163,7 @@ internal override bool SetInnerConnectionFrom(DbConnection owningObject, DbConne internal override void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to) { - OleDbConnection c = (owningObject as OleDbConnection); + OleDbConnection? c = (owningObject as OleDbConnection); if (null != c) { c.SetInnerConnectionTo(to); diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs index e4d1e5022383..09ab6982105b 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs @@ -15,7 +15,7 @@ namespace System.Data.OleDb internal sealed class OleDbConnectionInternal : DbConnectionInternal, IDisposable { - private static volatile OleDbServicesWrapper idataInitialize; + private static volatile OleDbServicesWrapper? idataInitialize; private static readonly object dataInitializeLock = new object(); internal readonly OleDbConnectionString ConnectionString; // parsed connection string attributes @@ -50,18 +50,18 @@ internal sealed class OleDbConnectionInternal : DbConnectionInternal, IDisposabl // offered much better performance. // the "Data Source object". - private readonly DataSourceWrapper _datasrcwrp; + private readonly DataSourceWrapper? _datasrcwrp; // the "Session object". - private readonly SessionWrapper _sessionwrp; + private readonly SessionWrapper? _sessionwrp; - private WeakReference weakTransaction; + private WeakReference? weakTransaction; // When set to true the current connection is enlisted in a transaction that must be // un-enlisted during Deactivate. private bool _unEnlistDuringDeactivate; - internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection connection) : base() + internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection? connection) : base() { Debug.Assert((null != constr) && !constr.IsEmpty, "empty connectionstring"); ConnectionString = constr; @@ -100,7 +100,7 @@ internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection c } else { - Exception e = OleDbConnection.ProcessResults(hr, null, null); + Exception? e = OleDbConnection.ProcessResults(hr, null, null); Debug.Assert(null != e, "CreateSessionError"); throw e; } @@ -123,11 +123,11 @@ internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection c } } - internal OleDbConnection Connection + internal OleDbConnection? Connection { get { - return (OleDbConnection)Owner; + return (OleDbConnection?)Owner; } } @@ -139,14 +139,14 @@ internal bool HasSession } } - internal OleDbTransaction LocalTransaction + internal OleDbTransaction? LocalTransaction { get { - OleDbTransaction result = null; + OleDbTransaction? result = null; if (null != weakTransaction) { - result = ((OleDbTransaction)weakTransaction.Target); + result = ((OleDbTransaction?)weakTransaction.Target); } return result; } @@ -171,8 +171,8 @@ public override string ServerVersion // consider making a method, not a property get { - object value = GetDataSourceValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DBMSVER); - return Convert.ToString(value, CultureInfo.InvariantCulture); + object value = GetDataSourceValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DBMSVER)!; + return Convert.ToString(value, CultureInfo.InvariantCulture)!; } } @@ -218,12 +218,12 @@ internal ITransactionJoinWrapper ITransactionJoin() } // optional interface, unsafe cast - internal UnsafeNativeMethods.ICommandText ICommandText() + internal UnsafeNativeMethods.ICommandText? ICommandText() { Debug.Assert(null != _datasrcwrp, "IDBCreateCommand: null datasource"); Debug.Assert(null != _sessionwrp, "IDBCreateCommand: null session"); - object icommandText = null; + object? icommandText = null; OleDbHResult hr = _sessionwrp.CreateCommand(ref icommandText); Debug.Assert((0 <= hr) || (null == icommandText), "CreateICommandText: error with ICommandText"); @@ -238,23 +238,23 @@ internal UnsafeNativeMethods.ICommandText ICommandText() SafeNativeMethods.Wrapper.ClearErrorInfo(); } } - return (UnsafeNativeMethods.ICommandText)icommandText; + return (UnsafeNativeMethods.ICommandText?)icommandText; } - protected override void Activate(SysTx.Transaction transaction) + protected override void Activate(SysTx.Transaction? transaction) { throw ADP.NotSupported(); } public override DbTransaction BeginTransaction(IsolationLevel isolationLevel) { - OleDbConnection outerConnection = Connection; + OleDbConnection outerConnection = Connection!; if (null != LocalTransaction) { throw ADP.ParallelTransactionsNotSupported(outerConnection); } - object unknown = null; + object? unknown = null; OleDbTransaction transaction; try { @@ -262,10 +262,10 @@ public override DbTransaction BeginTransaction(IsolationLevel isolationLevel) Debug.Assert(null != _datasrcwrp, "ITransactionLocal: null datasource"); Debug.Assert(null != _sessionwrp, "ITransactionLocal: null session"); unknown = _sessionwrp.ComWrapper(); - UnsafeNativeMethods.ITransactionLocal value = (unknown as UnsafeNativeMethods.ITransactionLocal); + UnsafeNativeMethods.ITransactionLocal? value = (unknown as UnsafeNativeMethods.ITransactionLocal); if (null == value) { - throw ODB.TransactionsNotSupported(Provider, (Exception)null); + throw ODB.TransactionsNotSupported(Provider, null); } transaction.BeginInternal(value); } @@ -294,7 +294,7 @@ protected override void Deactivate() // Un-enlist transaction as OLEDB connection pool is unaware of managed transactions. EnlistTransactionInternal(null); } - OleDbTransaction transaction = LocalTransaction; + OleDbTransaction? transaction = LocalTransaction; if (null != transaction) { LocalTransaction = null; @@ -318,7 +318,7 @@ public override void Dispose() base.Dispose(); } - public override void EnlistTransaction(SysTx.Transaction transaction) + public override void EnlistTransaction(SysTx.Transaction? transaction) { if (null != LocalTransaction) { @@ -327,15 +327,15 @@ public override void EnlistTransaction(SysTx.Transaction transaction) EnlistTransactionInternal(transaction); } - internal void EnlistTransactionInternal(SysTx.Transaction transaction) + internal void EnlistTransactionInternal(SysTx.Transaction? transaction) { - SysTx.IDtcTransaction oleTxTransaction = ADP.GetOletxTransaction(transaction); + SysTx.IDtcTransaction? oleTxTransaction = ADP.GetOletxTransaction(transaction); using (ITransactionJoinWrapper transactionJoin = ITransactionJoin()) { if (null == transactionJoin.Value) { - throw ODB.TransactionsNotSupported(Provider, (Exception)null); + throw ODB.TransactionsNotSupported(Provider, null); } transactionJoin.Value.JoinTransaction(oleTxTransaction, (int)IsolationLevel.Unspecified, 0, IntPtr.Zero); _unEnlistDuringDeactivate = (null != transaction); @@ -343,9 +343,9 @@ internal void EnlistTransactionInternal(SysTx.Transaction transaction) EnlistedTransaction = transaction; } - internal object GetDataSourceValue(Guid propertySet, int propertyID) + internal object? GetDataSourceValue(Guid propertySet, int propertyID) { - object value = GetDataSourcePropertyValue(propertySet, propertyID); + object? value = GetDataSourcePropertyValue(propertySet, propertyID); if ((value is OleDbPropertyStatus) || Convert.IsDBNull(value)) { value = null; @@ -353,7 +353,7 @@ internal object GetDataSourceValue(Guid propertySet, int propertyID) return value; } - internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) + internal object? GetDataSourcePropertyValue(Guid propertySet, int propertyID) { OleDbHResult hr; ItagDBPROP[] dbprops; @@ -380,11 +380,12 @@ internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) return dbprops[0].dwStatus; } - internal DataTable BuildInfoLiterals() + internal DataTable? BuildInfoLiterals() { using (IDBInfoWrapper wrapper = IDBInfo()) { UnsafeNativeMethods.IDBInfo dbInfo = wrapper.Value; + // TODO-NULLABLE: check may not be necessary (and thus method may return non-nullable) if (null == dbInfo) { return null; @@ -445,9 +446,9 @@ internal DataTable BuildInfoLiterals() } } - internal DataTable BuildInfoKeywords() + internal DataTable? BuildInfoKeywords() { - DataTable table = new DataTable(ODB.DbInfoKeywords); + DataTable? table = new DataTable(ODB.DbInfoKeywords); table.Locale = CultureInfo.InvariantCulture; DataColumn keyword = new DataColumn(ODB.Keyword, typeof(string)); table.Columns.Add(keyword); @@ -506,7 +507,7 @@ internal DataTable BuildSchemaGuids() table.Columns.Add(schemaGuid); table.Columns.Add(restrictionSupport); - SchemaSupport[] supportedSchemas = GetSchemaRowsetInformation(); + SchemaSupport[]? supportedSchemas = GetSchemaRowsetInformation(); if (null != supportedSchemas) { @@ -523,7 +524,7 @@ internal DataTable BuildSchemaGuids() return table; } - internal string GetLiteralInfo(int literal) + internal string? GetLiteralInfo(int literal) { using (IDBInfoWrapper wrapper = IDBInfo()) { @@ -532,7 +533,7 @@ internal string GetLiteralInfo(int literal) { return null; } - string literalValue = null; + string? literalValue = null; IntPtr literalInfo = ADP.PtrZero; int literalCount = 0; OleDbHResult hr; @@ -560,17 +561,17 @@ internal string GetLiteralInfo(int literal) } } - internal SchemaSupport[] GetSchemaRowsetInformation() + internal SchemaSupport[]? GetSchemaRowsetInformation() { OleDbConnectionString constr = ConnectionString; - SchemaSupport[] supportedSchemas = constr.SchemaSupport; + SchemaSupport[]? supportedSchemas = constr.SchemaSupport; if (null != supportedSchemas) { return supportedSchemas; } using (IDBSchemaRowsetWrapper wrapper = IDBSchemaRowset()) { - UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset = wrapper.Value; + UnsafeNativeMethods.IDBSchemaRowset? dbSchemaRowset = wrapper.Value; if (null == dbSchemaRowset) { return null; // IDBSchemaRowset not supported @@ -595,7 +596,7 @@ internal SchemaSupport[] GetSchemaRowsetInformation() for (int i = 0, offset = 0; i < supportedSchemas.Length; ++i, offset += ODB.SizeOf_Guid) { IntPtr ptr = ADP.IntPtrOffset(schemaGuids, i * ODB.SizeOf_Guid); - supportedSchemas[i]._schemaRowset = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid)); + supportedSchemas[i]._schemaRowset = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid))!; } } if (ADP.PtrZero != schemaRestrictions) @@ -611,13 +612,13 @@ internal SchemaSupport[] GetSchemaRowsetInformation() } } - internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) + internal DataTable? GetSchemaRowset(Guid schema, object?[]? restrictions) { if (null == restrictions) { restrictions = Array.Empty(); } - DataTable dataTable = null; + DataTable? dataTable = null; using (IDBSchemaRowsetWrapper wrapper = IDBSchemaRowset()) { UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset = wrapper.Value; @@ -626,7 +627,7 @@ internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) throw ODB.SchemaRowsetsNotSupported(Provider); } - UnsafeNativeMethods.IRowset rowset = null; + UnsafeNativeMethods.IRowset? rowset = null; OleDbHResult hr; hr = dbSchemaRowset.GetRowset(ADP.PtrZero, ref schema, restrictions.Length, restrictions, ref ODB.IID_IRowset, 0, ADP.PtrZero, out rowset); @@ -656,7 +657,7 @@ internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) // returns true if there is an active data reader on the specified command internal bool HasLiveReader(OleDbCommand cmd) { - OleDbDataReader reader = null; + OleDbDataReader? reader = null; if (null != ReferenceCollection) { @@ -668,15 +669,15 @@ internal bool HasLiveReader(OleDbCommand cmd) private void ProcessResults(OleDbHResult hr) { - OleDbConnection connection = Connection; // get value from weakref only once - Exception e = OleDbConnection.ProcessResults(hr, connection, connection); + OleDbConnection? connection = Connection; // get value from weakref only once + Exception? e = OleDbConnection.ProcessResults(hr, connection, connection); if (null != e) { throw e; } } internal bool SupportSchemaRowset(Guid schema) { - SchemaSupport[] schemaSupport = GetSchemaRowsetInformation(); + SchemaSupport[]? schemaSupport = GetSchemaRowsetInformation(); if (null != schemaSupport) { for (int i = 0; i < schemaSupport.Length; ++i) @@ -692,8 +693,8 @@ internal bool SupportSchemaRowset(Guid schema) private static object CreateInstanceDataLinks() { - Type datalink = Type.GetTypeFromCLSID(ODB.CLSID_DataLinks, true); - return Activator.CreateInstance(datalink, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null); + Type datalink = Type.GetTypeFromCLSID(ODB.CLSID_DataLinks, true)!; + return Activator.CreateInstance(datalink, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null)!; } // @devnote: should be multithread safe access to OleDbConnection.idataInitialize, @@ -701,7 +702,7 @@ private static object CreateInstanceDataLinks() // OLE DB will ensure I'll work with just the single pool private static OleDbServicesWrapper GetObjectPool() { - OleDbServicesWrapper wrapper = OleDbConnectionInternal.idataInitialize; + OleDbServicesWrapper? wrapper = OleDbConnectionInternal.idataInitialize; if (null == wrapper) { lock (dataInitializeLock) @@ -764,11 +765,11 @@ public static void ReleaseObjectPool() OleDbConnectionInternal.idataInitialize = null; } - internal OleDbTransaction ValidateTransaction(OleDbTransaction transaction, string method) + internal OleDbTransaction? ValidateTransaction(OleDbTransaction? transaction, string method) { if (null != this.weakTransaction) { - OleDbTransaction head = (OleDbTransaction)this.weakTransaction.Target; + OleDbTransaction? head = (OleDbTransaction?)this.weakTransaction.Target; if ((null != head) && this.weakTransaction.IsAlive) { head = OleDbTransaction.TransactionUpdate(head); @@ -817,9 +818,9 @@ internal OleDbTransaction ValidateTransaction(OleDbTransaction transaction, stri return null; } - internal Dictionary GetPropertyInfo(Guid[] propertySets) + internal Dictionary? GetPropertyInfo(Guid[] propertySets) { - Dictionary properties = null; + Dictionary? properties = null; if (null == propertySets) { diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionPoolGroupProviderInfo.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionPoolGroupProviderInfo.cs index fc472aa109d0..594f0db3f6a0 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionPoolGroupProviderInfo.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionPoolGroupProviderInfo.cs @@ -8,7 +8,7 @@ namespace System.Data.OleDb internal sealed class OleDbConnectionPoolGroupProviderInfo : DbConnectionPoolGroupProviderInfo { private bool _hasQuoteFix; - private string _quotePrefix, _quoteSuffix; + private string? _quotePrefix, _quoteSuffix; internal OleDbConnectionPoolGroupProviderInfo() { @@ -18,11 +18,11 @@ internal bool HasQuoteFix { get { return _hasQuoteFix; } } - internal string QuotePrefix + internal string? QuotePrefix { get { return _quotePrefix; } } - internal string QuoteSuffix + internal string? QuoteSuffix { get { return _quoteSuffix; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionString.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionString.cs index 665421f8ba40..7f3946291684 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionString.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionString.cs @@ -50,7 +50,7 @@ private static class UDL internal static volatile bool _PoolSizeInit; internal static int _PoolSize; - internal static volatile Dictionary _Pool; + internal static volatile Dictionary? _Pool; internal static object _PoolLock = new object(); } @@ -61,11 +61,11 @@ private static class VALUES // set during ctor internal readonly bool PossiblePrompt; - internal readonly string ActualConnectionString; // cached value passed to GetDataSource + internal readonly string? ActualConnectionString; // cached value passed to GetDataSource - private readonly string _expandedConnectionString; + private readonly string? _expandedConnectionString; - internal SchemaSupport[] _schemaSupport; + internal SchemaSupport[]? _schemaSupport; internal int _sqlSupport; internal bool _supportMultipleResults; @@ -76,10 +76,10 @@ private static class VALUES private int _oledbServices; // these are cached delegates (per unique connectionstring) - internal UnsafeNativeMethods.IUnknownQueryInterface DangerousDataSourceIUnknownQueryInterface; - internal UnsafeNativeMethods.IDBInitializeInitialize DangerousIDBInitializeInitialize; - internal UnsafeNativeMethods.IDBCreateSessionCreateSession DangerousIDBCreateSessionCreateSession; - internal UnsafeNativeMethods.IDBCreateCommandCreateCommand DangerousIDBCreateCommandCreateCommand; + internal UnsafeNativeMethods.IUnknownQueryInterface? DangerousDataSourceIUnknownQueryInterface; + internal UnsafeNativeMethods.IDBInitializeInitialize? DangerousIDBInitializeInitialize; + internal UnsafeNativeMethods.IDBCreateSessionCreateSession? DangerousIDBCreateSessionCreateSession; + internal UnsafeNativeMethods.IDBCreateCommandCreateCommand? DangerousIDBCreateCommandCreateCommand; // since IDBCreateCommand interface may not be supported for a particular provider (only IOpenRowset) // we cache that fact rather than call QueryInterface on every call to Open @@ -89,17 +89,17 @@ private static class VALUES // from the UDL file. The UDL file is opened as FileMode.Open, FileAccess.Read, FileShare.Read, allowing concurrent access to it. internal OleDbConnectionString(string connectionString, bool validate) : base(connectionString) { - string prompt = this[KEY.Prompt]; + string? prompt = this[KEY.Prompt]; PossiblePrompt = ((!ADP.IsEmpty(prompt) && (0 != string.Compare(prompt, VALUES.NoPrompt, StringComparison.OrdinalIgnoreCase))) || !ADP.IsEmpty(this[KEY.WindowHandle])); if (!IsEmpty) { - string udlConnectionString = null; + string? udlConnectionString = null; if (!validate) { int position = 0; - string udlFileName = null; + string? udlFileName = null; _expandedConnectionString = ExpandDataDirectories(ref udlFileName, ref position); if (!ADP.IsEmpty(udlFileName)) @@ -112,7 +112,7 @@ internal OleDbConnectionString(string connectionString, bool validate) : base(co if (!ADP.IsEmpty(udlConnectionString)) { - _expandedConnectionString = _expandedConnectionString.Substring(0, position) + udlConnectionString + ';' + _expandedConnectionString.Substring(position); + _expandedConnectionString = _expandedConnectionString!.Substring(0, position) + udlConnectionString + ';' + _expandedConnectionString.Substring(position); } } } @@ -130,12 +130,12 @@ internal int ConnectTimeout internal string DataSource { - get { return base.ConvertValueToString(KEY.Data_Source, string.Empty); } + get { return base.ConvertValueToString(KEY.Data_Source, string.Empty)!; } } internal string InitialCatalog { - get { return base.ConvertValueToString(KEY.Initial_Catalog, string.Empty); } + get { return base.ConvertValueToString(KEY.Initial_Catalog, string.Empty)!; } } internal string Provider @@ -143,7 +143,7 @@ internal string Provider get { Debug.Assert(!ADP.IsEmpty(this[KEY.Provider]), "no Provider"); - return this[KEY.Provider]; + return this[KEY.Provider]!; } } @@ -155,7 +155,7 @@ internal int OleDbServices } } - internal SchemaSupport[] SchemaSupport + internal SchemaSupport[]? SchemaSupport { // OleDbConnection.GetSchemaRowsetInformation get { return _schemaSupport; } set { _schemaSupport = value; } @@ -178,7 +178,7 @@ internal int GetSqlSupport(OleDbConnection connection) int sqlSupport = _sqlSupport; if (!_hasSqlSupport) { - object value = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_SQLSUPPORT); + object? value = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_SQLSUPPORT); if (value is int) { // not OleDbPropertyStatus sqlSupport = (int)value; @@ -194,7 +194,7 @@ internal bool GetSupportIRow(OleDbConnection connection, OleDbCommand command) bool supportIRow = _supportIRow; if (!_hasSupportIRow) { - object value = command.GetPropertyValue(OleDbPropertySetGuid.Rowset, ODB.DBPROP_IRow); + object? value = command.GetPropertyValue(OleDbPropertySetGuid.Rowset, ODB.DBPROP_IRow); // SQLOLEDB always returns VARIANT_FALSE for DBPROP_IROW, so base the answer on existance supportIRow = !(value is OleDbPropertyStatus); @@ -209,7 +209,7 @@ internal bool GetSupportMultipleResults(OleDbConnection connection) bool supportMultipleResults = _supportMultipleResults; if (!_hasSupportMultipleResults) { - object value = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_MULTIPLERESULTS); + object? value = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_MULTIPLERESULTS); if (value is int) {// not OleDbPropertyStatus supportMultipleResults = (ODB.DBPROPVAL_MR_NOTSUPPORTED != (int)value); @@ -228,7 +228,7 @@ private static int UdlPoolSize int poolsize = UDL._PoolSize; if (!UDL._PoolSizeInit) { - object value = ADP.LocalMachineRegistryValue(UDL.Location, UDL.Pooling); + object? value = ADP.LocalMachineRegistryValue(UDL.Location, UDL.Pooling); if (value is int) { poolsize = (int)value; @@ -241,10 +241,10 @@ private static int UdlPoolSize } } - private static string LoadStringFromStorage(string udlfilename) + private static string? LoadStringFromStorage(string udlfilename) { - string udlConnectionString = null; - Dictionary udlcache = UDL._Pool; + string? udlConnectionString = null; + Dictionary? udlcache = UDL._Pool; if ((null == udlcache) || !udlcache.TryGetValue(udlfilename, out udlConnectionString)) { @@ -295,8 +295,8 @@ private static string LoadStringFromFileStorage(string udlfilename) // [oledb] // ; Everything after this line is an OLE DB initstring // - string connectionString = null; - Exception failure = null; + string? connectionString = null; + Exception? failure = null; try { int hdrlength = ADP.CharSize * UDL.Header.Length; @@ -342,7 +342,7 @@ private static string LoadStringFromFileStorage(string udlfilename) { throw failure; } - return connectionString.Trim(); + return connectionString!.Trim(); } private string ValidateConnectionString(string connectionString) @@ -358,7 +358,7 @@ private string ValidateConnectionString(string connectionString) throw ADP.InvalidConnectTimeoutValue(); } - string progid = ConvertValueToString(KEY.Data_Provider, null); + string? progid = ConvertValueToString(KEY.Data_Provider, null); if (null != progid) { progid = progid.Trim(); @@ -376,7 +376,7 @@ private string ValidateConnectionString(string connectionString) ValidateProvider(progid); } } - progid = ConvertValueToString(KEY.Provider, string.Empty).Trim(); + progid = ConvertValueToString(KEY.Provider, string.Empty)!.Trim(); ValidateProvider(progid); // will fail on empty 'Provider' value // initialize to default @@ -385,10 +385,10 @@ private string ValidateConnectionString(string connectionString) // our default is -13, we turn off ODB.DBPROPVAL_OS_AGR_AFTERSESSION and ODB.DBPROPVAL_OS_CLIENTCURSOR flags _oledbServices = DbConnectionStringDefaults.OleDbServices; - bool hasOleDBServices = (base.ContainsKey(KEY.Ole_DB_Services) && !ADP.IsEmpty((string)base[KEY.Ole_DB_Services])); + bool hasOleDBServices = (base.ContainsKey(KEY.Ole_DB_Services) && !ADP.IsEmpty((string?)base[KEY.Ole_DB_Services])); if (!hasOleDBServices) { // don't touch registry if they have OLE DB Services - string classid = (string)ADP.ClassesRootRegistryValue(progid + "\\CLSID", string.Empty); + string? classid = (string?)ADP.ClassesRootRegistryValue(progid + "\\CLSID", string.Empty); if ((null != classid) && (0 < classid.Length)) { // CLSID detection of 'Microsoft OLE DB Provider for ODBC Drivers' @@ -397,7 +397,7 @@ private string ValidateConnectionString(string connectionString) { throw ODB.MSDASQLNotSupported(); } - object tmp = ADP.ClassesRootRegistryValue("CLSID\\{" + classidProvider.ToString("D", CultureInfo.InvariantCulture) + "}", ODB.OLEDB_SERVICES); + object? tmp = ADP.ClassesRootRegistryValue("CLSID\\{" + classidProvider.ToString("D", CultureInfo.InvariantCulture) + "}", ODB.OLEDB_SERVICES); if (null != tmp) { // @devnote: some providers like MSDataShape don't have the OLEDB_SERVICES value diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs index 0ffb80427fc5..91e07a35389d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; @@ -41,8 +42,8 @@ private enum Keywords { DbConnectionStringKeywords.OleDbServices, Keywords.OleDbServices }, }; - private string[] _knownKeywords; - private Dictionary _propertyInfo; + private string[]? _knownKeywords; + private Dictionary? _propertyInfo; private string _fileName = DbConnectionStringDefaults.FileName; @@ -58,7 +59,7 @@ public OleDbConnectionStringBuilder() : this(null) _knownKeywords = s_validKeywords; } - public OleDbConnectionStringBuilder(string connectionString) : base() + public OleDbConnectionStringBuilder(string? connectionString) : base() { if (!ADP.IsEmpty(connectionString)) { @@ -66,12 +67,13 @@ public OleDbConnectionStringBuilder(string connectionString) : base() } } + [AllowNull] public override object this[string keyword] { get { ADP.CheckArgumentNull(keyword, "keyword"); - object value; + object? value; Keywords index; if (s_keywords.TryGetValue(keyword, out index)) { @@ -81,7 +83,7 @@ public override object this[string keyword] { Dictionary dynamic = GetProviderInfo(Provider); OleDbPropertyInfo info = dynamic[keyword]; - value = info._defaultValue; + value = info._defaultValue!; } return value; } @@ -199,7 +201,7 @@ public override ICollection Keys { get { - string[] knownKeywords = _knownKeywords; + string[]? knownKeywords = _knownKeywords; if (null == knownKeywords) { Dictionary dynamic = GetProviderInfo(Provider); @@ -369,11 +371,11 @@ private void RestartProvider() private void SetValue(string keyword, bool value) { - base[keyword] = value.ToString((System.IFormatProvider)null); + base[keyword] = value.ToString(null); } private void SetValue(string keyword, int value) { - base[keyword] = value.ToString((System.IFormatProvider)null); + base[keyword] = value.ToString((System.IFormatProvider?)null); } private void SetValue(string keyword, string value) { @@ -381,7 +383,7 @@ private void SetValue(string keyword, string value) base[keyword] = value; } - public override bool TryGetValue(string keyword, out object value) + public override bool TryGetValue(string keyword, [NotNullWhen(true)] out object? value) { ADP.CheckArgumentNull(keyword, "keyword"); Keywords index; @@ -393,10 +395,10 @@ public override bool TryGetValue(string keyword, out object value) else if (!base.TryGetValue(keyword, out value)) { Dictionary dynamic = GetProviderInfo(Provider); - OleDbPropertyInfo info; + OleDbPropertyInfo? info; if (dynamic.TryGetValue(keyword, out info)) { - value = info._defaultValue; + value = info._defaultValue!; return true; } return false; @@ -406,13 +408,13 @@ public override bool TryGetValue(string keyword, out object value) private Dictionary GetProviderInfo(string provider) { - Dictionary providerInfo = _propertyInfo; + Dictionary? providerInfo = _propertyInfo; if (null == providerInfo) { providerInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); if (!ADP.IsEmpty(provider)) { - Dictionary hash = null; + Dictionary? hash = null; try { StringBuilder builder = new StringBuilder(); @@ -420,15 +422,15 @@ private Dictionary GetProviderInfo(string provider) OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true); // load provider without calling Initialize or CreateDataSource - using (OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, (OleDbConnection)null)) + using (OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, null)) { // get all the init property information for the provider - hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll }); + hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll })!; foreach (KeyValuePair entry in hash) { Keywords index; OleDbPropertyInfo info = entry.Value; - if (!s_keywords.TryGetValue(info._description, out index)) + if (!s_keywords.TryGetValue(info._description!, out index)) { if ((OleDbPropertySetGuid.DBInit == info._propertySet) && ((ODB.DBPROP_INIT_ASYNCH == info._propertyID) || @@ -437,7 +439,7 @@ private Dictionary GetProviderInfo(string provider) { continue; // skip this keyword } - providerInfo[info._description] = info; + providerInfo[info._description!] = info; } } @@ -529,7 +531,7 @@ private sealed class OleDbProviderConverter : StringConverter private const int DBSOURCETYPE_DATASOURCE_TDP = 1; private const int DBSOURCETYPE_DATASOURCE_MDP = 3; - private StandardValuesCollection _standardValues; + private StandardValuesCollection? _standardValues; // converter classes should have public ctor public OleDbProviderConverter() @@ -546,16 +548,16 @@ public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) return false; } - public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext context) { - StandardValuesCollection dataSourceNames = _standardValues; + StandardValuesCollection? dataSourceNames = _standardValues; if (null == _standardValues) { // Get the sources rowset for the SQLOLEDB enumerator DataTable table = (new OleDbEnumerator()).GetElements(); - DataColumn column2 = table.Columns["SOURCES_NAME"]; - DataColumn column5 = table.Columns["SOURCES_TYPE"]; + DataColumn column2 = table.Columns["SOURCES_NAME"]!; + DataColumn column5 = table.Columns["SOURCES_TYPE"]!; //DataColumn column4 = table.Columns["SOURCES_DESCRIPTION"]; System.Collections.Generic.List providerNames = new System.Collections.Generic.List(table.Rows.Count); @@ -597,7 +599,7 @@ internal enum OleDbServiceValues : int internal sealed class OleDbServicesConverter : TypeConverter { - private StandardValuesCollection _standardValues; + private StandardValuesCollection? _standardValues; // converter classes should have public ctor public OleDbServicesConverter() : base() @@ -612,7 +614,7 @@ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceT public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { - string svalue = (value as string); + string? svalue = (value as string); if (null != svalue) { int services; @@ -631,7 +633,6 @@ public override object ConvertFrom(ITypeDescriptorContext context, System.Global convertedValue |= (int)(OleDbServiceValues)Enum.Parse(typeof(OleDbServiceValues), v, true); } return (int)convertedValue; - ; } else { @@ -669,7 +670,7 @@ public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { - StandardValuesCollection standardValues = _standardValues; + StandardValuesCollection? standardValues = _standardValues; if (null == standardValues) { Array objValues = Enum.GetValues(typeof(OleDbServiceValues)); @@ -711,7 +712,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) { - OleDbConnectionStringBuilder obj = (value as OleDbConnectionStringBuilder); + OleDbConnectionStringBuilder? obj = (value as OleDbConnectionStringBuilder); if (null != obj) { return ConvertToInstanceDescriptor(obj); @@ -724,7 +725,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI { Type[] ctorParams = new Type[] { typeof(string) }; object[] ctorValues = new object[] { options.ConnectionString }; - System.Reflection.ConstructorInfo ctor = typeof(OleDbConnectionStringBuilder).GetConstructor(ctorParams); + System.Reflection.ConstructorInfo ctor = typeof(OleDbConnectionStringBuilder).GetConstructor(ctorParams)!; return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 6b772f1a30fb..05714cef63f9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -13,25 +13,25 @@ public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable private static readonly object EventRowUpdated = new object(); private static readonly object EventRowUpdating = new object(); - private OleDbCommand _deleteCommand, _insertCommand, _selectCommand, _updateCommand; + private OleDbCommand? _deleteCommand, _insertCommand, _selectCommand, _updateCommand; public OleDbDataAdapter() : base() { GC.SuppressFinalize(this); } - public OleDbDataAdapter(OleDbCommand selectCommand) : this() + public OleDbDataAdapter(OleDbCommand? selectCommand) : this() { SelectCommand = selectCommand; } - public OleDbDataAdapter(string selectCommandText, string selectConnectionString) : this() + public OleDbDataAdapter(string? selectCommandText, string? selectConnectionString) : this() { OleDbConnection connection = new OleDbConnection(selectConnectionString); SelectCommand = new OleDbCommand(selectCommandText, connection); } - public OleDbDataAdapter(string selectCommandText, OleDbConnection selectConnection) : this() + public OleDbDataAdapter(string? selectCommandText, OleDbConnection? selectConnection) : this() { SelectCommand = new OleDbCommand(selectCommandText, selectConnection); } @@ -44,80 +44,80 @@ private OleDbDataAdapter(OleDbDataAdapter from) : base(from) [ DefaultValue(null), ] - public new OleDbCommand DeleteCommand + public new OleDbCommand? DeleteCommand { get { return _deleteCommand; } set { _deleteCommand = value; } } - IDbCommand IDbDataAdapter.DeleteCommand + IDbCommand? IDbDataAdapter.DeleteCommand { get { return _deleteCommand; } - set { _deleteCommand = (OleDbCommand)value; } + set { _deleteCommand = (OleDbCommand?)value; } } [ DefaultValue(null) ] - public new OleDbCommand InsertCommand + public new OleDbCommand? InsertCommand { get { return _insertCommand; } set { _insertCommand = value; } } - IDbCommand IDbDataAdapter.InsertCommand + IDbCommand? IDbDataAdapter.InsertCommand { get { return _insertCommand; } - set { _insertCommand = (OleDbCommand)value; } + set { _insertCommand = (OleDbCommand?)value; } } [ DefaultValue(null) ] - public new OleDbCommand SelectCommand + public new OleDbCommand? SelectCommand { get { return _selectCommand; } set { _selectCommand = value; } } - IDbCommand IDbDataAdapter.SelectCommand + IDbCommand? IDbDataAdapter.SelectCommand { get { return _selectCommand; } - set { _selectCommand = (OleDbCommand)value; } + set { _selectCommand = (OleDbCommand?)value; } } [ DefaultValue(null) ] - public new OleDbCommand UpdateCommand + public new OleDbCommand? UpdateCommand { get { return _updateCommand; } set { _updateCommand = value; } } - IDbCommand IDbDataAdapter.UpdateCommand + IDbCommand? IDbDataAdapter.UpdateCommand { get { return _updateCommand; } - set { _updateCommand = (OleDbCommand)value; } + set { _updateCommand = (OleDbCommand?)value; } } - public event OleDbRowUpdatedEventHandler RowUpdated + public event OleDbRowUpdatedEventHandler? RowUpdated { add { Events.AddHandler(EventRowUpdated, value); } remove { Events.RemoveHandler(EventRowUpdated, value); } } - public event OleDbRowUpdatingEventHandler RowUpdating + public event OleDbRowUpdatingEventHandler? RowUpdating { add { - OleDbRowUpdatingEventHandler handler = (OleDbRowUpdatingEventHandler)Events[EventRowUpdating]; + OleDbRowUpdatingEventHandler? handler = (OleDbRowUpdatingEventHandler?)Events[EventRowUpdating]; // prevent someone from registering two different command builders on the adapter by // silently removing the old one if ((null != handler) && (value.Target is DbCommandBuilder)) { - OleDbRowUpdatingEventHandler d = (OleDbRowUpdatingEventHandler)ADP.FindBuilder(handler); + OleDbRowUpdatingEventHandler? d = (OleDbRowUpdatingEventHandler?)ADP.FindBuilder(handler); if (null != d) { Events.RemoveHandler(EventRowUpdating, d); @@ -133,12 +133,12 @@ object ICloneable.Clone() return new OleDbDataAdapter(this); } - protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new OleDbRowUpdatedEventArgs(dataRow, command, statementType, tableMapping); } - protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) { return new OleDbRowUpdatingEventArgs(dataRow, command, statementType, tableMapping); } @@ -179,7 +179,7 @@ public int Fill(DataSet dataSet, object ADODBRecordSet, string srcTable) return FillFromADODB((object)dataSet, ADODBRecordSet, srcTable, true); } - private int FillFromADODB(object data, object adodb, string srcTable, bool multipleResults) + private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) { Debug.Assert(null != data, "FillFromADODB: null data object"); Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); @@ -200,8 +200,8 @@ private int FillFromADODB(object data, object adodb, string srcTable, bool multi */ bool closeRecordset = multipleResults; - UnsafeNativeMethods.ADORecordsetConstruction recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); - UnsafeNativeMethods.ADORecordConstruction record = null; + UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); + UnsafeNativeMethods.ADORecordConstruction? record = null; if (null != recordset) { @@ -237,10 +237,10 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction); do { - string tmp = null; + string? tmp = null; if (data is DataSet) { - tmp = GetSourceTableName(srcTable, resultCount); + tmp = GetSourceTableName(srcTable!, resultCount); } results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); @@ -257,7 +257,7 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction); // Current provider does not support returning multiple recordsets from a single execution. if (ODB.ADODB_NextResultError != (int)hr) { - UnsafeNativeMethods.IErrorInfo errorInfo = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); string message = string.Empty; @@ -287,7 +287,7 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction); } else if (null != record) { - results = FillFromRecord(data, record, srcTable); + results = FillFromRecord(data, record, srcTable!); if (closeRecordset) { FillClose(false, record); @@ -304,12 +304,12 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction); // return base.Fill(dataTable, dataReader); //} - private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConstruction recordset, string srcTable, out bool incrementResultCount) + private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConstruction recordset, string? srcTable, out bool incrementResultCount) { incrementResultCount = false; IntPtr chapter; /*ODB.DB_NULL_HCHAPTER*/ - object result = null; + object? result = null; try { result = recordset.get_Rowset(); @@ -331,7 +331,7 @@ private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConst CommandBehavior behavior = (MissingSchemaAction.AddWithKey != MissingSchemaAction) ? 0 : CommandBehavior.KeyInfo; behavior |= CommandBehavior.SequentialAccess; - OleDbDataReader dataReader = null; + OleDbDataReader? dataReader = null; try { // intialized with chapter only since we don't want ReleaseChapter called for this chapter handle @@ -350,7 +350,7 @@ private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConst } else { - return base.Fill((DataSet)data, srcTable, dataReader, 0, 0); + return base.Fill((DataSet)data, srcTable!, dataReader, 0, 0); } } } @@ -367,7 +367,7 @@ private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConst private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstruction record, string srcTable) { - object result = null; + object? result = null; try { result = record.get_Row(); @@ -388,7 +388,7 @@ private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstructio CommandBehavior behavior = (MissingSchemaAction.AddWithKey != MissingSchemaAction) ? 0 : CommandBehavior.KeyInfo; behavior |= CommandBehavior.SequentialAccess | CommandBehavior.SingleRow; - OleDbDataReader dataReader = null; + OleDbDataReader? dataReader = null; try { dataReader = new OleDbDataReader(null, null, 0, behavior); @@ -428,7 +428,7 @@ private void FillClose(bool isrecordset, object value) } if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) { - UnsafeNativeMethods.IErrorInfo errorInfo = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); string message = string.Empty; throw new COMException(message, (int)hr); @@ -437,7 +437,7 @@ private void FillClose(bool isrecordset, object value) protected override void OnRowUpdated(RowUpdatedEventArgs value) { - OleDbRowUpdatedEventHandler handler = (OleDbRowUpdatedEventHandler)Events[EventRowUpdated]; + OleDbRowUpdatedEventHandler? handler = (OleDbRowUpdatedEventHandler?)Events[EventRowUpdated]; if ((null != handler) && (value is OleDbRowUpdatedEventArgs)) { handler(this, (OleDbRowUpdatedEventArgs)value); @@ -447,7 +447,7 @@ protected override void OnRowUpdated(RowUpdatedEventArgs value) protected override void OnRowUpdating(RowUpdatingEventArgs value) { - OleDbRowUpdatingEventHandler handler = (OleDbRowUpdatingEventHandler)Events[EventRowUpdating]; + OleDbRowUpdatingEventHandler? handler = (OleDbRowUpdatingEventHandler?)Events[EventRowUpdating]; if ((null != handler) && (value is OleDbRowUpdatingEventArgs)) { handler(this, (OleDbRowUpdatingEventArgs)value); diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs index 5560f3f0e956..cf0a8ef67023 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs @@ -18,17 +18,17 @@ public sealed class OleDbDataReader : DbDataReader private readonly CommandBehavior _commandBehavior; // object model interaction - private OleDbConnection _connection; - private OleDbCommand _command; + private OleDbConnection? _connection; + private OleDbCommand? _command; // DataReader owns the parameter bindings until CloseDataReader // this allows OleDbCommand.Dispose to not require OleDbDataReader.Dispose - private Bindings _parameterBindings; + private Bindings? _parameterBindings; // OLEDB interfaces - private UnsafeNativeMethods.IMultipleResults _imultipleResults; - private UnsafeNativeMethods.IRowset _irowset; - private UnsafeNativeMethods.IRow _irow; + private UnsafeNativeMethods.IMultipleResults? _imultipleResults; + private UnsafeNativeMethods.IRowset? _irowset; + private UnsafeNativeMethods.IRow? _irow; private ChapterHandle _chapterHandle = ChapterHandle.DB_NULL_HCHAPTER; @@ -38,7 +38,7 @@ public sealed class OleDbDataReader : DbDataReader private long _sequentialBytesRead; private int _sequentialOrdinal; - private Bindings[] _bindings; // _metdata contains the ColumnBinding + private Bindings?[]? _bindings; // _metdata contains the ColumnBinding // do we need to jump to the next accessor private int _nextAccessorForRetrieval; @@ -55,20 +55,20 @@ public sealed class OleDbDataReader : DbDataReader // cached information for Reading (rowhandles/status) private IntPtr _rowHandleFetchCount; // (>1 fails against jet) - private RowHandleBuffer _rowHandleNativeBuffer; + private RowHandleBuffer? _rowHandleNativeBuffer; private IntPtr _rowFetchedCount; private int _currentRow; - private DataTable _dbSchemaTable; + private DataTable? _dbSchemaTable; private int _visibleFieldCount; - private MetaData[] _metadata; - private FieldNameLookup _fieldNameLookup; + private MetaData[]? _metadata; + private FieldNameLookup? _fieldNameLookup; // ctor for an ICommandText, IMultipleResults, IRowset, IRow // ctor for an ADODB.Recordset, ADODB.Record or Hierarchial resultset - internal OleDbDataReader(OleDbConnection connection, OleDbCommand command, int depth, CommandBehavior commandBehavior) + internal OleDbDataReader(OleDbConnection? connection, OleDbCommand? command, int depth, CommandBehavior commandBehavior) { _connection = connection; _command = command; @@ -92,12 +92,12 @@ private void Initialize() } } - internal void InitializeIMultipleResults(object result) + internal void InitializeIMultipleResults(object? result) { Initialize(); - _imultipleResults = (UnsafeNativeMethods.IMultipleResults)result; // maybe null if no results + _imultipleResults = (UnsafeNativeMethods.IMultipleResults?)result; // maybe null if no results } - internal void InitializeIRowset(object result, ChapterHandle chapterHandle, IntPtr recordsAffected) + internal void InitializeIRowset(object? result, ChapterHandle chapterHandle, IntPtr recordsAffected) { // if from ADODB, connection will be null if ((null == _connection) || (ChapterHandle.DB_NULL_HCHAPTER != chapterHandle)) @@ -107,21 +107,21 @@ internal void InitializeIRowset(object result, ChapterHandle chapterHandle, IntP Initialize(); _recordsAffected = recordsAffected; - _irowset = (UnsafeNativeMethods.IRowset)result; // maybe null if no results + _irowset = (UnsafeNativeMethods.IRowset?)result; // maybe null if no results _chapterHandle = chapterHandle; } - internal void InitializeIRow(object result, IntPtr recordsAffected) + internal void InitializeIRow(object? result, IntPtr recordsAffected) { Initialize(); Debug.Assert(_singleRow, "SingleRow not already set"); _singleRow = true; _recordsAffected = recordsAffected; - _irow = (UnsafeNativeMethods.IRow)result; // maybe null if no results + _irow = (UnsafeNativeMethods.IRow?)result; // maybe null if no results _hasRows = (null != _irow); } - internal OleDbCommand Command + internal OleDbCommand? Command { get { @@ -149,7 +149,7 @@ public override int FieldCount { throw ADP.DataReaderClosed("FieldCount"); } - MetaData[] metadata = MetaData; + MetaData[]? metadata = MetaData; return ((null != metadata) ? metadata.Length : 0); } } @@ -178,7 +178,7 @@ public override bool IsClosed } } - private MetaData[] MetaData + private MetaData[]? MetaData { get { return _metadata; } } @@ -232,7 +232,7 @@ private UnsafeNativeMethods.IRowsetInfo IRowsetInfo() private UnsafeNativeMethods.IRowset IRowset() { - UnsafeNativeMethods.IRowset irowset = _irowset; + UnsafeNativeMethods.IRowset? irowset = _irowset; if (null == irowset) { Debug.Assert(false, "object is disposed"); @@ -243,7 +243,7 @@ private UnsafeNativeMethods.IRowset IRowset() private UnsafeNativeMethods.IRow IRow() { - UnsafeNativeMethods.IRow irow = _irow; + UnsafeNativeMethods.IRow? irow = _irow; if (null == irow) { Debug.Assert(false, "object is disposed"); @@ -254,10 +254,10 @@ private UnsafeNativeMethods.IRow IRow() public override DataTable GetSchemaTable() { - DataTable schemaTable = _dbSchemaTable; + DataTable? schemaTable = _dbSchemaTable; if (null == schemaTable) { - MetaData[] metadata = MetaData; + MetaData[]? metadata = MetaData; if ((null != metadata) && (0 < metadata.Length)) { if ((0 < metadata.Length) && _useIColumnsRowset && (null != _connection)) @@ -273,7 +273,10 @@ public override DataTable GetSchemaTable() //GetSchemaTable() is defined to return null after NextResult returns false //throw ADP.DataReaderNoData(); } +// TODO-NULLABLE: Behavior change (https://github.com/dotnet/runtime/issues/509) +#nullable disable return schemaTable; +#nullable enable } internal void BuildMetaInfo() @@ -451,7 +454,7 @@ private void BuildSchemaTableInfo(object handle, bool filterITypeInfo, bool filt Debug.Assert(null == _dbSchemaTable, "non-null SchemaTable"); Debug.Assert(null == _metadata, "non-null metadata"); Debug.Assert(null != handle, "unexpected null rowset"); - UnsafeNativeMethods.IColumnsInfo icolumnsInfo = (handle as UnsafeNativeMethods.IColumnsInfo); + UnsafeNativeMethods.IColumnsInfo? icolumnsInfo = (handle as UnsafeNativeMethods.IColumnsInfo); if (null == icolumnsInfo) { _dbSchemaTable = null; @@ -606,11 +609,11 @@ private void BuildSchemaTableRowset(object handle) { Debug.Assert(null == _dbSchemaTable, "BuildSchemaTableRowset - non-null SchemaTable"); Debug.Assert(null != handle, "BuildSchemaTableRowset(object) - unexpected null handle"); - UnsafeNativeMethods.IColumnsRowset icolumnsRowset = (handle as UnsafeNativeMethods.IColumnsRowset); + UnsafeNativeMethods.IColumnsRowset? icolumnsRowset = (handle as UnsafeNativeMethods.IColumnsRowset); if (null != icolumnsRowset) { - UnsafeNativeMethods.IRowset rowset = null; + UnsafeNativeMethods.IRowset? rowset = null; IntPtr cOptColumns; OleDbHResult hr; @@ -643,11 +646,11 @@ private void BuildSchemaTableRowset(object handle) public override void Close() { - OleDbConnection con = _connection; - OleDbCommand cmd = _command; - Bindings bindings = _parameterBindings; - _connection = null; - _command = null; + OleDbConnection? con = _connection; + OleDbCommand? cmd = _command; + Bindings? bindings = _parameterBindings; + _connection = null!; + _command = null!; _parameterBindings = null; _isClosed = true; @@ -667,7 +670,7 @@ public override void Close() } else { - UnsafeNativeMethods.IMultipleResults multipleResults = _imultipleResults; + UnsafeNativeMethods.IMultipleResults? multipleResults = _imultipleResults; _imultipleResults = null; if (null != multipleResults) @@ -682,7 +685,7 @@ public override void Close() if ((null != cmd) && !cmd.canceling) { IntPtr affected = IntPtr.Zero; - OleDbException nextResultsFailure = NextResults(multipleResults, null, cmd, out affected); + OleDbException? nextResultsFailure = NextResults(multipleResults, null, cmd, out affected); _recordsAffected = AddRecordsAffected(_recordsAffected, affected); if (null != nextResultsFailure) { @@ -718,7 +721,7 @@ public override void Close() } // release unmanaged objects - RowHandleBuffer rowHandleNativeBuffer = _rowHandleNativeBuffer; + RowHandleBuffer? rowHandleNativeBuffer = _rowHandleNativeBuffer; _rowHandleNativeBuffer = null; if (null != rowHandleNativeBuffer) { @@ -738,7 +741,7 @@ internal void CloseReaderFromConnection(bool canceling) // called from the connection which will remove this from its ReferenceCollection // we want the NextResult behavior, but no errors - _connection = null; + _connection = null!; Close(); } @@ -754,16 +757,16 @@ private void DisposeManagedRowset() _nextAccessorForRetrieval = 0; _nextValueForRetrieval = 0; - Bindings[] bindings = _bindings; + Bindings?[]? bindings = _bindings; _bindings = null; if (null != bindings) { for (int i = 0; i < bindings.Length; ++i) { - if (null != bindings[i]) + if (bindings[i] is Bindings binding) { - bindings[i].Dispose(); + binding.Dispose(); } } } @@ -779,7 +782,7 @@ private void DisposeManagedRowset() private void DisposeNativeMultipleResults() { - UnsafeNativeMethods.IMultipleResults imultipleResults = _imultipleResults; + UnsafeNativeMethods.IMultipleResults? imultipleResults = _imultipleResults; _imultipleResults = null; if (null != imultipleResults) @@ -790,7 +793,7 @@ private void DisposeNativeMultipleResults() private void DisposeNativeRowset() { - UnsafeNativeMethods.IRowset irowset = _irowset; + UnsafeNativeMethods.IRowset? irowset = _irowset; _irowset = null; ChapterHandle chapter = _chapterHandle; @@ -809,7 +812,7 @@ private void DisposeNativeRowset() private void DisposeNativeRow() { - UnsafeNativeMethods.IRow irow = _irow; + UnsafeNativeMethods.IRow? irow = _irow; _irow = null; if (null != irow) @@ -860,7 +863,7 @@ private ColumnBinding DoSequentialCheck(int ordinal, long dataIndex, string meth return binding; } - public override long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length) + public override long GetBytes(int ordinal, long dataIndex, byte[]? buffer, int bufferIndex, int length) { ColumnBinding binding = DoSequentialCheck(ordinal, dataIndex, ADP.GetBytes); byte[] value = binding.ValueByteArray(); @@ -896,7 +899,7 @@ public override long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bu return byteCount; } - public override long GetChars(int ordinal, long dataIndex, char[] buffer, int bufferIndex, int length) + public override long GetChars(int ordinal, long dataIndex, char[]? buffer, int bufferIndex, int length) { ColumnBinding binding = DoSequentialCheck(ordinal, dataIndex, ADP.GetChars); string value = binding.ValueString(); @@ -951,21 +954,22 @@ protected override DbDataReader GetDbDataReader(int ordinal) return GetData(ordinal); } - internal OleDbDataReader ResetChapter(int bindingIndex, int index, RowBinding rowbinding, int valueOffset) + internal OleDbDataReader? ResetChapter(int bindingIndex, int index, RowBinding rowbinding, int valueOffset) { - return GetDataForReader(_metadata[bindingIndex + index].ordinal, rowbinding, valueOffset); + return GetDataForReader(_metadata![bindingIndex + index].ordinal, rowbinding, valueOffset); } - private OleDbDataReader GetDataForReader(IntPtr ordinal, RowBinding rowbinding, int valueOffset) + private OleDbDataReader? GetDataForReader(IntPtr ordinal, RowBinding rowbinding, int valueOffset) { UnsafeNativeMethods.IRowsetInfo rowsetInfo = IRowsetInfo(); - UnsafeNativeMethods.IRowset result; + UnsafeNativeMethods.IRowset? result; OleDbHResult hr; hr = rowsetInfo.GetReferencedRowset((IntPtr)ordinal, ref ODB.IID_IRowset, out result); ProcessResults(hr); - OleDbDataReader reader = null; + OleDbDataReader? reader = null; + // TODO: Not sure if GetReferenceRowset above actually returns null, calling code seems to assume it doesn't if (null != result) { // only when the first datareader is closed will the connection close @@ -1021,7 +1025,8 @@ public override Type GetFieldType(int index) { if (null != _metadata) { - return _metadata[index].type.dataType; + // TODO-NULLABLE: Should throw if null (empty), though it probably doesn't happen + return _metadata[index].type.dataType!; } throw ADP.DataReaderNoData(); } @@ -1102,7 +1107,7 @@ private MetaData DoValueCheck(int ordinal) throw ADP.NonSequentialColumnAccess(ordinal, _nextValueForRetrieval); } // @usernote: user may encounter the IndexOutOfRangeException - MetaData info = _metadata[ordinal]; + MetaData info = _metadata![ordinal]; return info; } @@ -1127,7 +1132,7 @@ private ColumnBinding GetValueBinding(MetaData info) { if (_nextValueForRetrieval != binding.Index) { // release old value - _metadata[_nextValueForRetrieval].columnBinding.ResetValue(); + _metadata![_nextValueForRetrieval].columnBinding.ResetValue(); } _nextAccessorForRetrieval = binding.IndexForAccessor; } @@ -1166,7 +1171,7 @@ public override int GetValues(object[] values) } DoValueCheck(0); int count = Math.Min(values.Length, _visibleFieldCount); - for (int i = 0; (i < _metadata.Length) && (i < count); ++i) + for (int i = 0; (i < _metadata!.Length) && (i < count); ++i) { ColumnBinding binding = GetValueBinding(_metadata[i]); values[i] = binding.Value(); @@ -1187,7 +1192,7 @@ public override bool IsDBNull(int ordinal) private void ProcessResults(OleDbHResult hr) { - Exception e; + Exception? e; if (null != _command) { e = OleDbConnection.ProcessResults(hr, _connection, _command); @@ -1249,10 +1254,10 @@ internal void HasRowsRead() _isRead = false; } - internal static OleDbException NextResults(UnsafeNativeMethods.IMultipleResults imultipleResults, OleDbConnection connection, OleDbCommand command, out IntPtr recordsAffected) + internal static OleDbException? NextResults(UnsafeNativeMethods.IMultipleResults? imultipleResults, OleDbConnection? connection, OleDbCommand command, out IntPtr recordsAffected) { recordsAffected = ADP.RecordsUnaffected; - List exceptions = null; + List? exceptions = null; if (null != imultipleResults) { object result; @@ -1278,10 +1283,10 @@ internal static OleDbException NextResults(UnsafeNativeMethods.IMultipleResults } if (null != connection) { - Exception e = OleDbConnection.ProcessResults(hr, connection, command); + Exception? e = OleDbConnection.ProcessResults(hr, connection, command); if (null != e) { - OleDbException excep = (e as OleDbException); + OleDbException? excep = (e as OleDbException); if (null != excep) { if (null == exceptions) @@ -1337,8 +1342,8 @@ public override bool NextResult() } _fieldNameLookup = null; - OleDbCommand command = _command; - UnsafeNativeMethods.IMultipleResults imultipleResults = _imultipleResults; + OleDbCommand? command = _command; + UnsafeNativeMethods.IMultipleResults? imultipleResults = _imultipleResults; if (null != imultipleResults) { DisposeOpenResults(); @@ -1349,7 +1354,7 @@ public override bool NextResult() Debug.Assert(null == _irow, "NextResult: row loop check"); Debug.Assert(null == _irowset, "NextResult: rowset loop check"); - object result = null; + object? result = null; OleDbHResult hr; IntPtr affected; @@ -1394,7 +1399,7 @@ public override bool NextResult() public override bool Read() { bool retflag = false; - OleDbCommand command = _command; + OleDbCommand? command = _command; if ((null != command) && command.canceling) { DisposeOpenResults(); @@ -1439,7 +1444,7 @@ private bool ReadRow() else { _isRead = true; - return (0 < _metadata.Length); + return (0 < _metadata!.Length); } return false; } @@ -1447,7 +1452,7 @@ private bool ReadRow() private bool ReadRowset() { Debug.Assert(null != _irowset, "ReadRow: null IRowset"); - Debug.Assert(0 <= _metadata.Length, "incorrect state for fieldCount"); + Debug.Assert(0 <= _metadata!.Length, "incorrect state for fieldCount"); // releases bindings as necessary // bumps current row, else resets it back to initial state @@ -1477,11 +1482,11 @@ private void ReleaseCurrentRow() if (0 < (int)_rowFetchedCount) { // release the data in the current row - Bindings[] bindings = _bindings; + Bindings?[]? bindings = _bindings; Debug.Assert(null != bindings, "ReleaseCurrentRow: null dbBindings"); for (int i = 0; (i < bindings.Length) && (i < _nextAccessorForRetrieval); ++i) { - bindings[i].CleanupBindings(); + bindings[i]!.CleanupBindings(); } _nextAccessorForRetrieval = 0; _nextValueForRetrieval = 0; @@ -1516,7 +1521,7 @@ private void CreateAccessors(bool allowMultipleAccessor) { _rowHandleFetchCount = new IntPtr(1); - object maxRows = GetPropertyValue(ODB.DBPROP_MAXROWS); + object? maxRows = GetPropertyValue(ODB.DBPROP_MAXROWS); if (maxRows is int) { _rowHandleFetchCount = new IntPtr((int)maxRows); @@ -1545,7 +1550,7 @@ private Bindings[] CreateBindingsFromMetaData(bool allowMultipleAccessor) int bindingCount = 0; int currentBindingIndex = 0; - MetaData[] metadata = _metadata; + MetaData[] metadata = _metadata!; int[] indexToBinding = new int[metadata.Length]; int[] indexWithinBinding = new int[metadata.Length]; @@ -1723,7 +1728,7 @@ private void GetRowHandles(/*int skipCount*/) OleDbHResult hr = 0; - RowHandleBuffer rowHandleBuffer = _rowHandleNativeBuffer; + RowHandleBuffer rowHandleBuffer = _rowHandleNativeBuffer!; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); @@ -1777,7 +1782,7 @@ private void GetRowDataFromHandle() IntPtr rowHandle = _rowHandleNativeBuffer.GetRowHandle(_currentRow); - RowBinding rowBinding = _bindings[_nextAccessorForRetrieval].RowBinding(); + RowBinding rowBinding = _bindings[_nextAccessorForRetrieval]!.RowBinding()!; IntPtr accessorHandle = rowBinding.DangerousGetAccessorHandle(); bool mustRelease = false; @@ -1811,7 +1816,7 @@ private void ReleaseRowHandles() OleDbHResult hr; UnsafeNativeMethods.IRowset irowset = IRowset(); - hr = irowset.ReleaseRows(_rowFetchedCount, _rowHandleNativeBuffer, ADP.PtrZero, ADP.PtrZero, ADP.PtrZero); + hr = irowset.ReleaseRows(_rowFetchedCount, _rowHandleNativeBuffer!, ADP.PtrZero, ADP.PtrZero, ADP.PtrZero); if (hr < 0) { @@ -1824,7 +1829,7 @@ private void ReleaseRowHandles() _isRead = false; } - private object GetPropertyValue(int propertyId) + private object? GetPropertyValue(int propertyId) { if (null != _irowset) { @@ -1837,7 +1842,7 @@ private object GetPropertyValue(int propertyId) return OleDbPropertyStatus.NotSupported; } - private object GetPropertyOnRowset(Guid propertySet, int propertyID) + private object? GetPropertyOnRowset(Guid propertySet, int propertyID) { OleDbHResult hr; ItagDBPROP[] dbprops; @@ -1868,14 +1873,14 @@ private void GetRowValue() Debug.Assert(null != _irow, "GetRowValue: null IRow"); Debug.Assert(null != _metadata, "GetRowValue: null MetaData"); - Bindings bindings = _bindings[_nextAccessorForRetrieval]; + Bindings bindings = _bindings![_nextAccessorForRetrieval]!; ColumnBinding[] columnBindings = bindings.ColumnBindings(); - RowBinding rowBinding = bindings.RowBinding(); + RowBinding rowBinding = bindings.RowBinding()!; Debug.Assert(_nextValueForRetrieval <= columnBindings[0].Index, "backwards retrieval"); bool mustReleaseBinding = false; bool[] mustRelease = new bool[columnBindings.Length]; - StringMemHandle[] sptr = new StringMemHandle[columnBindings.Length]; + StringMemHandle?[] sptr = new StringMemHandle[columnBindings.Length]; RuntimeHelpers.PrepareConstrainedRegions(); try @@ -1892,9 +1897,9 @@ private void GetRowValue() columnBindings[i]._sptr = sptr[i]; } - sptr[i].DangerousAddRef(ref mustRelease[i]); + sptr[i]!.DangerousAddRef(ref mustRelease[i]); - IntPtr ulPropid = ((null != sptr[i]) ? sptr[i].DangerousGetHandle() : info.propid); + IntPtr ulPropid = ((null != sptr[i]) ? sptr[i]!.DangerousGetHandle() : info.propid); bindings.GuidKindName(info.guid, info.kind, ulPropid); } @@ -1917,7 +1922,7 @@ private void GetRowValue() { if (mustRelease[i]) { - sptr[i].DangerousRelease(); + sptr[i]!.DangerousRelease(); } } } @@ -1927,7 +1932,7 @@ private void GetRowValue() private int IndexOf(Hashtable hash, string name) { // via case sensitive search, first match with lowest ordinal matches - object index = hash[name]; + object? index = hash[name]; if (null != index) { return (int)index; // match via case-insensitive or by chance lowercase @@ -1963,7 +1968,7 @@ private void AppendSchemaInfo() } string schemaName, catalogName; // enforce single table - string baseSchemaName = null, baseCatalogName = null, baseTableName = null; + string? baseSchemaName = null, baseCatalogName = null, baseTableName = null; for (int i = 0; i < _metadata.Length; ++i) { MetaData info = _metadata[i]; @@ -2005,7 +2010,7 @@ private void AppendSchemaInfo() { if (ODB.DBPROPVAL_IC_SENSITIVE == _connection.QuotedIdentifierCase()) { - string p = null, s = null; + string? p = null, s = null; _connection.GetLiteralQuotes(ADP.GetSchemaTable, out s, out p); if (null == s) { @@ -2023,7 +2028,7 @@ private void AppendSchemaInfo() for (int i = _metadata.Length - 1; 0 <= i; --i) { - string basecolumname = _metadata[i].baseColumnName; + string? basecolumname = _metadata[i].baseColumnName; if (!ADP.IsEmpty(basecolumname)) { baseColumnNames[basecolumname] = i; @@ -2031,7 +2036,7 @@ private void AppendSchemaInfo() } for (int i = 0; i < _metadata.Length; ++i) { - string basecolumname = _metadata[i].baseColumnName; + string? basecolumname = _metadata[i].baseColumnName; if (!ADP.IsEmpty(basecolumname)) { basecolumname = basecolumname.ToLowerInvariant(); @@ -2043,9 +2048,9 @@ private void AppendSchemaInfo() } // look for primary keys in the table - if (_connection.SupportSchemaRowset(OleDbSchemaGuid.Primary_Keys)) + if (_connection!.SupportSchemaRowset(OleDbSchemaGuid.Primary_Keys)) { - object[] restrictions = new object[] { baseCatalogName, baseSchemaName, baseTableName }; + object?[] restrictions = new object?[] { baseCatalogName, baseSchemaName, baseTableName }; keyCount = AppendSchemaPrimaryKey(baseColumnNames, restrictions); } if (0 != keyCount) @@ -2056,19 +2061,19 @@ private void AppendSchemaInfo() // look for a single unique contraint that can be upgraded if (_connection.SupportSchemaRowset(OleDbSchemaGuid.Indexes)) { - object[] restrictions = new object[] { baseCatalogName, baseSchemaName, null, null, baseTableName }; + object?[] restrictions = new object?[] { baseCatalogName, baseSchemaName, null, null, baseTableName }; AppendSchemaUniqueIndexAsKey(baseColumnNames, restrictions); } } - private int AppendSchemaPrimaryKey(Hashtable baseColumnNames, object[] restrictions) + private int AppendSchemaPrimaryKey(Hashtable baseColumnNames, object?[] restrictions) { int keyCount = 0; bool partialPrimaryKey = false; - DataTable table = null; + DataTable? table = null; try { - table = _connection.GetSchemaRowset(OleDbSchemaGuid.Primary_Keys, restrictions); + table = _connection!.GetSchemaRowset(OleDbSchemaGuid.Primary_Keys, restrictions); } catch (Exception e) { @@ -2095,7 +2100,7 @@ private int AppendSchemaPrimaryKey(Hashtable baseColumnNames, object[] restricti int metaindex = IndexOf(baseColumnNames, name); if (0 <= metaindex) { - MetaData info = _metadata[metaindex]; + MetaData info = _metadata![metaindex]; info.isKeyColumn = true; info.flags &= ~ODB.DBCOLUMNFLAGS_ISNULLABLE; keyCount++; @@ -2116,7 +2121,7 @@ private int AppendSchemaPrimaryKey(Hashtable baseColumnNames, object[] restricti } if (partialPrimaryKey) { // partial primary key detected - for (int i = 0; i < _metadata.Length; ++i) + for (int i = 0; i < _metadata!.Length; ++i) { _metadata[i].isKeyColumn = false; } @@ -2125,13 +2130,13 @@ private int AppendSchemaPrimaryKey(Hashtable baseColumnNames, object[] restricti return keyCount; } - private void AppendSchemaUniqueIndexAsKey(Hashtable baseColumnNames, object[] restrictions) + private void AppendSchemaUniqueIndexAsKey(Hashtable baseColumnNames, object?[] restrictions) { bool partialPrimaryKey = false; - DataTable table = null; + DataTable? table = null; try { - table = _connection.GetSchemaRowset(OleDbSchemaGuid.Indexes, restrictions); + table = _connection!.GetSchemaRowset(OleDbSchemaGuid.Indexes, restrictions); } catch (Exception e) { @@ -2159,11 +2164,11 @@ private void AppendSchemaUniqueIndexAsKey(Hashtable baseColumnNames, object[] re DataColumn pkeyColumn = dataColumns[pkeyIndex]; DataColumn uniqCOlumn = dataColumns[uniqIndex]; DataColumn nameColumn = dataColumns[nameIndex]; - DataColumn nulls = ((-1 != nullIndex) ? dataColumns[nullIndex] : null); + DataColumn? nulls = ((-1 != nullIndex) ? dataColumns[nullIndex] : null); - bool[] keys = new bool[_metadata.Length]; - bool[] uniq = new bool[_metadata.Length]; - string uniqueIndexName = null; + bool[] keys = new bool[_metadata!.Length]; + bool[]? uniq = new bool[_metadata.Length]; + string? uniqueIndexName = null; // match pkey name BaseColumnName foreach (DataRow dataRow in table.Rows) @@ -2257,21 +2262,22 @@ private void AppendSchemaUniqueIndexAsKey(Hashtable baseColumnNames, object[] re } } - private MetaData FindMetaData(string name) + private MetaData? FindMetaData(string name) { - int index = _fieldNameLookup.IndexOfName(name); - return ((-1 != index) ? _metadata[index] : null); + int index = _fieldNameLookup!.IndexOfName(name); + return ((-1 != index) ? _metadata![index] : null); } - internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset) + internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset? rowset) { List metainfo = new List(); - object hiddenColumns = null; + object? hiddenColumns = null; using (OleDbDataReader dataReader = new OleDbDataReader(_connection, _command, int.MinValue, 0)) { dataReader.InitializeIRowset(rowset, ChapterHandle.DB_NULL_HCHAPTER, IntPtr.Zero); - dataReader.BuildSchemaTableInfo(rowset, true, false); + // TODO-NULLABLE: BuildSchemaTableInfo asserts that rowset isn't null, but doesn't do anything with it + dataReader.BuildSchemaTableInfo(rowset!, true, false); hiddenColumns = GetPropertyValue(ODB.DBPROP_HIDDENCOLUMNS); if (0 == dataReader.FieldCount) @@ -2286,24 +2292,24 @@ internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset) // This column, together with the DBCOLUMN_GUID and DBCOLUMN_PROPID // columns, forms the ID of the column. One or more (but not all) of these columns // will be NULL, depending on which elements of the DBID structure the provider uses. - MetaData columnidname = dataReader.FindMetaData(ODB.DBCOLUMN_IDNAME); - MetaData columnguid = dataReader.FindMetaData(ODB.DBCOLUMN_GUID); - MetaData columnpropid = dataReader.FindMetaData(ODB.DBCOLUMN_PROPID); - - MetaData columnname = dataReader.FindMetaData(ODB.DBCOLUMN_NAME); - MetaData columnordinal = dataReader.FindMetaData(ODB.DBCOLUMN_NUMBER); - MetaData dbtype = dataReader.FindMetaData(ODB.DBCOLUMN_TYPE); - MetaData columnsize = dataReader.FindMetaData(ODB.DBCOLUMN_COLUMNSIZE); - MetaData numericprecision = dataReader.FindMetaData(ODB.DBCOLUMN_PRECISION); - MetaData numericscale = dataReader.FindMetaData(ODB.DBCOLUMN_SCALE); - MetaData columnflags = dataReader.FindMetaData(ODB.DBCOLUMN_FLAGS); - MetaData baseschemaname = dataReader.FindMetaData(ODB.DBCOLUMN_BASESCHEMANAME); - MetaData basecatalogname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECATALOGNAME); - MetaData basetablename = dataReader.FindMetaData(ODB.DBCOLUMN_BASETABLENAME); - MetaData basecolumnname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECOLUMNNAME); - MetaData isautoincrement = dataReader.FindMetaData(ODB.DBCOLUMN_ISAUTOINCREMENT); - MetaData isunique = dataReader.FindMetaData(ODB.DBCOLUMN_ISUNIQUE); - MetaData iskeycolumn = dataReader.FindMetaData(ODB.DBCOLUMN_KEYCOLUMN); + MetaData columnidname = dataReader.FindMetaData(ODB.DBCOLUMN_IDNAME)!; + MetaData columnguid = dataReader.FindMetaData(ODB.DBCOLUMN_GUID)!; + MetaData columnpropid = dataReader.FindMetaData(ODB.DBCOLUMN_PROPID)!; + + MetaData columnname = dataReader.FindMetaData(ODB.DBCOLUMN_NAME)!; + MetaData columnordinal = dataReader.FindMetaData(ODB.DBCOLUMN_NUMBER)!; + MetaData dbtype = dataReader.FindMetaData(ODB.DBCOLUMN_TYPE)!; + MetaData columnsize = dataReader.FindMetaData(ODB.DBCOLUMN_COLUMNSIZE)!; + MetaData numericprecision = dataReader.FindMetaData(ODB.DBCOLUMN_PRECISION)!; + MetaData numericscale = dataReader.FindMetaData(ODB.DBCOLUMN_SCALE)!; + MetaData columnflags = dataReader.FindMetaData(ODB.DBCOLUMN_FLAGS)!; + MetaData baseschemaname = dataReader.FindMetaData(ODB.DBCOLUMN_BASESCHEMANAME)!; + MetaData basecatalogname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECATALOGNAME)!; + MetaData basetablename = dataReader.FindMetaData(ODB.DBCOLUMN_BASETABLENAME)!; + MetaData basecolumnname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECOLUMNNAME)!; + MetaData isautoincrement = dataReader.FindMetaData(ODB.DBCOLUMN_ISAUTOINCREMENT)!; + MetaData isunique = dataReader.FindMetaData(ODB.DBCOLUMN_ISUNIQUE)!; + MetaData iskeycolumn = dataReader.FindMetaData(ODB.DBCOLUMN_KEYCOLUMN)!; // @devnote: because we want to use the DBACCESSOR_OPTIMIZED bit, // we are required to create the accessor before fetching any rows @@ -2517,7 +2523,7 @@ internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset) #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { - Debug.WriteLine("Filtered Column: DBCOLUMN_FLAGS=" + info.flags.ToString("X8", (System.IFormatProvider)null) + " DBCOLUMN_NAME=" + info.columnName); + Debug.WriteLine("Filtered Column: DBCOLUMN_FLAGS=" + info.flags.ToString("X8", null) + " DBCOLUMN_NAME=" + info.columnName); } #endif info.isHidden = true; @@ -2542,7 +2548,7 @@ internal static void GenerateSchemaTable(OleDbDataReader dataReader, object hand { dataReader.BuildSchemaTableInfo(handle, false, false); // only tries IColumnsInfo } - MetaData[] metadata = dataReader.MetaData; + MetaData[]? metadata = dataReader.MetaData; if ((null != metadata) && (0 < metadata.Length)) { dataReader.BuildSchemaTable(metadata); @@ -2581,17 +2587,17 @@ private static bool IsReadOnly(int flags) internal sealed class MetaData : IComparable { - internal Bindings bindings; - internal ColumnBinding columnBinding; + internal Bindings? bindings; + internal ColumnBinding columnBinding = null!; // Late-initialized - internal string columnName; + internal string columnName = null!; // Late-initialized internal Guid guid; internal int kind; internal IntPtr propid; - internal string idname; + internal string? idname; - internal NativeDBType type; + internal NativeDBType type = null!; // Late-initialized internal IntPtr ordinal; internal int size; @@ -2606,22 +2612,22 @@ internal sealed class MetaData : IComparable internal bool isKeyColumn; internal bool isHidden; - internal string baseSchemaName; - internal string baseCatalogName; - internal string baseTableName; - internal string baseColumnName; + internal string? baseSchemaName; + internal string? baseCatalogName; + internal string? baseTableName; + internal string? baseColumnName; - int IComparable.CompareTo(object obj) + int IComparable.CompareTo(object? obj) { - if (isHidden == (obj as MetaData).isHidden) + if (isHidden == (obj as MetaData)!.isHidden) { if (ODB.IsRunningOnX86) { - return ((int)ordinal - (int)(obj as MetaData).ordinal); + return ((int)ordinal - (int)(obj as MetaData)!.ordinal); } else { - long v = ((long)ordinal - (long)(obj as MetaData).ordinal); + long v = ((long)ordinal - (long)(obj as MetaData)!.ordinal); return ((0 < v) ? 1 : ((v < 0) ? -1 : 0)); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs b/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs index 8b78d5618d23..03ddf2574155 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs @@ -28,17 +28,17 @@ public static OleDbDataReader GetEnumerator(Type type) internal static OleDbDataReader GetEnumeratorFromType(Type type) { - object value = Activator.CreateInstance(type, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null); + object? value = Activator.CreateInstance(type, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null); return GetEnumeratorReader(value); } - private static OleDbDataReader GetEnumeratorReader(object value) + private static OleDbDataReader GetEnumeratorReader(object? value) { - NativeMethods.ISourcesRowset srcrowset = null; + NativeMethods.ISourcesRowset? srcrowset = null; try { - srcrowset = (NativeMethods.ISourcesRowset)value; + srcrowset = (NativeMethods.ISourcesRowset?)value; } catch (InvalidCastException) { @@ -54,7 +54,7 @@ private static OleDbDataReader GetEnumeratorReader(object value) IntPtr propSets = ADP.PtrZero; OleDbHResult hr = srcrowset.GetSourcesRowset(ADP.PtrZero, ODB.IID_IRowset, propCount, propSets, out value); - Exception f = OleDbConnection.ProcessResults(hr, null, null); + Exception? f = OleDbConnection.ProcessResults(hr, null, null); if (null != f) { throw f; @@ -72,7 +72,7 @@ public static OleDbDataReader GetRootEnumerator() //readonly Guid CLSID_MSDAENUM = new Guid(0xc8b522d0,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d); //Type msdaenum = Type.GetTypeFromCLSID(CLSID_MSDAENUM, true); const string PROGID_MSDAENUM = "MSDAENUM"; - Type msdaenum = Type.GetTypeFromProgID(PROGID_MSDAENUM, true); + Type msdaenum = Type.GetTypeFromProgID(PROGID_MSDAENUM, true)!; return GetEnumeratorFromType(msdaenum); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbError.cs b/src/libraries/System.Data.OleDb/src/OleDbError.cs index d578a50da637..333cdb3128a7 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbError.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbError.cs @@ -8,9 +8,9 @@ namespace System.Data.OleDb { public sealed class OleDbError { - private readonly string message; - private readonly string source; - private readonly string sqlState; + private readonly string? message; + private readonly string? source; + private readonly string? sqlState; private readonly int nativeError; internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) @@ -56,7 +56,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) { this.source = ODB.FailedGetSource(hr); } - Marshal.ReleaseComObject(errorInfo); + Marshal.ReleaseComObject(errorInfo!); } } @@ -74,7 +74,7 @@ public string Message { get { - string message = this.message; + string? message = this.message; return ((null != message) ? message : string.Empty); } } @@ -91,7 +91,7 @@ public string Source { get { - string source = this.source; + string? source = this.source; return ((null != source) ? source : string.Empty); } } @@ -100,7 +100,7 @@ public string SQLState { get { - string sqlState = this.sqlState; + string? sqlState = this.sqlState; return ((null != sqlState) ? sqlState : string.Empty); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbErrorCollection.cs b/src/libraries/System.Data.OleDb/src/OleDbErrorCollection.cs index 72e47b72705c..d6a164487559 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbErrorCollection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbErrorCollection.cs @@ -12,10 +12,10 @@ public sealed class OleDbErrorCollection : System.Collections.ICollection { private readonly ArrayList items; - internal OleDbErrorCollection(UnsafeNativeMethods.IErrorInfo errorInfo) + internal OleDbErrorCollection(UnsafeNativeMethods.IErrorInfo? errorInfo) { ArrayList items = new ArrayList(); - UnsafeNativeMethods.IErrorRecords errorRecords = (errorInfo as UnsafeNativeMethods.IErrorRecords); + UnsafeNativeMethods.IErrorRecords? errorRecords = (errorInfo as UnsafeNativeMethods.IErrorRecords); if (null != errorRecords) { int recordCount = errorRecords.GetRecordCount(); @@ -52,7 +52,7 @@ public OleDbError this[int index] { get { - return (this.items[index] as OleDbError); + return (this.items[index] as OleDbError)!; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index 563099230061..410e9cb33da8 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -15,19 +15,19 @@ public sealed class OleDbException : System.Data.Common.DbException { private readonly OleDbErrorCollection oledbErrors; - internal OleDbException(string message, OleDbHResult errorCode, Exception inner) : base(message, inner) + internal OleDbException(string? message, OleDbHResult errorCode, Exception? inner) : base(message, inner) { HResult = (int)errorCode; this.oledbErrors = new OleDbErrorCollection(null); } - internal OleDbException(OleDbException previous, Exception inner) : base(previous.Message, inner) + internal OleDbException(OleDbException previous, Exception? inner) : base(previous.Message, inner) { HResult = previous.ErrorCode; this.oledbErrors = previous.oledbErrors; } - private OleDbException(string message, Exception inner, string source, OleDbHResult errorCode, OleDbErrorCollection errors) : base(message, inner) + private OleDbException(string? message, Exception? inner, string? source, OleDbHResult errorCode, OleDbErrorCollection errors) : base(message, inner) { Debug.Assert(null != errors, "OleDbException without OleDbErrorCollection"); Source = source; @@ -64,11 +64,11 @@ public OleDbErrorCollection Errors } } - internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception inner) + internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) { OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); - string message = null; - string source = null; + string? message = null; + string? source = null; OleDbHResult hr = 0; if (null != errorInfo) diff --git a/src/libraries/System.Data.OleDb/src/OleDbInfoMessageEvent.cs b/src/libraries/System.Data.OleDb/src/OleDbInfoMessageEvent.cs index c9f7444a3bc1..e082c8f5c53c 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbInfoMessageEvent.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbInfoMessageEvent.cs @@ -39,7 +39,7 @@ public string Message } } - public string Source + public string? Source { get { diff --git a/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs b/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs index d5d32870a357..e978419c2f83 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs @@ -33,7 +33,7 @@ internal SchemaRowsetName(string schemaName, Guid schemaRowset) internal OleDbMetaDataFactory(Stream XMLStream, string serverVersion, string serverVersionNormalized, - SchemaSupport[] schemaSupport) : + SchemaSupport[]? schemaSupport) : base(XMLStream, serverVersion, serverVersionNormalized) { // set up the colletion mane schema rowset guid mapping @@ -50,7 +50,7 @@ internal OleDbMetaDataFactory(Stream XMLStream, new SchemaRowsetName(OleDbMetaDataCollectionNames.Views, OleDbSchemaGuid.Views)}; // verify the existance of the table in the data set - DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; + DataTable? metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; if (metaDataCollectionsTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.MetaDataCollections); @@ -60,7 +60,7 @@ internal OleDbMetaDataFactory(Stream XMLStream, metaDataCollectionsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.MetaDataCollections, null); // verify the existance of the table in the data set - DataTable restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; + DataTable? restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; if (restrictionsTable != null) { // copy the table filtering out any rows that don't apply to the current version of the provider @@ -72,17 +72,17 @@ internal OleDbMetaDataFactory(Stream XMLStream, // 2) it is in the collection to schema rowset mapping above // 3) the provider does not support the necessary schema rowset - DataColumn populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism]; + DataColumn? populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism]; if ((null == populationMechanism) || (typeof(string) != populationMechanism.DataType)) { throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, _populationMechanism); } - DataColumn collectionName = metaDataCollectionsTable.Columns[_collectionName]; + DataColumn? collectionName = metaDataCollectionsTable.Columns[_collectionName]; if ((null == collectionName) || (typeof(string) != collectionName.DataType)) { throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, _collectionName); } - DataColumn restrictionCollectionName = null; + DataColumn? restrictionCollectionName = null; if (restrictionsTable != null) { restrictionCollectionName = restrictionsTable.Columns[_collectionName]; @@ -94,12 +94,12 @@ internal OleDbMetaDataFactory(Stream XMLStream, foreach (DataRow collection in metaDataCollectionsTable.Rows) { - string populationMechanismValue = collection[populationMechanism] as string; + string? populationMechanismValue = collection[populationMechanism] as string; if (ADP.IsEmpty(populationMechanismValue)) { throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections, _populationMechanism); } - string collectionNameValue = collection[collectionName] as string; + string? collectionNameValue = collection[collectionName] as string; if (ADP.IsEmpty(collectionNameValue)) { throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections, _collectionName); @@ -144,7 +144,7 @@ internal OleDbMetaDataFactory(Stream XMLStream, { foreach (DataRow restriction in restrictionsTable.Rows) { - string restrictionCollectionNameValue = restriction[restrictionCollectionName] as string; + string? restrictionCollectionNameValue = restriction[restrictionCollectionName!] as string; if (ADP.IsEmpty(restrictionCollectionNameValue)) { throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.Restrictions, _collectionName); @@ -164,12 +164,12 @@ internal OleDbMetaDataFactory(Stream XMLStream, // replace the original table with the updated one metaDataCollectionsTable.AcceptChanges(); - CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]); + CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!); CollectionDataSet.Tables.Add(metaDataCollectionsTable); if (restrictionsTable != null) { - CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]); + CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]!); CollectionDataSet.Tables.Add(restrictionsTable); } @@ -189,7 +189,7 @@ private string BuildRegularExpression(string invalidChars, string invalidStartin private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleDbConnectionInternal internalConnection) { // verify that the data source information table is in the data set - DataTable dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; + DataTable? dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; if (dataSourceInformationTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataSourceInformation); @@ -206,8 +206,8 @@ private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleD DataRow dataSourceInformation = dataSourceInformationTable.Rows[0]; // update the identifier separator - string catalogSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_CATALOG_SEPARATOR); - string schemaSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_SCHEMA_SEPARATOR); + string? catalogSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_CATALOG_SEPARATOR); + string? schemaSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_SCHEMA_SEPARATOR); if (catalogSeparatorPattern != null) { @@ -233,7 +233,7 @@ private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleD } // update the DataSourceProductName - object property; + object? property; property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DBMSNAME); if (property != null) { @@ -283,7 +283,7 @@ private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleD dataSourceInformation[DbMetaDataColumnNames.OrderByColumnsInSelect] = (bool)property; } - DataTable infoLiterals = internalConnection.BuildInfoLiterals(); + DataTable? infoLiterals = internalConnection.BuildInfoLiterals(); if (infoLiterals != null) { DataRow[] tableNameRow = infoLiterals.Select("Literal = " + ODB.DBLITERAL_TABLE_NAME.ToString(CultureInfo.InvariantCulture)); @@ -353,7 +353,7 @@ private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleD private DataTable GetDataTypesTable(OleDbConnection connection) { // verify the existance of the table in the data set - DataTable dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes]; + DataTable? dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes]; if (dataTypesTable == null) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataTypes); @@ -362,9 +362,9 @@ private DataTable GetDataTypesTable(OleDbConnection connection) // copy the table filtering out any rows that don't apply to tho current version of the prrovider dataTypesTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataTypes, null); - DataTable providerTypesTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Provider_Types, null); + DataTable providerTypesTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Provider_Types, null)!; - DataColumn[] targetColumns = new DataColumn[] { + DataColumn?[] targetColumns = new DataColumn?[] { dataTypesTable.Columns[DbMetaDataColumnNames.TypeName], dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize], dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters], @@ -381,7 +381,7 @@ private DataTable GetDataTypesTable(OleDbConnection connection) dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix], dataTypesTable.Columns[OleDbMetaDataColumnNames.NativeDataType]}; - DataColumn[] sourceColumns = new DataColumn[] { + DataColumn?[] sourceColumns = new DataColumn?[] { providerTypesTable.Columns["TYPE_NAME"], providerTypesTable.Columns["COLUMN_SIZE"], providerTypesTable.Columns["CREATE_PARAMS"], @@ -400,31 +400,31 @@ private DataTable GetDataTypesTable(OleDbConnection connection) Debug.Assert(sourceColumns.Length == targetColumns.Length); - DataColumn isSearchable = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable]; - DataColumn isSearchableWithLike = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]; - DataColumn providerDbType = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]; - DataColumn clrType = dataTypesTable.Columns[DbMetaDataColumnNames.DataType]; - DataColumn isLong = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]; - DataColumn isFixed = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength]; - DataColumn sourceOleDbType = providerTypesTable.Columns["DATA_TYPE"]; + DataColumn isSearchable = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable]!; + DataColumn isSearchableWithLike = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]!; + DataColumn providerDbType = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]!; + DataColumn clrType = dataTypesTable.Columns[DbMetaDataColumnNames.DataType]!; + DataColumn isLong = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]!; + DataColumn isFixed = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength]!; + DataColumn sourceOleDbType = providerTypesTable.Columns["DATA_TYPE"]!; - DataColumn searchable = providerTypesTable.Columns["SEARCHABLE"]; + DataColumn searchable = providerTypesTable.Columns["SEARCHABLE"]!; foreach (DataRow sourceRow in providerTypesTable.Rows) { DataRow newRow = dataTypesTable.NewRow(); for (int i = 0; i < sourceColumns.Length; i++) { - if ((sourceColumns[i] != null) && (targetColumns[i] != null)) + if ((sourceColumns[i] is DataColumn sourceColumn) && (targetColumns[i] is DataColumn targetColumn)) { - newRow[targetColumns[i]] = sourceRow[sourceColumns[i]]; + newRow[targetColumn] = sourceRow[sourceColumn]; } } short nativeDataType = (short)Convert.ChangeType(sourceRow[sourceOleDbType], typeof(short), CultureInfo.InvariantCulture); NativeDBType nativeType = NativeDBType.FromDBType(nativeDataType, (bool)newRow[isLong], (bool)newRow[isFixed]); - newRow[clrType] = nativeType.dataType.FullName; + newRow[clrType] = nativeType.dataType!.FullName; newRow[providerDbType] = nativeType.enumOleDbType; // searchable has to be special cased becasue it is not an eaxct mapping @@ -472,7 +472,7 @@ private DataTable GetDataTypesTable(OleDbConnection connection) private DataTable GetReservedWordsTable(OleDbConnectionInternal internalConnection) { // verify the existance of the table in the data set - DataTable reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; + DataTable? reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; if (null == reservedWordsTable) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); @@ -481,7 +481,7 @@ private DataTable GetReservedWordsTable(OleDbConnectionInternal internalConnecti // copy the table filtering out any rows that don't apply to tho current version of the prrovider reservedWordsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.ReservedWords, null); - DataColumn reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord]; + DataColumn? reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord]; if (null == reservedWordColumn) { throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); @@ -495,11 +495,11 @@ private DataTable GetReservedWordsTable(OleDbConnectionInternal internalConnecti return reservedWordsTable; } - protected override DataTable PrepareCollection(string collectionName, string[] restrictions, DbConnection connection) + protected override DataTable PrepareCollection(string collectionName, string?[]? restrictions, DbConnection connection) { OleDbConnection oleDbConnection = (OleDbConnection)connection; OleDbConnectionInternal oleDbInternalConnection = (OleDbConnectionInternal)(oleDbConnection.InnerConnection); - DataTable resultTable = null; + DataTable? resultTable = null; if (collectionName == DbMetaDataCollectionNames.DataSourceInformation) { if (ADP.IsEmptyArray(restrictions) == false) @@ -532,12 +532,12 @@ protected override DataTable PrepareCollection(string collectionName, string[] r { // need to special case the oledb schema rowset restrictions on columns that are not // string tpyes - object[] mungedRestrictions = restrictions; + object?[]? mungedRestrictions = restrictions; ; if (restrictions != null) { //verify that there are not too many restrictions - DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; + DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!; int numberOfSupportedRestictions = -1; // prepare colletion is called with the exact collection name so // we can do an exact string comparision here @@ -595,7 +595,7 @@ protected override DataTable PrepareCollection(string collectionName, string[] r } else { - throw ADP.InvalidRestrictionValue(collectionName, "TYPE", restrictions[indexRestrictionTypeSlot]); + throw ADP.InvalidRestrictionValue(collectionName, "TYPE", restrictions[indexRestrictionTypeSlot]!); } mungedRestrictions[indexRestrictionTypeSlot] = indexTypeValue; @@ -634,7 +634,7 @@ protected override DataTable PrepareCollection(string collectionName, string[] r } else { - throw ADP.InvalidRestrictionValue(collectionName, "PROCEDURE_TYPE", restrictions[procedureRestrictionTypeSlot]); + throw ADP.InvalidRestrictionValue(collectionName, "PROCEDURE_TYPE", restrictions[procedureRestrictionTypeSlot]!); } mungedRestrictions[procedureRestrictionTypeSlot] = procedureTypeValue; @@ -658,7 +658,7 @@ protected override DataTable PrepareCollection(string collectionName, string[] r private void SetIdentifierCase(string columnName, int propertyID, DataRow row, OleDbConnection connection) { - object property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, propertyID); + object? property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, propertyID); IdentifierCase identifierCase = IdentifierCase.Unknown; if (property != null) { diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs index 169c660ad73f..61053ad7c319 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Data.OleDb @@ -11,21 +12,21 @@ namespace System.Data.OleDb [TypeConverter(typeof(OleDbParameter.OleDbParameterConverter))] public sealed partial class OleDbParameter : DbParameter, ICloneable, IDbDataParameter { - private NativeDBType _metaType; + private NativeDBType? _metaType; private int _changeID; - private string _parameterName; + private string? _parameterName; private byte _precision; private byte _scale; private bool _hasScale; - private NativeDBType _coerceMetaType; + private NativeDBType? _coerceMetaType; public OleDbParameter() : base() { // V1.0 nothing } - public OleDbParameter(string name, object value) : this() + public OleDbParameter(string? name, object? value) : this() { Debug.Assert(!(value is OleDbType), "use OleDbParameter(string, OleDbType)"); Debug.Assert(!(value is SqlDbType), "use OleDbParameter(string, OleDbType)"); @@ -34,20 +35,20 @@ public OleDbParameter(string name, object value) : this() Value = value; } - public OleDbParameter(string name, OleDbType dataType) : this() + public OleDbParameter(string? name, OleDbType dataType) : this() { ParameterName = name; OleDbType = dataType; } - public OleDbParameter(string name, OleDbType dataType, int size) : this() + public OleDbParameter(string? name, OleDbType dataType, int size) : this() { ParameterName = name; OleDbType = dataType; Size = size; } - public OleDbParameter(string name, OleDbType dataType, int size, string srcColumn) : this() + public OleDbParameter(string? name, OleDbType dataType, int size, string? srcColumn) : this() { ParameterName = name; OleDbType = dataType; @@ -56,12 +57,12 @@ public OleDbParameter(string name, OleDbType dataType, int size, string srcColum } [EditorBrowsable(EditorBrowsableState.Advanced)] - public OleDbParameter(string parameterName, + public OleDbParameter(string? parameterName, OleDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, - string srcColumn, DataRowVersion srcVersion, - object value) : this() + string? srcColumn, DataRowVersion srcVersion, + object? value) : this() { // V1.0 everything ParameterName = parameterName; OleDbType = dbType; @@ -76,12 +77,12 @@ public OleDbParameter(string parameterName, } [EditorBrowsable(EditorBrowsableState.Advanced)] - public OleDbParameter(string parameterName, + public OleDbParameter(string? parameterName, OleDbType dbType, int size, ParameterDirection direction, byte precision, byte scale, - string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, - object value) : this() + string? sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, + object? value) : this() { // V2.0 everything - round trip all browsable properties + precision/scale ParameterName = parameterName; OleDbType = dbType; @@ -111,7 +112,7 @@ public override DbType DbType } set { - NativeDBType dbtype = _metaType; + NativeDBType? dbtype = _metaType; if ((null == dbtype) || (dbtype.enumDbType != value)) { PropertyTypeChanging(); @@ -137,7 +138,7 @@ public OleDbType OleDbType } set { - NativeDBType dbtype = _metaType; + NativeDBType? dbtype = _metaType; if ((null == dbtype) || (dbtype.enumOleDbType != value)) { PropertyTypeChanging(); @@ -160,11 +161,12 @@ public void ResetOleDbType() } } + [AllowNull] public override string ParameterName { // V1.2.3300, XXXParameter V1.0.3300 get { - string parameterName = _parameterName; + string? parameterName = _parameterName; return ((null != parameterName) ? parameterName : string.Empty); } set @@ -289,7 +291,7 @@ private void PropertyTypeChanging() internal bool BindParameter(int index, Bindings bindings) { int changeID = _changeID; - object value = Value; + object? value = Value; NativeDBType dbtype = GetBindType(value); if (OleDbType.Empty == dbtype.enumOleDbType) @@ -357,7 +359,7 @@ internal bool BindParameter(int index, Bindings bindings) { // variable length data (varbinary, varchar, nvarchar) if (!ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output)) { - throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType); + throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType!); } bool computedSize; @@ -460,7 +462,7 @@ internal bool BindParameter(int index, Bindings bindings) return IsParameterComputed(); } - private static object CoerceValue(object value, NativeDBType destinationType) + private static object? CoerceValue(object? value, NativeDBType destinationType) { Debug.Assert(null != destinationType, "null destinationType"); if ((null != value) && (DBNull.Value != value) && (typeof(object) != destinationType.dataType)) @@ -475,11 +477,11 @@ private static object CoerceValue(object value, NativeDBType destinationType) } else if ((NativeDBType.CY == destinationType.dbType) && (typeof(string) == currentType)) { - value = decimal.Parse((string)value, NumberStyles.Currency, (IFormatProvider)null); + value = decimal.Parse((string)value, NumberStyles.Currency, null); } else { - value = Convert.ChangeType(value, destinationType.dataType, (IFormatProvider)null); + value = Convert.ChangeType(value, destinationType.dataType!, null); } } catch (Exception e) @@ -490,16 +492,16 @@ private static object CoerceValue(object value, NativeDBType destinationType) throw; } - throw ADP.ParameterConversionFailed(value, destinationType.dataType, e); + throw ADP.ParameterConversionFailed(value, destinationType.dataType!, e); } } } return value; } - private NativeDBType GetBindType(object value) + private NativeDBType GetBindType(object? value) { - NativeDBType dbtype = _metaType; + NativeDBType? dbtype = _metaType; if (null == dbtype) { if (ADP.IsNull(value)) @@ -514,12 +516,12 @@ private NativeDBType GetBindType(object value) return dbtype; } - internal object GetCoercedValue() + internal object? GetCoercedValue() { - object value = CoercedValue; // will also be set during binding, will rebind everytime if _metaType not set + object? value = CoercedValue; // will also be set during binding, will rebind everytime if _metaType not set if (null == value) { - value = CoerceValue(Value, _coerceMetaType); + value = CoerceValue(Value, _coerceMetaType!); CoercedValue = value; } return value; @@ -527,7 +529,7 @@ internal object GetCoercedValue() internal bool IsParameterComputed() { - NativeDBType metaType = _metaType; + NativeDBType? metaType = _metaType; return ((null == metaType) || (!ShouldSerializeSize() && metaType.IsVariableLength) || ((NativeDBType.DECIMAL == metaType.dbType) || (NativeDBType.NUMERIC == metaType.dbType) @@ -560,7 +562,7 @@ internal void Prepare(OleDbCommand cmd) RefreshProperties(RefreshProperties.All), TypeConverter(typeof(StringConverter)), ] - public override object Value + public override object? Value { // V1.2.3300, XXXParameter V1.0.3300 get { @@ -573,17 +575,17 @@ public override object Value } } - private byte ValuePrecision(object value) + private byte ValuePrecision(object? value) { return ValuePrecisionCore(value); } - private byte ValueScale(object value) + private byte ValueScale(object? value) { return ValueScaleCore(value); } - private int ValueSize(object value) + private int ValueSize(object? value) { return ValueSizeCore(value); } @@ -641,9 +643,9 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul { throw ADP.ArgumentNull("destinationType"); } - if ((typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) && (value is OleDbParameter)) + if ((typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) && (value is OleDbParameter parameter)) { - return ConvertToInstanceDescriptor(value as OleDbParameter); + return ConvertToInstanceDescriptor(parameter); } return base.ConvertTo(context, culture, value, destinationType); } @@ -680,7 +682,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI } Type[] ctorParams; - object[] ctorValues; + object?[] ctorValues; switch (flags) { case 0: // ParameterName @@ -702,7 +704,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI break; case 8: // Value ctorParams = new Type[] { typeof(string), typeof(object) }; - ctorValues = new object[] { p.ParameterName, p.Value }; + ctorValues = new object?[] { p.ParameterName, p.Value }; break; default: // everything else if (0 == (32 & flags)) @@ -711,7 +713,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI typeof(string), typeof(OleDbType), typeof(int), typeof(ParameterDirection), typeof(bool), typeof(byte), typeof(byte), typeof(string), typeof(DataRowVersion), typeof(object) }; - ctorValues = new object[] { + ctorValues = new object?[] { p.ParameterName, p.OleDbType, p.Size, p.Direction, p.IsNullable, p.PrecisionInternal, p.ScaleInternal, p.SourceColumn, p.SourceVersion, p.Value }; @@ -723,7 +725,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI typeof(byte), typeof(byte), typeof(string), typeof(DataRowVersion), typeof(bool), typeof(object) }; - ctorValues = new object[] { + ctorValues = new object?[] { p.ParameterName, p.OleDbType, p.Size, p.Direction, p.PrecisionInternal, p.ScaleInternal, p.SourceColumn, p.SourceVersion, p.SourceColumnNullMapping, @@ -731,7 +733,7 @@ private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToI } break; } - System.Reflection.ConstructorInfo ctor = typeof(OleDbParameter).GetConstructor(ctorParams); + System.Reflection.ConstructorInfo ctor = typeof(OleDbParameter).GetConstructor(ctorParams)!; return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameterCollection.cs b/src/libraries/System.Data.OleDb/src/OleDbParameterCollection.cs index 393e1cc494d6..3f540656e000 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameterCollection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameterCollection.cs @@ -64,27 +64,27 @@ public OleDbParameter Add(OleDbParameter value) [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Add(String parameterName, Object value) has been deprecated. Use AddWithValue(String parameterName, Object value). https://go.microsoft.com/fwlink/?linkid=14202", false)] - public OleDbParameter Add(string parameterName, object value) + public OleDbParameter Add(string? parameterName, object? value) { return Add(new OleDbParameter(parameterName, value)); } - public OleDbParameter AddWithValue(string parameterName, object value) + public OleDbParameter AddWithValue(string? parameterName, object? value) { return Add(new OleDbParameter(parameterName, value)); } - public OleDbParameter Add(string parameterName, OleDbType oleDbType) + public OleDbParameter Add(string? parameterName, OleDbType oleDbType) { return Add(new OleDbParameter(parameterName, oleDbType)); } - public OleDbParameter Add(string parameterName, OleDbType oleDbType, int size) + public OleDbParameter Add(string? parameterName, OleDbType oleDbType, int size) { return Add(new OleDbParameter(parameterName, oleDbType, size)); } - public OleDbParameter Add(string parameterName, OleDbType oleDbType, int size, string sourceColumn) + public OleDbParameter Add(string? parameterName, OleDbType oleDbType, int size, string? sourceColumn) { return Add(new OleDbParameter(parameterName, oleDbType, size, sourceColumn)); } diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameterCollectionHelper.cs b/src/libraries/System.Data.OleDb/src/OleDbParameterCollectionHelper.cs index 3470271878fd..9f0f898c5c30 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameterCollectionHelper.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameterCollectionHelper.cs @@ -11,7 +11,7 @@ namespace System.Data.OleDb { public sealed partial class OleDbParameterCollection : DbParameterCollection { - private List _items; + private List? _items; public override int Count { @@ -25,7 +25,7 @@ private List InnerList { get { - List items = _items; + List? items = _items; if (null == items) { @@ -298,7 +298,7 @@ private void Validate(int index, object value) throw ADP.ParameterNull(nameof(value), this, s_itemType); } - object parent = ((OleDbParameter)value).CompareExchangeParent(this, null); + object? parent = ((OleDbParameter)value).CompareExchangeParent(this, null); if (null != parent) { if (this != parent) diff --git a/src/libraries/System.Data.OleDb/src/OleDbRowUpdatedEvent.cs b/src/libraries/System.Data.OleDb/src/OleDbRowUpdatedEvent.cs index 07e5a442fac4..99c2db066904 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbRowUpdatedEvent.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbRowUpdatedEvent.cs @@ -7,16 +7,16 @@ namespace System.Data.OleDb { public sealed class OleDbRowUpdatedEventArgs : RowUpdatedEventArgs { - public OleDbRowUpdatedEventArgs(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + public OleDbRowUpdatedEventArgs(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) : base(dataRow, command, statementType, tableMapping) { } - public new OleDbCommand Command + public new OleDbCommand? Command { get { - return (OleDbCommand)base.Command; + return (OleDbCommand?)base.Command; } } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbRowUpdatingEvent.cs b/src/libraries/System.Data.OleDb/src/OleDbRowUpdatingEvent.cs index 6233b2f6d607..d9f38ddea44f 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbRowUpdatingEvent.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbRowUpdatingEvent.cs @@ -7,18 +7,18 @@ namespace System.Data.OleDb { public sealed class OleDbRowUpdatingEventArgs : RowUpdatingEventArgs { - public OleDbRowUpdatingEventArgs(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) + public OleDbRowUpdatingEventArgs(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) : base(dataRow, command, statementType, tableMapping) { } - public new OleDbCommand Command + public new OleDbCommand? Command { get { return (base.Command as OleDbCommand); } set { base.Command = value; } } - protected override IDbCommand BaseCommand + protected override IDbCommand? BaseCommand { get { return base.BaseCommand; } set { base.BaseCommand = (value as OleDbCommand); } diff --git a/src/libraries/System.Data.OleDb/src/OleDbStruct.cs b/src/libraries/System.Data.OleDb/src/OleDbStruct.cs index 638b0973586e..69a0e4807db7 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbStruct.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbStruct.cs @@ -248,13 +248,13 @@ typedef struct tagDBLITERALINFO { internal sealed class tagDBLITERALINFO { [MarshalAs(UnmanagedType.LPWStr)] - internal string pwszLiteralValue = null; + internal string? pwszLiteralValue = null; [MarshalAs(UnmanagedType.LPWStr)] - internal string pwszInvalidChars = null; + internal string? pwszInvalidChars = null; [MarshalAs(UnmanagedType.LPWStr)] - internal string pwszInvalidStartingChars = null; + internal string? pwszInvalidStartingChars = null; internal int it; @@ -309,7 +309,7 @@ typedef struct tagDBPROP { internal interface ItagDBPROP { OleDbPropertyStatus dwStatus { get; } - object vValue { get; } + object? vValue { get; } int dwPropertyID { get; } } @@ -318,7 +318,7 @@ internal sealed class tagDBPROP_x86 : ItagDBPROP { OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus; - object ItagDBPROP.vValue => this.vValue; + object? ItagDBPROP.vValue => this.vValue; int ItagDBPROP.dwPropertyID => this.dwPropertyID; @@ -329,7 +329,7 @@ internal sealed class tagDBPROP_x86 : ItagDBPROP internal tagDBIDX columnid; // Variant - [MarshalAs(UnmanagedType.Struct)] internal object vValue; + [MarshalAs(UnmanagedType.Struct)] internal object? vValue; internal tagDBPROP_x86() { @@ -348,7 +348,7 @@ internal sealed class tagDBPROP : ItagDBPROP { OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus; - object ItagDBPROP.vValue => this.vValue; + object? ItagDBPROP.vValue => this.vValue; int ItagDBPROP.dwPropertyID => this.dwPropertyID; internal int dwPropertyID; @@ -358,7 +358,7 @@ internal sealed class tagDBPROP : ItagDBPROP internal tagDBIDX columnid; // Variant - [MarshalAs(UnmanagedType.Struct)] internal object vValue; + [MarshalAs(UnmanagedType.Struct)] internal object? vValue; internal tagDBPROP() { @@ -416,7 +416,7 @@ typedef struct tagDBCOLUMNINFO { internal sealed class tagDBCOLUMNINFO { [MarshalAs(UnmanagedType.LPWStr)] - internal string pwszName = null; + internal string? pwszName = null; //[MarshalAs(UnmanagedType.Interface)] internal IntPtr pTypeInfo = (IntPtr)0; @@ -493,8 +493,8 @@ internal interface ItagDBPROPINFO int dwPropertyID { get; } int dwFlags { get; } int vtType { get; } - object vValue { get; } - string pwszDescription { get; } + object? vValue { get; } + string? pwszDescription { get; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] @@ -506,18 +506,18 @@ internal sealed class tagDBPROPINFO_x86 : ItagDBPROPINFO int ItagDBPROPINFO.vtType => this.vtType; - object ItagDBPROPINFO.vValue => this.vValue; + object? ItagDBPROPINFO.vValue => this.vValue; - string ItagDBPROPINFO.pwszDescription => this.pwszDescription; + string? ItagDBPROPINFO.pwszDescription => this.pwszDescription; - [MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription; + [MarshalAs(UnmanagedType.LPWStr)] internal string? pwszDescription; internal int dwPropertyID; internal int dwFlags; internal short vtType; - [MarshalAs(UnmanagedType.Struct)] internal object vValue; + [MarshalAs(UnmanagedType.Struct)] internal object? vValue; internal tagDBPROPINFO_x86() { @@ -533,17 +533,17 @@ internal sealed class tagDBPROPINFO : ItagDBPROPINFO int ItagDBPROPINFO.vtType => this.vtType; - object ItagDBPROPINFO.vValue => this.vValue; + object? ItagDBPROPINFO.vValue => this.vValue; - string ItagDBPROPINFO.pwszDescription => this.pwszDescription; - [MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription; + string? ItagDBPROPINFO.pwszDescription => this.pwszDescription; + [MarshalAs(UnmanagedType.LPWStr)] internal string? pwszDescription; internal int dwPropertyID; internal int dwFlags; internal short vtType; - [MarshalAs(UnmanagedType.Struct)] internal object vValue; + [MarshalAs(UnmanagedType.Struct)] internal object? vValue; internal tagDBPROPINFO() { diff --git a/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs b/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs index 9dbd11d705a2..d8712488698e 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs @@ -11,11 +11,11 @@ namespace System.Data.OleDb { public sealed class OleDbTransaction : DbTransaction { - private readonly OleDbTransaction _parentTransaction; // strong reference to keep parent alive + private readonly OleDbTransaction? _parentTransaction; // strong reference to keep parent alive private readonly System.Data.IsolationLevel _isolationLevel; - private WeakReference _nestedTransaction; // child transactions - private WrappedTransaction _transaction; + private WeakReference? _nestedTransaction; // child transactions + private WrappedTransaction? _transaction; internal OleDbConnection _parentConnection; @@ -114,7 +114,7 @@ protected override bool ReleaseHandle() } } - internal OleDbTransaction(OleDbConnection connection, OleDbTransaction transaction, IsolationLevel isolevel) + internal OleDbTransaction(OleDbConnection connection, OleDbTransaction? transaction, IsolationLevel isolevel) { _parentConnection = connection; _parentTransaction = transaction; @@ -165,7 +165,7 @@ public override IsolationLevel IsolationLevel } } - internal OleDbTransaction Parent + internal OleDbTransaction? Parent { get { @@ -188,7 +188,7 @@ public OleDbTransaction Begin(IsolationLevel isolevel) OleDbTransaction transaction = new OleDbTransaction(_parentConnection, this, isolevel); _nestedTransaction = new WeakReference(transaction, false); - UnsafeNativeMethods.ITransactionLocal wrapper = null; + UnsafeNativeMethods.ITransactionLocal? wrapper = null; try { wrapper = (UnsafeNativeMethods.ITransactionLocal)_transaction.ComWrapper(); @@ -238,7 +238,7 @@ private void CommitInternal() } if (null != _nestedTransaction) { - OleDbTransaction transaction = (OleDbTransaction)_nestedTransaction.Target; + OleDbTransaction? transaction = (OleDbTransaction?)_nestedTransaction.Target; if ((null != transaction) && _nestedTransaction.IsAlive) { transaction.CommitInternal(); @@ -291,12 +291,12 @@ private void DisposeManaged() { _parentConnection.LocalTransaction = null; } - _parentConnection = null; + _parentConnection = null!; } private void ProcessResults(OleDbHResult hr) { - Exception e = OleDbConnection.ProcessResults(hr, _parentConnection, this); + Exception? e = OleDbConnection.ProcessResults(hr, _parentConnection, this); if (null != e) { throw e; } } @@ -319,7 +319,7 @@ internal OleDbHResult RollbackInternal(bool exceptionHandling) { if (null != _nestedTransaction) { - OleDbTransaction transaction = (OleDbTransaction)_nestedTransaction.Target; + OleDbTransaction? transaction = (OleDbTransaction?)_nestedTransaction.Target; if ((null != transaction) && _nestedTransaction.IsAlive) { hr = transaction.RollbackInternal(exceptionHandling); @@ -353,7 +353,7 @@ internal static OleDbTransaction TransactionLast(OleDbTransaction head) { if (null != head._nestedTransaction) { - OleDbTransaction current = (OleDbTransaction)head._nestedTransaction.Target; + OleDbTransaction? current = (OleDbTransaction?)head._nestedTransaction.Target; if ((null != current) && head._nestedTransaction.IsAlive) { return TransactionLast(current); @@ -362,7 +362,7 @@ internal static OleDbTransaction TransactionLast(OleDbTransaction head) return head; } - internal static OleDbTransaction TransactionUpdate(OleDbTransaction transaction) + internal static OleDbTransaction? TransactionUpdate(OleDbTransaction? transaction) { if ((null != transaction) && (null == transaction._transaction)) { diff --git a/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs b/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs index 19e66808fd25..23ef6c6b0d49 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs @@ -17,10 +17,10 @@ internal sealed class OleDbServicesWrapper : WrappedIUnknown // since we only have one DataLinks object, caching the delegate here is valid as long we // maintain an AddRef which is also the lifetime of this class instance - private readonly UnsafeNativeMethods.IDataInitializeGetDataSource DangerousIDataInitializeGetDataSource; + private readonly UnsafeNativeMethods.IDataInitializeGetDataSource? DangerousIDataInitializeGetDataSource; // DataLinks (the unknown parameter) is created via Activator.CreateInstance outside of the SafeHandle - internal OleDbServicesWrapper(object unknown) : base() + internal OleDbServicesWrapper(object? unknown) : base() { if (null != unknown) { @@ -44,7 +44,7 @@ internal OleDbServicesWrapper(object unknown) : base() internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper datasrcWrapper) { OleDbHResult hr; - UnsafeNativeMethods.IDataInitializeGetDataSource GetDataSource = DangerousIDataInitializeGetDataSource; + UnsafeNativeMethods.IDataInitializeGetDataSource GetDataSource = DangerousIDataInitializeGetDataSource!; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try @@ -52,7 +52,7 @@ internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper DangerousAddRef(ref mustRelease); // this is the string that DataLinks / OLE DB Services will use to create the provider - string connectionString = constr.ActualConnectionString; + string connectionString = constr.ActualConnectionString!; // base.handle is the 'this' pointer for making the COM call to GetDataSource // the datasrcWrapper will store the IID_IDBInitialize pointer @@ -72,7 +72,7 @@ internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper { throw ODB.ProviderUnavailable(constr.Provider, null); } - Exception e = OleDbConnection.ProcessResults(hr, null, null); + Exception? e = OleDbConnection.ProcessResults(hr, null, null); Debug.Assert(null != e, "CreateProviderError"); throw e; } @@ -113,7 +113,7 @@ internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, r IntPtr method = Marshal.ReadIntPtr(vtable, 0); // we cache the QueryInterface delegate to prevent recreating it on every call - UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = constr.DangerousDataSourceIUnknownQueryInterface; + UnsafeNativeMethods.IUnknownQueryInterface? QueryInterface = constr.DangerousDataSourceIUnknownQueryInterface; // since the delegate lifetime is longer than the original instance used to create it // we double check before each usage to verify the delegates function pointer @@ -130,7 +130,7 @@ internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, r method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size); // Initialize is the 4'th vtable entry // we cache the Initialize delegate to prevent recreating it on every call - UnsafeNativeMethods.IDBInitializeInitialize Initialize = constr.DangerousIDBInitializeInitialize; + UnsafeNativeMethods.IDBInitializeInitialize? Initialize = constr.DangerousIDBInitializeInitialize; // since the delegate lifetime is longer than the original instance used to create it // we double check before each usage to verify the delegates function pointer @@ -156,7 +156,7 @@ internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, r vtable = Marshal.ReadIntPtr(idbCreateSession, 0); method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size); // CreateSession is the 4'th vtable entry - UnsafeNativeMethods.IDBCreateSessionCreateSession CreateSession = constr.DangerousIDBCreateSessionCreateSession; + UnsafeNativeMethods.IDBCreateSessionCreateSession? CreateSession = constr.DangerousIDBCreateSessionCreateSession; // since the delegate lifetime is longer than the original instance used to create it // we double check before each usage to verify the delegates function pointer @@ -227,7 +227,7 @@ internal sealed class SessionWrapper : WrappedIUnknown // we cache the DangerousIDBCreateCommandCreateCommand (expecting base.handle to be IDBCreateCommand) // since we maintain an AddRef on IDBCreateCommand it is safe to use the delegate without rechecking its function pointer - private UnsafeNativeMethods.IDBCreateCommandCreateCommand DangerousIDBCreateCommandCreateCommand; + private UnsafeNativeMethods.IDBCreateCommandCreateCommand? DangerousIDBCreateCommandCreateCommand; internal SessionWrapper() : base() { @@ -319,11 +319,11 @@ internal void VerifyIDBCreateCommand(OleDbConnectionString constr) DangerousIDBCreateCommandCreateCommand = CreateCommand; } - internal OleDbHResult CreateCommand(ref object icommandText) + internal OleDbHResult CreateCommand(ref object? icommandText) { // if (null == CreateCommand), the IDBCreateCommand isn't supported - aka E_NOINTERFACE OleDbHResult hr = OleDbHResult.E_NOINTERFACE; - UnsafeNativeMethods.IDBCreateCommandCreateCommand CreateCommand = DangerousIDBCreateCommandCreateCommand; + UnsafeNativeMethods.IDBCreateCommandCreateCommand? CreateCommand = DangerousIDBCreateCommandCreateCommand; if (null != CreateCommand) { bool mustRelease = false; @@ -362,7 +362,7 @@ internal ITransactionJoinWrapper ITransactionJoin(OleDbConnectionInternal connec } } - // unable to use generics bacause (unknown as T) doesn't compile + // unable to use generics because (unknown as T) doesn't compile internal struct IDBInfoWrapper : IDisposable { // _unknown must be tracked because the _value may not exist, @@ -373,7 +373,7 @@ internal struct IDBInfoWrapper : IDisposable internal IDBInfoWrapper(object unknown) { _unknown = unknown; - _value = (unknown as UnsafeNativeMethods.IDBInfo); + _value = (unknown as UnsafeNativeMethods.IDBInfo)!; } internal UnsafeNativeMethods.IDBInfo Value @@ -387,8 +387,8 @@ internal UnsafeNativeMethods.IDBInfo Value public void Dispose() { object unknown = _unknown; - _unknown = null; - _value = null; + _unknown = null!; + _value = null!; if (null != unknown) { Marshal.ReleaseComObject(unknown); @@ -404,7 +404,7 @@ internal struct IDBPropertiesWrapper : IDisposable internal IDBPropertiesWrapper(object unknown) { _unknown = unknown; - _value = (unknown as UnsafeNativeMethods.IDBProperties); + _value = (unknown as UnsafeNativeMethods.IDBProperties)!; Debug.Assert(null != _value, "null IDBProperties"); } @@ -420,8 +420,8 @@ internal UnsafeNativeMethods.IDBProperties Value public void Dispose() { object unknown = _unknown; - _unknown = null; - _value = null; + _unknown = null!; + _value = null!; if (null != unknown) { Marshal.ReleaseComObject(unknown); @@ -437,7 +437,7 @@ internal struct IDBSchemaRowsetWrapper : IDisposable internal IDBSchemaRowsetWrapper(object unknown) { _unknown = unknown; - _value = (unknown as UnsafeNativeMethods.IDBSchemaRowset); + _value = (unknown as UnsafeNativeMethods.IDBSchemaRowset)!; } internal UnsafeNativeMethods.IDBSchemaRowset Value @@ -451,8 +451,8 @@ internal UnsafeNativeMethods.IDBSchemaRowset Value public void Dispose() { object unknown = _unknown; - _unknown = null; - _value = null; + _unknown = null!; + _value = null!; if (null != unknown) { Marshal.ReleaseComObject(unknown); @@ -468,7 +468,7 @@ internal struct IOpenRowsetWrapper : IDisposable internal IOpenRowsetWrapper(object unknown) { _unknown = unknown; - _value = (unknown as UnsafeNativeMethods.IOpenRowset); + _value = (unknown as UnsafeNativeMethods.IOpenRowset)!; Debug.Assert(null != _value, "null IOpenRowsetWrapper"); } @@ -484,8 +484,8 @@ internal UnsafeNativeMethods.IOpenRowset Value public void Dispose() { object unknown = _unknown; - _unknown = null; - _value = null; + _unknown = null!; + _value = null!; if (null != unknown) { Marshal.ReleaseComObject(unknown); @@ -501,7 +501,7 @@ internal struct ITransactionJoinWrapper : IDisposable internal ITransactionJoinWrapper(object unknown) { _unknown = unknown; - _value = (unknown as NativeMethods.ITransactionJoin); + _value = (unknown as NativeMethods.ITransactionJoin)!; } internal NativeMethods.ITransactionJoin Value @@ -515,8 +515,8 @@ internal NativeMethods.ITransactionJoin Value public void Dispose() { object unknown = _unknown; - _unknown = null; - _value = null; + _unknown = null!; + _value = null!; if (null != unknown) { Marshal.ReleaseComObject(unknown); diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Enum.cs b/src/libraries/System.Data.OleDb/src/OleDb_Enum.cs index e2e491501488..b1c7664c3c58 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Enum.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Enum.cs @@ -178,7 +178,7 @@ internal sealed class NativeDBType internal readonly DbType enumDbType; // enum System.Data.DbType internal readonly short dbType; // OLE DB DBTYPE_ internal readonly short wType; // OLE DB DBTYPE_ we ask OleDB Provider to bind as - internal readonly Type dataType; // CLR Type + internal readonly Type? dataType; // CLR Type internal readonly int dbPart; // the DBPart w or w/out length internal readonly bool isfixed; // IsFixedLength @@ -189,7 +189,7 @@ internal sealed class NativeDBType internal readonly string dataSourceType; // ICommandWithParameters.SetParameterInfo standard type name internal readonly StringMemHandle dbString; // ptr to native allocated memory for dataSourceType string - private NativeDBType(byte maxpre, int fixlen, bool isfixed, bool islong, OleDbType enumOleDbType, short dbType, string dbstring, Type dataType, short wType, DbType enumDbType) + private NativeDBType(byte maxpre, int fixlen, bool isfixed, bool islong, OleDbType enumOleDbType, short dbType, string dbstring, Type? dataType, short wType, DbType enumDbType) { this.enumOleDbType = enumOleDbType; this.dbType = dbType; @@ -265,7 +265,7 @@ internal static NativeDBType FromDataType(OleDbType enumOleDbType) => internal static NativeDBType FromSystemType(object value) { - IConvertible ic = (value as IConvertible); + IConvertible? ic = (value as IConvertible); if (null != ic) { return ic.GetTypeCode() switch diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index 5d125952f194..b0a39dea96c7 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs @@ -92,7 +92,7 @@ internal static Exception BadStatus_ParamAcc(int index, DBBindStatus status) { return ADP.DataAdapter(SR.Format(SR.OleDb_BadStatus_ParamAcc, index.ToString(CultureInfo.InvariantCulture), status.ToString())); } - internal static Exception NoProviderSupportForParameters(string provider, Exception inner) + internal static Exception NoProviderSupportForParameters(string provider, Exception? inner) { return ADP.DataAdapter(SR.Format(SR.OleDb_NoProviderSupportForParameters, provider), inner); } @@ -174,7 +174,7 @@ internal static ArgumentException SchemaRowsetsNotSupported(string provider) { return ADP.Argument(SR.Format(SR.OleDb_SchemaRowsetsNotSupported, "IDBSchemaRowset", provider)); } - internal static OleDbException NoErrorInformation(string provider, OleDbHResult hr, Exception inner) + internal static OleDbException NoErrorInformation(string? provider, OleDbHResult hr, Exception? inner) { OleDbException e; if (!ADP.IsEmpty(provider)) @@ -188,7 +188,7 @@ internal static OleDbException NoErrorInformation(string provider, OleDbHResult ADP.TraceExceptionAsReturnValue(e); return e; } - internal static InvalidOperationException MDACNotAvailable(Exception inner) + internal static InvalidOperationException MDACNotAvailable(Exception? inner) { return ADP.DataAdapter(SR.Format(SR.OleDb_MDACNotAvailable), inner); } @@ -196,7 +196,7 @@ internal static ArgumentException MSDASQLNotSupported() { return ADP.Argument(SR.Format(SR.OleDb_MSDASQLNotSupported)); } - internal static InvalidOperationException CommandTextNotSupported(string provider, Exception inner) + internal static InvalidOperationException CommandTextNotSupported(string provider, Exception? inner) { return ADP.DataAdapter(SR.Format(SR.OleDb_CommandTextNotSupported, provider), inner); } @@ -204,12 +204,12 @@ internal static InvalidOperationException PossiblePromptNotUserInteractive() { return ADP.DataAdapter(SR.Format(SR.OleDb_PossiblePromptNotUserInteractive)); } - internal static InvalidOperationException ProviderUnavailable(string provider, Exception inner) + internal static InvalidOperationException ProviderUnavailable(string provider, Exception? inner) { //return new OleDbException(SR.Format(SR.OleDb_ProviderUnavailable, provider), (int)OleDbHResult.CO_E_CLASSSTRING, inner); return ADP.DataAdapter(SR.Format(SR.OleDb_ProviderUnavailable, provider), inner); } - internal static InvalidOperationException TransactionsNotSupported(string provider, Exception inner) + internal static InvalidOperationException TransactionsNotSupported(string provider, Exception? inner) { return ADP.DataAdapter(SR.Format(SR.OleDb_TransactionsNotSupported, provider), inner); } @@ -707,7 +707,7 @@ internal static string ELookup(OleDbHResult hr) private static readonly Hashtable g_wlookpup = new Hashtable(); internal static string WLookup(short id) { - string value = (string)g_wlookpup[id]; + string? value = (string?)g_wlookpup[id]; if (null == value) { value = "0x" + ((short)id).ToString("X2", CultureInfo.InvariantCulture) + " " + ((short)id); diff --git a/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs b/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs index 60690d084bbe..60b44bab7de4 100644 --- a/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs +++ b/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs @@ -13,15 +13,15 @@ internal sealed class OleDbPropertyInfo { public Guid _propertySet; public int _propertyID; - public string _description; - public string _lowercase; - public Type _type; + public string? _description; + public string? _lowercase; + public Type? _type; public int _flags; public int _vtype; - public object _supportedValues; + public object? _supportedValues; - public object _defaultValue; + public object? _defaultValue; } internal sealed class PropertyInfoSet : SafeHandle @@ -54,9 +54,9 @@ public override bool IsInvalid } } - internal Dictionary GetValues() + internal Dictionary? GetValues() { - Dictionary propertyLookup = null; + Dictionary? propertyLookup = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); @@ -88,7 +88,7 @@ internal Dictionary GetValues() propertyInfo._vtype = propinfo.vtType; propertyInfo._supportedValues = propinfo.vValue; propertyInfo._description = propinfo.pwszDescription; - propertyInfo._lowercase = propinfo.pwszDescription.ToLowerInvariant(); + propertyInfo._lowercase = propinfo.pwszDescription!.ToLowerInvariant(); propertyInfo._type = PropertyInfoSet.FromVtType(propinfo.vtType); propertyLookup[propertyInfo._lowercase] = propertyInfo; @@ -142,7 +142,7 @@ protected override bool ReleaseHandle() return true; } - internal static Type FromVtType(int vartype) => + internal static Type? FromVtType(int vartype) => (VarEnum)vartype switch { VarEnum.VT_EMPTY => null, diff --git a/src/libraries/System.Data.OleDb/src/RowBinding.cs b/src/libraries/System.Data.OleDb/src/RowBinding.cs index fbbd25154651..7f94bf563d5f 100644 --- a/src/libraries/System.Data.OleDb/src/RowBinding.cs +++ b/src/libraries/System.Data.OleDb/src/RowBinding.cs @@ -15,7 +15,7 @@ internal sealed class RowBinding : System.Data.ProviderBase.DbBuffer private readonly int _dataLength; private readonly int _emptyStringOffset; - private UnsafeNativeMethods.IAccessor _iaccessor; + private UnsafeNativeMethods.IAccessor? _iaccessor; private IntPtr _accessorHandle; private readonly bool _needToReset; @@ -117,9 +117,9 @@ internal OleDbHResult CreateAccessor(UnsafeNativeMethods.IAccessor iaccessor, in return hr; } - internal ColumnBinding[] SetBindings(OleDbDataReader dataReader, Bindings bindings, + internal ColumnBinding[] SetBindings(OleDbDataReader? dataReader, Bindings bindings, int indexStart, int indexForAccessor, - OleDbParameter[] parameters, tagDBBINDING[] dbbindings, bool ifIRowsetElseIRow) + OleDbParameter[]? parameters, tagDBBINDING[] dbbindings, bool ifIRowsetElseIRow) { Debug.Assert(null != bindings, "null bindings"); Debug.Assert(dbbindings.Length == BindingCount(), "count mismatch"); @@ -150,9 +150,9 @@ internal ColumnBinding[] SetBindings(OleDbDataReader dataReader, Bindings bindin for (int indexWithinAccessor = 0; indexWithinAccessor < columns.Length; ++indexWithinAccessor) { int index = indexStart + indexWithinAccessor; - OleDbParameter parameter = ((null != parameters) ? parameters[index] : null); + OleDbParameter? parameter = ((null != parameters) ? parameters[index] : null); columns[indexWithinAccessor] = new ColumnBinding( - dataReader, index, indexForAccessor, indexWithinAccessor, + dataReader!, index, indexForAccessor, indexWithinAccessor, parameter, this, bindings, dbbindings[indexWithinAccessor], _headerLength, ifIRowsetElseIRow); } @@ -172,7 +172,7 @@ internal object GetVariantValue(int offset) Debug.Assert(0 == offset % 8, "invalid alignment"); ValidateCheck(offset, 2 * ODB.SizeOf_Variant); - object value = null; + object? value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try @@ -320,7 +320,7 @@ internal void CloseFromConnection() { ResetValues(); - UnsafeNativeMethods.IAccessor iaccessor = _iaccessor; + UnsafeNativeMethods.IAccessor? iaccessor = _iaccessor; IntPtr accessorHandle = _accessorHandle; _iaccessor = null; @@ -393,7 +393,7 @@ internal void ResetValues() #endif } - private unsafe void ResetValues(IntPtr buffer, object iaccessor) + private unsafe void ResetValues(IntPtr buffer, object? iaccessor) { Debug.Assert(ADP.PtrZero != buffer && _needToReset && _haveData, "shouldn't be calling ResetValues"); for (int i = 0; i < _bindingCount; ++i) @@ -473,7 +473,7 @@ private static void FreeChapter(IntPtr buffer, int valueOffset, object iaccessor { Debug.Assert(0 == valueOffset % 8, "unexpected unaligned ptr offset"); - UnsafeNativeMethods.IChapteredRowset chapteredRowset = (iaccessor as UnsafeNativeMethods.IChapteredRowset); + UnsafeNativeMethods.IChapteredRowset chapteredRowset = (iaccessor as UnsafeNativeMethods.IChapteredRowset)!; IntPtr chapter = SafeNativeMethods.InterlockedExchangePointer(ADP.IntPtrOffset(buffer, valueOffset), ADP.PtrZero); if (ODB.DB_NULL_HCHAPTER != chapter) { diff --git a/src/libraries/System.Data.OleDb/src/SafeHandles.cs b/src/libraries/System.Data.OleDb/src/SafeHandles.cs index bd26b91d9d3b..185712be565c 100644 --- a/src/libraries/System.Data.OleDb/src/SafeHandles.cs +++ b/src/libraries/System.Data.OleDb/src/SafeHandles.cs @@ -21,7 +21,7 @@ private DualCoTaskMem() : base(IntPtr.Zero, true) } // IDBInfo.GetLiteralInfo - internal DualCoTaskMem(UnsafeNativeMethods.IDBInfo dbInfo, int[] literals, out int literalCount, out IntPtr literalInfo, out OleDbHResult hr) : this() + internal DualCoTaskMem(UnsafeNativeMethods.IDBInfo dbInfo, int[]? literals, out int literalCount, out IntPtr literalInfo, out OleDbHResult hr) : this() { int count = (null != literals) ? literals.Length : 0; hr = dbInfo.GetLiteralInfo(count, literals, out literalCount, out base.handle, out this.handle2); @@ -93,7 +93,7 @@ internal IntPtr GetRowHandle(int index) internal sealed class StringMemHandle : DbBuffer { - internal StringMemHandle(string value) : base((null != value) ? checked(2 + 2 * value.Length) : 0) + internal StringMemHandle(string? value) : base((null != value) ? checked(2 + 2 * value.Length) : 0) { if (null != value) { @@ -128,7 +128,7 @@ internal static ChapterHandle CreateChapterHandle(IntPtr chapter) } // from ADODBRecordSetConstruction we do not want to release the initial chapter handle - private ChapterHandle(IntPtr chapter) : base((object)null) + private ChapterHandle(IntPtr chapter) : base((object?)null) { _chapterHandle = chapter; } @@ -665,7 +665,7 @@ internal static unsafe OleDbHResult IChapteredRowsetReleaseChapter(System.IntPtr { OleDbHResult hr = OleDbHResult.E_UNEXPECTED; IntPtr hchapter = chapter; - System.Data.Common.UnsafeNativeMethods.IChapteredRowset chapteredRowset = null; + System.Data.Common.UnsafeNativeMethods.IChapteredRowset? chapteredRowset = null; RuntimeHelpers.PrepareConstrainedRegions(); try { } @@ -687,7 +687,7 @@ internal static unsafe OleDbHResult IChapteredRowsetReleaseChapter(System.IntPtr internal static unsafe OleDbHResult ITransactionAbort(System.IntPtr ptr) { OleDbHResult hr = OleDbHResult.E_UNEXPECTED; - ITransactionLocal transactionLocal = null; + ITransactionLocal? transactionLocal = null; RuntimeHelpers.PrepareConstrainedRegions(); try { } @@ -709,7 +709,7 @@ internal static unsafe OleDbHResult ITransactionAbort(System.IntPtr ptr) internal static unsafe OleDbHResult ITransactionCommit(System.IntPtr ptr) { OleDbHResult hr = OleDbHResult.E_UNEXPECTED; - ITransactionLocal transactionLocal = null; + ITransactionLocal? transactionLocal = null; RuntimeHelpers.PrepareConstrainedRegions(); try { } diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj index 815959031dba..d3029f06d56d 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -3,6 +3,7 @@ true netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT true + enable diff --git a/src/libraries/System.Data.OleDb/src/System/Data/Common/AdapterUtil.cs b/src/libraries/System.Data.OleDb/src/System/Data/Common/AdapterUtil.cs index 2bb8e85534f7..f5bacfd62391 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/Common/AdapterUtil.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/Common/AdapterUtil.cs @@ -6,6 +6,7 @@ using System.Configuration; using System.Data.SqlTypes; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.Versioning; @@ -66,13 +67,13 @@ internal static ArgumentException Argument(string error) TraceExceptionAsReturnValue(e); return e; } - internal static ArgumentException Argument(string error, Exception inner) + internal static ArgumentException Argument(string error, Exception? inner) { ArgumentException e = new ArgumentException(error, inner); TraceExceptionAsReturnValue(e); return e; } - internal static ArgumentException Argument(string error, string parameter) + internal static ArgumentException Argument(string error, string? parameter) { ArgumentException e = new ArgumentException(error, parameter); TraceExceptionAsReturnValue(e); @@ -118,7 +119,7 @@ internal static InvalidCastException InvalidCast(string error) { return InvalidCast(error, null); } - internal static InvalidCastException InvalidCast(string error, Exception inner) + internal static InvalidCastException InvalidCast(string error, Exception? inner) { InvalidCastException e = new InvalidCastException(error, inner); TraceExceptionAsReturnValue(e); @@ -136,7 +137,7 @@ internal static TimeoutException TimeoutException(string error) TraceExceptionAsReturnValue(e); return e; } - internal static InvalidOperationException InvalidOperation(string error, Exception inner) + internal static InvalidOperationException InvalidOperation(string error, Exception? inner) { InvalidOperationException e = new InvalidOperationException(error, inner); TraceExceptionAsReturnValue(e); @@ -158,7 +159,7 @@ internal static InvalidOperationException DataAdapter(string error) { return InvalidOperation(error); } - internal static InvalidOperationException DataAdapter(string error, Exception inner) + internal static InvalidOperationException DataAdapter(string error, Exception? inner) { return InvalidOperation(error, inner); } @@ -366,7 +367,7 @@ internal static InvalidOperationException InvalidDataDirectory() { return ADP.InvalidOperation(SR.GetString(SR.ADP_InvalidDataDirectory)); } - internal static ArgumentException InvalidKeyname(string parameterName) + internal static ArgumentException InvalidKeyname(string? parameterName) { return Argument(SR.GetString(SR.ADP_InvalidKey), parameterName); } @@ -376,7 +377,7 @@ internal static ArgumentException InvalidValue(string parameterName) } internal static ArgumentException ConvertFailed(Type fromType, Type toType, Exception innerException) { - return ADP.Argument(SR.GetString(SR.SqlConvert_ConvertFailed, fromType.FullName, toType.FullName), innerException); + return ADP.Argument(SR.GetString(SR.SqlConvert_ConvertFailed, fromType.FullName!, toType.FullName!), innerException); } // @@ -424,7 +425,7 @@ internal static Exception InvalidConnectionOptionValue(string key) { return InvalidConnectionOptionValue(key, null); } - internal static Exception InvalidConnectionOptionValue(string key, Exception inner) + internal static Exception InvalidConnectionOptionValue(string key, Exception? inner) { return Argument(SR.GetString(SR.ADP_InvalidConnectionOptionValue, key), inner); } @@ -509,7 +510,7 @@ internal static Exception OpenReaderExists() return OpenReaderExists(null); } - internal static Exception OpenReaderExists(Exception e) + internal static Exception OpenReaderExists(Exception? e) { return InvalidOperation(SR.GetString(SR.ADP_OpenReaderExists), e); } @@ -698,7 +699,7 @@ internal static ArgumentException DbTypeNotSupported(System.Data.DbType type, Ty } internal static ArgumentException UnknownDataTypeCode(Type dataType, TypeCode typeCode) { - return Argument(SR.GetString(SR.ADP_UnknownDataTypeCode, ((int)typeCode).ToString(CultureInfo.InvariantCulture), dataType.FullName)); + return Argument(SR.GetString(SR.ADP_UnknownDataTypeCode, ((int)typeCode).ToString(CultureInfo.InvariantCulture), dataType.FullName!)); } internal static ArgumentException InvalidOffsetValue(int value) { @@ -909,7 +910,7 @@ internal static bool CompareInsensitiveInvariant(string strvalue, string strcons return (0 == CultureInfo.InvariantCulture.CompareInfo.Compare(strvalue, strconst, CompareOptions.IgnoreCase)); } - internal static Delegate FindBuilder(MulticastDelegate mcd) + internal static Delegate? FindBuilder(MulticastDelegate? mcd) { // V1.2.3300 if (null != mcd) { @@ -927,20 +928,20 @@ internal static Delegate FindBuilder(MulticastDelegate mcd) internal static readonly bool IsWindowsNT = (PlatformID.Win32NT == Environment.OSVersion.Platform); internal static readonly bool IsPlatformNT5 = (ADP.IsWindowsNT && (Environment.OSVersion.Version.Major >= 5)); - internal static SysTx.Transaction GetCurrentTransaction() + internal static SysTx.Transaction? GetCurrentTransaction() { - SysTx.Transaction transaction = SysTx.Transaction.Current; + SysTx.Transaction? transaction = SysTx.Transaction.Current; return transaction; } - internal static void SetCurrentTransaction(SysTx.Transaction transaction) + internal static void SetCurrentTransaction(SysTx.Transaction? transaction) { SysTx.Transaction.Current = transaction; } - internal static SysTx.IDtcTransaction GetOletxTransaction(SysTx.Transaction transaction) + internal static SysTx.IDtcTransaction? GetOletxTransaction(SysTx.Transaction? transaction) { - SysTx.IDtcTransaction oleTxTransaction = null; + SysTx.IDtcTransaction? oleTxTransaction = null; if (null != transaction) { @@ -1092,11 +1093,11 @@ internal static Stream GetXmlStream(string value, string errorString) } - internal static object ClassesRootRegistryValue(string subkey, string queryvalue) + internal static object? ClassesRootRegistryValue(string subkey, string queryvalue) { try { - using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(subkey, false)) + using (RegistryKey? key = Registry.ClassesRoot.OpenSubKey(subkey, false)) { return ((null != key) ? key.GetValue(queryvalue) : null); } @@ -1110,11 +1111,11 @@ internal static object ClassesRootRegistryValue(string subkey, string queryvalue } } - internal static object LocalMachineRegistryValue(string subkey, string queryvalue) + internal static object? LocalMachineRegistryValue(string subkey, string queryvalue) { try { - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subkey, false)) + using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(subkey, false)) { return ((null != key) ? key.GetValue(queryvalue) : null); } @@ -1132,14 +1133,14 @@ internal static object LocalMachineRegistryValue(string subkey, string queryvalu internal static void CheckVersionMDAC(bool ifodbcelseoledb) { int major, minor, build; - string version; + string? version; try { - version = (string)ADP.LocalMachineRegistryValue("Software\\Microsoft\\DataAccess", "FullInstallVer"); + version = (string?)ADP.LocalMachineRegistryValue("Software\\Microsoft\\DataAccess", "FullInstallVer"); if (ADP.IsEmpty(version)) { - string filename = (string)ADP.ClassesRootRegistryValue(System.Data.OleDb.ODB.DataLinks_CLSID, string.Empty); + string filename = (string)ADP.ClassesRootRegistryValue(System.Data.OleDb.ODB.DataLinks_CLSID, string.Empty)!; FileVersionInfo versionInfo = ADP.GetVersionInfo(filename); major = versionInfo.FileMajorPart; minor = versionInfo.FileMinorPart; @@ -1183,7 +1184,7 @@ internal static void CheckVersionMDAC(bool ifodbcelseoledb) // the return value is true if the string was quoted and false if it was not // this allows the caller to determine if it is an error or not for the quotedString to not be quoted - internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, string quotedString, out string unquotedString) + internal static bool RemoveStringQuotes(string? quotePrefix, string? quoteSuffix, string? quotedString, out string? unquotedString) { int prefixLength; if (quotePrefix == null) @@ -1229,7 +1230,7 @@ internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, // is the prefix present? if (prefixLength > 0) { - if (quotedString.StartsWith(quotePrefix, StringComparison.Ordinal) == false) + if (quotedString.StartsWith(quotePrefix!, StringComparison.Ordinal) == false) { unquotedString = quotedString; return false; @@ -1239,7 +1240,7 @@ internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, // is the suffix present? if (suffixLength > 0) { - if (quotedString.EndsWith(quoteSuffix, StringComparison.Ordinal) == false) + if (quotedString.EndsWith(quoteSuffix!, StringComparison.Ordinal) == false) { unquotedString = quotedString; return false; @@ -1279,12 +1280,12 @@ internal static int IntPtrToInt32(IntPtr value) } // TODO: are those names appropriate for common code? - internal static int SrcCompare(string strA, string strB) + internal static int SrcCompare(string? strA, string? strB) { // this is null safe return ((strA == strB) ? 0 : 1); } - internal static int DstCompare(string strA, string strB) + internal static int DstCompare(string? strA, string? strB) { // this is null safe return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, ADP.compareOptions); } @@ -1312,23 +1313,23 @@ private static void IsDirectionValid(ParameterDirection value) } #endif - internal static bool IsEmpty(string str) + internal static bool IsEmpty([NotNullWhen(false)] string? str) { return ((null == str) || (0 == str.Length)); } - internal static bool IsEmptyArray(string[] array) + internal static bool IsEmptyArray([NotNullWhen(false)] string?[]? array) { return ((null == array) || (0 == array.Length)); } - internal static bool IsNull(object value) + internal static bool IsNull([NotNullWhen(false)] object? value) { if ((null == value) || (DBNull.Value == value)) { return true; } - INullable nullable = (value as INullable); + INullable? nullable = (value as INullable); return ((null != nullable) && nullable.IsNull); } } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/Common/DbConnectionPoolKey.cs b/src/libraries/System.Data.OleDb/src/System/Data/Common/DbConnectionPoolKey.cs index 011e9d871a0a..80252bde49e8 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/Common/DbConnectionPoolKey.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/Common/DbConnectionPoolKey.cs @@ -10,9 +10,9 @@ namespace System.Data.Common // Only connection string is used as a key internal class DbConnectionPoolKey : ICloneable { - private string _connectionString; + private string? _connectionString; - internal DbConnectionPoolKey(string connectionString) + internal DbConnectionPoolKey(string? connectionString) { _connectionString = connectionString; } @@ -27,7 +27,7 @@ object ICloneable.Clone() return new DbConnectionPoolKey(this); } - internal virtual string ConnectionString + internal virtual string? ConnectionString { get { @@ -40,14 +40,14 @@ internal virtual string ConnectionString } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null || obj.GetType() != typeof(DbConnectionPoolKey)) { return false; } - DbConnectionPoolKey key = obj as DbConnectionPoolKey; + DbConnectionPoolKey? key = obj as DbConnectionPoolKey; return (key != null && _connectionString == key._connectionString); } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/Common/FieldNameLookup.cs b/src/libraries/System.Data.OleDb/src/System/Data/Common/FieldNameLookup.cs index 32a4c27e59d8..918c3304fe60 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/Common/FieldNameLookup.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/Common/FieldNameLookup.cs @@ -12,14 +12,14 @@ internal sealed class FieldNameLookup { // V1.2.3300 // hashtable stores the index into the _fieldNames, match via case-sensitive - private Hashtable _fieldNameLookup; + private Hashtable? _fieldNameLookup; // original names for linear searches when exact matches fail private readonly string[] _fieldNames; // if _defaultLocaleID is -1 then _compareInfo is initialized with InvariantCulture CompareInfo // otherwise it is specified by the server? for the correct compare info - private CompareInfo _compareInfo; + private CompareInfo? _compareInfo; private readonly int _defaultLocaleID; public FieldNameLookup(IDataRecord reader, int defaultLocaleID) @@ -57,7 +57,7 @@ public int IndexOfName(string fieldName) GenerateLookup(); } // via case sensitive search, first match with lowest ordinal matches - object value = _fieldNameLookup[fieldName]; + object? value = _fieldNameLookup![fieldName]; return ((null != value) ? (int)value : -1); } @@ -68,7 +68,7 @@ public int IndexOf(string fieldName) GenerateLookup(); } int index; - object value = _fieldNameLookup[fieldName]; + object? value = _fieldNameLookup![fieldName]; if (null != value) { // via case sensitive search, first match with lowest ordinal matches @@ -89,7 +89,7 @@ public int IndexOf(string fieldName) private int LinearIndexOf(string fieldName, CompareOptions compareOptions) { - CompareInfo compareInfo = _compareInfo; + CompareInfo? compareInfo = _compareInfo; if (null == compareInfo) { if (-1 != _defaultLocaleID) @@ -107,7 +107,7 @@ private int LinearIndexOf(string fieldName, CompareOptions compareOptions) { if (0 == compareInfo.Compare(fieldName, _fieldNames[i], compareOptions)) { - _fieldNameLookup[fieldName] = i; // add an exact match for the future + _fieldNameLookup![fieldName] = i; // add an exact match for the future return i; } } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/Common/NameValuePair.cs b/src/libraries/System.Data.OleDb/src/System/Data/Common/NameValuePair.cs index 6b7887034b40..09ec22615fca 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/Common/NameValuePair.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/Common/NameValuePair.cs @@ -8,11 +8,11 @@ namespace System.Data.Common internal sealed class NameValuePair { private readonly string _name; - private readonly string _value; + private readonly string? _value; private readonly int _length; - private NameValuePair _next; + private NameValuePair? _next; - internal NameValuePair(string name, string value, int length) + internal NameValuePair(string name, string? value, int length) { Debug.Assert(!string.IsNullOrEmpty(name), "empty keyname"); _name = name; @@ -30,9 +30,9 @@ internal int Length } internal string Name => _name; - internal string Value => _value; + internal string? Value => _value; - internal NameValuePair Next + internal NameValuePair? Next { get { return _next; } set diff --git a/src/libraries/System.Data.OleDb/src/System/Data/Common/SR.cs b/src/libraries/System.Data.OleDb/src/System/Data/Common/SR.cs index 4212e8d0b1f1..b89c3c7c1ff4 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/Common/SR.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/Common/SR.cs @@ -10,7 +10,7 @@ internal static string GetString(string value) return value; } - internal static string GetString(string format, params object[] args) + internal static string GetString(string format, params object?[] args) { return SR.Format(format, args); } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs index b849aa34e3fa..dc0db72fa5c6 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs @@ -71,7 +71,7 @@ internal string PtrToStringUni(int offset, int length) Validate(offset, 2 * length); Debug.Assert(0 == offset % ADP.PtrSize, "invalid alignment"); - string value = null; + string? value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionClosed.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionClosed.cs index 8fd14e20d6ba..0d89234d92bc 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionClosed.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionClosed.cs @@ -23,7 +23,7 @@ public override string ServerVersion } } - protected override void Activate(SysTx.Transaction transaction) + protected override void Activate(SysTx.Transaction? transaction) { throw ADP.ClosedConnectionError(); } @@ -43,12 +43,12 @@ protected override void Deactivate() throw ADP.ClosedConnectionError(); } - public override void EnlistTransaction(SysTx.Transaction transaction) + public override void EnlistTransaction(SysTx.Transaction? transaction) { throw ADP.ClosedConnectionError(); } - protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) + protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string?[]? restrictions) { throw ADP.ClosedConnectionError(); } @@ -58,7 +58,7 @@ protected override DbReferenceCollection CreateReferenceCollection() throw ADP.ClosedConnectionError(); } - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { return base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions); } @@ -70,7 +70,7 @@ protected DbConnectionBusy(ConnectionState state) : base(state, true, false) { } - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { throw ADP.ConnectionAlreadyOpen(State); } @@ -111,7 +111,7 @@ internal override void CloseConnection(DbConnection owningObject, DbConnectionFa connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance); } - internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { if (retry == null || !retry.Task.IsCompleted) { diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionFactory.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionFactory.cs index 539ef470492f..d096b432bc80 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionFactory.cs @@ -23,8 +23,8 @@ internal abstract class DbConnectionFactory // s_pendingOpenNonPooled is an array of tasks used to throttle creation of non-pooled connections to // a maximum of Environment.ProcessorCount at a time. private static int s_pendingOpenNonPooledNext; - private static readonly Task[] s_pendingOpenNonPooled = new Task[Environment.ProcessorCount]; - private static Task s_completedTask; + private static readonly Task[] s_pendingOpenNonPooled = new Task[Environment.ProcessorCount]; + private static Task? s_completedTask; protected DbConnectionFactory() : this(DbConnectionPoolCountersNoCounters.SingletonInstance) { } @@ -68,13 +68,13 @@ protected virtual DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal i throw ADP.NotSupported(); } - internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) + internal DbConnectionInternal? CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions? userOptions) { Debug.Assert(null != owningConnection, "null owningConnection?"); Debug.Assert(null != poolGroup, "null poolGroup?"); DbConnectionOptions connectionOptions = poolGroup.ConnectionOptions; - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo; + DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo!; DbConnectionPoolKey poolKey = poolGroup.PoolKey; DbConnectionInternal newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions); @@ -86,10 +86,10 @@ internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConne return newConnection; } - internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) + internal DbConnectionInternal? CreatePooledConnection(DbConnectionPool pool, DbConnection? owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions? userOptions) { Debug.Assert(null != pool, "null pool?"); - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo; + DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo!; DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) @@ -100,7 +100,7 @@ internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbCo return newConnection; } - internal virtual DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions) + internal virtual DbConnectionPoolGroupProviderInfo? CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions) { return null; } @@ -112,23 +112,23 @@ private Timer CreatePruningTimer() } // GetCompletedTask must be called from within s_pendingOpenPooled lock - private static Task GetCompletedTask() + private static Task GetCompletedTask() { if (s_completedTask == null) { - TaskCompletionSource source = new TaskCompletionSource(); + TaskCompletionSource source = new TaskCompletionSource(); source.SetResult(null); s_completedTask = source.Task; } return s_completedTask; } - internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, out DbConnectionInternal connection) + internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource? retry, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection, out DbConnectionInternal? connection) { Debug.Assert(null != owningConnection, "null owningConnection?"); DbConnectionPoolGroup poolGroup; - DbConnectionPool connectionPool; + DbConnectionPool? connectionPool; connection = null; // Work around race condition with clearing the pool between GetConnectionPool obtaining pool @@ -145,7 +145,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour do { - poolGroup = GetConnectionPoolGroup(owningConnection); + poolGroup = GetConnectionPoolGroup(owningConnection)!; // Doing this on the callers thread is important because it looks up the WindowsIdentity from the thread. connectionPool = GetConnectionPool(owningConnection, poolGroup); if (null == connectionPool) @@ -153,7 +153,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour // If GetConnectionPool returns null, we can be certain that // this connection should not be pooled via DbConnectionPool // or have a disabled pool entry. - poolGroup = GetConnectionPoolGroup(owningConnection); // previous entry have been disabled + poolGroup = GetConnectionPoolGroup(owningConnection)!; // previous entry have been disabled if (retry != null) { @@ -190,7 +190,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour // than intended. newTask = s_pendingOpenNonPooled[idx].ContinueWith((_) => { - Transactions.Transaction originalTransaction = ADP.GetCurrentTransaction(); + Transactions.Transaction? originalTransaction = ADP.GetCurrentTransaction(); try { ADP.SetCurrentTransaction(retry.Task.AsyncState as Transactions.Transaction); @@ -206,10 +206,10 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour { ADP.SetCurrentTransaction(originalTransaction); } - }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default); + }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default)!; // Place this new task in the slot so any future work will be queued behind it - s_pendingOpenNonPooled[idx] = newTask; + s_pendingOpenNonPooled[idx] = newTask!; } // Set up the timeout (if needed) @@ -229,7 +229,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour } else if (task.IsFaulted) { - retry.TrySetException(task.Exception.InnerException); + retry.TrySetException(task.Exception!.InnerException!); } else { @@ -298,7 +298,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour return true; } - private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup) + private DbConnectionPool? GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup) { // if poolgroup is disabled, it will be replaced with a new entry @@ -320,25 +320,25 @@ private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnecti DbConnectionPoolGroupOptions poolOptions = connectionPoolGroup.PoolGroupOptions; // get the string to hash on again - DbConnectionOptions connectionOptions = connectionPoolGroup.ConnectionOptions; + DbConnectionOptions? connectionOptions = connectionPoolGroup.ConnectionOptions; Debug.Assert(null != connectionOptions, "prevent expansion of connectionString"); - connectionPoolGroup = GetConnectionPoolGroup(connectionPoolGroup.PoolKey, poolOptions, ref connectionOptions); + connectionPoolGroup = GetConnectionPoolGroup(connectionPoolGroup.PoolKey, poolOptions, ref connectionOptions)!; Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup?"); SetConnectionPoolGroup(owningObject, connectionPoolGroup); } - DbConnectionPool connectionPool = connectionPoolGroup.GetConnectionPool(this); + DbConnectionPool? connectionPool = connectionPoolGroup.GetConnectionPool(this); return connectionPool; } - internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions) + internal DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions? poolOptions, ref DbConnectionOptions? userConnectionOptions) { if (ADP.IsEmpty(key.ConnectionString)) { - return (DbConnectionPoolGroup)null; + return null; } - DbConnectionPoolGroup connectionPoolGroup; + DbConnectionPoolGroup? connectionPoolGroup; Dictionary connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions))) { @@ -389,7 +389,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, D connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup)) { - DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions); + DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions!); newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions); // build new dictionary with space for new connection string @@ -426,7 +426,7 @@ internal DbMetaDataFactory GetMetaDataFactory(DbConnectionPoolGroup connectionPo // get the matadatafactory from the pool entry. If it does not already have one // create one and save it on the pool entry - DbMetaDataFactory metaDataFactory = connectionPoolGroup.MetaDataFactory; + DbMetaDataFactory? metaDataFactory = connectionPoolGroup.MetaDataFactory; // consider serializing this so we don't construct multiple metadata factories // if two threads happen to hit this at the same time. One will be GC'd @@ -442,7 +442,7 @@ internal DbMetaDataFactory GetMetaDataFactory(DbConnectionPoolGroup connectionPo return metaDataFactory; } - private void PruneConnectionPoolGroups(object state) + private void PruneConnectionPoolGroups(object? state) { // when debugging this method, expect multiple threads at the same time // First, walk the pool release list and attempt to clear each @@ -559,18 +559,18 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup) PerformanceCounters.NumberOfInactiveConnectionPoolGroups.Increment(); } - protected virtual DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) + protected virtual DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningConnection, DbConnectionOptions? userOptions) { return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection); } - protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection); + protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool? pool, DbConnection? owningConnection); - protected abstract DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous); + protected abstract DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions? previous); - protected abstract DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions options); + protected abstract DbConnectionPoolGroupOptions? CreateConnectionPoolGroupOptions(DbConnectionOptions options); - internal abstract DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection); + internal abstract DbConnectionPoolGroup? GetConnectionPoolGroup(DbConnection connection); internal abstract void PermissionDemand(DbConnection outerConnection); internal abstract void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup); diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs index 51a21ee36549..c7cacdaf6cab 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs @@ -14,8 +14,8 @@ public sealed partial class OleDbConnection : DbConnection { private static readonly DbConnectionFactory _connectionFactory = OleDbConnectionFactory.SingletonInstance; - private DbConnectionOptions _userConnectionOptions; - private DbConnectionPoolGroup _poolGroup; + private DbConnectionOptions? _userConnectionOptions; + private DbConnectionPoolGroup? _poolGroup; private DbConnectionInternal _innerConnection; private int _closeCount; // used to distinguish between different uses of this object, so we don't have to maintain a list of it's children @@ -52,11 +52,11 @@ internal DbConnectionFactory ConnectionFactory } } - internal DbConnectionOptions ConnectionOptions + internal DbConnectionOptions? ConnectionOptions { get { - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = PoolGroup; + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; return ((null != poolGroup) ? poolGroup.ConnectionOptions : null); } } @@ -64,11 +64,11 @@ internal DbConnectionOptions ConnectionOptions private string ConnectionString_Get() { bool hidePassword = InnerConnection.ShouldHidePassword; - DbConnectionOptions connectionOptions = UserConnectionOptions; + DbConnectionOptions? connectionOptions = UserConnectionOptions; return ((null != connectionOptions) ? connectionOptions.UsersConnectionString(hidePassword) : ""); } - private void ConnectionString_Set(string value) + private void ConnectionString_Set(string? value) { DbConnectionPoolKey key = new DbConnectionPoolKey(value); @@ -77,8 +77,8 @@ private void ConnectionString_Set(string value) private void ConnectionString_Set(DbConnectionPoolKey key) { - DbConnectionOptions connectionOptions = null; - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); + DbConnectionOptions? connectionOptions = null; + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); DbConnectionInternal connectionInternal = InnerConnection; bool flag = connectionInternal.AllowSetConnectionString; if (flag) @@ -115,7 +115,7 @@ internal DbConnectionInternal InnerConnection } } - internal System.Data.ProviderBase.DbConnectionPoolGroup PoolGroup + internal System.Data.ProviderBase.DbConnectionPoolGroup? PoolGroup { get { @@ -129,7 +129,7 @@ internal System.Data.ProviderBase.DbConnectionPoolGroup PoolGroup } } - internal DbConnectionOptions UserConnectionOptions + internal DbConnectionOptions? UserConnectionOptions { get { @@ -144,10 +144,10 @@ internal void AddWeakReference(object value, int tag) protected override DbCommand CreateDbCommand() { - DbCommand command = null; + DbCommand? command = null; DbProviderFactory providerFactory = ConnectionFactory.ProviderFactory; - command = providerFactory.CreateCommand(); + command = providerFactory.CreateCommand()!; command.Connection = this; return command; } @@ -189,7 +189,7 @@ protected override void Dispose(bool disposing) // GC.KeepAlive(this); //} - public override void EnlistTransaction(SysTx.Transaction transaction) + public override void EnlistTransaction(SysTx.Transaction? transaction) { // If we're currently enlisted in a transaction and we were called // on the EnlistTransaction method (Whidbey) we're not allowed to @@ -200,7 +200,7 @@ public override void EnlistTransaction(SysTx.Transaction transaction) // NOTE: since transaction enlistment involves round trips to the // server, we don't want to lock here, we'll handle the race conditions // elsewhere. - SysTx.Transaction enlistedTransaction = innerConnection.EnlistedTransaction; + SysTx.Transaction? enlistedTransaction = innerConnection.EnlistedTransaction; if (enlistedTransaction != null) { // Allow calling enlist if already enlisted (no-op) @@ -235,11 +235,11 @@ public override DataTable GetSchema(string collectionName) return this.GetSchema(collectionName, null); } - public override DataTable GetSchema(string collectionName, string[] restrictionValues) + public override DataTable GetSchema(string collectionName, string?[]? restrictionValues) { // NOTE: This is virtual because not all providers may choose to support // returning schema data - return InnerConnection.GetSchema(ConnectionFactory, PoolGroup, this, collectionName, restrictionValues); + return InnerConnection.GetSchema(ConnectionFactory, PoolGroup!, this, collectionName, restrictionValues); } internal void NotifyWeakReference(int message) @@ -251,14 +251,14 @@ internal void PermissionDemand() { Debug.Assert(DbConnectionClosedConnecting.SingletonInstance == _innerConnection, "not connecting"); - System.Data.ProviderBase.DbConnectionPoolGroup poolGroup = PoolGroup; - DbConnectionOptions connectionOptions = ((null != poolGroup) ? poolGroup.ConnectionOptions : null); + System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; + DbConnectionOptions? connectionOptions = ((null != poolGroup) ? poolGroup.ConnectionOptions : null); if ((null == connectionOptions) || connectionOptions.IsEmpty) { throw ADP.NoConnectionString(); } - DbConnectionOptions userConnectionOptions = UserConnectionOptions; + DbConnectionOptions? userConnectionOptions = UserConnectionOptions; Debug.Assert(null != userConnectionOptions, "null UserConnectionOptions"); } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.Shared.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.Shared.cs index 802248ca51b4..7aa55a95e73d 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.Shared.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.Shared.cs @@ -20,9 +20,9 @@ internal abstract partial class DbConnectionInternal // V1.1.3300 private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections) - private DbConnectionPool _connectionPool; // the pooler that the connection came from (Pooled connections only) - private DbConnectionPoolCounters _performanceCounters; // the performance counters we're supposed to update - private DbReferenceCollection _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated + private DbConnectionPool? _connectionPool; // the pooler that the connection came from (Pooled connections only) + private DbConnectionPoolCounters? _performanceCounters; // the performance counters we're supposed to update + private DbReferenceCollection? _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated private int _pooledCount; // [usage must be thread safe] the number of times this object has been pushed into the pool less the number of times it's been popped (0 != inPool) private bool _connectionIsDoomed; // true when the connection should no longer be used. @@ -31,13 +31,13 @@ internal abstract partial class DbConnectionInternal // V1.1.3300 private DateTime _createTime; // when the connection was created. - private SysTx.Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically + private SysTx.Transaction? _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically // _enlistedTransaction is a clone, so that transaction information can be queried even if the original transaction object is disposed. // However, there are times when we need to know if the original transaction object was disposed, so we keep a reference to it here. // This field should only be assigned a value at the same time _enlistedTransaction is updated. // Also, this reference should not be disposed, since we aren't taking ownership of it. - private SysTx.Transaction _enlistedTransactionOriginal; + private SysTx.Transaction? _enlistedTransactionOriginal; #if DEBUG private int _activateCount; // debug only counter to verify activate/deactivates are in sync. @@ -72,7 +72,7 @@ internal bool CanBePooled } } - protected internal SysTx.Transaction EnlistedTransaction + protected internal SysTx.Transaction? EnlistedTransaction { get { @@ -80,7 +80,7 @@ protected internal SysTx.Transaction EnlistedTransaction } set { - SysTx.Transaction currentEnlistedTransaction = _enlistedTransaction; + SysTx.Transaction? currentEnlistedTransaction = _enlistedTransaction; if (((null == currentEnlistedTransaction) && (null != value)) || ((null != currentEnlistedTransaction) && !currentEnlistedTransaction.Equals(value))) { @@ -92,8 +92,8 @@ protected internal SysTx.Transaction EnlistedTransaction // we need to use a clone of the transaction // when we store it, or we'll end up keeping it past the // duration of the using block of the TransactionScope - SysTx.Transaction valueClone = null; - SysTx.Transaction previousTransactionClone = null; + SysTx.Transaction? valueClone = null; + SysTx.Transaction? previousTransactionClone = null; try { if (null != value) @@ -231,17 +231,17 @@ internal bool IsEmancipated } } - protected internal object Owner + protected internal object? Owner { // We use a weak reference to the owning object so we can identify when - // it has been garbage collected without thowing exceptions. + // it has been garbage collected without throwing exceptions. get { return _owningObject.Target; } } - internal DbConnectionPool Pool + internal DbConnectionPool? Pool { get { @@ -249,14 +249,14 @@ internal DbConnectionPool Pool } } - protected DbConnectionPoolCounters PerformanceCounters + protected DbConnectionPoolCounters? PerformanceCounters { get { return _performanceCounters; } } - protected internal DbReferenceCollection ReferenceCollection + protected internal DbReferenceCollection? ReferenceCollection { get { @@ -285,7 +285,7 @@ public ConnectionState State } } - protected abstract void Activate(SysTx.Transaction transaction); + protected abstract void Activate(SysTx.Transaction? transaction); internal void AddWeakReference(object value, int tag) { @@ -312,12 +312,12 @@ protected virtual void PrepareForCloseConnection() // By default, there is no preperation required } - protected virtual object ObtainAdditionalLocksForClose() + protected virtual object? ObtainAdditionalLocksForClose() { return null; // no additional locks in default implementation } - protected virtual void ReleaseAdditionalLocksForClose(object lockToken) + protected virtual void ReleaseAdditionalLocksForClose(object? lockToken) { // no additional locks in default implementation } @@ -343,7 +343,7 @@ internal void DeactivateConnection() PerformanceCounters.NumberOfActiveConnections.Decrement(); } - if (!_connectionIsDoomed && Pool.UseLoadBalancing) + if (!_connectionIsDoomed && Pool!.UseLoadBalancing) { // If we're not already doomed, check the connection's lifetime and // doom it if it's lifetime has elapsed. @@ -377,7 +377,7 @@ internal virtual void DelegatedTransactionEnded() Deactivate(); // call it one more time just in case - DbConnectionPool pool = Pool; + DbConnectionPool? pool = Pool; if (null == pool) { @@ -399,7 +399,7 @@ internal virtual void DelegatedTransactionEnded() // once and for all, or the server will have fits about us // leaving connections open until the client-side GC kicks // in. - PerformanceCounters.NumberOfNonPooledConnections.Decrement(); + PerformanceCounters!.NumberOfNonPooledConnections.Decrement(); Dispose(); } // When _pooledCount is 0, the connection is a pooled connection @@ -419,9 +419,9 @@ protected internal void DoomThisConnection() _connectionIsDoomed = true; } - public abstract void EnlistTransaction(SysTx.Transaction transaction); + public abstract void EnlistTransaction(SysTx.Transaction? transaction); - protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) + protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string?[]? restrictions) { Debug.Assert(outerConnection != null, "outerConnection may not be null."); @@ -456,7 +456,7 @@ internal void MakePooledConnection(DbConnectionPool connectionPool) internal void NotifyWeakReference(int message) { - DbReferenceCollection referenceCollection = ReferenceCollection; + DbReferenceCollection? referenceCollection = ReferenceCollection; if (null != referenceCollection) { referenceCollection.Notify(message); @@ -476,17 +476,17 @@ internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionF /// override this and do the correct thing. // User code should either override DbConnectionInternal.Activate when it comes out of the pool // or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections - internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { throw ADP.ConnectionAlreadyOpen(State); } - protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource retry, DbConnectionOptions userOptions) + protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource? retry, DbConnectionOptions? userOptions) { // ?->Connecting: prevent set_ConnectionString during Open if (connectionFactory.SetInnerConnectionFrom(outerConnection, DbConnectionClosedConnecting.SingletonInstance, this)) { - DbConnectionInternal openConnection = null; + DbConnectionInternal? openConnection = null; try { connectionFactory.PermissionDemand(outerConnection); @@ -512,7 +512,7 @@ protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnect return true; } - internal void PrePush(object expectedOwner) + internal void PrePush(object? expectedOwner) { // Called by DbConnectionPool when we're about to be put into it's pool, we // take this opportunity to ensure ownership and pool counts are legit. @@ -581,7 +581,7 @@ internal void PostPop(object newOwner) internal void RemoveWeakReference(object value) { - DbReferenceCollection referenceCollection = ReferenceCollection; + DbReferenceCollection? referenceCollection = ReferenceCollection; if (null != referenceCollection) { referenceCollection.Remove(value); @@ -590,7 +590,7 @@ internal void RemoveWeakReference(object value) internal void DetachCurrentTransactionIfEnded() { - SysTx.Transaction enlistedTransaction = EnlistedTransaction; + SysTx.Transaction? enlistedTransaction = EnlistedTransaction; if (enlistedTransaction != null) { bool transactionIsDead; @@ -619,10 +619,10 @@ internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitly lock (this) { // Detach if detach-on-end behavior, or if outer connection was closed - DbConnection owner = (DbConnection)Owner; + DbConnection? owner = (DbConnection?)Owner; if (isExplicitlyReleasing || UnbindOnTransactionCompletion || null == owner) { - SysTx.Transaction currentEnlistedTransaction = _enlistedTransaction; + SysTx.Transaction? currentEnlistedTransaction = _enlistedTransaction; if (currentEnlistedTransaction != null && transaction.Equals(currentEnlistedTransaction)) { EnlistedTransaction = null; @@ -639,12 +639,12 @@ internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitly internal void SetInStasis() { _isInStasis = true; - PerformanceCounters.NumberOfStasisConnections.Increment(); + PerformanceCounters!.NumberOfStasisConnections.Increment(); } private void TerminateStasis(bool returningToPool) { - PerformanceCounters.NumberOfStasisConnections.Decrement(); + PerformanceCounters!.NumberOfStasisConnections.Decrement(); _isInStasis = false; } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.cs index 2f63a7a84987..f98d94b4ba04 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionInternal.cs @@ -11,7 +11,7 @@ namespace System.Data.ProviderBase { internal abstract partial class DbConnectionInternal { - internal void ActivateConnection(SysTx.Transaction transaction) + internal void ActivateConnection(SysTx.Transaction? transaction) { // Internal method called from the connection pooler so we don't expose // the Activate method publicly. @@ -22,7 +22,7 @@ internal void ActivateConnection(SysTx.Transaction transaction) Activate(transaction); - PerformanceCounters.NumberOfActiveConnections.Increment(); + PerformanceCounters!.NumberOfActiveConnections.Increment(); } internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) @@ -76,12 +76,12 @@ internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFac // Lock to prevent race condition with cancellation lock (this) { - object lockToken = ObtainAdditionalLocksForClose(); + object? lockToken = ObtainAdditionalLocksForClose(); try { PrepareForCloseConnection(); - DbConnectionPool connectionPool = Pool; + DbConnectionPool? connectionPool = Pool; // Detach from enlisted transactions that are no longer active on close DetachCurrentTransactionIfEnded(); @@ -100,7 +100,7 @@ internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFac { Deactivate(); // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up... - PerformanceCounters.HardDisconnectsPerSecond.Increment(); + PerformanceCounters!.HardDisconnectsPerSecond.Increment(); // To prevent an endless recursion, we need to clear // the owning object before we call dispose so that @@ -143,7 +143,7 @@ public virtual void Dispose() // Dispose of the _enlistedTransaction since it is a clone // of the original reference. // _enlistedTransaction can be changed by another thread (TX end event) - SysTx.Transaction enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null); + SysTx.Transaction? enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null); if (enlistedTransaction != null) { enlistedTransaction.Dispose(); diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPool.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPool.cs index 5809fc7a5f78..e411fc550101 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPool.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPool.cs @@ -47,7 +47,7 @@ internal void Dispose() private sealed class PendingGetConnection { - public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSource completion, DbConnectionOptions userOptions) + public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSource completion, DbConnectionOptions? userOptions) { DueTime = dueTime; Owner = owner; @@ -56,7 +56,7 @@ public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSour public long DueTime { get; private set; } public DbConnection Owner { get; private set; } public TaskCompletionSource Completion { get; private set; } - public DbConnectionOptions UserOptions { get; private set; } + public DbConnectionOptions? UserOptions { get; private set; } } private sealed class TransactedConnectionPool @@ -81,13 +81,13 @@ internal DbConnectionPool Pool } } - internal DbConnectionInternal GetTransactedObject(SysTx.Transaction transaction) + internal DbConnectionInternal? GetTransactedObject(SysTx.Transaction transaction) { Debug.Assert(null != transaction, "null transaction?"); - DbConnectionInternal transactedObject = null; + DbConnectionInternal? transactedObject = null; - TransactedConnectionList connections; + TransactedConnectionList? connections; bool txnFound = false; lock (_transactedCxns) @@ -126,7 +126,7 @@ internal void PutTransactedObject(SysTx.Transaction transaction, DbConnectionInt Debug.Assert(null != transaction, "null transaction?"); Debug.Assert(null != transactedObject, "null transactedObject?"); - TransactedConnectionList connections; + TransactedConnectionList? connections; bool txnFound = false; // NOTE: because TransactionEnded is an asynchronous notification, there's no guarantee @@ -155,8 +155,8 @@ internal void PutTransactedObject(SysTx.Transaction transaction, DbConnectionInt { // create the transacted pool, making sure to clone the associated transaction // for use as a key in our internal dictionary of transactions and connections - SysTx.Transaction transactionClone = null; - TransactedConnectionList newConnections = null; + SysTx.Transaction? transactionClone = null; + TransactedConnectionList? newConnections = null; try { @@ -339,7 +339,7 @@ protected override bool ReleaseHandle() private static readonly Random _random = new Random(5101977); // Value obtained from Dave Driver private readonly int _cleanupWait; - private readonly DbConnectionPoolIdentity _identity; + private readonly DbConnectionPoolIdentity? _identity; private readonly DbConnectionFactory _connectionFactory; private readonly DbConnectionPoolGroup _connectionPoolGroup; @@ -357,15 +357,15 @@ protected override bool ReleaseHandle() private int _waitCount; private readonly PoolWaitHandles _waitHandles; - private Exception _resError; + private Exception? _resError; private volatile bool _errorOccurred; private int _errorWait; - private Timer _errorTimer; + private Timer? _errorTimer; - private Timer _cleanupTimer; + private Timer? _cleanupTimer; - private readonly TransactedConnectionPool _transactedConnectionPool; + private readonly TransactedConnectionPool? _transactedConnectionPool; private readonly List _objectList; private int _totalObjects; @@ -508,7 +508,7 @@ private bool UsingIntegrateSecurity get { return (null != _identity && DbConnectionPoolIdentity.NoIdentity != _identity); } } - private void CleanupCallback(object state) + private void CleanupCallback(object? state) { // Called when the cleanup-timer ticks over. @@ -536,7 +536,7 @@ private void CleanupCallback(object state) if (_waitHandles.PoolSemaphore.WaitOne(0, false) /* != WAIT_TIMEOUT */) { // We obtained a objects from the semaphore. - DbConnectionInternal obj; + DbConnectionInternal? obj; if (_stackOld.TryPop(out obj)) { @@ -595,7 +595,7 @@ private void CleanupCallback(object state) { while (true) { - DbConnectionInternal obj; + DbConnectionInternal? obj; if (!_stackNew.TryPop(out obj)) break; @@ -616,7 +616,7 @@ private void CleanupCallback(object state) internal void Clear() { - DbConnectionInternal obj; + DbConnectionInternal? obj; // First, quickly doom everything. lock (_objectList) @@ -660,9 +660,9 @@ private Timer CreateCleanupTimer() private bool IsBlockingPeriodEnabled() => true; - private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) + private DbConnectionInternal CreateObject(DbConnection? owningObject, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection) { - DbConnectionInternal newObj = null; + DbConnectionInternal? newObj = null; try { @@ -821,7 +821,7 @@ private void DeactivateObject(DbConnectionInternal obj) // the transaction asyncronously completing on a second // thread. - SysTx.Transaction transaction = obj.EnlistedTransaction; + SysTx.Transaction? transaction = obj.EnlistedTransaction; if (null != transaction) { // NOTE: we're not locking on _state, so it's possible that its @@ -921,13 +921,13 @@ internal void DestroyObject(DbConnectionInternal obj) } } - private void ErrorCallback(object state) + private void ErrorCallback(object? state) { _errorOccurred = false; _waitHandles.ErrorEvent.Reset(); // the error state is cleaned, destroy the timer to avoid periodic invocation - Timer t = _errorTimer; + Timer? t = _errorTimer; _errorTimer = null; if (t != null) { @@ -937,7 +937,7 @@ private void ErrorCallback(object state) // TODO: move this to src/Common and integrate with SqlClient // Note: OleDb connections are not passing through this code - private Exception TryCloneCachedException() + private Exception? TryCloneCachedException() { return _resError; } @@ -946,7 +946,7 @@ private void WaitForPendingOpen() { Debug.Assert(!Thread.CurrentThread.IsThreadPoolThread, "This thread may block for a long time. Threadpool threads should not be used."); - PendingGetConnection next; + PendingGetConnection? next; do { @@ -985,9 +985,9 @@ private void WaitForPendingOpen() delay = (uint)Math.Max(ADP.TimerRemainingMilliseconds(next.DueTime), 0); } - DbConnectionInternal connection = null; + DbConnectionInternal? connection = null; bool timeout = false; - Exception caughtException = null; + Exception? caughtException = null; RuntimeHelpers.PrepareConstrainedRegions(); try @@ -1050,7 +1050,7 @@ private void WaitForPendingOpen() } while (_pendingOpens.TryPeek(out next)); } - internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource retry, DbConnectionOptions userOptions, out DbConnectionInternal connection) + internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource? retry, DbConnectionOptions? userOptions, out DbConnectionInternal? connection) { uint waitForMultipleObjectsTimeout = 0; bool allowCreate = false; @@ -1103,10 +1103,10 @@ internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSourceOptions used to create the new connection /// Inner connection that will be replaced /// A new inner connection that is attached to the - internal DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) + internal DbConnectionInternal? ReplaceConnection(DbConnection owningObject, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection) { PerformanceCounters.SoftConnectsPerSecond.Increment(); - DbConnectionInternal newConnection = UserCreateRequest(owningObject, userOptions, oldConnection); + DbConnectionInternal? newConnection = UserCreateRequest(owningObject, userOptions, oldConnection); if (newConnection != null) { - PrepareConnection(owningObject, newConnection, oldConnection.EnlistedTransaction); + PrepareConnection(owningObject, newConnection, oldConnection!.EnlistedTransaction); oldConnection.PrepareForReplaceConnection(); oldConnection.DeactivateConnection(); oldConnection.Dispose(); @@ -1344,9 +1344,9 @@ internal DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbCon return newConnection; } - private DbConnectionInternal GetFromGeneralPool() + private DbConnectionInternal? GetFromGeneralPool() { - DbConnectionInternal obj = null; + DbConnectionInternal? obj = null; if (!_stackNew.TryPop(out obj)) { @@ -1377,10 +1377,10 @@ private DbConnectionInternal GetFromGeneralPool() return (obj); } - private DbConnectionInternal GetFromTransactedPool(out SysTx.Transaction transaction) + private DbConnectionInternal? GetFromTransactedPool(out SysTx.Transaction? transaction) { transaction = ADP.GetCurrentTransaction(); - DbConnectionInternal obj = null; + DbConnectionInternal? obj = null; if (null != transaction && null != _transactedConnectionPool) { @@ -1412,7 +1412,7 @@ private DbConnectionInternal GetFromTransactedPool(out SysTx.Transaction transac return obj; } - private void PoolCreateRequest(object state) + private void PoolCreateRequest(object? state) { // called by pooler to ensure pool requests are currently being satisfied - // creation mutex has not been obtained @@ -1442,7 +1442,7 @@ private void PoolCreateRequest(object state) // since either Open will fail or we will open a object for this pool that does // not belong in this pool. The side effect of this is that if using integrated // security min pool size cannot be guaranteed. - if (UsingIntegrateSecurity && !_identity.Equals(DbConnectionPoolIdentity.GetCurrent())) + if (UsingIntegrateSecurity && !_identity!.Equals(DbConnectionPoolIdentity.GetCurrent())) { return; } @@ -1686,7 +1686,7 @@ internal void Shutdown() _state = State.ShuttingDown; // deactivate timer callbacks - Timer t = _cleanupTimer; + Timer? t = _cleanupTimer; _cleanupTimer = null; if (null != t) { @@ -1694,15 +1694,15 @@ internal void Shutdown() } } - private DbConnectionInternal UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection = null) + private DbConnectionInternal? UserCreateRequest(DbConnection owningObject, DbConnectionOptions? userOptions, DbConnectionInternal? oldConnection = null) { // called by user when they were not able to obtain a free object but // instead obtained creation mutex - DbConnectionInternal obj = null; + DbConnectionInternal? obj = null; if (ErrorOccurred) { - throw TryCloneCachedException(); + throw TryCloneCachedException()!; } else { diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolCounters.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolCounters.cs index df6f363cf6f3..e1c2f3bfca2b 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolCounters.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolCounters.cs @@ -90,9 +90,9 @@ private static class CreationData internal sealed class Counter { - private PerformanceCounter _instance; + private PerformanceCounter? _instance; - internal Counter(string categoryName, string instanceName, string counterName, PerformanceCounterType counterType) + internal Counter(string? categoryName, string? instanceName, string counterName, PerformanceCounterType counterType) { if (ADP.IsPlatformNT5) { @@ -120,7 +120,7 @@ internal Counter(string categoryName, string instanceName, string counterName, P internal void Decrement() { - PerformanceCounter instance = _instance; + PerformanceCounter? instance = _instance; if (null != instance) { instance.Decrement(); @@ -129,7 +129,7 @@ internal void Decrement() internal void Dispose() { // TODO: race condition, Dispose at the same time as Increment/Decrement - PerformanceCounter instance = _instance; + PerformanceCounter? instance = _instance; _instance = null; if (null != instance) { @@ -142,7 +142,7 @@ internal void Dispose() internal void Increment() { - PerformanceCounter instance = _instance; + PerformanceCounter? instance = _instance; if (null != instance) { instance.Increment(); @@ -171,13 +171,13 @@ protected DbConnectionPoolCounters() : this(null, null) { } - protected DbConnectionPoolCounters(string categoryName, string categoryHelp) + protected DbConnectionPoolCounters(string? categoryName, string? categoryHelp) { AppDomain.CurrentDomain.DomainUnload += new EventHandler(this.UnloadEventHandler); AppDomain.CurrentDomain.ProcessExit += new EventHandler(this.ExitEventHandler); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(this.ExceptionEventHandler); - string instanceName = null; + string? instanceName = null; if (!ADP.IsEmpty(categoryName)) { @@ -188,7 +188,7 @@ protected DbConnectionPoolCounters(string categoryName, string categoryHelp) } // level 0-3: hard connects/disconnects, plus basic pool/pool entry statistics - string basicCategoryName = categoryName; + string? basicCategoryName = categoryName; HardConnectsPerSecond = new Counter(basicCategoryName, instanceName, CreationData.HardConnectsPerSecond.CounterName, CreationData.HardConnectsPerSecond.CounterType); HardDisconnectsPerSecond = new Counter(basicCategoryName, instanceName, CreationData.HardDisconnectsPerSecond.CounterName, CreationData.HardDisconnectsPerSecond.CounterType); NumberOfNonPooledConnections = new Counter(basicCategoryName, instanceName, CreationData.NumberOfNonPooledConnections.CounterName, CreationData.NumberOfNonPooledConnections.CounterType); @@ -201,7 +201,7 @@ protected DbConnectionPoolCounters(string categoryName, string categoryHelp) NumberOfReclaimedConnections = new Counter(basicCategoryName, instanceName, CreationData.NumberOfReclaimedConnections.CounterName, CreationData.NumberOfReclaimedConnections.CounterType); // level 4: expensive stuff - string verboseCategoryName = null; + string? verboseCategoryName = null; if (!ADP.IsEmpty(categoryName)) { // don't load TraceSwitch if no categoryName so that Odbc/OleDb have a chance of not loading TraceSwitch @@ -217,12 +217,12 @@ protected DbConnectionPoolCounters(string categoryName, string categoryHelp) NumberOfActiveConnections = new Counter(verboseCategoryName, instanceName, CreationData.NumberOfActiveConnections.CounterName, CreationData.NumberOfActiveConnections.CounterType); NumberOfFreeConnections = new Counter(verboseCategoryName, instanceName, CreationData.NumberOfFreeConnections.CounterName, CreationData.NumberOfFreeConnections.CounterType); } - private string GetAssemblyName() + private string? GetAssemblyName() { - string result = null; + string? result = null; // First try GetEntryAssembly name, then AppDomain.FriendlyName. - Assembly assembly = Assembly.GetEntryAssembly(); + Assembly? assembly = Assembly.GetEntryAssembly(); if (null != assembly) { @@ -239,9 +239,9 @@ private string GetAssemblyName() // TODO: remove the Resource* attributes if you do not use GetCurrentProcessId after the fix private string GetInstanceName() { - string result = null; + string? result = null; - string instanceName = GetAssemblyName(); // instance perfcounter name + string? instanceName = GetAssemblyName(); // instance perfcounter name if (ADP.IsEmpty(instanceName)) { @@ -259,7 +259,7 @@ private string GetInstanceName() // to PERFMON. They recommend that we translate them as shown below, to // prevent problems. - result = string.Format((IFormatProvider)null, "{0}[{1}]", instanceName, pid); + result = string.Format(null, "{0}[{1}]", instanceName, pid); result = result.Replace('(', '[').Replace(')', ']').Replace('#', '_').Replace('/', '_').Replace('\\', '_'); // counter instance name cannot be greater than 127 @@ -272,13 +272,13 @@ private string GetInstanceName() const string insertString = "[...]"; int firstPartLength = (CounterInstanceNameMaxLength - insertString.Length) / 2; int lastPartLength = CounterInstanceNameMaxLength - firstPartLength - insertString.Length; - result = string.Format((IFormatProvider)null, "{0}{1}{2}", + result = string.Format(null, "{0}{1}{2}", result.Substring(0, firstPartLength), insertString, result.Substring(result.Length - lastPartLength, lastPartLength)); Debug.Assert(result.Length == CounterInstanceNameMaxLength, - string.Format((IFormatProvider)null, "wrong calculation of the instance name: expected {0}, actual: {1}", CounterInstanceNameMaxLength, result.Length)); + string.Format(null, "wrong calculation of the instance name: expected {0}, actual: {1}", CounterInstanceNameMaxLength, result.Length)); } return result; @@ -319,12 +319,12 @@ private void ExceptionEventHandler(object sender, UnhandledExceptionEventArgs e) } } - private void ExitEventHandler(object sender, EventArgs e) + private void ExitEventHandler(object? sender, EventArgs e) { Dispose(); } - private void UnloadEventHandler(object sender, EventArgs e) + private void UnloadEventHandler(object? sender, EventArgs e) { Dispose(); } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs index 0f9320b122ce..792f6e7bc2d4 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs @@ -33,8 +33,8 @@ internal sealed class DbConnectionPoolGroup private int _state; // see PoolGroupState* below - private DbConnectionPoolGroupProviderInfo _providerInfo; - private DbMetaDataFactory _metaDataFactory; + private DbConnectionPoolGroupProviderInfo? _providerInfo; + private DbMetaDataFactory? _metaDataFactory; // always lock this before changing _state, we don't want to move out of the 'Disabled' state // PoolGroupStateUninitialized = 0; @@ -49,7 +49,7 @@ internal DbConnectionPoolGroup(DbConnectionOptions connectionOptions, DbConnecti _connectionOptions = connectionOptions; _poolKey = key; - _poolGroupOptions = poolGroupOptions; + _poolGroupOptions = poolGroupOptions!; // always lock this object before changing state // HybridDictionary does not create any sub-objects until add @@ -75,7 +75,7 @@ internal DbConnectionPoolKey PoolKey } } - internal DbConnectionPoolGroupProviderInfo ProviderInfo + internal DbConnectionPoolGroupProviderInfo? ProviderInfo { get { @@ -86,7 +86,7 @@ internal DbConnectionPoolGroupProviderInfo ProviderInfo _providerInfo = value; if (null != value) { - _providerInfo.PoolGroup = this; + _providerInfo!.PoolGroup = this; } } } @@ -107,7 +107,7 @@ internal DbConnectionPoolGroupOptions PoolGroupOptions } } - internal DbMetaDataFactory MetaDataFactory + internal DbMetaDataFactory? MetaDataFactory { get { @@ -126,7 +126,7 @@ internal int Clear() // will return the number of connections in the group after clearing has finished // First, note the old collection and create a new collection to be used - ConcurrentDictionary oldPoolCollection = null; + ConcurrentDictionary? oldPoolCollection = null; lock (this) { if (_poolCollection.Count > 0) @@ -162,7 +162,7 @@ internal int Clear() return _poolCollection.Count; } - internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory) + internal DbConnectionPool? GetConnectionPool(DbConnectionFactory connectionFactory) { // When this method returns null it indicates that the connection // factory should not use pooling. @@ -171,12 +171,12 @@ internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactor // many of the APIs we require. // PoolGroupOptions will only be null when we're not supposed to pool // connections. - DbConnectionPool pool = null; + DbConnectionPool? pool = null; if (null != _poolGroupOptions) { Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x"); - DbConnectionPoolIdentity currentIdentity = DbConnectionPoolIdentity.NoIdentity; + DbConnectionPoolIdentity? currentIdentity = DbConnectionPoolIdentity.NoIdentity; if (_poolGroupOptions.PoolByIdentity) { // if we're pooling by identity (because integrated security is diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs index 911720230d21..44c2fd1a379e 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs @@ -5,9 +5,9 @@ namespace System.Data.ProviderBase { internal class DbConnectionPoolGroupProviderInfo { - private DbConnectionPoolGroup _poolGroup; + private DbConnectionPoolGroup? _poolGroup; - internal DbConnectionPoolGroup PoolGroup + internal DbConnectionPoolGroup? PoolGroup { get { diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolIdentity.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolIdentity.cs index a7d839b8c2e2..9fe3910b372a 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolIdentity.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolIdentity.cs @@ -58,7 +58,7 @@ private static byte[] CreateWellKnownSid(WellKnownSidType sidType) return resultSid; } - public override bool Equals(object value) + public override bool Equals(object? value) { bool result = ((this == NoIdentity) || (this == value)); if (!result && (null != value)) diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs index 24e665052e8a..68892d670c3c 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs @@ -38,7 +38,8 @@ public DbMetaDataFactory(Stream xmlStream, string serverVersion, string normaliz ADP.CheckArgumentNull(serverVersion, "serverVersion"); ADP.CheckArgumentNull(normalizedServerVersion, "normalizedServerVersion"); - LoadDataSetFromXml(xmlStream); + _metaDataCollectionsDataSet = new DataSet { Locale = CultureInfo.InvariantCulture }; + _metaDataCollectionsDataSet.ReadXml(xmlStream); _serverVersionString = serverVersion; _normalizedServerVersion = normalizedServerVersion; @@ -68,9 +69,9 @@ protected string ServerVersionNormalized } } - protected DataTable CloneAndFilterCollection(string collectionName, string[] hiddenColumnNames) + protected DataTable CloneAndFilterCollection(string collectionName, string[]? hiddenColumnNames) { - DataTable sourceTable; + DataTable? sourceTable; DataTable destinationTable; DataColumn[] filteredSourceColumns; DataColumnCollection destinationColumns; @@ -115,28 +116,28 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - _normalizedServerVersion = null; - _serverVersionString = null; + _normalizedServerVersion = null!; + _serverVersionString = null!; _metaDataCollectionsDataSet.Dispose(); } } - private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restrictions, DbConnection connection) + private DataTable ExecuteCommand(DataRow requestedCollectionRow, string?[]? restrictions, DbConnection connection) { - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; - DataColumn populationStringColumn = metaDataCollectionsTable.Columns[_populationString]; - DataColumn numberOfRestrictionsColumn = metaDataCollectionsTable.Columns[_numberOfRestrictions]; - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[_collectionName]; + DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!; + DataColumn populationStringColumn = metaDataCollectionsTable.Columns[_populationString]!; + DataColumn numberOfRestrictionsColumn = metaDataCollectionsTable.Columns[_numberOfRestrictions]!; + DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[_collectionName]!; //DataColumn restrictionNameColumn = metaDataCollectionsTable.Columns[_restrictionName]; - DataTable resultTable = null; - DbCommand command = null; - DataTable schemaTable = null; + DataTable? resultTable = null; + DbCommand? command = null; + DataTable? schemaTable = null; Debug.Assert(requestedCollectionRow != null); - string sqlCommand = requestedCollectionRow[populationStringColumn, DataRowVersion.Current] as string; + string sqlCommand = (requestedCollectionRow[populationStringColumn, DataRowVersion.Current] as string)!; int numberOfRestrictions = (int)requestedCollectionRow[numberOfRestrictionsColumn, DataRowVersion.Current]; - string collectionName = requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string; + string collectionName = (requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string)!; if ((restrictions != null) && (restrictions.Length > numberOfRestrictions)) { @@ -167,7 +168,7 @@ private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restri command.Parameters.Add(restrictionParameter); } - DbDataReader reader = null; + DbDataReader? reader = null; try { try @@ -212,11 +213,11 @@ private DataTable ExecuteCommand(DataRow requestedCollectionRow, string[] restri return resultTable; } - private DataColumn[] FilterColumns(DataTable sourceTable, string[] hiddenColumnNames, DataColumnCollection destinationColumns) + private DataColumn[] FilterColumns(DataTable sourceTable, string[]? hiddenColumnNames, DataColumnCollection destinationColumns) { DataColumn newDestinationColumn; int currentColumn; - DataColumn[] filteredSourceColumns = null; + DataColumn[]? filteredSourceColumns = null; int columnCount = 0; foreach (DataColumn sourceColumn in sourceTable.Columns) @@ -253,23 +254,23 @@ internal DataRow FindMetaDataCollectionRow(string collectionName) bool versionFailure; bool haveExactMatch; bool haveMultipleInexactMatches; - string candidateCollectionName; + string? candidateCollectionName; - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; + DataTable? metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; if (metaDataCollectionsTable == null) { throw ADP.InvalidXml(); } - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; + DataColumn? collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; if ((null == collectionNameColumn) || (typeof(string) != collectionNameColumn.DataType)) { throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, DbMetaDataColumnNames.CollectionName); } - DataRow requestedCollectionRow = null; - string exactCollectionName = null; + DataRow? requestedCollectionRow = null; + string? exactCollectionName = null; // find the requested collection versionFailure = false; @@ -341,8 +342,8 @@ internal DataRow FindMetaDataCollectionRow(string collectionName) private void FixUpVersion(DataTable dataSourceInfoTable) { Debug.Assert(dataSourceInfoTable.TableName == DbMetaDataCollectionNames.DataSourceInformation); - DataColumn versionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersion]; - DataColumn normalizedVersionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersionNormalized]; + DataColumn? versionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersion]; + DataColumn? normalizedVersionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersionNormalized]; if ((versionColumn == null) || (normalizedVersionColumn == null)) { @@ -363,14 +364,14 @@ private void FixUpVersion(DataTable dataSourceInfoTable) private string GetParameterName(string neededCollectionName, int neededRestrictionNumber) { - DataTable restrictionsTable = null; - DataColumnCollection restrictionColumns = null; - DataColumn collectionName = null; - DataColumn parameterName = null; - DataColumn restrictionName = null; - DataColumn restrictionNumber = null; + DataTable? restrictionsTable = null; + DataColumnCollection? restrictionColumns = null; + DataColumn? collectionName = null; + DataColumn? parameterName = null; + DataColumn? restrictionName = null; + DataColumn? restrictionNumber = null; ; - string result = null; + string? result = null; restrictionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; if (restrictionsTable != null) @@ -390,7 +391,7 @@ private string GetParameterName(string neededCollectionName, int neededRestricti throw ADP.MissingRestrictionColumn(); } - foreach (DataRow restriction in restrictionsTable.Rows) + foreach (DataRow restriction in restrictionsTable!.Rows) { if (((string)restriction[collectionName] == neededCollectionName) && ((int)restriction[restrictionNumber] == neededRestrictionNumber) && @@ -410,26 +411,26 @@ private string GetParameterName(string neededCollectionName, int neededRestricti } - public virtual DataTable GetSchema(DbConnection connection, string collectionName, string[] restrictions) + public virtual DataTable GetSchema(DbConnection connection, string collectionName, string?[]? restrictions) { Debug.Assert(_metaDataCollectionsDataSet != null); - DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; - DataColumn populationMechanismColumn = metaDataCollectionsTable.Columns[_populationMechanism]; - DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; - DataRow requestedCollectionRow = null; - DataTable requestedSchema = null; - string[] hiddenColumns; - string exactCollectionName = null; + DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]!; + DataColumn populationMechanismColumn = metaDataCollectionsTable.Columns[_populationMechanism]!; + DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]!; + DataRow? requestedCollectionRow = null; + DataTable? requestedSchema = null; + string[]? hiddenColumns; + string? exactCollectionName = null; requestedCollectionRow = FindMetaDataCollectionRow(collectionName); - exactCollectionName = requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string; + exactCollectionName = (requestedCollectionRow[collectionNameColumn, DataRowVersion.Current] as string)!; if (ADP.IsEmptyArray(restrictions) == false) { - for (int i = 0; i < restrictions.Length; i++) + for (int i = 0; i < restrictions!.Length; i++) { - if ((restrictions[i] != null) && (restrictions[i].Length > 4096)) + if ((restrictions[i]?.Length > 4096)) { // use a non-specific error because no new beta 2 error messages are allowed // TODO: will add a more descriptive error in RTM @@ -438,7 +439,7 @@ public virtual DataTable GetSchema(DbConnection connection, string collectionNam } } - string populationMechanism = requestedCollectionRow[populationMechanismColumn, DataRowVersion.Current] as string; + string populationMechanism = (requestedCollectionRow[populationMechanismColumn, DataRowVersion.Current] as string)!; switch (populationMechanism) { case _dataTable: @@ -485,7 +486,7 @@ public virtual DataTable GetSchema(DbConnection connection, string collectionNam return requestedSchema; } - private bool IncludeThisColumn(DataColumn sourceColumn, string[] hiddenColumnNames) + private bool IncludeThisColumn(DataColumn sourceColumn, string[]? hiddenColumnNames) { bool result = true; string sourceColumnName = sourceColumn.ColumnName; @@ -516,14 +517,7 @@ private bool IncludeThisColumn(DataColumn sourceColumn, string[] hiddenColumnNam return result; } - private void LoadDataSetFromXml(Stream XmlStream) - { - _metaDataCollectionsDataSet = new DataSet(); - _metaDataCollectionsDataSet.Locale = System.Globalization.CultureInfo.InvariantCulture; - _metaDataCollectionsDataSet.ReadXml(XmlStream); - } - - protected virtual DataTable PrepareCollection(string collectionName, string[] restrictions, DbConnection connection) + protected virtual DataTable PrepareCollection(string collectionName, string?[]? restrictions, DbConnection connection) { throw ADP.NotSupported(); } @@ -532,7 +526,7 @@ private bool SupportedByCurrentVersion(DataRow requestedCollectionRow) { bool result = true; DataColumnCollection tableColumns = requestedCollectionRow.Table.Columns; - DataColumn versionColumn; + DataColumn? versionColumn; object version; // check the minimum version first diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs index c08b3436a640..8cf24c84ed2f 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading; namespace System.Data.ProviderBase @@ -51,7 +52,7 @@ public int Tag } } - public object Target + public object? Target { get { @@ -132,6 +133,7 @@ protected void AddItem(object value, int tag) } } + [return: MaybeNull] internal T FindItem(int tag, Func filterMethod) where T : class { bool lockObtained = false; @@ -150,11 +152,11 @@ internal T FindItem(int tag, Func filterMethod) where T : class { // NOTE: Check if the returned value is null twice may seem wasteful, but this if for performance // Since checking for null twice is cheaper than calling both HasTarget and Target OR always attempting to typecast - object value = _items[counter].Target; + object? value = _items[counter].Target; if (value != null) { // Make sure the item has the correct type and passes the filtering - T tempItem = value as T; + T? tempItem = value as T; if ((tempItem != null) && (filterMethod(tempItem))) { return tempItem; @@ -191,7 +193,7 @@ public void Notify(int message) { for (int index = 0; index <= _lastItemIndex; ++index) { - object value = _items[index].Target; // checks tag & gets target + object? value = _items[index].Target; // checks tag & gets target if (null != value) { NotifyItem(message, _items[index].Tag, value); diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/WrappedIUnknown.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/WrappedIUnknown.cs index 66ba0d16fb29..a45f38e06111 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/WrappedIUnknown.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/WrappedIUnknown.cs @@ -18,7 +18,7 @@ internal WrappedIUnknown() : base(IntPtr.Zero, true) { } - internal WrappedIUnknown(object unknown) : this() + internal WrappedIUnknown(object? unknown) : this() { if (null != unknown) { @@ -44,7 +44,7 @@ internal object ComWrapper() { // NOTE: Method, instead of property, to avoid being evaluated at // runtime in the debugger. - object value = null; + object? value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs index b6e203b43ae5..4f6717007d3e 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs @@ -337,7 +337,7 @@ HRESULT GetProperties( [PreserveSig] System.Data.OleDb.OleDbHResult GetProperties( [In] int cPropertyIDSets, - [In] SafeHandle rgPropertyIDSets, + [In] SafeHandle? rgPropertyIDSets, [Out] out int pcPropertySets, [Out] out IntPtr prgPropertySets); @@ -372,7 +372,7 @@ HRESULT Execute( System.Data.OleDb.OleDbHResult Execute( [In] IntPtr pUnkOuter, [In] ref Guid riid, - [In] System.Data.OleDb.tagDBPARAMS pDBParams, + [In] System.Data.OleDb.tagDBPARAMS? pDBParams, [Out] out IntPtr pcRowsAffected, [Out, MarshalAs(UnmanagedType.Interface)] out object ppRowset); @@ -436,7 +436,7 @@ [out] OLECHAR ** ppCharBuffer [PreserveSig] System.Data.OleDb.OleDbHResult GetLiteralInfo( [In] int cLiterals, - [In, MarshalAs(UnmanagedType.LPArray)] int[] rgLiterals, + [In, MarshalAs(UnmanagedType.LPArray)] int[]? rgLiterals, [Out] out int pcLiteralInfo, [Out] out IntPtr prgLiteralInfo, [Out] out IntPtr ppCharBuffer); @@ -455,7 +455,7 @@ HRESULT GetProperties( [PreserveSig] System.Data.OleDb.OleDbHResult GetProperties( [In] int cPropertyIDSets, - [In] SafeHandle rgPropertyIDSets, + [In] SafeHandle? rgPropertyIDSets, [Out] out int pcPropertySets, [Out] out IntPtr prgPropertySets); @@ -492,7 +492,7 @@ System.Data.OleDb.OleDbHResult GetRowset( [In] IntPtr pUnkOuter, [In] ref Guid rguidSchema, [In] int cRestrictions, - [In, MarshalAs(UnmanagedType.LPArray)] object[] rgRestrictions, + [In, MarshalAs(UnmanagedType.LPArray)] object?[] rgRestrictions, [In] ref Guid riid, [In] int cPropertySets, [In] IntPtr rgPropertySets, @@ -715,7 +715,7 @@ HRESULT GetProperties( [PreserveSig] System.Data.OleDb.OleDbHResult GetProperties( [In] int cPropertyIDSets, - [In] SafeHandle rgPropertyIDSets, + [In] SafeHandle? rgPropertyIDSets, [Out] out int pcPropertySets, [Out] out IntPtr prgPropertySets); @@ -811,7 +811,7 @@ internal delegate System.Data.OleDb.OleDbHResult IDBCreateCommandCreateCommand( IntPtr pThis, // first parameter is always the 'this' value, must use use result from QI IntPtr pUnkOuter, ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] ref object ppCommand); + [MarshalAs(UnmanagedType.Interface)] ref object? ppCommand); // // Advapi32.dll Integrated security functions @@ -840,7 +840,7 @@ internal Trustee(string name) [DllImport(Interop.Libraries.Advapi32, EntryPoint = "CreateWellKnownSid", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern int CreateWellKnownSid( int sidType, - byte[] domainSid, + byte[]? domainSid, [Out] byte[] resultSid, ref uint resultSidLength); } From 2207a35504fa8462648b32200d954a192ce5b97a Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Mon, 27 Jul 2020 15:08:16 +0300 Subject: [PATCH 063/755] [wasm] Remove System.ValueTuple.Tests test suite from the exclusion list (#39957) --- src/libraries/tests.proj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 37ddac60b2de..fd1d83a31723 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -32,7 +32,6 @@ - From 79f984bf5eb6dd1f97787ed4af02d7ed082c65ff Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 27 Jul 2020 16:38:45 +0200 Subject: [PATCH 064/755] Fix build on some libs projects when metadata isn't available (#39960) * Fix build on some libs projects when metadata isn't available * Update references.targets --- eng/references.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/references.targets b/eng/references.targets index 0f3ea17b4a4f..38037cf78ab0 100644 --- a/eng/references.targets +++ b/eng/references.targets @@ -49,7 +49,7 @@ + Condition="$(NetCoreAppLibrary.Contains('%(Filename);'))" /> From 0404a4b26ec5adacbb6af1f0b821e8a003c72557 Mon Sep 17 00:00:00 2001 From: Ganbarukamo41 Date: Tue, 28 Jul 2020 00:26:22 +0900 Subject: [PATCH 065/755] Fix Half comparison (#39773) * Fix Half comparison * Fixes the comparison to be correct when both numbers are negative * Add relevant tests * Add parentheses for clarity * Add tests validating comparison between negative numbers for Single/Double as well --- src/libraries/System.Private.CoreLib/src/System/Half.cs | 4 ++-- src/libraries/System.Runtime/tests/System/DoubleTests.cs | 4 ++++ src/libraries/System.Runtime/tests/System/HalfTests.cs | 4 ++++ src/libraries/System.Runtime/tests/System/SingleTests.cs | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index d124d7a8992d..34adab5856cb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -116,7 +116,7 @@ private ushort Significand // says they should be equal, even if the signs differ. return leftIsNegative && !AreZero(left, right); } - return (short)(left._value) < (short)(right._value); + return (left._value < right._value) ^ leftIsNegative; } public static bool operator >(Half left, Half right) @@ -141,7 +141,7 @@ private ushort Significand // says they should be equal, even if the signs differ. return leftIsNegative || AreZero(left, right); } - return (short)(left._value) <= (short)(right._value); + return (left._value <= right._value) ^ leftIsNegative; } public static bool operator >=(Half left, Half right) diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.cs index 92f413c429aa..3de09c613166 100644 --- a/src/libraries/System.Runtime/tests/System/DoubleTests.cs +++ b/src/libraries/System.Runtime/tests/System/DoubleTests.cs @@ -39,6 +39,10 @@ public static void CompareTo_ObjectNotDouble_ThrowsArgumentException(object valu [InlineData(double.NaN, double.NaN, 0)] [InlineData(double.NaN, 0.0, -1)] [InlineData(234.0, null, 1)] + [InlineData(double.MinValue, double.NegativeInfinity, 1)] + [InlineData(double.NegativeInfinity, double.MinValue, -1)] + [InlineData(-0d, double.NegativeInfinity, 1)] + [InlineData(double.NegativeInfinity, -0d, -1)] public static void CompareTo_Other_ReturnsExpected(double d1, object value, int expected) { if (value is double d2) diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System/HalfTests.cs index 4de5db4c5142..de5eddf9f9dc 100644 --- a/src/libraries/System.Runtime/tests/System/HalfTests.cs +++ b/src/libraries/System.Runtime/tests/System/HalfTests.cs @@ -281,6 +281,10 @@ public static IEnumerable CompareTo_TestData() yield return new object[] { Half.NaN, Half.NaN, 0 }; yield return new object[] { Half.NaN, UInt16BitsToHalf(0x0000), -1 }; yield return new object[] { Half.MaxValue, null, 1 }; + yield return new object[] { Half.MinValue, Half.NegativeInfinity, 1 }; + yield return new object[] { Half.NegativeInfinity, Half.MinValue, -1 }; + yield return new object[] { UInt16BitsToHalf(0x8000), Half.NegativeInfinity, 1 }; // Negative zero + yield return new object[] { Half.NegativeInfinity, UInt16BitsToHalf(0x8000), -1 }; // Negative zero } [Theory] diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.cs b/src/libraries/System.Runtime/tests/System/SingleTests.cs index 53018c7a0b22..a9701f391434 100644 --- a/src/libraries/System.Runtime/tests/System/SingleTests.cs +++ b/src/libraries/System.Runtime/tests/System/SingleTests.cs @@ -40,6 +40,10 @@ public static void CompareTo_ObjectNotFloat_ThrowsArgumentException(object value [InlineData(float.NaN, float.NaN, 0)] [InlineData(float.NaN, 0.0f, -1)] [InlineData(234.0f, null, 1)] + [InlineData(float.MinValue, float.NegativeInfinity, 1)] + [InlineData(float.NegativeInfinity, float.MinValue, -1)] + [InlineData(-0f, float.NegativeInfinity, 1)] + [InlineData(float.NegativeInfinity, -0f, -1)] public static void CompareTo_Other_ReturnsExpected(float f1, object value, int expected) { if (value is float f2) From 824d7709f03d093e48b1ea23f0bad771de6d12dc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 19:59:25 +0200 Subject: [PATCH 066/755] [master] Update dependencies from Microsoft/vstest mono/linker dotnet/icu (#39697) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 10 +++++----- eng/Versions.props | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cf9414cfae45..5004c7a38e1d 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 - 797c523dd8d75096319f3591958f703b8d74d04b + 75440631a7eb7f89da35d5a509d1d5f2eaab7f96 @@ -86,7 +86,7 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest 069d8bd6357e2dbc260a35016ddbefe5dfec4102 @@ -182,9 +182,9 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - f7c8a2a9e5aa47718169140db23c42f3439e6660 + 8224c7254fc4aa5da70bb7d2e0d1c55bca1e19bf https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 8a36d350af35..25c6db6eea46 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -133,7 +133,7 @@ 4.9.4 4.9.4 - 16.8.0-preview-20200716-03 + 16.8.0-preview-20200720-01 1.0.0-prerelease.20352.3 1.0.0-prerelease.20352.3 2.4.1 @@ -146,9 +146,9 @@ 3.0.0-preview-20200715.1 - 5.0.0-preview.3.20366.2 + 5.0.0-preview.3.20374.1 - 5.0.0-preview.8.20370.1 + 5.0.0-preview.8.20373.1 9.0.1-alpha.1.20365.1 9.0.1-alpha.1.20365.1 From 397bb22b0dac4fb971f8269fb086d0002ed39915 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Mon, 27 Jul 2020 22:07:11 +0300 Subject: [PATCH 067/755] [wasm] Mark DiagnosticSource.Switches.Tests with an active issue (#39952) --- .../tests/TestWithConfigSwitches/AssemblyInfo.cs | 6 ++++++ ...ystem.Diagnostics.DiagnosticSource.Switches.Tests.csproj | 2 ++ src/libraries/tests.proj | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/AssemblyInfo.cs diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/AssemblyInfo.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/AssemblyInfo.cs new file mode 100644 index 000000000000..7fe77fb2043e --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/AssemblyInfo.cs @@ -0,0 +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 Xunit; + +[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/38433", TestPlatforms.Browser)] \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/System.Diagnostics.DiagnosticSource.Switches.Tests.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/System.Diagnostics.DiagnosticSource.Switches.Tests.csproj index 04a992f8cd81..1d596d074a3a 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/System.Diagnostics.DiagnosticSource.Switches.Tests.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestWithConfigSwitches/System.Diagnostics.DiagnosticSource.Switches.Tests.csproj @@ -2,8 +2,10 @@ $(NetCoreAppCurrent) true + true + \ No newline at end of file diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index fd1d83a31723..3a61b3e16c98 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -23,7 +23,6 @@ - From 168409e0f96f4d96a7e747dff0a5764b59592cfb Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 27 Jul 2020 12:18:57 -0700 Subject: [PATCH 068/755] Fix JSON possible dupe key issue (#39860) --- .../src/JsonConsoleFormatter.cs | 34 +-- .../tests/JsonConsoleFormatterTests.cs | 193 ++++++++++++++++++ 2 files changed, 214 insertions(+), 13 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs index 418350e892eb..3a5aafe0cffe 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs @@ -41,14 +41,12 @@ public override void Write(in LogEntry logEntry, IExternalScopeP using (var writer = new Utf8JsonWriter(output, FormatterOptions.JsonWriterOptions)) { writer.WriteStartObject(); - string timestamp = null; var timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { DateTimeOffset dateTimeOffset = FormatterOptions.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; - timestamp = dateTimeOffset.ToString(timestampFormat); + writer.WriteString("Timestamp", dateTimeOffset.ToString(timestampFormat)); } - writer.WriteString("Timestamp", timestamp); writer.WriteNumber(nameof(logEntry.EventId), eventId); writer.WriteString(nameof(logEntry.LogLevel), GetLogLevelString(logLevel)); writer.WriteString(nameof(logEntry.Category), category); @@ -77,12 +75,18 @@ public override void Write(in LogEntry logEntry, IExternalScopeP writer.WriteEndObject(); } - if (logEntry.State is IReadOnlyCollection> stateDictionary) + if (logEntry.State != null) { - foreach (KeyValuePair item in stateDictionary) + writer.WriteStartObject(nameof(logEntry.State)); + writer.WriteString("Message", logEntry.State.ToString()); + if (logEntry.State is IReadOnlyCollection> stateProperties) { - writer.WriteString(item.Key, Convert.ToString(item.Value, CultureInfo.InvariantCulture)); + foreach (KeyValuePair item in stateProperties) + { + writer.WriteString(item.Key, ToInvariantString(item.Value)); + } } + writer.WriteEndObject(); } WriteScopeInformation(writer, scopeProvider); writer.WriteEndObject(); @@ -115,26 +119,30 @@ private void WriteScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider { if (FormatterOptions.IncludeScopes && scopeProvider != null) { - int numScopes = 0; - writer.WriteStartObject("Scopes"); + writer.WriteStartArray("Scopes"); scopeProvider.ForEachScope((scope, state) => { - if (scope is IReadOnlyCollection> scopeDictionary) + if (scope is IReadOnlyCollection> scopes) { - foreach (KeyValuePair item in scopeDictionary) + state.WriteStartObject(); + state.WriteString("Message", scope.ToString()); + foreach (KeyValuePair item in scopes) { - state.WriteString(item.Key, Convert.ToString(item.Value, CultureInfo.InvariantCulture)); + state.WriteString(item.Key, ToInvariantString(item.Value)); } + state.WriteEndObject(); } else { - state.WriteString(numScopes++.ToString(), scope.ToString()); + state.WriteStringValue(ToInvariantString(scope)); } }, writer); - writer.WriteEndObject(); + writer.WriteEndArray(); } } + private static string ToInvariantString(object obj) => Convert.ToString(obj, CultureInfo.InvariantCulture); + internal JsonConsoleFormatterOptions FormatterOptions { get; set; } private void ReloadLoggerOptions(JsonConsoleFormatterOptions options) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs index f5e536d94adb..09f4050a9ed4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs @@ -44,5 +44,198 @@ public void NoLogScope_DoesNotWriteAnyScopeContentToOutput_Json() Assert.Contains("123", write.Message); Assert.Contains("SimpleScope", write.Message); } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_TimestampFormatSet_ContainsTimestamp() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + TimestampFormat = "hh:mm:ss ", + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + var exception = new InvalidOperationException("Invalid value"); + + // Act + logger.LogCritical(eventId: 0, message: null); + + // Assert + Assert.Equal(1, sink.Writes.Count); + Assert.Contains( + "\"Timestamp\":", + GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_NullMessage_LogsWhenMessageIsNotProvided() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false } + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + var exception = new InvalidOperationException("Invalid value"); + + // Act + logger.LogCritical(eventId: 0, exception: null, message: null); + logger.LogCritical(eventId: 0, message: null); + logger.LogCritical(eventId: 0, message: null, exception: exception); + + // Assert + Assert.Equal(3, sink.Writes.Count); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Critical\",\"Category\":\"test\",\"Message\":\"[null]\"" + + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" + + Environment.NewLine, + GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Critical\",\"Category\":\"test\",\"Message\":\"[null]\"" + + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" + + Environment.NewLine, + GetMessage(sink.Writes.GetRange(1 * t.WritesPerMsg, t.WritesPerMsg))); + + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Critical\",\"Category\":\"test\"" + + ",\"Message\":\"[null]\"" + + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" + + Environment.NewLine, + GetMessage(sink.Writes.GetRange(2 * t.WritesPerMsg, t.WritesPerMsg))); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_ExceptionWithMessage_ExtractsInfo() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + var exception = new InvalidOperationException("Invalid value"); + + // Act + logger.LogInformation(exception, "exception message with {0}", "stacktrace"); + logger.Log(LogLevel.Information, 0, state: "exception message", exception: exception, formatter: (a, b) => a); + + using (logger.BeginScope("scope1 {name1}", 123)) + using (logger.BeginScope("scope2 {name1} {name2}", 456, 789)) + logger.Log(LogLevel.Information, 0, state: "exception message", exception: exception, formatter: (a, b) => a); + + // Assert + Assert.Equal(3, sink.Writes.Count); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + + ",\"Message\":\"exception message with stacktrace\"" + + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + + ",\"State\":{\"Message\":\"exception message with stacktrace\",\"0\":\"stacktrace\",\"{OriginalFormat}\":\"exception message with {0}\"}" + + ",\"Scopes\":[]" + +"}" + Environment.NewLine, + GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + + ",\"Message\":\"exception message\"" + + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + + ",\"State\":{\"Message\":\"exception message\"}" + + ",\"Scopes\":[]" + +"}" + Environment.NewLine, + GetMessage(sink.Writes.GetRange(1 * t.WritesPerMsg, t.WritesPerMsg))); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + + ",\"Message\":\"exception message\"" + + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + + ",\"State\":{\"Message\":\"exception message\"}" + + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":\"123\",\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":\"456\",\"name2\":\"789\",\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" + +"}" + Environment.NewLine, + GetMessage(sink.Writes.GetRange(2 * t.WritesPerMsg, t.WritesPerMsg))); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_IncludeScopes_ContainsDuplicateNamedPropertiesInScope_AcceptableJson() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + + // Act + using (logger.BeginScope("scope1 {name1}", 123)) + using (logger.BeginScope("scope2 {name1} {name2}", 456, 789)) + logger.Log(LogLevel.Information, 0, state: "exception message", exception: null, formatter: (a, b) => a); + + // Assert + Assert.Equal(1, sink.Writes.Count); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + + ",\"Message\":\"exception message\"" + + ",\"State\":{\"Message\":\"exception message\"}" + + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":\"123\",\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":\"456\",\"name2\":\"789\",\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" + +"}" + Environment.NewLine, + GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_StateAndScopeAreCollections_IncludesMessageAndCollectionValues() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + + // Act + using (logger.BeginScope("{Number}", 2)) + using (logger.BeginScope("{AnotherNumber}", 3)) + { + logger.LogInformation("{LogEntryNumber}", 1); + } + + // Assert + Assert.Equal(1, sink.Writes.Count); + Assert.Equal( + "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + + ",\"Message\":\"1\"" + + ",\"State\":{\"Message\":\"1\",\"LogEntryNumber\":\"1\",\"{OriginalFormat}\":\"{LogEntryNumber}\"}" + + ",\"Scopes\":[{\"Message\":\"2\",\"Number\":\"2\",\"{OriginalFormat}\":\"{Number}\"},{\"Message\":\"3\",\"AnotherNumber\":\"3\",\"{OriginalFormat}\":\"{AnotherNumber}\"}]" + +"}" + Environment.NewLine, + GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); + } } } From 1fad4a5b655ab26d71f4e851e4f5f522ae199cb1 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 27 Jul 2020 14:02:32 -0700 Subject: [PATCH 069/755] Add nullability annotations to files in XPath folder (#39821) * Add nullability annotations to files in XPath folder * Address feedback from krwq * Make changes based on recently merged annotations * Mark resolver parameter in SelectSingleNode as nullable --- .../System/Xml/Cache/XPathDocumentIterator.cs | 11 +- .../Xml/Cache/XPathDocumentNavigator.cs | 92 +++++++------- .../src/System/Xml/Core/XmlWriter.cs | 2 +- .../src/System/Xml/Core/XmlWriterAsync.cs | 2 +- .../src/System/Xml/Dom/XPathNodeList.cs | 5 +- .../src/System/Xml/Schema/Asttree.cs | 12 +- .../System/Xml/Schema/XmlSchemaAttribute.cs | 4 +- .../src/System/Xml/Schema/XmlSchemaElement.cs | 4 +- .../src/System/Xml/Schema/XmlSchemaType.cs | 4 +- .../src/System/Xml/XPath/IXPathNavigable.cs | 3 +- .../Xml/XPath/Internal/AbsoluteQuery.cs | 5 +- .../src/System/Xml/XPath/Internal/AstNode.cs | 1 + .../Xml/XPath/Internal/AttributeQuery.cs | 6 +- .../src/System/Xml/XPath/Internal/Axis.cs | 13 +- .../Xml/XPath/Internal/BaseAxisQuery.cs | 10 +- .../System/Xml/XPath/Internal/BooleanExpr.cs | 1 + .../Xml/XPath/Internal/BooleanFunctions.cs | 14 ++- .../Xml/XPath/Internal/CacheAxisQuery.cs | 5 +- .../Xml/XPath/Internal/CacheChildrenQuery.cs | 17 +-- .../Xml/XPath/Internal/CacheOutputQuery.cs | 5 +- .../Xml/XPath/Internal/ChildrenQuery.cs | 9 +- .../Xml/XPath/Internal/ClonableStack.cs | 1 + .../Xml/XPath/Internal/CompiledXPathExpr.cs | 19 +-- .../System/Xml/XPath/Internal/ContextQuery.cs | 9 +- .../Xml/XPath/Internal/DescendantBaseQuery.cs | 5 +- .../Xml/XPath/Internal/DescendantQuery.cs | 9 +- .../Internal/DescendantoverDescendantQuery.cs | 6 +- .../Xml/XPath/Internal/DocumentorderQuery.cs | 5 +- .../System/Xml/XPath/Internal/EmptyQuery.cs | 5 +- .../Xml/XPath/Internal/ExtensionQuery.cs | 22 ++-- .../src/System/Xml/XPath/Internal/Filter.cs | 1 + .../System/Xml/XPath/Internal/FilterQuery.cs | 17 +-- .../Xml/XPath/Internal/FollSiblingQuery.cs | 11 +- .../Xml/XPath/Internal/FollowingQuery.cs | 12 +- .../XPath/Internal/ForwardPositionQuery.cs | 5 +- .../src/System/Xml/XPath/Internal/Function.cs | 9 +- .../Xml/XPath/Internal/FunctionQuery.cs | 20 ++- .../src/System/Xml/XPath/Internal/Group.cs | 1 + .../System/Xml/XPath/Internal/GroupQuery.cs | 3 +- .../src/System/Xml/XPath/Internal/IdQuery.cs | 13 +- .../Xml/XPath/Internal/IteratorFilter.cs | 5 +- .../System/Xml/XPath/Internal/LogicalExpr.cs | 38 +++--- .../Xml/XPath/Internal/MergeFilterQuery.cs | 11 +- .../Xml/XPath/Internal/NamespaceQuery.cs | 5 +- .../Xml/XPath/Internal/NodeFunctions.cs | 15 +-- .../Xml/XPath/Internal/NumberFunctions.cs | 17 ++- .../System/Xml/XPath/Internal/NumericExpr.cs | 1 + .../src/System/Xml/XPath/Internal/Operand.cs | 1 + .../System/Xml/XPath/Internal/OperandQuery.cs | 1 + .../src/System/Xml/XPath/Internal/Operator.cs | 1 + .../System/Xml/XPath/Internal/ParentQuery.cs | 3 +- .../Xml/XPath/Internal/PreSiblingQuery.cs | 1 + .../Xml/XPath/Internal/PrecedingQuery.cs | 9 +- .../src/System/Xml/XPath/Internal/Query.cs | 15 ++- .../System/Xml/XPath/Internal/QueryBuilder.cs | 32 ++--- .../Xml/XPath/Internal/ResetableIterator.cs | 1 + .../XPath/Internal/ReversePositionQuery.cs | 1 + .../src/System/Xml/XPath/Internal/Root.cs | 1 + .../System/Xml/XPath/Internal/SortQuery.cs | 9 +- .../Xml/XPath/Internal/StringFunctions.cs | 40 +++--- .../System/Xml/XPath/Internal/UnionExpr.cs | 15 +-- .../System/Xml/XPath/Internal/ValueQuery.cs | 1 + .../src/System/Xml/XPath/Internal/Variable.cs | 1 + .../Xml/XPath/Internal/VariableQuery.cs | 13 +- .../XPath/Internal/XPathAncestorIterator.cs | 1 + .../Xml/XPath/Internal/XPathAncestorQuery.cs | 5 +- .../Xml/XPath/Internal/XPathArrayIterator.cs | 8 +- .../Xml/XPath/Internal/XPathAxisIterator.cs | 5 +- .../Xml/XPath/Internal/XPathChildIterator.cs | 1 + .../XPath/Internal/XPathDescendantIterator.cs | 1 + .../Xml/XPath/Internal/XPathEmptyIterator.cs | 3 +- .../Xml/XPath/Internal/XPathMultyIterator.cs | 13 +- .../System/Xml/XPath/Internal/XPathParser.cs | 49 ++++---- .../System/Xml/XPath/Internal/XPathScanner.cs | 7 +- .../XPath/Internal/XPathSelectionIterator.cs | 3 +- .../Xml/XPath/Internal/XPathSelfQuery.cs | 3 +- .../XPath/Internal/XPathSingletonIterator.cs | 1 + .../src/System/Xml/XPath/XPathDocument.cs | 29 +++-- .../src/System/Xml/XPath/XPathException.cs | 27 ++-- .../src/System/Xml/XPath/XPathExpr.cs | 3 +- .../src/System/Xml/XPath/XPathItem.cs | 5 +- .../System/Xml/XPath/XPathNamespaceScope.cs | 1 + .../src/System/Xml/XPath/XPathNavigator.cs | 119 +++++++++--------- .../Xml/XPath/XPathNavigatorKeyComparer.cs | 13 +- .../System/Xml/XPath/XPathNavigatorReader.cs | 111 ++++++++-------- .../src/System/Xml/XPath/XPathNodeIterator.cs | 8 +- .../src/System/Xml/XPath/XPathNodeType.cs | 1 + .../src/System/Xml/XmlConvert.cs | 2 +- 88 files changed, 609 insertions(+), 445 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentIterator.cs index af2d3d91484a..bcdaaabb7af0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentIterator.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. +#nullable enable using System; using System.Xml.XPath; @@ -54,7 +55,8 @@ public override int CurrentPosition /// internal class XPathDocumentElementChildIterator : XPathDocumentBaseIterator { - private readonly string _localName, _namespaceUri; + private readonly string? _localName; + private readonly string _namespaceUri; /// /// Create an iterator that ranges over all element children of "parent" having the specified QName. @@ -164,8 +166,9 @@ public override bool MoveNext() /// internal class XPathDocumentElementDescendantIterator : XPathDocumentBaseIterator { - private readonly XPathDocumentNavigator _end; - private readonly string _localName, _namespaceUri; + private readonly XPathDocumentNavigator? _end; + private readonly string? _localName; + private readonly string _namespaceUri; private bool _matchSelf; /// @@ -236,7 +239,7 @@ public override bool MoveNext() /// internal class XPathDocumentKindDescendantIterator : XPathDocumentBaseIterator { - private readonly XPathDocumentNavigator _end; + private readonly XPathDocumentNavigator? _end; private readonly XPathNodeType _typ; private bool _matchSelf; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs index 51b98d48d438..3ece1a4ce15f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.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. +#nullable enable using System.Diagnostics; using System.Text; using System.Xml; @@ -15,10 +16,10 @@ namespace MS.Internal.Xml.Cache internal sealed class XPathDocumentNavigator : XPathNavigator, IXmlLineInfo { private XPathNode[] _pageCurrent; - private XPathNode[] _pageParent; + private XPathNode[]? _pageParent; private int _idxCurrent; private int _idxParent; - private string _atomizedLocalName; + private string? _atomizedLocalName; //----------------------------------------------- @@ -29,7 +30,7 @@ internal sealed class XPathDocumentNavigator : XPathNavigator, IXmlLineInfo /// Create a new navigator positioned on the specified current node. If the current node is a namespace or a collapsed /// text node, then the parent is a virtualized parent (may be different than .Parent on the current node). /// - public XPathDocumentNavigator(XPathNode[] pageCurrent, int idxCurrent, XPathNode[] pageParent, int idxParent) + public XPathDocumentNavigator(XPathNode[]? pageCurrent, int idxCurrent, XPathNode[]? pageParent, int idxParent) { Debug.Assert(pageCurrent != null && idxCurrent != 0); Debug.Assert((pageParent == null) == (idxParent == 0)); @@ -63,7 +64,8 @@ public override string Value get { string value; - XPathNode[] page, pageEnd; + XPathNode[] page; + XPathNode[]? pageEnd; int idx, idxEnd; // Try to get the pre-computed string value of the node @@ -82,7 +84,7 @@ public override string Value break; case XPathNodeType.Text: - Debug.Assert(_idxParent != 0 && _pageParent[_idxParent].HasCollapsedText, + Debug.Assert(_idxParent != 0 && _pageParent![_idxParent].HasCollapsedText, "ReadStringValue() should have taken care of anything but collapsed text."); break; } @@ -92,12 +94,12 @@ public override string Value if (_idxParent != 0) { Debug.Assert(_pageCurrent[_idxCurrent].NodeType == XPathNodeType.Text); - return _pageParent[_idxParent].Value; + return _pageParent![_idxParent].Value; } // Must be node with complex content, so concatenate the string values of all text descendants string s = string.Empty; - StringBuilder bldr = null; + StringBuilder? bldr = null; // Get all text nodes which follow the current node in document order, but which are still descendants page = pageEnd = _pageCurrent; @@ -197,7 +199,7 @@ public override string BaseURI if (_idxParent != 0) { // Get BaseUri of parent for attribute, namespace, and collapsed text nodes - page = _pageParent; + page = _pageParent!; idx = _idxParent; } else @@ -285,12 +287,12 @@ public override bool HasAttributes /// attribute can be found, return false. Don't assume the name parts are atomized with respect /// to this document. /// - public override bool MoveToAttribute(string localName, string namespaceURI) + public override bool MoveToAttribute(string? localName, string namespaceURI) { XPathNode[] page = _pageCurrent; int idx = _idxCurrent; - if ((object)localName != (object)_atomizedLocalName) + if ((object?)localName != (object?)_atomizedLocalName) _atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; if (XPathNodeHelper.GetAttribute(ref _pageCurrent, ref _idxCurrent, _atomizedLocalName, namespaceURI)) @@ -370,7 +372,7 @@ public override bool MoveToNextNamespace(XPathNamespaceScope scope) case XPathNamespaceScope.Local: // Once parent changes, there are no longer any local namespaces idxParent = page[idx].GetParent(out pageParent); - if (idxParent != _idxParent || (object)pageParent != (object)_pageParent) + if (idxParent != _idxParent || (object)pageParent != (object?)_pageParent) return false; break; @@ -424,7 +426,8 @@ public override bool MoveToFirstChild() // Virtualize collapsed text nodes _pageParent = _pageCurrent; _idxParent = _idxCurrent; - _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent); + _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent!); + Debug.Assert(_pageCurrent != null); return true; } @@ -461,7 +464,7 @@ public override bool MoveToParent() /// public override bool MoveTo(XPathNavigator other) { - XPathDocumentNavigator that = other as XPathDocumentNavigator; + XPathDocumentNavigator? that = other as XPathDocumentNavigator; if (that != null) { _pageCurrent = that._pageCurrent; @@ -478,12 +481,13 @@ public override bool MoveTo(XPathNavigator other) /// public override bool MoveToId(string id) { - XPathNode[] page; + XPathNode[]? page; int idx; idx = _pageCurrent[_idxCurrent].Document.LookupIdElement(id, out page); if (idx != 0) { + Debug.Assert(page != null); // Move to ID element and clear parent state Debug.Assert(page[idx].NodeType == XPathNodeType.Element); _pageCurrent = page; @@ -502,7 +506,7 @@ public override bool MoveToId(string id) /// public override bool IsSamePosition(XPathNavigator other) { - XPathDocumentNavigator that = other as XPathDocumentNavigator; + XPathDocumentNavigator? that = other as XPathDocumentNavigator; if (that != null) { return _idxCurrent == that._idxCurrent && _pageCurrent == that._pageCurrent && @@ -537,9 +541,9 @@ public override void MoveToRoot() /// Move to the first element child of the current node with the specified name. Return false /// if the current node has no matching element children. /// - public override bool MoveToChild(string localName, string namespaceURI) + public override bool MoveToChild(string? localName, string namespaceURI) { - if ((object)localName != (object)_atomizedLocalName) + if ((object?)localName != (object?)_atomizedLocalName) _atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; return XPathNodeHelper.GetElementChild(ref _pageCurrent, ref _idxCurrent, _atomizedLocalName, namespaceURI); @@ -549,9 +553,9 @@ public override bool MoveToChild(string localName, string namespaceURI) /// Move to the first element sibling of the current node with the specified name. Return false /// if the current node has no matching element siblings. /// - public override bool MoveToNext(string localName, string namespaceURI) + public override bool MoveToNext(string? localName, string namespaceURI) { - if ((object)localName != (object)_atomizedLocalName) + if ((object?)localName != (object?)_atomizedLocalName) _atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; return XPathNodeHelper.GetElementSibling(ref _pageCurrent, ref _idxCurrent, _atomizedLocalName, namespaceURI); @@ -572,7 +576,8 @@ public override bool MoveToChild(XPathNodeType type) // Virtualize collapsed text nodes _pageParent = _pageCurrent; _idxParent = _idxCurrent; - _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent); + _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent!); + Debug.Assert(_pageCurrent != null); return true; } @@ -595,12 +600,12 @@ public override bool MoveToNext(XPathNodeType type) /// 3. Has the specified QName /// Return false if the current node has no matching following elements. /// - public override bool MoveToFollowing(string localName, string namespaceURI, XPathNavigator end) + public override bool MoveToFollowing(string? localName, string namespaceURI, XPathNavigator? end) { - XPathNode[] pageEnd; + XPathNode[]? pageEnd; int idxEnd; - if ((object)localName != (object)_atomizedLocalName) + if ((object?)localName != (object?)_atomizedLocalName) _atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; // Get node on which scan ends (null if rest of document should be scanned) @@ -629,10 +634,11 @@ public override bool MoveToFollowing(string localName, string namespaceURI, XPat /// 3. Has the specified XPathNodeType /// Return false if the current node has no matching following nodes. /// - public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) + public override bool MoveToFollowing(XPathNodeType type, XPathNavigator? end) { - XPathDocumentNavigator endTiny = end as XPathDocumentNavigator; - XPathNode[] page, pageEnd; + XPathDocumentNavigator? endTiny = end as XPathDocumentNavigator; + XPathNode[] page; + XPathNode[]? pageEnd; int idx, idxEnd; // If searching for text, make sure to handle collapsed text nodes correctly @@ -649,7 +655,8 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) _pageParent = _pageCurrent; _idxParent = _idxCurrent; - _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent); + _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent!); + Debug.Assert(_pageCurrent != null); return true; } @@ -661,7 +668,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) // If this navigator is positioned on a virtual node, then compute following of parent if (_idxParent != 0) { - page = _pageParent; + page = _pageParent!; idx = _idxParent; } else @@ -682,7 +689,8 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { // Virtualize collapsed text nodes Debug.Assert(page[idx].HasCollapsedText); - _idxCurrent = page[idx].Document.GetCollapsedTextNode(out _pageCurrent); + _idxCurrent = page[idx].Document.GetCollapsedTextNode(out _pageCurrent!); + Debug.Assert(_pageCurrent != null); _pageParent = page; _idxParent = idx; } @@ -732,7 +740,7 @@ public override XPathNodeIterator SelectChildren(XPathNodeType type) public override XPathNodeIterator SelectChildren(string name, string namespaceURI) { // If local name is wildcard, then call XPathNavigator.SelectChildren - if (name == null || name.Length == 0) + if (name.Length == 0) return base.SelectChildren(name, namespaceURI); return new XPathDocumentElementChildIterator(this, name, namespaceURI); @@ -754,7 +762,7 @@ public override XPathNodeIterator SelectDescendants(XPathNodeType type, bool mat public override XPathNodeIterator SelectDescendants(string name, string namespaceURI, bool matchSelf) { // If local name is wildcard, then call XPathNavigator.SelectDescendants - if (name == null || name.Length == 0) + if (name.Length == 0) return base.SelectDescendants(name, namespaceURI, matchSelf); return new XPathDocumentElementDescendantIterator(this, name, namespaceURI, matchSelf); @@ -770,9 +778,9 @@ public override XPathNodeIterator SelectDescendants(string name, string namespac /// in document order. /// XmlNodeOrder.Same -- This navigator is positioned on the same node as the "other" navigator. /// - public override XmlNodeOrder ComparePosition(XPathNavigator other) + public override XmlNodeOrder ComparePosition(XPathNavigator? other) { - XPathDocumentNavigator that = other as XPathDocumentNavigator; + XPathDocumentNavigator? that = other as XPathDocumentNavigator; if (that != null) { XPathDocument thisDoc = _pageCurrent[_idxCurrent].Document; @@ -799,9 +807,9 @@ public override XmlNodeOrder ComparePosition(XPathNavigator other) /// /// Return true if the "other" navigator's current node is a descendant of this navigator's current node. /// - public override bool IsDescendant(XPathNavigator other) + public override bool IsDescendant(XPathNavigator? other) { - XPathDocumentNavigator that = other as XPathDocumentNavigator; + XPathDocumentNavigator? that = other as XPathDocumentNavigator; if (that != null) { XPathNode[] pageThat; @@ -810,7 +818,7 @@ public override bool IsDescendant(XPathNavigator other) // If that current node's parent is virtualized, then start with the virtual parent if (that._idxParent != 0) { - pageThat = that._pageParent; + pageThat = that._pageParent!; idxThat = that._idxParent; } else @@ -893,7 +901,7 @@ internal override string UniqueId // If the current node is virtualized, code its parent if (_idxParent != 0) { - loc = (_pageParent[0].PageInfo.PageNumber - 1) << 16 | (_idxParent - 1); + loc = (_pageParent![0].PageInfo.PageNumber - 1) << 16 | (_idxParent - 1); do { buf[idx++] = UniqueIdTbl[loc & 0x1f]; @@ -947,7 +955,7 @@ public int LineNumber { // If the current node is a collapsed text node, then return parent element's line number if (_idxParent != 0 && NodeType == XPathNodeType.Text) - return _pageParent[_idxParent].LineNumber; + return _pageParent![_idxParent].LineNumber; return _pageCurrent[_idxCurrent].LineNumber; } @@ -962,7 +970,7 @@ public int LinePosition { // If the current node is a collapsed text node, then get position from parent element if (_idxParent != 0 && NodeType == XPathNodeType.Text) - return _pageParent[_idxParent].CollapsedLinePosition; + return _pageParent![_idxParent].CollapsedLinePosition; return _pageCurrent[_idxCurrent].LinePosition; } @@ -984,9 +992,9 @@ public int GetPositionHashCode() /// /// Return true if navigator is positioned to an element having the specified name. /// - public bool IsElementMatch(string localName, string namespaceURI) + public bool IsElementMatch(string? localName, string namespaceURI) { - if ((object)localName != (object)_atomizedLocalName) + if ((object?)localName != (object?)_atomizedLocalName) _atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; // Cannot be an element if parent is stored @@ -1011,7 +1019,7 @@ public bool IsKindMatch(XPathNodeType typ) /// 1. If useParentOfVirtual is true, then return the page and index of the virtual node's parent /// 2. If useParentOfVirtual is false, then return the page and index of the virtual node's parent + 1. /// - private int GetFollowingEnd(XPathDocumentNavigator end, bool useParentOfVirtual, out XPathNode[] pageEnd) + private int GetFollowingEnd(XPathDocumentNavigator? end, bool useParentOfVirtual, out XPathNode[]? pageEnd) { // If ending navigator is positioned to a node in another document, then return null if (end != null && _pageCurrent[_idxCurrent].Document == end._pageCurrent[end._idxCurrent].Document) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs index 8c15b6def4e1..90c848747ad4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs @@ -490,7 +490,7 @@ public virtual void WriteNode(XPathNavigator navigator, bool defattr) { do { - IXmlSchemaInfo schemaInfo = navigator.SchemaInfo; + IXmlSchemaInfo? schemaInfo = navigator.SchemaInfo; if (defattr || (schemaInfo == null || !schemaInfo.IsDefault)) { WriteStartAttribute(navigator.Prefix, navigator.LocalName, navigator.NamespaceURI); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs index b35c292262e0..703d0e101a68 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterAsync.cs @@ -466,7 +466,7 @@ public virtual async Task WriteNodeAsync(XPathNavigator navigator, bool defattr) { do { - IXmlSchemaInfo schemaInfo = navigator.SchemaInfo; + IXmlSchemaInfo? schemaInfo = navigator.SchemaInfo; if (defattr || (schemaInfo == null || !schemaInfo.IsDefault)) { await WriteStartAttributeAsync(navigator.Prefix, navigator.LocalName, navigator.NamespaceURI).ConfigureAwait(false); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs index 520267634f86..4a0ffa3f53c5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XPathNodeList.cs @@ -34,7 +34,7 @@ public override int Count } } - private XmlNode GetNode(XPathNavigator n) + private XmlNode? GetNode(XPathNavigator n) { IHasXmlNode iHasNode = (IHasXmlNode)n; return iHasNode.GetNode(); @@ -47,7 +47,8 @@ internal int ReadUntil(int index) { if (_nodeIterator.MoveNext()) { - XmlNode n = GetNode(_nodeIterator.Current); + Debug.Assert(_nodeIterator.Current != null); + XmlNode? n = GetNode(_nodeIterator.Current); if (n != null) { _list.Add(n); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Asttree.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Asttree.cs index f30dc546f209..7fefb7ac0606 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Asttree.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Asttree.cs @@ -416,7 +416,7 @@ internal Axis? Next } //constructor - internal DoubleLinkAxis(Axis axis, DoubleLinkAxis inputaxis) + internal DoubleLinkAxis(Axis axis, DoubleLinkAxis? inputaxis) : base(axis.TypeOfAxis, inputaxis, axis.Prefix, axis.Name, axis.NodeType) { this.next = null; @@ -437,7 +437,7 @@ internal DoubleLinkAxis(Axis axis, DoubleLinkAxis inputaxis) return null; } - return new DoubleLinkAxis(axis, ConvertTree((Axis)axis.Input)); + return new DoubleLinkAxis(axis, ConvertTree((Axis?)axis.Input)); } } @@ -575,7 +575,7 @@ public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr) throw new XmlSchemaException(SR.Sch_ICXpathError, xPath); } - Axis stepAst; + Axis? stepAst; for (int i = 0; i < AstArray.Count; ++i) { Axis ast = (Axis)AstArray[i]!; @@ -603,7 +603,7 @@ public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr) SetURN(stepAst, nsmgr); try { - stepAst = (Axis)(stepAst.Input); + stepAst = (Axis?)(stepAst.Input); } catch { @@ -631,7 +631,7 @@ public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr) } try { - stepAst = (Axis)(stepAst.Input); + stepAst = (Axis?)(stepAst.Input); } catch { @@ -660,7 +660,7 @@ public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr) } try { - stepAst = (Axis)(stepAst.Input); + stepAst = (Axis?)(stepAst.Input); } catch { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs index d191b5e2298c..0f8fe5f74fd3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs @@ -4,6 +4,7 @@ #nullable enable using System.Collections; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Xml.Serialization; namespace System.Xml.Schema @@ -113,7 +114,8 @@ public XmlSchemaSimpleType? AttributeSchemaType get { return _attributeType; } } - internal XmlReader? Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) + [return: NotNullIfNotNull("schemaSet")] + internal XmlReader? Validate(XmlReader reader, XmlResolver? resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) { if (schemaSet != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs index a8d41372e1ea..7ea0845bf01b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Xml.Serialization; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Schema { @@ -195,7 +196,8 @@ public XmlSchemaDerivationMethod FinalResolved get { return _finalResolved; } } - internal XmlReader? Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) + [return: NotNullIfNotNull("schemaSet")] + internal XmlReader? Validate(XmlReader reader, XmlResolver? resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) { if (schemaSet != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs index c00a0d58c946..b3a10c4e1984 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs @@ -4,6 +4,7 @@ #nullable enable using System.Collections; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Xml.Serialization; namespace System.Xml.Schema @@ -209,7 +210,8 @@ internal XmlValueConverter ValueConverter } } - internal XmlReader? Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) + [return: NotNullIfNotNull("schemaSet")] + internal XmlReader? Validate(XmlReader reader, XmlResolver? resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) { if (schemaSet != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/IXPathNavigable.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/IXPathNavigable.cs index 48e81316b307..30154d43cfde 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/IXPathNavigable.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/IXPathNavigable.cs @@ -1,10 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml.XPath { public interface IXPathNavigable { - XPathNavigator CreateNavigator(); + XPathNavigator? CreateNavigator(); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AbsoluteQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AbsoluteQuery.cs index 57e041492341..e50788851e5c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AbsoluteQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AbsoluteQuery.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. +#nullable enable +using System.Diagnostics; using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -12,13 +14,14 @@ private AbsoluteQuery(AbsoluteQuery other) : base(other) { } public override object Evaluate(XPathNodeIterator context) { + Debug.Assert(context.Current != null); base.contextNode = context.Current.Clone(); base.contextNode.MoveToRoot(); count = 0; return this; } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { if (context != null && context.NodeType == XPathNodeType.Root) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AstNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AstNode.cs index 77990da06fed..0ffc5380a22e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AstNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AstNode.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AttributeQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AttributeQuery.cs index b152fd938741..eea9f6fb04cb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AttributeQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/AttributeQuery.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -22,7 +23,7 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (true) { @@ -39,6 +40,7 @@ public override XPathNavigator Advance() } else { + Debug.Assert(currentNode != null); _onAttribute = currentNode.MoveToNextAttribute(); } @@ -54,7 +56,7 @@ public override XPathNavigator Advance() } // while } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { if (context != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Axis.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Axis.cs index ebf10976b732..d29b580aab14 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Axis.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Axis.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -9,7 +10,7 @@ namespace MS.Internal.Xml.XPath internal class Axis : AstNode { private readonly AxisType _axisType; - private AstNode _input; + private AstNode? _input; private readonly string _prefix; private readonly string _name; private readonly XPathNodeType _nodeType; @@ -34,7 +35,7 @@ public enum AxisType }; // constructor - public Axis(AxisType axisType, AstNode input, string prefix, string name, XPathNodeType nodetype) + public Axis(AxisType axisType, AstNode? input, string prefix, string name, XPathNodeType nodetype) { Debug.Assert(prefix != null); Debug.Assert(name != null); @@ -46,7 +47,7 @@ public Axis(AxisType axisType, AstNode input, string prefix, string name, XPathN } // constructor - public Axis(AxisType axisType, AstNode input) + public Axis(AxisType axisType, AstNode? input) : this(axisType, input, string.Empty, string.Empty, XPathNodeType.All) { this.abbrAxis = true; @@ -56,7 +57,7 @@ public Axis(AxisType axisType, AstNode input) public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; } } - public AstNode Input + public AstNode? Input { get { return _input; } set { _input = value; } @@ -69,8 +70,8 @@ public AstNode Input public bool AbbrAxis { get { return abbrAxis; } } // Used by AstTree in Schema - private string _urn = string.Empty; - public string Urn + private string? _urn = string.Empty; + public string? Urn { get { return _urn; } set { _urn = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BaseAxisQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BaseAxisQuery.cs index 330137bf344b..bdc4cc22459c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BaseAxisQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BaseAxisQuery.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -14,12 +15,12 @@ internal abstract class BaseAxisQuery : Query private readonly bool _nameTest; private readonly string _name; private readonly string _prefix; - private string _nsUri; + private string? _nsUri; private readonly XPathNodeType _typeTest; // these two things are the state of this class // that need to be reset whenever the context changes. - protected XPathNavigator currentNode; + protected XPathNavigator? currentNode; protected int position; protected BaseAxisQuery(Query qyInput) @@ -67,12 +68,12 @@ public override void SetXsltContext(XsltContext context) } protected string Name { get { return _name; } } - protected string Namespace { get { return _nsUri; } } + protected string? Namespace { get { return _nsUri; } } protected bool NameTest { get { return _nameTest; } } protected XPathNodeType TypeTest { get { return _typeTest; } } public override int CurrentPosition { get { return position; } } - public override XPathNavigator Current { get { return currentNode; } } + public override XPathNavigator? Current { get { return currentNode; } } public virtual bool matches(XPathNavigator e) { @@ -86,6 +87,7 @@ public virtual bool matches(XPathNavigator e) { if (_name.Equals(e.LocalName) || _name.Length == 0) { + Debug.Assert(_nsUri != null); if (_nsUri.Equals(e.NamespaceURI)) { return true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanExpr.cs index 4cf058b90289..2174615d51d7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanExpr.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs index 7b5c13e573be..ae0e4144c36e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.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. +#nullable enable using System; using System.Diagnostics; using System.Xml; @@ -12,10 +13,10 @@ namespace MS.Internal.Xml.XPath { internal sealed class BooleanFunctions : ValueQuery { - private readonly Query _arg; + private readonly Query? _arg; private readonly FT _funcType; - public BooleanFunctions(FT funcType, Query arg) + public BooleanFunctions(FT funcType, Query? arg) { _arg = arg; _funcType = funcType; @@ -56,10 +57,10 @@ internal static bool toBoolean(string str) internal bool toBoolean(XPathNodeIterator nodeIterator) { - object result = _arg.Evaluate(nodeIterator); + object result = _arg!.Evaluate(nodeIterator); if (result is XPathNodeIterator) return _arg.Advance() != null; - string str = result as string; + string? str = result as string; if (str != null) return toBoolean(str); @@ -73,12 +74,13 @@ internal bool toBoolean(XPathNodeIterator nodeIterator) private bool Not(XPathNodeIterator nodeIterator) { - return !(bool)_arg.Evaluate(nodeIterator); + return !(bool)_arg!.Evaluate(nodeIterator); } private bool Lang(XPathNodeIterator nodeIterator) { - string str = _arg.Evaluate(nodeIterator).ToString(); + string str = _arg!.Evaluate(nodeIterator).ToString()!; + Debug.Assert(nodeIterator.Current != null); string lang = nodeIterator.Current.XmlLang; return ( lang.StartsWith(str, StringComparison.OrdinalIgnoreCase) && diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheAxisQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheAxisQuery.cs index d2b45ba505cb..a01d88dd7c36 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheAxisQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheAxisQuery.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml.XPath; @@ -35,7 +36,7 @@ public override object Evaluate(XPathNodeIterator context) return this; } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { Debug.Assert(0 <= count && count <= outputBuffer.Count); if (count < outputBuffer.Count) @@ -45,7 +46,7 @@ public override XPathNavigator Advance() return null; } - public override XPathNavigator Current + public override XPathNavigator? Current { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheChildrenQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheChildrenQuery.cs index 1325d2ff88d6..6dcaae29d95e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheChildrenQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheChildrenQuery.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -16,12 +17,12 @@ namespace MS.Internal.Xml.XPath // So we don't need to call DecideNextNode() when needInput == true && stack is empty. internal sealed class CacheChildrenQuery : ChildrenQuery { - private XPathNavigator _nextInput; + private XPathNavigator? _nextInput; private readonly StackNav _elementStk; private readonly StackInt _positionStk; private bool _needInput; #if DEBUG - private XPathNavigator _lastNode; + private XPathNavigator? _lastNode; #endif public CacheChildrenQuery(Query qyInput, string name, string prefix, XPathNodeType type) : base(qyInput, name, prefix, type) @@ -53,7 +54,7 @@ public override void Reset() #endif } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { do { @@ -85,7 +86,7 @@ public override XPathNavigator Advance() } else { - if (!currentNode.MoveToNext() || !DecideNextNode()) + if (!currentNode!.MoveToNext() || !DecideNextNode()) { _needInput = true; continue; @@ -104,9 +105,9 @@ private bool DecideNextNode() _nextInput = GetNextInput(); if (_nextInput != null) { - if (CompareNodes(currentNode, _nextInput) == XmlNodeOrder.After) + if (CompareNodes(currentNode!, _nextInput) == XmlNodeOrder.After) { - _elementStk.Push(currentNode); + _elementStk.Push(currentNode!); _positionStk.Push(position); currentNode = _nextInput; _nextInput = null; @@ -120,9 +121,9 @@ private bool DecideNextNode() return true; } - private XPathNavigator GetNextInput() + private XPathNavigator? GetNextInput() { - XPathNavigator result; + XPathNavigator? result; if (_nextInput != null) { result = _nextInput; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheOutputQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheOutputQuery.cs index 3a3ea0623d56..c200c466015a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheOutputQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CacheOutputQuery.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml; @@ -46,7 +47,7 @@ public override object Evaluate(XPathNodeIterator context) // All subclasses should and would anyway override this method and return this. } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { Debug.Assert(0 <= count && count <= outputBuffer.Count); if (count < outputBuffer.Count) @@ -56,7 +57,7 @@ public override XPathNavigator Advance() return null; } - public override XPathNavigator Current + public override XPathNavigator? Current { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ChildrenQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ChildrenQuery.cs index 3caf9d300a4d..3a9d201f0837 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ChildrenQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ChildrenQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -21,11 +22,11 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (!_iterator.MoveNext()) { - XPathNavigator input = qyInput.Advance(); + XPathNavigator? input = qyInput.Advance(); if (input == null) { return null; @@ -38,7 +39,7 @@ public override XPathNavigator Advance() } else { - _iterator = input.SelectChildren(Name, Namespace); + _iterator = input.SelectChildren(Name, Namespace!); } } else @@ -52,7 +53,7 @@ public override XPathNavigator Advance() return currentNode; } // Advance - public sealed override XPathNavigator MatchNode(XPathNavigator context) + public sealed override XPathNavigator? MatchNode(XPathNavigator? context) { if (context != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ClonableStack.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ClonableStack.cs index 08af2101b2e0..4637938a1532 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ClonableStack.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ClonableStack.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. +#nullable enable namespace MS.Internal.Xml.XPath { internal sealed class ClonableStack : System.Collections.Generic.List diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs index 5fb8907cee26..e8c5556b22ea 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.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. +#nullable enable using System; using System.Collections; using System.Diagnostics; @@ -51,14 +52,14 @@ public override void AddSort(object expr, IComparer comparer) // sort makes sense only when we are dealing with a query that // returns a nodeset. Query evalExpr; - string query = expr as string; + string? query = expr as string; if (query != null) { evalExpr = new QueryBuilder().Build(query, out _needContext); // this will throw if expr is invalid } else { - CompiledXpathExpr xpathExpr = expr as CompiledXpathExpr; + CompiledXpathExpr? xpathExpr = expr as CompiledXpathExpr; if (xpathExpr != null) { evalExpr = xpathExpr.QueryTree; @@ -68,7 +69,7 @@ public override void AddSort(object expr, IComparer comparer) throw XPathException.Create(SR.Xp_BadQueryObject); } } - SortQuery sortQuery = _query as SortQuery; + SortQuery? sortQuery = _query as SortQuery; if (sortQuery == null) { _query = sortQuery = new SortQuery(_query); @@ -91,9 +92,9 @@ public override void SetContext(XmlNamespaceManager nsManager) SetContext((IXmlNamespaceResolver)nsManager); } - public override void SetContext(IXmlNamespaceResolver nsResolver) + public override void SetContext(IXmlNamespaceResolver? nsResolver) { - XsltContext xsltContext = nsResolver as XsltContext; + XsltContext? xsltContext = nsResolver as XsltContext; if (xsltContext == null) { if (nsResolver == null) @@ -129,7 +130,7 @@ public override string LookupNamespace(string prefix) { return string.Empty; } - string ns = _nsResolver.LookupNamespace(prefix); + string? ns = _nsResolver.LookupNamespace(prefix); if (ns == null) { throw XPathException.Create(SR.XmlUndefinedAlias, prefix); @@ -196,13 +197,13 @@ public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string la _dataType = dataType; } - public int Compare(object x, object y) + public int Compare(object? x, object? y) { switch (_dataType) { case XmlDataType.Text: - string s1 = Convert.ToString(x, _cinfo); - string s2 = Convert.ToString(y, _cinfo); + string? s1 = Convert.ToString(x, _cinfo); + string? s2 = Convert.ToString(y, _cinfo); int result = _cinfo.CompareInfo.Compare(s1, s2, _caseOrder != XmlCaseOrder.None ? CompareOptions.IgnoreCase : CompareOptions.None); if (result != 0 || _caseOrder == XmlCaseOrder.None) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs index 814d86ba0988..6725fea72579 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs @@ -1,13 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath { internal class ContextQuery : Query { - protected XPathNavigator contextNode; + protected XPathNavigator? contextNode; public ContextQuery() { @@ -22,7 +23,7 @@ public override void Reset() count = 0; } - public override XPathNavigator Current { get { return contextNode; } } + public override XPathNavigator? Current { get { return contextNode; } } public override object Evaluate(XPathNodeIterator context) { @@ -31,7 +32,7 @@ public override object Evaluate(XPathNodeIterator context) return this; } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { if (count == 0) { @@ -41,7 +42,7 @@ public override XPathNavigator Advance() return null; } - public override XPathNavigator MatchNode(XPathNavigator current) + public override XPathNavigator? MatchNode(XPathNavigator? current) { return current; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantBaseQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantBaseQuery.cs index 7e9ea6ab427b..2c289612b82a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantBaseQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantBaseQuery.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. +#nullable enable using System; using System.Xml; using System.Xml.XPath; @@ -23,7 +24,7 @@ public DescendantBaseQuery(DescendantBaseQuery other) : base(other) this.abbrAxis = other.abbrAxis; } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { if (context != null) { @@ -31,7 +32,7 @@ public override XPathNavigator MatchNode(XPathNavigator context) { throw XPathException.Create(SR.Xp_InvalidPattern); } - XPathNavigator result = null; + XPathNavigator? result = null; if (matches(context)) { if (matchSelf) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantQuery.cs index db248bb6ac7e..413da810a407 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantQuery.cs @@ -1,13 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath { internal class DescendantQuery : DescendantBaseQuery { - private XPathNodeIterator _nodeIterator; + private XPathNodeIterator? _nodeIterator; internal DescendantQuery(Query qyParent, string Name, string Prefix, XPathNodeType Type, bool matchSelf, bool abbrAxis) : base(qyParent, Name, Prefix, Type, matchSelf, abbrAxis) @@ -24,14 +25,14 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (true) { if (_nodeIterator == null) { position = 0; - XPathNavigator nav = qyInput.Advance(); + XPathNavigator? nav = qyInput.Advance(); if (nav == null) { return null; @@ -44,7 +45,7 @@ public override XPathNavigator Advance() } else { - _nodeIterator = nav.SelectDescendants(Name, Namespace, matchSelf); + _nodeIterator = nav.SelectDescendants(Name, Namespace!, matchSelf); } } else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs index af1d23bee52f..1b0d657a406f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DescendantoverDescendantQuery.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -28,7 +29,7 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (true) { @@ -60,6 +61,7 @@ public override XPathNavigator Advance() } do { + Debug.Assert(currentNode != null); if (matches(currentNode)) { position++; @@ -71,6 +73,7 @@ public override XPathNavigator Advance() private bool MoveToFirstChild() { + Debug.Assert(currentNode != null); if (currentNode.MoveToFirstChild()) { _level++; @@ -81,6 +84,7 @@ private bool MoveToFirstChild() private bool MoveUpUntilNext() { // move up until we can move next + Debug.Assert(currentNode != null); while (!currentNode.MoveToNext()) { --_level; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DocumentorderQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DocumentorderQuery.cs index 7577f3c0f3c2..f2f56f6a72e7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DocumentorderQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/DocumentorderQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -14,7 +15,7 @@ public override object Evaluate(XPathNodeIterator context) { base.Evaluate(context); - XPathNavigator node; + XPathNavigator? node; while ((node = base.input.Advance()) != null) { Insert(outputBuffer, node); @@ -23,7 +24,7 @@ public override object Evaluate(XPathNodeIterator context) return this; } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { return input.MatchNode(context); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/EmptyQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/EmptyQuery.cs index fe95898adbbd..ebfd1a7229d1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/EmptyQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/EmptyQuery.cs @@ -1,13 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath { internal sealed class EmptyQuery : Query { - public override XPathNavigator Advance() { return null; } + public override XPathNavigator? Advance() { return null; } public override XPathNodeIterator Clone() { return this; } public override object Evaluate(XPathNodeIterator context) { return this; } public override int CurrentPosition { get { return 0; } } @@ -15,6 +16,6 @@ internal sealed class EmptyQuery : Query public override QueryProps Properties { get { return QueryProps.Merge | QueryProps.Cached | QueryProps.Position | QueryProps.Count; } } public override XPathResultType StaticType { get { return XPathResultType.NodeSet; } } public override void Reset() { } - public override XPathNavigator Current { get { return null; } } + public override XPathNavigator? Current { get { return null; } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ExtensionQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ExtensionQuery.cs index f4ed528d7343..4645ba2bc93b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ExtensionQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ExtensionQuery.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. +#nullable enable using System; using System.Xml; using System.Xml.XPath; @@ -12,8 +13,8 @@ internal abstract class ExtensionQuery : Query { protected string prefix; protected string name; - protected XsltContext xsltContext; - private ResetableIterator _queryIterator; + protected XsltContext? xsltContext; + private ResetableIterator? _queryIterator; public ExtensionQuery(string prefix, string name) : base() { @@ -25,7 +26,7 @@ protected ExtensionQuery(ExtensionQuery other) : base(other) this.prefix = other.prefix; this.name = other.name; this.xsltContext = other.xsltContext; - _queryIterator = (ResetableIterator)Clone(other._queryIterator); + _queryIterator = (ResetableIterator?)Clone(other._queryIterator); } public override void Reset() @@ -36,7 +37,7 @@ public override void Reset() } } - public override XPathNavigator Current + public override XPathNavigator? Current { get { @@ -52,7 +53,7 @@ public override XPathNavigator Current } } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { if (_queryIterator == null) { @@ -77,7 +78,7 @@ public override int CurrentPosition } } - protected object ProcessResult(object value) + protected object? ProcessResult(object? value) { if (value is string) return value; if (value is double) return value; @@ -91,7 +92,7 @@ protected object ProcessResult(object value) return this; // We map null to NodeSet to let $null/foo work well. } - ResetableIterator resetable = value as ResetableIterator; + ResetableIterator? resetable = value as ResetableIterator; if (resetable != null) { // We need Clone() value because variable may be used several times @@ -99,15 +100,16 @@ protected object ProcessResult(object value) _queryIterator = (ResetableIterator)resetable.Clone(); return this; } - XPathNodeIterator nodeIterator = value as XPathNodeIterator; + XPathNodeIterator? nodeIterator = value as XPathNodeIterator; if (nodeIterator != null) { _queryIterator = new XPathArrayIterator(nodeIterator); return this; } - IXPathNavigable navigable = value as IXPathNavigable; + IXPathNavigable? navigable = value as IXPathNavigable; if (navigable != null) { + // This may be null if navigable is typeof(XmlNode). return navigable.CreateNavigator(); } @@ -118,7 +120,7 @@ protected object ProcessResult(object value) if (value is ulong) return (double)(ulong)value; if (value is float) return (double)(float)value; if (value is decimal) return (double)(decimal)value; - return value.ToString(); + return value.ToString()!; } protected string QName { get { return prefix.Length != 0 ? prefix + ":" + name : name; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Filter.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Filter.cs index 11ecec19c49c..e0840ef34996 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Filter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Filter.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FilterQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FilterQuery.cs index d64034eb0259..53eaf5a23a10 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FilterQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FilterQuery.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -40,7 +41,7 @@ public override void SetXsltContext(XsltContext input) { // BugBug: We can do such trick at Evaluate time only. // But to do this FilterQuery should stop inherit from BaseAxisQuery - ReversePositionQuery query = qyInput as ReversePositionQuery; + ReversePositionQuery? query = qyInput as ReversePositionQuery; if (query != null) { qyInput = query.input; @@ -48,7 +49,7 @@ public override void SetXsltContext(XsltContext input) } } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while ((currentNode = qyInput.Advance()) != null) { @@ -72,9 +73,9 @@ internal bool EvaluatePredicate() return true; } - public override XPathNavigator MatchNode(XPathNavigator current) + public override XPathNavigator? MatchNode(XPathNavigator? current) { - XPathNavigator context; + XPathNavigator? context; if (current == null) { return null; @@ -87,11 +88,11 @@ public override XPathNavigator MatchNode(XPathNavigator current) switch (_cond.StaticType) { case XPathResultType.Number: - OperandQuery operand = _cond as OperandQuery; + OperandQuery? operand = _cond as OperandQuery; if (operand != null) { double val = (double)operand.val; - ChildrenQuery childrenQuery = qyInput as ChildrenQuery; + ChildrenQuery? childrenQuery = qyInput as ChildrenQuery; if (childrenQuery != null) { // foo[2], but not foo[expr][2] XPathNavigator result = current.Clone(); @@ -111,7 +112,7 @@ public override XPathNavigator MatchNode(XPathNavigator current) } while (result.MoveToNext()); return null; } - AttributeQuery attributeQuery = qyInput as AttributeQuery; + AttributeQuery? attributeQuery = qyInput as AttributeQuery; if (attributeQuery != null) {// @foo[3], but not @foo[expr][2] XPathNavigator result = current.Clone(); @@ -156,7 +157,7 @@ public override XPathNavigator MatchNode(XPathNavigator current) /* Generic case */ { Evaluate(new XPathSingletonIterator(context, /*moved:*/true)); - XPathNavigator result; + XPathNavigator? result; while ((result = Advance()) != null) { if (result.IsSamePosition(current)) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollSiblingQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollSiblingQuery.cs index 3135c9ec0ce7..a579d60cc75e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollSiblingQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollSiblingQuery.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. +#nullable enable using System.Collections.Generic; using System.Xml.XPath; using StackNav = MS.Internal.Xml.XPath.ClonableStack; @@ -11,7 +12,7 @@ internal sealed class FollSiblingQuery : BaseAxisQuery { private readonly StackNav _elementStk; private readonly List _parentStk; - private XPathNavigator _nextInput; + private XPathNavigator? _nextInput; public FollSiblingQuery(Query qyInput, string name, string prefix, XPathNodeType type) : base(qyInput, name, prefix, type) { @@ -48,9 +49,9 @@ private bool Visited(XPathNavigator nav) return false; } - private XPathNavigator FetchInput() + private XPathNavigator? FetchInput() { - XPathNavigator input; + XPathNavigator? input; do { input = qyInput.Advance(); @@ -62,7 +63,7 @@ private XPathNavigator FetchInput() return input.Clone(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (true) { @@ -90,7 +91,7 @@ public override XPathNavigator Advance() while (currentNode.IsDescendant(_nextInput)) { _elementStk.Push(currentNode); - currentNode = _nextInput; + currentNode = _nextInput!; _nextInput = qyInput.Advance(); if (_nextInput != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollowingQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollowingQuery.cs index a5f309d34b1d..48a998caa030 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollowingQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FollowingQuery.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable +using System.Diagnostics; using System.Xml.XPath; namespace MS.Internal.Xml.XPath { internal sealed class FollowingQuery : BaseAxisQuery { - private XPathNavigator _input; - private XPathNodeIterator _iterator; + private XPathNavigator? _input; + private XPathNodeIterator? _iterator; public FollowingQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest) : base(qyInput, name, prefix, typeTest) { } private FollowingQuery(FollowingQuery other) : base(other) @@ -23,7 +25,7 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { if (_iterator == null) { @@ -47,7 +49,7 @@ public override XPathNavigator Advance() while (!_iterator.MoveNext()) { bool matchSelf; - if (_input.NodeType == XPathNodeType.Attribute || _input.NodeType == XPathNodeType.Namespace) + if (_input!.NodeType == XPathNodeType.Attribute || _input.NodeType == XPathNodeType.Namespace) { _input.MoveToParent(); matchSelf = false; @@ -65,7 +67,7 @@ public override XPathNavigator Advance() } if (NameTest) { - _iterator = _input.SelectDescendants(Name, Namespace, matchSelf); + _iterator = _input.SelectDescendants(Name, Namespace!, matchSelf); } else { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ForwardPositionQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ForwardPositionQuery.cs index 26887dd4439e..f70c9a50fbbf 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ForwardPositionQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ForwardPositionQuery.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -18,7 +19,7 @@ public override object Evaluate(XPathNodeIterator context) { base.Evaluate(context); - XPathNavigator node; + XPathNavigator? node; while ((node = base.input.Advance()) != null) { outputBuffer.Add(node.Clone()); @@ -27,7 +28,7 @@ public override object Evaluate(XPathNodeIterator context) return this; } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { return input.MatchNode(context); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Function.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Function.cs index a9b24a624fc7..c1c0e0d2d715 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Function.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Function.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. +#nullable enable using System.Collections.Generic; using System.Xml.XPath; @@ -43,8 +44,8 @@ public enum FunctionType private readonly FunctionType _functionType; private readonly List _argumentList; - private readonly string _name; - private readonly string _prefix; + private readonly string? _name; + private readonly string? _prefix; public Function(FunctionType ftype, List argumentList) { @@ -79,8 +80,8 @@ public override XPathResultType ReturnType public FunctionType TypeOfFunction { get { return _functionType; } } public List ArgumentList { get { return _argumentList; } } - public string Prefix { get { return _prefix; } } - public string Name { get { return _name; } } + public string? Prefix { get { return _prefix; } } + public string? Name { get { return _name; } } internal static XPathResultType[] ReturnTypes = { /* FunctionType.FuncLast */ XPathResultType.Number, diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs index f239694a6397..31a38e173321 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections.Generic; +using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -12,7 +14,7 @@ namespace MS.Internal.Xml.XPath internal sealed class FunctionQuery : ExtensionQuery { private readonly IList _args; - private IXsltContextFunction _function; + private IXsltContextFunction? _function; public FunctionQuery(string prefix, string name, List args) : base(prefix, name) { @@ -73,12 +75,18 @@ public override object Evaluate(XPathNodeIterator nodeIterator) argVals[i] = _args[i].Evaluate(nodeIterator); if (argVals[i] is XPathNodeIterator) {// ForBack Compat. To protect our queries from users. + Debug.Assert(nodeIterator.Current != null); argVals[i] = new XPathSelectionIterator(nodeIterator.Current, _args[i]); } } try { - return ProcessResult(_function.Invoke(xsltContext, argVals, nodeIterator.Current)); + Debug.Assert(_function != null); + object? retVal = ProcessResult(_function.Invoke(xsltContext, argVals, nodeIterator.Current)); + + // ProcessResult may return null when the input value is XmlNode and here doesn't seem to be the case. + Debug.Assert(retVal != null); + return retVal; } catch (Exception ex) { @@ -86,17 +94,17 @@ public override object Evaluate(XPathNodeIterator nodeIterator) } } - public override XPathNavigator MatchNode(XPathNavigator navigator) + public override XPathNavigator? MatchNode(XPathNavigator? navigator) { if (name != "key" && prefix.Length != 0) { throw XPathException.Create(SR.Xp_InvalidPattern); } - this.Evaluate(new XPathSingletonIterator(navigator, /*moved:*/true)); - XPathNavigator nav = null; + this.Evaluate(new XPathSingletonIterator(navigator!, /*moved:*/true)); + XPathNavigator? nav = null; while ((nav = this.Advance()) != null) { - if (nav.IsSamePosition(navigator)) + if (nav.IsSamePosition(navigator!)) { return nav; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Group.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Group.cs index de0171981253..de71354d8133 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Group.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Group.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/GroupQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/GroupQuery.cs index 62539469c3cb..f5b43b98a88b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/GroupQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/GroupQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -10,7 +11,7 @@ internal sealed class GroupQuery : BaseAxisQuery public GroupQuery(Query qy) : base(qy) { } private GroupQuery(GroupQuery other) : base(other) { } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { currentNode = qyInput.Advance(); if (currentNode != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IdQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IdQuery.cs index e7c26e6c7e03..1bf9010d8cab 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IdQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IdQuery.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. +#nullable enable +using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -14,12 +16,13 @@ private IDQuery(IDQuery other) : base(other) { } public override object Evaluate(XPathNodeIterator context) { object argVal = base.Evaluate(context); + Debug.Assert(context.Current != null); XPathNavigator contextNode = context.Current.Clone(); switch (GetXPathType(argVal)) { case XPathResultType.NodeSet: - XPathNavigator temp; + XPathNavigator? temp; while ((temp = input.Advance()) != null) { ProcessIds(contextNode, temp.Value); @@ -53,13 +56,13 @@ private void ProcessIds(XPathNavigator contextNode, string val) } } - public override XPathNavigator MatchNode(XPathNavigator context) + public override XPathNavigator? MatchNode(XPathNavigator? context) { - Evaluate(new XPathSingletonIterator(context, /*moved:*/true)); - XPathNavigator result; + Evaluate(new XPathSingletonIterator(context!, /*moved:*/true)); + XPathNavigator? result; while ((result = Advance()) != null) { - if (result.IsSamePosition(context)) + if (result.IsSamePosition(context!)) { return context; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IteratorFilter.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IteratorFilter.cs index a0bedd88ff03..adb9d0bb256a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IteratorFilter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/IteratorFilter.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. +#nullable enable +using System.Diagnostics; using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -25,13 +27,14 @@ private IteratorFilter(IteratorFilter it) } public override XPathNodeIterator Clone() { return new IteratorFilter(this); } - public override XPathNavigator Current { get { return _innerIterator.Current; } } + public override XPathNavigator? Current { get { return _innerIterator.Current; } } public override int CurrentPosition { get { return _position; } } public override bool MoveNext() { while (_innerIterator.MoveNext()) { + Debug.Assert(_innerIterator.Current != null); if (_innerIterator.Current.LocalName == _name) { _position++; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/LogicalExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/LogicalExpr.cs index d0b642e71b3b..53f556d5a952 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/LogicalExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/LogicalExpr.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; @@ -56,34 +57,39 @@ public override object Evaluate(XPathNodeIterator nodeIterator) type2 = typeTmp; } + cmpXslt? cmp; + if (op == Operator.Op.EQ || op == Operator.Op.NE) { - return s_CompXsltE[type1][type2](op, val1, val2); + cmp = s_CompXsltE[type1][type2]; } else { - return s_CompXsltO[type1][type2](op, val1, val2); + cmp = s_CompXsltO[type1][type2]; } + + Debug.Assert(cmp != null); + return cmp(op, val1, val2); } private delegate bool cmpXslt(Operator.Op op, object val1, object val2); // Number, String, Boolean, NodeSet, Navigator - private static readonly cmpXslt[][] s_CompXsltE = + private static readonly cmpXslt?[][] s_CompXsltE = { - new cmpXslt[] { new cmpXslt(cmpNumberNumber), null, null, null, null }, - new cmpXslt[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringE), null, null, null }, - new cmpXslt[] { new cmpXslt(cmpBoolNumberE ), new cmpXslt(cmpBoolStringE ), new cmpXslt(cmpBoolBoolE ), null, null }, - new cmpXslt[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringE ), new cmpXslt(cmpQueryBoolE ), new cmpXslt(cmpQueryQueryE ), null }, - new cmpXslt[] { new cmpXslt(cmpRtfNumber ), new cmpXslt(cmpRtfStringE ), new cmpXslt(cmpRtfBoolE ), new cmpXslt(cmpRtfQueryE ), new cmpXslt(cmpRtfRtfE) }, + new cmpXslt?[] { new cmpXslt(cmpNumberNumber), null, null, null, null }, + new cmpXslt?[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringE), null, null, null }, + new cmpXslt?[] { new cmpXslt(cmpBoolNumberE ), new cmpXslt(cmpBoolStringE ), new cmpXslt(cmpBoolBoolE ), null, null }, + new cmpXslt?[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringE ), new cmpXslt(cmpQueryBoolE ), new cmpXslt(cmpQueryQueryE ), null }, + new cmpXslt?[] { new cmpXslt(cmpRtfNumber ), new cmpXslt(cmpRtfStringE ), new cmpXslt(cmpRtfBoolE ), new cmpXslt(cmpRtfQueryE ), new cmpXslt(cmpRtfRtfE) }, }; - private static readonly cmpXslt[][] s_CompXsltO = + private static readonly cmpXslt?[][] s_CompXsltO = { - new cmpXslt[] { new cmpXslt(cmpNumberNumber), null, null, null, null }, - new cmpXslt[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringO), null, null, null }, - new cmpXslt[] { new cmpXslt(cmpBoolNumberO ), new cmpXslt(cmpBoolStringO ), new cmpXslt(cmpBoolBoolO ), null, null }, - new cmpXslt[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringO ), new cmpXslt(cmpQueryBoolO ), new cmpXslt(cmpQueryQueryO ), null }, - new cmpXslt[] { new cmpXslt(cmpRtfNumber ), new cmpXslt(cmpRtfStringO ), new cmpXslt(cmpRtfBoolO ), new cmpXslt(cmpRtfQueryO ), new cmpXslt(cmpRtfRtfO) }, + new cmpXslt?[] { new cmpXslt(cmpNumberNumber), null, null, null, null }, + new cmpXslt?[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringO), null, null, null }, + new cmpXslt?[] { new cmpXslt(cmpBoolNumberO ), new cmpXslt(cmpBoolStringO ), new cmpXslt(cmpBoolBoolO ), null, null }, + new cmpXslt?[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringO ), new cmpXslt(cmpQueryBoolO ), new cmpXslt(cmpQueryQueryO ), null }, + new cmpXslt?[] { new cmpXslt(cmpRtfNumber ), new cmpXslt(cmpRtfStringO ), new cmpXslt(cmpRtfBoolO ), new cmpXslt(cmpRtfQueryO ), new cmpXslt(cmpRtfRtfO) }, }; /*cmpXslt:*/ @@ -408,7 +414,7 @@ private static bool cmpRtfRtfO(Operator.Op op, object val1, object val2) private struct NodeSet { private readonly Query _opnd; - private XPathNavigator _current; + private XPathNavigator? _current; public NodeSet(object opnd) { @@ -426,7 +432,7 @@ public void Reset() _opnd.Reset(); } - public string Value { get { return _current.Value; } } + public string Value { get { return _current!.Value; } } } private static string Rtf(object o) { return ((XPathNavigator)o).Value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/MergeFilterQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/MergeFilterQuery.cs index bea4a1cc7ac0..81c661d15178 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/MergeFilterQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/MergeFilterQuery.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. +#nullable enable +using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -33,7 +35,7 @@ public override object Evaluate(XPathNodeIterator nodeIterator) while (input.Advance() != null) { _child.Evaluate(input); - XPathNavigator node; + XPathNavigator? node; while ((node = _child.Advance()) != null) { Insert(outputBuffer, node); @@ -42,9 +44,9 @@ public override object Evaluate(XPathNodeIterator nodeIterator) return this; } - public override XPathNavigator MatchNode(XPathNavigator current) + public override XPathNavigator? MatchNode(XPathNavigator? current) { - XPathNavigator context = _child.MatchNode(current); + XPathNavigator? context = _child.MatchNode(current); if (context == null) { return null; @@ -55,9 +57,10 @@ public override XPathNavigator MatchNode(XPathNavigator current) return null; } Evaluate(new XPathSingletonIterator(context.Clone(), /*moved:*/true)); - XPathNavigator result = Advance(); + XPathNavigator? result = Advance(); while (result != null) { + Debug.Assert(current != null); if (result.IsSamePosition(current)) { return context; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NamespaceQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NamespaceQuery.cs index b7351e9af9ae..0d44a9b25376 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NamespaceQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NamespaceQuery.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; @@ -22,7 +23,7 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while (true) { @@ -39,7 +40,7 @@ public override XPathNavigator Advance() } else { - _onNamespace = currentNode.MoveToNextNamespace(); + _onNamespace = currentNode!.MoveToNextNamespace(); } if (_onNamespace) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NodeFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NodeFunctions.cs index 6dfc45b82cd3..8cd1bd738019 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NodeFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NodeFunctions.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. +#nullable enable using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -10,11 +11,11 @@ namespace MS.Internal.Xml.XPath { internal sealed class NodeFunctions : ValueQuery { - private readonly Query _arg; + private readonly Query? _arg; private readonly FT _funcType; - private XsltContext _xsltContext; + private XsltContext? _xsltContext; - public NodeFunctions(FT funcType, Query arg) + public NodeFunctions(FT funcType, Query? arg) { _funcType = funcType; _arg = arg; @@ -29,7 +30,7 @@ public override void SetXsltContext(XsltContext context) } } - private XPathNavigator EvaluateArg(XPathNodeIterator context) + private XPathNavigator? EvaluateArg(XPathNodeIterator context) { if (_arg == null) { @@ -41,7 +42,7 @@ private XPathNavigator EvaluateArg(XPathNodeIterator context) public override object Evaluate(XPathNodeIterator context) { - XPathNavigator argVal; + XPathNavigator? argVal; switch (_funcType) { @@ -71,11 +72,11 @@ public override object Evaluate(XPathNodeIterator context) } break; case FT.FuncCount: - _arg.Evaluate(context); + _arg!.Evaluate(context); int count = 0; if (_xsltContext != null) { - XPathNavigator nav; + XPathNavigator? nav; while ((nav = _arg.Advance()) != null) { if (nav.NodeType != XPathNodeType.Whitespace || _xsltContext.PreserveWhitespace(nav)) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs index db805361a7fc..6675f776aa35 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; +using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -11,10 +13,10 @@ namespace MS.Internal.Xml.XPath { internal sealed class NumberFunctions : ValueQuery { - private readonly Query _arg; + private readonly Query? _arg; private readonly FT _ftype; - public NumberFunctions(FT ftype, Query arg) + public NumberFunctions(FT ftype, Query? arg) { _arg = arg; _ftype = ftype; @@ -50,20 +52,21 @@ public override object Evaluate(XPathNodeIterator nodeIterator) => FT.FuncFloor => Floor(nodeIterator), FT.FuncCeiling => Ceiling(nodeIterator), FT.FuncRound => Round(nodeIterator), - _ => null, + _ => throw new InvalidOperationException(), }; private double Number(XPathNodeIterator nodeIterator) { if (_arg == null) { + Debug.Assert(nodeIterator.Current != null); return XmlConvert.ToXPathDouble(nodeIterator.Current.Value); } object argVal = _arg.Evaluate(nodeIterator); switch (GetXPathType(argVal)) { case XPathResultType.NodeSet: - XPathNavigator value = _arg.Advance(); + XPathNavigator? value = _arg.Advance(); if (value != null) { return Number(value.Value); @@ -84,8 +87,9 @@ private double Number(XPathNodeIterator nodeIterator) private double Sum(XPathNodeIterator nodeIterator) { double sum = 0; + Debug.Assert(_arg != null); _arg.Evaluate(nodeIterator); - XPathNavigator nav; + XPathNavigator? nav; while ((nav = _arg.Advance()) != null) { sum += Number(nav.Value); @@ -95,16 +99,19 @@ private double Sum(XPathNodeIterator nodeIterator) private double Floor(XPathNodeIterator nodeIterator) { + Debug.Assert(_arg != null); return Math.Floor((double)_arg.Evaluate(nodeIterator)); } private double Ceiling(XPathNodeIterator nodeIterator) { + Debug.Assert(_arg != null); return Math.Ceiling((double)_arg.Evaluate(nodeIterator)); } private double Round(XPathNodeIterator nodeIterator) { + Debug.Assert(_arg != null); double n = XmlConvert.ToXPathDouble(_arg.Evaluate(nodeIterator)); return XmlConvert.XPathRound(n); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumericExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumericExpr.cs index 854232dc96b8..eeb5775e7e21 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumericExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumericExpr.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operand.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operand.cs index ae309945f415..edde39245f64 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operand.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operand.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/OperandQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/OperandQuery.cs index 851944910e9b..ff8172d18a8f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/OperandQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/OperandQuery.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. +#nullable enable using System; using System.Globalization; using System.Xml; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operator.cs index 6dd69c8e611c..2a79a96f7ce1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Operator.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ParentQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ParentQuery.cs index 567259abe76a..7661973f0594 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ParentQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ParentQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -14,7 +15,7 @@ public override object Evaluate(XPathNodeIterator context) { base.Evaluate(context); - XPathNavigator input; + XPathNavigator? input; while ((input = qyInput.Advance()) != null) { input = input.Clone(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PreSiblingQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PreSiblingQuery.cs index 6db2488019be..17762b4e6617 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PreSiblingQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PreSiblingQuery.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PrecedingQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PrecedingQuery.cs index b0243dad2f9b..818ab4085d6f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PrecedingQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/PrecedingQuery.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; using StackNav = MS.Internal.Xml.XPath.ClonableStack; @@ -20,7 +21,7 @@ namespace MS.Internal.Xml.XPath internal sealed class PrecedingQuery : BaseAxisQuery { - private XPathNodeIterator _workIterator; + private XPathNodeIterator? _workIterator; private readonly StackNav _ancestorStk; public PrecedingQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest) : base(qyInput, name, prefix, typeTest) @@ -40,13 +41,13 @@ public override void Reset() base.Reset(); } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { if (_workIterator == null) { XPathNavigator last; { - XPathNavigator input = qyInput.Advance(); + XPathNavigator? input = qyInput.Advance(); if (input == null) { return null; @@ -74,7 +75,7 @@ public override XPathNavigator Advance() while (_workIterator.MoveNext()) { - currentNode = _workIterator.Current; + currentNode = _workIterator.Current!; if (currentNode.IsSamePosition(_ancestorStk.Peek())) { _ancestorStk.Pop(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Query.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Query.cs index c9622097a201..cfb402c3a11c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Query.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Query.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -53,9 +55,9 @@ public override int Count public virtual void SetXsltContext(XsltContext context) { } public abstract object Evaluate(XPathNodeIterator nodeIterator); - public abstract XPathNavigator Advance(); + public abstract XPathNavigator? Advance(); - public virtual XPathNavigator MatchNode(XPathNavigator current) + public virtual XPathNavigator? MatchNode(XPathNavigator? current) { throw XPathException.Create(SR.Xp_InvalidPattern); } @@ -65,7 +67,8 @@ public virtual XPathNavigator MatchNode(XPathNavigator current) public virtual QueryProps Properties { get { return QueryProps.Merge; } } // ----------------- Helper methods ------------- - public static Query Clone(Query input) + [return: NotNullIfNotNull("input")] + public static Query? Clone(Query? input) { if (input != null) { @@ -74,7 +77,8 @@ public static Query Clone(Query input) return null; } - protected static XPathNodeIterator Clone(XPathNodeIterator input) + [return: NotNullIfNotNull("input")] + protected static XPathNodeIterator? Clone(XPathNodeIterator? input) { if (input != null) { @@ -83,7 +87,8 @@ protected static XPathNodeIterator Clone(XPathNodeIterator input) return null; } - protected static XPathNavigator Clone(XPathNavigator input) + [return: NotNullIfNotNull("input")] + protected static XPathNavigator? Clone(XPathNavigator? input) { if (input != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/QueryBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/QueryBuilder.cs index 004adff0653e..efda195b62e8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/QueryBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/QueryBuilder.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -40,12 +41,12 @@ private enum Props } // comment are approximate. This is my best understanding: - private string _query; + private string? _query; private bool _allowVar; private bool _allowKey; private bool _allowCurrent; private bool _needContext; - private BaseAxisQuery _firstInput; // Input of the leftmost predicate. Set by leftmost predicate, used in rightmost one + private BaseAxisQuery? _firstInput; // Input of the leftmost predicate. Set by leftmost predicate, used in rightmost one private void Reset() { @@ -55,7 +56,7 @@ private void Reset() private Query ProcessAxis(Axis root, Flags flags, out Props props) { - Query result = null; + Query? result = null; if (root.Prefix.Length > 0) { _needContext = true; @@ -68,7 +69,7 @@ private Query ProcessAxis(Axis root, Flags flags, out Props props) Flags inputFlags = Flags.None; if ((flags & Flags.PosFilter) == 0) { - Axis input = root.Input as Axis; + Axis? input = root.Input as Axis; if (input != null) { if ( @@ -198,7 +199,7 @@ private Query ProcessAxis(Axis root, Flags flags, out Props props) } break; default: - throw XPathException.Create(SR.Xp_NotSupported, _query); + throw XPathException.Create(SR.Xp_NotSupported, _query!); } return result; @@ -252,7 +253,7 @@ private Query ProcessFilter(Filter root, Flags flags, out Props props) /*merging predicates*/ { - FilterQuery qyFilter = qyInput as FilterQuery; + FilterQuery? qyFilter = qyInput as FilterQuery; if (qyFilter != null && (propsCond & Props.HasPosition) == 0 && qyFilter.Condition.StaticType != XPathResultType.Any) { Query prevCond = qyFilter.Condition; @@ -308,7 +309,7 @@ private Query ProcessFilter(Filter root, Flags flags, out Props props) return new FilterQuery(qyInput, cond, /*noPosition:*/(propsCond & Props.HasPosition) == 0); } - private Query ProcessOperator(Operator root, out Props props) + private Query? ProcessOperator(Operator root, out Props props) { Props props1, props2; Query op1 = ProcessNode(root.Operand1, Flags.None, out props1); @@ -344,7 +345,7 @@ private Query ProcessVariable(Variable root) _needContext = true; if (!_allowVar) { - throw XPathException.Create(SR.Xp_InvalidKeyPattern, _query); + throw XPathException.Create(SR.Xp_InvalidKeyPattern, _query!); } return new VariableQuery(root.Localname, root.Prefix); } @@ -352,7 +353,7 @@ private Query ProcessVariable(Variable root) private Query ProcessFunction(Function root, out Props props) { props = Props.None; - Query qy = null; + Query? qy = null; switch (root.TypeOfFunction) { case FT.FuncLast: @@ -420,6 +421,9 @@ private Query ProcessFunction(Function root, out Props props) ProcessNode((AstNode)root.ArgumentList[0], Flags.None, out props) ); case FT.FuncUserDefined: + Debug.Assert(root.Prefix != null); + Debug.Assert(root.Name != null); + _needContext = true; if (!_allowCurrent && root.Name == "current" && root.Prefix.Length == 0) { @@ -427,19 +431,19 @@ private Query ProcessFunction(Function root, out Props props) } if (!_allowKey && root.Name == "key" && root.Prefix.Length == 0) { - throw XPathException.Create(SR.Xp_InvalidKeyPattern, _query); + throw XPathException.Create(SR.Xp_InvalidKeyPattern, _query!); } qy = new FunctionQuery(root.Prefix, root.Name, ProcessArguments(root.ArgumentList, out props)); props |= Props.NonFlat; return qy; default: - throw XPathException.Create(SR.Xp_NotSupported, _query); + throw XPathException.Create(SR.Xp_NotSupported, _query!); } } private List ProcessArguments(List args, out Props props) { - int numArgs = args != null ? args.Count : 0; + int numArgs = args.Count; List argList = new List(numArgs); props = Props.None; for (int count = 0; count < numArgs; count++) @@ -462,7 +466,7 @@ private Query ProcessNode(AstNode root, Flags flags, out Props props) } Debug.Assert(root != null, "root != null"); - Query result = null; + Query? result = null; props = Props.None; switch (root.Type) { @@ -495,7 +499,7 @@ private Query ProcessNode(AstNode root, Flags flags, out Props props) break; } --_parseDepth; - return result; + return result!; } private Query Build(AstNode root, string query) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ResetableIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ResetableIterator.cs index d88410000e39..ed06c29494e7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ResetableIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ResetableIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ReversePositionQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ReversePositionQuery.cs index 7d65497e2485..116b29568a95 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ReversePositionQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ReversePositionQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Root.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Root.cs index 505bc9e2bb3a..5e9303fa81dd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Root.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Root.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/SortQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/SortQuery.cs index 3d441e27b491..96eeb329426f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/SortQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/SortQuery.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -53,7 +54,7 @@ private void BuildResultsList() Debug.Assert(numSorts > 0, "Why was the sort query created?"); - XPathNavigator eNext; + XPathNavigator? eNext; while ((eNext = _qyInput.Advance()) != null) { SortKey key = new SortKey(numSorts, /*originalPosition:*/_results.Count, eNext.Clone()); @@ -77,7 +78,7 @@ public override object Evaluate(XPathNodeIterator context) return this; } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { Debug.Assert(0 <= count && count <= _results.Count); if (count < _results.Count) @@ -87,7 +88,7 @@ public override XPathNavigator Advance() return null; } - public override XPathNavigator Current + public override XPathNavigator? Current { get { @@ -192,7 +193,7 @@ public Query Expression(int i) return _expressions[i]; } - int IComparer.Compare(SortKey x, SortKey y) + int IComparer.Compare(SortKey? x, SortKey? y) { Debug.Assert(x != null && y != null, "Oops!! what happened?"); int result = 0; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs index 24cc50c015ad..d2634c7084ed 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -79,7 +80,7 @@ private string toString(XPathNodeIterator nodeIterator) switch (GetXPathType(argVal)) { case XPathResultType.NodeSet: - XPathNavigator value = _argList[0].Advance(); + XPathNavigator? value = _argList[0].Advance(); return value != null ? value.Value : string.Empty; case XPathResultType.String: return (string)argVal; @@ -92,6 +93,7 @@ private string toString(XPathNodeIterator nodeIterator) return toString((double)argVal); } } + Debug.Assert(nodeIterator.Current != null); return nodeIterator.Current.Value; } @@ -127,8 +129,9 @@ private string Concat(XPathNodeIterator nodeIterator) private bool StartsWith(XPathNodeIterator nodeIterator) { - string s1 = _argList[0].Evaluate(nodeIterator).ToString(); - string s2 = _argList[1].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 1); + string s1 = _argList[0].Evaluate(nodeIterator).ToString()!; + string s2 = _argList[1].Evaluate(nodeIterator).ToString()!; return s1.Length >= s2.Length && string.CompareOrdinal(s1, 0, s2, 0, s2.Length) == 0; } @@ -136,15 +139,17 @@ private bool StartsWith(XPathNodeIterator nodeIterator) private bool Contains(XPathNodeIterator nodeIterator) { - string s1 = _argList[0].Evaluate(nodeIterator).ToString(); - string s2 = _argList[1].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 1); + string s1 = _argList[0].Evaluate(nodeIterator).ToString()!; + string s2 = _argList[1].Evaluate(nodeIterator).ToString()!; return s_compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal) >= 0; } private string SubstringBefore(XPathNodeIterator nodeIterator) { - string s1 = _argList[0].Evaluate(nodeIterator).ToString(); - string s2 = _argList[1].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 1); + string s1 = _argList[0].Evaluate(nodeIterator).ToString()!; + string s2 = _argList[1].Evaluate(nodeIterator).ToString()!; if (s2.Length == 0) { return s2; } int idx = s_compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal); return (idx < 1) ? string.Empty : s1.Substring(0, idx); @@ -152,8 +157,9 @@ private string SubstringBefore(XPathNodeIterator nodeIterator) private string SubstringAfter(XPathNodeIterator nodeIterator) { - string s1 = _argList[0].Evaluate(nodeIterator).ToString(); - string s2 = _argList[1].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 1); + string s1 = _argList[0].Evaluate(nodeIterator).ToString()!; + string s2 = _argList[1].Evaluate(nodeIterator).ToString()!; if (s2.Length == 0) { return s1; } int idx = s_compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal); return (idx < 0) ? string.Empty : s1.Substring(idx + s2.Length); @@ -161,7 +167,8 @@ private string SubstringAfter(XPathNodeIterator nodeIterator) private string Substring(XPathNodeIterator nodeIterator) { - string str1 = _argList[0].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 0); + string str1 = _argList[0].Evaluate(nodeIterator).ToString()!; double num = XmlConvert.XPathRound(XmlConvert.ToXPathDouble(_argList[1].Evaluate(nodeIterator))) - 1; if (double.IsNaN(num) || str1.Length <= num) @@ -203,8 +210,9 @@ private double StringLength(XPathNodeIterator nodeIterator) { if (_argList.Count > 0) { - return _argList[0].Evaluate(nodeIterator).ToString().Length; + return _argList[0].Evaluate(nodeIterator).ToString()!.Length; } + Debug.Assert(nodeIterator.Current != null); return nodeIterator.Current.Value.Length; } @@ -213,10 +221,11 @@ private string Normalize(XPathNodeIterator nodeIterator) string value; if (_argList.Count > 0) { - value = _argList[0].Evaluate(nodeIterator).ToString(); + value = _argList[0].Evaluate(nodeIterator).ToString()!; } else { + Debug.Assert(nodeIterator.Current != null); value = nodeIterator.Current.Value; } int modifyPos = -1; @@ -249,9 +258,10 @@ private string Normalize(XPathNodeIterator nodeIterator) private string Translate(XPathNodeIterator nodeIterator) { - string value = _argList[0].Evaluate(nodeIterator).ToString(); - string mapFrom = _argList[1].Evaluate(nodeIterator).ToString(); - string mapTo = _argList[2].Evaluate(nodeIterator).ToString(); + Debug.Assert(_argList.Count > 2); + string value = _argList[0].Evaluate(nodeIterator).ToString()!; + string mapFrom = _argList[1].Evaluate(nodeIterator).ToString()!; + string mapTo = _argList[2].Evaluate(nodeIterator).ToString()!; int modifyPos = -1; char[] chars = value.ToCharArray(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/UnionExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/UnionExpr.cs index 902788d8841b..d7684f6ac1e4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/UnionExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/UnionExpr.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. +#nullable enable using System; using System.Xml; using System.Xml.XPath; @@ -12,8 +13,8 @@ internal sealed class UnionExpr : Query { internal Query qy1, qy2; private bool _advance1, _advance2; - private XPathNavigator _currentNode; - private XPathNavigator _nextNode; + private XPathNavigator? _currentNode; + private XPathNavigator? _nextNode; public UnionExpr(Query query1, Query query2) { @@ -83,9 +84,9 @@ private XPathNavigator ProcessAfterPosition(XPathNavigator res1, XPathNavigator return res2; } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { - XPathNavigator res1, res2; + XPathNavigator? res1, res2; XmlNodeOrder order = 0; if (_advance1) { @@ -139,11 +140,11 @@ public override XPathNavigator Advance() } } - public override XPathNavigator MatchNode(XPathNavigator xsltContext) + public override XPathNavigator? MatchNode(XPathNavigator? xsltContext) { if (xsltContext != null) { - XPathNavigator result = qy1.MatchNode(xsltContext); + XPathNavigator? result = qy1.MatchNode(xsltContext); if (result != null) { return result; @@ -157,7 +158,7 @@ public override XPathNavigator MatchNode(XPathNavigator xsltContext) public override XPathNodeIterator Clone() { return new UnionExpr(this); } - public override XPathNavigator Current { get { return _currentNode; } } + public override XPathNavigator? Current { get { return _currentNode; } } public override int CurrentPosition { get { throw new InvalidOperationException(); } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ValueQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ValueQuery.cs index 654e86db2ca7..8cb5615d0628 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ValueQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ValueQuery.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. +#nullable enable using System; using System.Xml; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Variable.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Variable.cs index 45eb4bcf7154..89150323978d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Variable.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/Variable.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/VariableQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/VariableQuery.cs index fd74484252a9..74678d2404de 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/VariableQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/VariableQuery.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; +using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -10,7 +12,7 @@ namespace MS.Internal.Xml.XPath { internal sealed class VariableQuery : ExtensionQuery { - private IXsltContextVariable _variable; + private IXsltContextVariable? _variable; public VariableQuery(string name, string prefix) : base(prefix, name) { } private VariableQuery(VariableQuery other) : base(other) @@ -44,7 +46,12 @@ public override object Evaluate(XPathNodeIterator nodeIterator) throw XPathException.Create(SR.Xp_NoContext); } - return ProcessResult(_variable.Evaluate(xsltContext)); + Debug.Assert(_variable != null); + object? retVal = ProcessResult(_variable.Evaluate(xsltContext)); + + // ProcessResult may return null when the input value is XmlNode and here doesn't seem to be the case. + Debug.Assert(retVal != null); + return retVal; } public override XPathResultType StaticType @@ -53,7 +60,7 @@ public override XPathResultType StaticType { if (_variable != null) { // Temp. fix to overcome dependency on static type - return GetXPathType(Evaluate(null)); + return GetXPathType(Evaluate(null!)); } XPathResultType result = _variable != null ? _variable.VariableType : XPathResultType.Any; if (result == XPathResultType.Error) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorIterator.cs index d5b07d571e98..621b4e0304ad 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorQuery.cs index 45dab44a1951..0487aa79f7e3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAncestorQuery.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. +#nullable enable using System.Xml; using System.Xml.XPath; @@ -23,8 +24,8 @@ public override object Evaluate(XPathNodeIterator context) { base.Evaluate(context); - XPathNavigator ancestor = null; - XPathNavigator input; + XPathNavigator? ancestor = null; + XPathNavigator? input; while ((input = qyInput.Advance()) != null) { if (_matchSelf) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathArrayIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathArrayIterator.cs index 89d7c8ad24e5..2bb0944ebee5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathArrayIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathArrayIterator.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -32,6 +33,7 @@ public XPathArrayIterator(XPathNodeIterator nodeIterator) this.list = new ArrayList(); while (nodeIterator.MoveNext()) { + Debug.Assert(nodeIterator.Current != null); this.list.Add(nodeIterator.Current.Clone()); } } @@ -46,7 +48,7 @@ public override XPathNodeIterator Clone() return new XPathArrayIterator(this); } - public override XPathNavigator Current + public override XPathNavigator? Current { get { @@ -56,7 +58,7 @@ public override XPathNavigator Current { throw new InvalidOperationException(SR.Format(SR.Sch_EnumNotStarted, string.Empty)); } - return (XPathNavigator)list[index - 1]; + return (XPathNavigator?)list[index - 1]; } } @@ -84,6 +86,6 @@ public override IEnumerator GetEnumerator() return list.GetEnumerator(); } - private object debuggerDisplayProxy { get { return index < 1 ? null : (object)new XPathNavigator.DebuggerDisplayProxy(Current); } } + private object? debuggerDisplayProxy { get { return index < 1 ? null : (object)new XPathNavigator.DebuggerDisplayProxy(Current!); } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAxisIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAxisIterator.cs index c5770eb6fdae..cf15bfd5f445 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAxisIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathAxisIterator.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. +#nullable enable using System; using System.Xml.XPath; @@ -10,8 +11,8 @@ internal abstract class XPathAxisIterator : XPathNodeIterator { internal XPathNavigator nav; internal XPathNodeType type; - internal string name; - internal string uri; + internal string? name; + internal string? uri; internal int position; internal bool matchSelf; internal bool first = true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathChildIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathChildIterator.cs index 1db05129cec2..3fdeb2ea79dd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathChildIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathChildIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathDescendantIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathDescendantIterator.cs index 65a0e9b17972..f0e1542b67ab 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathDescendantIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathDescendantIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathEmptyIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathEmptyIterator.cs index 318ca6d34014..bd6b5a0964f4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathEmptyIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathEmptyIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -10,7 +11,7 @@ internal sealed class XPathEmptyIterator : ResetableIterator private XPathEmptyIterator() { } public override XPathNodeIterator Clone() { return this; } - public override XPathNavigator Current + public override XPathNavigator? Current { get { return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathMultyIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathMultyIterator.cs index 1ca2a7c0c9fd..437cd1953905 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathMultyIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathMultyIterator.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. +#nullable enable namespace MS.Internal.Xml.XPath { using System; @@ -22,7 +23,9 @@ public XPathMultyIterator(ArrayList inputArray) this.arr = new ResetableIterator[inputArray.Count]; for (int i = 0; i < this.arr.Length; i++) { - this.arr[i] = new XPathArrayIterator((ArrayList)inputArray[i]); + var iterator = (ArrayList?)inputArray[i]; + Debug.Assert(iterator != null); + this.arr[i] = new XPathArrayIterator(iterator); } Init(); } @@ -101,14 +104,16 @@ private bool SiftItem(int item) ResetableIterator it = arr[item]; while (item + 1 < arr.Length) { - XmlNodeOrder order = Query.CompareNodes(it.Current, arr[item + 1].Current); + ResetableIterator itNext = arr[item + 1]; + Debug.Assert(it.Current != null && itNext.Current != null); + XmlNodeOrder order = Query.CompareNodes(it.Current, itNext.Current); if (order == XmlNodeOrder.Before) { break; } if (order == XmlNodeOrder.After) { - arr[item] = arr[item + 1]; + arr[item] = itNext; //arr[item + 1] = it; item++; } @@ -149,7 +154,7 @@ public override XPathNodeIterator Clone() return new XPathMultyIterator(this); } - public override XPathNavigator Current + public override XPathNavigator? Current { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathParser.cs index 1546771f979a..8c75360e61cd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathParser.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -51,7 +52,7 @@ public static AstNode ParseXPathPattern(string xpathPattern) private int _parseDepth; private const int MaxParseDepth = 200; - private AstNode ParseExpression(AstNode qyInput) + private AstNode ParseExpression(AstNode? qyInput) { if (++_parseDepth > MaxParseDepth) { @@ -63,7 +64,7 @@ private AstNode ParseExpression(AstNode qyInput) } //>> OrExpr ::= ( OrExpr 'or' )? AndExpr - private AstNode ParseOrExpr(AstNode qyInput) + private AstNode ParseOrExpr(AstNode? qyInput) { AstNode opnd = ParseAndExpr(qyInput); @@ -79,7 +80,7 @@ private AstNode ParseOrExpr(AstNode qyInput) } //>> AndExpr ::= ( AndExpr 'and' )? EqualityExpr - private AstNode ParseAndExpr(AstNode qyInput) + private AstNode ParseAndExpr(AstNode? qyInput) { AstNode opnd = ParseEqualityExpr(qyInput); @@ -96,7 +97,7 @@ private AstNode ParseAndExpr(AstNode qyInput) //>> EqualityOp ::= '=' | '!=' //>> EqualityExpr ::= ( EqualityExpr EqualityOp )? RelationalExpr - private AstNode ParseEqualityExpr(AstNode qyInput) + private AstNode ParseEqualityExpr(AstNode? qyInput) { AstNode opnd = ParseRelationalExpr(qyInput); @@ -118,7 +119,7 @@ private AstNode ParseEqualityExpr(AstNode qyInput) //>> RelationalOp ::= '<' | '>' | '<=' | '>=' //>> RelationalExpr ::= ( RelationalExpr RelationalOp )? AdditiveExpr - private AstNode ParseRelationalExpr(AstNode qyInput) + private AstNode ParseRelationalExpr(AstNode? qyInput) { AstNode opnd = ParseAdditiveExpr(qyInput); @@ -142,7 +143,7 @@ private AstNode ParseRelationalExpr(AstNode qyInput) //>> AdditiveOp ::= '+' | '-' //>> AdditiveExpr ::= ( AdditiveExpr AdditiveOp )? MultiplicativeExpr - private AstNode ParseAdditiveExpr(AstNode qyInput) + private AstNode ParseAdditiveExpr(AstNode? qyInput) { AstNode opnd = ParseMultiplicativeExpr(qyInput); @@ -164,7 +165,7 @@ private AstNode ParseAdditiveExpr(AstNode qyInput) //>> MultiplicativeOp ::= '*' | 'div' | 'mod' //>> MultiplicativeExpr ::= ( MultiplicativeExpr MultiplicativeOp )? UnaryExpr - private AstNode ParseMultiplicativeExpr(AstNode qyInput) + private AstNode ParseMultiplicativeExpr(AstNode? qyInput) { AstNode opnd = ParseUnaryExpr(qyInput); @@ -186,7 +187,7 @@ private AstNode ParseMultiplicativeExpr(AstNode qyInput) } //>> UnaryExpr ::= UnionExpr | '-' UnaryExpr - private AstNode ParseUnaryExpr(AstNode qyInput) + private AstNode ParseUnaryExpr(AstNode? qyInput) { bool minus = false; while (_scanner.Kind == XPathScanner.LexKind.Minus) @@ -206,7 +207,7 @@ private AstNode ParseUnaryExpr(AstNode qyInput) } //>> UnionExpr ::= ( UnionExpr '|' )? PathExpr - private AstNode ParseUnionExpr(AstNode qyInput) + private AstNode ParseUnionExpr(AstNode? qyInput) { AstNode opnd = ParsePathExpr(qyInput); @@ -239,7 +240,7 @@ private static bool IsNodeType(XPathScanner scaner) //>> PathOp ::= '/' | '//' //>> PathExpr ::= LocationPath | //>> FilterExpr ( PathOp RelativeLocationPath )? - private AstNode ParsePathExpr(AstNode qyInput) + private AstNode ParsePathExpr(AstNode? qyInput) { AstNode opnd; if (IsPrimaryExpr(_scanner)) @@ -265,7 +266,7 @@ private AstNode ParsePathExpr(AstNode qyInput) } //>> FilterExpr ::= PrimaryExpr | FilterExpr Predicate - private AstNode ParseFilterExpr(AstNode qyInput) + private AstNode ParseFilterExpr(AstNode? qyInput) { AstNode opnd = ParsePrimaryExpr(qyInput); while (_scanner.Kind == XPathScanner.LexKind.LBracket) @@ -292,7 +293,7 @@ private AstNode ParsePredicate(AstNode qyInput) } //>> LocationPath ::= RelativeLocationPath | AbsoluteLocationPath - private AstNode ParseLocationPath(AstNode qyInput) + private AstNode ParseLocationPath(AstNode? qyInput) { if (_scanner.Kind == XPathScanner.LexKind.Slash) { @@ -318,9 +319,9 @@ private AstNode ParseLocationPath(AstNode qyInput) //>> PathOp ::= '/' | '//' //>> RelativeLocationPath ::= ( RelativeLocationPath PathOp )? Step - private AstNode ParseRelativeLocationPath(AstNode qyInput) + private AstNode ParseRelativeLocationPath(AstNode? qyInput) { - AstNode opnd = qyInput; + AstNode? opnd = qyInput; do { opnd = ParseStep(opnd); @@ -356,7 +357,7 @@ private static bool IsStep(XPathScanner.LexKind lexKind) } //>> Step ::= '.' | '..' | ( AxisName '::' | '@' )? NodeTest Predicate* - private AstNode ParseStep(AstNode qyInput) + private AstNode ParseStep(AstNode? qyInput) { AstNode opnd; if (XPathScanner.LexKind.Dot == _scanner.Kind) @@ -400,7 +401,7 @@ private AstNode ParseStep(AstNode qyInput) } //>> NodeTest ::= NameTest | 'comment ()' | 'text ()' | 'node ()' | 'processing-instruction (' Literal ? ')' - private AstNode ParseNodeTest(AstNode qyInput, Axis.AxisType axisType, XPathNodeType nodeType) + private AstNode ParseNodeTest(AstNode? qyInput, Axis.AxisType axisType, XPathNodeType nodeType) { string nodeName, nodePrefix; @@ -469,10 +470,10 @@ private static bool IsPrimaryExpr(XPathScanner scanner) } //>> PrimaryExpr ::= Literal | Number | VariableReference | '(' Expr ')' | FunctionCall - private AstNode ParsePrimaryExpr(AstNode qyInput) + private AstNode ParsePrimaryExpr(AstNode? qyInput) { Debug.Assert(IsPrimaryExpr(_scanner)); - AstNode opnd = null; + AstNode? opnd = null; switch (_scanner.Kind) { case XPathScanner.LexKind.String: @@ -509,7 +510,7 @@ private AstNode ParsePrimaryExpr(AstNode qyInput) return opnd; } - private AstNode ParseMethod(AstNode qyInput) + private AstNode ParseMethod(AstNode? qyInput) { List argList = new List(); string name = _scanner.Name; @@ -531,7 +532,7 @@ private AstNode ParseMethod(AstNode qyInput) PassToken(XPathScanner.LexKind.RParens); if (prefix.Length == 0) { - ParamInfo pi; + ParamInfo? pi; if (s_functionTable.TryGetValue(name, out pi)) { int argCount = argList.Count; @@ -619,7 +620,7 @@ private AstNode ParsePattern() //>> | IdKeyPattern (('/' | '//') RelativePathPattern)? private AstNode ParseLocationPathPattern() { - AstNode opnd = null; + AstNode? opnd = null; switch (_scanner.Kind) { case XPathScanner.LexKind.Slash: @@ -660,7 +661,7 @@ private AstNode ParseLocationPathPattern() } //>> IdKeyPattern ::= 'id' '(' Literal ')' | 'key' '(' Literal ',' Literal ')' - private AstNode ParseIdKeyPattern() + private AstNode? ParseIdKeyPattern() { Debug.Assert(_scanner.CanBeFunction); List argList = new List(); @@ -697,7 +698,7 @@ private AstNode ParseIdKeyPattern() //>> PathOp ::= '/' | '//' //>> RelativePathPattern ::= ( RelativePathPattern PathOp )? StepPattern - private AstNode ParseRelativePathPattern(AstNode qyInput) + private AstNode ParseRelativePathPattern(AstNode? qyInput) { AstNode opnd = ParseStepPattern(qyInput); if (XPathScanner.LexKind.SlashSlash == _scanner.Kind) @@ -715,7 +716,7 @@ private AstNode ParseRelativePathPattern(AstNode qyInput) //>> StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* //>> ChildOrAttributeAxisSpecifier ::= @ ? | ('child' | 'attribute') '::' - private AstNode ParseStepPattern(AstNode qyInput) + private AstNode ParseStepPattern(AstNode? qyInput) { AstNode opnd; Axis.AxisType axisType = Axis.AxisType.Child; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathScanner.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathScanner.cs index 831d7c8df149..5477ab18321d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathScanner.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathScanner.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. +#nullable enable using System; using System.Diagnostics; using System.Globalization; @@ -15,9 +16,9 @@ internal sealed class XPathScanner private int _xpathExprIndex; private LexKind _kind; private char _currentChar; - private string _name; - private string _prefix; - private string _stringValue; + private string? _name; + private string? _prefix; + private string? _stringValue; private double _numberValue = double.NaN; private bool _canBeFunction; private XmlCharType _xmlCharType = XmlCharType.Instance; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelectionIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelectionIterator.cs index a872e91172f2..1431765888b7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelectionIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelectionIterator.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -34,7 +35,7 @@ public override void Reset() public override bool MoveNext() { - XPathNavigator n = _query.Advance(); + XPathNavigator? n = _query.Advance(); if (n != null) { _position++; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelfQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelfQuery.cs index c1b020f0e7f6..8fa0b677eb75 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelfQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSelfQuery.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. +#nullable enable using System.Xml.XPath; namespace MS.Internal.Xml.XPath @@ -10,7 +11,7 @@ internal sealed class XPathSelfQuery : BaseAxisQuery public XPathSelfQuery(Query qyInput, string Name, string Prefix, XPathNodeType Type) : base(qyInput, Name, Prefix, Type) { } private XPathSelfQuery(XPathSelfQuery other) : base(other) { } - public override XPathNavigator Advance() + public override XPathNavigator? Advance() { while ((currentNode = qyInput.Advance()) != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSingletonIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSingletonIterator.cs index 67cdd8803603..7311ec45018d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSingletonIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/XPathSingletonIterator.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. +#nullable enable using System.Diagnostics; using System.Xml.XPath; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs index 492ae0562b74..e54f875101c3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathDocument.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using MS.Internal.Xml.Cache; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; namespace System.Xml.XPath @@ -15,12 +17,12 @@ namespace System.Xml.XPath /// public class XPathDocument : IXPathNavigable { - private XPathNode[] _pageText, _pageRoot, _pageXmlNmsp; + private XPathNode[]? _pageText, _pageRoot, _pageXmlNmsp; private int _idxText, _idxRoot, _idxXmlNmsp; private XmlNameTable _nameTable; private bool _hasLineInfo; - private Dictionary _mapNmsp; - private Dictionary _idValueMap; + private Dictionary? _mapNmsp; + private Dictionary? _idValueMap; /// /// Flags that control Load behavior. @@ -145,11 +147,12 @@ internal XmlRawWriter LoadFromWriter(LoadFlags flags, string baseUri) /// Create a writer that can be used to create nodes in this document. The root node will be assigned "baseUri", and flags /// can be passed to indicate that names should be atomized by the builder and/or a fragment should be created. /// + [MemberNotNull(nameof(_nameTable))] internal void LoadFromReader(XmlReader reader, XmlSpace space) { XPathDocumentBuilder builder; - IXmlLineInfo lineInfo; - string xmlnsUri; + IXmlLineInfo? lineInfo; + string? xmlnsUri; bool topLevelReader; int initialDepth; @@ -172,7 +175,7 @@ internal void LoadFromReader(XmlReader reader, XmlSpace space) initialDepth = reader.Depth; // Get atomized xmlns uri - Debug.Assert((object)_nameTable.Get(string.Empty) == (object)string.Empty, "NameTable must contain atomized string.Empty"); + Debug.Assert((object?)_nameTable.Get(string.Empty) == (object)string.Empty, "NameTable must contain atomized string.Empty"); xmlnsUri = _nameTable.Get(XmlReservedNs.NsXmlNs); // Read past Initial state; if there are no more events then load is complete @@ -199,7 +202,7 @@ internal void LoadFromReader(XmlReader reader, XmlSpace space) { string namespaceUri = reader.NamespaceURI; - if ((object)namespaceUri == (object)xmlnsUri) + if ((object)namespaceUri == (object?)xmlnsUri) { if (reader.Prefix.Length == 0) { @@ -269,7 +272,7 @@ internal void LoadFromReader(XmlReader reader, XmlSpace space) case XmlNodeType.DocumentType: // Create ID tables - IDtdInfo info = reader.DtdInfo; + IDtdInfo? info = reader.DtdInfo; if (info != null) builder.CreateIdTables(info); break; @@ -322,7 +325,7 @@ internal bool HasLineInfo /// represents each logical text node in the document that is the only content-typed child of its /// element parent. /// - internal int GetCollapsedTextNode(out XPathNode[] pageText) + internal int GetCollapsedTextNode(out XPathNode[]? pageText) { pageText = _pageText; return _idxText; @@ -341,7 +344,7 @@ internal void SetCollapsedTextNode(XPathNode[] pageText, int idxText) /// Return the root node of the document. This may not be a node of type XPathNodeType.Root if this /// is a document fragment. /// - internal int GetRootNode(out XPathNode[] pageRoot) + internal int GetRootNode(out XPathNode[]? pageRoot) { pageRoot = _pageRoot; return _idxRoot; @@ -359,7 +362,7 @@ internal void SetRootNode(XPathNode[] pageRoot, int idxRoot) /// /// Every document has an implicit xmlns:xml namespace node. /// - internal int GetXmlNamespaceNode(out XPathNode[] pageXmlNmsp) + internal int GetXmlNamespaceNode(out XPathNode[]? pageXmlNmsp) { pageXmlNmsp = _pageXmlNmsp; return _idxXmlNmsp; @@ -390,7 +393,7 @@ internal void AddNamespace(XPathNode[] pageElem, int idxElem, XPathNode[] pageNm /// /// Lookup the namespace nodes associated with an element. /// - internal int LookupNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[] pageNmsp) + internal int LookupNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[]? pageNmsp) { XPathNodeRef nodeRef = new XPathNodeRef(pageElem, idxElem); Debug.Assert(pageElem[idxElem].NodeType == XPathNodeType.Element); @@ -424,7 +427,7 @@ internal void AddIdElement(string id, XPathNode[] pageElem, int idxElem) /// /// Lookup the element node associated with the specified ID value. /// - internal int LookupIdElement(string id, out XPathNode[] pageElem) + internal int LookupIdElement(string id, out XPathNode[]? pageElem) { XPathNodeRef nodeRef; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs index dbceed23125c..017f4044d613 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs @@ -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. +#nullable enable using System; using System.Resources; using System.Runtime.Serialization; @@ -16,24 +17,24 @@ public class XPathException : SystemException { // we need to keep this members for V1 serialization compatibility private readonly string _res; - private readonly string[] _args; + private readonly string[]? _args; // message != null for V1 & V2 exceptions deserialized in Whidbey // message == null for created V2 exceptions; the exception message is stored in Exception._message - private readonly string _message; + private readonly string? _message; protected XPathException(SerializationInfo info, StreamingContext context) : base(info, context) { - _res = (string)info.GetValue("res", typeof(string)); - _args = (string[])info.GetValue("args", typeof(string[])); + _res = (string)info.GetValue("res", typeof(string))!; + _args = (string[]?)info.GetValue("args", typeof(string[])); // deserialize optional members - string version = null; + string? version = null; foreach (SerializationEntry e in info) { if (e.Name == "version") { - version = (string)e.Value; + version = (string?)e.Value; } } @@ -57,18 +58,18 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont info.AddValue("version", "2.0"); } - public XPathException() : this(string.Empty, (Exception)null) { } + public XPathException() : this(string.Empty, (Exception?)null) { } - public XPathException(string message) : this(message, (Exception)null) { } + public XPathException(string message) : this(message, (Exception?)null) { } - public XPathException(string message, Exception innerException) : + public XPathException(string message, Exception? innerException) : this(SR.Xml_UserException, new string[] { message }, innerException) { } internal static XPathException Create(string res) { - return new XPathException(res, (string[])null); + return new XPathException(res, (string[]?)null); } internal static XPathException Create(string res, string arg) @@ -86,12 +87,12 @@ internal static XPathException Create(string res, string arg, Exception innerExc return new XPathException(res, new string[] { arg }, innerException); } - private XPathException(string res, string[] args) : + private XPathException(string res, string[]? args) : this(res, args, null) { } - private XPathException(string res, string[] args, Exception inner) : + private XPathException(string res, string[]? args, Exception? inner) : base(CreateMessage(res, args), inner) { HResult = HResults.XmlXPath; @@ -99,7 +100,7 @@ private XPathException(string res, string[] args, Exception inner) : _args = args; } - private static string CreateMessage(string res, string[] args) + private static string CreateMessage(string res, string[]? args) { try { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathExpr.cs index b25f7b85b30c..af967030af59 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathExpr.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. +#nullable enable using MS.Internal.Xml.XPath; using System.Collections; @@ -59,7 +60,7 @@ public static XPathExpression Compile(string xpath) return Compile(xpath, /*nsResolver:*/null); } - public static XPathExpression Compile(string xpath, IXmlNamespaceResolver nsResolver) + public static XPathExpression Compile(string xpath, IXmlNamespaceResolver? nsResolver) { bool hasPrefix; Query query = new QueryBuilder().Build(xpath, out hasPrefix); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathItem.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathItem.cs index 77308682a7c6..abe7141ce9a4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathItem.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathItem.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. +#nullable enable using System.Xml.Schema; namespace System.Xml.XPath @@ -18,7 +19,7 @@ public abstract class XPathItem /// /// Returns Xsd type of atomic value, or of node's content. /// - public abstract XmlSchemaType XmlType { get; } + public abstract XmlSchemaType? XmlType { get; } /// /// Typed and untyped value accessors. @@ -32,6 +33,6 @@ public abstract class XPathItem public abstract int ValueAsInt { get; } public abstract long ValueAsLong { get; } public virtual object ValueAs(Type returnType) { return ValueAs(returnType, null); } - public abstract object ValueAs(Type returnType, IXmlNamespaceResolver nsResolver); + public abstract object ValueAs(Type returnType, IXmlNamespaceResolver? nsResolver); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNamespaceScope.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNamespaceScope.cs index 82fcb44330f6..48399c0fb8bc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNamespaceScope.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNamespaceScope.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. +#nullable enable namespace System.Xml.XPath { public enum XPathNamespaceScope diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs index 6db4765ed9b3..02baf072f2a2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs @@ -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. +#nullable enable using System.ComponentModel; using System.IO; using System.Collections; @@ -13,6 +14,7 @@ using System.Xml; using MS.Internal.Xml.Cache; using MS.Internal.Xml.XPath; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.XPath { @@ -40,16 +42,16 @@ public override sealed bool IsNode get { return true; } } - public override XmlSchemaType XmlType + public override XmlSchemaType? XmlType { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; + IXmlSchemaInfo? schemaInfo = SchemaInfo; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) { - XmlSchemaType memberType = schemaInfo.MemberType; + XmlSchemaType? memberType = schemaInfo.MemberType; if (memberType != null) { return memberType; @@ -70,9 +72,9 @@ public override object TypedValue { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -122,15 +124,15 @@ public virtual void SetTypedValue(object typedValue) default: throw new InvalidOperationException(SR.Xpn_BadPosition); } - string value = null; - IXmlSchemaInfo schemaInfo = SchemaInfo; + string? value = null; + IXmlSchemaInfo? schemaInfo = SchemaInfo; if (schemaInfo != null) { - XmlSchemaType schemaType = schemaInfo.SchemaType; + XmlSchemaType? schemaType = schemaInfo.SchemaType; if (schemaType != null) { value = schemaType.ValueConverter.ToString(typedValue, this); - XmlSchemaDatatype datatype = schemaType.Datatype; + XmlSchemaDatatype? datatype = schemaType.Datatype; if (datatype != null) { datatype.ParseValue(value, NameTable, this); @@ -148,9 +150,9 @@ public override Type ValueType { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -190,9 +192,9 @@ public override bool ValueAsBoolean { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -228,9 +230,9 @@ public override DateTime ValueAsDateTime { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -266,9 +268,9 @@ public override double ValueAsDouble { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -304,9 +306,9 @@ public override int ValueAsInt { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -342,9 +344,9 @@ public override long ValueAsLong { get { - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -376,15 +378,15 @@ public override long ValueAsLong } } - public override object ValueAs(Type returnType, IXmlNamespaceResolver nsResolver) + public override object ValueAs(Type returnType, IXmlNamespaceResolver? nsResolver) { if (nsResolver == null) { nsResolver = this; } - IXmlSchemaInfo schemaInfo = SchemaInfo; - XmlSchemaType schemaType; - XmlSchemaDatatype datatype; + IXmlSchemaInfo? schemaInfo = SchemaInfo; + XmlSchemaType? schemaType; + XmlSchemaDatatype? datatype; if (schemaInfo != null) { if (schemaInfo.Validity == XmlSchemaValidity.Valid) @@ -439,7 +441,7 @@ public virtual XPathNavigator CreateNavigator() public abstract XmlNameTable NameTable { get; } - public virtual string LookupNamespace(string prefix) + public virtual string? LookupNamespace(string prefix) { if (prefix == null) return null; @@ -470,7 +472,7 @@ public virtual string LookupNamespace(string prefix) return null; } - public virtual string LookupPrefix(string namespaceURI) + public virtual string? LookupPrefix(string namespaceURI) { if (namespaceURI == null) return null; @@ -610,7 +612,7 @@ public virtual void WriteSubtree(XmlWriter writer) writer.WriteNode(this, true); } - public virtual object UnderlyingObject + public virtual object? UnderlyingObject { get { return null; } } @@ -778,7 +780,7 @@ public virtual bool MoveToFollowing(string localName, string namespaceURI) return MoveToFollowing(localName, namespaceURI, null); } - public virtual bool MoveToFollowing(string localName, string namespaceURI, XPathNavigator end) + public virtual bool MoveToFollowing(string localName, string namespaceURI, XPathNavigator? end) { XPathNavigator navSave = Clone(); @@ -844,7 +846,7 @@ public virtual bool MoveToFollowing(XPathNodeType type) return MoveToFollowing(type, null); } - public virtual bool MoveToFollowing(XPathNodeType type, XPathNavigator end) + public virtual bool MoveToFollowing(XPathNodeType type, XPathNavigator? end) { XPathNavigator navSave = Clone(); int mask = GetContentKindMask(type); @@ -947,7 +949,7 @@ public virtual bool HasChildren public abstract bool IsSamePosition(XPathNavigator other); - public virtual bool IsDescendant(XPathNavigator nav) + public virtual bool IsDescendant([NotNullWhen(true)] XPathNavigator? nav) { if (nav != null) { @@ -959,7 +961,7 @@ public virtual bool IsDescendant(XPathNavigator nav) return false; } - public virtual XmlNodeOrder ComparePosition(XPathNavigator nav) + public virtual XmlNodeOrder ComparePosition(XPathNavigator? nav) { if (nav == null) { @@ -1019,17 +1021,17 @@ public virtual XmlNodeOrder ComparePosition(XPathNavigator nav) } } - public virtual IXmlSchemaInfo SchemaInfo + public virtual IXmlSchemaInfo? SchemaInfo { get { return this as IXmlSchemaInfo; } } public virtual bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) { - IXmlSchemaInfo schemaInfo; - XmlSchemaType schemaType = null; - XmlSchemaElement schemaElement = null; - XmlSchemaAttribute schemaAttribute = null; + IXmlSchemaInfo? schemaInfo; + XmlSchemaType? schemaType = null; + XmlSchemaElement? schemaElement = null; + XmlSchemaAttribute? schemaAttribute = null; switch (NodeType) { @@ -1080,9 +1082,9 @@ public virtual bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler v Debug.Assert(schemaType != null || this.NodeType == XPathNodeType.Root, "schemaType != null || this.NodeType == XPathNodeType.Root"); - XmlReader reader = CreateReader(); + XPathNavigatorReader reader = (XPathNavigatorReader)CreateReader(); - CheckValidityHelper validityTracker = new CheckValidityHelper(validationEventHandler, reader as XPathNavigatorReader); + CheckValidityHelper validityTracker = new CheckValidityHelper(validationEventHandler, reader); validationEventHandler = new ValidationEventHandler(validityTracker.ValidationCallback); XmlReader validatingReader = GetValidatingReader(reader, schemas, validationEventHandler, schemaType, schemaElement, schemaAttribute); @@ -1092,7 +1094,7 @@ public virtual bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler v return validityTracker.IsValid; } - private XmlReader GetValidatingReader(XmlReader reader, XmlSchemaSet schemas, ValidationEventHandler validationEvent, XmlSchemaType schemaType, XmlSchemaElement schemaElement, XmlSchemaAttribute schemaAttribute) + private XmlReader GetValidatingReader(XmlReader reader, XmlSchemaSet schemas, ValidationEventHandler validationEvent, XmlSchemaType? schemaType, XmlSchemaElement? schemaElement, XmlSchemaAttribute? schemaAttribute) { if (schemaAttribute != null) { @@ -1128,12 +1130,12 @@ internal CheckValidityHelper(ValidationEventHandler nextEventHandler, XPathNavig _reader = reader; } - internal void ValidationCallback(object sender, ValidationEventArgs args) + internal void ValidationCallback(object? sender, ValidationEventArgs args) { Debug.Assert(args != null); if (args.Severity == XmlSeverityType.Error) _isValid = false; - XmlSchemaValidationException exception = args.Exception as XmlSchemaValidationException; + XmlSchemaValidationException? exception = args.Exception as XmlSchemaValidationException; if (exception != null && _reader != null) exception.SetSourceObject(_reader.UnderlyingObject); @@ -1158,17 +1160,17 @@ public virtual XPathExpression Compile(string xpath) return XPathExpression.Compile(xpath); } - public virtual XPathNavigator SelectSingleNode(string xpath) + public virtual XPathNavigator? SelectSingleNode(string xpath) { return SelectSingleNode(XPathExpression.Compile(xpath)); } - public virtual XPathNavigator SelectSingleNode(string xpath, IXmlNamespaceResolver resolver) + public virtual XPathNavigator? SelectSingleNode(string xpath, IXmlNamespaceResolver? resolver) { return SelectSingleNode(XPathExpression.Compile(xpath, resolver)); } - public virtual XPathNavigator SelectSingleNode(XPathExpression expression) + public virtual XPathNavigator? SelectSingleNode(XPathExpression expression) { // PERF BUG: this actually caches _all_ matching nodes... XPathNodeIterator iter = this.Select(expression); @@ -1191,7 +1193,7 @@ public virtual XPathNodeIterator Select(string xpath, IXmlNamespaceResolver reso public virtual XPathNodeIterator Select(XPathExpression expr) { - XPathNodeIterator result = Evaluate(expr) as XPathNodeIterator; + XPathNodeIterator? result = Evaluate(expr) as XPathNodeIterator; if (result == null) { throw XPathException.Create(SR.Xp_NodeSetExpected); @@ -1214,9 +1216,9 @@ public virtual object Evaluate(XPathExpression expr) return Evaluate(expr, null); } - public virtual object Evaluate(XPathExpression expr, XPathNodeIterator context) + public virtual object Evaluate(XPathExpression expr, XPathNodeIterator? context) { - CompiledXpathExpr cexpr = expr as CompiledXpathExpr; + CompiledXpathExpr? cexpr = expr as CompiledXpathExpr; if (cexpr == null) { throw XPathException.Create(SR.Xp_BadQueryObject); @@ -1233,6 +1235,7 @@ public virtual object Evaluate(XPathExpression expr, XPathNodeIterator context) if (result is XPathNodeIterator) { + Debug.Assert(context.Current != null); return new XPathSelectionIterator(context.Current, query); } @@ -1241,7 +1244,7 @@ public virtual object Evaluate(XPathExpression expr, XPathNodeIterator context) public virtual bool Matches(XPathExpression expr) { - CompiledXpathExpr cexpr = expr as CompiledXpathExpr; + CompiledXpathExpr? cexpr = expr as CompiledXpathExpr; if (cexpr == null) throw XPathException.Create(SR.Xp_BadQueryObject); @@ -1695,10 +1698,10 @@ internal bool MoveToPrevious(string localName, string namespaceURI) { XPathNavigator navClone = Clone(); - localName = (localName != null) ? NameTable.Get(localName) : null; + string? atomizedLocalName = (localName != null) ? NameTable.Get(localName) : null; while (MoveToPrevious()) { - if (NodeType == XPathNodeType.Element && (object)localName == (object)LocalName && namespaceURI == NamespaceURI) + if (NodeType == XPathNodeType.Element && atomizedLocalName == LocalName && namespaceURI == NamespaceURI) return true; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorKeyComparer.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorKeyComparer.cs index 7a8f59d78641..b79cc674d533 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorKeyComparer.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorKeyComparer.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. +#nullable enable using MS.Internal.Xml.Cache; using System.Collections; @@ -8,10 +9,10 @@ namespace System.Xml.XPath { internal class XPathNavigatorKeyComparer : IEqualityComparer { - bool IEqualityComparer.Equals(object obj1, object obj2) + bool IEqualityComparer.Equals(object? obj1, object? obj2) { - XPathNavigator nav1 = obj1 as XPathNavigator; - XPathNavigator nav2 = obj2 as XPathNavigator; + XPathNavigator? nav1 = obj1 as XPathNavigator; + XPathNavigator? nav2 = obj2 as XPathNavigator; if ((nav1 != null) && (nav2 != null)) { if (nav1.IsSamePosition(nav2)) @@ -23,8 +24,8 @@ bool IEqualityComparer.Equals(object obj1, object obj2) int IEqualityComparer.GetHashCode(object obj) { int hashCode; - XPathNavigator nav; - XPathDocumentNavigator xpdocNav; + XPathNavigator? nav; + XPathDocumentNavigator? xpdocNav; if (obj == null) { @@ -36,7 +37,7 @@ int IEqualityComparer.GetHashCode(object obj) } else if (null != (nav = obj as XPathNavigator)) { - object underlyingObject = nav.UnderlyingObject; + object? underlyingObject = nav.UnderlyingObject; if (underlyingObject != null) { hashCode = underlyingObject.GetHashCode(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorReader.cs index d0e51d85fcbd..1b8a06a8dcfd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigatorReader.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.IO; using System.Xml.Schema; using System.Collections; using System.Diagnostics; using System.Collections.Generic; - namespace System.Xml.XPath { /// @@ -36,10 +36,10 @@ private enum State private int _attrCount; private bool _readEntireDocument; - protected IXmlLineInfo lineInfo; - protected IXmlSchemaInfo schemaInfo; + protected IXmlLineInfo? lineInfo; + protected IXmlSchemaInfo? schemaInfo; - private ReadContentAsBinaryHelper _readBinaryHelper; + private ReadContentAsBinaryHelper? _readBinaryHelper; private State _savedState; internal const string space = "space"; @@ -66,7 +66,7 @@ internal static XmlNodeType ToXmlNodeType(XPathNodeType typ) return XPathNavigatorReader.convertFromXPathNodeType[(int)typ]; } - internal object UnderlyingObject + internal object? UnderlyingObject { get { @@ -77,8 +77,8 @@ internal object UnderlyingObject public static XPathNavigatorReader Create(XPathNavigator navToRead) { XPathNavigator nav = navToRead.Clone(); - IXmlLineInfo xli = nav as IXmlLineInfo; - IXmlSchemaInfo xsi = nav as IXmlSchemaInfo; + IXmlLineInfo? xli = nav as IXmlLineInfo; + IXmlSchemaInfo? xsi = nav as IXmlSchemaInfo; #if NAVREADER_SUPPORTSLINEINFO if (null == xsi) { if (null == xli) { @@ -108,7 +108,7 @@ public static XPathNavigatorReader Create(XPathNavigator navToRead) #endif } - protected XPathNavigatorReader(XPathNavigator navToRead, IXmlLineInfo xli, IXmlSchemaInfo xsi) + protected XPathNavigatorReader(XPathNavigator navToRead, IXmlLineInfo? xli, IXmlSchemaInfo? xsi) { // Need clone that can be moved independently of original navigator _navToRead = navToRead; @@ -147,12 +147,12 @@ IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamesp return _nav.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _nav.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _nav.LookupPrefix(namespaceName); } @@ -174,7 +174,7 @@ public override XmlReaderSettings Settings } } - public override IXmlSchemaInfo SchemaInfo + public override IXmlSchemaInfo? SchemaInfo { get { @@ -316,9 +316,9 @@ public override string Value } } - private XPathNavigator GetElemNav() + private XPathNavigator? GetElemNav() { - XPathNavigator tempNav; + XPathNavigator? tempNav; switch (_state) { case State.Content: @@ -331,16 +331,16 @@ private XPathNavigator GetElemNav() break; case State.InReadBinary: _state = _savedState; - XPathNavigator nav = GetElemNav(); + XPathNavigator? nav = GetElemNav(); _state = State.InReadBinary; return nav; } return null; } - private XPathNavigator GetElemNav(out int depth) + private XPathNavigator? GetElemNav(out int depth) { - XPathNavigator nav = null; + XPathNavigator? nav = null; switch (_state) { case State.Content: @@ -385,7 +385,7 @@ public override int AttributeCount if (_attrCount < 0) { // attribute count works for element, regardless of where you are in start tag - XPathNavigator tempNav = GetElemNav(); + XPathNavigator? tempNav = GetElemNav(); int count = 0; if (null != tempNav) { @@ -411,7 +411,7 @@ public override int AttributeCount } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { // reader allows calling GetAttribute, even when positioned inside attributes XPathNavigator nav = _nav; @@ -456,7 +456,7 @@ public override string GetAttribute(string name) return null; } - public override string GetAttribute(string localName, string namespaceURI) + public override string? GetAttribute(string localName, string? namespaceURI) { if (null == localName) throw new ArgumentNullException(nameof(localName)); @@ -498,10 +498,10 @@ public override string GetAttribute(string localName, string namespaceURI) } } - private static string GetNamespaceByIndex(XPathNavigator nav, int index, out int count) + private static string? GetNamespaceByIndex(XPathNavigator nav, int index, out int count) { string thisValue = nav.Value; - string value = null; + string? value = null; if (nav.MoveToNextNamespace(XPathNamespaceScope.Local)) { value = GetNamespaceByIndex(nav, index, out count); @@ -523,7 +523,7 @@ public override string GetAttribute(int index) { if (index < 0) goto Error; - XPathNavigator nav = GetElemNav(); + XPathNavigator? nav = GetElemNav(); if (null == nav) goto Error; if (nav.MoveToFirstNamespace(XPathNamespaceScope.Local)) @@ -532,7 +532,7 @@ public override string GetAttribute(int index) // but we want to return them in the correct order, // so first count the namespaces int nsCount; - string value = GetNamespaceByIndex(nav, index, out nsCount); + string? value = GetNamespaceByIndex(nav, index, out nsCount); if (null != value) { return value; @@ -555,12 +555,12 @@ public override string GetAttribute(int index) } - public override bool MoveToAttribute(string localName, string namespaceName) + public override bool MoveToAttribute(string localName, string? namespaceName) { if (null == localName) throw new ArgumentNullException(nameof(localName)); int depth = _depth; - XPathNavigator nav = GetElemNav(out depth); + XPathNavigator? nav = GetElemNav(out depth); if (null != nav) { if (namespaceName == XmlReservedNs.NsXmlNs) @@ -589,7 +589,7 @@ public override bool MoveToAttribute(string localName, string namespaceName) FoundMatch: if (_state == State.InReadBinary) { - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); _state = _savedState; } MoveToAttr(nav, depth + 1); @@ -599,7 +599,7 @@ public override bool MoveToAttribute(string localName, string namespaceName) public override bool MoveToFirstAttribute() { int depth; - XPathNavigator nav = GetElemNav(out depth); + XPathNavigator? nav = GetElemNav(out depth); if (null != nav) { if (nav.MoveToFirstNamespace(XPathNamespaceScope.Local)) @@ -618,7 +618,7 @@ public override bool MoveToFirstAttribute() FoundMatch: if (_state == State.InReadBinary) { - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); _state = _savedState; } MoveToAttr(nav, depth + 1); @@ -693,7 +693,7 @@ public override bool MoveToNextAttribute() _state = State.InReadBinary; return false; } - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); return true; default: @@ -704,7 +704,7 @@ public override bool MoveToNextAttribute() public override bool MoveToAttribute(string name) { int depth; - XPathNavigator nav = GetElemNav(out depth); + XPathNavigator? nav = GetElemNav(out depth); if (null == nav) return false; @@ -749,7 +749,7 @@ public override bool MoveToAttribute(string name) FoundMatch: if (_state == State.InReadBinary) { - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); _state = _savedState; } MoveToAttr(nav, depth + 1); @@ -777,7 +777,7 @@ public override bool MoveToElement() _state = State.InReadBinary; return false; } - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); break; } return false; @@ -824,7 +824,7 @@ public override bool ReadAttributeValue() { if (_state == State.InReadBinary) { - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); _state = _savedState; } if (_state == State.Attribute) @@ -863,7 +863,7 @@ public override int ReadContentAsBase64(byte[] buffer, int index, int count) _state = _savedState; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBase64(buffer, index, count); // turn on InReadBinary state again and return _savedState = _state; @@ -889,7 +889,7 @@ public override int ReadContentAsBinHex(byte[] buffer, int index, int count) _state = _savedState; // call to the helper - int readCount = _readBinaryHelper.ReadContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadContentAsBinHex(buffer, index, count); // turn on InReadBinary state again and return _savedState = _state; @@ -915,7 +915,7 @@ public override int ReadElementContentAsBase64(byte[] buffer, int index, int cou _state = _savedState; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBase64(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBase64(buffer, index, count); // turn on InReadBinary state again and return _savedState = _state; @@ -941,7 +941,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou _state = _savedState; // call to the helper - int readCount = _readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count); + int readCount = _readBinaryHelper!.ReadElementContentAsBinHex(buffer, index, count); // turn on InReadBinary state again and return _savedState = _state; @@ -949,7 +949,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou return readCount; } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return _nav.LookupNamespace(prefix); } @@ -1051,7 +1051,7 @@ public override bool Read() goto case State.Content; case State.InReadBinary: _state = _savedState; - _readBinaryHelper.Finish(); + _readBinaryHelper!.Finish(); return Read(); } return true; @@ -1083,7 +1083,7 @@ private void SetEOF() #if NAVREADER_SUPPORTSLINEINFO internal class XPathNavigatorReaderWithLI : XPathNavigatorReader, System.Xml.IXmlLineInfo { - internal XPathNavigatorReaderWithLI( XPathNavigator navToRead, IXmlLineInfo xli, IXmlSchemaInfo xsi ) + internal XPathNavigatorReaderWithLI( XPathNavigator navToRead, IXmlLineInfo xli, IXmlSchemaInfo? xsi ) : base( navToRead, xli, xsi ) { } @@ -1117,22 +1117,23 @@ internal XPathNavigatorReaderWithLIAndSI( XPathNavigator navToRead, IXmlLineInfo internal class XPathNavigatorReaderWithSI : XPathNavigatorReader, System.Xml.Schema.IXmlSchemaInfo { - internal XPathNavigatorReaderWithSI(XPathNavigator navToRead, IXmlLineInfo xli, IXmlSchemaInfo xsi) + internal XPathNavigatorReaderWithSI(XPathNavigator navToRead, IXmlLineInfo? xli, IXmlSchemaInfo xsi) : base(navToRead, xli, xsi) { + schemaInfo = xsi; } //----------------------------------------------- // IXmlSchemaInfo //----------------------------------------------- - public virtual XmlSchemaValidity Validity { get { return IsReading ? this.schemaInfo.Validity : XmlSchemaValidity.NotKnown; } } - public override bool IsDefault { get { return IsReading ? this.schemaInfo.IsDefault : false; } } - public virtual bool IsNil { get { return IsReading ? this.schemaInfo.IsNil : false; } } - public virtual XmlSchemaSimpleType MemberType { get { return IsReading ? this.schemaInfo.MemberType : null; } } - public virtual XmlSchemaType SchemaType { get { return IsReading ? this.schemaInfo.SchemaType : null; } } - public virtual XmlSchemaElement SchemaElement { get { return IsReading ? this.schemaInfo.SchemaElement : null; } } - public virtual XmlSchemaAttribute SchemaAttribute { get { return IsReading ? this.schemaInfo.SchemaAttribute : null; } } + public virtual XmlSchemaValidity Validity { get { return IsReading ? this.schemaInfo!.Validity : XmlSchemaValidity.NotKnown; } } + public override bool IsDefault { get { return IsReading ? this.schemaInfo!.IsDefault : false; } } + public virtual bool IsNil { get { return IsReading ? this.schemaInfo!.IsNil : false; } } + public virtual XmlSchemaSimpleType? MemberType { get { return IsReading ? this.schemaInfo!.MemberType : null; } } + public virtual XmlSchemaType? SchemaType { get { return IsReading ? this.schemaInfo!.SchemaType : null; } } + public virtual XmlSchemaElement? SchemaElement { get { return IsReading ? this.schemaInfo!.SchemaElement : null; } } + public virtual XmlSchemaAttribute? SchemaAttribute { get { return IsReading ? this.schemaInfo!.SchemaAttribute : null; } } } /// @@ -1142,7 +1143,7 @@ internal XPathNavigatorReaderWithSI(XPathNavigator navToRead, IXmlLineInfo xli, /// internal class XmlEmptyNavigator : XPathNavigator { - private static volatile XmlEmptyNavigator s_singleton; + private static volatile XmlEmptyNavigator? s_singleton; private XmlEmptyNavigator() { @@ -1270,7 +1271,8 @@ public override bool MoveToId(string id) public override string GetAttribute(string localName, string namespaceName) { - return null; + Debug.Fail("This shouldn't be called."); + return null!; } public override bool MoveToAttribute(string localName, string namespaceName) @@ -1280,7 +1282,8 @@ public override bool MoveToAttribute(string localName, string namespaceName) public override string GetNamespace(string name) { - return null; + Debug.Fail("This shouldn't be called."); + return null!; } public override bool MoveToNamespace(string prefix) @@ -1307,13 +1310,13 @@ public override bool MoveToParent() public override bool MoveTo(XPathNavigator other) { // Only one instance of XmlEmptyNavigator exists on the system - return (object)this == (object)other; + return (object)this == (object?)other; } - public override XmlNodeOrder ComparePosition(XPathNavigator other) + public override XmlNodeOrder ComparePosition(XPathNavigator? other) { // Only one instance of XmlEmptyNavigator exists on the system - return ((object)this == (object)other) ? XmlNodeOrder.Same : XmlNodeOrder.Unknown; + return ((object)this == (object?)other) ? XmlNodeOrder.Same : XmlNodeOrder.Unknown; } public override bool IsSamePosition(XPathNavigator other) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeIterator.cs index 8e2c89ca186f..d9573be04b37 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeIterator.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. +#nullable enable using System.Collections; using System.Diagnostics; @@ -15,7 +16,7 @@ public abstract class XPathNodeIterator : ICloneable, IEnumerable public abstract XPathNodeIterator Clone(); public abstract bool MoveNext(); - public abstract XPathNavigator Current { get; } + public abstract XPathNavigator? Current { get; } public abstract int CurrentPosition { get; } public virtual int Count { @@ -35,7 +36,7 @@ public virtual IEnumerator GetEnumerator() return new Enumerator(this); } - private object debuggerDisplayProxy { get { return Current == null ? null : (object)new XPathNavigator.DebuggerDisplayProxy(Current); } } + private object? debuggerDisplayProxy { get { return Current == null ? null : (object)new XPathNavigator.DebuggerDisplayProxy(Current); } } /// /// Implementation of a resetable enumerator that is linked to the XPathNodeIterator used to create it. @@ -43,7 +44,7 @@ public virtual IEnumerator GetEnumerator() private class Enumerator : IEnumerator { private readonly XPathNodeIterator _original; // Keep original XPathNodeIterator in case Reset() is called - private XPathNodeIterator _current; + private XPathNodeIterator? _current; private bool _iterationStarted; public Enumerator(XPathNodeIterator original) @@ -63,6 +64,7 @@ public virtual object Current if (_current == null) throw new InvalidOperationException(SR.Format(SR.Sch_EnumFinished, string.Empty)); + Debug.Assert(_current.Current != null); return _current.Current.Clone(); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeType.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeType.cs index a7008883b65b..e23fcd921afe 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNodeType.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. +#nullable enable namespace System.Xml.XPath { public enum XPathNodeType diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs index 83268d4a8a8e..e04ebb6969af 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs @@ -1093,7 +1093,7 @@ public static double ToDouble(string s) return null; } - internal static double ToXPathDouble(object o) + internal static double ToXPathDouble(object? o) { if (o is string str) { From fdb2bef710c61dc9af737799937b93a4c9bc8b31 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 27 Jul 2020 14:10:59 -0700 Subject: [PATCH 070/755] Keep only Abstractions dependency on Configuration.Binder (#39461) --- .../ref/Microsoft.Extensions.Configuration.Binder.csproj | 1 - .../src/Microsoft.Extensions.Configuration.Binder.csproj | 1 - .../tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj | 1 + .../tests/Microsoft.Extensions.Options.Tests.csproj | 1 + 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj index 4a128e5c3845..3e14fd0db31e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj @@ -6,7 +6,6 @@ - diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 0c2ba3fbdfe6..0295775fad12 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -6,7 +6,6 @@ - diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj index 219d53b133ef..d2323d0b590c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj index 3dfad737c847..e6fb72af7317 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj @@ -6,6 +6,7 @@ + From da669c474cc595efce538f33c8de593926a9ee21 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Mon, 27 Jul 2020 15:37:01 -0700 Subject: [PATCH 071/755] Fix issue with Crossgen2 package excluding Icon (#39972) The latest packaging targets rely on ProjectDefaults inclusion of package icon, but this item was being removed by the Crossgen2 project's targets. Also updating the version of packaging tools to see if we have any other failures. --- eng/Versions.props | 2 +- .../netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 25c6db6eea46..86656b65675a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -59,7 +59,7 @@ 5.0.0-beta.20364.3 5.0.0-beta.20367.6 2.5.1-beta.20364.3 - 5.0.0-beta.20364.3 + 5.0.0-beta.20374.3 5.0.0-beta.20367.6 5.0.0-beta.20364.3 diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj index 08933b133652..e9fc92b2acbb 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj +++ b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj @@ -38,7 +38,7 @@ DependsOnTargets="ConvertItems" BeforeTargets="GetPackageFiles"> - + From 0168d8e36c5ca3393391f596ac4e57fa31a31402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 28 Jul 2020 00:59:51 +0200 Subject: [PATCH 072/755] [mono] Fix building multiple os/arch combinations in the same working directory (#39970) After adding the ICU shim code to the runtime we hit an issue when e.g. compiling for "desktop" mono in a working directory that already had Browser wasm artifacts in it. This is due to automake putting the intermediate compilation artifacts at the same location where a file was referenced from. This means that e.g. when using `../../../libraries/Native/Unix/System.Globalization.Native/pal_icushim.c` in the Makefile.am we'd get the intermediaries in `artifacts/obj/mono/libraries/` instead of somewhere in `artifacts/obj/mono/OSX.x64.Debug`. Later on we'd get the following error because it was reusing the existing .o file from another architecture: ``` Undefined symbols for architecture x86_64: "_gPalGlobalizationNative", referenced from: _c_qcalls in libmonoruntimesgen.a(libmonoruntimesgen_la-native-library-qcall.o) ``` Fix this by symlinking the source files into the build directory. --- src/mono/mono/metadata/Makefile.am | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/metadata/Makefile.am b/src/mono/mono/metadata/Makefile.am index 06abdd51ab2b..76fa995d570d 100644 --- a/src/mono/mono/metadata/Makefile.am +++ b/src/mono/mono/metadata/Makefile.am @@ -142,26 +142,31 @@ libmonoruntime_support_la_CFLAGS = $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@) @ if ENABLE_NETCORE if HAVE_SYS_ICU + +# symlink ICU sources to a local dir so automake puts intermediates into the target-specific folder +icushim/%.c: @ICU_SHIM_PATH@/%.c + $(LN_S) $^ $@ + shim_libraries = libmonoruntime-shimglobalization.la nodist_libmonoruntime_shimglobalization_la_SOURCES = \ - @ICU_SHIM_PATH@/pal_calendarData.c \ - @ICU_SHIM_PATH@/pal_casing.c \ - @ICU_SHIM_PATH@/pal_collation.c \ - @ICU_SHIM_PATH@/pal_idna.c \ - @ICU_SHIM_PATH@/pal_locale.c \ - @ICU_SHIM_PATH@/pal_localeNumberData.c \ - @ICU_SHIM_PATH@/pal_localeStringData.c \ - @ICU_SHIM_PATH@/pal_normalization.c \ - @ICU_SHIM_PATH@/pal_timeZoneInfo.c \ - @ICU_SHIM_PATH@/entrypoints.c + icushim/pal_calendarData.c \ + icushim/pal_casing.c \ + icushim/pal_collation.c \ + icushim/pal_idna.c \ + icushim/pal_locale.c \ + icushim/pal_localeNumberData.c \ + icushim/pal_localeStringData.c \ + icushim/pal_normalization.c \ + icushim/pal_timeZoneInfo.c \ + icushim/entrypoints.c libmonoruntime_shimglobalization_la_CFLAGS = @ICU_CFLAGS@ -I$(top_srcdir)/../libraries/Native/Unix/System.Globalization.Native/ -I$(top_srcdir)/../libraries/Native/Unix/Common/ if STATIC_ICU -nodist_libmonoruntime_shimglobalization_la_SOURCES += @ICU_SHIM_PATH@/pal_icushim_static.c +nodist_libmonoruntime_shimglobalization_la_SOURCES += icushim/pal_icushim_static.c else -nodist_libmonoruntime_shimglobalization_la_SOURCES += @ICU_SHIM_PATH@/pal_icushim.c +nodist_libmonoruntime_shimglobalization_la_SOURCES += icushim/pal_icushim.c endif # STATIC_ICU endif # HAVE_SYS_ICU From 383295b707da09db530d86b14a4f409a05d0c5f6 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Mon, 27 Jul 2020 16:01:04 -0700 Subject: [PATCH 073/755] Remove GetIPCEventSendBufferContinuation (#39662) * Fix write on failure to allocate buffer * Remove GetIPCEventSendBufferContinuation altogether --- src/coreclr/src/debug/ee/debugger.h | 31 ----------------------------- 1 file changed, 31 deletions(-) diff --git a/src/coreclr/src/debug/ee/debugger.h b/src/coreclr/src/debug/ee/debugger.h index 2450ab65d4f9..6c113315852b 100644 --- a/src/coreclr/src/debug/ee/debugger.h +++ b/src/coreclr/src/debug/ee/debugger.h @@ -725,37 +725,6 @@ class DebuggerRCThread return GetRCThreadSendBuffer(); } - DebuggerIPCEvent *GetIPCEventSendBufferContinuation( - DebuggerIPCEvent *eventCur) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - PRECONDITION(eventCur != NULL); - PRECONDITION(eventCur->next == NULL); - } - CONTRACTL_END; - - DebuggerIPCEvent *dipce = (DebuggerIPCEvent *) new (nothrow) BYTE [CorDBIPC_BUFFER_SIZE]; - dipce->next = NULL; - - LOG((LF_CORDB,LL_INFO1000000, "About to GIPCESBC 0x%x\n",dipce)); - - if (dipce != NULL) - { - eventCur->next = dipce; - } -#ifdef _DEBUG - else - { - _ASSERTE( !"GetIPCEventSendBufferContinuation failed to allocate mem!" ); - } -#endif //_DEBUG - - return dipce; - } - // Send an IPCEvent once we're ready for sending. This should be done inbetween // SENDIPCEVENT_BEGIN & SENDIPCEVENT_END. See definition of SENDIPCEVENT_BEGIN // for usage pattern From ed4f3360767aacabb4905cf454c02c520468e92f Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 27 Jul 2020 16:32:36 -0700 Subject: [PATCH 074/755] Disable gcdump test under GCStress due to test failure (#39977) Issue: https://github.com/dotnet/runtime/issues/39931 --- src/tests/tracing/eventpipe/gcdump/gcdump.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj index a1915b163e35..676d812f12ea 100644 --- a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj +++ b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj @@ -6,6 +6,8 @@ true true 0 + + true From cfb447b28d3a37c7f3ba1c985da3c039a6c1aaf6 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 27 Jul 2020 16:33:38 -0700 Subject: [PATCH 075/755] Disable eventpipe test under GCStress due to test failure (#39978) Issue: https://github.com/dotnet/runtime/issues/39932 --- src/tests/profiler/eventpipe/eventpipe.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/profiler/eventpipe/eventpipe.csproj b/src/tests/profiler/eventpipe/eventpipe.csproj index 7a525ce745d2..cc0888d25678 100644 --- a/src/tests/profiler/eventpipe/eventpipe.csproj +++ b/src/tests/profiler/eventpipe/eventpipe.csproj @@ -6,6 +6,8 @@ true 0 true + + true From d6d8e8ae67079d37284e8064bb64afd0bfb1e478 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 27 Jul 2020 17:12:15 -0700 Subject: [PATCH 076/755] Fix superpmi.py script for asmdiffs (#39948) --- src/coreclr/scripts/superpmi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py index fa0f3e2f165d..377af07e0a9d 100755 --- a/src/coreclr/scripts/superpmi.py +++ b/src/coreclr/scripts/superpmi.py @@ -2128,7 +2128,7 @@ def verify_superpmi_common_args(): # yielding # [0]: "" # [1]: "\Windows_NT.x64.Checked" - standard_location_split = os.path.dirname(coreclr_args.jit_path).split(os.path.dirname(coreclr_args.product_location)) + standard_location_split = os.path.dirname(coreclr_args.base_jit_path).split(os.path.dirname(coreclr_args.product_location)) assert(coreclr_args.host_os in standard_location_split[1]) # Get arch/flavor. Remove leading slash. From fa72c754c513e1a681e3df59c87573af59656afd Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 27 Jul 2020 20:20:28 -0400 Subject: [PATCH 077/755] [jit] Add a intrinsic for ThrowForUnsupportedVectorBaseType. (#39965) Part of https://github.com/dotnet/runtime/issues/38718. --- src/mono/mono/mini/intrinsics.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index 6f6d93bbe407..cf8bcc936aaa 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -1948,6 +1948,34 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign } } + if (in_corlib && + !strcmp ("System", cmethod_klass_name_space) && + !strcmp ("ThrowHelper", cmethod_klass_name) && + !strcmp ("ThrowForUnsupportedVectorBaseType", cmethod->name)) { + /* The mono JIT can't optimize the body of this method away */ + MonoGenericContext *ctx = mono_method_get_context (cmethod); + g_assert (ctx); + g_assert (ctx->method_inst); + + MonoType *t = ctx->method_inst->type_argv [0]; + switch (t->type) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_R4: + case MONO_TYPE_R8: + MONO_INST_NEW (cfg, ins, OP_NOP); + MONO_ADD_INS (cfg->cbb, ins); + return ins; + default: + break; + } + } #endif ins = mono_emit_native_types_intrinsics (cfg, cmethod, fsig, args); From 7c422d37e5b044ea7f9b450f547688be2b6e248e Mon Sep 17 00:00:00 2001 From: Elinor Fung <47805090+elinor-fung@users.noreply.github.com> Date: Mon, 27 Jul 2020 18:12:25 -0700 Subject: [PATCH 078/755] Fix releasing of file handle in binder tracing (#39974) --- src/coreclr/src/binder/bindertracing.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/binder/bindertracing.cpp b/src/coreclr/src/binder/bindertracing.cpp index 2e5c83d7b09b..be09ebced11e 100644 --- a/src/coreclr/src/binder/bindertracing.cpp +++ b/src/coreclr/src/binder/bindertracing.cpp @@ -216,14 +216,14 @@ namespace BinderTracing AssemblyBindOperation::~AssemblyBindOperation() { - if (!BinderTracing::IsEnabled() || ShouldIgnoreBind()) - return; - - // Make sure the bind request is populated. Tracing may have been enabled mid-bind. - if (!m_populatedBindRequest) - PopulateBindRequest(m_bindRequest); + if (BinderTracing::IsEnabled() && !ShouldIgnoreBind()) + { + // Make sure the bind request is populated. Tracing may have been enabled mid-bind. + if (!m_populatedBindRequest) + PopulateBindRequest(m_bindRequest); - FireAssemblyLoadStop(m_bindRequest, m_resultAssembly, m_cached); + FireAssemblyLoadStop(m_bindRequest, m_resultAssembly, m_cached); + } if (m_resultAssembly != nullptr) m_resultAssembly->Release(); From 2ad46cdeca74a2c3f451cfe31c19ee9ada0edd41 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 27 Jul 2020 22:00:48 -0400 Subject: [PATCH 079/755] [wasm] Use interp-only instead of interp-llvmonly as the default execution mode. (#39880) interp-llvmonly caused mono_llvm_only to be set, causing bad behavior like stack walks not working. Co-authored-by: vargaz --- src/mono/mono/mini/driver.c | 6 +----- src/mono/mono/mini/jit.h | 2 ++ src/mono/mono/mini/mini-runtime.h | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index 322a23cef651..aa72d2af850a 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -2006,10 +2006,6 @@ apply_root_domain_configuration_file_bindings (MonoDomain *domain, char *root_do static void mono_check_interp_supported (void) { -#ifdef DISABLE_INTERPRETER - g_error ("Mono IL interpreter support is missing\n"); -#endif - #ifdef MONO_CROSS_COMPILE g_error ("--interpreter on cross-compile runtimes not supported\n"); #endif @@ -2999,7 +2995,7 @@ mono_runtime_set_execution_mode_full (int mode, gboolean override) mono_llvm_only = TRUE; break; - case MONO_EE_MODE_INTERP: + case MONO_AOT_MODE_INTERP_ONLY: mono_check_interp_supported (); mono_use_interpreter = TRUE; diff --git a/src/mono/mono/mini/jit.h b/src/mono/mono/mini/jit.h index 011792c346b4..02639c95122d 100644 --- a/src/mono/mono/mini/jit.h +++ b/src/mono/mono/mini/jit.h @@ -65,6 +65,8 @@ typedef enum { MONO_AOT_MODE_INTERP_LLVMONLY, /* Use only llvm compiled code, fall back to the interpeter */ MONO_AOT_MODE_LLVMONLY_INTERP, + /* Same as --interp */ + MONO_AOT_MODE_INTERP_ONLY, /* Sentinel value used internally by the runtime. We use a large number to avoid clashing with some internal values. */ MONO_AOT_MODE_LAST = 1000, } MonoAotMode; diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 971d9a59c675..7061283543cc 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -411,11 +411,9 @@ extern MonoEEFeatures mono_ee_features; //XXX this enum *MUST extend MonoAotMode as they are consumed together. typedef enum { - /* Always execute with interp, will use JIT to produce trampolines */ - MONO_EE_MODE_INTERP = MONO_AOT_MODE_LAST, + MONO_EE_MODE_INTERP = MONO_AOT_MODE_INTERP_ONLY, } MonoEEMode; - static inline MonoMethod* jinfo_get_method (MonoJitInfo *ji) { From 56d45b13c092c8ed3642113fc1991aacd86d26ef Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 27 Jul 2020 21:58:32 -0700 Subject: [PATCH 080/755] Update safemath.h Fixes #39985 --- src/coreclr/src/inc/safemath.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/src/inc/safemath.h b/src/coreclr/src/inc/safemath.h index 84ea377c54b8..d93e4a57011e 100644 --- a/src/coreclr/src/inc/safemath.h +++ b/src/coreclr/src/inc/safemath.h @@ -154,8 +154,7 @@ inline bool DoubleFitsInIntType(double val) //----------------------------------------------------------------------------- // -// Liberally lifted from the Office example on MSDN and modified. -// http://msdn.microsoft.com/library/en-us/dncode/html/secure01142004.asp +// Liberally lifted from https://github.com/dcleblanc/SafeInt and modified. // // Modified to track an overflow bit instead of throwing exceptions. In most // cases the Visual C++ optimizer (Whidbey beta1 - v14.00.40607) is able to From 7e98079afbf860d04d95330d0f00ee235383e6b1 Mon Sep 17 00:00:00 2001 From: Alexis Christoforides Date: Tue, 28 Jul 2020 01:22:22 -0400 Subject: [PATCH 081/755] [mono] Use DefaultDllSearchPaths attribute for PInvokes (#38975) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [mono] Use DefaultDllSearchPaths attribute for PInvokes So far we have been ignoring the flags contained in the attribute. Attribute can be applied to a pinvoke method or an assembly. See https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.defaultdllimportsearchpathsattribute.-ctor?view=netcore-3.1#System_Runtime_InteropServices_DefaultDllImportSearchPathsAttribute__ctor_System_Runtime_InteropServices_DllImportSearchPath_ * Update src/mono/mono/metadata/native-library.c Co-authored-by: Aleksey Kliger (λgeek) * Minor fixes to comments and error handling * Additional fixes Co-authored-by: Aleksey Kliger (λgeek) Co-authored-by: Ryan Lucia --- src/mono/mono/metadata/custom-attrs.c | 2 +- src/mono/mono/metadata/native-library.c | 93 ++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 648f5a068d96..491ae63bfb8f 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -1203,7 +1203,7 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth /* * mono_reflection_create_custom_attr_data_args_noalloc: * - * Same as mono_reflection_create_custom_attr_data_args_noalloc but allocate no managed objects, return values + * Same as mono_reflection_create_custom_attr_data_args but allocate no managed objects, return values * using C arrays. Only usable for cattrs with primitive/type arguments. * TYPED_ARGS, NAMED_ARGS, and NAMED_ARG_INFO should be freed using g_free (). */ diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index b2d5712c813c..ff2c6cc8d647 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -11,13 +11,25 @@ #include "mono/utils/mono-logger-internals.h" #include "mono/utils/mono-path.h" #include "mono/metadata/native-library.h" +#include "mono/metadata/custom-attrs-internals.h" #ifdef ENABLE_NETCORE static int pinvoke_search_directories_count; static char **pinvoke_search_directories; -// In DllImportSearchPath enum, bit 0x2 represents AssemblyDirectory. It is not passed on and is instead handled by the runtime. -#define DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY 0x2 +// sync with src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DllImportSearchPath.cs +typedef enum +{ + DLLIMPORTSEARCHPATH_LEGACY_BEHAVIOR = 0x0, // when no other flags are present, search the application directory and then call LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH + DLLIMPORTSEARCHPATH_USE_DLL_DIRECTORY_FOR_DEPENDENCIES = 0x100, + DLLIMPORTSEARCHPATH_APPLICATION_DIRECTORY = 0x200, + DLLIMPORTSEARCHPATH_USER_DIRECTORIES = 0x400, + DLLIMPORTSEARCHPATH_SYSTEM32 = 0x800, + DLLIMPORTSEARCHPATH_SAFE_DIRECTORIES = 0x1000, + DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY = 0x2, // search the assembly directory first regardless of platform, not passed on to LoadLibraryEx +} DllImportSearchPath; +//static const int DLLIMPORTSEARCHPATH_LOADLIBRARY_FLAG_MASK = DLLIMPORTSEARCHPATH_USE_DLL_DIRECTORY_FOR_DEPENDENCIES | DLLIMPORTSEARCHPATH_APPLICATION_DIRECTORY | +// DLLIMPORTSEARCHPATH_USER_DIRECTORIES | DLLIMPORTSEARCHPATH_SYSTEM32 | DLLIMPORTSEARCHPATH_SAFE_DIRECTORIES; // This lock may be taken within an ALC lock, and should never be the other way around. static MonoCoopMutex native_library_module_lock; @@ -58,6 +70,7 @@ GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomai GENERATE_TRY_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomainUnloadedException") #ifdef ENABLE_NETCORE GENERATE_GET_CLASS_WITH_CACHE (native_library, "System.Runtime.InteropServices", "NativeLibrary"); +static GENERATE_TRY_GET_CLASS_WITH_CACHE (dllimportsearchpath_attribute, "System.Runtime.InteropServices", "DefaultDllImportSearchPathsAttribute"); #endif #ifndef DISABLE_DLLMAP @@ -504,7 +517,6 @@ static MonoDl * netcore_probe_for_module (MonoImage *image, const char *file_name, int flags) { MonoDl *module = NULL; - gboolean search_assembly_dir = flags & DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY; // Try without any path additions module = netcore_probe_for_module_variations (NULL, file_name); @@ -514,13 +526,15 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags) module = netcore_probe_for_module_variations (pinvoke_search_directories[i], file_name); // Check the assembly directory if the search flag is set and the image exists - if (search_assembly_dir && image != NULL && module == NULL) { + if (flags & DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY && image != NULL && module == NULL) { char *mdirname = g_path_get_dirname (image->filename); if (mdirname) module = netcore_probe_for_module_variations (mdirname, file_name); g_free (mdirname); } + // TODO: Pass remaining flags on to LoadLibraryEx on Windows where appropriate, see https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportsearchpath?view=netcore-3.1 + return module; } @@ -835,6 +849,50 @@ netcore_lookup_native_library (MonoAssemblyLoadContext *alc, MonoImage *image, c return module; } +static int +get_dllimportsearchpath_flags (MonoCustomAttrInfo *cinfo) +{ + ERROR_DECL (error); + MonoCustomAttrEntry *attr = NULL; + MonoClass *dllimportsearchpath = mono_class_try_get_dllimportsearchpath_attribute_class (); + int idx; + int flags; + + if (!dllimportsearchpath) + return -1; + if (!cinfo) + return -2; + + for (idx = 0; idx < cinfo->num_attrs; ++idx) { + MonoClass *ctor_class = cinfo->attrs [idx].ctor->klass; + if (ctor_class == dllimportsearchpath) { + attr = &cinfo->attrs [idx]; + break; + } + } + if (!attr) + return -3; + + gpointer *typed_args, *named_args; + CattrNamedArg *arginfo; + int num_named_args; + + mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, + &typed_args, &named_args, &num_named_args, &arginfo, error); + if (!is_ok (error)) { + mono_error_cleanup (error); + return -4; + } + + flags = *(gint32*)typed_args [0]; + g_free (typed_args [0]); + g_free (typed_args); + g_free (named_args); + g_free (arginfo); + + return flags; +} + #else // ENABLE_NETCORE static MonoDl * @@ -1174,6 +1232,8 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou MonoImage *image = m_class_get_image (method->klass); #ifdef ENABLE_NETCORE MonoAssemblyLoadContext *alc = mono_image_get_alc (image); + MonoCustomAttrInfo *cinfo; + int flags; #endif MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method; MonoTableInfo *tables = image->tables; @@ -1240,8 +1300,26 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou #ifndef HOST_WIN32 retry_with_libcoreclr: #endif - // FIXME: these flags are not getting passed correctly - module = netcore_lookup_native_library (alc, image, new_scope, 0); + { + ERROR_DECL (local_error); + cinfo = mono_custom_attrs_from_method_checked (method, local_error); + mono_error_cleanup (local_error); + } + flags = get_dllimportsearchpath_flags (cinfo); + if (cinfo && !cinfo->cached) + mono_custom_attrs_free (cinfo); + + if (flags < 0) { + ERROR_DECL (local_error); + cinfo = mono_custom_attrs_from_assembly_checked (m_class_get_image (method->klass)->assembly, TRUE, local_error); + mono_error_cleanup (local_error); + flags = get_dllimportsearchpath_flags (cinfo); + if (cinfo && !cinfo->cached) + mono_custom_attrs_free (cinfo); + } + if (flags < 0) + flags = 0; + module = netcore_lookup_native_library (alc, image, new_scope, flags); #else module = legacy_lookup_native_library (image, new_scope); #endif @@ -1496,7 +1574,7 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_LoadByName (MonoStringHan goto_if_nok (error, leave); // FIXME: implement search flag defaults properly - module = netcore_probe_for_module (image, lib_name, has_search_flag ? search_flag : 0x2); + module = netcore_probe_for_module (image, lib_name, has_search_flag ? search_flag : DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY); if (!module) mono_error_set_generic_error (error, "System", "DllNotFoundException", "%s", lib_name); goto_if_nok (error, leave); @@ -1601,4 +1679,3 @@ mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const g_free (buffer); } - From 2bfbb56fdc293f9ca44702782bd020805e4fa428 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Tue, 28 Jul 2020 01:13:10 -0700 Subject: [PATCH 082/755] Fix ILLink descriptors for Mono.CoreLib (#39898) --- .../src/ILLink/ILLink.Descriptors.xml | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) 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 244f9da5b3ac..31c5d3516b80 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 @@ -49,7 +49,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -276,9 +276,6 @@ - - - @@ -420,7 +417,7 @@ - + @@ -457,7 +454,7 @@ - + @@ -520,11 +517,6 @@ - - - - - @@ -577,12 +569,9 @@ - + - - - @@ -592,7 +581,7 @@ - + @@ -640,8 +629,6 @@ - - @@ -660,9 +647,7 @@ - - - + @@ -684,7 +669,7 @@ - + From c40de2b15937902347cdf2a8a5254bc55fe12918 Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Tue, 28 Jul 2020 11:05:19 +0200 Subject: [PATCH 083/755] Fix issue in sort_mark_list causing AVs in merge_mark_lists. This happens during gen 2 GCs where at least one GC thread sees no surviving objects. The bug causes merge_mark_lists to attempt the merge when in fact we are not using the mark lists at all during gen 2 GCs. Fix comment in sort_mark_list. --- src/coreclr/src/gc/gc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 6bf8e51a6bce..9cc20ad740e2 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -8347,6 +8347,8 @@ void gc_heap::sort_mark_list() { if (settings.condemned_generation >= max_generation) { + // fake a mark list overflow so merge_mark_lists knows to quit early + mark_list_index = mark_list_end + 1; return; } @@ -8397,7 +8399,7 @@ void gc_heap::sort_mark_list() high = max (high, heap_segment_allocated (hp->ephemeral_heap_segment)); } - // give up if this is not an ephemeral GC or the mark list size is unreasonably large + // give up if the mark list size is unreasonably large if (total_mark_list_size > (total_ephemeral_size / 256)) { mark_list_index = mark_list_end + 1; From 1d05f27bf92586e8b7e0d312194b83de6a35ba67 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 28 Jul 2020 11:21:41 +0200 Subject: [PATCH 084/755] [browser][http] Fix HttpClientHandler "Supports*" properties regressions (#39889) * [browser][http] Fix HttpClientHandler "Supports*" properties regressions * Also needs implementing on SocketsHttpHandler. On the SocketsHttpHandler we will default to `true` here. ``` internal bool SupportsAutomaticDecompression => true; internal bool SupportsProxy => true; internal bool SupportsRedirectConfiguration => true; ``` * Should be internal accessor --- .../Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs | 4 ++++ .../src/System/Net/Http/HttpClientHandler.cs | 6 +++--- .../Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs index eb577324faa1..4a6c5b26fbca 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs @@ -120,6 +120,10 @@ public SslClientAuthenticationOptions SslOptions set => throw new PlatformNotSupportedException(); } + public bool SupportsAutomaticDecompression => false; + public bool SupportsProxy => false; + public bool SupportsRedirectConfiguration => false; + private Dictionary? _properties; public IDictionary Properties => _properties ??= new Dictionary(); 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 996e42ca02c3..5540ba7f642c 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 @@ -48,9 +48,9 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - public virtual bool SupportsAutomaticDecompression => true; - public virtual bool SupportsProxy => true; - public virtual bool SupportsRedirectConfiguration => true; + public virtual bool SupportsAutomaticDecompression => _underlyingHandler.SupportsAutomaticDecompression; + public virtual bool SupportsProxy => _underlyingHandler.SupportsProxy; + public virtual bool SupportsRedirectConfiguration => _underlyingHandler.SupportsRedirectConfiguration; public bool UseCookies { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 294b0c1734b7..9b122a615916 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -273,6 +273,10 @@ public TimeSpan Expect100ContinueTimeout } } + internal bool SupportsAutomaticDecompression => true; + internal bool SupportsProxy => true; + internal bool SupportsRedirectConfiguration => true; + public IDictionary Properties => _settings._properties ?? (_settings._properties = new Dictionary()); From 43670d59e25a6f9b5e6aeb8d1fd7cff1abe6d947 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Tue, 28 Jul 2020 12:43:39 +0200 Subject: [PATCH 085/755] [retry only] Additional HTTP/2 connections created when active streams limit is reached (#39439) HTTP/2 standard commands clients to not open more than one HTTP/2 connection to the same server. At the same time, server has right to limit the maximum number of active streams per that HTTP/2 connection. These two directives combined impose limit on the number of requests concurrently send to the server. This limitation is justified in client to server scenarios, but become a bottleneck in server to server cases like gRPC. This PR introduces a new SocketsHttpHandler API enabling establishing additional HTTP/2 connections to the same server when the maximum stream limit is reached on the existing ones. **Note**. This algorithm version uses only retries to make request choose another connection when all stream slots are occupied. It does not implement stream credit management in `HttpConnectionPool` and therefore exhibit a sub-optimal request scheduling behavior in "request burst" and "infinite requests" scenarios. Fixes #35088 --- .../Net/Http/Http2LoopbackConnection.cs | 25 +- .../System/Net/Http/Http2LoopbackServer.cs | 29 +- .../System.Net.Http/ref/System.Net.Http.cs | 1 + .../BrowserHttpHandler/SocketsHttpHandler.cs | 6 + .../src/System/Net/Http/RequestRetryType.cs | 6 +- .../Http/SocketsHttpHandler/CreditManager.cs | 45 ++- .../SocketsHttpHandler/Http2Connection.cs | 15 +- .../SocketsHttpHandler/HttpConnectionPool.cs | 197 +++++++++--- .../HttpConnectionSettings.cs | 7 +- .../SocketsHttpHandler/SocketsHttpHandler.cs | 11 + .../FunctionalTests/SocketsHttpHandlerTest.cs | 294 ++++++++++++++++++ 11 files changed, 563 insertions(+), 73 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 3750a36d15be..3bc20976fdef 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -21,18 +21,25 @@ public class Http2LoopbackConnection : GenericLoopbackConnection private Stream _connectionStream; private TaskCompletionSource _ignoredSettingsAckPromise; private bool _ignoreWindowUpdates; - public static TimeSpan Timeout => Http2LoopbackServer.Timeout; + private readonly TimeSpan _timeout; private int _lastStreamId; private readonly byte[] _prefix; public string PrefixString => Encoding.UTF8.GetString(_prefix, 0, _prefix.Length); public bool IsInvalid => _connectionSocket == null; public Stream Stream => _connectionStream; + public Task SettingAckWaiter => _ignoredSettingsAckPromise?.Task; public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) + : this(socket, httpOptions, Http2LoopbackServer.Timeout) + { + } + + public Http2LoopbackConnection(Socket socket, Http2Options httpOptions, TimeSpan timeout) { _connectionSocket = socket; _connectionStream = new NetworkStream(_connectionSocket, true); + _timeout = timeout; if (httpOptions.UseSsl) { @@ -81,12 +88,12 @@ public async Task SendConnectionPrefaceAsync() await WriteFrameAsync(emptySettings).ConfigureAwait(false); // Receive and ACK the client settings frame. - Frame clientSettings = await ReadFrameAsync(Timeout).ConfigureAwait(false); + Frame clientSettings = await ReadFrameAsync(_timeout).ConfigureAwait(false); clientSettings.Flags = clientSettings.Flags | FrameFlags.Ack; await WriteFrameAsync(clientSettings).ConfigureAwait(false); // Receive the client ACK of the server settings frame. - clientSettings = await ReadFrameAsync(Timeout).ConfigureAwait(false); + clientSettings = await ReadFrameAsync(_timeout).ConfigureAwait(false); } public async Task WriteFrameAsync(Frame frame) @@ -225,7 +232,7 @@ public void IgnoreWindowUpdates() public async Task ReadRstStreamAsync(int streamId) { - Frame frame = await ReadFrameAsync(Timeout); + Frame frame = await ReadFrameAsync(_timeout); if (frame == null) { @@ -248,7 +255,7 @@ public async Task WaitForClientDisconnectAsync(bool ignoreUnexpectedFrames = fal { IgnoreWindowUpdates(); - Frame frame = await ReadFrameAsync(Timeout).ConfigureAwait(false); + Frame frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); if (frame != null) { if (!ignoreUnexpectedFrames) @@ -310,7 +317,7 @@ public async Task ReadRequestHeaderAsync() public async Task ReadRequestHeaderFrameAsync() { // Receive HEADERS frame for request. - Frame frame = await ReadFrameAsync(Timeout).ConfigureAwait(false); + Frame frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); if (frame == null) { throw new IOException("Failed to read Headers frame."); @@ -476,7 +483,7 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) do { - frame = await ReadFrameAsync(Timeout).ConfigureAwait(false); + frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); if (frame == null && expectEndOfStream) { break; @@ -516,7 +523,7 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) HttpRequestData requestData = new HttpRequestData(); // Receive HEADERS frame for request. - Frame frame = await ReadFrameAsync(Timeout).ConfigureAwait(false); + Frame frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); if (frame == null) { throw new IOException("Failed to read Headers frame."); @@ -567,7 +574,7 @@ public async Task PingPong() byte[] pingData = new byte[8] { 1, 2, 3, 4, 50, 60, 70, 80 }; PingFrame ping = new PingFrame(pingData, FrameFlags.None, 0); await WriteFrameAsync(ping).ConfigureAwait(false); - PingFrame pingAck = (PingFrame)await ReadFrameAsync(Timeout).ConfigureAwait(false); + PingFrame pingAck = (PingFrame)await ReadFrameAsync(_timeout).ConfigureAwait(false); if (pingAck == null || pingAck.Type != FrameType.Ping || !pingAck.AckFlag) { throw new Exception("Expected PING ACK"); diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index a3ff123657a6..8516140e517c 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -74,7 +74,12 @@ private void RemoveInvalidConnections() _connections.RemoveAll((c) => c.IsInvalid); } - public async Task AcceptConnectionAsync() + public Task AcceptConnectionAsync() + { + return AcceptConnectionAsync(null); + } + + public async Task AcceptConnectionAsync(TimeSpan? timeout) { RemoveInvalidConnections(); @@ -85,7 +90,7 @@ public async Task AcceptConnectionAsync() Socket connectionSocket = await _listenSocket.AcceptAsync().ConfigureAwait(false); - Http2LoopbackConnection connection = new Http2LoopbackConnection(connectionSocket, _options); + Http2LoopbackConnection connection = timeout != null ? new Http2LoopbackConnection(connectionSocket, _options, timeout.Value) : new Http2LoopbackConnection(connectionSocket, _options); _connections.Add(connection); return connection; @@ -96,15 +101,25 @@ public override async Task EstablishGenericConnection return await EstablishConnectionAsync(); } - public async Task EstablishConnectionAsync(params SettingsEntry[] settingsEntries) + public Task EstablishConnectionAsync(params SettingsEntry[] settingsEntries) { - (Http2LoopbackConnection connection, _) = await EstablishConnectionGetSettingsAsync(settingsEntries).ConfigureAwait(false); + return EstablishConnectionAsync(null, null, settingsEntries); + } + + public async Task EstablishConnectionAsync(TimeSpan? timeout, TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) + { + (Http2LoopbackConnection connection, _) = await EstablishConnectionGetSettingsAsync(timeout, ackTimeout, settingsEntries).ConfigureAwait(false); return connection; } - public async Task<(Http2LoopbackConnection, SettingsFrame)> EstablishConnectionGetSettingsAsync(params SettingsEntry[] settingsEntries) + public Task<(Http2LoopbackConnection, SettingsFrame)> EstablishConnectionGetSettingsAsync(params SettingsEntry[] settingsEntries) + { + return EstablishConnectionGetSettingsAsync(null, null, settingsEntries); + } + + public async Task<(Http2LoopbackConnection, SettingsFrame)> EstablishConnectionGetSettingsAsync(TimeSpan? timeout, TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) { - Http2LoopbackConnection connection = await AcceptConnectionAsync().ConfigureAwait(false); + Http2LoopbackConnection connection = await AcceptConnectionAsync(timeout).ConfigureAwait(false); // Receive the initial client settings frame. Frame receivedFrame = await connection.ReadFrameAsync(Timeout).ConfigureAwait(false); @@ -129,7 +144,7 @@ public async Task EstablishConnectionAsync(params Setti await connection.WriteFrameAsync(settingsAck).ConfigureAwait(false); // The client will send us a SETTINGS ACK eventually, but not necessarily right away. - await connection.ExpectSettingsAckAsync(); + await connection.ExpectSettingsAckAsync((int) (ackTimeout?.TotalMilliseconds ?? 5000)); return (connection, clientSettingsFrame); } diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index dc1e77f19d7f..3386d321c045 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -310,6 +310,7 @@ public SocketsHttpHandler() { } protected override void Dispose(bool disposing) { } protected internal override System.Net.Http.HttpResponseMessage Send(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } + public bool EnableMultipleHttp2Connections { get { throw null; } set { } } } public partial class StreamContent : System.Net.Http.HttpContent { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs index 6f474758b897..4644b8b6a195 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs @@ -131,5 +131,11 @@ public TimeSpan Expect100ContinueTimeout protected internal override Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) => throw new PlatformNotSupportedException(); + + public bool EnableMultipleHttp2Connections + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/RequestRetryType.cs b/src/libraries/System.Net.Http/src/System/Net/Http/RequestRetryType.cs index 4456e4fa6405..f2e29c4726d5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/RequestRetryType.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/RequestRetryType.cs @@ -26,6 +26,10 @@ internal enum RequestRetryType /// /// The proxy failed, so the request should be retried on the next proxy. /// - RetryOnNextProxy + RetryOnNextProxy, + + /// The HTTP/2 connection reached the maximum number of streams and + /// another HTTP/2 connection must be created or found to serve the request. + RetryOnNextConnection } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs index 0439b51c85b7..f6d37aef6238 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs @@ -28,6 +28,8 @@ public CreditManager(IHttpTrace owner, string name, int initialCredit) _current = initialCredit; } + public bool IsCreditAvailable => Volatile.Read(ref _current) > 0; + private object SyncObject { // Generally locking on "this" is considered poor form, but this type is internal, @@ -35,23 +37,23 @@ private object SyncObject get => this; } - public ValueTask RequestCreditAsync(int amount, CancellationToken cancellationToken) + public bool TryRequestCreditNoWait(int amount) { lock (SyncObject) { - if (_disposed) - { - throw new ObjectDisposedException($"{nameof(CreditManager)}:{_owner.GetType().Name}:{_name}"); - } + return TryRequestCreditNoLock(amount) > 0; + } + } + public ValueTask RequestCreditAsync(int amount, CancellationToken cancellationToken) + { + lock (SyncObject) + { // If we can satisfy the request with credit already available, do so synchronously. - if (_current > 0) - { - Debug.Assert(_waitersTail is null, "Shouldn't have waiters when credit is available"); + int granted = TryRequestCreditNoLock(amount); - int granted = Math.Min(amount, _current); - if (NetEventSource.Log.IsEnabled()) _owner.Trace($"{_name}. requested={amount}, current={_current}, granted={granted}"); - _current -= granted; + if (granted > 0) + { return new ValueTask(granted); } @@ -155,5 +157,26 @@ public void Dispose() } } } + + private int TryRequestCreditNoLock(int amount) + { + Debug.Assert(Monitor.IsEntered(SyncObject), "Shouldn't be called outside lock."); + + if (_disposed) + { + throw new ObjectDisposedException($"{nameof(CreditManager)}:{_owner.GetType().Name}:{_name}"); + } + + if (_current > 0) + { + Debug.Assert(_waitersTail is null, "Shouldn't have waiters when credit is available"); + + int granted = Math.Min(amount, _current); + if (NetEventSource.Log.IsEnabled()) _owner.Trace($"{_name}. requested={amount}, current={_current}, granted={granted}"); + _current -= granted; + return granted; + } + return 0; + } } } 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 5432df730991..83f7953b86b9 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 @@ -114,12 +114,15 @@ public Http2Connection(HttpConnectionPool pool, Stream stream) _initialWindowSize = DefaultInitialWindowSize; _maxConcurrentStreams = int.MaxValue; _pendingWindowUpdate = 0; + _idleSinceTickCount = Environment.TickCount64; if (NetEventSource.Log.IsEnabled()) TraceConnection(stream); } private object SyncObject => _httpStreams; + public bool CanAddNewStream => _concurrentStreams.IsCreditAvailable; + public async ValueTask SetupAsync() { _outgoingBuffer.EnsureAvailableSpace(s_http2ConnectionPreface.Length + @@ -1203,7 +1206,17 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request // in order to avoid consuming resources in potentially many requests waiting for access. try { - await _concurrentStreams.RequestCreditAsync(1, cancellationToken).ConfigureAwait(false); + if (_pool.EnableMultipleHttp2Connections) + { + if (!_concurrentStreams.TryRequestCreditNoWait(1)) + { + throw new HttpRequestException(null, null, RequestRetryType.RetryOnNextConnection); + } + } + else + { + await _concurrentStreams.RequestCreditAsync(1, cancellationToken).ConfigureAwait(false); + } } catch (ObjectDisposedException) { 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 a363430d1bf4..072c9c24fd1f 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 @@ -66,7 +66,8 @@ internal sealed class HttpConnectionPool : IDisposable private readonly int _maxConnections; private bool _http2Enabled; - private Http2Connection? _http2Connection; + // This array must be treated as immutable. It can only be replaced with a new value in AddHttp2Connection method. + private volatile Http2Connection[]? _http2Connections; private SemaphoreSlim? _http2ConnectionCreateLock; private byte[]? _http2AltSvcOriginUri; internal readonly byte[]? _http2EncodedAuthorityHostHeader; @@ -329,6 +330,8 @@ public byte[] Http2AltSvcOriginUri } } + public bool EnableMultipleHttp2Connections => _poolManager.Settings.EnableMultipleHttp2Connections; + /// Object used to synchronize access to state in the pool. private object SyncObj => _idleConnections; @@ -483,24 +486,14 @@ public byte[] Http2AltSvcOriginUri Debug.Assert(_kind == HttpConnectionKind.Https || _kind == HttpConnectionKind.SslProxyTunnel || _kind == HttpConnectionKind.Http); // See if we have an HTTP2 connection - Http2Connection? http2Connection = _http2Connection; + Http2Connection? http2Connection = GetExistingHttp2Connection(); if (http2Connection != null) { - TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; - if (http2Connection.LifetimeExpired(Environment.TickCount64, pooledConnectionLifetime)) - { - // Connection expired. - http2Connection.Dispose(); - InvalidateHttp2Connection(http2Connection); - } - else - { - // Connection exist and it is still good to use. - if (NetEventSource.Log.IsEnabled()) Trace("Using existing HTTP2 connection."); - _usedSinceLastCleanup = true; - return (http2Connection, false, null); - } + // Connection exists and it is still good to use. + if (NetEventSource.Log.IsEnabled()) Trace("Using existing HTTP2 connection."); + _usedSinceLastCleanup = true; + return (http2Connection, false, null); } // Ensure that the connection creation semaphore is created @@ -524,16 +517,10 @@ public byte[] Http2AltSvcOriginUri await _http2ConnectionCreateLock.WaitAsync(cancellationToken).ConfigureAwait(false); try { - if (_http2Connection != null) + http2Connection = GetExistingHttp2Connection(); + if (http2Connection != null) { - // Someone beat us to it - - if (NetEventSource.Log.IsEnabled()) - { - Trace("Using existing HTTP2 connection."); - } - - return (_http2Connection, false, null); + return (http2Connection, false, null); } // Recheck if HTTP2 has been disabled by a previous attempt. @@ -558,15 +545,14 @@ public byte[] Http2AltSvcOriginUri http2Connection = new Http2Connection(this, stream!); await http2Connection.SetupAsync().ConfigureAwait(false); - Debug.Assert(_http2Connection == null); - _http2Connection = http2Connection; + AddHttp2Connection(http2Connection); if (NetEventSource.Log.IsEnabled()) { Trace("New unencrypted HTTP2 connection established."); } - return (_http2Connection, true, null); + return (http2Connection, true, null); } sslStream = (SslStream)stream!; @@ -582,15 +568,14 @@ public byte[] Http2AltSvcOriginUri http2Connection = new Http2Connection(this, sslStream); await http2Connection.SetupAsync().ConfigureAwait(false); - Debug.Assert(_http2Connection == null); - _http2Connection = http2Connection; + AddHttp2Connection(http2Connection); if (NetEventSource.Log.IsEnabled()) { Trace("New HTTP2 connection established."); } - return (_http2Connection, true, null); + return (http2Connection, true, null); } } } @@ -648,6 +633,53 @@ public byte[] Http2AltSvcOriginUri return await GetHttpConnectionAsync(request, async, cancellationToken).ConfigureAwait(false); } + private Http2Connection? GetExistingHttp2Connection() + { + Http2Connection[]? localConnections = _http2Connections; + + if (localConnections == null) + { + return null; + } + + for (int i = 0; i < localConnections.Length; i++) + { + Http2Connection http2Connection = localConnections[i]; + + TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; + if (http2Connection.LifetimeExpired(Environment.TickCount64, pooledConnectionLifetime)) + { + // Connection expired. + http2Connection.Dispose(); + InvalidateHttp2Connection(http2Connection); + } + else if (!EnableMultipleHttp2Connections || http2Connection.CanAddNewStream) + { + return http2Connection; + } + } + + return null; + } + + private void AddHttp2Connection(Http2Connection newConnection) + { + lock (SyncObj) + { + Http2Connection[]? localHttp2Connections = _http2Connections; + int newCollectionSize = localHttp2Connections == null ? 1 : localHttp2Connections.Length + 1; + Http2Connection[] newHttp2Connections = new Http2Connection[newCollectionSize]; + newHttp2Connections[0] = newConnection; + + if (localHttp2Connections != null) + { + Array.Copy(localHttp2Connections, 0, newHttp2Connections, 1, localHttp2Connections.Length); + } + + _http2Connections = newHttp2Connections; + } + } + private async ValueTask<(HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse)> GetHttp3ConnectionAsync(HttpRequestMessage request, HttpAuthority authority, CancellationToken cancellationToken) { @@ -794,6 +826,16 @@ public async ValueTask SendWithRetryAsync(HttpRequestMessag // Eat exception and try again. continue; } + catch (HttpRequestException e) when (e.AllowRetry == RequestRetryType.RetryOnNextConnection) + { + if (NetEventSource.Log.IsEnabled()) + { + Trace($"Retrying request on another HTTP/2 connection after active streams limit is reached on existing one: {e}"); + } + + // Eat exception and try again. + continue; + } // Check for the Alt-Svc header, to upgrade to HTTP/3. if (_altSvcEnabled && response.Headers.TryGetValues(KnownHeaders.AltSvc.Descriptor, out IEnumerable? altSvcHeaderValues)) @@ -1355,9 +1397,39 @@ public void InvalidateHttp2Connection(Http2Connection connection) { lock (SyncObj) { - if (_http2Connection == connection) + Http2Connection[]? localHttp2Connections = _http2Connections; + + if (localHttp2Connections == null) + { + return; + } + + if (localHttp2Connections.Length == 1) + { + // Fast shortcut for the most common case. + if (localHttp2Connections[0] == connection) + { + _http2Connections = null; + } + return; + } + + int invalidatedIndex = Array.IndexOf(localHttp2Connections, connection); + if (invalidatedIndex >= 0) { - _http2Connection = null; + Http2Connection[] newHttp2Connections = new Http2Connection[localHttp2Connections.Length - 1]; + + if (invalidatedIndex > 0) + { + Array.Copy(localHttp2Connections, newHttp2Connections, invalidatedIndex); + } + + if (invalidatedIndex < localHttp2Connections.Length - 1) + { + Array.Copy(localHttp2Connections, invalidatedIndex + 1, newHttp2Connections, invalidatedIndex, newHttp2Connections.Length - invalidatedIndex); + } + + _http2Connections = newHttp2Connections; } } } @@ -1389,10 +1461,13 @@ public void Dispose() list.ForEach(c => c._connection.Dispose()); list.Clear(); - if (_http2Connection != null) + if (_http2Connections != null) { - _http2Connection.Dispose(); - _http2Connection = null; + for (int i = 0; i < _http2Connections.Length; i++) + { + _http2Connections[i].Dispose(); + } + _http2Connections = null; } if (_authorityExpireTimer != null) @@ -1436,15 +1511,51 @@ public bool CleanCacheAndDisposeIfUnused() // Get the current time. This is compared against each connection's last returned // time to determine whether a connection is too old and should be closed. long nowTicks = Environment.TickCount64; - Http2Connection? http2Connection = _http2Connection; + // Copy the reference to a local variable to simplify the removal logic below. + Http2Connection[]? localHttp2Connections = _http2Connections; - if (http2Connection != null) + if (localHttp2Connections != null) { - if (http2Connection.IsExpired(nowTicks, pooledConnectionLifetime, pooledConnectionIdleTimeout)) + Http2Connection[]? newHttp2Connections = null; + int newIndex = 0; + for (int i = 0; i < localHttp2Connections.Length; i++) + { + Http2Connection http2Connection = localHttp2Connections[i]; + if (http2Connection.IsExpired(nowTicks, pooledConnectionLifetime, pooledConnectionIdleTimeout)) + { + http2Connection.Dispose(); + + if (newHttp2Connections == null) + { + newHttp2Connections = new Http2Connection[localHttp2Connections.Length]; + if (i > 0) + { + // Copy valid connections residing at the beggining of the current collection. + Array.Copy(localHttp2Connections, newHttp2Connections, i); + newIndex = i; + } + } + } + else if (newHttp2Connections != null) + { + newHttp2Connections[newIndex] = localHttp2Connections[i]; + newIndex++; + } + } + + if (newHttp2Connections != null) { - http2Connection.Dispose(); - // We can set _http2Connection directly while holding lock instead of calling InvalidateHttp2Connection(). - _http2Connection = null; + //Some connections have been removed, so _http2Connections must be replaced. + if (newIndex > 0) + { + Array.Resize(ref newHttp2Connections, newIndex); + _http2Connections = newHttp2Connections; + } + else + { + // All connections expired. + _http2Connections = null; + } } } @@ -1493,7 +1604,7 @@ public bool CleanCacheAndDisposeIfUnused() // if a pool was used since the last time we cleaned up, give it another chance. New pools // start out saying they've recently been used, to give them a bit of breathing room and time // for the initial collection to be added to it. - if (_associatedConnectionCount == 0 && !_usedSinceLastCleanup && _http2Connection == null) + if (_associatedConnectionCount == 0 && !_usedSinceLastCleanup && _http2Connections == null) { Debug.Assert(list.Count == 0, $"Expected {nameof(list)}.{nameof(list.Count)} == 0"); _disposed = true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 959f82ba83f4..4ba769673e75 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -52,6 +52,8 @@ internal sealed class HttpConnectionSettings internal SslClientAuthenticationOptions? _sslOptions; + internal bool _enableMultipleHttp2Connections; + internal IDictionary? _properties; public HttpConnectionSettings() @@ -101,7 +103,8 @@ public HttpConnectionSettings CloneAndNormalize() _useCookies = _useCookies, _useProxy = _useProxy, _allowUnencryptedHttp2 = _allowUnencryptedHttp2, - _assumePrenegotiatedHttp3ForTesting = _assumePrenegotiatedHttp3ForTesting + _assumePrenegotiatedHttp3ForTesting = _assumePrenegotiatedHttp3ForTesting, + _enableMultipleHttp2Connections = _enableMultipleHttp2Connections }; } @@ -183,6 +186,8 @@ private static bool AllowDraftHttp3 } } + public bool EnableMultipleHttp2Connections => _enableMultipleHttp2Connections; + private byte[]? _http3SettingsFrame; internal byte[] Http3SettingsFrame => _http3SettingsFrame ??= Http3Connection.BuildSettingsFrame(this); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 9b122a615916..1874723a9773 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -273,6 +273,17 @@ public TimeSpan Expect100ContinueTimeout } } + public bool EnableMultipleHttp2Connections + { + get => _settings._enableMultipleHttp2Connections; + set + { + CheckDisposedOrStarted(); + + _settings._enableMultipleHttp2Connections = value; + } + } + internal bool SupportsAutomaticDecompression => true; internal bool SupportsProxy => true; internal bool SupportsRedirectConfiguration => true; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index ae32a02a0ef3..3a4aef661e41 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1925,6 +1925,300 @@ private static byte[] PreperateResponseWithRedirect(byte[] location) public sealed class SocketsHttpHandlerTest_Http2 : HttpClientHandlerTest_Http2 { public SocketsHttpHandlerTest_Http2(ITestOutputHelper output) : base(output) { } + + [ConditionalFact(nameof(SupportsAlpn))] + public async Task Http2_MultipleConnectionsEnabled_ConnectionLimitNotReached_ConcurrentRequestsSuccessfullyHandled() + { + const int MaxConcurrentStreams = 2; + using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + using SocketsHttpHandler handler = CreateHandler(); + using (HttpClient client = CreateHttpClient(handler)) + { + server.AllowMultipleConnections = true; + List> sendTasks = new List>(); + List connections = new List(); + List acceptedStreams = new List(); + for (int i = 0; i < 3; i++) + { + Http2LoopbackConnection connection = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + connections.Add(connection); + int prevAcceptedStreamCount = acceptedStreams.Count; + acceptedStreams.AddRange(await AcceptRequests(connection, MaxConcurrentStreams).ConfigureAwait(false)); + Assert.Equal(prevAcceptedStreamCount + MaxConcurrentStreams, acceptedStreams.Count); + } + + int responseIndex = 0; + List responseTasks = new List(); + foreach (Http2LoopbackConnection connection in connections) + { + for (int i = 0; i < MaxConcurrentStreams; i++) + { + int streamId = acceptedStreams[responseIndex++]; + responseTasks.Add(connection.SendDefaultResponseAsync(streamId)); + } + } + + await Task.WhenAll(responseTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + await VerifySendTasks(sendTasks).ConfigureAwait(false); + } + } + + [ConditionalFact(nameof(SupportsAlpn))] + public async Task Http2_MultipleConnectionsEnabled_InfiniteRequestsCompletelyBlockOneConnection_RemaningRequestsAreHandledByNewConnection() + { + const int MaxConcurrentStreams = 2; + using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + using SocketsHttpHandler handler = CreateHandler(); + using (HttpClient client = CreateHttpClient(handler)) + { + server.AllowMultipleConnections = true; + List> sendTasks = new List>(); + Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + // Block the first connection on infinite requests. + List blockedStreamIds = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); + Assert.Equal(MaxConcurrentStreams, blockedStreamIds.Count); + + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + int handledRequestCount = (await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)).Count; + + Assert.Equal(MaxConcurrentStreams, handledRequestCount); + + //Complete inifinite requests. + handledRequestCount = await SendResponses(connection0, blockedStreamIds); + + Assert.Equal(MaxConcurrentStreams, handledRequestCount); + + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + await VerifySendTasks(sendTasks).ConfigureAwait(false); + } + } + + [ConditionalFact(nameof(SupportsAlpn))] + public async Task Http2_MultipleConnectionsEnabled_OpenAndCloseMultipleConnections_Success() + { + const int MaxConcurrentStreams = 2; + using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + using SocketsHttpHandler handler = CreateHandler(); + using (HttpClient client = CreateHttpClient(handler)) + { + server.AllowMultipleConnections = true; + List> sendTasks = new List>(); + Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + Task<(int Count, int LastStreamId)>[] handleRequestTasks = new[] { + HandleAllPendingRequests(connection0, sendTasks.Count), + HandleAllPendingRequests(connection1, sendTasks.Count), + HandleAllPendingRequests(connection2, sendTasks.Count) + }; + + await Task.WhenAll(handleRequestTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + Assert.Equal(handleRequestTasks[0].Result.Count, MaxConcurrentStreams); + Assert.Equal(handleRequestTasks[1].Result.Count, MaxConcurrentStreams); + Assert.Equal(handleRequestTasks[2].Result.Count, MaxConcurrentStreams); + + await connection0.ShutdownIgnoringErrorsAsync(handleRequestTasks[0].Result.LastStreamId).ConfigureAwait(false); + await connection2.ShutdownIgnoringErrorsAsync(handleRequestTasks[2].Result.LastStreamId).ConfigureAwait(false); + + //Fill all connection1's stream slots + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + Http2LoopbackConnection connection3 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + Http2LoopbackConnection connection4 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + Task<(int Count, int LastStreamId)>[] finalHandleTasks = new[] { + HandleAllPendingRequests(connection1, sendTasks.Count), + HandleAllPendingRequests(connection3, sendTasks.Count), + HandleAllPendingRequests(connection4, sendTasks.Count) + }; + + await Task.WhenAll(finalHandleTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + Assert.Equal(finalHandleTasks[0].Result.Count, MaxConcurrentStreams); + Assert.Equal(finalHandleTasks[1].Result.Count, MaxConcurrentStreams); + Assert.Equal(finalHandleTasks[2].Result.Count, MaxConcurrentStreams); + + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + await VerifySendTasks(sendTasks).ConfigureAwait(false); + } + } + + [ConditionalFact(nameof(SupportsAlpn))] + public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ConnectionRemovedAndNewCreated() + { + const int MaxConcurrentStreams = 2; + using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + using SocketsHttpHandler handler = CreateHandler(); + handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(5); + using (HttpClient client = CreateHttpClient(handler)) + { + server.AllowMultipleConnections = true; + List> sendTasks = new List>(); + Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + List acceptedStreamIds = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); + Assert.Equal(MaxConcurrentStreams, acceptedStreamIds.Count); + + List> connection1SendTasks = new List>(); + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 10).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, connection1SendTasks, MaxConcurrentStreams); + int handledRequests1 = (await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)).Count; + + Assert.Equal(MaxConcurrentStreams, handledRequests1); + + // Complete all the requests. + await Task.WhenAll(connection1SendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + await VerifySendTasks(connection1SendTasks).ConfigureAwait(false); + connection1SendTasks.ForEach(t => t.Result.Dispose()); + + // Wait until the idle connection timeout expires. + await connection1.WaitForClientDisconnectAsync(false).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + // Client connection might be still alive, so send an extra request which will either land on the shutting down connection or on a new one. + try + { + await client.GetAsync(server.Address).TimeoutAfter(handler.PooledConnectionIdleTimeout).ConfigureAwait(false); + } + catch (Exception) + { + // Suppress all exceptions. + } + + Assert.True(connection1.IsInvalid); + Assert.False(connection0.IsInvalid); + + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 5, expectedWarpUpTasks:2).ConfigureAwait(false); + + AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + + int handledRequests2 = (await HandleAllPendingRequests(connection2, MaxConcurrentStreams).ConfigureAwait(false)).Count; + Assert.Equal(MaxConcurrentStreams, handledRequests2); + + //Make sure connection0 is still alive. + int handledRequests0 = await SendResponses(connection0, acceptedStreamIds).ConfigureAwait(false); + Assert.Equal(MaxConcurrentStreams, handledRequests0); + + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + await VerifySendTasks(sendTasks).ConfigureAwait(false); + } + } + + private async Task VerifySendTasks(IReadOnlyList> sendTasks) + { + foreach (Task sendTask in sendTasks) + { + HttpResponseMessage response = await sendTask.ConfigureAwait(false); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + } + + private static SocketsHttpHandler CreateHandler() => new SocketsHttpHandler + { + EnableMultipleHttp2Connections = true, + PooledConnectionIdleTimeout = TimeSpan.FromHours(1), + PooledConnectionLifetime = TimeSpan.FromHours(1), + SslOptions = { RemoteCertificateValidationCallback = delegate { return true; } } + }; + + private async Task PrepareConnection(Http2LoopbackServer server, HttpClient client, uint maxConcurrentStreams, int readTimeout = 3, int expectedWarpUpTasks = 1) + { + Task warmUpTask = client.GetAsync(server.Address); + Http2LoopbackConnection connection = await GetConnection(server, maxConcurrentStreams, readTimeout).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + // Wait until the client confirms MaxConcurrentStreams setting took into effect. + Task settingAckReceived = connection.SettingAckWaiter; + while (true) + { + Task handleRequestTask = HandleAllPendingRequests(connection, expectedWarpUpTasks); + await Task.WhenAll(warmUpTask, handleRequestTask).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.True(warmUpTask.Result.IsSuccessStatusCode); + warmUpTask.Result.Dispose(); + if (settingAckReceived.IsCompleted) + { + break; + } + + warmUpTask = client.GetAsync(server.Address); + } + return connection; + } + + private static void AcquireAllStreamSlots(Http2LoopbackServer server, HttpClient client, List> sendTasks, uint maxConcurrentStreams) + { + for (int i = 0; i < maxConcurrentStreams; i++) + { + sendTasks.Add(client.GetAsync(server.Address)); + } + } + + private static async Task GetConnection(Http2LoopbackServer server, uint maxConcurrentStreams, int readTimeout) => + await server.EstablishConnectionAsync(TimeSpan.FromSeconds(readTimeout), TimeSpan.FromSeconds(10), new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = maxConcurrentStreams }).ConfigureAwait(false); + + private async Task<(int Count, int LastStreamId)> HandleAllPendingRequests(Http2LoopbackConnection connection, int totalRequestCount) + { + int streamId = -1; + for (int i = 0; i < totalRequestCount; i++) + { + try + { + // Exact number of requests sent over the given connection is unknown, + // so we keep reading headers and sending response while there are available requests. + streamId = await connection.ReadRequestHeaderAsync().ConfigureAwait(false); + await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + return (i, streamId); + } + } + + return (totalRequestCount, streamId); + } + + private async Task> AcceptRequests(Http2LoopbackConnection connection, int maxRequests = int.MaxValue) + { + List streamIds = new List(); + for (int i = 0; i < maxRequests; i++) + { + try + { + streamIds.Add(await connection.ReadRequestHeaderAsync().ConfigureAwait(false)); + } + catch (OperationCanceledException) + { + return streamIds; + } + } + + return streamIds; + } + + private async Task SendResponses(Http2LoopbackConnection connection, IEnumerable streamIds) + { + int count = 0; + foreach (int streamId in streamIds) + { + count++; + await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); + } + + return count; + } } [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] From 18316b6d305b13e66ee2fe910e59ad6fe018aea4 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Tue, 28 Jul 2020 07:07:25 -0400 Subject: [PATCH 086/755] Add brew update before brew bundle (#39999) Every lane appears to be failing because of an issue with brew bundle expecting the latest homebrew but not automatically updating: https://github.com/Homebrew/homebrew-bundle/issues/751 So forcibly update, which is apparently good practice anyway: https://github.com/Homebrew/homebrew-bundle/issues/751#issuecomment-664958735 --- eng/install-native-dependencies.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/install-native-dependencies.sh b/eng/install-native-dependencies.sh index 00be5a628728..e8ab193c2d51 100755 --- a/eng/install-native-dependencies.sh +++ b/eng/install-native-dependencies.sh @@ -11,6 +11,7 @@ if [ "$1" = "Linux" ]; then fi elif [ "$1" = "OSX" ] || [ "$1" = "tvOS" ] || [ "$1" = "iOS" ]; then engdir=$(dirname "${BASH_SOURCE[0]}") + brew update --preinstall brew bundle --no-lock --file "${engdir}/Brewfile" if [ "$?" != "0" ]; then exit 1; From 675c402146cdeea927f5636f824799ec0b54e087 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Tue, 28 Jul 2020 04:19:58 -0700 Subject: [PATCH 087/755] Add ICorDebugModule4 - Get Module mapping mode (#39865) * Add IDL for ICorDebugModule4 * Add cached version of the MIDL generated stubs * Implement ICorDebugModule4 * Align method naming with other methods in ICorDebug --- src/coreclr/src/debug/daccess/dacdbiimpl.cpp | 24 ++++ src/coreclr/src/debug/daccess/dacdbiimpl.h | 2 + src/coreclr/src/debug/di/module.cpp | 22 +++ src/coreclr/src/debug/di/rspriv.h | 8 +- src/coreclr/src/debug/inc/dacdbiinterface.h | 3 + src/coreclr/src/inc/cordebug.idl | 24 ++++ .../src/pal/prebuilt/idl/cordebug_i.cpp | 5 +- src/coreclr/src/pal/prebuilt/inc/cordebug.h | 125 +++++++++++++++--- 8 files changed, 192 insertions(+), 21 deletions(-) diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp index 4bcd6f2ff4cb..aab49139e91b 100644 --- a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp @@ -4272,6 +4272,30 @@ void DacDbiInterfaceImpl::GetModuleSimpleName(VMPTR_Module vmModule, IStringHold IfFailThrow(pStrFilename->AssignCopy(convert.GetUnicode())); } +HRESULT DacDbiInterfaceImpl::IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped) +{ + LOG((LF_CORDB, LL_INFO10000, "DDBII::IMM - TADDR 0x%x\n", pModule)); + DD_ENTER_MAY_THROW; + + HRESULT hr = S_FALSE; + PTR_Module pTargetModule = pModule.GetDacPtr(); + + EX_TRY + { + PTR_PEFile pPEFile = pTargetModule->GetFile(); + _ASSERTE(pPEFile != NULL); + + if (pPEFile->HasLoadedIL()) + { + *isModuleMapped = pPEFile->GetLoadedIL()->IsMapped(); + hr = S_OK; + } + } + EX_CATCH_HRESULT(hr); + + return hr; +} + // Helper to intialize a TargetBuffer from a MemoryRange // // Arguments: diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.h b/src/coreclr/src/debug/daccess/dacdbiimpl.h index 9178e7173626..219b51dc77af 100644 --- a/src/coreclr/src/debug/daccess/dacdbiimpl.h +++ b/src/coreclr/src/debug/daccess/dacdbiimpl.h @@ -363,6 +363,8 @@ class DacDbiInterfaceImpl : HRESULT GetLoaderHeapMemoryRanges(OUT DacDbiArrayList * pRanges); + HRESULT IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped); + // retrieves the list of COM interfaces implemented by vmObject, as it is known at // the time of the call (the list may change as new interface types become available // in the runtime) diff --git a/src/coreclr/src/debug/di/module.cpp b/src/coreclr/src/debug/di/module.cpp index d02dfdd08146..9554f61dc860 100644 --- a/src/coreclr/src/debug/di/module.cpp +++ b/src/coreclr/src/debug/di/module.cpp @@ -1200,6 +1200,10 @@ HRESULT CordbModule::QueryInterface(REFIID id, void **pInterface) { *pInterface = static_cast(this); } + else if (id == IID_ICorDebugModule4) + { + *pInterface = static_cast(this); + } else if (id == IID_IUnknown) { *pInterface = static_cast(static_cast(this)); @@ -2752,6 +2756,24 @@ HRESULT CordbModule::GetJITCompilerFlags(DWORD *pdwFlags ) return hr; } +HRESULT CordbModule::IsMappedLayout(BOOL *isMapped) +{ + VALIDATE_POINTER_TO_OBJECT(isMapped, BOOL*); + FAIL_IF_NEUTERED(this); + + HRESULT hr = S_OK; + CordbProcess *pProcess = GetProcess(); + + ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess); + PUBLIC_API_BEGIN(pProcess); + { + hr = pProcess->GetDAC()->IsModuleMapped(m_vmModule, isMapped); + } + PUBLIC_API_END(hr); + + return hr; +} + /* ------------------------------------------------------------------------- * * CordbCode class * ------------------------------------------------------------------------- */ diff --git a/src/coreclr/src/debug/di/rspriv.h b/src/coreclr/src/debug/di/rspriv.h index 1bb48df2356c..4dc93ebf7317 100644 --- a/src/coreclr/src/debug/di/rspriv.h +++ b/src/coreclr/src/debug/di/rspriv.h @@ -4139,7 +4139,8 @@ class CordbProcess : class CordbModule : public CordbBase, public ICorDebugModule, public ICorDebugModule2, - public ICorDebugModule3 + public ICorDebugModule3, + public ICorDebugModule4 { public: CordbModule(CordbProcess * process, @@ -4234,6 +4235,11 @@ class CordbModule : public CordbBase, COM_METHOD CreateReaderForInMemorySymbols(REFIID riid, void** ppObj); + //----------------------------------------------------------- + // ICorDebugModule4 + //----------------------------------------------------------- + COM_METHOD IsMappedLayout(BOOL *isMapped); + //----------------------------------------------------------- // Internal members //----------------------------------------------------------- diff --git a/src/coreclr/src/debug/inc/dacdbiinterface.h b/src/coreclr/src/debug/inc/dacdbiinterface.h index 79405d60e3d8..1f99f5f29665 100644 --- a/src/coreclr/src/debug/inc/dacdbiinterface.h +++ b/src/coreclr/src/debug/inc/dacdbiinterface.h @@ -2733,6 +2733,9 @@ class IDacDbiInterface virtual HRESULT GetLoaderHeapMemoryRanges(OUT DacDbiArrayList *pRanges) = 0; + virtual + HRESULT IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped) = 0; + // The following tag tells the DD-marshalling tool to stop scanning. // END_MARSHAL diff --git a/src/coreclr/src/inc/cordebug.idl b/src/coreclr/src/inc/cordebug.idl index 7ab2867d9f28..02c98f25d8a1 100644 --- a/src/coreclr/src/inc/cordebug.idl +++ b/src/coreclr/src/inc/cordebug.idl @@ -5173,6 +5173,30 @@ interface ICorDebugModule3 : IUnknown [out][iid_is(riid)] void **ppObj); } +/* + * ICorDebugModule4 is a logical extension to ICorDebugModule. + */ +[ + object, + local, + uuid(FF8B8EAF-25CD-4316-8859-84416DE4402E), + pointer_default(unique) +] +interface ICorDebugModule4 : IUnknown +{ + /* + * Query to see if the module is loaded into memory in mapped/hydrated format + * + * Arguments: + * pIsMapped - BOOL to store mapping information. TRUE will represent mapped + format while FALSE represents flat format. + * Return Value: + * S_OK in successful case. + * Notes: + */ + HRESULT IsMappedLayout([out] BOOL *pIsMapped); +} + /* * ICorDebugRuntimeUnwindableFrame is a specialized interface of ICorDebugFrame for unmanaged methods * which requires special knowledge to unwind. They are not jitted code. When the debugger sees this type diff --git a/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp b/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp index 85d7ab575a51..5208843c10eb 100644 --- a/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp +++ b/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp @@ -8,7 +8,7 @@ /* File created by MIDL compiler version 8.01.0622 */ /* at Mon Jan 18 19:14:07 2038 */ -/* Compiler settings for E:/repos/runtime2/src/coreclr/src/inc/cordebug.idl: +/* Compiler settings for runtime/src/coreclr/src/inc/cordebug.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 @@ -289,6 +289,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame2,0x35389FF1,0x3684,0x4c55,0xA2,0x MIDL_DEFINE_GUID(IID, IID_ICorDebugModule3,0x86F012BF,0xFF15,0x4372,0xBD,0x30,0xB6,0xF1,0x1C,0xAA,0xE1,0xDD); +MIDL_DEFINE_GUID(IID, IID_ICorDebugModule4,0xFF8B8EAF,0x25CD,0x4316,0x88,0x59,0x84,0x41,0x6D,0xE4,0x40,0x2E); + + MIDL_DEFINE_GUID(IID, IID_ICorDebugRuntimeUnwindableFrame,0x879CAC0A,0x4A53,0x4668,0xB8,0xE3,0xCB,0x84,0x73,0xCB,0x18,0x7F); diff --git a/src/coreclr/src/pal/prebuilt/inc/cordebug.h b/src/coreclr/src/pal/prebuilt/inc/cordebug.h index 3418b8cf9b30..b497d141c480 100644 --- a/src/coreclr/src/pal/prebuilt/inc/cordebug.h +++ b/src/coreclr/src/pal/prebuilt/inc/cordebug.h @@ -6,7 +6,7 @@ /* File created by MIDL compiler version 8.01.0622 */ /* at Mon Jan 18 19:14:07 2038 */ -/* Compiler settings for E:/repos/runtime2/src/coreclr/src/inc/cordebug.idl: +/* Compiler settings for runtime/src/coreclr/src/inc/cordebug.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 @@ -563,6 +563,13 @@ typedef interface ICorDebugModule3 ICorDebugModule3; #endif /* __ICorDebugModule3_FWD_DEFINED__ */ +#ifndef __ICorDebugModule4_FWD_DEFINED__ +#define __ICorDebugModule4_FWD_DEFINED__ +typedef interface ICorDebugModule4 ICorDebugModule4; + +#endif /* __ICorDebugModule4_FWD_DEFINED__ */ + + #ifndef __ICorDebugRuntimeUnwindableFrame_FWD_DEFINED__ #define __ICorDebugRuntimeUnwindableFrame_FWD_DEFINED__ typedef interface ICorDebugRuntimeUnwindableFrame ICorDebugRuntimeUnwindableFrame; @@ -11691,6 +11698,86 @@ EXTERN_C const IID IID_ICorDebugModule3; #endif /* __ICorDebugModule3_INTERFACE_DEFINED__ */ +#ifndef __ICorDebugModule4_INTERFACE_DEFINED__ +#define __ICorDebugModule4_INTERFACE_DEFINED__ + +/* interface ICorDebugModule4 */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ICorDebugModule4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FF8B8EAF-25CD-4316-8859-84416DE4402E") + ICorDebugModule4 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE IsMappedLayout( + /* [out] */ BOOL *pIsMapped) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ICorDebugModule4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICorDebugModule4 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICorDebugModule4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ICorDebugModule4 * This); + + HRESULT ( STDMETHODCALLTYPE *IsMappedLayout )( + ICorDebugModule4 * This, + /* [out] */ BOOL *pIsMapped); + + END_INTERFACE + } ICorDebugModule4Vtbl; + + interface ICorDebugModule4 + { + CONST_VTBL struct ICorDebugModule4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICorDebugModule4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ICorDebugModule4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ICorDebugModule4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ICorDebugModule4_IsMappedLayout(This,pIsMapped) \ + ( (This)->lpVtbl -> IsMappedLayout(This,pIsMapped) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ICorDebugModule4_INTERFACE_DEFINED__ */ + + #ifndef __ICorDebugRuntimeUnwindableFrame_INTERFACE_DEFINED__ #define __ICorDebugRuntimeUnwindableFrame_INTERFACE_DEFINED__ @@ -12075,14 +12162,14 @@ EXTERN_C const IID IID_ICorDebugModule; #endif /* __ICorDebugModule_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0075 */ +/* interface __MIDL_itf_cordebug_0000_0076 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0075_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0075_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0076_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0076_v0_0_s_ifspec; #ifndef __ICorDebugModule2_INTERFACE_DEFINED__ #define __ICorDebugModule2_INTERFACE_DEFINED__ @@ -15129,15 +15216,15 @@ EXTERN_C const IID IID_ICorDebugBoxValue; #endif /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0102 */ +/* interface __MIDL_itf_cordebug_0000_0103 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0102_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0102_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_s_ifspec; #ifndef __ICorDebugStringValue_INTERFACE_DEFINED__ #define __ICorDebugStringValue_INTERFACE_DEFINED__ @@ -15277,14 +15364,14 @@ EXTERN_C const IID IID_ICorDebugStringValue; #endif /* __ICorDebugStringValue_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0103 */ +/* interface __MIDL_itf_cordebug_0000_0104 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0104_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0104_v0_0_s_ifspec; #ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__ #define __ICorDebugArrayValue_INTERFACE_DEFINED__ @@ -18059,15 +18146,15 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum; #endif /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0127 */ +/* interface __MIDL_itf_cordebug_0000_0128 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0127_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0127_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_s_ifspec; #ifndef __ICorDebugMDA_INTERFACE_DEFINED__ #define __ICorDebugMDA_INTERFACE_DEFINED__ @@ -18207,7 +18294,7 @@ EXTERN_C const IID IID_ICorDebugMDA; #endif /* __ICorDebugMDA_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0128 */ +/* interface __MIDL_itf_cordebug_0000_0129 */ /* [local] */ #pragma warning(pop) @@ -18215,8 +18302,8 @@ EXTERN_C const IID IID_ICorDebugMDA; #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_s_ifspec; #ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ #define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ @@ -18332,14 +18419,14 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo; #endif /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0129 */ +/* interface __MIDL_itf_cordebug_0000_0130 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0130_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0130_v0_0_s_ifspec; #ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__ #define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__ From d8d56b4564848a9f4bb33fbc6eb74b8feefc77d7 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Tue, 28 Jul 2020 08:34:29 -0400 Subject: [PATCH 088/755] Apple Silicon support (#39939) Co-authored-by: vargaz --- src/mono/configure.ac | 18 ++++++- src/mono/mono/arch/arm64/Makefile.am | 6 +++ src/mono/mono/arch/arm64/arm64-codegen.h | 36 +++++++++++++ src/mono/mono/arch/arm64/codegen-test.c | 13 +++++ src/mono/mono/eglib/eglib-remap.h | 3 ++ src/mono/mono/mini/aot-compiler.c | 3 ++ src/mono/mono/mini/exceptions-arm64.c | 22 ++++---- src/mono/mono/mini/helpers.c | 2 +- src/mono/mono/mini/llvm-jit.cpp | 2 +- src/mono/mono/mini/mini-arm64.c | 30 +++++++---- src/mono/mono/mini/mini-arm64.h | 5 +- src/mono/mono/mini/mini-llvm.c | 2 + src/mono/mono/mini/mini-runtime.c | 6 +++ src/mono/mono/mini/mini-runtime.h | 11 ++++ src/mono/mono/mini/mini.c | 11 ++++ src/mono/mono/mini/mini.h | 3 +- src/mono/mono/mini/trace.c | 2 +- src/mono/mono/mini/tramp-arm64-gsharedvt.c | 11 +++- src/mono/mono/mini/tramp-arm64.c | 61 ++++++++++++++-------- src/mono/mono/tests/Makefile.am | 4 +- src/mono/mono/utils/mono-codeman.c | 56 +++++++++++++++++++- src/mono/mono/utils/mono-codeman.h | 3 ++ 22 files changed, 256 insertions(+), 54 deletions(-) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 18f807f842b9..7a0d36d9ce57 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -449,6 +449,10 @@ case "$host" in platform_ios=yes has_dtrace=no ;; + aarch64*-darwin20*) + # OSX/arm64 + support_boehm=no + ;; aarch64*-darwin*) platform_ios=yes ;; @@ -1208,6 +1212,7 @@ if test "x$crash_reporting" != "xyes"; then CFLAGS="$CFLAGS -DDISABLE_CRASH_REPORTING=1" CXXFLAGS="$CXXFLAGS -DDISABLE_CRASH_REPORTING=1" fi +AM_CONDITIONAL(DISABLE_CRASH_REPORTING, test x$crash_reporting != xyes) AC_ARG_ENABLE(monodroid, [ --enable-monodroid Enable runtime support for Monodroid (Xamarin.Android)], enable_monodroid=$enableval, enable_monodroid=no) AM_CONDITIONAL(ENABLE_MONODROID, test x$enable_monodroid = xyes) @@ -2815,7 +2820,7 @@ if test x$host_win32 = xno; then AC_CHECK_HEADERS(pthread_np.h) AC_CHECK_FUNCS(pthread_mutex_timedlock) AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_get_np pthread_getname_np pthread_setname_np pthread_cond_timedwait_relative_np) - AC_CHECK_FUNCS(pthread_kill) + AC_CHECK_FUNCS(pthread_kill pthread_jit_write_protect_np) AC_MSG_CHECKING(for PTHREAD_MUTEX_RECURSIVE) AC_TRY_COMPILE([ #include ], [ pthread_mutexattr_t attr; @@ -4772,6 +4777,12 @@ if test "x$host" != "x$target"; then sizeof_register=8 AC_DEFINE(TARGET_WATCHOS, 1, [...]) ;; + aarch64*darwin*) + TARGET=ARM64 + # Both ios and osx/arm64 have the same aarc64-darwin triple, + # assume ios for now when cross compiling + TARGET_SYS=IOS + ;; aarch64-*) TARGET=ARM64 ;; @@ -4984,7 +4995,7 @@ if test "x$target_mach" = "xyes"; then CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_WATCHOS" CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_WATCHOS" BTLS_SUPPORTED=no - elif test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64" -o "x$TARGET" = "xARM6432"; then + elif test "x$TARGET_SYS" = "xIOS" -o "x$TARGET" = "xARM" -o "x$TARGET" = "xARM6432"; then AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS]) CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS" CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS" @@ -5000,6 +5011,9 @@ if test "x$target_mach" = "xyes"; then CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_OSX" CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_OSX" target_osx=yes + if test "x$TARGET" = "xARM64"; then + BTLS_SUPPORTED=no + fi ], [ AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS]) CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS" diff --git a/src/mono/mono/arch/arm64/Makefile.am b/src/mono/mono/arch/arm64/Makefile.am index bdc37622a640..e735d0ed69aa 100644 --- a/src/mono/mono/arch/arm64/Makefile.am +++ b/src/mono/mono/arch/arm64/Makefile.am @@ -1,3 +1,9 @@ MAKEFLAGS := $(MAKEFLAGS) --no-builtin-rules EXTRA_DIST = arm64-codegen.h codegen-test.c + +test-codegen: + $(CC) $(CFLAGS) -I../../.. -I../../eglib/ ../../eglib/.libs/libeglib.a -o codegen-test codegen-test.c + ./codegen-test > tmp.s + $(CC) $(CFLAGS) -c -o tmp.o tmp.s + objdump -d --triple=arm64e tmp.o diff --git a/src/mono/mono/arch/arm64/arm64-codegen.h b/src/mono/mono/arch/arm64/arm64-codegen.h index 239f4161fd92..d35fda11752f 100644 --- a/src/mono/mono/arch/arm64/arm64-codegen.h +++ b/src/mono/mono/arch/arm64/arm64-codegen.h @@ -867,4 +867,40 @@ arm_encode_arith_imm (int imm, guint32 *shift) #define arm_cmpp arm_cmpx #endif +/* ARM v8.3 */ + +/* PACIA */ + +#define arm_format_pacia(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5)) +#define arm_paciasp(p) arm_format_pacia ((p), 0b0011, 0b001) + +/* PACIB */ + +#define arm_format_pacib(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5)) +#define arm_pacibsp(p) arm_format_pacib ((p), 0b0011, 0b011) + +/* RETA */ +#define arm_format_reta(p,key) arm_emit ((p), 0b11010110010111110000101111111111 + ((key) << 10)) + +#define arm_retaa(p) arm_format_reta ((p),0) +#define arm_retab(p) arm_format_reta ((p),1) + +/* BRA */ + +#define arm_format_bra(p, z, m, rn, rm) arm_emit ((p), (0b1101011000011111000010 << 10) + ((z) << 24) + ((m) << 10) + ((rn) << 5) + ((rm) << 0)) + +#define arm_braaz(p, rn) arm_format_bra ((p), 0, 0, (rn), 0b11111) +#define arm_brabz(p, rn) arm_format_bra ((p), 0, 1, (rn), 0b11111) +#define arm_braa(p, rn, rm) arm_format_bra ((p), 1, 0, (rn), (rm)) +#define arm_brab(p, rn, rm) arm_format_bra ((p), 1, 1, (rn), (rm)) + +/* BLRA */ + +#define arm_format_blra(p, z, m, rn, rm) arm_emit ((p), (0b1101011000111111000010 << 10) + ((z) << 24) + ((m) << 10) + ((rn) << 5) + ((rm) << 0)) + +#define arm_blraaz(p, rn) arm_format_blra ((p), 0, 0, (rn), 0b11111) +#define arm_blraa(p, rn, rm) arm_format_blra ((p), 1, 0, (rn), (rm)) +#define arm_blrabz(p, rn) arm_format_blra ((p), 0, 1, (rn), 0b11111) +#define arm_blrab(p, rn, rm) arm_format_blra ((p), 1, 1, (rn), (rm)) + #endif /* __arm_CODEGEN_H__ */ diff --git a/src/mono/mono/arch/arm64/codegen-test.c b/src/mono/mono/arch/arm64/codegen-test.c index bb9d9dcdecd4..efb991e84273 100644 --- a/src/mono/mono/arch/arm64/codegen-test.c +++ b/src/mono/mono/arch/arm64/codegen-test.c @@ -416,6 +416,19 @@ main (int argc, char *argv []) arm_stlxrx (code, ARMREG_R0, ARMREG_R1, ARMREG_R2); arm_stlxrw (code, ARMREG_R0, ARMREG_R1, ARMREG_R2); + arm_paciasp (code); + arm_pacibsp (code); + arm_retaa (code); + arm_retab (code); + arm_braaz (code, ARMREG_R1); + arm_brabz (code, ARMREG_R1); + arm_braa (code, ARMREG_R1, ARMREG_R2); + arm_brab (code, ARMREG_R1, ARMREG_R2); + arm_blraaz (code, ARMREG_R1); + arm_blraa (code, ARMREG_R1, ARMREG_R2); + arm_blrabz (code, ARMREG_R1); + arm_blrab (code, ARMREG_R1, ARMREG_R2); + for (i = 0; i < code - buf; ++i) printf (".byte %d\n", buf [i]); printf ("\n"); diff --git a/src/mono/mono/eglib/eglib-remap.h b/src/mono/mono/eglib/eglib-remap.h index c5e27adae85d..c9751049c3b7 100644 --- a/src/mono/mono/eglib/eglib-remap.h +++ b/src/mono/mono/eglib/eglib-remap.h @@ -311,3 +311,6 @@ #define g_set_printerr_handler monoeg_set_printerr_handler #define g_size_to_int monoeg_size_to_int +#define g_ascii_charcmp monoeg_ascii_charcmp +#define g_ascii_charcasecmp monoeg_ascii_charcasecmp +#define g_warning_d monoeg_warning_d diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 7c76e4ce154b..5e8d1d3ab734 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -12296,6 +12296,9 @@ compile_asm (MonoAotCompile *acfg) #elif defined(TARGET_AMD64) && defined(TARGET_MACH) #define LD_NAME "clang" #define LD_OPTIONS "--shared" +#elif defined(TARGET_ARM64) && defined(TARGET_OSX) +#define LD_NAME "clang" +#define LD_OPTIONS "--shared" #elif defined(TARGET_WIN32_MSVC) #define LD_NAME "link.exe" #define LD_OPTIONS "/DLL /MACHINE:X64 /NOLOGO /INCREMENTAL:NO" diff --git a/src/mono/mono/mini/exceptions-arm64.c b/src/mono/mono/mini/exceptions-arm64.c index 11cb6ccdd9d3..3c06a2ac070d 100644 --- a/src/mono/mono/mini/exceptions-arm64.c +++ b/src/mono/mono/mini/exceptions-arm64.c @@ -36,6 +36,8 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) size = 256; code = start = mono_global_codeman_reserve (size); + MINI_BEGIN_CODEGEN (); + arm_movx (code, ARMREG_IP0, ARMREG_R0); ctx_reg = ARMREG_IP0; @@ -63,8 +65,8 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) arm_brk (code, 0); g_assert ((code - start) < size); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); + + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); if (info) *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops); @@ -106,6 +108,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) * returning the value returned by the call. */ + MINI_BEGIN_CODEGEN (); + /* Setup a frame */ arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size); arm_movspx (code, ARMREG_FP, ARMREG_SP); @@ -152,8 +156,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) arm_retx (code, ARMREG_LR); g_assert ((code - start) < size); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); + + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); if (info) *info = mono_tramp_info_create ("call_filter", start, code - start, ji, unwind_ops); @@ -186,6 +190,8 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm offset += num_fregs * 8; frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + MINI_BEGIN_CODEGEN (); + /* Setup a frame */ arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size); arm_movspx (code, ARMREG_FP, ARMREG_SP); @@ -254,8 +260,8 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm arm_brk (code, 0x0); g_assert ((code - start) < size); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); + + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); if (info) *info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops); @@ -329,9 +335,6 @@ mono_arch_exceptions_init (void) GSList *tramps, *l; if (mono_aot_only) { - - // FIXME Macroize. - tramp = mono_aot_get_trampoline ("llvm_throw_corlib_exception_trampoline"); mono_register_jit_icall_info (&mono_get_jit_icall_info ()->mono_llvm_throw_corlib_exception_trampoline, tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE, NULL); @@ -340,7 +343,6 @@ mono_arch_exceptions_init (void) tramp = mono_aot_get_trampoline ("llvm_resume_unwind_trampoline"); mono_register_jit_icall_info (&mono_get_jit_icall_info ()->mono_llvm_resume_unwind_trampoline, tramp, "llvm_resume_unwind_trampoline", NULL, TRUE, NULL); - } else { tramps = mono_arm_get_exception_trampolines (FALSE); for (l = tramps; l; l = l->next) { diff --git a/src/mono/mono/mini/helpers.c b/src/mono/mono/mini/helpers.c index 3ceffe6f1376..b62361ed532a 100644 --- a/src/mono/mono/mini/helpers.c +++ b/src/mono/mono/mini/helpers.c @@ -263,7 +263,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id) fflush (stdout); -#if defined(__arm__) || defined(__aarch64__) +#if (defined(__arm__) || defined(__aarch64__)) && !defined(TARGET_OSX) /* * The arm assembler inserts ELF directives instructing objdump to display * everything as data. diff --git a/src/mono/mono/mini/llvm-jit.cpp b/src/mono/mono/mini/llvm-jit.cpp index 1e896419f0b4..8307990a4e25 100644 --- a/src/mono/mono/mini/llvm-jit.cpp +++ b/src/mono/mono/mini/llvm-jit.cpp @@ -247,7 +247,7 @@ struct MonoLLVMJIT { void *sym = nullptr; auto err = mono_dl_symbol (current, name, &sym); if (!sym) { - outs () << "R: " << namestr << "\n"; + outs () << "R: " << namestr << " " << err << "\n"; } assert (sym); return JITSymbol{(uint64_t)(gssize)sym, flags}; diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 7907193b5e0f..30992b6cd881 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -114,6 +114,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co { guint8 *code, *start; + MINI_BEGIN_CODEGEN (); + if (has_target) { start = code = mono_global_codeman_reserve (12); @@ -123,9 +125,6 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co arm_brx (code, ARMREG_IP0); g_assert ((code - start) <= 12); - - mono_arch_flush_icache (start, 12); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL)); } else { int size, i; @@ -139,10 +138,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co arm_brx (code, ARMREG_IP0); g_assert ((code - start) <= size); - - mono_arch_flush_icache (start, size); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL)); } + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL); if (code_size) *code_size = code - start; @@ -255,7 +252,7 @@ mono_arch_init (void) mono_arm_gsharedvt_init (); -#if defined(TARGET_IOS) || defined(TARGET_WATCHOS) +#if defined(TARGET_IOS) || defined(TARGET_WATCHOS) || defined(TARGET_OSX) ios_abi = TRUE; #endif } @@ -1076,7 +1073,11 @@ add_general (CallInfo *cinfo, ArgInfo *ainfo, int size, gboolean sign) { if (cinfo->gr >= PARAM_REGS) { ainfo->storage = ArgOnStack; - if (ios_abi) { + /* + * FIXME: The vararg argument handling code in ves_icall_System_ArgIterator_IntGetNextArg + * assumes every argument is allocated to a separate full size stack slot. + */ + if (ios_abi && !cinfo->vararg) { /* Assume size == align */ } else { /* Put arguments into 8 byte aligned stack slots */ @@ -1344,6 +1345,10 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) cinfo->nargs = n; cinfo->pinvoke = sig->pinvoke; + // Constrain this to OSX only for now +#ifdef TARGET_OSX + cinfo->vararg = sig->call_convention == MONO_CALL_VARARG; +#endif /* Return value */ add_param (cinfo, &cinfo->ret, sig->ret); @@ -5350,6 +5355,8 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC buf = mono_domain_code_reserve (domain, buf_len); code = buf; + MINI_BEGIN_CODEGEN (); + /* * We are called by JITted code, which passes in the IMT argument in * MONO_ARCH_RGCTX_REG (r27). We need to preserve all caller saved regs @@ -5419,8 +5426,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC g_assert ((code - buf) <= buf_len); - mono_arch_flush_icache (buf, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL)); + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL); return buf; } @@ -5460,7 +5466,9 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) } else { /* ip points to an ldrx */ code += 4; + mono_codeman_enable_write (); arm_blrx (code, ARMREG_IP0); + mono_codeman_disable_write (); mono_arch_flush_icache (ip, code - ip); } } @@ -5479,7 +5487,9 @@ mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip) } else { /* ip points to an ldrx */ code += 4; + mono_codeman_enable_write (); arm_nop (code); + mono_codeman_disable_write (); mono_arch_flush_icache (ip, code - ip); } } diff --git a/src/mono/mono/mini/mini-arm64.h b/src/mono/mono/mini/mini-arm64.h index 41590fb0e87f..4074aa8b43f2 100644 --- a/src/mono/mono/mini/mini-arm64.h +++ b/src/mono/mono/mini/mini-arm64.h @@ -177,6 +177,9 @@ typedef struct { #define MONO_ARCH_FLOAT32_SUPPORTED 1 #define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n32:64-S128" +#ifdef TARGET_OSX +#define MONO_ARCH_FORCE_FLOAT32 1 +#endif // Does the ABI have a volatile non-parameter register, so tailcall // can pass context to generics or interfaces? @@ -250,7 +253,7 @@ typedef struct { struct CallInfo { int nargs; int gr, fr, stack_usage; - gboolean pinvoke; + gboolean pinvoke, vararg; ArgInfo ret; ArgInfo sig_cookie; ArgInfo args [1]; diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index c400e94f8164..4ac4e72eece2 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -11675,8 +11675,10 @@ llvm_jit_finalize_method (EmitContext *ctx) while (g_hash_table_iter_next (&iter, NULL, (void**)&var)) callee_vars [i ++] = var; + mono_codeman_enable_write (); cfg->native_code = (guint8*)mono_llvm_compile_method (ctx->module->mono_ee, cfg, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame); mono_llvm_remove_gc_safepoint_poll (ctx->lmodule); + mono_codeman_disable_write (); if (cfg->verbose_level > 1) { g_print ("\n*** Optimized LLVM IR for %s ***\n", mono_method_full_name (cfg->method, TRUE)); if (cfg->compile_aot) { diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 2176226b554b..82a8da22d6f7 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1460,9 +1460,11 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, } } + mono_codeman_enable_write (); for (i = 0; i < patch_info->data.table->table_size; i++) { jump_table [i] = code + GPOINTER_TO_INT (patch_info->data.table->table [i]); } + mono_codeman_disable_write (); target = jump_table; break; @@ -1754,6 +1756,8 @@ mini_patch_jump_sites (MonoDomain *domain, MonoMethod *method, gpointer addr) patch_info.type = MONO_PATCH_INFO_METHOD_JUMP; patch_info.data.method = method; + mono_codeman_enable_write (); + #ifdef MONO_ARCH_HAVE_PATCH_CODE_NEW for (tmp = jlist->list; tmp; tmp = tmp->next) mono_arch_patch_code_new (NULL, domain, (guint8 *)tmp->data, &patch_info, addr); @@ -1766,6 +1770,8 @@ mini_patch_jump_sites (MonoDomain *domain, MonoMethod *method, gpointer addr) mono_error_assert_ok (error); } #endif + + mono_codeman_disable_write (); } } diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 7061283543cc..9eea434e05e7 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -611,5 +611,16 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal); void mini_register_sigterm_handler (void); +#define MINI_BEGIN_CODEGEN() do { \ + mono_codeman_enable_write (); \ + } while (0) + +#define MINI_END_CODEGEN(buf,size,type,arg) do { \ + mono_codeman_disable_write (); \ + mono_arch_flush_icache ((buf), (size)); \ + if ((int)type != -1) \ + MONO_PROFILER_RAISE (jit_code_buffer, ((buf), (size), (type), (arg))); \ + } while (0) + #endif /* __MONO_MINI_RUNTIME_H__ */ diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 965771de378d..2a6ca7f4b16c 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -2248,6 +2248,8 @@ mono_codegen (MonoCompile *cfg) code = (guint8 *)mono_domain_code_reserve (code_domain, cfg->code_size + cfg->thunk_area + unwindlen); } + mono_codeman_enable_write (); + if (cfg->thunk_area) { cfg->thunks_offset = cfg->code_size + unwindlen; cfg->thunks = code + cfg->thunks_offset; @@ -2339,6 +2341,9 @@ mono_codegen (MonoCompile *cfg) } else { mono_domain_code_commit (code_domain, cfg->native_code, cfg->code_size, cfg->code_len); } + + mono_codeman_disable_write (); + MONO_PROFILER_RAISE (jit_code_buffer, (cfg->native_code, cfg->code_len, MONO_PROFILER_CODE_BUFFER_METHOD, cfg->method)); mono_arch_flush_icache (cfg->native_code, cfg->code_len); @@ -3044,6 +3049,9 @@ init_backend (MonoBackend *backend) #ifdef MONO_ARCH_HAVE_OPTIMIZED_DIV backend->optimized_div = 1; #endif +#ifdef MONO_ARCH_FORCE_FLOAT32 + backend->force_float32 = 1; +#endif } static gboolean @@ -3146,6 +3154,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl #ifndef MONO_ARCH_FLOAT32_SUPPORTED opts &= ~MONO_OPT_FLOAT32; #endif + if (current_backend->force_float32) + /* Force float32 mode on newer platforms */ + opts |= MONO_OPT_FLOAT32; restart_compile: if (method_is_gshared) { diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index e782440c7e18..58eb136d3181 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1193,7 +1193,7 @@ typedef struct { guint have_generalized_imt_trampoline : 1; gboolean have_op_tailcall_membase : 1; gboolean have_op_tailcall_reg : 1; - gboolean have_volatile_non_param_register : 1; + gboolean have_volatile_non_param_register : 1; guint gshared_supported : 1; guint use_fpstack : 1; guint ilp32 : 1; @@ -1203,6 +1203,7 @@ typedef struct { guint disable_div_with_mul : 1; guint explicit_null_checks : 1; guint optimized_div : 1; + guint force_float32 : 1; int monitor_enter_adjustment; int dyn_call_param_area; } MonoBackend; diff --git a/src/mono/mono/mini/trace.c b/src/mono/mono/mini/trace.c index 0e28cc773ee2..56e19a857512 100644 --- a/src/mono/mono/mini/trace.c +++ b/src/mono/mono/mini/trace.c @@ -31,7 +31,7 @@ #pragma warning(disable:4312) // FIXME pointer cast to different size #endif -#if defined (HOST_ANDROID) || (defined (TARGET_IOS) && defined (TARGET_IOS)) +#if defined (HOST_ANDROID) || defined (TARGET_IOS) # undef printf # define printf(...) g_log("mono", G_LOG_LEVEL_MESSAGE, __VA_ARGS__) # undef fprintf diff --git a/src/mono/mono/mini/tramp-arm64-gsharedvt.c b/src/mono/mono/mini/tramp-arm64-gsharedvt.c index c1038511d67f..269624c259da 100644 --- a/src/mono/mono/mini/tramp-arm64-gsharedvt.c +++ b/src/mono/mono/mini/tramp-arm64-gsharedvt.c @@ -13,6 +13,7 @@ #include "mini.h" #include "mini-arm64.h" #include "mini-arm64-gsharedvt.h" +#include "mini-runtime.h" /* * GSHAREDVT @@ -36,13 +37,16 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint */ buf = code = mono_global_codeman_reserve (buf_len); + MINI_BEGIN_CODEGEN (); + code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); arm_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); - mono_arch_flush_icache (buf, code - buf); + + MINI_END_CODEGEN (buf, code - buf, -1, NULL); return buf; } @@ -248,6 +252,8 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) cfa_offset = offset; + MINI_BEGIN_CODEGEN (); + /* Setup frame */ arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -cfa_offset); mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset); @@ -547,7 +553,8 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) if (info) *info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops); - mono_arch_flush_icache (buf, code - buf); + MINI_END_CODEGEN (buf, code - buf, -1, NULL); + return buf; } diff --git a/src/mono/mono/mini/tramp-arm64.c b/src/mono/mono/mini/tramp-arm64.c index 04eda906c469..7b889a3ffde4 100644 --- a/src/mono/mono/mini/tramp-arm64.c +++ b/src/mono/mono/mini/tramp-arm64.c @@ -30,8 +30,9 @@ void mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr) { + MINI_BEGIN_CODEGEN (); mono_arm_patch (code_ptr - 4, addr, MONO_R_ARM64_BL); - mono_arch_flush_icache (code_ptr - 4, 4); + MINI_END_CODEGEN (code_ptr - 4, 4, -1, NULL); } void @@ -133,6 +134,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf //offset += 22 * 8; frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + MINI_BEGIN_CODEGEN (); + /* Setup stack frame */ imm = frame_size; mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0); @@ -303,8 +306,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf arm_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); - mono_arch_flush_icache (buf, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL)); + + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); if (info) { tramp_name = mono_get_generic_trampoline_name (tramp_type); @@ -328,14 +331,16 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty buf = code = mono_domain_code_reserve (domain, buf_len); + MINI_BEGIN_CODEGEN (); + code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg1); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); arm_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); - mono_arch_flush_icache (buf, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, mono_get_generic_trampoline_simple_name (tramp_type))); + + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, mono_get_generic_trampoline_simple_name (tramp_type)); if (code_len) *code_len = code - buf; @@ -351,13 +356,17 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) MonoDomain *domain = mono_domain_get (); start = code = mono_domain_code_reserve (domain, size); + + MINI_BEGIN_CODEGEN (); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); arm_addx_imm (code, ARMREG_R0, ARMREG_R0, MONO_ABI_SIZEOF (MonoObject)); arm_brx (code, ARMREG_IP0); g_assert ((code - start) <= size); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m)); + + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m); + return start; } @@ -369,14 +378,16 @@ mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr) MonoDomain *domain = mono_domain_get (); start = code = mono_domain_code_reserve (domain, buf_len); + + MINI_BEGIN_CODEGEN (); + code = mono_arm_emit_imm64 (code, MONO_ARCH_RGCTX_REG, (guint64)arg); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); arm_brx (code, ARMREG_IP0); - g_assert ((code - start) <= buf_len); + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL)); + g_assert ((code - start) <= buf_len); return start; } @@ -415,6 +426,8 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info /* The vtable/mrgtx is in R0 */ g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0); + MINI_BEGIN_CODEGEN (); + if (is_mrgctx) { /* get mrgctx ptr */ arm_movx (code, ARMREG_IP1, ARMREG_R0); @@ -468,11 +481,10 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info } arm_brx (code, ARMREG_IP0); - mono_arch_flush_icache (buf, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL)); - g_assert (code - buf <= buf_size); + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); + if (info) { char *name = mono_get_rgctx_fetch_trampoline_name (slot); *info = mono_tramp_info_create (name, buf, code - buf, ji, unwind_ops); @@ -498,6 +510,8 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0); + MINI_BEGIN_CODEGEN (); + // FIXME: Currently, we always go to the slow path. /* Load trampoline addr */ arm_ldrx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG, 8); @@ -505,11 +519,10 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0); arm_brx (code, ARMREG_IP0); - mono_arch_flush_icache (buf, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL)); - g_assert (code - buf <= tramp_size); + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); + if (info) *info = mono_tramp_info_create ("rgctx_fetch_trampoline_general", buf, code - buf, ji, unwind_ops); @@ -547,6 +560,8 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo // FIXME: Unwind info + MINI_BEGIN_CODEGEN (); + /* Setup stack frame */ imm = frame_size; while (imm > 256) { @@ -605,10 +620,10 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo arm_retx (code, ARMREG_LR); - mono_arch_flush_icache (code, code - buf); - MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL)); g_assert (code - buf <= tramp_size); + MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); + const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline"; *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops); @@ -644,6 +659,8 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info) framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT); + MINI_BEGIN_CODEGEN (); + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, framesize); arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); arm_movspx (code, ARMREG_FP, ARMREG_SP); @@ -712,8 +729,7 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info) g_assert (code - start < buf_len); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL)); + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); if (info) *info = mono_tramp_info_create ("interp_to_native_trampoline", start, code - start, ji, unwind_ops); @@ -744,6 +760,8 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) offset += sizeof (CallContext); framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + MINI_BEGIN_CODEGEN (); + mono_add_unwind_op_def_cfa (unwind_ops, code, start, ARMREG_SP, 0); arm_subx_imm (code, ARMREG_SP, ARMREG_SP, framesize); @@ -788,8 +806,7 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) g_assert (code - start < buf_len); - mono_arch_flush_icache (start, code - start); - MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); if (info) *info = mono_tramp_info_create ("native_to_interp_trampoline", start, code - start, ji, unwind_ops); diff --git a/src/mono/mono/tests/Makefile.am b/src/mono/mono/tests/Makefile.am index fc2a7661882d..6a3af788dfe4 100755 --- a/src/mono/mono/tests/Makefile.am +++ b/src/mono/mono/tests/Makefile.am @@ -1121,7 +1121,9 @@ endif endif - +if DISABLE_CRASH_REPORTING +PLATFORM_DISABLED_TESTS += merp-json-valid.exe merp-crash-test.exe +endif if HOST_DARWIN diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index a69f25bb43ec..24c90a3e6dd4 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -27,7 +27,7 @@ static void* mono_code_manager_heap; #endif #include - +#include static uintptr_t code_memory_used = 0; static size_t dynamic_code_alloc_count; @@ -102,6 +102,7 @@ struct _MonoCodeManager { static mono_mutex_t valloc_mutex; static GHashTable *valloc_freelists; +static MonoNativeTlsKey write_level_tls_id; static void* codechunk_valloc (void *preferred, guint32 size) @@ -121,7 +122,9 @@ codechunk_valloc (void *preferred, guint32 size) freelist = (GSList *) g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size)); if (freelist) { ptr = freelist->data; + mono_codeman_enable_write (); memset (ptr, 0, size); + mono_codeman_disable_write (); freelist = g_slist_delete_link (freelist, freelist); g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist); } else { @@ -176,6 +179,8 @@ mono_code_manager_init (void) mono_counters_register ("Dynamic code allocs", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_alloc_count); mono_counters_register ("Dynamic code bytes", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_bytes_count); mono_counters_register ("Dynamic code frees", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_frees_count); + + mono_native_tls_alloc (&write_level_tls_id, NULL); } void @@ -271,7 +276,10 @@ mono_codeman_malloc (gsize n) g_assert (heap); return HeapAlloc (heap, 0, n); #else - return dlmemalign (MIN_ALIGN, n); + mono_codeman_enable_write (); + gpointer res = dlmemalign (MIN_ALIGN, n); + mono_codeman_disable_write (); + return res; #endif } @@ -285,7 +293,9 @@ mono_codeman_free (gpointer p) g_assert (heap); HeapFree (heap, 0, p); #else + mono_codeman_enable_write (); dlfree (p); + mono_codeman_disable_write (); #endif } @@ -476,7 +486,9 @@ new_codechunk (MonoCodeManager *cman, int size) #ifdef BIND_ROOM if (flags == CODE_FLAG_MALLOC) { /* Make sure the thunks area is zeroed */ + mono_codeman_enable_write (); memset (ptr, 0, bsize); + mono_codeman_disable_write (); } #endif @@ -639,3 +651,43 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size) *used_size = used; return size; } + +/* + * mono_codeman_enable_write (): + * + * Enable writing to code memory on the current thread on platforms that need it. + * Calls can be nested. + */ +void +mono_codeman_enable_write (void) +{ +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP + if (__builtin_available (macOS 11, *)) { + int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); + level ++; + mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); + pthread_jit_write_protect_np (0); + } +#endif +} + +/* + * mono_codeman_disable_write (): + * + * Disable writing to code memory on the current thread on platforms that need it. + * Calls can be nested. + */ +void +mono_codeman_disable_write (void) +{ +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP + if (__builtin_available (macOS 11, *)) { + int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); + g_assert (level); + level --; + mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); + if (level == 0) + pthread_jit_write_protect_np (1); + } +#endif +} diff --git a/src/mono/mono/utils/mono-codeman.h b/src/mono/mono/utils/mono-codeman.h index 4cf447f6e086..fbe2a2f2d4f4 100644 --- a/src/mono/mono/utils/mono-codeman.h +++ b/src/mono/mono/utils/mono-codeman.h @@ -41,5 +41,8 @@ void mono_code_manager_install_callbacks (const MonoCodeManagerCallb typedef int (*MonoCodeManagerFunc) (void *data, int csize, int size, void *user_data); void mono_code_manager_foreach (MonoCodeManager *cman, MonoCodeManagerFunc func, void *user_data); +void mono_codeman_enable_write (void); +void mono_codeman_disable_write (void); + #endif /* __MONO_CODEMAN_H__ */ From 61b284325be69ce1cb9303b9dc388922590baaad Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 28 Jul 2020 16:42:31 +0200 Subject: [PATCH 089/755] Adapt RFC 6265 in path handling for cookies (#39250) Resolves "Path related issues" of #26141 (described in #21440, #22372 and #25226) by adapting RFC 6265 for path management: - Removes the restriction for the Path attribute (it's no longer expected to prefix the request path) - Introduces the default-path calculation and path matching algorithms as defined in section 5.1.4 of the new RFC - Adds integration tests for HttpClient based on user scenarios described in the issues --- .../Net/Http/HttpClientHandlerTest.Cookies.cs | 115 +++++++++++++++++- .../TestUtilities/System/PlatformDetection.cs | 1 + .../src/System/Net/Cookie.cs | 31 +++-- .../src/System/Net/CookieContainer.cs | 23 +++- .../FunctionalTests/CookieContainerTest.cs | 1 - .../tests/UnitTests/CookieContainerTest.cs | 95 ++++++++++++++- 6 files changed, 244 insertions(+), 22 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index 0efb77153765..e722e8bb37c5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -293,18 +293,19 @@ public async Task GetAsyncWithRedirect_SetCookieContainer_CorrectCookiesSent() { const string path1 = "/foo"; const string path2 = "/bar"; + const string unusedPath = "/unused"; await LoopbackServerFactory.CreateClientAndServerAsync(async url => { Uri url1 = new Uri(url, path1); Uri url2 = new Uri(url, path2); - Uri unusedUrl = new Uri(url, "/unused"); + Uri unusedUrl = new Uri(url, unusedPath); HttpClientHandler handler = CreateHttpClientHandler(); handler.CookieContainer = new CookieContainer(); - handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1")); - handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2")); - handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3")); + handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1", path1)); + handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2", path2)); + handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3", unusedPath)); using (HttpClient client = CreateHttpClient(handler)) { @@ -393,6 +394,112 @@ await LoopbackServerFactory.CreateServerAsync(async (server, url) => }); } + // Default path should be calculated according to https://tools.ietf.org/html/rfc6265#section-5.1.4 + // When a cookie is being sent without an explicitly defined Path for a URL with URL-Path /path/sub, + // the cookie should be added with Path=/path. + // ConditionalFact: CookieContainer does not follow RFC6265 on .NET Framework, therefore the (WinHttpHandler) test is expected to fail + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNetFramework))] + public async Task GetAsync_NoPathDefined_CookieAddedWithDefaultPath() + { + await LoopbackServerFactory.CreateServerAsync(async (server, serverUrl) => + { + Uri requestUrl = new Uri(serverUrl, "path/sub"); + HttpClientHandler handler = CreateHttpClientHandler(); + + using (HttpClient client = CreateHttpClient(handler)) + { + Task getResponseTask = client.GetAsync(requestUrl); + Task serverTask = server.HandleRequestAsync( + HttpStatusCode.OK, + new HttpHeaderData[] + { + new HttpHeaderData("Set-Cookie", "A=1"), + }, + s_simpleContent); + await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask); + + Cookie cookie = handler.CookieContainer.GetCookies(requestUrl)[0]; + Assert.Equal("/path", cookie.Path); + } + }); + } + + // According to RFC6265, cookie path is not expected to match the request's path, + // these cookies should be accepted by the client. + // ConditionalFact: CookieContainer does not follow RFC6265 on .NET Framework, therefore the (WinHttpHandler) test is expected to fail + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNetFramework))] + public async Task GetAsync_CookiePathDoesNotMatchRequestPath_CookieAccepted() + { + await LoopbackServerFactory.CreateServerAsync(async (server, serverUrl) => + { + Uri requestUrl = new Uri(serverUrl, "original"); + Uri otherUrl = new Uri(serverUrl, "other"); + HttpClientHandler handler = CreateHttpClientHandler(); + + using (HttpClient client = CreateHttpClient(handler)) + { + Task getResponseTask = client.GetAsync(requestUrl); + Task serverTask = server.HandleRequestAsync( + HttpStatusCode.OK, + new[] + { + new HttpHeaderData("Set-Cookie", "A=1; Path=/other"), + }, + s_simpleContent); + await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask); + + Cookie cookie = handler.CookieContainer.GetCookies(otherUrl)[0]; + Assert.Equal("/other", cookie.Path); + } + }); + } + + // Based on the OIDC login scenario described in comments: + // https://github.com/dotnet/runtime/pull/39250#issuecomment-659783480 + // https://github.com/dotnet/runtime/issues/26141#issuecomment-612097147 + // ConditionalFact: CookieContainer does not follow RFC6265 on .NET Framework, therefore the (WinHttpHandler) test is expected to fail + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNetFramework))] + public async Task GetAsync_Redirect_CookiesArePreserved() + { + HttpClientHandler handler = CreateHttpClientHandler(); + + string loginPath = "/login/user"; + string returnPath = "/return"; + + await LoopbackServerFactory.CreateClientAndServerAsync(async serverUrl => + { + Uri loginUrl = new Uri(serverUrl, loginPath); + Uri returnUrl = new Uri(serverUrl, returnPath); + CookieContainer cookies = handler.CookieContainer; + + using (HttpClient client = CreateHttpClient(handler)) + { + client.DefaultRequestHeaders.ConnectionClose = true; // to avoid issues with connection pooling + HttpResponseMessage response = await client.GetAsync(loginUrl); + string content = await response.Content.ReadAsStringAsync(); + Assert.Equal(s_simpleContent, content); + + Cookie cookie = handler.CookieContainer.GetCookies(returnUrl)[0]; + Assert.Equal("LoggedIn", cookie.Name); + } + }, + async server => + { + HttpRequestData requestData1 = await server.HandleRequestAsync(HttpStatusCode.Found, new[] + { + new HttpHeaderData("Location", returnPath), + new HttpHeaderData("Set-Cookie", "LoggedIn=true; Path=/return"), + }); + + Assert.Equal(0, requestData1.GetHeaderValueCount("Cookie")); + + HttpRequestData requestData2 = await server.HandleRequestAsync(content: s_simpleContent, headers: new[]{ + new HttpHeaderData("Set-Cookie", "LoggedIn=true; Path=/return"), + }); + Assert.Equal("LoggedIn=true", requestData2.GetSingleHeaderValue("Cookie")); + }); + } + [Fact] public async Task GetAsync_ReceiveSetCookieHeader_CookieUpdated() { diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 7a4d50d540bb..6d5811e10140 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -29,6 +29,7 @@ public static partial class PlatformDetection public static bool IsSolaris => RuntimeInformation.IsOSPlatform(OSPlatform.Create("SOLARIS")); public static bool IsBrowser => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); public static bool IsNotBrowser => !IsBrowser; + public static bool IsNotNetFramework => !IsNetFramework; public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm; public static bool IsNotArmProcess => !IsArmProcess; diff --git a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs index c9a4ef4efe43..dc694bc09ecd 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs @@ -490,7 +490,24 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma switch (m_cookieVariant) { case CookieVariant.Plain: - m_path = path; + // As per RFC6265 5.1.4. (https://tools.ietf.org/html/rfc6265#section-5.1.4): + // | 2. If the uri-path is empty or if the first character of the uri- + // | path is not a %x2F ("/") character, output %x2F ("/") and skip + // | the remaining steps. + // | 3. If the uri-path contains no more than one %x2F ("/") character, + // | output %x2F ("/") and skip the remaining step. + // Note: Normally Uri.AbsolutePath contains at least one "/" after parsing, + // but it's possible construct Uri with an empty path using a custom UriParser + int lastSlash; + if (path.Length == 0 || path[0] != '/' || (lastSlash = path.LastIndexOf('/')) == 0) + { + m_path = "/"; + break; + } + + // | 4. Output the characters of the uri-path from the first character up + // | to, but not including, the right-most %x2F ("/"). + m_path = path.Substring(0, lastSlash); break; case CookieVariant.Rfc2109: m_path = path.Substring(0, path.LastIndexOf('/')); // May be empty @@ -503,18 +520,6 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma break; } } - else - { - // Check current path (implicit/explicit) against given URI. - if (!path.StartsWith(CookieParser.CheckQuoted(m_path), StringComparison.Ordinal)) - { - if (shouldThrow) - { - throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PathAttributeName, m_path)); - } - return false; - } - } // Set the default port if Port attribute was present but had no value. if (setDefault && (m_port_implicit == false && m_port.Length == 0)) diff --git a/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs b/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs index c381399b43c9..9728030b8cd4 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Net.NetworkInformation; using System.Text; @@ -885,7 +886,7 @@ private void BuildCookieCollectionFromDomainMatches(Uri uri, bool isSecure, int for (int e = 0; e < listCount; e++) { string path = (string)list.GetKey(e); - if (uri.AbsolutePath.StartsWith(CookieParser.CheckQuoted(path), StringComparison.Ordinal)) + if (PathMatch(uri.AbsolutePath, path)) { CookieCollection cc = (CookieCollection)list.GetByIndex(e)!; cc.TimeStamp(CookieCollection.Stamp.Set); @@ -905,6 +906,26 @@ private void BuildCookieCollectionFromDomainMatches(Uri uri, bool isSecure, int } } + // Implement path-matching according to https://tools.ietf.org/html/rfc6265#section-5.1.4: + // | A request-path path-matches a given cookie-path if at least one of the following conditions holds: + // | - The cookie-path and the request-path are identical. + // | - The cookie-path is a prefix of the request-path, and the last character of the cookie-path is %x2F ("/"). + // | - The cookie-path is a prefix of the request-path, and the first character of the request-path that is not included in the cookie-path is a %x2F ("/") character. + // The latter conditions are needed to make sure that + // PathMatch("/fooBar, "/foo") == false + // but: + // PathMatch("/foo/bar", "/foo") == true, PathMatch("/foo/bar", "/foo/") == true + private static bool PathMatch(string requestPath, string cookiePath) + { + cookiePath = CookieParser.CheckQuoted(cookiePath); + + if (!requestPath.StartsWith(cookiePath, StringComparison.Ordinal)) + return false; + return requestPath.Length == cookiePath.Length || + cookiePath.Length > 0 && cookiePath[^1] == '/' || + requestPath[cookiePath.Length] == '/'; + } + private void MergeUpdateCollections(ref CookieCollection? destination, CookieCollection source, int port, bool isSecure, bool isPlainOnly) { lock (source) diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieContainerTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieContainerTest.cs index 6b45b096ccab..da3bd1f6e909 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieContainerTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieContainerTest.cs @@ -140,7 +140,6 @@ public static IEnumerable SetCookiesInvalidData() yield return new object[] { u5, "$=value" }; // Invalid name yield return new object[] { new Uri("http://url.com"), "na\tme=value; domain=.domain.com" }; // Invalid name yield return new object[] { new Uri("http://url.com"), "name=value; domain=.domain.com" }; // Domain not the same - yield return new object[] { new Uri("http://url.com/path"), "name=value; domain=.url.com; path=/root" }; // Path not the same yield return new object[] { new Uri("http://url.com:90"), "name=value; port=\"80\"" }; // Port not the same yield return new object[] { new Uri("http://url.com"), "name=value; domain=" }; // Empty domain yield return new object[] { u6, "name11=value11; version=invalidversion" }; // Invalid version diff --git a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs index cd2ba344da44..6daad6860a7b 100644 --- a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs +++ b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Threading.Tasks; @@ -36,6 +37,18 @@ public class CookieContainerTest private const string CookieValue1 = "CookieValue1"; private const string CookieValue2 = "CookieValue2"; + // Creates cookies as following: + // c1 | .url1.com | name1=value + // c2 | .url1.com | name2=value; Secure=True + // c3 | .url1.com | name3=value; $Version=1; $Domain=.url1.com; $Port="80, 90, 100, 443" + // c4 | 127.0.0.1 | name4=value + // c5 | 127.0.0.1 | name4=value; Path=/path + // c6 | .url3.com | name6=value + // c7 | .url3.com | name7=value + // c8 | url4.com | name8=value + // c9 | url4.com | name9=value + // c10 | url5.com/path | name10=value + // c11 | url5.com/path | name11=value; $Version=1; $Port="80, 90, 100" private CookieContainer CreateCount11Container() { CookieContainer cc1 = new CookieContainer(); @@ -100,9 +113,9 @@ public static IEnumerable SetCookiesData() new Cookie[] { c10, + c11, new Cookie("name98", "value98"), new Cookie("name99", "value99"), - c11 } }; // Simple @@ -637,7 +650,7 @@ public void GetCookies_DifferentPaths_GetsMatchedPathsIncludingEmptyPath() { // Internally, paths are stored alphabetically sorted - so expect a cookie collection sorted by the path of each cookie // This test ensures that all cookies with paths (that the path specified by the uri starts with) are returned - Cookie c1 = new Cookie("name1", "value", "/aa", ".url.com"); + Cookie c1 = new Cookie("name1", "value", "/a/a", ".url.com"); Cookie c2 = new Cookie("name2", "value", "/a", ".url.com"); Cookie c3 = new Cookie("name3", "value", "/b", ".url.com"); // Should be ignored - no match with the URL's path Cookie c4 = new Cookie("name4", "value", "/", ".url.com"); // Should NOT be ignored (has no path specified) @@ -648,7 +661,7 @@ public void GetCookies_DifferentPaths_GetsMatchedPathsIncludingEmptyPath() cc1.Add(c3); cc1.Add(c4); - CookieCollection cc2 = cc1.GetCookies(new Uri("http://url.com/aaa")); + CookieCollection cc2 = cc1.GetCookies(new Uri("http://url.com/a/a/a")); Assert.Equal(3, cc2.Count); Assert.Equal(c1, cc2[0]); Assert.Equal(c2, cc2[1]); @@ -838,5 +851,81 @@ public void SetCookies_DomainCheckFailure_IgnoresAbsenceOfLeadingDot(string doma Assert.Throws(() => container.SetCookies(uri, cookie)); } + + // Test default-path calculation as defined in + // https://tools.ietf.org/html/rfc6265#section-5.1.4 + public static readonly TheoryData DefaultPathData = new TheoryData() + { + {"http://url1.com", "/"}, + {"http://url1.com/abc", "/"}, + {"http://url1.com/abc/xy", "/abc"}, + {"http://url1.com/abc/xy/foo", "/abc/xy"}, + {"http://127.0.0.1", "/"}, + {"http://127.0.0.1/a/s/d/f", "/a/s/d"}, + }; + + [Theory] + [MemberData(nameof(DefaultPathData))] + public void GetCookies_DefaultPathCalculationFollowsRfc6265(string uriString, string expectedPath) + { + Cookie cookie = new Cookie("n", "v"); + Uri uri = new Uri(uriString); + + CookieContainer container = new CookieContainer(); + container.Add(uri, cookie); + + Cookie actualCookie = container.GetCookies(uri).Single(); + Assert.Equal(expectedPath, actualCookie.Path); + } + + // Test path-match as defined in + // https://tools.ietf.org/html/rfc6265#section-5.1.4 + public static readonly TheoryData PathMatchData = new TheoryData + { + {false, new [] {"/"}, "/", 1}, + {false, new [] {"/asd/fg/hjk/l", "/x"}, "/asd/fg/hjk/l", 1}, + {false, new [] {"/a", "/x"}, "/a/hello", 1}, + {false, new [] {"/a/foo", "/a/lol"}, "/a/foo/1/2/3", 1}, + {false, new [] {"/a/", "/x"}, "/a/hello", 1}, + {false, new [] {"", "/x"}, "/y", 1}, + {false, new [] {"//"}, "/", 0}, + {false, new [] {"//"}, "//", 1}, + {false, new [] {"", "/", "//", "///"}, "///", 4}, + + // Should not match the second half of the criteria: + // "The cookie-path is a prefix of the request-path, and the first + // character of the request-path that is not included in the cookie- + // path is a %x2F ("/") character." + {false, new [] {"/a/foo", "/x"}, "/a/foo123", 0}, + + {true, new [] {"/"}, "/", 1}, + {true, new [] {"/a/b", "/a/c", "/x/y"}, "/a/hello", 2}, + {true, new [] {"/a/foo/b", "/a/foo/c", "/a/foo/42", "/a/lol/42"}, "/a/foo/hello", 3}, + }; + + [Theory] + [MemberData(nameof(PathMatchData))] + public void GetCookies_PathMatchingFollowsRfc6265(bool useDefaultPath, string[] cookiePaths, string requestPath, int expectedMatches) + { + CookieContainer container = new CookieContainer(); + + int i = 0; + foreach (string cookiePath in cookiePaths) + { + if (useDefaultPath) + { + container.Add(new Uri("http://test.com" + cookiePath), new Cookie($"c{i}", "value")); + } + else + { + container.Add(new Uri("http://test.com"), new Cookie($"c{i}", "value", cookiePath)); + } + i++; + } + + Uri requestUri = new Uri("http://test.com" + requestPath); + CookieCollection collection = container.GetCookies(requestUri); + Assert.Equal(expectedMatches, collection.Count); + } } } From d3199700654c46994157eb4974f98a4bcb6edf76 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Tue, 28 Jul 2020 16:55:12 +0200 Subject: [PATCH 090/755] System.Net.Sockets telemetry counters (#39708) Counters in SocketsTelemetry measuring `bytes-received` (Bytes Received) The cumulative total number of bytes received by all Socket objects since the process started. `bytes-sent` (Bytes Sent) The cumulative number of bytes sent by all Socket objects since the process started. `outgoing-connections-established` (Outgoing Connections Established) The cumulative total number of outgoing connections established by Socket objects for stream sockets since the process started. `incoming-connections-established` (Incoming Connections Established) The cumulative total number of incoming connections established by Socket objects for stream sockets since the process started. `datagrams-received` (Datagrams Received) The cumulative total number of datagram packets received by all Socket objects since the process started. `datagrams-sent` (Datagrams Sent) The cumulative total number of datagram packets sent by all Socket objects since the process started. Contributes to #37428 --- .../Diagnostics/Tracing/TestEventListener.cs | 17 ++- .../src/System/Net/Sockets/Socket.cs | 103 +++++++++++++++ .../Net/Sockets/SocketAsyncEventArgs.cs | 38 +++++- .../System/Net/Sockets/SocketsTelemetry.cs | 120 ++++++++++++++++++ .../tests/FunctionalTests/TelemetryTest.cs | 61 +++++++-- 5 files changed, 320 insertions(+), 19 deletions(-) diff --git a/src/libraries/Common/tests/System/Diagnostics/Tracing/TestEventListener.cs b/src/libraries/Common/tests/System/Diagnostics/Tracing/TestEventListener.cs index bc210b2b83b5..b12f5022c62f 100644 --- a/src/libraries/Common/tests/System/Diagnostics/Tracing/TestEventListener.cs +++ b/src/libraries/Common/tests/System/Diagnostics/Tracing/TestEventListener.cs @@ -12,24 +12,27 @@ internal sealed class TestEventListener : EventListener private readonly string _targetSourceName; private readonly Guid _targetSourceGuid; private readonly EventLevel _level; + private readonly double? _eventCounterInterval; private Action _eventWritten; private List _tmpEventSourceList = new List(); - public TestEventListener(string targetSourceName, EventLevel level) + public TestEventListener(string targetSourceName, EventLevel level, double? eventCounterInterval = null) { // Store the arguments _targetSourceName = targetSourceName; _level = level; + _eventCounterInterval = eventCounterInterval; LoadSourceList(); } - public TestEventListener(Guid targetSourceGuid, EventLevel level) + public TestEventListener(Guid targetSourceGuid, EventLevel level, double? eventCounterInterval = null) { // Store the arguments _targetSourceGuid = targetSourceGuid; _level = level; + _eventCounterInterval = eventCounterInterval; LoadSourceList(); } @@ -80,7 +83,15 @@ private void EnableSourceIfMatch(EventSource source) if (source.Name.Equals(_targetSourceName) || source.Guid.Equals(_targetSourceGuid)) { - EnableEvents(source, _level); + if (_eventCounterInterval != null) + { + var args = new Dictionary { { "EventCounterIntervalSec", _eventCounterInterval?.ToString() } }; + EnableEvents(source, _level, EventKeywords.All, args); + } + else + { + EnableEvents(source, _level); + } } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index a874c7f60dc4..08eae7dbecb7 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -1087,6 +1087,8 @@ public Socket Accept() IPEndPointExtensions.Serialize(_rightEndPoint) : new Internals.SocketAddress(_addressFamily, SocketPal.MaximumAddressSize); // may be different size. + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStart(socketAddress); + // This may throw ObjectDisposedException. SafeSocketHandle acceptedSocketHandle; SocketError errorCode = SocketPal.Accept( @@ -1098,10 +1100,16 @@ public Socket Accept() // Throw an appropriate SocketException if the native call fails. if (errorCode != SocketError.Success) { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptFailedAndStop(errorCode, null); + Debug.Assert(acceptedSocketHandle.IsInvalid); UpdateAcceptSocketErrorForDisposed(ref errorCode); UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else + { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStop(); + } Debug.Assert(!acceptedSocketHandle.IsInvalid); @@ -1169,9 +1177,16 @@ public int Send(IList> buffers, SocketFlags socketFlags, out // Update the internal state of this socket according to the error before throwing. UpdateStatusAfterSocketError(errorCode); if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); + // Don't log transfered byte count in case of a failure. return 0; } + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + return bytesTransferred; } @@ -1223,6 +1238,12 @@ public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, ou return 0; } + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"Send returns:{bytesTransferred}"); @@ -1258,6 +1279,14 @@ public int Send(ReadOnlySpan buffer, SocketFlags socketFlags, out SocketEr if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); bytesTransferred = 0; } + else + { + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + } return bytesTransferred; } @@ -1322,6 +1351,14 @@ public int SendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else + { + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + } if (_rightEndPoint == null) { @@ -1400,6 +1437,11 @@ public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffer, offset, size, socketFlags, out bytesTransferred); + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1433,6 +1475,11 @@ public int Receive(Span buffer, SocketFlags socketFlags, out SocketError e int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffer, socketFlags, out bytesTransferred); + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1482,6 +1529,12 @@ public int Receive(IList> buffers, SocketFlags socketFlags, o int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffers, socketFlags, out bytesTransferred); + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } + UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); if (errorCode != SocketError.Success) @@ -1542,6 +1595,11 @@ public int ReceiveMessageFrom(byte[] buffer, int offset, int size, ref SocketFla Internals.SocketAddress receiveAddress; int bytesTransferred; SocketError errorCode = SocketPal.ReceiveMessageFrom(this, _handle, buffer, offset, size, ref socketFlags, socketAddress, out receiveAddress, out ipPacketInformation, out bytesTransferred); + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1618,6 +1676,11 @@ public int ReceiveFrom(byte[] buffer, int offset, int size, SocketFlags socketFl int bytesTransferred; SocketError errorCode = SocketPal.ReceiveFrom(_handle, buffer, offset, size, socketFlags, socketAddress.Buffer, ref socketAddress.InternalSize, out bytesTransferred); + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -2587,6 +2650,12 @@ public int EndSend(IAsyncResult asyncResult, out SocketError errorCode) return 0; } + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + return bytesTransferred; } @@ -2761,6 +2830,14 @@ public int EndSendTo(IAsyncResult asyncResult) UpdateSendSocketErrorForDisposed(ref errorCode); UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else + { + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + } + } return bytesTransferred; } @@ -2985,6 +3062,11 @@ public int EndReceive(IAsyncResult asyncResult, out SocketError errorCode) int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } // Throw an appropriate SocketException if the native call failed asynchronously. errorCode = (SocketError)castedAsyncResult.ErrorCode; @@ -3141,6 +3223,11 @@ public int EndReceiveMessageFrom(IAsyncResult asyncResult, ref SocketFlags socke int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } // Update socket address size. castedAsyncResult.SocketAddress!.InternalSize = castedAsyncResult.GetSocketAddressSize(); @@ -3344,6 +3431,11 @@ public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint) int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; + if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } // Update socket address size. castedAsyncResult.SocketAddress!.InternalSize = castedAsyncResult.GetSocketAddressSize(); @@ -3446,6 +3538,7 @@ private void DoBeginAccept(Socket? acceptSocket, int receiveSize, AcceptOverlapp asyncResult.AcceptSocket = GetOrCreateAcceptSocket(acceptSocket, false, nameof(acceptSocket), out acceptHandle); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"AcceptSocket:{acceptSocket}"); + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStart(_rightEndPoint); int socketAddressSize = GetAddressSize(_rightEndPoint); SocketError errorCode = SocketPal.AcceptAsync(this, _handle, acceptHandle, receiveSize, socketAddressSize, asyncResult); @@ -3455,9 +3548,13 @@ private void DoBeginAccept(Socket? acceptSocket, int receiveSize, AcceptOverlapp // Throw an appropriate SocketException if the native call fails synchronously. if (!CheckErrorAndUpdateStatus(errorCode)) { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptFailedAndStop(errorCode, null); + UpdateAcceptSocketErrorForDisposed(ref errorCode); throw new SocketException((int)errorCode); } + + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStop(); } // Routine Description: @@ -3521,9 +3618,15 @@ public Socket EndAccept(out byte[]? buffer, out int bytesTransferred, IAsyncResu SocketError errorCode = (SocketError)castedAsyncResult.ErrorCode; if (errorCode != SocketError.Success) { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptFailedAndStop(errorCode, null); + UpdateAcceptSocketErrorForDisposed(ref errorCode); UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else + { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStop(); + } if (NetEventSource.Log.IsEnabled()) NetEventSource.Accepted(socket, socket.RemoteEndPoint, socket.LocalEndPoint); return socket; diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index 213cb30909b9..114a65d256d7 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs @@ -547,6 +547,8 @@ internal void StartOperationAccept() _acceptBuffer = new byte[_acceptAddressBufferCount]; } } + + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStart(_currentSocket!._rightEndPoint!); } internal void StartOperationConnect(MultipleConnectAsync? multipleConnect, bool userSocket) @@ -587,9 +589,10 @@ internal void FinishOperationSyncFailure(SocketError socketError, int bytesTrans { SetResults(socketError, bytesTransferred, flags); - if (SocketsTelemetry.Log.IsEnabled() && _multipleConnect == null && _completedOperation == SocketAsyncOperation.Connect) + if (SocketsTelemetry.Log.IsEnabled()) { - SocketsTelemetry.Log.ConnectFailedAndStop(socketError, null); + if (_multipleConnect == null && _completedOperation == SocketAsyncOperation.Connect) SocketsTelemetry.Log.ConnectFailedAndStop(socketError, null); + if (_completedOperation == SocketAsyncOperation.Accept) SocketsTelemetry.Log.AcceptFailedAndStop(socketError, null); } // This will be null if we're doing a static ConnectAsync to a DnsEndPoint with AddressFamily.Unspecified; @@ -615,6 +618,8 @@ internal void FinishOperationSyncFailure(SocketError socketError, int bytesTrans break; } + // Don't log transfered byte count in case of a failure. + Complete(); } @@ -665,6 +670,8 @@ internal void FinishWrapperConnectSuccess(Socket? connectSocket, int bytesTransf _currentSocket = connectSocket; _connectSocket = connectSocket; + if (SocketsTelemetry.Log.IsEnabled()) LogBytesTransferEvents(connectSocket?.SocketType, SocketAsyncOperation.Connect, bytesTransferred); + // Complete the operation and raise the event. ExecutionContext? context = _context; // store context before it's cleared as part of completing the operation Complete(); @@ -708,9 +715,13 @@ internal void FinishOperationSyncSuccess(int bytesTransferred, SocketFlags flags } catch (ObjectDisposedException) { } } + + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStop(); } else { + if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptFailedAndStop(socketError, null); + SetResults(socketError, bytesTransferred, flags); _acceptSocket = null; _currentSocket.UpdateStatusAfterSocketError(socketError); @@ -789,6 +800,8 @@ internal void FinishOperationSyncSuccess(int bytesTransferred, SocketFlags flags break; } + if (SocketsTelemetry.Log.IsEnabled()) LogBytesTransferEvents(_currentSocket?.SocketType, _completedOperation, bytesTransferred); + Complete(); } @@ -822,5 +835,26 @@ private void FinishOperationSync(SocketError socketError, int bytesTransferred, FinishOperationSyncFailure(socketError, bytesTransferred, flags); } } + + private static void LogBytesTransferEvents(SocketType? socketType, SocketAsyncOperation operation, int bytesTransferred) + { + switch (operation) + { + case SocketAsyncOperation.Receive: + case SocketAsyncOperation.ReceiveFrom: + case SocketAsyncOperation.ReceiveMessageFrom: + case SocketAsyncOperation.Accept: + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (socketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + break; + case SocketAsyncOperation.Send: + case SocketAsyncOperation.SendTo: + case SocketAsyncOperation.SendPackets: + case SocketAsyncOperation.Connect: + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (socketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); + break; + } + } } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketsTelemetry.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketsTelemetry.cs index 7f0e2a78eb74..f3430e7b7ed7 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketsTelemetry.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketsTelemetry.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.Tracing; +using System.Threading; namespace System.Net.Sockets { @@ -10,9 +11,24 @@ internal sealed class SocketsTelemetry : EventSource { public static readonly SocketsTelemetry Log = new SocketsTelemetry(); + private PollingCounter? _outgoingConnectionsEstablishedCounter; + private PollingCounter? _incomingConnectionsEstablishedCounter; + private PollingCounter? _bytesReceivedCounter; + private PollingCounter? _bytesSentCounter; + private PollingCounter? _datagramsReceivedCounter; + private PollingCounter? _datagramsSentCounter; + + private long _outgoingConnectionsEstablished; + private long _incomingConnectionsEstablished; + private long _bytesReceived; + private long _bytesSent; + private long _datagramsReceived; + private long _datagramsSent; + [Event(1, Level = EventLevel.Informational)] public void ConnectStart(string? address) { + Interlocked.Increment(ref _outgoingConnectionsEstablished); if (IsEnabled(EventLevel.Informational, EventKeywords.All)) { WriteEvent(eventId: 1, address ?? ""); @@ -46,6 +62,34 @@ public void ConnectCanceled() } } + [Event(5, Level = EventLevel.Informational)] + public void AcceptStart(string? address) + { + Interlocked.Increment(ref _incomingConnectionsEstablished); + if (IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + WriteEvent(eventId: 5, address ?? ""); + } + } + + [Event(6, Level = EventLevel.Informational)] + public void AcceptStop() + { + if (IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + WriteEvent(eventId: 6); + } + } + + [Event(7, Level = EventLevel.Error)] + public void AcceptFailed(SocketError error, string? exceptionMessage) + { + if (IsEnabled(EventLevel.Error, EventKeywords.All)) + { + WriteEvent(eventId: 7, (int)error, exceptionMessage ?? string.Empty); + } + } + [NonEvent] public void ConnectStart(Internals.SocketAddress address) { @@ -71,5 +115,81 @@ public void ConnectFailedAndStop(SocketError error, string? exceptionMessage) ConnectFailed(error, exceptionMessage); ConnectStop(); } + + [NonEvent] + public void AcceptStart(Internals.SocketAddress address) + { + AcceptStart(address.ToString()); + } + + [NonEvent] + public void AcceptStart(EndPoint address) + { + AcceptStart(address.ToString()); + } + + [NonEvent] + public void AcceptFailedAndStop(SocketError error, string? exceptionMessage) + { + AcceptFailed(error, exceptionMessage); + AcceptStop(); + } + + [NonEvent] + public void BytesReceived(int count) + { + Interlocked.Add(ref _bytesReceived, count); + } + + [NonEvent] + public void BytesSent(int count) + { + Interlocked.Add(ref _bytesSent, count); + } + + [NonEvent] + public void DatagramReceived() + { + Interlocked.Increment(ref _datagramsReceived); + } + + [NonEvent] + public void DatagramSent() + { + Interlocked.Increment(ref _datagramsSent); + } + + protected override void OnEventCommand(EventCommandEventArgs command) + { + if (command.Command == EventCommand.Enable) + { + // This is the convention for initializing counters in the RuntimeEventSource (lazily on the first enable command). + + _outgoingConnectionsEstablishedCounter ??= new PollingCounter("outgoing-connections-established", this, () => Interlocked.Read(ref _outgoingConnectionsEstablished)) + { + DisplayName = "Outgoing Connections Established", + }; + _incomingConnectionsEstablishedCounter ??= new PollingCounter("incoming-connections-established", this, () => Interlocked.Read(ref _incomingConnectionsEstablished)) + { + DisplayName = "Incoming Connections Established", + }; + _bytesReceivedCounter ??= new PollingCounter("bytes-received", this, () => Interlocked.Read(ref _bytesReceived)) + { + DisplayName = "Bytes Received", + }; + _bytesSentCounter ??= new PollingCounter("bytes-sent", this, () => Interlocked.Read(ref _bytesSent)) + { + DisplayName = "Bytes Sent", + }; + _datagramsReceivedCounter ??= new PollingCounter("datagrams-received", this, () => Interlocked.Read(ref _datagramsReceived)) + { + DisplayName = "Datagrams Received", + }; + _datagramsSentCounter ??= new PollingCounter("datagrams-sent", this, () => Interlocked.Read(ref _datagramsSent)) + { + DisplayName = "Datagrams Sent", + }; + } + } } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs index 33529f980d22..783fbf52e133 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs @@ -1,8 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Tracing; +using System.Linq; +using System.Threading.Tasks; using Microsoft.DotNet.RemoteExecutor; using Xunit; using Xunit.Abstractions; @@ -36,32 +41,60 @@ public void EventSource_EventsRaisedAsExpected() { RemoteExecutor.Invoke(() => { - using (var listener = new TestEventListener("System.Net.Sockets", EventLevel.Verbose)) + using (var listener = new TestEventListener("System.Net.Sockets", EventLevel.Verbose, 0.1)) { var events = new ConcurrentQueue(); - listener.RunWithCallback(events.Enqueue, () => + listener.RunWithCallbackAsync(events.Enqueue, async () => { // Invoke several tests to execute code paths while tracing is enabled - new SendReceiveSync(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter(); - new SendReceiveSync(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter(); + await new SendReceiveSync(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).ConfigureAwait(false); + await new SendReceiveSync(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).ConfigureAwait(false); - new SendReceiveTask(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter(); - new SendReceiveTask(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter(); + await new SendReceiveTask(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).ConfigureAwait(false); + await new SendReceiveTask(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).ConfigureAwait(false); - new SendReceiveEap(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter(); - new SendReceiveEap(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter(); + await new SendReceiveEap(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).ConfigureAwait(false); + await new SendReceiveEap(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).ConfigureAwait(false); - new SendReceiveApm(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter(); - new SendReceiveApm(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter(); + await new SendReceiveApm(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).ConfigureAwait(false); + await new SendReceiveApm(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).ConfigureAwait(false); - new NetworkStreamTest().CopyToAsync_AllDataCopied(4096, true).GetAwaiter().GetResult(); - new NetworkStreamTest().Timeout_ValidData_Roundtrips().GetAwaiter().GetResult(); - }); + await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback).ConfigureAwait(false); + await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback).ConfigureAwait(false); + + await new NetworkStreamTest().CopyToAsync_AllDataCopied(4096, true).ConfigureAwait(false); + await new NetworkStreamTest().Timeout_ValidData_Roundtrips().ConfigureAwait(false); + await Task.Delay(300).ConfigureAwait(false); + }).Wait(); Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself - Assert.InRange(events.Count, 1, int.MaxValue); + VerifyEvents(events, "ConnectStart", 10); + VerifyEvents(events, "ConnectStop", 10); + + Dictionary eventCounters = events.Where(e => e.EventName == "EventCounters").Select(e => (IDictionary) e.Payload.Single()) + .GroupBy(d => (string)d["Name"], d => (double)d["Mean"], (k, v) => new { Name = k, Value = v.Sum() }) + .ToDictionary(p => p.Name, p => p.Value); + + VerifyEventCounter("incoming-connections-established", eventCounters); + VerifyEventCounter("outgoing-connections-established", eventCounters); + VerifyEventCounter("bytes-received", eventCounters); + VerifyEventCounter("bytes-sent", eventCounters); + VerifyEventCounter("datagrams-received", eventCounters); + VerifyEventCounter("datagrams-sent", eventCounters); } }).Dispose(); } + + private static void VerifyEvents(IEnumerable events, string eventName, int expectedCount) + { + EventWrittenEventArgs[] starts = events.Where(e => e.EventName == eventName).ToArray(); + Assert.Equal(expectedCount, starts.Length); + } + + private static void VerifyEventCounter(string name, Dictionary eventCounters) + { + Assert.True(eventCounters.ContainsKey(name)); + Assert.True(eventCounters[name] > 0); + } } } From 7a6ca80bcde1d133dccba2c2ab361cf76c0832c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Tue, 28 Jul 2020 16:58:43 +0200 Subject: [PATCH 091/755] Expect 100 Continue Hang (#38774) Inside sendRequestContentTask recognizes that it's invoked from a timer thread and if request content fails, unblocks SendAsyncCore and eventually propagates the exception from the content to the outside. Fixes the issue for H2 as well. Fixes #36717 --- .../System/Net/Http/HttpClientHandlerTest.cs | 39 +++++++++++++++++++ .../tests/System/Net/Http}/ThrowingContent.cs | 5 ++- ...ttp.WinHttpHandler.Functional.Tests.csproj | 2 + .../SocketsHttpHandler/Http2Connection.cs | 3 +- .../Http/SocketsHttpHandler/Http2Stream.cs | 2 + .../Http/SocketsHttpHandler/HttpConnection.cs | 30 +++++++++++++- .../System.Net.Http.Functional.Tests.csproj | 5 ++- .../ThrowingContent.netcore.cs | 17 ++++++++ 8 files changed, 97 insertions(+), 6 deletions(-) rename src/libraries/{System.Net.Http/tests/FunctionalTests => Common/tests/System/Net/Http}/ThrowingContent.cs (88%) create mode 100644 src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.netcore.cs diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 2aa3c26ee16b..687fa61ab06d 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -2116,6 +2116,45 @@ await server.AcceptConnectionAsync(async connection => }); } + [Fact] + public async Task SendAsync_Expect100Continue_RequestBodyFails_ThrowsContentException() + { + if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) + { + return; + } + if (!TestAsync && UseVersion >= HttpVersion20.Value) + { + return; + } + + var clientFinished = new TaskCompletionSource(); + + await LoopbackServerFactory.CreateClientAndServerAsync(async uri => + { + using (HttpClient client = CreateHttpClient()) + { + HttpRequestMessage initialMessage = new HttpRequestMessage(HttpMethod.Post, uri) { Version = UseVersion }; + initialMessage.Content = new ThrowingContent(() => new ThrowingContentException()); + initialMessage.Headers.ExpectContinue = true; + Exception exception = await Assert.ThrowsAsync(() => client.SendAsync(TestAsync, initialMessage)); + + clientFinished.SetResult(true); + } + }, async server => + { + await server.AcceptConnectionAsync(async connection => + { + try + { + await connection.ReadRequestDataAsync(readBody: true); + } + catch { } // Eat errors from client disconnect. + await clientFinished.Task.TimeoutAfter(TimeSpan.FromMinutes(2)); + }); + }); + } + [Fact] public async Task SendAsync_No100ContinueReceived_RequestBodySentEventually() { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.cs b/src/libraries/Common/tests/System/Net/Http/ThrowingContent.cs similarity index 88% rename from src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.cs rename to src/libraries/Common/tests/System/Net/Http/ThrowingContent.cs index 276570552bd1..8b757e8830ea 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.cs +++ b/src/libraries/Common/tests/System/Net/Http/ThrowingContent.cs @@ -10,7 +10,7 @@ namespace System.Net.Http.Functional.Tests { /// HttpContent that mocks exceptions on serialization. - public class ThrowingContent : HttpContent + public partial class ThrowingContent : HttpContent { private readonly Func _exnFactory; private readonly int _length; @@ -32,4 +32,7 @@ protected override bool TryComputeLength(out long length) return true; } } + + public class ThrowingContentException : Exception + { } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj index b1dbc739244a..1d0dceca18b3 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj @@ -129,6 +129,8 @@ Link="Common\System\Net\Http\SchSendAuxRecordHttpTest.cs" /> + SendAsync(HttpRequestMess if (requestBodyTask.IsCompleted || duplex == false || await Task.WhenAny(requestBodyTask, responseHeadersTask).ConfigureAwait(false) == requestBodyTask || - requestBodyTask.IsCompleted) + requestBodyTask.IsCompleted || + http2Stream.SendRequestFinished) { // The sending of the request body completed before receiving all of the request headers (or we're // ok waiting for the request body even if it hasn't completed, e.g. because we're not doing duplex). 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 f9cee658c61e..5ac829bbe3dc 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 @@ -145,6 +145,8 @@ public void Initialize(int streamId, int initialWindowSize) public int StreamId { get; private set; } + public bool SendRequestFinished => _requestCompletionState != StreamCompletionState.InProgress; + public HttpResponseMessage GetAndClearResponse() { // Once SendAsync completes, the Http2Stream should no longer hold onto the response message. 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 4a9485a47242..780212df7806 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 @@ -692,6 +692,21 @@ public async Task SendAsyncCore(HttpRequestMessage request, // hook up a continuation that will log it. if (sendRequestContentTask != null && !sendRequestContentTask.IsCompletedSuccessfully) { + // In case the connection is disposed, it's most probable that + // expect100Continue timer expired and request content sending failed. + // We're awaiting the task to propagate the exception in this case. + if (Volatile.Read(ref _disposed) == 1) + { + if (async) + { + await sendRequestContentTask.ConfigureAwait(false); + } + else + { + // No way around it here if we want to get the exception from the task. + sendRequestContentTask.GetAwaiter().GetResult(); + } + } LogExceptions(sendRequestContentTask); } @@ -793,7 +808,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http } private async Task SendRequestContentWithExpect100ContinueAsync( - HttpRequestMessage request, Task allowExpect100ToContinueTask, HttpContentWriteStream stream, Timer expect100Timer, bool async, CancellationToken cancellationToken) + HttpRequestMessage request, Task allowExpect100ToContinueTask, + HttpContentWriteStream stream, Timer expect100Timer, bool async, CancellationToken cancellationToken) { // Wait until we receive a trigger notification that it's ok to continue sending content. // This will come either when the timer fires or when we receive a response status line from the server. @@ -806,7 +822,17 @@ private async Task SendRequestContentWithExpect100ContinueAsync( if (sendRequestContent) { if (NetEventSource.Log.IsEnabled()) Trace($"Sending request content for Expect: 100-continue."); - await SendRequestContentAsync(request, stream, async, cancellationToken).ConfigureAwait(false); + try + { + await SendRequestContentAsync(request, stream, async, cancellationToken).ConfigureAwait(false); + } + catch + { + // Tear down the connection if called from the timer thread because caller's thread will wait for server status line indefinitely + // or till HttpClient.Timeout tear the connection itself. + Dispose(); + throw; + } } else { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index dc5bc00ef6ad..2e00a8921702 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -179,7 +179,6 @@ - @@ -227,7 +226,9 @@ Link="Common\System\Net\Http\SyncBlockingContent.cs" /> - + + diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.netcore.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.netcore.cs new file mode 100644 index 000000000000..8f4fd4724770 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/ThrowingContent.netcore.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Http.Functional.Tests +{ + public partial class ThrowingContent : HttpContent + { + protected override void SerializeToStream(Stream stream, TransportContext context, CancellationToken cancellationToken) + { + throw _exnFactory(); + } + } +} From a9009db46e315d0eb862c6925cca19798b947163 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Tue, 28 Jul 2020 18:04:00 +0300 Subject: [PATCH 092/755] Annotate System.ComponentModel.DataAnnotations for nullability (#39611) --- .../ref/System.ComponentModel.Annotations.cs | 155 +++++++++--------- .../System.ComponentModel.Annotations.csproj | 1 + .../System.ComponentModel.Annotations.csproj | 1 + ...atedMetadataTypeTypeDescriptionProvider.cs | 3 + .../AssociatedMetadataTypeTypeDescriptor.cs | 3 + .../DataAnnotations/AssociationAttribute.cs | 2 +- .../DataAnnotations/CompareAttribute.cs | 12 +- .../DataAnnotations/CreditCardAttribute.cs | 2 +- .../CustomValidationAttribute.cs | 34 ++-- .../DataAnnotations/DataTypeAttribute.cs | 8 +- .../DataAnnotations/DisplayAttribute.cs | 24 +-- .../DataAnnotations/DisplayColumnAttribute.cs | 6 +- .../DataAnnotations/DisplayFormatAttribute.cs | 8 +- .../DataAnnotations/EmailAddressAttribute.cs | 2 +- .../DataAnnotations/EnumDataTypeAttribute.cs | 8 +- .../FileExtensionsAttribute.cs | 4 +- .../DataAnnotations/FilterUIHintAttribute.cs | 12 +- .../DataAnnotations/LocalizableString.cs | 14 +- .../DataAnnotations/MaxLengthAttribute.cs | 6 +- .../DataAnnotations/MinLengthAttribute.cs | 2 +- .../DataAnnotations/PhoneAttribute.cs | 2 +- .../DataAnnotations/RangeAttribute.cs | 12 +- .../RegularExpressionAttribute.cs | 8 +- .../DataAnnotations/RequiredAttribute.cs | 2 +- .../DataAnnotations/Schema/ColumnAttribute.cs | 8 +- .../DataAnnotations/Schema/TableAttribute.cs | 6 +- .../DataAnnotations/StringLengthAttribute.cs | 2 +- .../DataAnnotations/UIHintAttribute.cs | 43 ++--- .../DataAnnotations/UrlAttribute.cs | 2 +- .../DataAnnotations/ValidationAttribute.cs | 49 +++--- .../ValidationAttributeStore.cs | 25 +-- .../DataAnnotations/ValidationContext.cs | 26 +-- .../DataAnnotations/ValidationException.cs | 16 +- .../DataAnnotations/ValidationResult.cs | 10 +- .../DataAnnotations/Validator.cs | 48 +++--- 35 files changed, 297 insertions(+), 269 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs index 1747a8cacd99..4db1cfdddce9 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs @@ -6,12 +6,15 @@ namespace System.ComponentModel.DataAnnotations { +// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated +#nullable disable public partial class AssociatedMetadataTypeTypeDescriptionProvider : System.ComponentModel.TypeDescriptionProvider { public AssociatedMetadataTypeTypeDescriptionProvider(System.Type type) { } public AssociatedMetadataTypeTypeDescriptionProvider(System.Type type, System.Type associatedMetadataType) { } public override System.ComponentModel.ICustomTypeDescriptor GetTypeDescriptor(System.Type objectType, object instance) { throw null; } } +#nullable enable [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] [System.ObsoleteAttribute("This attribute is no longer in use and will be ignored if applied.")] public sealed partial class AssociationAttribute : System.Attribute @@ -29,7 +32,7 @@ public partial class CompareAttribute : System.ComponentModel.DataAnnotations.Va { public CompareAttribute(string otherProperty) { } public string OtherProperty { get { throw null; } } - public string OtherPropertyDisplayName { get { throw null; } } + public string? OtherPropertyDisplayName { get { throw null; } } public override bool RequiresValidationContext { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } @@ -43,7 +46,7 @@ public ConcurrencyCheckAttribute() { } public sealed partial class CreditCardAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public CreditCardAttribute() : base (default(System.ComponentModel.DataAnnotations.DataType)) { } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=true)] public sealed partial class CustomValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute @@ -52,7 +55,7 @@ public CustomValidationAttribute(System.Type validatorType, string method) { } public string Method { get { throw null; } } public System.Type ValidatorType { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } - protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } + protected override System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } } public enum DataType { @@ -79,11 +82,11 @@ public partial class DataTypeAttribute : System.ComponentModel.DataAnnotations.V { public DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType dataType) { } public DataTypeAttribute(string customDataType) { } - public string CustomDataType { get { throw null; } } + public string? CustomDataType { get { throw null; } } public System.ComponentModel.DataAnnotations.DataType DataType { get { throw null; } } - public System.ComponentModel.DataAnnotations.DisplayFormatAttribute DisplayFormat { get { throw null; } protected set { } } + public System.ComponentModel.DataAnnotations.DisplayFormatAttribute? DisplayFormat { get { throw null; } protected set { } } public virtual string GetDataTypeName() { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class DisplayAttribute : System.Attribute @@ -91,30 +94,30 @@ public sealed partial class DisplayAttribute : System.Attribute public DisplayAttribute() { } public bool AutoGenerateField { get { throw null; } set { } } public bool AutoGenerateFilter { get { throw null; } set { } } - public string Description { get { throw null; } set { } } - public string GroupName { get { throw null; } set { } } - public string Name { get { throw null; } set { } } + public string? Description { get { throw null; } set { } } + public string? GroupName { get { throw null; } set { } } + public string? Name { get { throw null; } set { } } public int Order { get { throw null; } set { } } - public string Prompt { get { throw null; } set { } } - public System.Type ResourceType { get { throw null; } set { } } - public string ShortName { get { throw null; } set { } } + public string? Prompt { get { throw null; } set { } } + public System.Type? ResourceType { get { throw null; } set { } } + public string? ShortName { get { throw null; } set { } } public bool? GetAutoGenerateField() { throw null; } public bool? GetAutoGenerateFilter() { throw null; } public string GetDescription() { throw null; } - public string GetGroupName() { throw null; } - public string GetName() { throw null; } + public string? GetGroupName() { throw null; } + public string? GetName() { throw null; } public int? GetOrder() { throw null; } - public string GetPrompt() { throw null; } - public string GetShortName() { throw null; } + public string? GetPrompt() { throw null; } + public string? GetShortName() { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, Inherited=true, AllowMultiple=false)] public partial class DisplayColumnAttribute : System.Attribute { public DisplayColumnAttribute(string displayColumn) { } - public DisplayColumnAttribute(string displayColumn, string sortColumn) { } - public DisplayColumnAttribute(string displayColumn, string sortColumn, bool sortDescending) { } + public DisplayColumnAttribute(string displayColumn, string? sortColumn) { } + public DisplayColumnAttribute(string displayColumn, string? sortColumn, bool sortDescending) { } public string DisplayColumn { get { throw null; } } - public string SortColumn { get { throw null; } } + public string? SortColumn { get { throw null; } } public bool SortDescending { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] @@ -123,11 +126,11 @@ public partial class DisplayFormatAttribute : System.Attribute public DisplayFormatAttribute() { } public bool ApplyFormatInEditMode { get { throw null; } set { } } public bool ConvertEmptyStringToNull { get { throw null; } set { } } - public string DataFormatString { get { throw null; } set { } } + public string? DataFormatString { get { throw null; } set { } } public bool HtmlEncode { get { throw null; } set { } } - public string NullDisplayText { get { throw null; } set { } } - public System.Type NullDisplayTextResourceType { get { throw null; } set { } } - public string GetNullDisplayText() { throw null; } + public string? NullDisplayText { get { throw null; } set { } } + public System.Type? NullDisplayTextResourceType { get { throw null; } set { } } + public string? GetNullDisplayText() { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public sealed partial class EditableAttribute : System.Attribute @@ -140,14 +143,14 @@ public EditableAttribute(bool allowEdit) { } public sealed partial class EmailAddressAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public EmailAddressAttribute() : base (default(System.ComponentModel.DataAnnotations.DataType)) { } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class EnumDataTypeAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public EnumDataTypeAttribute(System.Type enumType) : base (default(System.ComponentModel.DataAnnotations.DataType)) { } public System.Type EnumType { get { throw null; } } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class FileExtensionsAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute @@ -155,19 +158,19 @@ public sealed partial class FileExtensionsAttribute : System.ComponentModel.Data public FileExtensionsAttribute() : base (default(System.ComponentModel.DataAnnotations.DataType)) { } public string Extensions { get { throw null; } set { } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] [System.ObsoleteAttribute("This attribute is no longer in use and will be ignored if applied.")] public sealed partial class FilterUIHintAttribute : System.Attribute { public FilterUIHintAttribute(string filterUIHint) { } - public FilterUIHintAttribute(string filterUIHint, string presentationLayer) { } - public FilterUIHintAttribute(string filterUIHint, string presentationLayer, params object[] controlParameters) { } + public FilterUIHintAttribute(string filterUIHint, string? presentationLayer) { } + public FilterUIHintAttribute(string filterUIHint, string? presentationLayer, params object[] controlParameters) { } public System.Collections.Generic.IDictionary ControlParameters { get { throw null; } } public string FilterUIHint { get { throw null; } } - public string PresentationLayer { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public string? PresentationLayer { get { throw null; } } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } } public partial interface IValidatableObject @@ -186,7 +189,7 @@ public MaxLengthAttribute() { } public MaxLengthAttribute(int length) { } public int Length { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false)] public sealed partial class MetadataTypeAttribute : System.Attribute @@ -200,13 +203,13 @@ public partial class MinLengthAttribute : System.ComponentModel.DataAnnotations. public MinLengthAttribute(int length) { } public int Length { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class PhoneAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public PhoneAttribute() : base (default(System.ComponentModel.DataAnnotations.DataType)) { } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public partial class RangeAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute @@ -220,7 +223,7 @@ public RangeAttribute(System.Type type, string minimum, string maximum) { } public System.Type OperandType { get { throw null; } } public bool ParseLimitsInInvariantCulture { get { throw null; } set { } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public partial class RegularExpressionAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute @@ -229,14 +232,14 @@ public RegularExpressionAttribute(string pattern) { } public int MatchTimeoutInMilliseconds { get { throw null; } set { } } public string Pattern { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public partial class RequiredAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public RequiredAttribute() { } public bool AllowEmptyStrings { get { throw null; } set { } } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] public partial class ScaffoldColumnAttribute : System.Attribute @@ -251,7 +254,7 @@ public StringLengthAttribute(int maximumLength) { } public int MaximumLength { get { throw null; } } public int MinimumLength { get { throw null; } set { } } public override string FormatErrorMessage(string name) { throw null; } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public sealed partial class TimestampAttribute : System.Attribute @@ -262,81 +265,81 @@ public TimestampAttribute() { } public partial class UIHintAttribute : System.Attribute { public UIHintAttribute(string uiHint) { } - public UIHintAttribute(string uiHint, string presentationLayer) { } - public UIHintAttribute(string uiHint, string presentationLayer, params object[] controlParameters) { } - public System.Collections.Generic.IDictionary ControlParameters { get { throw null; } } - public string PresentationLayer { get { throw null; } } + public UIHintAttribute(string uiHint, string? presentationLayer) { } + public UIHintAttribute(string uiHint, string? presentationLayer, params object?[]? controlParameters) { } + public System.Collections.Generic.IDictionary ControlParameters { get { throw null; } } + public string? PresentationLayer { get { throw null; } } public string UIHint { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class UrlAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public UrlAttribute() : base (default(System.ComponentModel.DataAnnotations.DataType)) { } - public override bool IsValid(object value) { throw null; } + public override bool IsValid(object? value) { throw null; } } public abstract partial class ValidationAttribute : System.Attribute { protected ValidationAttribute() { } protected ValidationAttribute(System.Func errorMessageAccessor) { } protected ValidationAttribute(string errorMessage) { } - public string ErrorMessage { get { throw null; } set { } } - public string ErrorMessageResourceName { get { throw null; } set { } } - public System.Type ErrorMessageResourceType { get { throw null; } set { } } + public string? ErrorMessage { get { throw null; } set { } } + public string? ErrorMessageResourceName { get { throw null; } set { } } + public System.Type? ErrorMessageResourceType { get { throw null; } set { } } protected string ErrorMessageString { get { throw null; } } public virtual bool RequiresValidationContext { get { throw null; } } public virtual string FormatErrorMessage(string name) { throw null; } - public System.ComponentModel.DataAnnotations.ValidationResult GetValidationResult(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } - public virtual bool IsValid(object value) { throw null; } - protected virtual System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } - public void Validate(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } - public void Validate(object value, string name) { } + public System.ComponentModel.DataAnnotations.ValidationResult? GetValidationResult(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } + public virtual bool IsValid(object? value) { throw null; } + protected virtual System.ComponentModel.DataAnnotations.ValidationResult IsValid(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { throw null; } + public void Validate(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } + public void Validate(object? value, string name) { } } public sealed partial class ValidationContext : System.IServiceProvider { public ValidationContext(object instance) { } - public ValidationContext(object instance, System.Collections.Generic.IDictionary items) { } - public ValidationContext(object instance, System.IServiceProvider serviceProvider, System.Collections.Generic.IDictionary items) { } + public ValidationContext(object instance, System.Collections.Generic.IDictionary? items) { } + public ValidationContext(object instance, System.IServiceProvider? serviceProvider, System.Collections.Generic.IDictionary? items) { } public string DisplayName { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Items { get { throw null; } } - public string MemberName { get { throw null; } set { } } + public System.Collections.Generic.IDictionary Items { get { throw null; } } + public string? MemberName { get { throw null; } set { } } public object ObjectInstance { get { throw null; } } public System.Type ObjectType { get { throw null; } } - public object GetService(System.Type serviceType) { throw null; } - public void InitializeServiceProvider(System.Func serviceProvider) { } + public object? GetService(System.Type serviceType) { throw null; } + public void InitializeServiceProvider(System.Func serviceProvider) { } } public partial class ValidationException : System.Exception { public ValidationException() { } - public ValidationException(System.ComponentModel.DataAnnotations.ValidationResult validationResult, System.ComponentModel.DataAnnotations.ValidationAttribute validatingAttribute, object value) { } + public ValidationException(System.ComponentModel.DataAnnotations.ValidationResult validationResult, System.ComponentModel.DataAnnotations.ValidationAttribute? validatingAttribute, object? value) { } protected ValidationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public ValidationException(string message) { } - public ValidationException(string errorMessage, System.ComponentModel.DataAnnotations.ValidationAttribute validatingAttribute, object value) { } - public ValidationException(string message, System.Exception innerException) { } - public System.ComponentModel.DataAnnotations.ValidationAttribute ValidationAttribute { get { throw null; } } + public ValidationException(string? message) { } + public ValidationException(string? errorMessage, System.ComponentModel.DataAnnotations.ValidationAttribute? validatingAttribute, object? value) { } + public ValidationException(string? message, System.Exception? innerException) { } + public System.ComponentModel.DataAnnotations.ValidationAttribute? ValidationAttribute { get { throw null; } } public System.ComponentModel.DataAnnotations.ValidationResult ValidationResult { get { throw null; } } - public object Value { get { throw null; } } + public object? Value { get { throw null; } } } public partial class ValidationResult { - public static readonly System.ComponentModel.DataAnnotations.ValidationResult Success; + public static readonly System.ComponentModel.DataAnnotations.ValidationResult? Success; protected ValidationResult(System.ComponentModel.DataAnnotations.ValidationResult validationResult) { } - public ValidationResult(string errorMessage) { } - public ValidationResult(string errorMessage, System.Collections.Generic.IEnumerable memberNames) { } - public string ErrorMessage { get { throw null; } set { } } + public ValidationResult(string? errorMessage) { } + public ValidationResult(string? errorMessage, System.Collections.Generic.IEnumerable? memberNames) { } + public string? ErrorMessage { get { throw null; } set { } } public System.Collections.Generic.IEnumerable MemberNames { get { throw null; } } public override string ToString() { throw null; } } public static partial class Validator { - public static bool TryValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection validationResults) { throw null; } - public static bool TryValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection validationResults, bool validateAllProperties) { throw null; } - public static bool TryValidateProperty(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection validationResults) { throw null; } - public static bool TryValidateValue(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection validationResults, System.Collections.Generic.IEnumerable validationAttributes) { throw null; } + public static bool TryValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults) { throw null; } + public static bool TryValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults, bool validateAllProperties) { throw null; } + public static bool TryValidateProperty(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults) { throw null; } + public static bool TryValidateValue(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults, System.Collections.Generic.IEnumerable validationAttributes) { throw null; } public static void ValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } public static void ValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, bool validateAllProperties) { } - public static void ValidateProperty(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } + public static void ValidateProperty(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } public static void ValidateValue(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.IEnumerable validationAttributes) { } } } @@ -347,9 +350,10 @@ public partial class ColumnAttribute : System.Attribute { public ColumnAttribute() { } public ColumnAttribute(string name) { } - public string Name { get { throw null; } } + public string? Name { get { throw null; } } public int Order { get { throw null; } set { } } - public string TypeName { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public string? TypeName { get { throw null; } set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false)] public partial class ComplexTypeAttribute : System.Attribute @@ -390,6 +394,7 @@ public partial class TableAttribute : System.Attribute { public TableAttribute(string name) { } public string Name { get { throw null; } } - public string Schema { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public string? Schema { get { throw null; } set { } } } } diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.csproj b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.csproj index 733060bf78e3..fdedddfbbdb2 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.csproj +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.csproj @@ -1,6 +1,7 @@ netstandard2.1 + enable diff --git a/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj b/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj index e871a28c7c0e..8e376bbde0ac 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj +++ b/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj @@ -1,6 +1,7 @@ netstandard2.1 + enable diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptionProvider.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptionProvider.cs index b0ca16061661..fc7b7e456b9b 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptionProvider.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptionProvider.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated +#nullable disable + namespace System.ComponentModel.DataAnnotations { /// diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptor.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptor.cs index 7ce7d3aecd9e..2bc82d50a6e3 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociatedMetadataTypeTypeDescriptor.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +// TODO-NULLABLE: Enable after System.ComponentModel.TypeDescriptionProvider is annotated +#nullable disable + using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociationAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociationAttribute.cs index 2276b3f33f66..41078c03f419 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociationAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/AssociationAttribute.cs @@ -68,7 +68,7 @@ public AssociationAttribute(string name, string thisKey, string otherKey) /// /// The key to parse /// Array of individual key members - private static string[] GetKeyMembers(string key) + private static string[] GetKeyMembers(string? key) { if (key == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CompareAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CompareAttribute.cs index 5b8ab828f6ee..dab56c6018e6 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CompareAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CompareAttribute.cs @@ -17,7 +17,7 @@ public CompareAttribute(string otherProperty) : base(SR.CompareAttribute_MustMat public string OtherProperty { get; } - public string OtherPropertyDisplayName { get; internal set; } + public string? OtherPropertyDisplayName { get; internal set; } public override bool RequiresValidationContext => true; @@ -25,7 +25,7 @@ public override string FormatErrorMessage(string name) => string.Format( CultureInfo.CurrentCulture, ErrorMessageString, name, OtherPropertyDisplayName ?? OtherProperty); - protected override ValidationResult IsValid(object value, ValidationContext validationContext) + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { var otherPropertyInfo = validationContext.ObjectType.GetRuntimeProperty(OtherProperty); if (otherPropertyInfo == null) @@ -37,7 +37,7 @@ protected override ValidationResult IsValid(object value, ValidationContext vali throw new ArgumentException(SR.Format(SR.Common_PropertyNotFound, validationContext.ObjectType.FullName, OtherProperty)); } - object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); + object? otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); if (!Equals(value, otherPropertyValue)) { if (OtherPropertyDisplayName == null) @@ -45,7 +45,7 @@ protected override ValidationResult IsValid(object value, ValidationContext vali OtherPropertyDisplayName = GetDisplayNameForProperty(otherPropertyInfo); } - string[] memberNames = validationContext.MemberName != null + string[]? memberNames = validationContext.MemberName != null ? new[] { validationContext.MemberName } : null; return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); @@ -54,12 +54,14 @@ protected override ValidationResult IsValid(object value, ValidationContext vali return null; } - private string GetDisplayNameForProperty(PropertyInfo property) + private string? GetDisplayNameForProperty(PropertyInfo property) { var attributes = CustomAttributeExtensions.GetCustomAttributes(property, true); var display = attributes.OfType().FirstOrDefault(); if (display != null) { + // TODO-NULLABLE: This will return null if [DisplayName] is specified but no Name has been defined - probably a bug. + // Should fall back to OtherProperty in this case instead. return display.GetName(); } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CreditCardAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CreditCardAttribute.cs index a9a5aea98dbc..4715007eaf8b 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CreditCardAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CreditCardAttribute.cs @@ -15,7 +15,7 @@ public CreditCardAttribute() DefaultErrorMessage = SR.CreditCardAttribute_Invalid; } - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (value == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CustomValidationAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CustomValidationAttribute.cs index 58b8a01e72a8..67c7077102be 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CustomValidationAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/CustomValidationAttribute.cs @@ -58,12 +58,12 @@ public sealed class CustomValidationAttribute : ValidationAttribute { #region Member Fields - private readonly Lazy _malformedErrorMessage; + private readonly Lazy _malformedErrorMessage; private bool _isSingleArgumentMethod; - private string _lastMessage; - private MethodInfo _methodInfo; - private Type _firstParameterType; - private Tuple _typeId; + private string? _lastMessage; + private MethodInfo? _methodInfo; + private Type? _firstParameterType; + private Tuple? _typeId; #endregion @@ -88,7 +88,7 @@ public CustomValidationAttribute(Type validatorType, string method) { ValidatorType = validatorType; Method = method; - _malformedErrorMessage = new Lazy(CheckAttributeWellFormed); + _malformedErrorMessage = new Lazy(CheckAttributeWellFormed); } #endregion @@ -143,7 +143,7 @@ public override bool RequiresValidationContext /// /// Whatever the in returns. /// is thrown if the current attribute is malformed. - protected override ValidationResult IsValid(object value, ValidationContext validationContext) + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { // If attribute is not valid, throw an exception right away to inform the developer ThrowIfAttributeNotWellFormed(); @@ -153,7 +153,7 @@ protected override ValidationResult IsValid(object value, ValidationContext vali // If the value is not of the correct type and cannot be converted, fail // to indicate it is not acceptable. The convention is that IsValid is merely a probe, // and clients are not expecting exceptions. - object convertedValue; + object? convertedValue; if (!TryConvertValue(value, out convertedValue)) { return new ValidationResult(SR.Format(SR.CustomValidationAttribute_Type_Conversion_Failed, @@ -171,10 +171,10 @@ protected override ValidationResult IsValid(object value, ValidationContext vali // 1-parameter form is ValidationResult Method(object value) // 2-parameter form is ValidationResult Method(object value, ValidationContext context), var methodParams = _isSingleArgumentMethod - ? new object[] { convertedValue } + ? new object?[] { convertedValue } : new[] { convertedValue, validationContext }; - var result = (ValidationResult)methodInfo.Invoke(null, methodParams); + var result = (ValidationResult?)methodInfo!.Invoke(null, methodParams); // We capture the message they provide us only in the event of failure, // otherwise we use the normal message supplied via the ctor @@ -189,7 +189,7 @@ protected override ValidationResult IsValid(object value, ValidationContext vali } catch (TargetInvocationException tie) { - throw tie.InnerException; + throw tie.InnerException!; } } @@ -217,13 +217,13 @@ public override string FormatErrorMessage(string name) /// Checks whether the current attribute instance itself is valid for use. /// /// The error message why it is not well-formed, null if it is well-formed. - private string CheckAttributeWellFormed() => ValidateValidatorTypeParameter() ?? ValidateMethodParameter(); + private string? CheckAttributeWellFormed() => ValidateValidatorTypeParameter() ?? ValidateMethodParameter(); /// /// Internal helper to determine whether is legal for use. /// /// null or the appropriate error message. - private string ValidateValidatorTypeParameter() + private string? ValidateValidatorTypeParameter() { if (ValidatorType == null) { @@ -242,7 +242,7 @@ private string ValidateValidatorTypeParameter() /// Internal helper to determine whether is legal for use. /// /// null or the appropriate error message. - private string ValidateMethodParameter() + private string? ValidateMethodParameter() { if (string.IsNullOrEmpty(Method)) { @@ -295,7 +295,7 @@ private string ValidateMethodParameter() /// private void ThrowIfAttributeNotWellFormed() { - string errorMessage = _malformedErrorMessage.Value; + string? errorMessage = _malformedErrorMessage.Value; if (errorMessage != null) { throw new InvalidOperationException(errorMessage); @@ -309,10 +309,10 @@ private void ThrowIfAttributeNotWellFormed() /// The value to check/convert. /// If successful, the converted (or copied) value. /// true if type value was already correct or was successfully converted. - private bool TryConvertValue(object value, out object convertedValue) + private bool TryConvertValue(object? value, out object? convertedValue) { convertedValue = null; - var expectedValueType = _firstParameterType; + var expectedValueType = _firstParameterType!; // Null is permitted for reference types or for Nullable<>'s only if (value == null) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs index 443b3b777aca..d6ea70b7c8fd 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs @@ -67,12 +67,12 @@ public DataTypeAttribute(string customDataType) /// Gets the string representing a custom data type. Returns a non-null value only if is /// DataType.Custom. /// - public string CustomDataType { get; } + public string? CustomDataType { get; } /// /// Gets the default display format that gets used along with this DataType. /// - public DisplayFormatAttribute DisplayFormat { get; protected set; } + public DisplayFormatAttribute? DisplayFormat { get; protected set; } /// /// Return the name of the data type, either using the enum or @@ -87,7 +87,7 @@ public virtual string GetDataTypeName() if (DataType == DataType.Custom) { // If it's a custom type string, use it as the template name - return CustomDataType; + return CustomDataType!; } // If it's an enum, turn it into a string // Use the cached array with enum string values instead of ToString() as the latter is too slow @@ -101,7 +101,7 @@ public virtual string GetDataTypeName() /// The value to validate /// Unconditionally returns true /// is thrown if the current attribute is ill-formed. - public override bool IsValid(object value) + public override bool IsValid(object? value) { EnsureValidDataType(); diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayAttribute.cs index 0b6d9a952438..2d8b11f00b31 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayAttribute.cs @@ -25,7 +25,7 @@ public sealed class DisplayAttribute : Attribute private bool? _autoGenerateField; private bool? _autoGenerateFilter; private int? _order; - private Type _resourceType; + private Type? _resourceType; #endregion @@ -54,7 +54,7 @@ public sealed class DisplayAttribute : Attribute /// The short name is generally used as the grid column label for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// - public string ShortName + public string? ShortName { get => _shortName.Value; set => _shortName.Value = value; @@ -79,7 +79,7 @@ public string ShortName /// The name is generally used as the field label for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// - public string Name + public string? Name { get => _name.Value; set => _name.Value = value; @@ -104,7 +104,7 @@ public string Name /// Description is generally used as a tool tip or description a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// - public string Description + public string? Description { get => _description.Value; set => _description.Value = value; @@ -129,7 +129,7 @@ public string Description /// A prompt is generally used as a prompt or watermark for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// - public string Prompt + public string? Prompt { get => _prompt.Value; set => _prompt.Value = value; @@ -154,7 +154,7 @@ public string Prompt /// A group name is used for grouping fields into the UI. A null or empty string is legal, /// and consumers must allow for that. /// - public string GroupName + public string? GroupName { get => _groupName.Value; set => _groupName.Value = value; @@ -167,7 +167,7 @@ public string GroupName /// , , , and /// methods to return localized values. /// - public Type ResourceType + public Type? ResourceType { get => _resourceType; set @@ -298,7 +298,7 @@ public int Order /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetShortName() => _shortName.GetLocalizableValue() ?? GetName(); + public string? GetShortName() => _shortName.GetLocalizableValue() ?? GetName(); /// /// Gets the UI display string for Name. @@ -325,7 +325,7 @@ public int Order /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetName() => _name.GetLocalizableValue(); + public string? GetName() => _name.GetLocalizableValue(); /// /// Gets the UI display string for Description. @@ -348,7 +348,7 @@ public int Order /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetDescription() => _description.GetLocalizableValue(); + public string? GetDescription() => _description.GetLocalizableValue(); /// /// Gets the UI display string for Prompt. @@ -371,7 +371,7 @@ public int Order /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetPrompt() => _prompt.GetLocalizableValue(); + public string? GetPrompt() => _prompt.GetLocalizableValue(); /// /// Gets the UI display string for GroupName. @@ -394,7 +394,7 @@ public int Order /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetGroupName() => _groupName.GetLocalizableValue(); + public string? GetGroupName() => _groupName.GetLocalizableValue(); /// /// Gets the value of if it has been set, or null. diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayColumnAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayColumnAttribute.cs index 1ed02dfe8745..d13f5cda2268 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayColumnAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayColumnAttribute.cs @@ -15,12 +15,12 @@ public DisplayColumnAttribute(string displayColumn) { } - public DisplayColumnAttribute(string displayColumn, string sortColumn) + public DisplayColumnAttribute(string displayColumn, string? sortColumn) : this(displayColumn, sortColumn, false) { } - public DisplayColumnAttribute(string displayColumn, string sortColumn, bool sortDescending) + public DisplayColumnAttribute(string displayColumn, string? sortColumn, bool sortDescending) { DisplayColumn = displayColumn; SortColumn = sortColumn; @@ -29,7 +29,7 @@ public DisplayColumnAttribute(string displayColumn, string sortColumn, bool sort public string DisplayColumn { get; } - public string SortColumn { get; } + public string? SortColumn { get; } public bool SortDescending { get; } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayFormatAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayFormatAttribute.cs index 76b7a8b525c4..96a82b04120e 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayFormatAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DisplayFormatAttribute.cs @@ -25,7 +25,7 @@ public DisplayFormatAttribute() /// /// Gets or sets the format string /// - public string DataFormatString { get; set; } + public string? DataFormatString { get; set; } /// /// Gets or sets the string to display when the value is null, which may be a resource key string. @@ -46,7 +46,7 @@ public DisplayFormatAttribute() /// The null display text is generally used as placeholder when the value is not specified. /// A null or empty string is legal, and consumers must allow for that. /// - public string NullDisplayText + public string? NullDisplayText { get => _nullDisplayText.Value; set => _nullDisplayText.Value = value; @@ -72,7 +72,7 @@ public string NullDisplayText /// Using along with , allows the /// method to return localized values. /// - public Type NullDisplayTextResourceType + public Type? NullDisplayTextResourceType { get => _nullDisplayText.ResourceType; set => _nullDisplayText.ResourceType = value; @@ -102,6 +102,6 @@ public Type NullDisplayTextResourceType /// but a public static property with a name matching the value couldn't be found /// on the . /// - public string GetNullDisplayText() => _nullDisplayText.GetLocalizableValue(); + public string? GetNullDisplayText() => _nullDisplayText.GetLocalizableValue(); } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs index eba694c990e2..2e28b0cb6ac3 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs @@ -15,7 +15,7 @@ public EmailAddressAttribute() DefaultErrorMessage = SR.EmailAddressAttribute_Invalid; } - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (value == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EnumDataTypeAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EnumDataTypeAttribute.cs index ba0a48e37c48..18dd723deb30 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EnumDataTypeAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EnumDataTypeAttribute.cs @@ -20,7 +20,7 @@ public EnumDataTypeAttribute(Type enumType) public Type EnumType { get; } - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (EnumType == null) { @@ -91,8 +91,8 @@ public override bool IsValid(object value) // If it is, the string representation of the enum value will be something like "A, B", while // the string representation of the underlying value will be "3". If the enum value does not // match a valid flag combination, then it would also be something like "3". - string underlying = GetUnderlyingTypeValueString(EnumType, convertedValue); - string converted = convertedValue.ToString(); + string underlying = GetUnderlyingTypeValueString(EnumType, convertedValue)!; + string? converted = convertedValue.ToString(); return !underlying.Equals(converted); } @@ -102,7 +102,7 @@ public override bool IsValid(object value) private static bool IsEnumTypeInFlagsMode(Type enumType) => enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any(); - private static string GetUnderlyingTypeValueString(Type enumType, object enumValue) => + private static string? GetUnderlyingTypeValueString(Type enumType, object enumValue) => Convert.ChangeType(enumValue, Enum.GetUnderlyingType(enumType), CultureInfo.InvariantCulture).ToString(); } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FileExtensionsAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FileExtensionsAttribute.cs index df2f1fc2add1..e66e2807e51a 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FileExtensionsAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FileExtensionsAttribute.cs @@ -12,7 +12,7 @@ namespace System.ComponentModel.DataAnnotations AllowMultiple = false)] public sealed class FileExtensionsAttribute : DataTypeAttribute { - private string _extensions; + private string? _extensions; public FileExtensionsAttribute() : base(DataType.Upload) @@ -42,7 +42,7 @@ private IEnumerable ExtensionsParsed public override string FormatErrorMessage(string name) => string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, ExtensionsFormatted); - public override bool IsValid(object value) => + public override bool IsValid(object? value) => value == null || value is string valueAsString && ValidateExtension(valueAsString); private bool ValidateExtension(string fileName) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FilterUIHintAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FilterUIHintAttribute.cs index e30b28383338..bb5138ef3900 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FilterUIHintAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/FilterUIHintAttribute.cs @@ -24,14 +24,14 @@ public sealed class FilterUIHintAttribute : Attribute /// Gets the name of the presentation layer that supports the control type /// in /// - public string PresentationLayer => _implementation.PresentationLayer; + public string? PresentationLayer => _implementation.PresentationLayer; /// /// Gets the name-value pairs used as parameters to the control's constructor /// /// is thrown if the current attribute /// is ill-formed. - public IDictionary ControlParameters => _implementation.ControlParameters; + public IDictionary ControlParameters => _implementation.ControlParameters; /// /// Constructor that accepts the name of the control, without specifying @@ -50,7 +50,7 @@ public FilterUIHintAttribute(string filterUIHint) /// The name of the control to use /// The name of the presentation layer that /// supports this control - public FilterUIHintAttribute(string filterUIHint, string presentationLayer) + public FilterUIHintAttribute(string filterUIHint, string? presentationLayer) : this(filterUIHint, presentationLayer, Array.Empty()) { } @@ -62,8 +62,8 @@ public FilterUIHintAttribute(string filterUIHint, string presentationLayer) /// The name of the control /// The presentation layer /// The list of parameters for the control - public FilterUIHintAttribute(string filterUIHint, string presentationLayer, - params object[] controlParameters) + public FilterUIHintAttribute(string filterUIHint, string? presentationLayer, + params object?[] controlParameters) { _implementation = new UIHintAttribute.UIHintImplementation( filterUIHint, presentationLayer, controlParameters); @@ -82,7 +82,7 @@ public FilterUIHintAttribute(string filterUIHint, string presentationLayer, /// An System.Object. /// true if obj is a FilterUIHintAttribute and its value is the same /// as this instance; otherwise, false. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FilterUIHintAttribute otherAttribute && _implementation.Equals(otherAttribute._implementation); } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/LocalizableString.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/LocalizableString.cs index a65becde4e64..5c8dfca6b56d 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/LocalizableString.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/LocalizableString.cs @@ -15,9 +15,9 @@ internal class LocalizableString #region Member fields private readonly string _propertyName; - private Func _cachedResult; - private string _propertyValue; - private Type _resourceType; + private Func? _cachedResult; + private string? _propertyValue; + private Type? _resourceType; #endregion @@ -46,7 +46,7 @@ public LocalizableString(string propertyName) /// either the literal, non-localized value, or it can be a resource name /// found on the resource type supplied to . /// - public string Value + public string? Value { get => _propertyValue; set @@ -62,7 +62,7 @@ public string Value /// /// Gets or sets the resource type to be used for localization. /// - public Type ResourceType + public Type? ResourceType { get => _resourceType; set @@ -108,7 +108,7 @@ private void ClearCache() /// /// Returns the potentially localized value. /// - public string GetLocalizableValue() + public string? GetLocalizableValue() { if (_cachedResult == null) { @@ -153,7 +153,7 @@ public string GetLocalizableValue() else { // We have a valid property, so cache the resource - _cachedResult = () => (string)property.GetValue(null, null); + _cachedResult = () => (string?)property!.GetValue(null, null); } } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MaxLengthAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MaxLengthAttribute.cs index 76d2e7407e7b..903112d41fa8 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MaxLengthAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MaxLengthAttribute.cs @@ -59,7 +59,7 @@ public MaxLengthAttribute() /// true if the value is null or less than or equal to the specified maximum length, otherwise false /// /// Length is zero or less than negative one. - public override bool IsValid(object value) + public override bool IsValid(object? value) { // Check the lengths for legality EnsureLegalLengths(); @@ -120,10 +120,10 @@ public static bool TryGetCount(object value, out int count) return true; } - PropertyInfo property = value.GetType().GetRuntimeProperty("Count"); + PropertyInfo? property = value.GetType().GetRuntimeProperty("Count"); if (property != null && property.CanRead && property.PropertyType == typeof(int)) { - count = (int)property.GetValue(value); + count = (int)property.GetValue(value)!; return true; } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MinLengthAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MinLengthAttribute.cs index 0b34a5f068c3..7b0e09f65905 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MinLengthAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MinLengthAttribute.cs @@ -43,7 +43,7 @@ public MinLengthAttribute(int length) /// false /// /// Length is less than zero. - public override bool IsValid(object value) + public override bool IsValid(object? value) { // Check the lengths for legality EnsureLegalLengths(); diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/PhoneAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/PhoneAttribute.cs index d264e5eeb2f6..cec872c27f4c 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/PhoneAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/PhoneAttribute.cs @@ -20,7 +20,7 @@ public PhoneAttribute() DefaultErrorMessage = SR.PhoneAttribute_Invalid; } - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (value == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs index 3e9bb7591d7a..a3b2e0b96c51 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs @@ -84,9 +84,9 @@ public RangeAttribute(Type type, string minimum, string maximum) /// parameters, for which the invariant culture is always used for any conversions of the validated value. public bool ConvertValueInInvariantCulture { get; set; } - private Func Conversion { get; set; } + private Func? Conversion { get; set; } - private void Initialize(IComparable minimum, IComparable maximum, Func conversion) + private void Initialize(IComparable minimum, IComparable maximum, Func conversion) { if (minimum.CompareTo(maximum) > 0) { @@ -104,7 +104,7 @@ private void Initialize(IComparable minimum, IComparable maximum, FuncThe value to test for validity. /// true means the is valid /// is thrown if the current attribute is ill-formed. - public override bool IsValid(object value) + public override bool IsValid(object? value) { // Validate our properties and create the conversion function SetupConversion(); @@ -115,11 +115,11 @@ public override bool IsValid(object value) return true; } - object convertedValue; + object? convertedValue; try { - convertedValue = Conversion(value); + convertedValue = Conversion!(value); } catch (FormatException) { @@ -207,7 +207,7 @@ private void SetupConversion() ? converter.ConvertFromInvariantString((string)maximum) : converter.ConvertFromString((string)maximum)); - Func conversion; + Func conversion; if (ConvertValueInInvariantCulture) { conversion = value => value.GetType() == type diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs index 79c1a7a945f7..e7f4eb1db432 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs @@ -35,7 +35,7 @@ public RegularExpressionAttribute(string pattern) /// public string Pattern { get; } - private Regex Regex { get; set; } + private Regex? Regex { get; set; } /// /// Override of @@ -47,12 +47,12 @@ public RegularExpressionAttribute(string pattern) /// true if the given value matches the current regular expression pattern /// is thrown if the current attribute is ill-formed. /// is thrown if the is not a valid regular expression. - public override bool IsValid(object value) + public override bool IsValid(object? value) { SetupRegex(); // Convert the value to a string - string stringValue = Convert.ToString(value, CultureInfo.CurrentCulture); + string? stringValue = Convert.ToString(value, CultureInfo.CurrentCulture); // Automatically pass if value is null or empty. RequiredAttribute should be used to assert a value is not empty. if (string.IsNullOrEmpty(stringValue)) @@ -60,7 +60,7 @@ public override bool IsValid(object value) return true; } - var m = Regex.Match(stringValue); + var m = Regex!.Match(stringValue); // We are looking for an exact match, not just a search hit. This matches what // the RegularExpressionValidator control does diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RequiredAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RequiredAttribute.cs index f7233499f959..a5003f0d2d31 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RequiredAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RequiredAttribute.cs @@ -36,7 +36,7 @@ public RequiredAttribute() /// /// then false is returned only if is null. /// - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (value == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/ColumnAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/ColumnAttribute.cs index d1e558389b12..f871d3d5c098 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/ColumnAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/ColumnAttribute.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.ComponentModel.DataAnnotations.Schema @@ -12,7 +13,7 @@ namespace System.ComponentModel.DataAnnotations.Schema public class ColumnAttribute : Attribute { private int _order = -1; - private string _typeName; + private string? _typeName; /// /// Initializes a new instance of the class. @@ -38,7 +39,7 @@ public ColumnAttribute(string name) /// /// The name of the column the property is mapped to. /// - public string Name { get; } + public string? Name { get; } /// /// The zero-based order of the column the property is mapped to. @@ -60,7 +61,8 @@ public int Order /// /// The database provider specific data type of the column the property is mapped to. /// - public string TypeName + [DisallowNull] + public string? TypeName { get => _typeName; set diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/TableAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/TableAttribute.cs index 911161490f90..489bf85830c8 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/TableAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Schema/TableAttribute.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.ComponentModel.DataAnnotations.Schema @@ -11,7 +12,7 @@ namespace System.ComponentModel.DataAnnotations.Schema [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class TableAttribute : Attribute { - private string _schema; + private string? _schema; /// /// Initializes a new instance of the class. @@ -35,7 +36,8 @@ public TableAttribute(string name) /// /// The schema of the table the class is mapped to. /// - public string Schema + [DisallowNull] + public string? Schema { get => _schema; set diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/StringLengthAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/StringLengthAttribute.cs index f6cb119e25e6..17e39eec4b3c 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/StringLengthAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/StringLengthAttribute.cs @@ -42,7 +42,7 @@ public StringLengthAttribute(int maximumLength) /// The value to test. /// true if the value is null or less than or equal to the set maximum length /// is thrown if the current attribute is ill-formed. - public override bool IsValid(object value) + public override bool IsValid(object? value) { // Check the lengths for legality EnsureLegalLengths(); diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UIHintAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UIHintAttribute.cs index 21de33d8d35a..f92ebaa75c10 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UIHintAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UIHintAttribute.cs @@ -42,7 +42,7 @@ public UIHintAttribute(string uiHint, string presentationLayer) /// The name of the control /// The presentation layer /// The list of parameters for the control - public UIHintAttribute(string uiHint, string presentationLayer, params object[] controlParameters) + public UIHintAttribute(string uiHint, string? presentationLayer, params object?[]? controlParameters) { _implementation = new UIHintImplementation(uiHint, presentationLayer, controlParameters); } @@ -55,25 +55,25 @@ public UIHintAttribute(string uiHint, string presentationLayer, params object[] /// /// Gets the name of the presentation layer that supports the control type in /// - public string PresentationLayer => _implementation.PresentationLayer; + public string? PresentationLayer => _implementation.PresentationLayer; /// /// Gets the name-value pairs used as parameters to the control's constructor /// /// is thrown if the current attribute is ill-formed. - public IDictionary ControlParameters => _implementation.ControlParameters; + public IDictionary ControlParameters => _implementation.ControlParameters; public override int GetHashCode() => _implementation.GetHashCode(); - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is UIHintAttribute otherAttribute && _implementation.Equals(otherAttribute._implementation); internal class UIHintImplementation { - private readonly object[] _inputControlParameters; - private IDictionary _controlParameters; + private readonly object?[]? _inputControlParameters; + private IDictionary? _controlParameters; - public UIHintImplementation(string uiHint, string presentationLayer, params object[] controlParameters) + public UIHintImplementation(string uiHint, string? presentationLayer, params object?[]? controlParameters) { UIHint = uiHint; PresentationLayer = presentationLayer; @@ -92,12 +92,12 @@ public UIHintImplementation(string uiHint, string presentationLayer, params obje /// /// Gets the name of the presentation layer that supports the control type in /// - public string PresentationLayer { get; } + public string? PresentationLayer { get; } // Lazy load the dictionary. It's fine if this method executes multiple times in stress scenarios. // If the method throws (indicating that the input params are invalid) this property will throw // every time it's accessed. - public IDictionary ControlParameters => + public IDictionary ControlParameters => _controlParameters ?? (_controlParameters = BuildControlParametersDictionary()); /// @@ -118,18 +118,19 @@ public override int GetHashCode() /// /// An System.Object. /// true if obj is a UIHintAttribute and its value is the same as this instance; otherwise, false. - public override bool Equals(object obj) + public override bool Equals(object? obj) { - // don't need to perform a type check on obj since this is an internal class - var otherImplementation = (UIHintImplementation)obj; + var otherImplementation = obj as UIHintImplementation; - if (UIHint != otherImplementation.UIHint || PresentationLayer != otherImplementation.PresentationLayer) + if (otherImplementation is null || + UIHint != otherImplementation.UIHint || + PresentationLayer != otherImplementation.PresentationLayer) { return false; } - IDictionary leftParams; - IDictionary rightParams; + IDictionary leftParams; + IDictionary rightParams; try { @@ -157,11 +158,11 @@ public override bool Equals(object obj) /// /// Dictionary of control parameters. /// - private IDictionary BuildControlParametersDictionary() + private IDictionary BuildControlParametersDictionary() { - IDictionary controlParameters = new Dictionary(); + IDictionary controlParameters = new Dictionary(); - object[] inputControlParameters = _inputControlParameters; + object?[]? inputControlParameters = _inputControlParameters; if (inputControlParameters == null || inputControlParameters.Length == 0) { @@ -174,8 +175,8 @@ private IDictionary BuildControlParametersDictionary() for (int i = 0; i < inputControlParameters.Length; i += 2) { - object key = inputControlParameters[i]; - object value = inputControlParameters[i + 1]; + object? key = inputControlParameters[i]; + object? value = inputControlParameters[i + 1]; if (key == null) { throw new InvalidOperationException(SR.Format(SR.UIHintImplementation_ControlParameterKeyIsNull, i)); @@ -185,7 +186,7 @@ private IDictionary BuildControlParametersDictionary() { throw new InvalidOperationException(SR.Format(SR.UIHintImplementation_ControlParameterKeyIsNotAString, i, - inputControlParameters[i].ToString())); + inputControlParameters[i]!.ToString())); } if (controlParameters.ContainsKey(keyString)) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UrlAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UrlAttribute.cs index cb11bc4ee5d5..9913f1883e76 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UrlAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/UrlAttribute.cs @@ -15,7 +15,7 @@ public UrlAttribute() DefaultErrorMessage = SR.UrlAttribute_Invalid; } - public override bool IsValid(object value) + public override bool IsValid(object? value) { if (value == null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs index 0d7f64cb861e..01ec012f20de 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs @@ -22,12 +22,12 @@ public abstract class ValidationAttribute : Attribute { #region Member Fields - private string _errorMessage; - private Func _errorMessageResourceAccessor; - private string _errorMessageResourceName; - private Type _errorMessageResourceType; + private string? _errorMessage; + private Func? _errorMessageResourceAccessor; + private string? _errorMessageResourceName; + private Type? _errorMessageResourceType; private volatile bool _hasBaseIsValid; - private string _defaultErrorMessage; + private string? _defaultErrorMessage; #endregion #region All Constructors @@ -76,7 +76,7 @@ protected ValidationAttribute(Func errorMessageAccessor) /// This property was added after the public contract for DataAnnotations was created. /// It is internal to avoid changing the DataAnnotations contract. /// - internal string DefaultErrorMessage + internal string? DefaultErrorMessage { set { @@ -99,7 +99,7 @@ protected string ErrorMessageString get { SetupResourceAccessor(); - return _errorMessageResourceAccessor(); + return _errorMessageResourceAccessor!(); } } @@ -127,7 +127,7 @@ protected string ErrorMessageString /// This property is intended to be used for non-localizable error messages. Use /// and for localizable error messages. /// - public string ErrorMessage + public string? ErrorMessage { // If _errorMessage is not set, return the default. This is done to preserve // behavior prior to the fix where ErrorMessage showed the non-null message to use. @@ -154,7 +154,7 @@ public string ErrorMessage /// Use this property to set the name of the property within /// that will provide a localized error message. Use for non-localized error messages. /// - public string ErrorMessageResourceName + public string? ErrorMessageResourceName { get => _errorMessageResourceName; set @@ -175,7 +175,7 @@ public string ErrorMessageResourceName /// Use instead of this pair if error messages are not localized. /// /// - public Type ErrorMessageResourceType + public Type? ErrorMessageResourceType { get => _errorMessageResourceType; set @@ -199,7 +199,7 @@ private void SetupResourceAccessor() { if (_errorMessageResourceAccessor == null) { - string localErrorMessage = ErrorMessage; + string? localErrorMessage = ErrorMessage; bool resourceNameSet = !string.IsNullOrEmpty(_errorMessageResourceName); bool errorMessageSet = !string.IsNullOrEmpty(_errorMessage); bool resourceTypeSet = _errorMessageResourceType != null; @@ -231,7 +231,7 @@ private void SetupResourceAccessor() // Here if not using resource type/name -- the accessor is just the error message string, // which we know is not empty to have gotten this far. // We captured error message to local in case it changes before accessor runs - _errorMessageResourceAccessor = () => localErrorMessage; + _errorMessageResourceAccessor = () => localErrorMessage!; } } } @@ -273,7 +273,9 @@ private void SetResourceAccessorByPropertyLookup() _errorMessageResourceType.FullName)); } - _errorMessageResourceAccessor = () => (string)property.GetValue(null, null); + + // TODO-NULLABLE: If the user-provided resource returns null, an ArgumentNullException is thrown - should probably throw a better exception + _errorMessageResourceAccessor = () => (string)property.GetValue(null, null)!; } #endregion @@ -321,7 +323,7 @@ public virtual string FormatErrorMessage(string name) => /// is thrown when neither overload of IsValid has been implemented /// by a derived class. /// - public virtual bool IsValid(object value) + public virtual bool IsValid(object? value) { if (!_hasBaseIsValid) { @@ -330,7 +332,10 @@ public virtual bool IsValid(object value) } // call overridden method. - return IsValid(value, null) == ValidationResult.Success; + // The IsValid method without a validationContext predates the one accepting the context. + // This is theoretically unreachable through normal use cases. + // Instead, the overload using validationContext should be called. + return IsValid(value, null!) == ValidationResult.Success; } /// @@ -355,7 +360,7 @@ public virtual bool IsValid(object value) /// is thrown when /// has not been implemented by a derived class. /// - protected virtual ValidationResult IsValid(object value, ValidationContext validationContext) + protected virtual ValidationResult? IsValid(object? value, ValidationContext validationContext) { if (_hasBaseIsValid) { @@ -369,8 +374,8 @@ protected virtual ValidationResult IsValid(object value, ValidationContext valid // call overridden method. if (!IsValid(value)) { - string[] memberNames = validationContext.MemberName != null - ? new string[] { validationContext.MemberName } + string[]? memberNames = validationContext.MemberName is { } memberName + ? new[] { memberName } : null; result = new ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); } @@ -404,7 +409,7 @@ protected virtual ValidationResult IsValid(object value, ValidationContext valid /// is thrown when /// has not been implemented by a derived class. /// - public ValidationResult GetValidationResult(object value, ValidationContext validationContext) + public ValidationResult? GetValidationResult(object? value, ValidationContext validationContext) { if (validationContext == null) { @@ -445,7 +450,7 @@ public ValidationResult GetValidationResult(object value, ValidationContext vali /// is thrown if returns false. /// /// is thrown if the current attribute is malformed. - public void Validate(object value, string name) + public void Validate(object? value, string name) { if (!IsValid(value)) { @@ -474,14 +479,14 @@ public void Validate(object value, string name) /// is thrown when /// has not been implemented by a derived class. /// - public void Validate(object value, ValidationContext validationContext) + public void Validate(object? value, ValidationContext validationContext) { if (validationContext == null) { throw new ArgumentNullException(nameof(validationContext)); } - ValidationResult result = GetValidationResult(value, validationContext); + ValidationResult? result = GetValidationResult(value, validationContext); if (result != null) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs index 710bb9d1ebcf..db3b57bd0be1 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; @@ -43,7 +44,7 @@ internal IEnumerable GetTypeValidationAttributes(Validation /// /// The context that describes the type. It cannot be null. /// The display attribute instance, if present. - internal DisplayAttribute GetTypeDisplayAttribute(ValidationContext validationContext) + internal DisplayAttribute? GetTypeDisplayAttribute(ValidationContext validationContext) { EnsureValidationContext(validationContext); var item = GetTypeStoreItem(validationContext.ObjectType); @@ -59,7 +60,7 @@ internal IEnumerable GetPropertyValidationAttributes(Valida { EnsureValidationContext(validationContext); var typeItem = GetTypeStoreItem(validationContext.ObjectType); - var item = typeItem.GetPropertyStoreItem(validationContext.MemberName); + var item = typeItem.GetPropertyStoreItem(validationContext.MemberName!); return item.ValidationAttributes; } @@ -68,11 +69,11 @@ internal IEnumerable GetPropertyValidationAttributes(Valida /// /// The context that describes the property. It cannot be null. /// The display attribute instance, if present. - internal DisplayAttribute GetPropertyDisplayAttribute(ValidationContext validationContext) + internal DisplayAttribute? GetPropertyDisplayAttribute(ValidationContext validationContext) { EnsureValidationContext(validationContext); var typeItem = GetTypeStoreItem(validationContext.ObjectType); - var item = typeItem.GetPropertyStoreItem(validationContext.MemberName); + var item = typeItem.GetPropertyStoreItem(validationContext.MemberName!); return item.DisplayAttribute; } @@ -85,7 +86,7 @@ internal Type GetPropertyType(ValidationContext validationContext) { EnsureValidationContext(validationContext); var typeItem = GetTypeStoreItem(validationContext.ObjectType); - var item = typeItem.GetPropertyStoreItem(validationContext.MemberName); + var item = typeItem.GetPropertyStoreItem(validationContext.MemberName!); return item.PropertyType; } @@ -100,8 +101,8 @@ internal bool IsPropertyContext(ValidationContext validationContext) { EnsureValidationContext(validationContext); var typeItem = GetTypeStoreItem(validationContext.ObjectType); - PropertyStoreItem item; - return typeItem.TryGetPropertyStoreItem(validationContext.MemberName, out item); + PropertyStoreItem? item; + return typeItem.TryGetPropertyStoreItem(validationContext.MemberName!, out item); } /// @@ -115,7 +116,7 @@ private TypeStoreItem GetTypeStoreItem(Type type) lock (_typeStoreItems) { - if (!_typeStoreItems.TryGetValue(type, out TypeStoreItem item)) + if (!_typeStoreItems.TryGetValue(type, out TypeStoreItem? item)) { // use CustomAttributeExtensions.GetCustomAttributes() to get inherited attributes as well as direct ones var attributes = CustomAttributeExtensions.GetCustomAttributes(type, true); @@ -158,7 +159,7 @@ internal StoreItem(IEnumerable attributes) internal IEnumerable ValidationAttributes { get; } - internal DisplayAttribute DisplayAttribute { get; } + internal DisplayAttribute? DisplayAttribute { get; } } /// @@ -168,7 +169,7 @@ private class TypeStoreItem : StoreItem { private readonly object _syncRoot = new object(); private readonly Type _type; - private Dictionary _propertyStoreItems; + private Dictionary? _propertyStoreItems; internal TypeStoreItem(Type type, IEnumerable attributes) : base(attributes) @@ -178,7 +179,7 @@ internal TypeStoreItem(Type type, IEnumerable attributes) internal PropertyStoreItem GetPropertyStoreItem(string propertyName) { - if (!TryGetPropertyStoreItem(propertyName, out PropertyStoreItem item)) + if (!TryGetPropertyStoreItem(propertyName, out PropertyStoreItem? item)) { throw new ArgumentException(SR.Format(SR.AttributeStore_Unknown_Property, _type.Name, propertyName), nameof(propertyName)); @@ -187,7 +188,7 @@ internal PropertyStoreItem GetPropertyStoreItem(string propertyName) return item; } - internal bool TryGetPropertyStoreItem(string propertyName, out PropertyStoreItem item) + internal bool TryGetPropertyStoreItem(string propertyName, [NotNullWhen(true)] out PropertyStoreItem? item) { if (string.IsNullOrEmpty(propertyName)) { diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationContext.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationContext.cs index ba91968f704a..f12578ac9d6e 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationContext.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationContext.cs @@ -28,9 +28,9 @@ public sealed class ValidationContext { #region Member Fields - private readonly Dictionary _items; - private string _displayName; - private Func _serviceProvider; + private readonly Dictionary _items; + private string? _displayName; + private Func? _serviceProvider; #endregion @@ -57,7 +57,7 @@ public ValidationContext(object instance) /// new dictionary, preventing consumers from modifying the original dictionary. /// /// When is null - public ValidationContext(object instance, IDictionary items) + public ValidationContext(object instance, IDictionary? items) : this(instance, null, items) { } @@ -78,7 +78,7 @@ public ValidationContext(object instance, IDictionary items) /// new dictionary, preventing consumers from modifying the original dictionary. /// /// When is null - public ValidationContext(object instance, IServiceProvider serviceProvider, IDictionary items) + public ValidationContext(object instance, IServiceProvider? serviceProvider, IDictionary? items) { if (instance == null) { @@ -90,7 +90,7 @@ public ValidationContext(object instance, IServiceProvider serviceProvider, IDic InitializeServiceProvider(serviceType => serviceProvider.GetService(serviceType)); } - _items = items != null ? new Dictionary(items) : new Dictionary(); + _items = items != null ? new Dictionary(items) : new Dictionary(); ObjectInstance = instance; } @@ -155,7 +155,7 @@ public string DisplayName /// This name reflects the API name of the member being validated, not a localized name. It should be set /// only for property or parameter contexts. /// - public string MemberName { get; set; } + public string? MemberName { get; set; } /// /// Gets the dictionary of key/value pairs associated with this context. @@ -164,7 +164,7 @@ public string DisplayName /// This property will never be null, but the dictionary may be empty. Changes made /// to items in this dictionary will never affect the original dictionary specified in the constructor. /// - public IDictionary Items => _items; + public IDictionary Items => _items; #endregion @@ -174,11 +174,11 @@ public string DisplayName /// Looks up the display name using the DisplayAttribute attached to the respective type or property. /// /// A display-friendly name of the member represented by the . - private string GetDisplayName() + private string? GetDisplayName() { - string displayName = null; + string? displayName = null; ValidationAttributeStore store = ValidationAttributeStore.Instance; - DisplayAttribute displayAttribute = null; + DisplayAttribute? displayAttribute = null; if (string.IsNullOrEmpty(MemberName)) { @@ -206,7 +206,7 @@ private string GetDisplayName() /// desired when is called. /// If it is null, will always return null. /// - public void InitializeServiceProvider(Func serviceProvider) + public void InitializeServiceProvider(Func serviceProvider) { _serviceProvider = serviceProvider; } @@ -220,7 +220,7 @@ public void InitializeServiceProvider(Func serviceProvider) /// /// The type of the service needed. /// An instance of that service or null if it is not available. - public object GetService(Type serviceType) => _serviceProvider?.Invoke(serviceType); + public object? GetService(Type serviceType) => _serviceProvider?.Invoke(serviceType); #endregion } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationException.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationException.cs index efb091e055e5..fc57b1f10cf6 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationException.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationException.cs @@ -12,7 +12,7 @@ namespace System.ComponentModel.DataAnnotations [System.Runtime.CompilerServices.TypeForwardedFrom("System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] public class ValidationException : Exception { - private ValidationResult _validationResult; + private ValidationResult? _validationResult; /// /// Constructor that accepts a structured describing the problem. @@ -20,8 +20,8 @@ public class ValidationException : Exception /// The value describing the validation error /// The attribute that triggered this exception /// The value that caused the validating attribute to trigger the exception - public ValidationException(ValidationResult validationResult, ValidationAttribute validatingAttribute, - object value) + public ValidationException(ValidationResult validationResult, ValidationAttribute? validatingAttribute, + object? value) : this(validationResult.ErrorMessage, validatingAttribute, value) { _validationResult = validationResult; @@ -33,7 +33,7 @@ public ValidationException(ValidationResult validationResult, ValidationAttribut /// The localized error message /// The attribute that triggered this exception /// The value that caused the validating attribute to trigger the exception - public ValidationException(string errorMessage, ValidationAttribute validatingAttribute, object value) + public ValidationException(string? errorMessage, ValidationAttribute? validatingAttribute, object? value) : base(errorMessage) { Value = value; @@ -53,7 +53,7 @@ public ValidationException() /// /// The long form of this constructor is preferred because it gives better error reporting. /// The localized message - public ValidationException(string message) + public ValidationException(string? message) : base(message) { } @@ -64,7 +64,7 @@ public ValidationException(string message) /// The long form of this constructor is preferred because it gives better error reporting /// The localized error message /// inner exception - public ValidationException(string message, Exception innerException) + public ValidationException(string? message, Exception? innerException) : base(message, innerException) { } @@ -82,7 +82,7 @@ protected ValidationException(SerializationInfo info, StreamingContext context) /// /// Gets the ValidationAttribute instance that triggered this exception. /// - public ValidationAttribute ValidationAttribute { get; } + public ValidationAttribute? ValidationAttribute { get; } /// /// Gets the instance that describes the validation error. @@ -96,6 +96,6 @@ protected ValidationException(SerializationInfo info, StreamingContext context) /// /// Gets the value that caused the validating attribute to trigger the exception /// - public object Value { get; } + public object? Value { get; } } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationResult.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationResult.cs index 5142f185d53e..fa26fd83bd18 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationResult.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationResult.cs @@ -23,7 +23,7 @@ public class ValidationResult /// The null value is used to indicate success. Consumers of s /// should compare the values to rather than checking for null. /// - public static readonly ValidationResult Success; + public static readonly ValidationResult? Success; #endregion @@ -37,7 +37,7 @@ public class ValidationResult /// The user-visible error message. If null, /// will use for its error message. /// - public ValidationResult(string errorMessage) + public ValidationResult(string? errorMessage) : this(errorMessage, null) { } @@ -54,7 +54,7 @@ public ValidationResult(string errorMessage) /// The list of member names affected by this result. /// This list of member names is meant to be used by presentation layers to indicate which fields are in error. /// - public ValidationResult(string errorMessage, IEnumerable memberNames) + public ValidationResult(string? errorMessage, IEnumerable? memberNames) { ErrorMessage = errorMessage; MemberNames = memberNames ?? Array.Empty(); @@ -88,7 +88,7 @@ protected ValidationResult(ValidationResult validationResult) /// /// Gets the error message for this result. It may be null. /// - public string ErrorMessage { get; set; } + public string? ErrorMessage { get; set; } #endregion @@ -107,7 +107,7 @@ protected ValidationResult(ValidationResult validationResult) /// The property value if specified, /// otherwise, the base result. /// - public override string ToString() => ErrorMessage ?? base.ToString(); + public override string ToString() => ErrorMessage ?? base.ToString()!; #endregion Methods } } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs index a50329ace698..b6251f53451f 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; @@ -46,12 +47,12 @@ public static class Validator /// When the of is not a valid /// property. /// - public static bool TryValidateProperty(object value, ValidationContext validationContext, - ICollection validationResults) + public static bool TryValidateProperty(object? value, ValidationContext validationContext, + ICollection? validationResults) { // Throw if value cannot be assigned to this property. That is not a validation exception. var propertyType = _store.GetPropertyType(validationContext); - var propertyName = validationContext.MemberName; + var propertyName = validationContext.MemberName!; EnsureValidPropertyType(propertyName, propertyType, value); var result = true; @@ -92,7 +93,7 @@ public static bool TryValidateProperty(object value, ValidationContext validatio /// on . /// public static bool TryValidateObject( - object instance, ValidationContext validationContext, ICollection validationResults) => + object instance, ValidationContext validationContext, ICollection? validationResults) => TryValidateObject(instance, validationContext, validationResults, false /*validateAllProperties*/); /// @@ -129,13 +130,14 @@ public static bool TryValidateObject( /// on . /// public static bool TryValidateObject(object instance, ValidationContext validationContext, - ICollection validationResults, bool validateAllProperties) + ICollection? validationResults, bool validateAllProperties) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } + // TODO-NULLABLE: null validationContext isn't supported (GetObjectValidationErrors will throw), remove that check if (validationContext != null && instance != validationContext.ObjectInstance) { throw new ArgumentException(SR.Validator_InstanceMustMatchValidationContextInstance, nameof(instance)); @@ -144,7 +146,7 @@ public static bool TryValidateObject(object instance, ValidationContext validati var result = true; var breakOnFirstError = (validationResults == null); - foreach (ValidationError err in GetObjectValidationErrors(instance, validationContext, validateAllProperties, breakOnFirstError)) + foreach (ValidationError err in GetObjectValidationErrors(instance, validationContext!, validateAllProperties, breakOnFirstError)) { result = false; @@ -184,7 +186,7 @@ public static bool TryValidateObject(object instance, ValidationContext validati /// /// true if the object is valid, false if any validation errors are encountered. public static bool TryValidateValue(object value, ValidationContext validationContext, - ICollection validationResults, IEnumerable validationAttributes) + ICollection? validationResults, IEnumerable validationAttributes) { var result = true; var breakOnFirstError = validationResults == null; @@ -211,11 +213,11 @@ var err in /// /// When is null. /// When is invalid for this property. - public static void ValidateProperty(object value, ValidationContext validationContext) + public static void ValidateProperty(object? value, ValidationContext validationContext) { // Throw if value cannot be assigned to this property. That is not a validation exception. var propertyType = _store.GetPropertyType(validationContext); - EnsureValidPropertyType(validationContext.MemberName, propertyType, value); + EnsureValidPropertyType(validationContext.MemberName!, propertyType, value); var attributes = _store.GetPropertyValidationAttributes(validationContext); @@ -343,7 +345,7 @@ private static ValidationContext CreateValidationContext(object instance, Valida /// /// true if the assignment is legal. /// When is null. - private static bool CanBeAssigned(Type destinationType, object value) + private static bool CanBeAssigned(Type destinationType, object? value) { if (value == null) { @@ -364,7 +366,7 @@ private static bool CanBeAssigned(Type destinationType, object value) /// The type of the property. /// The value. Null is permitted only if the property will accept it. /// is thrown if is the wrong type for this property. - private static void EnsureValidPropertyType(string propertyName, Type propertyType, object value) + private static void EnsureValidPropertyType(string propertyName, Type propertyType, object? value) { if (!CanBeAssigned(propertyType, value)) { @@ -476,7 +478,7 @@ private static IEnumerable GetObjectPropertyValidationErrors(ob var validationResult = reqAttr.GetValidationResult(property.Value, property.Key); if (validationResult != ValidationResult.Success) { - errors.Add(new ValidationError(reqAttr, property.Value, validationResult)); + errors.Add(new ValidationError(reqAttr, property.Value, validationResult!)); } } } @@ -500,12 +502,12 @@ private static IEnumerable GetObjectPropertyValidationErrors(ob /// value. /// /// Ignores indexed properties. - private static ICollection> GetPropertyValues(object instance, + private static ICollection> GetPropertyValues(object instance, ValidationContext validationContext) { var properties = instance.GetType().GetRuntimeProperties() .Where(p => ValidationAttributeStore.IsPublic(p) && !p.GetIndexParameters().Any()); - var items = new List>(properties.Count()); + var items = new List>(properties.Count()); foreach (var property in properties) { var context = CreateValidationContext(instance, validationContext); @@ -513,7 +515,7 @@ private static ICollection> GetPropertyV if (_store.GetPropertyValidationAttributes(context).Any()) { - items.Add(new KeyValuePair(context, property.GetValue(instance, null))); + items.Add(new KeyValuePair(context, property.GetValue(instance, null))); } } @@ -537,7 +539,7 @@ private static ICollection> GetPropertyV /// /// The collection of validation errors. /// When is null. - private static IEnumerable GetValidationErrors(object value, + private static IEnumerable GetValidationErrors(object? value, ValidationContext validationContext, IEnumerable attributes, bool breakOnFirstError) { if (validationContext == null) @@ -546,7 +548,7 @@ private static IEnumerable GetValidationErrors(object value, } var errors = new List(); - ValidationError validationError; + ValidationError? validationError; // Get the required validator if there is one and test it first, aborting on failure var required = attributes.OfType().FirstOrDefault(); @@ -592,15 +594,15 @@ private static IEnumerable GetValidationErrors(object value, /// /// true if the value is valid. /// When is null. - private static bool TryValidate(object value, ValidationContext validationContext, ValidationAttribute attribute, - out ValidationError validationError) + private static bool TryValidate(object? value, ValidationContext validationContext, ValidationAttribute attribute, + [NotNullWhen(false)] out ValidationError? validationError) { Debug.Assert(validationContext != null); var validationResult = attribute.GetValidationResult(value, validationContext); if (validationResult != ValidationResult.Success) { - validationError = new ValidationError(attribute, value, validationResult); + validationError = new ValidationError(attribute, value, validationResult!); return false; } @@ -614,10 +616,10 @@ private static bool TryValidate(object value, ValidationContext validationContex /// private class ValidationError { - private readonly object _value; - private readonly ValidationAttribute _validationAttribute; + private readonly object? _value; + private readonly ValidationAttribute? _validationAttribute; - internal ValidationError(ValidationAttribute validationAttribute, object value, + internal ValidationError(ValidationAttribute? validationAttribute, object? value, ValidationResult validationResult) { _validationAttribute = validationAttribute; From 4b8c5fe2b4757f77f5699d49a072fcb123d2e33b Mon Sep 17 00:00:00 2001 From: Cory Nelson Date: Tue, 28 Jul 2020 08:06:57 -0700 Subject: [PATCH 093/755] Initial (partially-reviewed API) System.Net.Connections. (#39524) --- .../System/Net/Http/GenericLoopbackServer.cs | 6 + .../Net/Http/Http2LoopbackConnection.cs | 79 ++++-- .../System/Net/Http/Http2LoopbackServer.cs | 49 ++-- .../Net/Http/Http3LoopbackConnection.cs | 6 + .../System/Net/Http/Http3LoopbackServer.cs | 9 + .../tests/System/Net/Http/LoopbackServer.cs | 14 +- .../Net/VirtualNetwork/VirtualNetwork.cs | 38 ++- ...VirtualNetworkConnectionListenerFactory.cs | 187 ++++++++++++ .../VirtualNetwork/VirtualNetworkStream.cs | 28 +- .../Threading/Tasks/TaskTimeoutExtensions.cs | 14 + src/libraries/NetCoreAppLibrary.props | 2 + .../pkg/System.IO.Pipelines.pkgproj | 1 + .../ref/System.IO.Pipelines.csproj | 9 +- .../Directory.Build.props | 6 + .../System.Net.Connections.sln | 50 ++++ .../ref/System.Net.Connections.cs | 74 +++++ .../ref/System.Net.Connections.csproj | 14 + .../src/Resources/Strings.resx | 138 +++++++++ .../src/System.Net.Connections.csproj | 26 ++ .../src/System/Net/Connections/Connection.cs | 265 ++++++++++++++++++ .../System/Net/Connections/ConnectionBase.cs | 80 ++++++ .../Net/Connections/ConnectionCloseMethod.cs | 26 ++ .../Net/Connections/ConnectionExtensions.cs | 87 ++++++ .../Net/Connections/ConnectionFactory.cs | 53 ++++ .../Net/Connections/ConnectionListener.cs | 62 ++++ .../Connections/ConnectionListenerFactory.cs | 46 +++ .../Net/Connections/DuplexPipeStream.cs | 166 +++++++++++ .../Net/Connections/IConnectionProperties.cs | 21 ++ .../ConnectionBaseTest.cs | 81 ++++++ .../ConnectionTest.cs | 264 +++++++++++++++++ .../ConnectionWithoutStreamOrPipe.cs | 22 ++ .../MockConnection.cs | 33 +++ .../System.Net.Connections.Tests/MockPipe.cs | 21 ++ .../MockPipeReader.cs | 44 +++ .../MockPipeWriter.cs | 40 +++ .../MockStream.cs | 107 +++++++ .../System.Net.Connections.Tests.csproj | 19 ++ .../System.Net.Http/ref/System.Net.Http.cs | 11 + .../ref/System.Net.Http.csproj | 2 + .../src/System.Net.Http.csproj | 7 + .../SocketsHttpConnectionFactory.cs | 19 ++ .../BrowserHttpHandler/SocketsHttpHandler.cs | 13 + .../Http/SocketsHttpHandler/ConnectHelper.cs | 99 +------ .../Connections/SocketConnection.cs | 101 +++++++ .../Connections/TaskSocketAsyncEventArgs.cs | 32 +++ .../DnsEndPointWithProperties.cs | 31 ++ .../SocketsHttpHandler/Http2Connection.cs | 11 +- .../Http/SocketsHttpHandler/HttpConnection.cs | 16 +- .../SocketsHttpHandler/HttpConnectionPool.cs | 95 +++++-- .../HttpConnectionSettings.cs | 10 +- .../SocketsHttpConnectionFactory.cs | 89 ++++++ .../SocketsHttpHandler/SocketsHttpHandler.cs | 28 ++ .../FunctionalTests/SocketsHttpHandlerTest.cs | 66 +++++ .../System.Net.Http.Functional.Tests.csproj | 3 + src/libraries/pkg/baseline/packageIndex.json | 4 +- 55 files changed, 2638 insertions(+), 186 deletions(-) create mode 100644 src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs create mode 100644 src/libraries/System.Net.Connections/Directory.Build.props create mode 100644 src/libraries/System.Net.Connections/System.Net.Connections.sln create mode 100644 src/libraries/System.Net.Connections/ref/System.Net.Connections.cs create mode 100644 src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj create mode 100644 src/libraries/System.Net.Connections/src/Resources/Strings.resx create mode 100644 src/libraries/System.Net.Connections/src/System.Net.Connections.csproj create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs create mode 100644 src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs create mode 100644 src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/SocketConnection.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/TaskSocketAsyncEventArgs.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index fd12e239e5d3..d15ab88b2618 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -6,6 +6,8 @@ using System.Text; using System.Threading.Tasks; using System.Security.Authentication; +using System.IO; +using System.Net.Sockets; namespace System.Net.Test.Common { @@ -17,6 +19,8 @@ public abstract class LoopbackServerFactory public abstract GenericLoopbackServer CreateServer(GenericLoopbackOptions options = null); public abstract Task CreateServerAsync(Func funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null); + public abstract Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null); + public abstract Version Version { get; } // Common helper methods @@ -58,6 +62,8 @@ public abstract class GenericLoopbackConnection : IDisposable { public abstract void Dispose(); + public abstract Task InitializeConnectionAsync(); + /// Read request Headers and optionally request body as well. public abstract Task ReadRequestDataAsync(bool readBody = true); /// Read complete request body if not done by ReadRequestData. diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 3bc20976fdef..ad60410c03ba 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -7,6 +7,7 @@ using System.Net.Http.Functional.Tests; using System.Net.Security; using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -24,28 +25,31 @@ public class Http2LoopbackConnection : GenericLoopbackConnection private readonly TimeSpan _timeout; private int _lastStreamId; - private readonly byte[] _prefix; + private readonly byte[] _prefix = new byte[24]; public string PrefixString => Encoding.UTF8.GetString(_prefix, 0, _prefix.Length); public bool IsInvalid => _connectionSocket == null; public Stream Stream => _connectionStream; public Task SettingAckWaiter => _ignoredSettingsAckPromise?.Task; - public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) - : this(socket, httpOptions, Http2LoopbackServer.Timeout) + private Http2LoopbackConnection(Socket socket, Stream stream, TimeSpan timeout) { + _connectionSocket = socket; + _connectionStream = stream; + _timeout = timeout; } - public Http2LoopbackConnection(Socket socket, Http2Options httpOptions, TimeSpan timeout) + public static Task CreateAsync(Socket socket, Stream stream, Http2Options httpOptions) { - _connectionSocket = socket; - _connectionStream = new NetworkStream(_connectionSocket, true); - _timeout = timeout; + return CreateAsync(socket, stream, httpOptions, Http2LoopbackServer.Timeout); + } + public static async Task CreateAsync(Socket socket, Stream stream, Http2Options httpOptions, TimeSpan timeout) + { if (httpOptions.UseSsl) { - var sslStream = new SslStream(_connectionStream, false, delegate { return true; }); + var sslStream = new SslStream(stream, false, delegate { return true; }); - using (var cert = Configuration.Certificates.GetServerCertificate()) + using (X509Certificate2 cert = Configuration.Certificates.GetServerCertificate()) { #if !NETFRAMEWORK SslServerAuthenticationOptions options = new SslServerAuthenticationOptions(); @@ -61,21 +65,29 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions, TimeSpan options.ClientCertificateRequired = httpOptions.ClientCertificateRequired; - sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).Wait(); + await sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).ConfigureAwait(false); #else - sslStream.AuthenticateAsServerAsync(cert, httpOptions.ClientCertificateRequired, httpOptions.SslProtocols, checkCertificateRevocation: false).Wait(); + await sslStream.AuthenticateAsServerAsync(cert, httpOptions.ClientCertificateRequired, httpOptions.SslProtocols, checkCertificateRevocation: false).ConfigureAwait(false); #endif } - _connectionStream = sslStream; + stream = sslStream; } - _prefix = new byte[24]; - if (!FillBufferAsync(_prefix).Result) + var con = new Http2LoopbackConnection(socket, stream, timeout); + await con.ReadPrefixAsync().ConfigureAwait(false); + + return con; + } + + private async Task ReadPrefixAsync() + { + if (!await FillBufferAsync(_prefix)) { throw new Exception("Connection stream closed while attempting to read connection preface."); } - else if (Text.Encoding.ASCII.GetString(_prefix).Contains("HTTP/1.1")) + + if (Text.Encoding.ASCII.GetString(_prefix).Contains("HTTP/1.1")) { throw new Exception("HTTP 1.1 request received."); } @@ -275,7 +287,7 @@ public async Task WaitForClientDisconnectAsync(bool ignoreUnexpectedFrames = fal public void ShutdownSend() { - _connectionSocket.Shutdown(SocketShutdown.Send); + _connectionSocket?.Shutdown(SocketShutdown.Send); } // This will cause a server-initiated shutdown of the connection. @@ -563,6 +575,41 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) return (streamId, requestData); } + public override Task InitializeConnectionAsync() + { + return ReadAndSendSettingsAsync(ackTimeout: null); + } + + public async Task ReadAndSendSettingsAsync(TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) + { + // Receive the initial client settings frame. + Frame receivedFrame = await ReadFrameAsync(_timeout).ConfigureAwait(false); + Assert.Equal(FrameType.Settings, receivedFrame.Type); + Assert.Equal(FrameFlags.None, receivedFrame.Flags); + Assert.Equal(0, receivedFrame.StreamId); + + var clientSettingsFrame = (SettingsFrame)receivedFrame; + + // Receive the initial client window update frame. + receivedFrame = await ReadFrameAsync(_timeout).ConfigureAwait(false); + Assert.Equal(FrameType.WindowUpdate, receivedFrame.Type); + Assert.Equal(FrameFlags.None, receivedFrame.Flags); + Assert.Equal(0, receivedFrame.StreamId); + + // Send the initial server settings frame. + SettingsFrame settingsFrame = new SettingsFrame(settingsEntries); + await WriteFrameAsync(settingsFrame).ConfigureAwait(false); + + // Send the client settings frame ACK. + Frame settingsAck = new Frame(0, FrameType.Settings, FrameFlags.Ack, 0); + await WriteFrameAsync(settingsAck).ConfigureAwait(false); + + // The client will send us a SETTINGS ACK eventually, but not necessarily right away. + await ExpectSettingsAckAsync((int?)ackTimeout?.TotalMilliseconds ?? 5000); + + return clientSettingsFrame; + } + public async Task SendGoAway(int lastStreamId, ProtocolErrors errorCode = ProtocolErrors.NO_ERROR) { GoAwayFrame frame = new GoAwayFrame(lastStreamId, (int)errorCode, new byte[] { }, 0); diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index 8516140e517c..e890812cdbcd 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -90,7 +90,10 @@ public async Task AcceptConnectionAsync(TimeSpan? timeo Socket connectionSocket = await _listenSocket.AcceptAsync().ConfigureAwait(false); - Http2LoopbackConnection connection = timeout != null ? new Http2LoopbackConnection(connectionSocket, _options, timeout.Value) : new Http2LoopbackConnection(connectionSocket, _options); + var stream = new NetworkStream(connectionSocket, ownsSocket: true); + Http2LoopbackConnection connection = + timeout != null ? await Http2LoopbackConnection.CreateAsync(connectionSocket, stream, _options, timeout.Value).ConfigureAwait(false) : + await Http2LoopbackConnection.CreateAsync(connectionSocket, stream, _options).ConfigureAwait(false); _connections.Add(connection); return connection; @@ -103,7 +106,7 @@ public override async Task EstablishGenericConnection public Task EstablishConnectionAsync(params SettingsEntry[] settingsEntries) { - return EstablishConnectionAsync(null, null, settingsEntries); + return EstablishConnectionAsync(timeout: null, ackTimeout: null, settingsEntries); } public async Task EstablishConnectionAsync(TimeSpan? timeout, TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) @@ -114,37 +117,13 @@ public async Task EstablishConnectionAsync(TimeSpan? ti public Task<(Http2LoopbackConnection, SettingsFrame)> EstablishConnectionGetSettingsAsync(params SettingsEntry[] settingsEntries) { - return EstablishConnectionGetSettingsAsync(null, null, settingsEntries); + return EstablishConnectionGetSettingsAsync(timeout: null, ackTimeout: null, settingsEntries); } public async Task<(Http2LoopbackConnection, SettingsFrame)> EstablishConnectionGetSettingsAsync(TimeSpan? timeout, TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) { Http2LoopbackConnection connection = await AcceptConnectionAsync(timeout).ConfigureAwait(false); - - // Receive the initial client settings frame. - Frame receivedFrame = await connection.ReadFrameAsync(Timeout).ConfigureAwait(false); - Assert.Equal(FrameType.Settings, receivedFrame.Type); - Assert.Equal(FrameFlags.None, receivedFrame.Flags); - Assert.Equal(0, receivedFrame.StreamId); - - var clientSettingsFrame = (SettingsFrame)receivedFrame; - - // Receive the initial client window update frame. - receivedFrame = await connection.ReadFrameAsync(Timeout).ConfigureAwait(false); - Assert.Equal(FrameType.WindowUpdate, receivedFrame.Type); - Assert.Equal(FrameFlags.None, receivedFrame.Flags); - Assert.Equal(0, receivedFrame.StreamId); - - // Send the initial server settings frame. - SettingsFrame settingsFrame = new SettingsFrame(settingsEntries); - await connection.WriteFrameAsync(settingsFrame).ConfigureAwait(false); - - // Send the client settings frame ACK. - Frame settingsAck = new Frame(0, FrameType.Settings, FrameFlags.Ack, 0); - await connection.WriteFrameAsync(settingsAck).ConfigureAwait(false); - - // The client will send us a SETTINGS ACK eventually, but not necessarily right away. - await connection.ExpectSettingsAckAsync((int) (ackTimeout?.TotalMilliseconds ?? 5000)); + SettingsFrame clientSettingsFrame = await connection.ReadAndSendSettingsAsync(ackTimeout, settingsEntries).ConfigureAwait(false); return (connection, clientSettingsFrame); } @@ -220,7 +199,6 @@ public class Http2Options : GenericLoopbackOptions public Http2Options() { - UseSsl = PlatformDetection.SupportsAlpn && !Capability.Http2ForceUnencryptedLoopback(); SslProtocols = SslProtocols.Tls12; } } @@ -238,6 +216,16 @@ public static async Task CreateServerAsync(Func } public override GenericLoopbackServer CreateServer(GenericLoopbackOptions options = null) + { + return Http2LoopbackServer.CreateServer(CreateOptions(options)); + } + + public override async Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) + { + return await Http2LoopbackConnection.CreateAsync(socket, stream, CreateOptions(options)).ConfigureAwait(false); + } + + private static Http2Options CreateOptions(GenericLoopbackOptions options) { Http2Options http2Options = new Http2Options(); if (options != null) @@ -246,8 +234,7 @@ public override GenericLoopbackServer CreateServer(GenericLoopbackOptions option http2Options.UseSsl = options.UseSsl; http2Options.SslProtocols = options.SslProtocols; } - - return Http2LoopbackServer.CreateServer(http2Options); + return http2Options; } public override async Task CreateServerAsync(Func funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index 5d6f3e70fe2d..cfa912a7f4bf 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using System.Linq; +using System.Net.Http.Functional.Tests; namespace System.Net.Test.Common { @@ -84,6 +85,11 @@ public Http3LoopbackStream GetOpenRequest(int requestId = 0) return requestId == 0 ? _currentStream : _openStreams[requestId - 1]; } + public override Task InitializeConnectionAsync() + { + throw new NotImplementedException(); + } + public async Task AcceptStreamAsync() { QuicStream quicStream = await _connection.AcceptStreamAsync().ConfigureAwait(false); diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 411557089b3d..49c3c867fff7 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Net.Quic; using System.Net.Security; +using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -80,5 +82,12 @@ public override async Task CreateServerAsync(Func CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) + { + // TODO: make a new overload that takes a MultiplexedConnection. + // This method is always unacceptable to call for HTTP/3. + throw new NotImplementedException("HTTP/3 does not operate over a Socket."); + } } } diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 208f9d7f29fa..76c8459a136e 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -594,13 +594,18 @@ public override void Dispose() // This seems to help avoid connection reset issues caused by buffered data // that has not been sent/acked when the graceful shutdown timeout expires. // This may throw if the socket was already closed, so eat any exception. - _socket.Shutdown(SocketShutdown.Send); + _socket?.Shutdown(SocketShutdown.Send); } catch (Exception) { } _writer.Dispose(); _stream.Dispose(); - _socket.Dispose(); + _socket?.Dispose(); + } + + public override Task InitializeConnectionAsync() + { + return Task.CompletedTask; } public async Task> ReadRequestHeaderAsync() @@ -896,6 +901,11 @@ public override Task CreateServerAsync(Func fu return LoopbackServer.CreateServerAsync((server, uri) => funcAsync(server, uri), options: CreateOptions(options)); } + public override Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) + { + return Task.FromResult(new LoopbackServer.Connection(socket, stream)); + } + private static LoopbackServer.Options CreateOptions(GenericLoopbackOptions options) { LoopbackServer.Options newOptions = new LoopbackServer.Options(); diff --git a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetwork.cs b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetwork.cs index 77a4695d0364..141fe66284b3 100644 --- a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetwork.cs +++ b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetwork.cs @@ -14,7 +14,7 @@ public class VirtualNetworkConnectionBroken : Exception public VirtualNetworkConnectionBroken() : base("Connection broken") { } } - private readonly int WaitForReadDataTimeoutMilliseconds = 30 * 1000; + private readonly int WaitForReadDataTimeoutMilliseconds = 60 * 1000; private readonly ConcurrentQueue _clientWriteQueue = new ConcurrentQueue(); private readonly ConcurrentQueue _serverWriteQueue = new ConcurrentQueue(); @@ -22,8 +22,11 @@ public VirtualNetworkConnectionBroken() : base("Connection broken") { } private readonly SemaphoreSlim _clientDataAvailable = new SemaphoreSlim(0); private readonly SemaphoreSlim _serverDataAvailable = new SemaphoreSlim(0); + private volatile bool _clientWriteShutdown = false; + private volatile bool _serverWriteShutdown = false; + public bool DisableConnectionBreaking { get; set; } = false; - private bool _connectionBroken = false; + private volatile bool _connectionBroken = false; public byte[] ReadFrame(bool server) => ReadFrameCoreAsync(server, sync: true, cancellationToken: default).GetAwaiter().GetResult(); @@ -75,6 +78,11 @@ private async Task ReadFrameCoreAsync(bool server, bool sync, Cancellati return buffer; } + if ((server && _clientWriteShutdown) || (!server && _serverWriteShutdown)) + { + return Array.Empty(); + } + remainingTries--; backOffDelayMilliseconds *= backOffDelayMilliseconds; if (sync) @@ -98,6 +106,16 @@ public void WriteFrame(bool server, byte[] buffer) throw new VirtualNetworkConnectionBroken(); } + if ((server && _serverWriteShutdown) || (!server && _clientWriteShutdown)) + { + throw new InvalidOperationException("Writing to a shutdown side."); + } + + if (buffer.Length == 0) + { + return; + } + SemaphoreSlim semaphore; ConcurrentQueue packetQueue; @@ -116,11 +134,25 @@ public void WriteFrame(bool server, byte[] buffer) semaphore.Release(); } + public void GracefulShutdown(bool server) + { + if (server) + { + _serverWriteShutdown = true; + _serverDataAvailable.Release(1_000_000); + } + else + { + _clientWriteShutdown = true; + _clientDataAvailable.Release(1_000_000); + } + } + public void BreakConnection() { if (!DisableConnectionBreaking) { - _connectionBroken = true; + _connectionBroken = !_serverWriteShutdown || !_clientWriteShutdown; _serverDataAvailable.Release(1_000_000); _clientDataAvailable.Release(1_000_000); } diff --git a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs new file mode 100644 index 000000000000..0a47a258057e --- /dev/null +++ b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs @@ -0,0 +1,187 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO; +using System.Net.Connections; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; + +namespace System.Net.Test.Common +{ + + internal sealed class VirtualNetworkConnectionListenerFactory : ConnectionListenerFactory + { + public static ConnectionFactory GetConnectionFactory(ConnectionListener listener) + { + bool hasFactory = listener.ListenerProperties.TryGet(out VirtualConnectionFactory factory); + Debug.Assert(hasFactory); + return factory; + } + + public override ValueTask BindAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) return ValueTask.FromCanceled(cancellationToken); + return new ValueTask(new VirtualConnectionListener(endPoint)); + } + + protected override void Dispose(bool disposing) + { + } + + protected override ValueTask DisposeAsyncCore() + { + return default; + } + + private sealed class VirtualConnectionListener : ConnectionListener, IConnectionProperties + { + private readonly Channel> _pendingConnects; + private readonly VirtualConnectionFactory _connectionFactory; + private readonly CancellationTokenSource _cts = new CancellationTokenSource(); + + public override IConnectionProperties ListenerProperties => this; + + public override EndPoint LocalEndPoint { get; } + + public VirtualConnectionListener(EndPoint localEndPoint) + { + LocalEndPoint = localEndPoint; + + _pendingConnects = Channel.CreateUnbounded>(); + _connectionFactory = new VirtualConnectionFactory(this); + } + + public override async ValueTask AcceptAsync(IConnectionProperties options = null, CancellationToken cancellationToken = default) + { + using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cancellationToken); + + var network = new VirtualNetwork(); + var serverConnection = new VirtualConnection(network, isServer: true); + var clientConnection = new VirtualConnection(network, isServer: false); + + while (true) + { + TaskCompletionSource tcs = await _pendingConnects.Reader.ReadAsync(cancellationToken); + if (tcs.TrySetResult(clientConnection)) + { + return serverConnection; + } + } + } + + internal async ValueTask ConnectAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) + { + var tcs = new TaskCompletionSource(); + await _pendingConnects.Writer.WriteAsync(tcs, cancellationToken).ConfigureAwait(false); + + using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cancellationToken)) + using (cts.Token.UnsafeRegister(o => ((TaskCompletionSource)o).TrySetCanceled(), tcs)) + { + return await tcs.Task.ConfigureAwait(false); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _cts.Cancel(); + } + } + + protected override ValueTask DisposeAsyncCore() + { + Dispose(true); + return default; + } + + bool IConnectionProperties.TryGet(Type propertyKey, out object property) + { + if (propertyKey == typeof(VirtualConnectionFactory)) + { + property = _connectionFactory; + return true; + } + + property = null; + return false; + } + } + + private sealed class VirtualConnectionFactory : ConnectionFactory + { + private readonly VirtualConnectionListener _listener; + + public VirtualConnectionFactory(VirtualConnectionListener listener) + { + _listener = listener; + } + + public override ValueTask ConnectAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) + { + return _listener.ConnectAsync(endPoint, options, cancellationToken); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _listener.Dispose(); + } + } + + protected override ValueTask DisposeAsyncCore() + { + return _listener.DisposeAsync(); + } + } + + private sealed class VirtualConnection : Connection, IConnectionProperties + { + private readonly VirtualNetwork _network; + private bool _isServer; + + public override IConnectionProperties ConnectionProperties => this; + + public override EndPoint LocalEndPoint => null; + + public override EndPoint RemoteEndPoint => null; + + public VirtualConnection(VirtualNetwork network, bool isServer) + { + _network = network; + _isServer = isServer; + } + + protected override Stream CreateStream() + { + return new VirtualNetworkStream(_network, _isServer, gracefulShutdown: true); + } + + protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) return ValueTask.FromCanceled(cancellationToken); + + if (method == ConnectionCloseMethod.GracefulShutdown) + { + _network.GracefulShutdown(_isServer); + } + else + { + _network.BreakConnection(); + } + + return default; + } + + bool IConnectionProperties.TryGet(Type propertyKey, out object property) + { + property = null; + return false; + } + } + } + +} diff --git a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs index 57705531ec2b..aa0fb2e4f3b1 100644 --- a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs +++ b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs @@ -12,13 +12,15 @@ internal class VirtualNetworkStream : Stream private readonly VirtualNetwork _network; private MemoryStream _readStream; private readonly bool _isServer; + private readonly bool _gracefulShutdown; private SemaphoreSlim _readStreamLock = new SemaphoreSlim(1, 1); private TaskCompletionSource _flushTcs; - public VirtualNetworkStream(VirtualNetwork network, bool isServer) + public VirtualNetworkStream(VirtualNetwork network, bool isServer, bool gracefulShutdown = false) { _network = network; _isServer = isServer; + _gracefulShutdown = gracefulShutdown; } public int DelayMilliseconds { get; set; } @@ -79,7 +81,10 @@ public override int Read(byte[] buffer, int offset, int count) { if (_readStream == null || (_readStream.Position >= _readStream.Length)) { - _readStream = new MemoryStream(_network.ReadFrame(_isServer)); + byte[] frame = _network.ReadFrame(_isServer); + if (frame.Length == 0) return 0; + + _readStream = new MemoryStream(frame); } return _readStream.Read(buffer, offset, count); @@ -102,7 +107,10 @@ public override async Task ReadAsync(byte[] buffer, int offset, int count, if (_readStream == null || (_readStream.Position >= _readStream.Length)) { - _readStream = new MemoryStream(await _network.ReadFrameAsync(_isServer, cancellationToken).ConfigureAwait(false)); + byte[] frame = await _network.ReadFrameAsync(_isServer, cancellationToken).ConfigureAwait(false); + if (frame.Length == 0) return 0; + + _readStream = new MemoryStream(frame); } return await _readStream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); @@ -147,10 +155,22 @@ protected override void Dispose(bool disposing) if (disposing) { Disposed = true; - _network.BreakConnection(); + if (_gracefulShutdown) + { + GracefulShutdown(); + } + else + { + _network.BreakConnection(); + } } base.Dispose(disposing); } + + public void GracefulShutdown() + { + _network.GracefulShutdown(_isServer); + } } } diff --git a/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs b/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs index 033cdd77029e..a2a6c5e087b2 100644 --- a/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs +++ b/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs @@ -60,6 +60,20 @@ public static async Task TimeoutAfter(this Task task, } } +#if !NETFRAMEWORK + public static Task TimeoutAfter(this ValueTask task, int millisecondsTimeout) + => task.AsTask().TimeoutAfter(TimeSpan.FromMilliseconds(millisecondsTimeout)); + + public static Task TimeoutAfter(this ValueTask task, TimeSpan timeout) + => task.AsTask().TimeoutAfter(timeout); + + public static Task TimeoutAfter(this ValueTask task, int millisecondsTimeout) + => task.AsTask().TimeoutAfter(TimeSpan.FromMilliseconds(millisecondsTimeout)); + + public static Task TimeoutAfter(this ValueTask task, TimeSpan timeout) + => task.AsTask().TimeoutAfter(timeout); +#endif + public static async Task WhenAllOrAnyFailed(this Task[] tasks, int millisecondsTimeout) { var cts = new CancellationTokenSource(); diff --git a/src/libraries/NetCoreAppLibrary.props b/src/libraries/NetCoreAppLibrary.props index 710e7b172db0..9b52e36fe43e 100644 --- a/src/libraries/NetCoreAppLibrary.props +++ b/src/libraries/NetCoreAppLibrary.props @@ -48,6 +48,7 @@ System.IO.FileSystem.Watcher; System.IO.IsolatedStorage; System.IO.MemoryMappedFiles; + System.IO.Pipelines; System.IO.Pipes; System.IO.Pipes.AccessControl; System.IO.UnmanagedMemoryStream; @@ -56,6 +57,7 @@ System.Linq.Parallel; System.Linq.Queryable; System.Memory; + System.Net.Connections; System.Net.Http; System.Net.Http.Json; System.Net.HttpListener; diff --git a/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj b/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj index da675e50fc19..517bc698cc6d 100644 --- a/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj +++ b/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj index a038d3552d1f..7cb28689989f 100644 --- a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj +++ b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj @@ -1,16 +1,21 @@ - netstandard2.0;net461 + $(NetCoreAppCurrent);netstandard2.0;net461 enable true netcoreapp2.0 + true - + + + + + diff --git a/src/libraries/System.Net.Connections/Directory.Build.props b/src/libraries/System.Net.Connections/Directory.Build.props new file mode 100644 index 000000000000..63f02a0f817e --- /dev/null +++ b/src/libraries/System.Net.Connections/Directory.Build.props @@ -0,0 +1,6 @@ + + + + Microsoft + + \ No newline at end of file diff --git a/src/libraries/System.Net.Connections/System.Net.Connections.sln b/src/libraries/System.Net.Connections/System.Net.Connections.sln new file mode 100644 index 000000000000..a325eb24b971 --- /dev/null +++ b/src/libraries/System.Net.Connections/System.Net.Connections.sln @@ -0,0 +1,50 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30310.162 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.Connections", "src\System.Net.Connections.csproj", "{1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}" + ProjectSection(ProjectDependencies) = postProject + {132BF813-FC40-4D39-8B6F-E55D7633F0ED} = {132BF813-FC40-4D39-8B6F-E55D7633F0ED} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.Connections", "ref\System.Net.Connections.csproj", "{132BF813-FC40-4D39-8B6F-E55D7633F0ED}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E0983BCC-F93B-4FFF-A4E4-EA874908783F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Connections.Tests", "tests\System.Net.Connections.Tests\System.Net.Connections.Tests.csproj", "{A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Release|Any CPU.Build.0 = Release|Any CPU + {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Release|Any CPU.Build.0 = Release|Any CPU + {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD} + {132BF813-FC40-4D39-8B6F-E55D7633F0ED} = {2E666815-2EDB-464B-9DF6-380BF4789AD4} + {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9} = {E0983BCC-F93B-4FFF-A4E4-EA874908783F} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5100F629-0FAB-4C6F-9A54-95AE9565EE0D} + EndGlobalSection +EndGlobal diff --git a/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs b/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs new file mode 100644 index 000000000000..c82551e09dc8 --- /dev/null +++ b/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs @@ -0,0 +1,74 @@ +// 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.Net.Connections +{ + public abstract partial class Connection : System.Net.Connections.ConnectionBase + { + protected Connection() { } + public System.IO.Pipelines.IDuplexPipe Pipe { get { throw null; } } + public System.IO.Stream Stream { get { throw null; } } + protected virtual System.IO.Pipelines.IDuplexPipe CreatePipe() { throw null; } + protected virtual System.IO.Stream CreateStream() { throw null; } + public static System.Net.Connections.Connection FromPipe(System.IO.Pipelines.IDuplexPipe pipe, bool leaveOpen = false, System.Net.Connections.IConnectionProperties? properties = null, System.Net.EndPoint? localEndPoint = null, System.Net.EndPoint? remoteEndPoint = null) { throw null; } + public static System.Net.Connections.Connection FromStream(System.IO.Stream stream, bool leaveOpen = false, System.Net.Connections.IConnectionProperties? properties = null, System.Net.EndPoint? localEndPoint = null, System.Net.EndPoint? remoteEndPoint = null) { throw null; } + } + public abstract partial class ConnectionBase : System.IAsyncDisposable, System.IDisposable + { + protected ConnectionBase() { } + public abstract System.Net.Connections.IConnectionProperties ConnectionProperties { get; } + public abstract System.Net.EndPoint? LocalEndPoint { get; } + public abstract System.Net.EndPoint? RemoteEndPoint { get; } + public System.Threading.Tasks.ValueTask CloseAsync(System.Net.Connections.ConnectionCloseMethod method = System.Net.Connections.ConnectionCloseMethod.GracefulShutdown, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected abstract System.Threading.Tasks.ValueTask CloseAsyncCore(System.Net.Connections.ConnectionCloseMethod method, System.Threading.CancellationToken cancellationToken); + public void Dispose() { } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + } + public enum ConnectionCloseMethod + { + GracefulShutdown = 0, + Abort = 1, + Immediate = 2, + } + public static partial class ConnectionExtensions + { + public static System.Net.Connections.ConnectionFactory Filter(this System.Net.Connections.ConnectionFactory factory, System.Func> filter) { throw null; } + public static bool TryGet(this System.Net.Connections.IConnectionProperties properties, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T property) { throw null; } + } + public abstract partial class ConnectionFactory : System.IAsyncDisposable, System.IDisposable + { + protected ConnectionFactory() { } + public abstract System.Threading.Tasks.ValueTask ConnectAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } + } + public abstract partial class ConnectionListener : System.IAsyncDisposable, System.IDisposable + { + protected ConnectionListener() { } + public abstract System.Net.Connections.IConnectionProperties ListenerProperties { get; } + public abstract System.Net.EndPoint? LocalEndPoint { get; } + public abstract System.Threading.Tasks.ValueTask AcceptAsync(System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } + } + public abstract partial class ConnectionListenerFactory : System.IAsyncDisposable, System.IDisposable + { + protected ConnectionListenerFactory() { } + public abstract System.Threading.Tasks.ValueTask BindAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } + } + public partial interface IConnectionProperties + { + bool TryGet(System.Type propertyKey, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? property); + } +} diff --git a/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj b/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj new file mode 100644 index 000000000000..b239637616b4 --- /dev/null +++ b/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj @@ -0,0 +1,14 @@ + + + $(NetCoreAppCurrent) + enable + + + + + + + + + + diff --git a/src/libraries/System.Net.Connections/src/Resources/Strings.resx b/src/libraries/System.Net.Connections/src/Resources/Strings.resx new file mode 100644 index 000000000000..004c0da9c849 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/Resources/Strings.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + The CreatePipe implementation returned null; a valid reference was expected. + + + The CreateStream implementation returned null; a valid reference was expected. + + + One of CreatePipe or CreateStream must be implemented + + + The Connection's Pipe may not be accessed after Stream has been accessed. + + + The Connection's Stream may not be accessed after Pipe has been accessed. + + + The PipeReader returned a zero-length read. + + \ No newline at end of file diff --git a/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj b/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj new file mode 100644 index 000000000000..c53e55947afb --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj @@ -0,0 +1,26 @@ + + + $(NetCoreAppCurrent) + enable + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs new file mode 100644 index 000000000000..8f7d479ce2a1 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs @@ -0,0 +1,265 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.IO.Pipelines; +using System.Runtime.ExceptionServices; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// A connection. + /// + public abstract class Connection : ConnectionBase + { + private Stream? _stream; + private IDuplexPipe? _pipe; + private bool _initializing; + + /// + /// The connection's . + /// + public Stream Stream => + _stream != null ? _stream : + _pipe != null ? throw new InvalidOperationException(SR.net_connections_stream_use_after_pipe) : + (_stream = CreateStream() ?? throw new InvalidOperationException(SR.net_connections_createstream_null)); + + /// + /// The connection's . + /// + public IDuplexPipe Pipe => + _pipe != null ? _pipe : + _stream != null ? throw new InvalidOperationException(SR.net_connections_pipe_use_after_stream) : + (_pipe = CreatePipe() ?? throw new InvalidOperationException(SR.net_connections_createpipe_null)); + + /// + /// Initializes the for the . + /// + /// A . + /// + /// At least one of and must be overridden. + /// If only is overridden, a user accessing will get a wrapping the . + /// + protected virtual Stream CreateStream() + { + if (_initializing) throw new InvalidOperationException(SR.net_connections_no_create_overrides); + + try + { + _initializing = true; + + IDuplexPipe pipe = CreatePipe(); + if (pipe == null) throw new InvalidOperationException(SR.net_connections_createpipe_null); + + return new DuplexPipeStream(pipe); + } + finally + { + _initializing = false; + } + } + + /// + /// Initializes the for the . + /// + /// An . + /// + /// At least one of and must be overridden. + /// If only is overridden, a user accessing will get a wrapping the . + /// + protected virtual IDuplexPipe CreatePipe() + { + if (_initializing) throw new InvalidOperationException(SR.net_connections_no_create_overrides); + + try + { + _initializing = true; + + Stream stream = CreateStream(); + if (stream == null) throw new InvalidOperationException(SR.net_connections_createstream_null); + + return new DuplexStreamPipe(stream); + } + finally + { + _initializing = false; + } + } + + private sealed class DuplexStreamPipe : IDuplexPipe + { + private static readonly StreamPipeReaderOptions s_readerOpts = new StreamPipeReaderOptions(leaveOpen: true); + private static readonly StreamPipeWriterOptions s_writerOpts = new StreamPipeWriterOptions(leaveOpen: true); + + public DuplexStreamPipe(Stream stream) + { + Input = PipeReader.Create(stream, s_readerOpts); + Output = PipeWriter.Create(stream, s_writerOpts); + } + + public PipeReader Input { get; } + + public PipeWriter Output { get; } + } + + /// + /// Creates a connection for a . + /// + /// The connection's . + /// If false, the will be disposed of once the connection has been closed. + /// The connection's . + /// The connection's . + /// The connection's . + /// A new . + public static Connection FromStream(Stream stream, bool leaveOpen = false, IConnectionProperties? properties = null, EndPoint? localEndPoint = null, EndPoint? remoteEndPoint = null) + { + if (stream == null) throw new ArgumentNullException(nameof(stream)); + return new ConnectionFromStream(stream, leaveOpen, properties, localEndPoint, remoteEndPoint); + } + + /// + /// Creates a connection for an . + /// + /// The connection's . + /// If false and the implements or , it will be disposed of once the connection has been closed. + /// The connection's . + /// The connection's . + /// The connection's . + /// A new . + public static Connection FromPipe(IDuplexPipe pipe, bool leaveOpen = false, IConnectionProperties? properties = null, EndPoint? localEndPoint = null, EndPoint? remoteEndPoint = null) + { + if (pipe == null) throw new ArgumentNullException(nameof(pipe)); + return new ConnectionFromPipe(pipe, leaveOpen, properties, localEndPoint, remoteEndPoint); + } + + private sealed class ConnectionFromStream : Connection, IConnectionProperties + { + private Stream? _originalStream; + private IConnectionProperties? _properties; + private readonly bool _leaveOpen; + + public override IConnectionProperties ConnectionProperties => _properties ?? this; + + public override EndPoint? LocalEndPoint { get; } + + public override EndPoint? RemoteEndPoint { get; } + + public ConnectionFromStream(Stream stream, bool leaveOpen, IConnectionProperties? properties, EndPoint? localEndPoint, EndPoint? remoteEndPoint) + { + _originalStream = stream; + _leaveOpen = leaveOpen; + _properties = properties; + LocalEndPoint = localEndPoint; + RemoteEndPoint = remoteEndPoint; + } + + protected override Stream CreateStream() => _originalStream ?? throw new ObjectDisposedException(nameof(Connection)); + + protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) + { + if (_originalStream == null) + { + return; + } + + if (method == ConnectionCloseMethod.GracefulShutdown) + { + await _originalStream.FlushAsync(cancellationToken).ConfigureAwait(false); + } + + if (!_leaveOpen) + { + await _originalStream.DisposeAsync().ConfigureAwait(false); + } + + _originalStream = null; + } + + bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) + { + property = null; + return false; + } + } + + private sealed class ConnectionFromPipe : Connection, IConnectionProperties + { + private IDuplexPipe? _originalPipe; + private IConnectionProperties? _properties; + private readonly bool _leaveOpen; + + public override IConnectionProperties ConnectionProperties => _properties ?? this; + + public override EndPoint? LocalEndPoint { get; } + + public override EndPoint? RemoteEndPoint { get; } + + public ConnectionFromPipe(IDuplexPipe pipe, bool leaveOpen, IConnectionProperties? properties, EndPoint? localEndPoint, EndPoint? remoteEndPoint) + { + _originalPipe = pipe; + _leaveOpen = leaveOpen; + _properties = properties; + LocalEndPoint = localEndPoint; + RemoteEndPoint = remoteEndPoint; + } + + protected override IDuplexPipe CreatePipe() => _originalPipe ?? throw new ObjectDisposedException(nameof(Connection)); + + protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) + { + if (_originalPipe == null) + { + return; + } + + Exception? inputException, outputException; + + if (method == ConnectionCloseMethod.GracefulShutdown) + { + // Flush happens implicitly from CompleteAsync(null), so only flush here if we need cancellation. + if (cancellationToken.CanBeCanceled) + { + FlushResult r = await _originalPipe.Output.FlushAsync(cancellationToken).ConfigureAwait(false); + if (r.IsCanceled) cancellationToken.ThrowIfCancellationRequested(); + } + + inputException = null; + outputException = null; + } + else + { + inputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); + outputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); + } + + await _originalPipe.Input.CompleteAsync(inputException).ConfigureAwait(false); + await _originalPipe.Output.CompleteAsync(outputException).ConfigureAwait(false); + + if (!_leaveOpen) + { + switch (_originalPipe) + { + case IAsyncDisposable d: + await d.DisposeAsync().ConfigureAwait(false); + break; + case IDisposable d: + d.Dispose(); + break; + } + } + + _originalPipe = null; + } + + bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) + { + property = null; + return false; + } + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs new file mode 100644 index 000000000000..027431babe2a --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// Provides base functionality shared between singular (e.g. TCP) and multiplexed (e.g. QUIC) connections. + /// + public abstract class ConnectionBase : IDisposable, IAsyncDisposable + { + private bool _disposed; + + /// + /// Properties exposed by this connection. + /// + public abstract IConnectionProperties ConnectionProperties { get; } + + /// + /// The local endpoint of this connection, if any. + /// + public abstract EndPoint? LocalEndPoint { get; } + + /// + /// The remote endpoint of this connection, if any. + /// + public abstract EndPoint? RemoteEndPoint { get; } + + /// + /// Closes the connection. + /// + /// The method to use when closing the connection. + /// A cancellation token for the asynchronous operation. + /// A for the asynchronous operation. + public async ValueTask CloseAsync(ConnectionCloseMethod method = ConnectionCloseMethod.GracefulShutdown, CancellationToken cancellationToken = default) + { + if (!_disposed) + { + await CloseAsyncCore(method, cancellationToken).ConfigureAwait(false); + _disposed = true; + } + GC.SuppressFinalize(this); + } + + /// + /// Closes the connection. + /// + /// The method to use when closing the connection. + /// A cancellation token for the asynchronous operation. + /// A for the asynchronous operation. + protected abstract ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken); + + /// + /// Disposes of the connection. + /// + /// + /// This is equivalent to calling with the method , and calling GetAwaiter().GetResult() on the resulting task. + /// To increase likelihood of synchronous completion, call directly with the method . + /// + public void Dispose() + { + ValueTask t = CloseAsync(ConnectionCloseMethod.GracefulShutdown, CancellationToken.None); + + if (t.IsCompleted) t.GetAwaiter().GetResult(); + else t.AsTask().GetAwaiter().GetResult(); + } + + /// + /// Disposes of the connection. + /// + /// A for the asynchronous operation. + /// This is equivalent to calling with the method . + public ValueTask DisposeAsync() + { + return CloseAsync(ConnectionCloseMethod.GracefulShutdown, CancellationToken.None); + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs new file mode 100644 index 000000000000..6b5a0792f4a4 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.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. + +namespace System.Net.Connections +{ + /// + /// Methods for closing a connection. + /// + public enum ConnectionCloseMethod + { + /// + /// The connection should be flushed and closed. + /// + GracefulShutdown, + + /// + /// The connection should be aborted gracefully, performing any I/O needed to notify the other side of the connection that it has been aborted. + /// + Abort, + + /// + /// The connection should be aborted immediately, avoiding any I/O needed to notify the other side of the connection that it has been aborted. + /// + Immediate + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs new file mode 100644 index 000000000000..6850247f3606 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs @@ -0,0 +1,87 @@ +// 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.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// Extension methods for working with the System.Net.Connections types. + /// + public static class ConnectionExtensions + { + /// + /// Retrieves a Type-based property from an , if it exists. + /// + /// The type of the property to retrieve. + /// The connection properties to retrieve a property from. + /// If contains a property of type , receives the property. Otherwise, default. + /// If contains a property of type , true. Otherwise, false. + public static bool TryGet(this IConnectionProperties properties, [MaybeNullWhen(false)] out T property) + { + if (properties == null) throw new ArgumentNullException(nameof(properties)); + + if (properties.TryGet(typeof(T), out object? obj) && obj is T propertyValue) + { + property = propertyValue; + return true; + } + else + { + property = default; + return false; + } + } + + /// + /// Creates a connection-level filter on top of a . + /// + /// The factory to be filtered. + /// The connection-level filter to apply on top of . + /// A new filtered . + public static ConnectionFactory Filter(this ConnectionFactory factory, Func> filter) + { + if (factory == null) throw new ArgumentNullException(nameof(factory)); + if (filter == null) throw new ArgumentNullException(nameof(filter)); + return new ConnectionFilteringFactory(factory, filter); + } + + private sealed class ConnectionFilteringFactory : ConnectionFactory + { + private readonly ConnectionFactory _baseFactory; + private readonly Func> _filter; + + public ConnectionFilteringFactory(ConnectionFactory baseFactory, Func> filter) + { + _baseFactory = baseFactory; + _filter = filter; + } + + public override async ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) + { + Connection con = await _baseFactory.ConnectAsync(endPoint, options, cancellationToken).ConfigureAwait(false); + try + { + return await _filter(con, options, cancellationToken).ConfigureAwait(false); + } + catch + { + await con.CloseAsync(ConnectionCloseMethod.Abort, cancellationToken).ConfigureAwait(false); + throw; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) _baseFactory.Dispose(); + } + + protected override ValueTask DisposeAsyncCore() + { + return _baseFactory.DisposeAsync(); + } + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs new file mode 100644 index 000000000000..812f78a6ae6e --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// A factory for opening outgoing connections. + /// + public abstract class ConnectionFactory : IAsyncDisposable, IDisposable + { + /// + /// Opens a new . + /// + /// The to connect to, if any. + /// Options used to create the connection, if any. + /// A token used to cancel the asynchronous operation. + /// A for the . + public abstract ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore().ConfigureAwait(false); + GC.SuppressFinalize(this); + } + + /// + /// Disposes the . + /// + /// If true, the is being disposed. If false, the is being finalized. + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Asynchronously disposes the . + /// + /// A representing the asynchronous dispose operation. + protected virtual ValueTask DisposeAsyncCore() + { + Dispose(true); + return default; + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs new file mode 100644 index 000000000000..299ba0d66350 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// A listener to accept incoming connections. + /// + public abstract class ConnectionListener : IAsyncDisposable, IDisposable + { + /// + /// Properties exposed by this listener. + /// + public abstract IConnectionProperties ListenerProperties { get; } + + /// + /// The local endpoint of this connection, if any. + /// + public abstract EndPoint? LocalEndPoint { get; } + + /// + /// Accepts an incoming connection. + /// + /// Options used to create the connection, if any. + /// A token used to cancel the asynchronous operation. + /// A for the . + public abstract ValueTask AcceptAsync(IConnectionProperties? options = null, CancellationToken cancellationToken = default); + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore().ConfigureAwait(false); + GC.SuppressFinalize(this); + } + + /// + /// Disposes the . + /// + /// If true, the is being disposed. If false, the is being finalized. + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Asynchronously disposes the . + /// + /// A representing the asynchronous dispose operation. + protected virtual ValueTask DisposeAsyncCore() + { + Dispose(true); + return default; + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs new file mode 100644 index 000000000000..d208f05a5d47 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + /// + /// A factory for creating connection listeners, to accept incoming connections. + /// + public abstract class ConnectionListenerFactory : IAsyncDisposable, IDisposable + { + public abstract ValueTask BindAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore().ConfigureAwait(false); + GC.SuppressFinalize(this); + } + + /// + /// Disposes the . + /// + /// If true, the is being disposed. If false, the is being finalized. + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Asynchronously disposes the . + /// + /// A representing the asynchronous dispose operation. + protected virtual ValueTask DisposeAsyncCore() + { + Dispose(true); + return default; + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs new file mode 100644 index 000000000000..3319c972b582 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.IO; +using System.IO.Pipelines; +using System.Runtime.ExceptionServices; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + internal sealed class DuplexPipeStream : Stream + { + private readonly PipeReader _reader; + private readonly PipeWriter _writer; + + public override bool CanRead => true; + public override bool CanSeek => false; + public override bool CanWrite => true; + public override long Length => throw new NotSupportedException(); + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } + + public DuplexPipeStream(IDuplexPipe pipe) + { + _reader = pipe.Input; + _writer = pipe.Output; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _reader.Complete(); + _writer.Complete(); + } + base.Dispose(disposing); + } + + public override async ValueTask DisposeAsync() + { + await _reader.CompleteAsync().ConfigureAwait(false); + await _writer.CompleteAsync().ConfigureAwait(false); + } + + public override void Flush() + { + FlushAsync().GetAwaiter().GetResult(); + } + + public override async Task FlushAsync(CancellationToken cancellationToken) + { + FlushResult r = await _writer.FlushAsync(cancellationToken).ConfigureAwait(false); + if (r.IsCanceled) throw new OperationCanceledException(cancellationToken); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (buffer == null) throw new ArgumentNullException(nameof(buffer)); + + ValueTask t = ReadAsync(buffer.AsMemory(offset, count)); + return + t.IsCompleted ? t.GetAwaiter().GetResult() : + t.AsTask().GetAwaiter().GetResult(); + } + + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (buffer == null) return Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ArgumentNullException(nameof(buffer)))); + return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + { + ReadResult result = await _reader.ReadAsync(cancellationToken).ConfigureAwait(false); + + if (result.IsCanceled) + { + throw new OperationCanceledException(); + } + + ReadOnlySequence sequence = result.Buffer; + long bufferLength = sequence.Length; + SequencePosition consumed = sequence.Start; + + try + { + if (bufferLength != 0) + { + int actual = (int)Math.Min(bufferLength, buffer.Length); + + ReadOnlySequence slice = actual == bufferLength ? sequence : sequence.Slice(0, actual); + consumed = slice.End; + slice.CopyTo(buffer.Span); + + return actual; + } + + if (result.IsCompleted) + { + return 0; + } + } + finally + { + _reader.AdvanceTo(consumed); + } + + // This is a buggy PipeReader implementation that returns 0 byte reads even though the PipeReader + // isn't completed or canceled. + throw new InvalidOperationException(SR.net_connections_zero_byte_pipe_read); + } + + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) + { + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); + } + + public override int EndRead(IAsyncResult asyncResult) + { + return TaskToApm.End(asyncResult); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); + } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + FlushResult r = await _writer.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); + if (r.IsCanceled) throw new OperationCanceledException(cancellationToken); + } + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) + { + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); + } + + public override void EndWrite(IAsyncResult asyncResult) + { + TaskToApm.End(asyncResult); + } + + public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + { + return _reader.CopyToAsync(destination, cancellationToken); + } + } +} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs new file mode 100644 index 000000000000..ce89dd97a216 --- /dev/null +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace System.Net.Connections +{ + /// + /// A container for connection properties. + /// + public interface IConnectionProperties + { + /// + /// Retrieves a connection property, if it exists. + /// + /// The key of the property to retrieve. + /// If the property was found, retrieves the property. Otherwise, null. + /// If the property was found, true. Otherwise, false. + bool TryGet(Type propertyKey, [NotNullWhen(true)] out object? property); + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs new file mode 100644 index 000000000000..66cc4a2352bc --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Connections.Tests +{ + public class ConnectionBaseTest + { + [Fact] + public void Dispose_CallsClose_Success() + { + ConnectionCloseMethod? method = null; + + var con = new MockConnection(); + con.OnCloseAsyncCore = (m, t) => + { + method = m; + return default(ValueTask); + }; + + con.Dispose(); + + Assert.Equal(ConnectionCloseMethod.GracefulShutdown, method); + } + + [Fact] + public async Task DisposeAsync_CallsClose_Success() + { + ConnectionCloseMethod? method = null; + + var con = new MockConnection(); + con.OnCloseAsyncCore = (m, t) => + { + method = m; + return default(ValueTask); + }; + + await con.DisposeAsync(); + + Assert.Equal(ConnectionCloseMethod.GracefulShutdown, method); + } + + [Fact] + public void Dispose_CalledOnce_Success() + { + int callCount = 0; + + var con = new MockConnection(); + con.OnCloseAsyncCore = delegate + { + ++callCount; + return default(ValueTask); + }; + + con.Dispose(); + con.Dispose(); + + Assert.Equal(1, callCount); + } + + [Fact] + public async Task DisposeAsync_CalledOnce_Success() + { + int callCount = 0; + + var con = new MockConnection(); + con.OnCloseAsyncCore = delegate + { + ++callCount; + return default(ValueTask); + }; + + await con.DisposeAsync(); + await con.DisposeAsync(); + + Assert.Equal(1, callCount); + } + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs new file mode 100644 index 000000000000..ad16e45fc6cf --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs @@ -0,0 +1,264 @@ +// 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.IO; +using System.IO.Pipelines; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Connections.Tests +{ + public class ConnectionTest + { + [Fact] + public void CreateStream_CalledOnce_Success() + { + int callCount = 0; + + var con = new MockConnection(); + con.OnCreateStream = () => + { + ++callCount; + return new MemoryStream(); + }; + + _ = con.Stream; + _ = con.Stream; + + Assert.Equal(1, callCount); + } + + [Fact] + public void CreatePipe_CalledOnce_Success() + { + int callCount = 0; + + var con = new MockConnection(); + con.OnCreatePipe = () => + { + ++callCount; + return new MockPipe(); + }; + + _ = con.Pipe; + _ = con.Pipe; + + Assert.Equal(1, callCount); + } + + [Fact] + public void AccessStream_AccessPipe_Fail() + { + var con = new MockConnection(); + con.OnCreateStream = () => new MemoryStream(); + + _ = con.Stream; + Assert.Throws(() => _ = con.Pipe); + } + + [Fact] + public void AccessPipe_AccessStream_Fail() + { + var con = new MockConnection(); + con.OnCreatePipe = () => new MockPipe(); + + _ = con.Pipe; + Assert.Throws(() => _ = con.Stream); + } + + [Fact] + public void AccessStream_NoOverloads_Fail() + { + var con = new ConnectionWithoutStreamOrPipe(); + Assert.Throws(() => _ = con.Stream); + } + + [Fact] + public void AccessPipe_NoOverloads_Fail() + { + var con = new ConnectionWithoutStreamOrPipe(); + Assert.Throws(() => _ = con.Pipe); + } + + [Fact] + public async Task WrappedStream_Success() + { + var bytesA = Encoding.ASCII.GetBytes("foo"); + var bytesB = Encoding.ASCII.GetBytes("bar"); + + var stream = new MemoryStream(); + stream.Write(bytesA); + stream.Position = 0; + + var con = new MockConnection(); + con.OnCreateStream = () => stream; + + IDuplexPipe pipe = con.Pipe; + + ReadResult res = await pipe.Input.ReadAsync(); + Assert.Equal(bytesA, res.Buffer.ToArray()); + + await pipe.Output.WriteAsync(bytesB); + Assert.Equal(bytesA.Concat(bytesB).ToArray(), stream.ToArray()); + } + + [Fact] + public async Task WrappedPipe_Success() + { + var bytesA = Encoding.ASCII.GetBytes("foo"); + var bytesB = Encoding.ASCII.GetBytes("bar"); + + var stream = new MemoryStream(); + stream.Write(bytesA); + stream.Position = 0; + + var pipe = new MockPipe + { + Input = PipeReader.Create(stream), + Output = PipeWriter.Create(stream) + }; + + var con = new MockConnection(); + con.OnCreatePipe = () => pipe; + + Stream s = con.Stream; + + var readBuffer = new byte[4]; + int len = await s.ReadAsync(readBuffer); + Assert.Equal(3, len); + Assert.Equal(bytesA, readBuffer.AsSpan(0, len).ToArray()); + + await s.WriteAsync(bytesB); + Assert.Equal(bytesA.Concat(bytesB).ToArray(), stream.ToArray()); + } + + [Theory] + [InlineData(ConnectionCloseMethod.GracefulShutdown, true)] + [InlineData(ConnectionCloseMethod.Abort, false)] + [InlineData(ConnectionCloseMethod.Immediate, false)] + public async Task FromStream_CloseMethod_Flushed(ConnectionCloseMethod method, bool shouldFlush) + { + bool streamFlushed = false; + + var stream = new MockStream + { + OnFlushAsync = _ => { streamFlushed = true; return Task.CompletedTask; } + }; + + var con = Connection.FromStream(stream, leaveOpen: true); + + await con.CloseAsync(method); + Assert.Equal(shouldFlush, streamFlushed); + } + + [Theory] + [InlineData(ConnectionCloseMethod.GracefulShutdown, true)] + [InlineData(ConnectionCloseMethod.Abort, false)] + [InlineData(ConnectionCloseMethod.Immediate, false)] + public async Task FromPipe_CloseMethod_Flushed(ConnectionCloseMethod method, bool shouldFlush) + { + bool pipeFlushed = false; + + var pipe = new MockPipe + { + Input = new MockPipeReader() + { + OnCompleteAsync = _ => default + }, + Output = new MockPipeWriter() + { + OnFlushAsync = _ => { pipeFlushed = true; return default; }, + OnCompleteAsync = _ => default + } + }; + + var con = Connection.FromPipe(pipe); + + await con.CloseAsync(method, new CancellationTokenSource().Token); + Assert.Equal(shouldFlush, pipeFlushed); + } + + [Theory] + [InlineData(true, false)] + [InlineData(false, true)] + public async Task FromStream_LeaveOpen_StreamDisposed(bool leaveOpen, bool shouldDispose) + { + bool streamDisposed = false; + + var stream = new MockStream(); + stream.OnDisposeAsync = delegate { streamDisposed = true; return default; }; + + var con = Connection.FromStream(stream, leaveOpen); + + await con.CloseAsync(ConnectionCloseMethod.Immediate); + Assert.Equal(shouldDispose, streamDisposed); + } + + [Theory] + [InlineData(true, false)] + [InlineData(false, true)] + public async Task FromPipe_LeaveOpen_PipeDisposed(bool leaveOpen, bool shouldDispose) + { + bool pipeDisposed = false; + + var pipe = new MockPipe + { + OnDisposeAsync = () => { pipeDisposed = true; return default; }, + Input = new MockPipeReader() + { + OnCompleteAsync = _ => default + }, + Output = new MockPipeWriter() + { + OnFlushAsync = _ => default, + OnCompleteAsync = _ => default + } + }; + + var con = Connection.FromPipe(pipe, leaveOpen); + + await con.CloseAsync(ConnectionCloseMethod.Immediate); + Assert.Equal(shouldDispose, pipeDisposed); + } + + [Fact] + public void FromStream_PropertiesInitialized() + { + var properties = new DummyConnectionProperties(); + var localEndPoint = new IPEndPoint(IPAddress.Any, 1); + var remoteEndPoint = new IPEndPoint(IPAddress.Any, 2); + + Connection c = Connection.FromStream(new MockStream(), leaveOpen: false, properties, localEndPoint, remoteEndPoint); + Assert.Same(properties, c.ConnectionProperties); + Assert.Same(localEndPoint, c.LocalEndPoint); + Assert.Same(remoteEndPoint, c.RemoteEndPoint); + } + + [Fact] + public void FromPipe_PropertiesInitialized() + { + var properties = new DummyConnectionProperties(); + var localEndPoint = new IPEndPoint(IPAddress.Any, 1); + var remoteEndPoint = new IPEndPoint(IPAddress.Any, 2); + + Connection c = Connection.FromPipe(new MockPipe(), leaveOpen: false, properties, localEndPoint, remoteEndPoint); + Assert.Same(properties, c.ConnectionProperties); + Assert.Same(localEndPoint, c.LocalEndPoint); + Assert.Same(remoteEndPoint, c.RemoteEndPoint); + } + + private sealed class DummyConnectionProperties : IConnectionProperties + { + public bool TryGet(Type propertyKey, [NotNullWhen(true)] out object property) + { + throw new NotImplementedException(); + } + } + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs new file mode 100644 index 000000000000..16e52387b1d6 --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class ConnectionWithoutStreamOrPipe : Connection + { + public override IConnectionProperties ConnectionProperties => throw new NotImplementedException(); + + public override EndPoint LocalEndPoint => throw new NotImplementedException(); + + public override EndPoint RemoteEndPoint => throw new NotImplementedException(); + + protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs new file mode 100644 index 000000000000..f1acf758fef8 --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class MockConnection : Connection + { + public Func OnConnectionProperties { get; set; } + public Func OnLocalEndPoint { get; set; } + public Func OnRemoteEndPoint { get; set; } + public Func OnCloseAsyncCore { get; set; } + public Func OnCreatePipe { get; set; } + public Func OnCreateStream { get; set; } + + public override IConnectionProperties ConnectionProperties => OnConnectionProperties(); + + public override EndPoint LocalEndPoint => OnLocalEndPoint(); + + public override EndPoint RemoteEndPoint => OnRemoteEndPoint(); + + protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) => + OnCloseAsyncCore(method, cancellationToken); + + protected override IDuplexPipe CreatePipe() => OnCreatePipe != null ? OnCreatePipe() : base.CreatePipe(); + + protected override Stream CreateStream() => OnCreateStream != null ? OnCreateStream() : base.CreateStream(); + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs new file mode 100644 index 000000000000..6abbb9a7cc62 --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Pipelines; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class MockPipe : IDuplexPipe, IAsyncDisposable + { + public Func OnDisposeAsync { get; set; } + public PipeReader Input { get; set; } + + public PipeWriter Output { get; set; } + + public ValueTask DisposeAsync() + { + return OnDisposeAsync?.Invoke() ?? default; + } + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs new file mode 100644 index 000000000000..2413bf10a77d --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class MockPipeReader : PipeReader + { + public Action OnAdvanceTo { get; set; } + public Action OnCancelPendingRead { get; set; } + public Action OnComplete { get; set; } + public Func OnCompleteAsync { get; set; } + public Func> OnReadAsync { get; set; } + public Func OnTryRead { get; set; } + + public override void AdvanceTo(SequencePosition consumed) + => OnAdvanceTo(consumed, consumed); + + public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) + => OnAdvanceTo(consumed, examined); + + public override void CancelPendingRead() + => OnCancelPendingRead(); + + public override void Complete(Exception exception = null) + => OnComplete(exception); + + public override ValueTask ReadAsync(CancellationToken cancellationToken = default) + => OnReadAsync(cancellationToken); + + public override bool TryRead(out ReadResult result) + { + ReadResult? r = OnTryRead(); + result = r.GetValueOrDefault(); + return r.HasValue; + } + + public override ValueTask CompleteAsync(Exception exception = null) + => OnCompleteAsync(exception); + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs new file mode 100644 index 000000000000..7c35e19a0ae5 --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class MockPipeWriter : PipeWriter + { + public Action OnAdvance { get; set; } + public Action OnCancelPendingFlush { get; set; } + public Action OnComplete { get; set; } + public Func OnCompleteAsync { get; set; } + public Func> OnFlushAsync { get; set; } + public Func> OnGetMemory { get; set; } + + public override void Advance(int bytes) + => OnAdvance(bytes); + + public override void CancelPendingFlush() + => OnCancelPendingFlush(); + + public override void Complete(Exception exception = null) + => OnComplete(exception); + + public override ValueTask CompleteAsync(Exception exception = null) + => OnCompleteAsync(exception); + + public override ValueTask FlushAsync(CancellationToken cancellationToken = default) + => OnFlushAsync(cancellationToken); + + public override Memory GetMemory(int sizeHint = 0) + => OnGetMemory(sizeHint); + + public override Span GetSpan(int sizeHint = 0) + => GetMemory(sizeHint).Span; + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs new file mode 100644 index 000000000000..50dbc31ab11c --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections.Tests +{ + internal class MockStream : Stream + { + public Func, CancellationToken, ValueTask> OnReadAsync { get; set; } + public Func, CancellationToken, ValueTask> OnWriteAsync { get; set; } + public Func OnFlushAsync { get; set; } + public Func OnDisposeAsync { get; set; } + + public override bool CanRead => true; + + public override bool CanSeek => false; + + public override bool CanWrite => true; + + public override long Length => throw new NotImplementedException(); + + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + protected override void Dispose(bool disposing) + { + if (disposing) DisposeAsync().AsTask().GetAwaiter().GetResult(); + } + + public override ValueTask DisposeAsync() + { + return OnDisposeAsync(); + } + + public override void Flush() + { + FlushAsync().GetAwaiter().GetResult(); + } + + public override Task FlushAsync(CancellationToken cancellationToken) + { + return OnFlushAsync(cancellationToken); + } + + public override int Read(byte[] buffer, int offset, int count) + { + return ReadAsync(buffer, offset, count).GetAwaiter().GetResult(); + } + + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + { + return OnReadAsync(buffer, cancellationToken); + } + + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); + } + + public override int EndRead(IAsyncResult asyncResult) + { + return TaskToApm.End(asyncResult); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + WriteAsync(buffer, offset, count).GetAwaiter().GetResult(); + } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + return OnWriteAsync(buffer, cancellationToken); + } + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); + } + + public override void EndWrite(IAsyncResult asyncResult) + { + TaskToApm.End(asyncResult); + } + } +} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj new file mode 100644 index 000000000000..9aa01126533b --- /dev/null +++ b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj @@ -0,0 +1,19 @@ + + + + $(NetCoreAppCurrent) + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 3386d321c045..31db0e5b710b 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -282,11 +282,21 @@ protected override void SerializeToStream(System.IO.Stream stream, System.Net.Tr protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } + public partial class SocketsHttpConnectionFactory : System.Net.Connections.ConnectionFactory + { + public SocketsHttpConnectionFactory() { } + public sealed override System.Threading.Tasks.ValueTask ConnectAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Net.Sockets.Socket CreateSocket(System.Net.Http.HttpRequestMessage message, System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties options) { throw null; } + protected override void Dispose(bool disposing) { } + protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } + public virtual System.Threading.Tasks.ValueTask EstablishConnectionAsync(System.Net.Http.HttpRequestMessage message, System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties options, System.Threading.CancellationToken cancellationToken) { throw null; } + } public sealed partial class SocketsHttpHandler : System.Net.Http.HttpMessageHandler { public SocketsHttpHandler() { } public bool AllowAutoRedirect { get { throw null; } set { } } public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } } + public System.Net.Connections.ConnectionFactory? ConnectionFactory { get { throw null; } set { } } public System.TimeSpan ConnectTimeout { get { throw null; } set { } } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public System.Net.CookieContainer CookieContainer { get { throw null; } set { } } @@ -297,6 +307,7 @@ public SocketsHttpHandler() { } public int MaxConnectionsPerServer { get { throw null; } set { } } public int MaxResponseDrainSize { get { throw null; } set { } } public int MaxResponseHeadersLength { get { throw null; } set { } } + public System.Func>? PlaintextFilter { get { throw null; } set { } } public System.TimeSpan PooledConnectionIdleTimeout { get { throw null; } set { } } public System.TimeSpan PooledConnectionLifetime { get { throw null; } set { } } public bool PreAuthenticate { get { throw null; } set { } } diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj index 9f96fca1d9e6..296b6c0cdb1b 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj @@ -9,6 +9,8 @@ + + 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 62a033499f44..57326769d64a 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -169,6 +169,10 @@ + + + + + @@ -672,7 +677,9 @@ + + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs new file mode 100644 index 000000000000..664de02694ba --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs @@ -0,0 +1,19 @@ +using System.Threading; +using System.Threading.Tasks; +using System.Net.Connections; +using System.Net.Sockets; + +namespace System.Net.Http +{ + public class SocketsHttpConnectionFactory : ConnectionFactory + { + public sealed override ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) + => throw new NotImplementedException(); + + public virtual Socket CreateSocket(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options) + => throw new NotImplementedException(); + + public virtual ValueTask EstablishConnectionAsync(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options, CancellationToken cancellationToken) + => throw new NotImplementedException(); + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs index 4644b8b6a195..657d0033984c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; +using System.Net.Connections; namespace System.Net.Http { @@ -127,6 +128,18 @@ public TimeSpan Expect100ContinueTimeout set => throw new PlatformNotSupportedException(); } + public ConnectionFactory? ConnectionFactory + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public Func>? PlaintextFilter + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public IDictionary Properties => throw new PlatformNotSupportedException(); protected internal override Task SendAsync( 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 48d530c2a03e..467e813c49ac 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 @@ -3,11 +3,10 @@ using System.Diagnostics; using System.IO; +using System.Net.Connections; using System.Net.Quic; using System.Net.Security; using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -33,58 +32,23 @@ public CertificateCallbackMapper(Func ConnectAsync(string host, int port, bool async, CancellationToken cancellationToken) + public static async ValueTask ConnectAsync(ConnectionFactory factory, DnsEndPoint endPoint, IConnectionProperties? options, CancellationToken cancellationToken) { - return async ? ConnectAsync(host, port, cancellationToken) : new ValueTask(Connect(host, port, cancellationToken)); - } - - private static async ValueTask ConnectAsync(string host, int port, CancellationToken cancellationToken) - { - // Rather than creating a new Socket and calling ConnectAsync on it, we use the static - // Socket.ConnectAsync with a SocketAsyncEventArgs, as we can then use Socket.CancelConnectAsync - // to cancel it if needed. - var saea = new ConnectEventArgs(); try { - saea.Initialize(cancellationToken); - - // Configure which server to which to connect. - saea.RemoteEndPoint = new DnsEndPoint(host, port); - - // Initiate the connection. - if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, saea)) - { - // Connect completing asynchronously. Enable it to be canceled and wait for it. - using (cancellationToken.UnsafeRegister(static s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), saea)) - { - await saea.Builder.Task.ConfigureAwait(false); - } - } - else if (saea.SocketError != SocketError.Success) - { - // Connect completed synchronously but unsuccessfully. - throw new SocketException((int)saea.SocketError); - } - - Debug.Assert(saea.SocketError == SocketError.Success, $"Expected Success, got {saea.SocketError}."); - Debug.Assert(saea.ConnectSocket != null, "Expected non-null socket"); - - // Configure the socket and return a stream for it. - Socket socket = saea.ConnectSocket; - socket.NoDelay = true; - return new NetworkStream(socket, ownsSocket: true); + return await factory.ConnectAsync(endPoint, options, cancellationToken).ConfigureAwait(false); } - catch (Exception error) when (!(error is OperationCanceledException)) + catch (OperationCanceledException ex) when (ex.CancellationToken == cancellationToken) { - throw CreateWrappedException(error, host, port, cancellationToken); + throw CancellationHelper.CreateOperationCanceledException(innerException: null, cancellationToken); } - finally + catch (Exception ex) { - saea.Dispose(); + throw CreateWrappedException(ex, endPoint.Host, endPoint.Port, cancellationToken); } } - private static Stream Connect(string host, int port, CancellationToken cancellationToken) + public static Connection Connect(string host, int port, CancellationToken cancellationToken) { // For synchronous connections, we can just create a socket and make the connection. cancellationToken.ThrowIfCancellationRequested(); @@ -96,59 +60,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); } - } - - /// SocketAsyncEventArgs that carries with it additional state for a Task builder and a CancellationToken. - private sealed class ConnectEventArgs : SocketAsyncEventArgs - { - internal ConnectEventArgs() : - // The OnCompleted callback serves just to complete a task that's awaited in ConnectAsync, - // so we don't need to also flow ExecutionContext again into the OnCompleted callback. - base(unsafeSuppressExecutionContextFlow: true) - { - } - - public AsyncTaskMethodBuilder Builder { get; private set; } - public CancellationToken CancellationToken { get; private set; } - public void Initialize(CancellationToken cancellationToken) - { - CancellationToken = cancellationToken; - AsyncTaskMethodBuilder b = default; - _ = b.Task; // force initialization - Builder = b; - } - - protected override void OnCompleted(SocketAsyncEventArgs _) - { - switch (SocketError) - { - case SocketError.Success: - Builder.SetResult(); - break; - - case SocketError.OperationAborted: - case SocketError.ConnectionAborted: - if (CancellationToken.IsCancellationRequested) - { - Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(CancellationHelper.CreateOperationCanceledException(null, CancellationToken))); - break; - } - goto default; - - default: - Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new SocketException((int)SocketError))); - break; - } - } + return new SocketConnection(socket); } public static ValueTask EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/SocketConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/SocketConnection.cs new file mode 100644 index 000000000000..37b6f8361d98 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/SocketConnection.cs @@ -0,0 +1,101 @@ +// 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.IO; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Connections +{ + internal sealed class SocketConnection : Connection, IConnectionProperties + { + private readonly SocketConnectionNetworkStream _stream; + + public override EndPoint? RemoteEndPoint => _stream.Socket.RemoteEndPoint; + public override EndPoint? LocalEndPoint => _stream.Socket.LocalEndPoint; + public override IConnectionProperties ConnectionProperties => this; + + public SocketConnection(Socket socket) + { + _stream = new SocketConnectionNetworkStream(socket, this); + } + + protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return ValueTask.FromCanceled(cancellationToken); + } + + try + { + if (method != ConnectionCloseMethod.GracefulShutdown) + { + // Dispose must be called first in order to cause a connection reset, + // as NetworkStream.Dispose() will call Shutdown(Both). + _stream.Socket.Dispose(); + } + + _stream.DisposeWithoutClosingConnection(); + } + catch (Exception ex) + { + return ValueTask.FromException(ex); + } + + return default; + } + + protected override Stream CreateStream() => _stream; + + bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) + { + if (propertyKey == typeof(Socket)) + { + property = _stream.Socket; + return true; + } + + property = null; + return false; + } + + // This is done to couple disposal of the SocketConnection and the NetworkStream. + private sealed class SocketConnectionNetworkStream : NetworkStream + { + private readonly SocketConnection _connection; + + public SocketConnectionNetworkStream(Socket socket, SocketConnection connection) : base(socket, ownsSocket: true) + { + _connection = connection; + } + + public void DisposeWithoutClosingConnection() + { + base.Dispose(true); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // This will call base.Dispose(). + _connection.Dispose(); + } + else + { + base.Dispose(disposing); + } + } + + public override ValueTask DisposeAsync() + { + // This will call base.Dispose(). + Dispose(true); + return default; + } + } + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/TaskSocketAsyncEventArgs.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/TaskSocketAsyncEventArgs.cs new file mode 100644 index 000000000000..7bf8947215a4 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Connections/TaskSocketAsyncEventArgs.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. + +using System.Net.Sockets; +using System.Threading.Tasks; +using System.Threading.Tasks.Sources; + +namespace System.Net.Connections +{ + internal sealed class TaskSocketAsyncEventArgs : SocketAsyncEventArgs, IValueTaskSource + { + private ManualResetValueTaskSourceCore _valueTaskSource; + + public void ResetTask() => _valueTaskSource.Reset(); + public ValueTask Task => new ValueTask(this, _valueTaskSource.Version); + + public void GetResult(short token) => _valueTaskSource.GetResult(token); + public ValueTaskSourceStatus GetStatus(short token) => _valueTaskSource.GetStatus(token); + public void OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _valueTaskSource.OnCompleted(continuation, state, token, flags); + public void Complete() => _valueTaskSource.SetResult(0); + + public TaskSocketAsyncEventArgs() + : base(unsafeSuppressExecutionContextFlow: true) + { + } + + protected override void OnCompleted(SocketAsyncEventArgs e) + { + _valueTaskSource.SetResult(0); + } + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs new file mode 100644 index 000000000000..b99801c1fac1 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Net.Connections; + +namespace System.Net.Http +{ + // Passed to a connection factory, merges allocations for the DnsEndPoint and connection properties. + internal sealed class DnsEndPointWithProperties : DnsEndPoint, IConnectionProperties + { + public HttpRequestMessage InitialRequest { get; } + + public DnsEndPointWithProperties(string host, int port, HttpRequestMessage initialRequest) : base(host, port) + { + InitialRequest = initialRequest; + } + + bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) + { + if (propertyKey == typeof(DnsEndPointWithProperties)) + { + property = this; + return true; + } + + property = null; + return false; + } + } +} 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 b21fd4a00b09..1bd39f4ca9ba 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 @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Net.Connections; using System.Net.Http.Headers; using System.Net.Http.HPack; using System.Net.Security; @@ -21,6 +22,7 @@ internal sealed partial class Http2Connection : HttpConnectionBase, IDisposable { private readonly HttpConnectionPool _pool; private readonly Stream _stream; + private readonly Connection _connection; // NOTE: These are mutable structs; do not make these readonly. private ArrayBuffer _incomingBuffer; @@ -94,10 +96,11 @@ internal sealed partial class Http2Connection : HttpConnectionBase, IDisposable // Channel options for creating _writeChannel private static readonly UnboundedChannelOptions s_channelOptions = new UnboundedChannelOptions() { SingleReader = true }; - public Http2Connection(HttpConnectionPool pool, Stream stream) + public Http2Connection(HttpConnectionPool pool, Connection connection) { _pool = pool; - _stream = stream; + _stream = connection.Stream; + _connection = connection; _incomingBuffer = new ArrayBuffer(InitialConnectionBufferSize); _outgoingBuffer = new ArrayBuffer(InitialConnectionBufferSize); @@ -116,7 +119,7 @@ public Http2Connection(HttpConnectionPool pool, Stream stream) _pendingWindowUpdate = 0; _idleSinceTickCount = Environment.TickCount64; - if (NetEventSource.Log.IsEnabled()) TraceConnection(stream); + if (NetEventSource.Log.IsEnabled()) TraceConnection(_stream); } private object SyncObject => _httpStreams; @@ -1585,7 +1588,7 @@ private void CheckForShutdown() } // Do shutdown. - _stream.Close(); + _connection.Dispose(); _connectionWindow.Dispose(); _concurrentStreams.Dispose(); 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 780212df7806..33383a117dd1 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 @@ -10,6 +10,7 @@ using System.Net.Http.Headers; using System.Net.Security; using System.Net.Sockets; +using System.Net.Connections; using System.Runtime.CompilerServices; using System.Text; using System.Threading; @@ -45,6 +46,7 @@ internal partial class HttpConnection : HttpConnectionBase, IDisposable private readonly HttpConnectionPool _pool; private readonly Socket? _socket; // used for polling; _stream should be used for all reading/writing. _stream owns disposal. private readonly Stream _stream; + private readonly Connection _connection; private readonly TransportContext? _transportContext; private readonly WeakReference _weakThisRef; @@ -68,16 +70,16 @@ internal partial class HttpConnection : HttpConnectionBase, IDisposable public HttpConnection( HttpConnectionPool pool, - Socket? socket, - Stream stream, + Connection connection, TransportContext? transportContext) { Debug.Assert(pool != null); - Debug.Assert(stream != null); + Debug.Assert(connection != null); _pool = pool; - _socket = socket; // may be null in cases where we couldn't easily get the underlying socket - _stream = stream; + connection.ConnectionProperties.TryGet(out _socket); // may be null in cases where we couldn't easily get the underlying socket + _stream = connection.Stream; + _connection = connection; _transportContext = transportContext; _writeBuffer = new byte[InitialWriteBufferSize]; @@ -101,7 +103,7 @@ protected void Dispose(bool disposing) if (disposing) { GC.SuppressFinalize(this); - _stream.Dispose(); + _connection.Dispose(); // Eat any exceptions from the read-ahead task. We don't need to log, as we expect // failures from this task due to closing the connection while a read is in progress. @@ -1917,7 +1919,7 @@ public sealed override void Trace(string message, [CallerMemberName] string? mem internal sealed class HttpConnectionWithFinalizer : HttpConnection { - public HttpConnectionWithFinalizer(HttpConnectionPool pool, Socket? socket, Stream stream, TransportContext? transportContext) : base(pool, socket, stream, transportContext) { } + public HttpConnectionWithFinalizer(HttpConnectionPool pool, Connection connection, TransportContext? transportContext) : base(pool, connection, transportContext) { } // This class is separated from HttpConnection so we only pay the price of having a finalizer // when it's actually needed, e.g. when MaxConnectionsPerServer is enabled. 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 072c9c24fd1f..af9e2cd61420 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 @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Net.Connections; using System.Net.Http.Headers; using System.Net.Http.HPack; using System.Net.Http.QPack; @@ -509,7 +510,7 @@ public byte[] Http2AltSvcOriginUri } // Try to establish an HTTP2 connection - Socket? socket = null; + Connection? connection = null; SslStream? sslStream = null; TransportContext? transportContext = null; @@ -531,18 +532,28 @@ public byte[] Http2AltSvcOriginUri Trace("Attempting new HTTP2 connection."); } - Stream? stream; HttpResponseMessage? failureResponse; - (socket, stream, transportContext, failureResponse) = + + (connection, transportContext, failureResponse) = await ConnectAsync(request, async, true, cancellationToken).ConfigureAwait(false); + if (failureResponse != null) { return (null, true, failureResponse); } + Debug.Assert(connection != null); + + sslStream = connection.Stream as SslStream; + + if (Settings._plaintextFilter != null) + { + connection = await Settings._plaintextFilter(request, connection, cancellationToken).ConfigureAwait(false); + } + if (_kind == HttpConnectionKind.Http) { - http2Connection = new Http2Connection(this, stream!); + http2Connection = new Http2Connection(this, connection); await http2Connection.SetupAsync().ConfigureAwait(false); AddHttp2Connection(http2Connection); @@ -555,7 +566,8 @@ public byte[] Http2AltSvcOriginUri return (http2Connection, true, null); } - sslStream = (SslStream)stream!; + Debug.Assert(sslStream != null); + if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2) { // The server accepted our request for HTTP2. @@ -565,7 +577,7 @@ public byte[] Http2AltSvcOriginUri throw new HttpRequestException(SR.Format(SR.net_ssl_http2_requires_tls12, sslStream.SslProtocol)); } - http2Connection = new Http2Connection(this, sslStream); + http2Connection = new Http2Connection(this, connection); await http2Connection.SetupAsync().ConfigureAwait(false); AddHttp2Connection(http2Connection); @@ -616,7 +628,7 @@ public byte[] Http2AltSvcOriginUri if (canUse) { - return (ConstructHttp11Connection(socket, sslStream, transportContext), true, null); + return (ConstructHttp11Connection(connection!, transportContext), true, null); } else { @@ -625,7 +637,7 @@ public byte[] Http2AltSvcOriginUri Trace("Discarding downgraded HTTP/1.1 connection because connection limit is exceeded"); } - sslStream.Close(); + await connection!.CloseAsync(ConnectionCloseMethod.GracefulShutdown, cancellationToken).ConfigureAwait(false); } } @@ -1124,7 +1136,7 @@ public ValueTask SendAsync(HttpRequestMessage request, bool return SendWithProxyAuthAsync(request, async, doRequestAuth, cancellationToken); } - private async ValueTask<(Socket?, Stream?, TransportContext?, HttpResponseMessage?)> ConnectAsync(HttpRequestMessage request, bool async, bool allowHttp2, CancellationToken cancellationToken) + private async ValueTask<(Connection?, TransportContext?, HttpResponseMessage?)> ConnectAsync(HttpRequestMessage request, bool async, bool allowHttp2, CancellationToken cancellationToken) { // If a non-infinite connect timeout has been set, create and use a new CancellationToken that will be canceled // when either the original token is canceled or a connect timeout occurs. @@ -1138,44 +1150,44 @@ public ValueTask SendAsync(HttpRequestMessage request, bool try { - Stream? stream = null; + Connection? connection = null; switch (_kind) { case HttpConnectionKind.Http: case HttpConnectionKind.Https: case HttpConnectionKind.ProxyConnect: Debug.Assert(_originAuthority != null); - stream = await ConnectHelper.ConnectAsync(_originAuthority.IdnHost, _originAuthority.Port, async, cancellationToken).ConfigureAwait(false); + connection = await ConnectToTcpHostAsync(_originAuthority.IdnHost, _originAuthority.Port, request, async, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.Proxy: - stream = await ConnectHelper.ConnectAsync(_proxyUri!.IdnHost, _proxyUri.Port, async, cancellationToken).ConfigureAwait(false); + connection = await ConnectToTcpHostAsync(_proxyUri!.IdnHost, _proxyUri.Port, request, async, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.ProxyTunnel: case HttpConnectionKind.SslProxyTunnel: HttpResponseMessage? response; - (stream, response) = await EstablishProxyTunnel(async, request.HasHeaders ? request.Headers : null, cancellationToken).ConfigureAwait(false); + (connection, response) = await EstablishProxyTunnel(async, request.HasHeaders ? request.Headers : null, cancellationToken).ConfigureAwait(false); if (response != null) { // Return non-success response from proxy. response.RequestMessage = request; - return (null, null, null, response); + return (null, null, response); } break; } - Socket? socket = (stream as NetworkStream)?.Socket; + Debug.Assert(connection != null); TransportContext? transportContext = null; if (_kind == HttpConnectionKind.Https || _kind == HttpConnectionKind.SslProxyTunnel) { - SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(allowHttp2 ? _sslOptionsHttp2! : _sslOptionsHttp11!, request, async, stream!, cancellationToken).ConfigureAwait(false); - stream = sslStream; + SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(allowHttp2 ? _sslOptionsHttp2! : _sslOptionsHttp11!, request, async, connection.Stream, cancellationToken).ConfigureAwait(false); + connection = Connection.FromStream(sslStream, leaveOpen: false, connection.ConnectionProperties, connection.LocalEndPoint, connection.RemoteEndPoint); transportContext = sslStream.TransportContext; } - return (socket, stream, transportContext, null); + return (connection, transportContext, null); } finally { @@ -1183,9 +1195,37 @@ public ValueTask SendAsync(HttpRequestMessage request, bool } } + private ValueTask ConnectToTcpHostAsync(string host, int port, HttpRequestMessage initialRequest, bool async, CancellationToken cancellationToken) + { + if (async) + { + ConnectionFactory connectionFactory = Settings._connectionFactory ?? SocketsHttpConnectionFactory.Default; + + var endPoint = new DnsEndPointWithProperties(host, port, initialRequest); + return ConnectHelper.ConnectAsync(connectionFactory, endPoint, endPoint, cancellationToken); + } + + // Synchronous path. + + if (Settings._connectionFactory != null) + { + // connection factories only support async. + throw new HttpRequestException(); + } + + try + { + return new ValueTask(ConnectHelper.Connect(host, port, cancellationToken)); + } + catch (Exception ex) + { + return ValueTask.FromException(ex); + } + } + internal async ValueTask<(HttpConnection?, HttpResponseMessage?)> CreateHttp11ConnectionAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken) { - (Socket? socket, Stream? stream, TransportContext? transportContext, HttpResponseMessage? failureResponse) = + (Connection? connection, TransportContext? transportContext, HttpResponseMessage? failureResponse) = await ConnectAsync(request, async, false, cancellationToken).ConfigureAwait(false); if (failureResponse != null) @@ -1193,18 +1233,18 @@ public ValueTask SendAsync(HttpRequestMessage request, bool return (null, failureResponse); } - return (ConstructHttp11Connection(socket, stream!, transportContext), null); + return (ConstructHttp11Connection(connection!, transportContext), null); } - private HttpConnection ConstructHttp11Connection(Socket? socket, Stream stream, TransportContext? transportContext) + private HttpConnection ConstructHttp11Connection(Connection connection, TransportContext? transportContext) { return _maxConnections == int.MaxValue ? - new HttpConnection(this, socket, stream, transportContext) : - new HttpConnectionWithFinalizer(this, socket, stream, transportContext); // finalizer needed to signal the pool when a connection is dropped + new HttpConnection(this, connection, transportContext) : + new HttpConnectionWithFinalizer(this, connection, transportContext); // finalizer needed to signal the pool when a connection is dropped } // Returns the established stream or an HttpResponseMessage from the proxy indicating failure. - private async ValueTask<(Stream?, HttpResponseMessage?)> EstablishProxyTunnel(bool async, HttpRequestHeaders? headers, CancellationToken cancellationToken) + private async ValueTask<(Connection?, HttpResponseMessage?)> EstablishProxyTunnel(bool async, HttpRequestHeaders? headers, CancellationToken cancellationToken) { Debug.Assert(_originAuthority != null); // Send a CONNECT request to the proxy server to establish a tunnel. @@ -1223,7 +1263,12 @@ private HttpConnection ConstructHttp11Connection(Socket? socket, Stream stream, return (null, tunnelResponse); } - return (tunnelResponse.Content!.ReadAsStream(cancellationToken), null); + Stream stream = tunnelResponse.Content.ReadAsStream(cancellationToken); + EndPoint remoteEndPoint = new DnsEndPoint(_originAuthority.IdnHost, _originAuthority.Port); + + // TODO: the Socket from the response can be funneled into a connection property here. + + return (Connection.FromStream(stream, remoteEndPoint: remoteEndPoint), null); } /// Enqueues a waiter to the waiters list. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 4ba769673e75..558e6cf1572a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Net.Connections; using System.Net.Security; +using System.Threading; +using System.Threading.Tasks; namespace System.Net.Http { @@ -54,6 +57,9 @@ internal sealed class HttpConnectionSettings internal bool _enableMultipleHttp2Connections; + internal ConnectionFactory? _connectionFactory; + internal Func>? _plaintextFilter; + internal IDictionary? _properties; public HttpConnectionSettings() @@ -104,7 +110,9 @@ public HttpConnectionSettings CloneAndNormalize() _useProxy = _useProxy, _allowUnencryptedHttp2 = _allowUnencryptedHttp2, _assumePrenegotiatedHttp3ForTesting = _assumePrenegotiatedHttp3ForTesting, - _enableMultipleHttp2Connections = _enableMultipleHttp2Connections + _enableMultipleHttp2Connections = _enableMultipleHttp2Connections, + _connectionFactory = _connectionFactory, + _plaintextFilter = _plaintextFilter }; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs new file mode 100644 index 000000000000..e224616c9e3f --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Connections; +using System.Net.Sockets; +using System.Runtime.ExceptionServices; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Http +{ + /// + /// The default connection factory used by , opening TCP connections. + /// + public class SocketsHttpConnectionFactory : ConnectionFactory + { + internal static SocketsHttpConnectionFactory Default { get; } = new SocketsHttpConnectionFactory(); + + /// + public sealed override ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) + { + if (options == null || !options.TryGet(out DnsEndPointWithProperties? httpOptions)) + { + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException($"{nameof(SocketsHttpConnectionFactory)} requires a {nameof(DnsEndPointWithProperties)} property."))); + } + + return EstablishConnectionAsync(httpOptions!.InitialRequest, endPoint, options, cancellationToken); + } + + /// + /// Creates the socket to be used for a request. + /// + /// The request causing this socket to be opened. Once opened, it may be reused for many subsequent requests. + /// The EndPoint this socket will be connected to. + /// Properties, if any, that might change how the socket is initialized. + /// A new unconnected socket. + public virtual Socket CreateSocket(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options) + { + return new Socket(SocketType.Stream, ProtocolType.Tcp); + } + + /// + /// Establishes a new connection for a request. + /// + /// The request causing this connection to be established. Once connected, it may be reused for many subsequent requests. + /// The EndPoint to connect to. + /// Properties, if any, that might change how the connection is made. + /// A cancellation token for the asynchronous operation. + /// A new open connection. + public virtual async ValueTask EstablishConnectionAsync(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options, CancellationToken cancellationToken) + { + if (message == null) throw new ArgumentNullException(nameof(message)); + if (endPoint == null) throw new ArgumentNullException(nameof(endPoint)); + + Socket socket = CreateSocket(message, endPoint, options); + + try + { + using var args = new TaskSocketAsyncEventArgs(); + args.RemoteEndPoint = endPoint; + + if (socket.ConnectAsync(args)) + { + using (cancellationToken.UnsafeRegister(o => Socket.CancelConnectAsync((SocketAsyncEventArgs)o!), args)) + { + await args.Task.ConfigureAwait(false); + } + } + + if (args.SocketError != SocketError.Success) + { + Exception ex = args.SocketError == SocketError.OperationAborted && cancellationToken.IsCancellationRequested + ? (Exception)new OperationCanceledException(cancellationToken) + : new SocketException((int)args.SocketError); + + throw ex; + } + + socket.NoDelay = true; + return new SocketConnection(socket); + } + catch + { + socket.Dispose(); + throw; + } + } + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 1874723a9773..de391e98b161 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; +using System.Net.Connections; namespace System.Net.Http { @@ -288,6 +289,33 @@ public bool EnableMultipleHttp2Connections internal bool SupportsProxy => true; internal bool SupportsRedirectConfiguration => true; + /// + /// When non-null, a custom factory used to open new TCP connections. + /// When null, a will be used. + /// + public ConnectionFactory? ConnectionFactory + { + get => _settings._connectionFactory; + set + { + CheckDisposedOrStarted(); + _settings._connectionFactory = value; + } + } + + /// + /// When non-null, a connection filter that is applied prior to any TLS encryption. + /// + public Func>? PlaintextFilter + { + get => _settings._plaintextFilter; + set + { + CheckDisposedOrStarted(); + _settings._plaintextFilter = value; + } + } + public IDictionary Properties => _settings._properties ?? (_settings._properties = new Dictionary()); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 3a4aef661e41..4328b0aad403 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Net.Connections; using System.Net.Quic; using System.Net.Security; using System.Net.Sockets; @@ -105,6 +106,71 @@ private sealed class SetOnFinalized } } + public class SocketsHttpHandler_ConnectionFactoryTest : HttpClientHandlerTestBase + { + public SocketsHttpHandler_ConnectionFactoryTest(ITestOutputHelper output) : base(output) { } + + [Fact] + public async Task CustomConnectionFactory_AsyncRequest_Success() + { + await using ConnectionListenerFactory listenerFactory = new VirtualNetworkConnectionListenerFactory(); + await using ConnectionListener listener = await listenerFactory.BindAsync(endPoint: null); + await using ConnectionFactory connectionFactory = VirtualNetworkConnectionListenerFactory.GetConnectionFactory(listener); + + // TODO: if GenericLoopbackOptions actually worked for HTTP/1 LoopbackServer we could just use that and pass in to CreateConnectionAsync. + // Making that work causes other tests to fail, so for now... + bool useHttps = UseVersion.Major >= 2 && new GenericLoopbackOptions().UseSsl; + + Task serverTask = Task.Run(async () => + { + await using Connection serverConnection = await listener.AcceptAsync(); + using GenericLoopbackConnection loopbackConnection = await LoopbackServerFactory.CreateConnectionAsync(socket: null, serverConnection.Stream); + + await loopbackConnection.InitializeConnectionAsync(); + + HttpRequestData requestData = await loopbackConnection.ReadRequestDataAsync(); + await loopbackConnection.SendResponseAsync(content: "foo"); + + Assert.Equal("/foo", requestData.Path); + }); + + Task clientTask = Task.Run(async () => + { + using HttpClientHandler handler = CreateHttpClientHandler(); + + var socketsHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); + socketsHandler.ConnectionFactory = connectionFactory; + + using HttpClient client = CreateHttpClient(handler); + + string response = await client.GetStringAsync($"{(useHttps ? "https" : "http")}://{Guid.NewGuid():N}.com/foo"); + Assert.Equal("foo", response); + }); + + await new[] { serverTask, clientTask }.WhenAllOrAnyFailed(60_000); + } + + [Fact] + public async Task CustomConnectionFactory_SyncRequest_Fails() + { + await using ConnectionFactory connectionFactory = new SocketsHttpConnectionFactory(); + using SocketsHttpHandler handler = new SocketsHttpHandler + { + ConnectionFactory = connectionFactory + }; + + using HttpClient client = CreateHttpClient(handler); + + await Assert.ThrowsAnyAsync(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo")); + } + } + + public sealed class SocketsHttpHandler_ConnectionFactoryTest_Http2 : SocketsHttpHandler_ConnectionFactoryTest + { + public SocketsHttpHandler_ConnectionFactoryTest_Http2(ITestOutputHelper output) : base(output) { } + protected override Version UseVersion => HttpVersion.Version20; + } + public sealed class SocketsHttpHandler_HttpProtocolTests : HttpProtocolTests { public SocketsHttpHandler_HttpProtocolTests(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index 2e00a8921702..bdf9887ad6c9 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -230,6 +230,9 @@ Link="Common\System\Net\Http\ThrowingContent.cs" /> + + + diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index 2c2fd2238699..5ab3eb994be6 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -3353,7 +3353,9 @@ "4.6.0" ], "BaselineVersion": "5.0.0", - "InboxOn": {}, + "InboxOn": { + "net5.0": "5.0.0.0" + }, "AssemblyVersionInPackageVersion": { "4.0.0.0": "4.5.0", "4.0.0.1": "4.5.2", From b34c19003f22174a99233dba4596c165e026a915 Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:19:18 +0100 Subject: [PATCH 094/755] Fix typo on comment on ReflectionEnum::InternalHasFlag (#39995) --- src/coreclr/src/vm/reflectioninvocation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index f485f9407eea..59a643192d19 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -2646,7 +2646,7 @@ FCIMPL2(FC_BOOL_RET, ReflectionEnum::InternalEquals, Object *pRefThis, Object* p } FCIMPLEND -// preform (this & flags) != flags +// perform (this & flags) == flags FCIMPL2(FC_BOOL_RET, ReflectionEnum::InternalHasFlag, Object *pRefThis, Object* pRefFlags) { FCALL_CONTRACT; From 36f0c48dbddc6de76b7e7beb67803bc9e09e6259 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 28 Jul 2020 10:07:39 -0700 Subject: [PATCH 095/755] Fix mdarrays (#39984) - MDArrays are special and method references to the methods needs to be encoded with their type in more cases than normal methods - Only generate the owner type if the memberref does not encode the same owner type - Add tests for various multidimensional array scenarios to crossgen2smoke Fix issue #38260 --- .../tools/Common/Compiler/TypeExtensions.cs | 13 ++ .../ReadyToRun/SignatureBuilder.cs | 12 +- src/coreclr/tests/issues.targets | 6 - src/tests/readytorun/crossgen2/Program.cs | 141 ++++++++++++++++++ src/tests/readytorun/crossgen2/helperildll.il | 88 +++++++++++ 5 files changed, 252 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs index 89fd08f3dbab..dd54a1387bdf 100644 --- a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs +++ b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs @@ -97,6 +97,19 @@ public static bool IsArrayAddressMethod(this MethodDesc method) return arrayMethod != null && arrayMethod.Kind == ArrayMethodKind.Address; } + + /// + /// Returns true if '' is one of the special methods on multidimensional array types (set, get, address). + /// + public static bool IsArrayMethod(this MethodDesc method) + { + var arrayMethod = method as ArrayMethod; + return arrayMethod != null && (arrayMethod.Kind == ArrayMethodKind.Address || + arrayMethod.Kind == ArrayMethodKind.Get || + arrayMethod.Kind == ArrayMethodKind.Set || + arrayMethod.Kind == ArrayMethodKind.Ctor); + } + /// /// Gets a value indicating whether this type has any generic virtual methods. /// diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs index 54b9849aed8c..fd80e7e74a58 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; @@ -441,11 +442,18 @@ public void EmitMethodSignature( // Owner type is needed for type specs to instantiating stubs or generics with signature variables still present if (!method.Method.OwningType.IsDefType && - ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables()) - || method.Method.IsArrayAddressMethod()) + ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables())) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType; } + else if (method.Method.IsArrayMethod()) + { + var memberRefMethod = method.Token.Module.GetMethod(MetadataTokens.EntityHandle((int)method.Token.Token)); + if (memberRefMethod.OwningType != method.Method.OwningType) + { + flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType; + } + } EmitUInt(flags); if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index e33de4df6132..ac5addebf4b3 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -920,9 +920,6 @@ https://github.com/dotnet/runtime/issues/38096 - - https://github.com/dotnet/runtime/issues/38260 - https://github.com/dotnet/runtime/issues/7597 @@ -959,9 +956,6 @@ https://github.com/dotnet/runtime/issues/38290 - - https://github.com/dotnet/runtime/issues/38260 - https://github.com/dotnet/runtime/issues/32728 diff --git a/src/tests/readytorun/crossgen2/Program.cs b/src/tests/readytorun/crossgen2/Program.cs index bd00957a7584..e2da74337546 100644 --- a/src/tests/readytorun/crossgen2/Program.cs +++ b/src/tests/readytorun/crossgen2/Program.cs @@ -1626,6 +1626,145 @@ private static bool GenericLdtokenTest() return true; } + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool CheckArrayVal(ref T refVal, T testValue) where T:IEquatable + { + return refVal.Equals(testValue); + } + + struct SomeLargeStruct : IEquatable + { + public SomeLargeStruct(int _xVal) + { + x = _xVal; + y = 0; + z = 0; + w = 0; + } + public int x; + public int y; + public int z; + public int w; + + public bool Equals(SomeLargeStruct other) + { + return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); + } + public override bool Equals(object other) + { + return Equals((SomeLargeStruct)other); + } + + public override int GetHashCode() { return x; } + } + + class SomeClass : IEquatable + { + public SomeClass(int _xVal) + { + x = _xVal; + y = 0; + z = 0; + w = 0; + } + public int x; + public int y; + public int z; + public int w; + + public bool Equals(SomeClass other) + { + return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); + } + public override bool Equals(object other) + { + return Equals((SomeClass)other); + } + + public override int GetHashCode() { return x; } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool DoLargeStructMDArrayTest(SomeLargeStruct testValue) + { + SomeLargeStruct[,] array = new SomeLargeStruct[2,2]; + array[0,0] = testValue; + if (!CheckArrayVal(ref array[0,0], testValue)) + { + return false; + } + if (!testValue.Equals(array[0,0])) + { + return false; + } + + return true; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool DoGenericArrayTest (T testValue) where T:IEquatable + { + T[,] array = new T[2,2]; + array[0,0] = testValue; + if (!CheckArrayVal(ref array[0,0], testValue)) + { + return false; + } + if (!testValue.Equals(array[0,0])) + { + return false; + } + + return true; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool TestGenericMDArrayBehavior() + { + if (!DoGenericArrayTest(42)) + { + return false; + } + + if (!DoGenericArrayTest(new SomeClass(42))) + { + return false; + } + + SomeLargeStruct testStruct = new SomeLargeStruct(42); + if (!DoGenericArrayTest(testStruct)) + { + return false; + } + + if (!DoLargeStructMDArrayTest(testStruct)) + { + return false; + } + + return true; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ArrayLdtokenTests() + { + // We're testing that mapping from ldtoken to RuntimeMethodHandle works for various ways that + // ldtokens can be referenced (either via a generic token, or not. + // (there are slightly different codepaths in crossgen for this) + // Incorrect encoding will trigger a BadImageFormatException + RuntimeMethodHandle rmhCtor1 = default(RuntimeMethodHandle); + RuntimeMethodHandle rmhCtor2 = default(RuntimeMethodHandle); + RuntimeMethodHandle rmhSet = default(RuntimeMethodHandle); + RuntimeMethodHandle rmhGet = default(RuntimeMethodHandle); + RuntimeMethodHandle rmhAddress = default(RuntimeMethodHandle); + HelperGenericILCode.LdTokenArrayMethods(ref rmhCtor1, ref rmhCtor2, ref rmhSet, ref rmhGet, ref rmhAddress); + HelperGenericILCode.LdTokenArrayMethods(ref rmhCtor1, ref rmhCtor2, ref rmhSet, ref rmhGet, ref rmhAddress); + HelperILCode.LdTokenArrayMethodsInt(ref rmhCtor1, ref rmhCtor2, ref rmhSet, ref rmhGet, ref rmhAddress); + HelperILCode.LdTokenArrayMethodsString(ref rmhCtor1, ref rmhCtor2, ref rmhSet, ref rmhGet, ref rmhAddress); + + return true; + } + public static int Main(string[] args) { _passedTests = new List(); @@ -1691,6 +1830,8 @@ public static int Main(string[] args) RunTest("ExplicitlySizedStructTest", ExplicitlySizedStructTest()); RunTest("ExplicitlySizedClassTest", ExplicitlySizedClassTest()); RunTest("GenericLdtokenTest", GenericLdtokenTest()); + RunTest("ArrayLdtokenTests", ArrayLdtokenTests()); + RunTest("TestGenericMDArrayBehavior", TestGenericMDArrayBehavior()); File.Delete(TextFileName); diff --git a/src/tests/readytorun/crossgen2/helperildll.il b/src/tests/readytorun/crossgen2/helperildll.il index 4a4194454a96..752d16c83c15 100644 --- a/src/tests/readytorun/crossgen2/helperildll.il +++ b/src/tests/readytorun/crossgen2/helperildll.il @@ -40,6 +40,55 @@ ret } + .method public hidebysig static void LdTokenArrayMethodsInt(valuetype[mscorlib]System.RuntimeMethodHandle& ctor, valuetype[mscorlib]System.RuntimeMethodHandle& ctor2, valuetype[mscorlib]System.RuntimeMethodHandle& set, valuetype[mscorlib]System.RuntimeMethodHandle& get, valuetype[mscorlib]System.RuntimeMethodHandle& address) + { + ldarg 0 + ldtoken method instance void int32[,]::.ctor(int32, int32, int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 1 + ldtoken method instance void int32[,]::.ctor(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 2 + ldtoken method instance void int32[,]::Set(int32, int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 3 + ldtoken method instance int32 int32[,]::Get(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 4 + ldtoken method instance int32& int32[,]::Address(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + ret + } + + .method public hidebysig static void LdTokenArrayMethodsString(valuetype[mscorlib]System.RuntimeMethodHandle& ctor, valuetype[mscorlib]System.RuntimeMethodHandle& ctor2, valuetype[mscorlib]System.RuntimeMethodHandle& set, valuetype[mscorlib]System.RuntimeMethodHandle& get, valuetype[mscorlib]System.RuntimeMethodHandle& address) + { + ldarg 0 + ldtoken method instance void string[,]::.ctor(int32, int32, int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 1 + ldtoken method instance void string[,]::.ctor(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 2 + ldtoken method instance void string[,]::Set(int32, int32, string) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 3 + ldtoken method instance string string[,]::Get(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 4 + ldtoken method instance string& string[,]::Address(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + ret + } + + .method public hidebysig static valuetype[mscorlib]System.RuntimeMethodHandle ForceStuffToBeCompiled() cil managed noinlining { call valuetype[mscorlib]System.RuntimeMethodHandle class HelperGenericILCode`1::GetGenericFunctionMethodHandle>() @@ -50,6 +99,22 @@ call valuetype[mscorlib]System.RuntimeMethodHandle HelperILCode::GetGenericFunctionMethodHandle() ret } + .method public hidebysig static void ForceStuffToBeCompiled3(valuetype[mscorlib]System.RuntimeMethodHandle& ctor, valuetype[mscorlib]System.RuntimeMethodHandle& ctor2, valuetype[mscorlib]System.RuntimeMethodHandle& set, valuetype[mscorlib]System.RuntimeMethodHandle& get, valuetype[mscorlib]System.RuntimeMethodHandle& address) cil managed noinlining + { + ldarg 0 + ldarg 1 + ldarg 2 + ldarg 3 + ldarg 4 + call void class HelperGenericILCode`1::LdTokenArrayMethods(valuetype[mscorlib]System.RuntimeMethodHandle&, valuetype[mscorlib]System.RuntimeMethodHandle&, valuetype[mscorlib]System.RuntimeMethodHandle&, valuetype[mscorlib]System.RuntimeMethodHandle&, valuetype[mscorlib]System.RuntimeMethodHandle&) + ldarg 0 + ldarg 1 + ldarg 2 + ldarg 3 + ldarg 4 + call void class HelperGenericILCode`1::LdTokenArrayMethods(valuetype[mscorlib]System.RuntimeMethodHandle& ctor, valuetype[mscorlib]System.RuntimeMethodHandle& ctor2, valuetype[mscorlib]System.RuntimeMethodHandle& set, valuetype[mscorlib]System.RuntimeMethodHandle& get, valuetype[mscorlib]System.RuntimeMethodHandle& address) + ret + } } .class auto ansi public beforefieldinit HelperGenericILCode`1 @@ -66,4 +131,27 @@ ldtoken method instance int32 valuetype [helperdll]GenericStructForLdtoken`1::GenericFunction(!0, !!0, string, int32) ret } + .method public hidebysig static void LdTokenArrayMethods(valuetype[mscorlib]System.RuntimeMethodHandle& ctor, valuetype[mscorlib]System.RuntimeMethodHandle& ctor2, valuetype[mscorlib]System.RuntimeMethodHandle& set, valuetype[mscorlib]System.RuntimeMethodHandle& get, valuetype[mscorlib]System.RuntimeMethodHandle& address) + { + ldarg 0 + ldtoken method instance void !0[,]::.ctor(int32, int32, int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 1 + ldtoken method instance void !0[,]::.ctor(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 2 + ldtoken method instance void !0[,]::Set(int32, int32, !0) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 3 + ldtoken method instance !0 !0[,]::Get(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + + ldarg 4 + ldtoken method instance !0& !0[,]::Address(int32, int32) + stobj valuetype[mscorlib]System.RuntimeMethodHandle + ret + } } From 50a999dd3597a33b62a7a1a1712c849e764d50e9 Mon Sep 17 00:00:00 2001 From: Elinor Fung <47805090+elinor-fung@users.noreply.github.com> Date: Tue, 28 Jul 2020 10:21:56 -0700 Subject: [PATCH 096/755] Error on multiple calling conventions in modopts (#39809) --- src/coreclr/src/dlls/mscorrc/mscorrc.rc | 1 + src/coreclr/src/dlls/mscorrc/resource.h | 1 + .../tools/Common/JitInterface/CorInfoImpl.cs | 34 +++++++++++-------- .../TypeSystem/Common/ExceptionStringID.cs | 1 + .../Common/Properties/Resources.resx | 5 ++- .../Common/TypeSystem/Common/ThrowHelper.cs | 6 ++++ .../TypeSystem/Common/TypeSystemException.cs | 5 +++ src/coreclr/src/vm/dllimport.cpp | 18 +++++++--- src/coreclr/src/vm/jitinterface.cpp | 7 +++- src/coreclr/src/vm/siginfo.cpp | 23 ++++++++++--- src/coreclr/src/vm/siginfo.hpp | 10 +++--- .../callconvs/TestCallingConventions.cs | 12 ++++--- 12 files changed, 87 insertions(+), 36 deletions(-) diff --git a/src/coreclr/src/dlls/mscorrc/mscorrc.rc b/src/coreclr/src/dlls/mscorrc/mscorrc.rc index a50f742cef00..360442044ca4 100644 --- a/src/coreclr/src/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/src/dlls/mscorrc/mscorrc.rc @@ -182,6 +182,7 @@ BEGIN IDS_EE_NDIRECT_UNSUPPORTED_SIG "Method's type signature is not PInvoke compatible." IDS_EE_COM_UNSUPPORTED_SIG "Method's type signature is not Interop compatible." IDS_EE_COM_UNSUPPORTED_TYPE "The method returned a COM Variant type that is not Interop compatible." + IDS_EE_MULTIPLE_CALLCONV_UNSUPPORTED "Multiple unmanaged calling conventions are specified. Only a single calling convention is supported." IDS_EE_NDIRECT_BADNATL "Invalid PInvoke or UnmanagedFunctionPointer metadata format." IDS_EE_NDIRECT_BADNATL_CALLCONV "Invalid PInvoke or UnmanagedFunctionPointer calling convention." IDS_EE_NDIRECT_BADNATL_VARARGS_CALLCONV "Invalid PInvoke calling convention. Vararg functions must use the cdecl calling convention." diff --git a/src/coreclr/src/dlls/mscorrc/resource.h b/src/coreclr/src/dlls/mscorrc/resource.h index 738b751c7fae..b78c5d84c304 100644 --- a/src/coreclr/src/dlls/mscorrc/resource.h +++ b/src/coreclr/src/dlls/mscorrc/resource.h @@ -43,6 +43,7 @@ #define IDS_EE_COM_UNSUPPORTED_SIG 0x170d #define IDS_EE_NOSYNCHRONIZED 0x170f #define IDS_EE_NDIRECT_BADNATL_THISCALL 0x1710 +#define IDS_EE_MULTIPLE_CALLCONV_UNSUPPORTED 0x1711 #define IDS_EE_LOAD_BAD_MAIN_SIG 0x1712 #define IDS_EE_COM_UNSUPPORTED_TYPE 0x1713 diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index f5496370e4e8..3d7dd28329b9 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -508,6 +508,7 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null) return false; + bool found = false; foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData()) { if (data.kind != EmbeddedSignatureDataKind.OptionalCustomModifier) @@ -524,25 +525,28 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur if (defType.Namespace != "System.Runtime.CompilerServices") continue; - // Take the first recognized calling convention in metadata. - switch (defType.Name) + // Look for a recognized calling convention in metadata. + CorInfoCallConv? callConvLocal = defType.Name switch { - case "CallConvCdecl": - callConv = CorInfoCallConv.CORINFO_CALLCONV_C; - return true; - case "CallConvStdcall": - callConv = CorInfoCallConv.CORINFO_CALLCONV_STDCALL; - return true; - case "CallConvFastcall": - callConv = CorInfoCallConv.CORINFO_CALLCONV_FASTCALL; - return true; - case "CallConvThiscall": - callConv = CorInfoCallConv.CORINFO_CALLCONV_THISCALL; - return true; + "CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C, + "CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL, + "CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL, + "CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL, + _ => null + }; + + if (callConvLocal.HasValue) + { + // Error if there are multiple recognized calling conventions + if (found) + ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled); + + callConv = callConvLocal.Value; + found = true; } } - return false; + return found; } private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs index 00286eabe3a9..d9d3de41634d 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs @@ -36,6 +36,7 @@ public enum ExceptionStringID InvalidProgramNonStaticMethod, InvalidProgramGenericMethod, InvalidProgramNonBlittableTypes, + InvalidProgramMultipleCallConv, // BadImageFormatException BadImageFormatGeneric, diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx index 368145929e05..b0efd67b4adc 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx @@ -174,7 +174,10 @@ UnmanagedCallersOnly attribute specified on method with non-blittable parameters '{0}' + + Multiple unmanaged calling conventions are specified. Only a single calling convention is supported. + The format of a DLL or executable being loaded is invalid - \ No newline at end of file + diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs index 9ab806e77ffe..094ade10faca 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs @@ -41,6 +41,12 @@ public static void ThrowInvalidProgramException() throw new TypeSystemException.InvalidProgramException(); } + [System.Diagnostics.DebuggerHidden] + public static void ThrowInvalidProgramException(ExceptionStringID id) + { + throw new TypeSystemException.InvalidProgramException(id); + } + [System.Diagnostics.DebuggerHidden] public static void ThrowInvalidProgramException(ExceptionStringID id, MethodDesc method) { diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs index 931136950f1a..17836ca309bd 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs @@ -138,6 +138,11 @@ internal InvalidProgramException(ExceptionStringID id, string method) { } + internal InvalidProgramException(ExceptionStringID id) + : base(id) + { + } + internal InvalidProgramException() : base(ExceptionStringID.InvalidProgramDefault) { diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 2fd2fefd1bc8..752fbd016f23 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -2955,7 +2955,8 @@ namespace _In_ Module *pModule, _In_ PCCOR_SIGNATURE pSig, _In_ ULONG cSig, - _Out_ CorPinvokeMap *pPinvokeMapOut) + _Out_ CorPinvokeMap *pPinvokeMapOut, + _Out_ UINT *errorResID) { CONTRACTL { @@ -2966,7 +2967,7 @@ namespace CONTRACTL_END CorUnmanagedCallingConvention callConvMaybe; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(pModule, pSig, cSig, &callConvMaybe); + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(pModule, pSig, cSig, &callConvMaybe, errorResID); if (hr != S_OK) return hr; @@ -2992,10 +2993,12 @@ void PInvokeStaticSigInfo::InitCallConv(CorPinvokeMap callConv, BOOL bIsVarArg) callConv = GetDefaultCallConv(bIsVarArg); CorPinvokeMap sigCallConv = (CorPinvokeMap)0; - HRESULT hr = GetUnmanagedPInvokeCallingConvention(m_pModule, m_sig.GetRawSig(), m_sig.GetRawSigLen(), &sigCallConv); + UINT errorResID; + HRESULT hr = GetUnmanagedPInvokeCallingConvention(m_pModule, m_sig.GetRawSig(), m_sig.GetRawSigLen(), &sigCallConv, &errorResID); if (FAILED(hr)) { - SetError(IDS_EE_NDIRECT_BADNATL); //Bad metadata format + // Set an error message specific to P/Invokes or UnmanagedFunction for bad format. + SetError(hr == COR_E_BADIMAGEFORMAT ? IDS_EE_NDIRECT_BADNATL : errorResID); } // Do the same WinAPI to StdCall or CDecl for the signature calling convention as well. We need @@ -6859,7 +6862,12 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) if (callConv == IMAGE_CEE_CS_CALLCONV_UNMANAGED) { CorUnmanagedCallingConvention callConvMaybe; - if (S_OK == MetaSig::TryGetUnmanagedCallingConventionFromModOpt(pVASigCookie->pModule, signature.GetRawSig(), signature.GetRawSigLen(), &callConvMaybe)) + UINT errorResID; + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(pVASigCookie->pModule, signature.GetRawSig(), signature.GetRawSigLen(), &callConvMaybe, &errorResID); + if (FAILED(hr)) + COMPlusThrowHR(hr, errorResID); + + if (hr == S_OK) { callConv = callConvMaybe; } diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 09c077665fe6..e955b3dadec4 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -515,7 +515,12 @@ CEEInfo::ConvToJitSig( static_assert_no_msg(CORINFO_CALLCONV_FASTCALL == (CorInfoCallConv)IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL); CorUnmanagedCallingConvention callConvMaybe; - if (S_OK == MetaSig::TryGetUnmanagedCallingConventionFromModOpt(module, pSig, cbSig, &callConvMaybe)) + UINT errorResID; + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(module, pSig, cbSig, &callConvMaybe, &errorResID); + if (FAILED(hr)) + COMPlusThrowHR(hr, errorResID); + + if (hr == S_OK) { sigRet->callConv = (CorInfoCallConv)callConvMaybe; } diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index 61bbbb8d0593..ee42a4e56404 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -5267,7 +5267,8 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( _In_ Module *pModule, _In_ PCCOR_SIGNATURE pSig, _In_ ULONG cSig, - _Out_ CorUnmanagedCallingConvention *callConvOut) + _Out_ CorUnmanagedCallingConvention *callConvOut, + _Out_ UINT *errorResID) { CONTRACTL { @@ -5276,6 +5277,7 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( FORBID_FAULT; MODE_ANY; PRECONDITION(callConvOut != NULL); + PRECONDITION(errorResID != NULL); } CONTRACTL_END @@ -5285,13 +5287,17 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( _ASSERTE(pWalk <= pSig + cSig); *callConvOut = (CorUnmanagedCallingConvention)0; + bool found = false; while ((pWalk < (pSig + cSig)) && ((*pWalk == ELEMENT_TYPE_CMOD_OPT) || (*pWalk == ELEMENT_TYPE_CMOD_REQD))) { BOOL fIsOptional = (*pWalk == ELEMENT_TYPE_CMOD_OPT); pWalk++; if (pWalk + CorSigUncompressedDataSize(pWalk) > pSig + cSig) - return E_FAIL; // Bad formatting + { + *errorResID = BFA_BAD_SIGNATURE; + return COR_E_BADIMAGEFORMAT; // Bad formatting + } mdToken tk; pWalk += CorSigUncompressToken(pWalk, &tk); @@ -5320,16 +5326,23 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( for (const auto &callConv : knownCallConvs) { - // Take the first recognized calling convention in metadata. + // Look for a recognized calling convention in metadata. if (::strcmp(typeName, callConv.name) == 0) { + // Error if there are multiple recognized calling conventions + if (found) + { + *errorResID = IDS_EE_MULTIPLE_CALLCONV_UNSUPPORTED; + return COR_E_INVALIDPROGRAM; + } + *callConvOut = callConv.value; - return S_OK; + found = true; } } } - return S_FALSE; + return found ? S_OK : S_FALSE; } //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/siginfo.hpp b/src/coreclr/src/vm/siginfo.hpp index 64c9341e693e..7f3fa8b6647b 100644 --- a/src/coreclr/src/vm/siginfo.hpp +++ b/src/coreclr/src/vm/siginfo.hpp @@ -781,20 +781,20 @@ class MetaSig //---------------------------------------------------------- // Gets the unmanaged calling convention by reading any modopts. - // If there are multiple modopts specifying recognized calling - // conventions, the first one that is found in the metadata wins. - // Note: the order in the metadata is the reverse of that in IL. // // Returns: - // E_FAIL - Signature had an invalid format // S_OK - Calling convention was read from modopt // S_FALSE - Calling convention was not read from modopt + // COR_E_BADIMAGEFORMAT - Signature had an invalid format + // COR_E_INVALIDPROGRAM - Program is considered invalid (more + // than one calling convention specified) //---------------------------------------------------------- static HRESULT TryGetUnmanagedCallingConventionFromModOpt( _In_ Module *pModule, _In_ PCCOR_SIGNATURE pSig, _In_ ULONG cSig, - _Out_ CorUnmanagedCallingConvention *callConvOut); + _Out_ CorUnmanagedCallingConvention *callConvOut, + _Out_ UINT *errorResID); static CorUnmanagedCallingConvention GetDefaultUnmanagedCallingConvention() { diff --git a/src/tests/baseservices/callconvs/TestCallingConventions.cs b/src/tests/baseservices/callconvs/TestCallingConventions.cs index 935e4016d20f..fe42b6956108 100644 --- a/src/tests/baseservices/callconvs/TestCallingConventions.cs +++ b/src/tests/baseservices/callconvs/TestCallingConventions.cs @@ -89,8 +89,10 @@ static void BlittableFunctionPointers() { // Multiple modopts with calling conventions Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(cdecl)"); - int b = CallFunctionPointers.CallUnmanagedIntInt_ModOptStdcall_ModOptCdecl(cbCdecl, a); - Assert.AreEqual(expected, b); + var ex = Assert.Throws( + () => CallFunctionPointers.CallUnmanagedIntInt_ModOptStdcall_ModOptCdecl(cbCdecl, a), + "Multiple modopts with calling conventions should fail"); + Assert.AreEqual("Multiple unmanaged calling conventions are specified. Only a single calling convention is supported.", ex.Message); } { @@ -165,8 +167,10 @@ static void NonblittableFunctionPointers() { // Multiple modopts with calling conventions Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(cdecl)"); - var b = CallFunctionPointers.CallUnmanagedCharChar_ModOptStdcall_ModOptCdecl(cbCdecl, a); - Assert.AreEqual(expected, b); + var ex = Assert.Throws( + () => CallFunctionPointers.CallUnmanagedCharChar_ModOptStdcall_ModOptCdecl(cbCdecl, a), + "Multiple modopts with calling conventions should fail"); + Assert.AreEqual("Multiple unmanaged calling conventions are specified. Only a single calling convention is supported.", ex.Message); } { From 065bf96e5c298352c790b9a82564d57a745725f5 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:03:37 +0200 Subject: [PATCH 097/755] Increase HTTP/2 connection expiration test's timeouts (#40015) --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 4328b0aad403..356dff6de0fb 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -2131,7 +2131,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ const int MaxConcurrentStreams = 2; using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); using SocketsHttpHandler handler = CreateHandler(); - handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(5); + handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(10); using (HttpClient client = CreateHttpClient(handler)) { server.AllowMultipleConnections = true; @@ -2142,7 +2142,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ Assert.Equal(MaxConcurrentStreams, acceptedStreamIds.Count); List> connection1SendTasks = new List>(); - Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 10).ConfigureAwait(false); + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 15).ConfigureAwait(false); AcquireAllStreamSlots(server, client, connection1SendTasks, MaxConcurrentStreams); int handledRequests1 = (await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)).Count; From 25c222b46d1ae65e2cb4f5529b81aef287a4aa4e Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 28 Jul 2020 12:14:04 -0700 Subject: [PATCH 098/755] use empty server name is client did not specify one (#39671) * use empty server name * fix merge * feedback from review * add missing file --- .../Interop.Ssl.cs | 2 +- .../Interop.OpenSsl.cs | 2 +- .../Net/Security/SslStream.Implementation.cs | 13 +++---- .../SslStreamNetworkStreamTest.cs | 34 ++++--------------- 4 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs index 4401dec463c5..577ee8126829 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs @@ -384,7 +384,7 @@ public static bool SslCheckHostnameMatch(SafeSslHandle handle, string hostName, // this code could be removed. // // It was verified as supporting case invariant match as of 10.12.1 (Sierra). - string matchName = s_idnMapping.GetAscii(hostName); + string matchName = string.IsNullOrEmpty(hostName) ? string.Empty : s_idnMapping.GetAscii(hostName); using (SafeCFDateHandle cfNotBefore = CoreFoundation.CFDateCreate(notBefore)) using (SafeCreateHandle cfHostname = CoreFoundation.CFStringCreateWithCString(matchName)) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 35f2309c3496..4a8695f5d3d6 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -189,7 +189,7 @@ internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX50 if (!sslAuthenticationOptions.IsServer) { // The IdnMapping converts unicode input into the IDNA punycode sequence. - string punyCode = s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost!); + string punyCode = string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) ? string.Empty : s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost!); // Similar to windows behavior, set SNI on openssl by default for client context, ignore errors. if (!Ssl.SslSetTlsExtHostName(context, punyCode)) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index afda3eb1de5e..5f3c5cdff31e 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -15,8 +15,6 @@ namespace System.Net.Security { public partial class SslStream { - private static int s_uniqueNameInteger = 123; - private SslAuthenticationOptions? _sslAuthenticationOptions; private int _nestedAuth; @@ -66,10 +64,6 @@ private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthe try { _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback); - if (_sslAuthenticationOptions.TargetHost!.Length == 0) - { - _sslAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo); - } _context = new SecureChannel(_sslAuthenticationOptions, this); } catch (Win32Exception e) @@ -420,12 +414,15 @@ private async ValueTask ReceiveBlobAsync(TIOAdapter a if (_lastFrame.HandshakeType == TlsHandshakeType.ClientHello) { // SNI if it exist. Even if we could not parse the hello, we can fall-back to default certificate. - _sslAuthenticationOptions!.TargetHost = _lastFrame.TargetName; + if (_lastFrame.TargetName != null) + { + _sslAuthenticationOptions!.TargetHost = _lastFrame.TargetName; + } if (_sslAuthenticationOptions.ServerOptionDelegate != null) { SslServerAuthenticationOptions userOptions = - await _sslAuthenticationOptions.ServerOptionDelegate(this, new SslClientHelloInfo(_lastFrame.TargetName, _lastFrame.SupportedVersions), + await _sslAuthenticationOptions.ServerOptionDelegate(this, new SslClientHelloInfo(_sslAuthenticationOptions.TargetHost, _lastFrame.SupportedVersions), _sslAuthenticationOptions.UserState, adapter.CancellationToken).ConfigureAwait(false); _sslAuthenticationOptions.UpdateOptions(userOptions); } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index fffc62a5a36e..46345ba49d42 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -205,7 +205,7 @@ public async Task SslStream_NestedAuth_Throws() [InlineData(true)] public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName) { - string tagetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N"); + string targetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N"); (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (clientStream) @@ -218,19 +218,12 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName) Assert.Equal(string.Empty, client.TargetHostName); Assert.Equal(string.Empty, server.TargetHostName); - SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = tagetName }; + SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = targetName }; clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { SslStream stream = (SslStream)sender; - if (useEmptyName) - { - Assert.Equal('?', stream.TargetHostName[0]); - } - else - { - Assert.Equal(tagetName, stream.TargetHostName); - } + Assert.Equal(targetName, stream.TargetHostName); return true; }; @@ -240,14 +233,7 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName) (sender, name) => { SslStream stream = (SslStream)sender; - if (useEmptyName) - { - Assert.Equal('?', stream.TargetHostName[0]); - } - else - { - Assert.Equal(tagetName, stream.TargetHostName); - } + Assert.Equal(targetName, stream.TargetHostName); return certificate; }; @@ -255,16 +241,8 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName) await TestConfiguration.WhenAllOrAnyFailedWithTimeout( client.AuthenticateAsClientAsync(clientOptions), server.AuthenticateAsServerAsync(serverOptions)); - if (useEmptyName) - { - Assert.Equal('?', client.TargetHostName[0]); - Assert.Equal('?', server.TargetHostName[0]); - } - else - { - Assert.Equal(tagetName, client.TargetHostName); - Assert.Equal(tagetName, server.TargetHostName); - } + Assert.Equal(targetName, client.TargetHostName); + Assert.Equal(targetName, server.TargetHostName); } } From 7242e14c534439d8b3aac9f90ce04224e1bdda70 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Tue, 28 Jul 2020 12:25:48 -0700 Subject: [PATCH 099/755] Stop using transport packages for CoreCLR assets (#40002) --- src/coreclr/src/.nuget/Directory.Build.props | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/.nuget/Directory.Build.props b/src/coreclr/src/.nuget/Directory.Build.props index 02ba072c4b88..257da02a7ffc 100644 --- a/src/coreclr/src/.nuget/Directory.Build.props +++ b/src/coreclr/src/.nuget/Directory.Build.props @@ -3,7 +3,7 @@ - + @@ -12,8 +12,10 @@ AnyCPU - - true + + false true From ad939422e1db604a0ff85af01d6cdf636c07fffc Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Tue, 28 Jul 2020 15:57:01 -0400 Subject: [PATCH 100/755] [mono] Fix warnings on OSX netcore (#39997) This commit brings us back to zero warnings for the default build configuration --- src/mono/mono/eventpipe/ep-event-source.c | 2 +- src/mono/mono/metadata/mono-config.c | 6 +++--- src/mono/mono/mini/debugger-agent.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-event-source.c b/src/mono/mono/eventpipe/ep-event-source.c index e4fd95df9bc1..7db34bee58c7 100644 --- a/src/mono/mono/eventpipe/ep-event-source.c +++ b/src/mono/mono/eventpipe/ep-event-source.c @@ -210,7 +210,7 @@ ep_event_source_send_process_info ( os_info_utf16 = ep_rt_utf8_to_utf16_string (_ep_os_info, -1); arch_info_utf16 = ep_rt_utf8_to_utf16_string (_ep_arch_info, -1); - EventData data [3] = { 0 }; + EventData data [3] = { { 0 } }; if (command_line_utf16) ep_event_data_init (&data[0], (uint64_t)command_line_utf16, (uint32_t)((ep_rt_utf16_string_len (command_line_utf16) + 1) * sizeof (ep_char16_t)), 0); if (os_info_utf16) diff --git a/src/mono/mono/metadata/mono-config.c b/src/mono/mono/metadata/mono-config.c index f0940187e1fd..df9cf248efe3 100644 --- a/src/mono/mono/metadata/mono-config.c +++ b/src/mono/mono/metadata/mono-config.c @@ -666,8 +666,7 @@ mono_config_for_assembly_internal (MonoImage *assembly) MONO_REQ_GC_UNSAFE_MODE; MonoConfigParseState state = {NULL}; - int i; - char *aname, *cfg, *cfg_name; + char *cfg_name; const char *bundled_config; state.assembly = assembly; @@ -684,6 +683,7 @@ mono_config_for_assembly_internal (MonoImage *assembly) #ifndef DISABLE_CFGDIR_CONFIG int got_it = 0; + char *aname, *cfg; cfg_name = g_strdup_printf ("%s.config", mono_image_get_name (assembly)); const char *cfg_dir = mono_get_config_dir (); if (!cfg_dir) { @@ -691,7 +691,7 @@ mono_config_for_assembly_internal (MonoImage *assembly) return; } - for (i = 0; (aname = get_assembly_filename (assembly, i)) != NULL; ++i) { + for (int i = 0; (aname = get_assembly_filename (assembly, i)) != NULL; ++i) { cfg = g_build_filename (cfg_dir, "mono", "assemblies", aname, cfg_name, (const char*)NULL); got_it += mono_config_parse_file_with_context (&state, cfg); g_free (cfg); diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index eb26b88570e1..6e39d3e56859 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -3598,9 +3598,9 @@ 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 GENERATE_TRY_GET_CLASS_WITH_CACHE(hidden_klass, "System.Diagnostics", "DebuggerHiddenAttribute") +static GENERATE_TRY_GET_CLASS_WITH_CACHE(step_through_klass, "System.Diagnostics", "DebuggerStepThroughAttribute") +static GENERATE_TRY_GET_CLASS_WITH_CACHE(non_user_klass, "System.Diagnostics", "DebuggerNonUserCodeAttribute") static void init_jit_info_dbg_attrs (MonoJitInfo *ji) From 56797842d45a0f55345842ab166618d0c153ec3c Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Tue, 28 Jul 2020 13:31:41 -0700 Subject: [PATCH 101/755] Enable dumping GC tables in release builds (#39946) * Dump GC info always in release builds Add support for dumping non-x86 info in release builds * Revert DUMP_GC_TABLES change * Fix formatting --- src/coreclr/src/jit/compiler.h | 3 +-- src/coreclr/src/jit/gcencode.cpp | 17 ++++++++++------- src/coreclr/src/jit/target.h | 4 ++-- src/coreclr/src/jit/utils.cpp | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 7c3a3473508a..9b7a3d24191f 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -8814,8 +8814,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool doLateDisasm; // Run the late disassembler #endif // LATE_DISASM -#if DUMP_GC_TABLES && !defined(DEBUG) && defined(JIT32_GCENCODER) -// Only the JIT32_GCENCODER implements GC dumping in non-DEBUG code. +#if DUMP_GC_TABLES && !defined(DEBUG) #pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!") static const bool dspGCtbls = true; #endif diff --git a/src/coreclr/src/jit/gcencode.cpp b/src/coreclr/src/jit/gcencode.cpp index 3c45137b0593..81edb0b0d29e 100644 --- a/src/coreclr/src/jit/gcencode.cpp +++ b/src/coreclr/src/jit/gcencode.cpp @@ -3633,7 +3633,10 @@ void GCInfo::gcFindPtrsInFrame(const void* infoBlock, const void* codeBlock, uns template class JitHashTable; template class JitHashTable; -#ifdef DEBUG +#if defined(DEBUG) || DUMP_GC_TABLES + +// This is a copy of GcStackSlotBaseNames from gcinfotypes.h so we can compile in to non-DEBUG builds. +const char* const JitGcStackSlotBaseNames[] = {"caller.sp", "sp", "frame"}; static const char* const GcSlotFlagsNames[] = {"", "(byref) ", @@ -3652,7 +3655,7 @@ class GcInfoEncoderWithLogging public: GcInfoEncoderWithLogging(GcInfoEncoder* gcInfoEncoder, bool verbose) - : m_gcInfoEncoder(gcInfoEncoder), m_doLogging(verbose || JitConfig.JitGCInfoLogging() != 0) + : m_gcInfoEncoder(gcInfoEncoder), m_doLogging(verbose INDEBUG(|| JitConfig.JitGCInfoLogging() != 0)) { } @@ -3662,7 +3665,7 @@ class GcInfoEncoderWithLogging if (m_doLogging) { printf("Stack slot id for offset %d (0x%x) (%s) %s= %d.\n", spOffset, spOffset, - GcStackSlotBaseNames[spBase], GcSlotFlagsNames[flags & 7], newSlotId); + JitGcStackSlotBaseNames[spBase], GcSlotFlagsNames[flags & 7], newSlotId); } return newSlotId; } @@ -3827,14 +3830,14 @@ class GcInfoEncoderWithLogging }; #define GCENCODER_WITH_LOGGING(withLog, realEncoder) \ - GcInfoEncoderWithLogging withLog##Var(realEncoder, compiler->verbose || compiler->opts.dspGCtbls); \ + GcInfoEncoderWithLogging withLog##Var(realEncoder, INDEBUG(compiler->verbose ||) compiler->opts.dspGCtbls); \ GcInfoEncoderWithLogging* withLog = &withLog##Var; -#else // DEBUG +#else // !(defined(DEBUG) || DUMP_GC_TABLES) #define GCENCODER_WITH_LOGGING(withLog, realEncoder) GcInfoEncoder* withLog = realEncoder; -#endif // DEBUG +#endif // !(defined(DEBUG) || DUMP_GC_TABLES) void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSize, unsigned prologSize) { @@ -4006,7 +4009,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz #endif // DISPLAY_SIZES } -#ifdef DEBUG +#if defined(DEBUG) || DUMP_GC_TABLES #define Encoder GcInfoEncoderWithLogging #else #define Encoder GcInfoEncoder diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index 9d6bc46472eb..17ecc23c0a16 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -1619,11 +1619,11 @@ class Target static const enum ArgOrder g_tgtArgOrder; }; -#if defined(DEBUG) || defined(LATE_DISASM) +#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES const char* getRegName(unsigned reg, bool isFloat = false); // this is for gcencode.cpp and disasm.cpp that don't use // the regNumber type const char* getRegName(regNumber reg, bool isFloat = false); -#endif // defined(DEBUG) || defined(LATE_DISASM) +#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES #ifdef DEBUG const char* getRegNameFloat(regNumber reg, var_types type); diff --git a/src/coreclr/src/jit/utils.cpp b/src/coreclr/src/jit/utils.cpp index 36e901a0acc4..de1fd4a880b2 100644 --- a/src/coreclr/src/jit/utils.cpp +++ b/src/coreclr/src/jit/utils.cpp @@ -128,7 +128,7 @@ const char* varTypeName(var_types vt) return varTypeNames[vt]; } -#if defined(DEBUG) || defined(LATE_DISASM) +#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES /***************************************************************************** * * Return the name of the given register. @@ -164,7 +164,7 @@ const char* getRegName(unsigned reg, { return getRegName((regNumber)reg, isFloat); } -#endif // defined(DEBUG) || defined(LATE_DISASM) +#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES #if defined(DEBUG) From e2f18bffa8f96a71b32ddd3f2881202a384cc1c8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 13:45:31 -0700 Subject: [PATCH 102/755] Update dependencies from https://github.com/dotnet/icu build 20200728.2 (#40011) Microsoft.NETCore.Runtime.ICU.Transport From Version 5.0.0-preview.8.20373.1 -> To Version 5.0.0-preview.8.20378.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5004c7a38e1d..19226bc17d50 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 - 75440631a7eb7f89da35d5a509d1d5f2eaab7f96 + 7ba1659d3c954a86115ddd0e0e8445a8c7c0dee8 diff --git a/eng/Versions.props b/eng/Versions.props index 86656b65675a..e005381789a8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -148,7 +148,7 @@ 5.0.0-preview.3.20374.1 - 5.0.0-preview.8.20373.1 + 5.0.0-preview.8.20378.2 9.0.1-alpha.1.20365.1 9.0.1-alpha.1.20365.1 From 9e06a244f20a6a81d17865688815158c49accceb Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 29 Jul 2020 00:23:56 +0300 Subject: [PATCH 103/755] Intrinsify MemoryMarshal.GetArrayDataReference for interp (#39920) --- src/mono/mono/mini/interp/interp.c | 7 +++++++ src/mono/mono/mini/interp/mintops.def | 1 + src/mono/mono/mini/interp/transform.c | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index d107b8d1b541..8d86279fd07e 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -5318,6 +5318,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs ++ip; MINT_IN_BREAK; } + MINT_IN_CASE(MINT_INTRINS_MEMORYMARSHAL_GETARRAYDATAREF) { + MonoObject* const o = sp [-1].data.o; + NULL_CHECK (o); + sp[-1].data.p = (guint8*)o + MONO_STRUCT_OFFSET (MonoArray, vector); + ++ip; + MINT_IN_BREAK; + } MINT_IN_CASE(MINT_INTRINS_ORDINAL_IGNORE_CASE_ASCII) { sp--; sp [-1].data.i = interp_intrins_ordinal_ignore_case_ascii ((guint32)sp [-1].data.i, (guint32)sp [0].data.i); diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index 488fc86dded3..6e4d90fab787 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -795,6 +795,7 @@ OPDEF(MINT_INTRINS_RUNTIMEHELPERS_OBJECT_HAS_COMPONENT_SIZE, "intrins_runtimehel OPDEF(MINT_INTRINS_CLEAR_WITH_REFERENCES, "intrin_clear_with_references", 1, Pop2, Push0, MintOpNoArgs) OPDEF(MINT_INTRINS_MARVIN_BLOCK, "intrins_marvin_block", 1, Pop2, Push0, MintOpNoArgs) OPDEF(MINT_INTRINS_ASCII_CHARS_TO_UPPERCASE, "intrins_ascii_chars_to_uppercase", 1, Pop1, Push1, MintOpNoArgs) +OPDEF(MINT_INTRINS_MEMORYMARSHAL_GETARRAYDATAREF, "intrins_memorymarshal_getarraydataref", 1, Pop1, Push1, MintOpNoArgs) OPDEF(MINT_INTRINS_ORDINAL_IGNORE_CASE_ASCII, "intrins_ordinal_ignore_case_ascii", 1, Pop2, Push1, MintOpNoArgs) OPDEF(MINT_INTRINS_64ORDINAL_IGNORE_CASE_ASCII, "intrins_64ordinal_ignore_case_ascii", 1, Pop2, Push1, MintOpNoArgs) OPDEF(MINT_INTRINS_U32_TO_DECSTR, "intrins_u32_to_decstr", 3, Pop1, Push1, MintOpNoArgs) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index f0a333d04dcf..13c910817b70 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1505,6 +1505,9 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas } else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "Marvin")) { if (!strcmp (tm, "Block")) *op = MINT_INTRINS_MARVIN_BLOCK; + } else if (in_corlib && !strcmp (klass_name_space, "System.Runtime.InteropServices") && !strcmp (klass_name, "MemoryMarshal")) { + if (!strcmp (tm, "GetArrayDataReference")) + *op = MINT_INTRINS_MEMORYMARSHAL_GETARRAYDATAREF; } else if (in_corlib && !strcmp (klass_name_space, "System.Text.Unicode") && !strcmp (klass_name, "Utf16Utility")) { if (!strcmp (tm, "ConvertAllAsciiCharsInUInt32ToUppercase")) *op = MINT_INTRINS_ASCII_CHARS_TO_UPPERCASE; From 9a9a2da91844dbfb0d9265daecacb31dc79f44fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 28 Jul 2020 23:27:17 +0200 Subject: [PATCH 104/755] [wasm] Add missing EMCC_FLAGS variable when building corebindings.o (#40024) --- src/mono/wasm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 636ff21d20c2..978bd1c1c4d3 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -88,7 +88,7 @@ $(BUILDS_OBJ_DIR)/pinvoke.o: runtime/pinvoke.c runtime/pinvoke.h $(BUILDS_OBJ_DI $(EMCC) $(EMCC_FLAGS) $(1) -Oz -DGEN_PINVOKE=1 -I$(BUILDS_OBJ_DIR) -I$(MONO_INCLUDE_DIR) runtime/pinvoke.c -c -o $$@ $(BUILDS_OBJ_DIR)/corebindings.o: runtime/corebindings.c | $(BUILDS_OBJ_DIR) - $(EMCC) $(1) -Oz -I$(MONO_INCLUDE_DIR) runtime/corebindings.c -c -o $$@ + $(EMCC) $(EMCC_FLAGS) $(1) -Oz -I$(MONO_INCLUDE_DIR) runtime/corebindings.c -c -o $$@ build-native: $(BUILDS_BIN_DIR)/dotnet.js From 87f016559967a9add507a80d5cc311eb008317ef Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Tue, 28 Jul 2020 14:33:36 -0700 Subject: [PATCH 105/755] Update visualstudio.md (#40047) --- docs/workflow/testing/visualstudio.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/workflow/testing/visualstudio.md b/docs/workflow/testing/visualstudio.md index c8c20b9cfc7f..106f069f7df7 100644 --- a/docs/workflow/testing/visualstudio.md +++ b/docs/workflow/testing/visualstudio.md @@ -1,9 +1,25 @@ -# Visual Studio Test Explorer support -For Visual Studio Test Explorer to work in dotnet/runtime, the following test settings need to be enabled: -- Test parameters (like which `dotnet` host to use) are persisted in an auto-generated .runsettings file. For that to work, make sure that the "Auto detect runsettings Files" (`Options -> Test`) option is enabled. -- Make sure that the "Processor Architecture for AnyCPU project" (`Test Explore pane -> Test Explorer toolbar options --> Settings`) value is set to `auto`. +# Working in dotnet/runtime using Visual Studio + +Visual Studio is a great tool to use when working in the dotnet/runtime repo. + +Almost all its features should work well, but there are a few special considerations to bear in mind: + +## Test Explorer + +You can run tests from the Visual Studio Test Explorer, but there are a few settings you need: +- Enable `Auto detect runsettings Files` (`Test Explorer window -> Settings button -> Options`). Test parameters (like which `dotnet` host to use) are persisted in an auto-generated .runsettings file, and it's important that Visual Studio knows to use it. +- Set `Processor Architecture for AnyCPU project` to `auto` (`Test Explorer window -> Settings button`). +- Consider whether to disable `Discover tests in real time from C# and Visual Basic .NET source files` (`Test explorer window -> Settings button -> Options`). + - You may want it enabled if you're actively writing new tests and want them to show up in Test Explorer without building first. + - You may want it disabled if you're mostly running existing tests, and some of them have conditional attributes. Many of our unit tests have attributes, like `[SkipOnTargetFramework]`, to indicate that they're only valid in certain configurations. Because the real-time discovery feature does not currently recognize these attributes the tests will show up in Test Explorer as well, and fail or possibly hang when you try to run them. +- Consider whether to enable `Run tests in Parallel` (`Test Explorer window -> Settings button`). + - You may want it enabled if some of the unit tests you're working with run slowly or there's many of them. + - You may want it disabled if you want to simplify debugging or viewing debug output. + +If you encounter puzzling behavior while running tests within Visual Studio, first check the settings above, verify they run correctly from the command line, and also make sure you're using the latest Visual Studio. It can be helpful to enable detailed logging of the test runner (`Test explorer window -> Settings button -> Options > Logging Level: Trace`) - it may suggest the problem, or at least provide more information to share. + +## Start with Debugging (F5) -# Visual Studio F5 Debugging support dotnet/runtime uses `dotnet test` ([VSTest](https://github.com/Microsoft/vstest)) which spawns child processes during test execution. Visual Studio by default doesn't automatically debug child processes, therefore preliminary steps need to be done to enable Debugging "F5" support. Note that these steps aren't necessary for Visual Studio Test Explorer support. @@ -14,3 +30,4 @@ Note that these steps aren't necessary for Visual Studio Test Explorer support. ## References - https://github.com/dotnet/project-system/issues/6176 tracks enabling the native code debugging functionality for multiple projects without user interaction. - https://github.com/dotnet/sdk/issues/7419#issuecomment-298261617 explains the necessary steps to install and enable the mentioned extension in more detail. +- https://github.com/microsoft/vstest/ is the repo for issues with the Visual Studio test execution features. From 0f8768677e26bd80e3d3be01940c699c63e9106e Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Tue, 28 Jul 2020 18:38:41 -0300 Subject: [PATCH 106/755] Manually merging driver.c from https://github.com/mono/mono/pull/20159 (#40031) --- src/mono/wasm/runtime/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 32383d7c9bc5..e98b1b845933 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -372,7 +372,7 @@ mono_wasm_load_runtime (const char *unused, int enable_debugging) mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY); #endif #else - mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_LLVMONLY); + mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_ONLY); if (enable_debugging) { // Disable optimizations which interfere with debugging interp_opts = "-all"; From f8620a152f33161ae462f208406a72f0b025441d Mon Sep 17 00:00:00 2001 From: monojenkins Date: Tue, 28 Jul 2020 18:35:56 -0400 Subject: [PATCH 107/755] [debugger] Revert Removing unhandled_exception which was used for android (#40027) This reverts commit 60643c36f5d4e349276e5dcce0e7fc3dc1d72f74. To investigate error on android tests. Co-authored-by: thaystg --- src/mono/mono/mini/debugger-agent-stubs.c | 7 +++++++ src/mono/mono/mini/debugger-agent.c | 21 +++++++++++++++++++++ src/mono/mono/mini/debugger-agent.h | 1 + src/mono/mono/mini/mini-exceptions.c | 11 ++--------- src/mono/mono/mini/mini-runtime.c | 5 +++++ 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/debugger-agent-stubs.c b/src/mono/mono/mini/debugger-agent-stubs.c index 539f454f044d..98054f84ce02 100644 --- a/src/mono/mono/mini/debugger-agent-stubs.c +++ b/src/mono/mono/mini/debugger-agent-stubs.c @@ -73,6 +73,12 @@ stub_debugger_agent_debug_log_is_enabled (void) return FALSE; } +static void +stub_debugger_agent_unhandled_exception (MonoException *exc) +{ + g_assert_not_reached (); +} + static void stub_debugger_agent_single_step_from_context (MonoContext *ctx) { @@ -104,6 +110,7 @@ mono_debugger_agent_stub_init (void) cbs.single_step_from_context = stub_debugger_agent_single_step_from_context; cbs.breakpoint_from_context = stub_debugger_agent_breakpoint_from_context; cbs.free_domain_info = stub_debugger_agent_free_domain_info; + cbs.unhandled_exception = stub_debugger_agent_unhandled_exception; cbs.handle_exception = stub_debugger_agent_handle_exception; cbs.begin_exception_filter = stub_debugger_agent_begin_exception_filter; cbs.end_exception_filter = stub_debugger_agent_end_exception_filter; diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index 6e39d3e56859..82108808fc21 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -5286,6 +5286,26 @@ debugger_agent_debug_log_is_enabled (void) return agent_config.enabled; } +static void +debugger_agent_unhandled_exception (MonoException *exc) +{ + int suspend_policy; + GSList *events; + EventInfo ei; + + if (!inited) + return; + + memset (&ei, 0, sizeof (ei)); + ei.exc = (MonoObject*)exc; + + mono_loader_lock (); + events = create_event_list (EVENT_KIND_EXCEPTION, NULL, NULL, &ei, &suspend_policy); + mono_loader_unlock (); + + process_event (EVENT_KIND_EXCEPTION, &ei, 0, NULL, events, suspend_policy); +} + static void debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame) @@ -10400,6 +10420,7 @@ mono_debugger_agent_init (void) cbs.single_step_from_context = debugger_agent_single_step_from_context; cbs.breakpoint_from_context = debugger_agent_breakpoint_from_context; cbs.free_domain_info = debugger_agent_free_domain_info; + cbs.unhandled_exception = debugger_agent_unhandled_exception; cbs.handle_exception = debugger_agent_handle_exception; cbs.begin_exception_filter = debugger_agent_begin_exception_filter; cbs.end_exception_filter = debugger_agent_end_exception_filter; diff --git a/src/mono/mono/mini/debugger-agent.h b/src/mono/mono/mini/debugger-agent.h index 750e5248f248..908189059611 100644 --- a/src/mono/mono/mini/debugger-agent.h +++ b/src/mono/mono/mini/debugger-agent.h @@ -21,6 +21,7 @@ struct _MonoDebuggerCallbacks { void (*single_step_from_context) (MonoContext *ctx); void (*breakpoint_from_context) (MonoContext *ctx); void (*free_domain_info) (MonoDomain *domain); + void (*unhandled_exception) (MonoException *exc); void (*handle_exception) (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame); void (*begin_exception_filter) (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx); diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index 2fc607c05ca6..e75267929377 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -2366,15 +2366,8 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED && ftnptr_eh_callback) { result = MONO_FIRST_PASS_CALLBACK_TO_NATIVE; } - -#if defined(HOST_ANDROID) || defined(TARGET_ANDROID) - //ignore the try catch in the .. icall_wrapper call - if (method->wrapper_type == WRAPPER_SUBTYPE_ICALL_WRAPPER) { - *ctx = new_ctx; - continue; - } -#endif - + + for (i = clause_index_start; i < ji->num_clauses; i++) { MonoJitExceptionInfo *ei = &ji->clauses [i]; gboolean filtered = FALSE; diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 82a8da22d6f7..33c2a761189f 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4646,6 +4646,11 @@ register_icalls (void) mono_add_internal_call_internal ("Mono.Runtime::mono_runtime_cleanup_handlers", mono_runtime_cleanup_handlers); +#if defined(HOST_ANDROID) || defined(TARGET_ANDROID) + mono_add_internal_call_internal ("System.Diagnostics.Debugger::Mono_UnhandledException_internal", + mini_get_dbg_callbacks ()->unhandled_exception); +#endif + /* * It's important that we pass `TRUE` as the last argument here, as * it causes the JIT to omit a wrapper for these icalls. If the JIT From 1a61fa02d3f03389a6e24816fa898f8198155df7 Mon Sep 17 00:00:00 2001 From: Jarret Shook Date: Tue, 28 Jul 2020 15:38:43 -0700 Subject: [PATCH 108/755] Disable based on #40034 (#40035) --- eng/pipelines/runtime.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 17afa74cdb36..3dcbae586984 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -226,7 +226,8 @@ jobs: jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml platforms: - Linux_x64 - - Windows_NT_x64 + # Isssue: https://github.com/dotnet/runtime/issues/40034 + #- Windows_NT_x64 jobParameters: condition: >- and( From 23922b52b350f14c2c2cbb9f2ec6d2dc1c1210c2 Mon Sep 17 00:00:00 2001 From: Elinor Fung <47805090+elinor-fung@users.noreply.github.com> Date: Tue, 28 Jul 2020 15:57:17 -0700 Subject: [PATCH 109/755] Fix parsing of embedded .clsidmap in comhost (#40022) * Fix parsing of embedded .clsidmap in comhost * Update tests to use HostModel to create/embed clsidmap --- .../corehost/cli/comhost/clsidmap.cpp | 41 +++++++--------- src/installer/corehost/cli/json_parser.cpp | 48 ++++++++++--------- src/installer/corehost/cli/json_parser.h | 3 +- .../TestProjects/ComLibrary/ComLibrary.csproj | 1 + .../NativeHosting/Comhost.cs | 40 ++++++++-------- 5 files changed, 65 insertions(+), 68 deletions(-) diff --git a/src/installer/corehost/cli/comhost/clsidmap.cpp b/src/installer/corehost/cli/comhost/clsidmap.cpp index b119c50ee9c5..7d740b95ab45 100644 --- a/src/installer/corehost/cli/comhost/clsidmap.cpp +++ b/src/installer/corehost/cli/comhost/clsidmap.cpp @@ -43,16 +43,8 @@ namespace return S_OK; } - clsid_map parse_stream(_Inout_ pal::istream_t &json_map_raw) + clsid_map get_map_from_json(_In_ const json_parser_t &json) { - json_parser_t json; - - if (!json.parse_stream(json_map_raw, _X(""))) - { - trace::error(_X("Embedded .clsidmap format is invalid")); - throw HResultException{ StatusCode::InvalidConfigFile }; - } - // Process JSON and construct a map HRESULT hr; clsid_map mapping; @@ -86,16 +78,6 @@ namespace return mapping; } - class memory_buffer : public std::basic_streambuf - { - public: - memory_buffer(_In_ DWORD dataInBytes, _In_reads_bytes_(dataInBytes) void *data) - { - auto raw_begin = reinterpret_cast(data); - setg(raw_begin, raw_begin, raw_begin + (dataInBytes / sizeof(pal::istream_t::char_type))); - } - }; - clsid_map get_json_map_from_resource(bool &found_resource) { found_resource = false; @@ -117,9 +99,14 @@ namespace if (data == nullptr) throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+ - memory_buffer resourceBuffer{ size, data }; - pal::istream_t stream{ &resourceBuffer }; - return parse_stream(stream); + json_parser_t json; + if (!json.parse_raw_data(reinterpret_cast(data), size, _X(""))) + { + trace::error(_X("Embedded .clsidmap format is invalid")); + throw HResultException{ StatusCode::InvalidConfigFile }; + } + + return get_map_from_json(json); } bool is_binary_unsigned(const pal::string_t &path) @@ -190,8 +177,14 @@ namespace if (!pal::file_exists(map_file_name)) return {}; - pal::ifstream_t file{ map_file_name }; - return parse_stream(file); + json_parser_t json; + if (!json.parse_file(map_file_name)) + { + trace::error(_X("File .clsidmap format is invalid")); + throw HResultException{ StatusCode::InvalidConfigFile }; + } + + return get_map_from_json(json); } } diff --git a/src/installer/corehost/cli/json_parser.cpp b/src/installer/corehost/cli/json_parser.cpp index 3953de113107..740b71494aa8 100644 --- a/src/installer/corehost/cli/json_parser.cpp +++ b/src/installer/corehost/cli/json_parser.cpp @@ -74,8 +74,10 @@ void json_parser_t::realloc_buffer(size_t size) m_json[size] = '\0'; } -bool json_parser_t::parse_json(char* data, int64_t size, const pal::string_t& context) +bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context) { + assert(data != nullptr); + constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag; #ifdef _WIN32 // Can't use in-situ parsing on Windows, as JSON data is encoded in @@ -109,26 +111,6 @@ bool json_parser_t::parse_json(char* data, int64_t size, const pal::string_t& co return true; } -bool json_parser_t::parse_stream(pal::istream_t& stream, - const pal::string_t& context) -{ - if (!stream.good()) - { - trace::error(_X("Cannot use stream for resource [%s]: %s"), context.c_str(), pal::strerror(errno)); - return false; - } - - auto current_pos = ::get_utf8_bom_length(stream); - stream.seekg(0, stream.end); - auto stream_size = stream.tellg(); - stream.seekg(current_pos, stream.beg); - - realloc_buffer(stream_size - current_pos); - stream.read(m_json.data(), stream_size - current_pos); - - return parse_json(m_json.data(), m_json.size(), context); -} - bool json_parser_t::parse_file(const pal::string_t& path) { // This code assumes that the caller has checked that the file `path` exists @@ -145,13 +127,33 @@ bool json_parser_t::parse_file(const pal::string_t& path) if (m_bundle_data != nullptr) { - bool result = parse_json(m_bundle_data, m_bundle_location->size, path); + bool result = parse_raw_data(m_bundle_data, m_bundle_location->size, path); return result; } } pal::ifstream_t file{ path }; - return parse_stream(file, path); + if (!file.good()) + { + trace::error(_X("Cannot use file stream for [%s]: %s"), path.c_str(), pal::strerror(errno)); + return false; + } + + auto current_pos = ::get_utf8_bom_length(file); + file.seekg(0, file.end); + auto stream_size = file.tellg(); + if (stream_size == -1) + { + trace::error(_X("Failed to get size of file [%s]"), path.c_str()); + return false; + } + + file.seekg(current_pos, file.beg); + + realloc_buffer(stream_size - current_pos); + file.read(m_json.data(), stream_size - current_pos); + + return parse_raw_data(m_json.data(), m_json.size(), path); } json_parser_t::~json_parser_t() diff --git a/src/installer/corehost/cli/json_parser.h b/src/installer/corehost/cli/json_parser.h index 350ea14e6037..f4be31d09b79 100644 --- a/src/installer/corehost/cli/json_parser.h +++ b/src/installer/corehost/cli/json_parser.h @@ -30,7 +30,7 @@ class json_parser_t { const document_t& document() const { return m_document; } - bool parse_stream(pal::istream_t& stream, const pal::string_t& context); + bool parse_raw_data(char* data, int64_t size, const pal::string_t& context); bool parse_file(const pal::string_t& path); json_parser_t() @@ -52,7 +52,6 @@ class json_parser_t { const bundle::location_t* m_bundle_location; // Location of this json file within the bundle. void realloc_buffer(size_t size); - bool parse_json(char* data, int64_t size, const pal::string_t& context); }; #endif // __JSON_PARSER_H__ diff --git a/src/installer/tests/Assets/TestProjects/ComLibrary/ComLibrary.csproj b/src/installer/tests/Assets/TestProjects/ComLibrary/ComLibrary.csproj index 637cbf46c656..27861faa6105 100644 --- a/src/installer/tests/Assets/TestProjects/ComLibrary/ComLibrary.csproj +++ b/src/installer/tests/Assets/TestProjects/ComLibrary/ComLibrary.csproj @@ -3,6 +3,7 @@ $(NetCoreAppCurrent) $(MNAVersion) + true diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs index ddf80fe20a29..7c6f5976c630 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.DotNet.Cli.Build.Framework; -using Newtonsoft.Json.Linq; using System.IO; +using System.Reflection.Metadata; using System.Runtime.InteropServices; + +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.NET.HostModel.ComHost; using Xunit; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting @@ -136,26 +138,26 @@ public SharedTestState() .EnsureRestored(RepoDirectories.CorehostPackages) .BuildProject(); - // [TODO] BEGIN - Remove once using .NET Core 3.0 to build tests - ComHostPath = Path.Combine( - ComLibraryFixture.TestProject.BuiltApp.Location, - $"{ ComLibraryFixture.TestProject.AssemblyName }.comhost.dll"); - - File.Copy(Path.Combine(RepoDirectories.CorehostPackages, "comhost.dll"), ComHostPath); - - RuntimeConfig.FromFile(ComLibraryFixture.TestProject.RuntimeConfigJson) - .WithFramework(new RuntimeConfig.Framework("Microsoft.NETCore.App", RepoDirectories.MicrosoftNETCoreAppVersion)) - .Save(); - - JObject clsidMap = new JObject() + // Create a .clsidmap from the assembly + string clsidMapPath = Path.Combine(BaseDirectory, $"{ ComLibraryFixture.TestProject.AssemblyName }.clsidmap"); + using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) + using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream)) { + if (peReader.HasMetadata) { - ClsidString, - new JObject() { {"assembly", "ComLibrary" }, {"type", "ComLibrary.Server" } } + MetadataReader reader = peReader.GetMetadataReader(); + ClsidMap.Create(reader, clsidMapPath); } - }; - File.WriteAllText($"{ ComHostPath }.clsidmap", clsidMap.ToString()); - // [TODO] END - Remove once using .NET Core 3.0 to build tests + } + + // Use the locally built comhost to create a comhost with the embedded .clsidmap + ComHostPath = Path.Combine( + ComLibraryFixture.TestProject.BuiltApp.Location, + $"{ ComLibraryFixture.TestProject.AssemblyName }.comhost.dll"); + ComHost.Create( + Path.Combine(RepoDirectories.CorehostPackages, "comhost.dll"), + ComHostPath, + clsidMapPath); } protected override void Dispose(bool disposing) From 04fbbd913d0c3f9a245de2d6db9e381da8a5b6d6 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 28 Jul 2020 16:10:38 -0700 Subject: [PATCH 110/755] Cleanup mscorlib references under src\coreclr\src (#39994) * s/MscorlibBinder/CoreLibBinder/ * s/g_Mscorlib/g_CoreLib/ * Remaining mscorlib->corelib renames * Delete unreachable FNV NGen string --- ...ateRuntimeRootILLinkDescriptorFile.targets | 2 +- .../src/System/Environment.CoreCLR.cs | 4 +- .../src/System/Exception.CoreCLR.cs | 4 +- .../System.Private.CoreLib/src/System/GC.cs | 2 +- .../Runtime/Versioning/CompatibilitySwitch.cs | 19 +- src/coreclr/src/binder/assemblybinder.cpp | 10 +- src/coreclr/src/binder/assemblyname.cpp | 4 +- src/coreclr/src/binder/bindertracing.cpp | 2 +- .../clrprivbinderassemblyloadcontext.cpp | 6 +- .../src/binder/clrprivbindercoreclr.cpp | 8 +- src/coreclr/src/binder/inc/assemblyname.hpp | 2 +- src/coreclr/src/binder/inc/variables.hpp | 2 +- src/coreclr/src/binder/variables.cpp | 2 +- .../classlibnative/bcltype/varargsnative.cpp | 8 +- src/coreclr/src/debug/daccess/dacdbiimpl.cpp | 4 +- src/coreclr/src/debug/daccess/enummem.cpp | 2 +- src/coreclr/src/debug/daccess/inspect.cpp | 2 +- src/coreclr/src/debug/daccess/nidump.cpp | 88 +++---- src/coreclr/src/debug/daccess/nidump.h | 6 +- src/coreclr/src/debug/daccess/request.cpp | 2 +- src/coreclr/src/debug/daccess/stack.cpp | 2 +- src/coreclr/src/debug/di/rstype.cpp | 2 +- src/coreclr/src/debug/ee/debugger.cpp | 4 +- src/coreclr/src/debug/inc/dbgipcevents.h | 2 +- src/coreclr/src/dlls/mscoree/mscoree.cpp | 2 +- src/coreclr/src/gc/gcinterface.h | 8 +- src/coreclr/src/inc/corcompile.h | 6 +- src/coreclr/src/inc/cordebug.idl | 4 +- src/coreclr/src/inc/corerror.xml | 10 +- src/coreclr/src/inc/corexcep.h | 2 +- src/coreclr/src/inc/corpriv.h | 2 +- src/coreclr/src/inc/dacvars.h | 2 +- src/coreclr/src/inc/random.h | 3 +- src/coreclr/src/inc/zapper.h | 2 +- src/coreclr/src/jit/codegencommon.cpp | 2 +- src/coreclr/src/jit/compiler.h | 2 +- src/coreclr/src/jit/flowgraph.cpp | 2 +- src/coreclr/src/jit/importer.cpp | 2 +- src/coreclr/src/jit/inline.cpp | 2 +- src/coreclr/src/jit/inlinepolicy.cpp | 2 +- src/coreclr/src/jit/lowerxarch.cpp | 2 +- src/coreclr/src/jit/scopeinfo.cpp | 2 +- src/coreclr/src/jit/ssabuilder.cpp | 2 - src/coreclr/src/jit/unwind.h | 4 +- .../src/pal/prebuilt/corerror/mscorurt.rc | 3 +- src/coreclr/src/pal/prebuilt/inc/corerror.h | 1 - src/coreclr/src/pal/src/locale/utf8.cpp | 2 +- .../tests/palsuite/common/ResultBuffer.cpp | 5 - .../nativecriticalsection/resultbuffer.cpp | 5 - .../nativecs_interlocked/resultbuffer.cpp | 5 - .../Common/Internal/Runtime/CorConstants.cs | 2 +- .../TypeSystem/IL/Stubs/VolatileIntrinsics.cs | 2 +- src/coreclr/src/tools/crossgen/CMakeLists.txt | 2 +- src/coreclr/src/tools/crossgen/crossgen.cpp | 16 +- src/coreclr/src/vm/CMakeLists.txt | 4 +- src/coreclr/src/vm/amd64/asmconstants.h | 2 +- src/coreclr/src/vm/appdomain.cpp | 124 +++++----- src/coreclr/src/vm/appdomain.hpp | 9 +- src/coreclr/src/vm/appdomainnative.cpp | 2 +- src/coreclr/src/vm/array.cpp | 22 +- src/coreclr/src/vm/assemblyname.cpp | 2 +- src/coreclr/src/vm/assemblynative.cpp | 10 +- src/coreclr/src/vm/assemblyspec.cpp | 14 +- src/coreclr/src/vm/baseassemblyspec.cpp | 24 +- src/coreclr/src/vm/baseassemblyspec.h | 6 +- src/coreclr/src/vm/baseassemblyspec.inl | 2 +- src/coreclr/src/vm/binder.cpp | 216 +++++++++--------- src/coreclr/src/vm/binder.h | 122 +++++----- src/coreclr/src/vm/callhelpers.cpp | 4 +- src/coreclr/src/vm/callhelpers.h | 14 +- src/coreclr/src/vm/callsiteinspect.cpp | 4 +- src/coreclr/src/vm/castcache.cpp | 2 +- src/coreclr/src/vm/ceeload.cpp | 24 +- src/coreclr/src/vm/ceeload.h | 8 +- src/coreclr/src/vm/ceemain.cpp | 12 +- src/coreclr/src/vm/cgensys.h | 2 +- src/coreclr/src/vm/classcompat.cpp | 43 ---- src/coreclr/src/vm/classlayoutinfo.cpp | 8 +- src/coreclr/src/vm/clrex.cpp | 14 +- src/coreclr/src/vm/clsload.cpp | 10 +- src/coreclr/src/vm/comcallablewrapper.cpp | 26 +-- src/coreclr/src/vm/comdelegate.cpp | 24 +- src/coreclr/src/vm/commodule.cpp | 4 +- src/coreclr/src/vm/common.h | 2 +- src/coreclr/src/vm/compatibilityswitch.cpp | 17 +- src/coreclr/src/vm/compatibilityswitch.h | 2 +- src/coreclr/src/vm/compile.cpp | 61 +++-- src/coreclr/src/vm/compile.h | 2 +- src/coreclr/src/vm/comsynchronizable.cpp | 4 +- src/coreclr/src/vm/comthreadpool.cpp | 6 +- src/coreclr/src/vm/comutilnative.cpp | 22 +- src/coreclr/src/vm/coreassemblyspec.cpp | 4 +- src/coreclr/src/vm/coreclr/corebindresult.h | 2 +- src/coreclr/src/vm/coreclr/corebindresult.inl | 4 +- .../src/vm/{mscorlib.cpp => corelib.cpp} | 70 +++--- src/coreclr/src/vm/{mscorlib.h => corelib.h} | 4 +- src/coreclr/src/vm/crossgen/CMakeLists.txt | 18 +- .../src/vm/crossloaderallocatorhash.inl | 48 ++-- src/coreclr/src/vm/customattribute.cpp | 24 +- src/coreclr/src/vm/custommarshalerinfo.cpp | 14 +- src/coreclr/src/vm/debugdebugger.cpp | 4 +- src/coreclr/src/vm/dispatchinfo.cpp | 44 ++-- src/coreclr/src/vm/dllimport.cpp | 18 +- src/coreclr/src/vm/domainfile.cpp | 24 +- src/coreclr/src/vm/domainfile.h | 2 +- src/coreclr/src/vm/dwreport.cpp | 4 +- src/coreclr/src/vm/ecall.cpp | 50 ++-- src/coreclr/src/vm/ecall.h | 2 +- src/coreclr/src/vm/ecalllist.h | 2 +- src/coreclr/src/vm/eedbginterfaceimpl.cpp | 4 +- src/coreclr/src/vm/encee.cpp | 8 +- src/coreclr/src/vm/eventpipeevent.cpp | 2 +- src/coreclr/src/vm/eventtrace.cpp | 2 +- src/coreclr/src/vm/excep.cpp | 28 ++- src/coreclr/src/vm/field.cpp | 2 +- src/coreclr/src/vm/fieldmarshaler.cpp | 16 +- src/coreclr/src/vm/gchelpers.cpp | 2 +- src/coreclr/src/vm/gdbjit.cpp | 4 +- src/coreclr/src/vm/genericdict.cpp | 4 +- src/coreclr/src/vm/ilmarshalers.cpp | 68 +++--- src/coreclr/src/vm/ilmarshalers.h | 30 +-- src/coreclr/src/vm/ilstubcache.cpp | 2 +- src/coreclr/src/vm/interoputil.cpp | 4 +- src/coreclr/src/vm/interpreter.cpp | 4 +- src/coreclr/src/vm/invokeutil.cpp | 22 +- src/coreclr/src/vm/jitinterface.cpp | 202 ++++++++-------- src/coreclr/src/vm/loaderallocator.cpp | 2 +- src/coreclr/src/vm/managedmdimport.cpp | 3 - src/coreclr/src/vm/memberload.cpp | 8 +- src/coreclr/src/vm/method.cpp | 2 +- src/coreclr/src/vm/method.hpp | 4 +- src/coreclr/src/vm/methodtable.cpp | 6 +- src/coreclr/src/vm/methodtablebuilder.cpp | 21 +- src/coreclr/src/vm/mlinfo.cpp | 26 +-- src/coreclr/src/vm/nativeoverlapped.cpp | 2 +- src/coreclr/src/vm/object.cpp | 6 +- src/coreclr/src/vm/object.h | 46 ++-- src/coreclr/src/vm/olevariant.cpp | 194 ++++++++-------- src/coreclr/src/vm/olevariant.h | 4 +- src/coreclr/src/vm/packedfields.inl | 2 +- src/coreclr/src/vm/pefile.h | 2 +- src/coreclr/src/vm/perfmap.cpp | 2 +- src/coreclr/src/vm/prestub.cpp | 6 +- src/coreclr/src/vm/qcall.cpp | 2 +- src/coreclr/src/vm/qcall.h | 4 +- src/coreclr/src/vm/reflectioninvocation.cpp | 6 +- src/coreclr/src/vm/rexcep.h | 10 - src/coreclr/src/vm/runtimecallablewrapper.cpp | 14 +- src/coreclr/src/vm/runtimehandles.cpp | 10 +- src/coreclr/src/vm/safehandle.cpp | 4 +- src/coreclr/src/vm/siginfo.cpp | 26 +-- src/coreclr/src/vm/siginfo.hpp | 2 +- .../src/vm/staticallocationhelpers.inl | 2 +- src/coreclr/src/vm/stubgen.cpp | 16 +- src/coreclr/src/vm/tailcallhelp.cpp | 10 +- src/coreclr/src/vm/threads.cpp | 6 +- src/coreclr/src/vm/threads.h | 2 +- src/coreclr/src/vm/typedesc.inl | 2 +- src/coreclr/src/vm/typehandle.cpp | 2 +- src/coreclr/src/vm/typehandle.inl | 2 +- src/coreclr/src/vm/typeparse.cpp | 6 +- src/coreclr/src/vm/typeparse.h | 2 +- src/coreclr/src/vm/weakreferencenative.cpp | 2 +- src/coreclr/src/vm/wks/CMakeLists.txt | 4 +- src/coreclr/src/zap/zapimage.cpp | 10 +- src/coreclr/src/zap/zapper.cpp | 18 +- src/coreclr/src/zap/zapreadytorun.cpp | 2 +- 167 files changed, 1140 insertions(+), 1271 deletions(-) rename src/coreclr/src/vm/{mscorlib.cpp => corelib.cpp} (88%) rename src/coreclr/src/vm/{mscorlib.h => corelib.h} (99%) diff --git a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets index bbed0d419853..4b232bbfdc21 100644 --- a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets +++ b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets @@ -7,7 +7,7 @@ <_ILLinkRuntimeRootDescriptorFilePath>$(ILLinkTrimXml) <_NamespaceFilePath Condition=" '$(_NamespaceFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\namespace.h - <_MscorlibFilePath Condition=" '$(_MscorlibFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\mscorlib.h + <_MscorlibFilePath Condition=" '$(_MscorlibFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\corelib.h <_CortypeFilePath Condition=" '$(_CortypeFilePath)' == '' ">$(MSBuildThisFileDirectory)..\inc\cortypeinfo.h <_RexcepFilePath Condition=" '$(_RexcepFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\rexcep.h <_ILLinkDescriptorsIntermediatePath>$(IntermediateOutputPath)ILLink.Descriptors.Combined.xml diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs index d2ea1e3fbdd0..82d9af92c643 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs @@ -83,9 +83,7 @@ public static string[] GetCommandLineArgs() [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] private static extern int GetProcessorCount(); - // If you change this method's signature then you must change the code that calls it - // in excep.cpp and probably you will have to visit mscorlib.h to add the new signature - // as well as metasig.h to create the new signature type + // Used by VM internal static string? GetResourceStringLocal(string key) => SR.GetResourceString(key); public static string StackTrace diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index c3f1e5b4fd43..d6bb435387b0 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -266,8 +266,8 @@ private string? SerializationStackTraceString } // This piece of infrastructure exists to help avoid deadlocks - // between parts of mscorlib that might throw an exception while - // holding a lock that are also used by mscorlib's ResourceManager + // between parts of CoreLib that might throw an exception while + // holding a lock that are also used by CoreLib's ResourceManager // instance. As a special case of code that may throw while holding // a lock, we also need to fix our asynchronous exceptions to use // Win32 resources as well (assuming we ever call a managed diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs index 865600fe8d2d..1809ea64685d 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs @@ -294,7 +294,7 @@ public static int GetGeneration(WeakReference wo) public static void WaitForPendingFinalizers() { - // QCalls can not be exposed from mscorlib directly, need to wrap it. + // QCalls can not be exposed directly, need to wrap it. _WaitForPendingFinalizers(); } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs index 3b69f789e61c..d90f81d48e98 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs @@ -7,24 +7,7 @@ namespace System.Runtime.Versioning { internal static class CompatibilitySwitch { - /* This class contains 3 sets of api: - * 1. internal apis : These apis are supposed to be used by mscorlib.dll and other assemblies which use the section in config - * These apis query for the value of quirk not only in windows quirk DB but also in runtime section of config files, - * registry and environment vars. - * 2. public apis : These apis are supposed to be used by FX assemblies which do not read the runtime section of config files and have - * have their own section in config files or do not use configs at all. - * - * 3. specialized apis: These apis are defined in order to retrieve a specific value defined in CLR Config. That value can have specific look-up rules - * for the order and location of the config sources used. - * - * These apis are for internal use only for FX assemblies. It has not been decided if they can be used by OOB components due to EULA restrictions - */ - internal static string? GetValueInternal(string compatibilitySwitchName) - { - return GetValueInternalCall(compatibilitySwitchName, false); - } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern string? GetValueInternalCall(string compatibilitySwitchName, bool onlyDB); + internal static extern string? GetValueInternal(string compatibilitySwitchName); } } diff --git a/src/coreclr/src/binder/assemblybinder.cpp b/src/coreclr/src/binder/assemblybinder.cpp index 5f13adc7b2c8..02a3646dab4a 100644 --- a/src/coreclr/src/binder/assemblybinder.cpp +++ b/src/coreclr/src/binder/assemblybinder.cpp @@ -447,25 +447,25 @@ namespace BINDER_SPACE // Satellite assembly's path: // * Absolute path when looking for a file on disk // * Bundle-relative path when looking within the single-file bundle. - StackSString sMscorlibSatellite; + StackSString sCoreLibSatellite; BinderTracing::PathSource pathSource = BinderTracing::PathSource::Bundle; BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(relativePath, /*pathIsBundleRelative */ true); if (!bundleFileLocation.IsValid()) { - sMscorlibSatellite.Set(systemDirectory); + sCoreLibSatellite.Set(systemDirectory); pathSource = BinderTracing::PathSource::ApplicationAssemblies; } - CombinePath(sMscorlibSatellite, relativePath, sMscorlibSatellite); + CombinePath(sCoreLibSatellite, relativePath, sCoreLibSatellite); ReleaseHolder pSystemAssembly; - IF_FAIL_GO(AssemblyBinder::GetAssembly(sMscorlibSatellite, + IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLibSatellite, TRUE /* fIsInGAC */, FALSE /* fExplicitBindToNativeImage */, &pSystemAssembly, NULL /* szMDAssemblyPath */, bundleFileLocation)); - BinderTracing::PathProbed(sMscorlibSatellite, pathSource, hr); + BinderTracing::PathProbed(sCoreLibSatellite, pathSource, hr); *ppSystemAssembly = pSystemAssembly.Extract(); diff --git a/src/coreclr/src/binder/assemblyname.cpp b/src/coreclr/src/binder/assemblyname.cpp index b073dc66f88b..71e70283c0b3 100644 --- a/src/coreclr/src/binder/assemblyname.cpp +++ b/src/coreclr/src/binder/assemblyname.cpp @@ -315,10 +315,10 @@ namespace BINDER_SPACE return ulRef; } - BOOL AssemblyName::IsMscorlib() + BOOL AssemblyName::IsCoreLib() { // TODO: Is this simple comparison enough? - return EqualsCaseInsensitive(GetSimpleName(), g_BinderVariables->mscorlib); + return EqualsCaseInsensitive(GetSimpleName(), g_BinderVariables->corelib); } ULONG AssemblyName::Hash(DWORD dwIncludeFlags) diff --git a/src/coreclr/src/binder/bindertracing.cpp b/src/coreclr/src/binder/bindertracing.cpp index be09ebced11e..29ba819ee6c9 100644 --- a/src/coreclr/src/binder/bindertracing.cpp +++ b/src/coreclr/src/binder/bindertracing.cpp @@ -246,7 +246,7 @@ namespace BinderTracing // ActivityTracker or EventSource may have triggered the system satellite load. // Don't track system satellite binding to avoid potential infinite recursion. - m_ignoreBind = m_bindRequest.AssemblySpec->IsMscorlibSatellite(); + m_ignoreBind = m_bindRequest.AssemblySpec->IsCoreLibSatellite(); m_checkedIgnoreBind = true; return m_ignoreBind; } diff --git a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp index f492adfab28b..69d8d8337289 100644 --- a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp +++ b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp @@ -20,8 +20,8 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByNameWorker(BINDER_SPACE: HRESULT hr = S_OK; #ifdef _DEBUG - // MSCORLIB should be bound using BindToSystem - _ASSERTE(!pAssemblyName->IsMscorlib()); + // CoreLib should be bound using BindToSystem + _ASSERTE(!pAssemblyName->IsCoreLib()); #endif // Do we have the assembly already loaded in the context of the current binder? @@ -145,7 +145,7 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pP // Disallow attempt to bind to the core library. Aside from that, // the LoadContext can load any assembly (even if it was in a different LoadContext like TPA). - if (pAssemblyName->IsMscorlib()) + if (pAssemblyName->IsCoreLib()) { IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); } diff --git a/src/coreclr/src/binder/clrprivbindercoreclr.cpp b/src/coreclr/src/binder/clrprivbindercoreclr.cpp index 1045cb93e76d..292ad99fd855 100644 --- a/src/coreclr/src/binder/clrprivbindercoreclr.cpp +++ b/src/coreclr/src/binder/clrprivbindercoreclr.cpp @@ -20,8 +20,8 @@ HRESULT CLRPrivBinderCoreCLR::BindAssemblyByNameWorker(BINDER_SPACE::AssemblyNam HRESULT hr = S_OK; #ifdef _DEBUG - // MSCORLIB should be bound using BindToSystem - _ASSERTE(!pAssemblyName->IsMscorlib()); + // CoreLib should be bound using BindToSystem + _ASSERTE(!pAssemblyName->IsCoreLib()); #endif hr = AssemblyBinder::BindAssembly(&m_appContext, @@ -155,8 +155,8 @@ HRESULT CLRPrivBinderCoreCLR::BindUsingPEImage( /* in */ PEImage *pPEImage, IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_BAD_FORMAT)); } - // Easy out for mscorlib - if (pAssemblyName->IsMscorlib()) + // Easy out for CoreLib + if (pAssemblyName->IsCoreLib()) { IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); } diff --git a/src/coreclr/src/binder/inc/assemblyname.hpp b/src/coreclr/src/binder/inc/assemblyname.hpp index 38590e09f78a..fb66d9830e0a 100644 --- a/src/coreclr/src/binder/inc/assemblyname.hpp +++ b/src/coreclr/src/binder/inc/assemblyname.hpp @@ -65,7 +65,7 @@ namespace BINDER_SPACE inline void SetHave(DWORD dwIdentityFlags); - BOOL IsMscorlib(); + BOOL IsCoreLib(); ULONG Hash(/* in */ DWORD dwIncludeFlags); BOOL Equals(/* in */ AssemblyName *pAssemblyName, diff --git a/src/coreclr/src/binder/inc/variables.hpp b/src/coreclr/src/binder/inc/variables.hpp index 50f392d0366e..d060a691bbec 100644 --- a/src/coreclr/src/binder/inc/variables.hpp +++ b/src/coreclr/src/binder/inc/variables.hpp @@ -31,7 +31,7 @@ namespace BINDER_SPACE // AssemblyName string constants SString cultureNeutral; - SString mscorlib; + SString corelib; }; extern Variables *g_BinderVariables; diff --git a/src/coreclr/src/binder/variables.cpp b/src/coreclr/src/binder/variables.cpp index d9c3f672657d..fbdd106b4dd2 100644 --- a/src/coreclr/src/binder/variables.cpp +++ b/src/coreclr/src/binder/variables.cpp @@ -40,7 +40,7 @@ namespace BINDER_SPACE // AssemblyName string constants cultureNeutral.SetLiteral(W("neutral")); - mscorlib.SetLiteral(CoreLibName_W); + corelib.SetLiteral(CoreLibName_W); } EX_CATCH_HRESULT(hr); diff --git a/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp b/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp index fb2c1aefe3c7..3a9ed227cfdd 100644 --- a/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp +++ b/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp @@ -502,7 +502,7 @@ VarArgsNative::GetNextArgHelper( value->data = (BYTE*)origArgPtr + (sizeof(void*)-1); } #endif - value->type = MscorlibBinder::GetElementType(elemType); + value->type = CoreLibBinder::GetElementType(elemType); break; case ELEMENT_TYPE_I2: @@ -513,7 +513,7 @@ VarArgsNative::GetNextArgHelper( value->data = (BYTE*)origArgPtr + (sizeof(void*)-2); } #endif - value->type = MscorlibBinder::GetElementType(elemType); + value->type = CoreLibBinder::GetElementType(elemType); break; case ELEMENT_TYPE_I4: @@ -522,13 +522,13 @@ VarArgsNative::GetNextArgHelper( case ELEMENT_TYPE_STRING: case ELEMENT_TYPE_I: case ELEMENT_TYPE_U: - value->type = MscorlibBinder::GetElementType(elemType); + value->type = CoreLibBinder::GetElementType(elemType); break; case ELEMENT_TYPE_I8: case ELEMENT_TYPE_U8: case ELEMENT_TYPE_R8: - value->type = MscorlibBinder::GetElementType(elemType); + value->type = CoreLibBinder::GetElementType(elemType); #if !defined(HOST_64BIT) && (DATA_ALIGNMENT > 4) if ( fData && origArgPtr == value->data ) { // allocate an aligned copy of the value diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp index aab49139e91b..c0e0a23f53a3 100644 --- a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp @@ -2399,7 +2399,7 @@ TypeHandle DacDbiInterfaceImpl::FindLoadedElementType(CorElementType elementType // Lookup operations run the class loader in non-load mode. ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE(); - MethodTable * pMethodTable = (&g_Mscorlib)->GetElementType(elementType); + MethodTable * pMethodTable = (&g_CoreLib)->GetElementType(elementType); return TypeHandle(pMethodTable); } // DacDbiInterfaceImpl::FindLoadedElementType @@ -7264,7 +7264,7 @@ HRESULT DacDbiInterfaceImpl::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLa if (mt->IsString()) { COR_TYPEID token; - token.token1 = MscorlibBinder::GetElementType(ELEMENT_TYPE_CHAR).GetAddr(); + token.token1 = CoreLibBinder::GetElementType(ELEMENT_TYPE_CHAR).GetAddr(); token.token2 = 0; pLayout->componentID = token; diff --git a/src/coreclr/src/debug/daccess/enummem.cpp b/src/coreclr/src/debug/daccess/enummem.cpp index 95909b89e3f8..a746aa46b3d1 100644 --- a/src/coreclr/src/debug/daccess/enummem.cpp +++ b/src/coreclr/src/debug/daccess/enummem.cpp @@ -276,7 +276,7 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags) } CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pEEDbgInterfaceImpl.EnumMem(); ) CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_CORDebuggerControlFlags.EnumMem(); ) - CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_Mscorlib.EnumMem(); ) + CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_CoreLib.EnumMem(); ) CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT].EnumMemoryRegions(flags); ) CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( StubManager::EnumMemoryRegions(flags); ) CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pFinalizerThread.EnumMem(); ) diff --git a/src/coreclr/src/debug/daccess/inspect.cpp b/src/coreclr/src/debug/daccess/inspect.cpp index 75cfcc3cadce..28375862bd38 100644 --- a/src/coreclr/src/debug/daccess/inspect.cpp +++ b/src/coreclr/src/debug/daccess/inspect.cpp @@ -136,7 +136,7 @@ GetTypeFieldValueFlags(TypeHandle typeHandle, // Perform extra checks to identify well-known classes. // - if ((&g_Mscorlib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING)) + if ((&g_CoreLib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING)) { otherFlags |= CLRDATA_VALUE_IS_STRING; } diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp index 06a6fffee157..b385e278d698 100644 --- a/src/coreclr/src/debug/daccess/nidump.cpp +++ b/src/coreclr/src/debug/daccess/nidump.cpp @@ -477,7 +477,7 @@ NativeImageDumper::NativeImageDumper(PTR_VOID loadedBase, m_dis(dis), m_MetadataSize(0), m_ILHostCopy(NULL), - m_isMscorlibHardBound(false), + m_isCoreLibHardBound(false), m_sectionAlignment(0) { IfFailThrow(m_display->GetDumpOptions(&m_dumpOptions)); @@ -1132,54 +1132,54 @@ NativeImageDumper::DumpNativeImage() /* XXX Wed 12/14/2005 * Now for the real insanity. I need to initialize static classes in - * the DAC. First I need to find mscorlib's dependency entry. Search + * the DAC. First I need to find CoreLib's dependency entry. Search * through all of the dependencies to find the one marked as - * fIsMscorlib. If I don't find anything marked that way, then "self" - * is mscorlib. + * fIsCoreLib. If I don't find anything marked that way, then "self" + * is CoreLib. */ - Dependency * mscorlib = NULL; + Dependency * corelib = NULL; for( COUNT_T i = 0; i < m_numDependencies; ++i ) { - if( m_dependencies[i].fIsMscorlib ) + if( m_dependencies[i].fIsCoreLib ) { - mscorlib = &m_dependencies[i]; + corelib = &m_dependencies[i]; break; } } - //If we're actually dumping mscorlib, remap the mscorlib dependency to our own native image. - if( (mscorlib == NULL) || !wcscmp(m_name, CoreLibName_W)) + //If we're actually dumping CoreLib, remap the CoreLib dependency to our own native image. + if( (corelib == NULL) || !wcscmp(m_name, CoreLibName_W)) { - mscorlib = GetDependency(0); - mscorlib->fIsMscorlib = TRUE; - _ASSERTE(mscorlib->fIsHardbound); + corelib = GetDependency(0); + corelib->fIsCoreLib = TRUE; + _ASSERTE(corelib->fIsHardbound); } - _ASSERTE(mscorlib != NULL); - if( mscorlib->fIsHardbound ) + _ASSERTE(corelib != NULL); + if( corelib->fIsHardbound ) { - m_isMscorlibHardBound = true; + m_isCoreLibHardBound = true; } - if( m_isMscorlibHardBound ) + if( m_isCoreLibHardBound ) { //go through the module to the binder. - PTR_Module mscorlibModule = mscorlib->pModule; + PTR_Module corelibModule = corelib->pModule; - PTR_MscorlibBinder binder = mscorlibModule->m_pBinder; - g_Mscorlib = *binder; + PTR_CoreLibBinder binder = corelibModule->m_pBinder; + g_CoreLib = *binder; - PTR_MethodTable mt = MscorlibBinder::GetExistingClass(CLASS__OBJECT); + PTR_MethodTable mt = CoreLibBinder::GetExistingClass(CLASS__OBJECT); g_pObjectClass = mt; } if (g_pObjectClass == NULL) { - //if mscorlib is not hard bound, then warn the user (many features of nidump are shut off) - m_display->ErrorPrintF( "Assembly %S is soft bound to mscorlib. nidump cannot dump MethodTables completely.\n", m_name ); + //if CoreLib is not hard bound, then warn the user (many features of nidump are shut off) + m_display->ErrorPrintF( "Assembly %S is soft bound to CoreLib. nidump cannot dump MethodTables completely.\n", m_name ); // TritonTODO: reason? // reset "hard bound state" - m_isMscorlibHardBound = false; + m_isCoreLibHardBound = false; } } @@ -1267,8 +1267,8 @@ void NativeImageDumper::TraceDumpDependency(int idx, NativeImageDumper::Dependen m_display->ErrorPrintF("\tSize: %x (%d)\n", dependency->size, dependency->size); m_display->ErrorPrintF("\tModule: P=%p, L=%p\n", DataPtrToDisplay(dac_cast(dependency->pModule)), PTR_TO_TADDR(dependency->pModule)); - m_display->ErrorPrintF("Mscorlib=%s, Hardbound=%s\n", - (dependency->fIsMscorlib ? "true" : "false"), + m_display->ErrorPrintF("CoreLib=%s, Hardbound=%s\n", + (dependency->fIsCoreLib ? "true" : "false"), (dependency->fIsHardbound ? "true" : "false")); m_display->ErrorPrintF("Name: %S\n", dependency->name); } @@ -2391,7 +2391,7 @@ mdAssemblyRef NativeImageDumper::MapAssemblyRefToManifest(mdAssemblyRef token, I } else if (wcscmp(szAssemblyName, CoreLibName_W) == 0) { - // Mscorlib is special - version number and public key token are ignored. + // CoreLib is special - version number and public key token are ignored. ret = currentRef; break; } @@ -2400,7 +2400,7 @@ mdAssemblyRef NativeImageDumper::MapAssemblyRefToManifest(mdAssemblyRef token, I metadata.usBuildNumber == 255 && metadata.usRevisionNumber == 255) { - // WinMDs encode all assemblyrefs with version 255.255.255.255 including CLR assembly dependencies (mscorlib, System). + // WinMDs encode all assemblyrefs with version 255.255.255.255 including CLR assembly dependencies (corelib, System). ret = currentRef; } else @@ -2602,8 +2602,8 @@ NativeImageDumper::Dependency *NativeImageDumper::OpenDependency(int index) Dependency& dependency = m_dependencies[index]; AppendTokenName(entry->dwAssemblyRef, buf, m_manifestImport, true); bool isHardBound = !!(entry->signNativeImage != INVALID_NGEN_SIGNATURE); - SString mscorlibStr(SString::Literal, CoreLibName_W); - bool isMscorlib = (0 == buf.Compare( mscorlibStr )); + SString corelibStr(SString::Literal, CoreLibName_W); + bool isCoreLib = (0 == buf.Compare( corelibStr )); dependency.fIsHardbound = isHardBound; wcscpy_s(dependency.name, _countof(dependency.name), (const WCHAR*)buf); @@ -2703,7 +2703,7 @@ NativeImageDumper::Dependency *NativeImageDumper::OpenDependency(int index) ofRead, IID_IMetaDataImport2, (IUnknown **) &dependency.pImport)); - dependency.fIsMscorlib = isMscorlib; + dependency.fIsCoreLib = isCoreLib; } m_dependencies[index].entry = entry; @@ -3716,7 +3716,7 @@ void NativeImageDumper::DumpModule( PTR_Module module ) /* REVISIT_TODO Fri 10/14/2005 * Dump the binder */ - PTR_MscorlibBinder binder = module->m_pBinder; + PTR_CoreLibBinder binder = module->m_pBinder; if( NULL != binder ) { DisplayStartStructureWithOffset( m_pBinder, DPtrToPreferredAddr(binder), @@ -3726,38 +3726,38 @@ void NativeImageDumper::DumpModule( PTR_Module module ) //these four fields don't have anything useful in ngen images. DisplayWriteFieldPointer( m_classDescriptions, DPtrToPreferredAddr(binder->m_classDescriptions), - MscorlibBinder, MODULE ); + CoreLibBinder, MODULE ); DisplayWriteFieldPointer( m_methodDescriptions, DPtrToPreferredAddr(binder->m_methodDescriptions), - MscorlibBinder, MODULE ); + CoreLibBinder, MODULE ); DisplayWriteFieldPointer( m_fieldDescriptions, DPtrToPreferredAddr(binder->m_fieldDescriptions), - MscorlibBinder, MODULE ); + CoreLibBinder, MODULE ); DisplayWriteFieldPointer( m_pModule, DPtrToPreferredAddr(binder->m_pModule), - MscorlibBinder, MODULE ); + CoreLibBinder, MODULE ); - DisplayWriteFieldInt( m_cClasses, binder->m_cClasses, MscorlibBinder, + DisplayWriteFieldInt( m_cClasses, binder->m_cClasses, CoreLibBinder, MODULE ); DisplayWriteFieldAddress( m_pClasses, DPtrToPreferredAddr(binder->m_pClasses), sizeof(*binder->m_pClasses) * binder->m_cClasses, - MscorlibBinder, MODULE ); - DisplayWriteFieldInt( m_cFields, binder->m_cFields, MscorlibBinder, + CoreLibBinder, MODULE ); + DisplayWriteFieldInt( m_cFields, binder->m_cFields, CoreLibBinder, MODULE ); DisplayWriteFieldAddress( m_pFields, DPtrToPreferredAddr(binder->m_pFields), sizeof(*binder->m_pFields) * binder->m_cFields, - MscorlibBinder, MODULE ); - DisplayWriteFieldInt( m_cMethods, binder->m_cMethods, MscorlibBinder, + CoreLibBinder, MODULE ); + DisplayWriteFieldInt( m_cMethods, binder->m_cMethods, CoreLibBinder, MODULE ); DisplayWriteFieldAddress( m_pMethods, DPtrToPreferredAddr(binder->m_pMethods), sizeof(*binder->m_pMethods) * binder->m_cMethods, - MscorlibBinder, MODULE ); + CoreLibBinder, MODULE ); DisplayEndStructure( MODULE ); //m_pBinder } @@ -6766,11 +6766,11 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name, MethodTableToString( mt, buf ); m_display->ErrorPrintF( "WARNING! MethodTable %S is generic but is not hard bound to its EEClass. Cannot compute generic dictionary sizes.\n", (const WCHAR *)buf ); } - else if( !m_isMscorlibHardBound ) + else if( !m_isCoreLibHardBound ) { /* REVISIT_TODO Mon 8/20/2007 - * If we're not hard bound to mscorlib, most things don't work. They depend on knowing what - * g_pObjectClass is. Without the hard binding to mscorlib, I can't figure that out. + * If we're not hard bound to CoreLib, most things don't work. They depend on knowing what + * g_pObjectClass is. Without the hard binding to CoreLib, I can't figure that out. */ haveCompleteExtents = false; } diff --git a/src/coreclr/src/debug/daccess/nidump.h b/src/coreclr/src/debug/daccess/nidump.h index b8c0a04ddb41..a6e9461a475a 100644 --- a/src/coreclr/src/debug/daccess/nidump.h +++ b/src/coreclr/src/debug/daccess/nidump.h @@ -305,7 +305,7 @@ class NativeImageDumper TADDR pMetadataStartTarget; TADDR pMetadataStartHost; SIZE_T MetadataSize; - bool fIsMscorlib; + bool fIsCoreLib; bool fIsHardbound; WCHAR name[128]; }; @@ -548,9 +548,9 @@ class NativeImageDumper COUNT_T m_ILSectionSize; #endif - //This is true if we are hard bound to mscorlib. This enables various forms of generics dumping and MT + //This is true if we are hard bound to corelib. This enables various forms of generics dumping and MT //dumping that require g_pObjectClass to be set. - bool m_isMscorlibHardBound; + bool m_isCoreLibHardBound; #if 0 PTR_CCOR_SIGNATURE metadataToHostDAC( PCCOR_SIGNATURE pSig, diff --git a/src/coreclr/src/debug/daccess/request.cpp b/src/coreclr/src/debug/daccess/request.cpp index 4c6671149bee..5047421d5959 100644 --- a/src/coreclr/src/debug/daccess/request.cpp +++ b/src/coreclr/src/debug/daccess/request.cpp @@ -1058,7 +1058,7 @@ HRESULT ClrDataAccess::GetMethodDescData( OBJECTREF value = pResolver->GetManagedResolver(); if (value) { - FieldDesc *pField = (&g_Mscorlib)->GetField(FIELD__DYNAMICRESOLVER__DYNAMIC_METHOD); + FieldDesc *pField = (&g_CoreLib)->GetField(FIELD__DYNAMICRESOLVER__DYNAMIC_METHOD); _ASSERTE(pField); value = pField->GetRefValue(value); if (value) diff --git a/src/coreclr/src/debug/daccess/stack.cpp b/src/coreclr/src/debug/daccess/stack.cpp index 09e16b4979ab..94ef49b972ad 100644 --- a/src/coreclr/src/debug/daccess/stack.cpp +++ b/src/coreclr/src/debug/daccess/stack.cpp @@ -1391,7 +1391,7 @@ ClrDataFrame::ValueFromDebugInfo(MetaSig* sig, // XXX Microsoft - Sometimes types can't be looked // up and this at least allows the value to be used, // but is it the right behavior? - argType = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_U8)); + argType = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_U8)); valueFlags = 0; } else diff --git a/src/coreclr/src/debug/di/rstype.cpp b/src/coreclr/src/debug/di/rstype.cpp index 36b137949664..a7412dea5713 100644 --- a/src/coreclr/src/debug/di/rstype.cpp +++ b/src/coreclr/src/debug/di/rstype.cpp @@ -683,7 +683,7 @@ HRESULT CordbType::GetType(CorElementType *pType) // Determining if something is a VC or not can involve asking the EE. // We could do it ourselves based on the metadata but it's non-trivial // determining if a class has System.ValueType as a parent (we have - // to find and OpenScope the mscorlib.dll which we don't currently do + // to find and OpenScope the System.Private.CoreLib.dll which we don't currently do // on the right-side). But the IsValueClass call can fail if the // class is not yet loaded on the right side. In that case we // ignore the failure and return ELEMENT_TYPE_CLASS diff --git a/src/coreclr/src/debug/ee/debugger.cpp b/src/coreclr/src/debug/ee/debugger.cpp index 7b2cd48b22ed..56ecf032b71d 100644 --- a/src/coreclr/src/debug/ee/debugger.cpp +++ b/src/coreclr/src/debug/ee/debugger.cpp @@ -3458,14 +3458,14 @@ void Debugger::getBoundaries(MethodDesc * md, if (pModule == SystemDomain::SystemModule()) { - // We don't look up PDBs for mscorlib. This is not quite right, but avoids + // We don't look up PDBs for CoreLib. This is not quite right, but avoids // a bootstrapping problem. When an EXE loads, it has the option of setting // the COM apartment model to STA if we need to. It is important that no // other Coinitialize happens before this. Since loading the PDB reader uses // com we can not come first. However managed code IS run before the COM // apartment model is set, and thus we have a problem since this code is // called for when JITTing managed code. We avoid the problem by just - // bailing for mscorlib. + // bailing for CoreLib. return; } diff --git a/src/coreclr/src/debug/inc/dbgipcevents.h b/src/coreclr/src/debug/inc/dbgipcevents.h index eda4029c0fb1..3bff8ccaa188 100644 --- a/src/coreclr/src/debug/inc/dbgipcevents.h +++ b/src/coreclr/src/debug/inc/dbgipcevents.h @@ -848,7 +848,7 @@ typedef VMPTR_Base VMPTR_CONTEXT; #endif // DomainFile is a base-class for a CLR module, with app-domain affinity. -// For domain-neutral modules (like mscorlib), there is a DomainFile instance +// For domain-neutral modules (like CoreLib), there is a DomainFile instance // for each appdomain the module lives in. // This is the canonical handle ICorDebug uses to a CLR module. DEFINE_VMPTR(class DomainFile, PTR_DomainFile, VMPTR_DomainFile); diff --git a/src/coreclr/src/dlls/mscoree/mscoree.cpp b/src/coreclr/src/dlls/mscoree/mscoree.cpp index 810a3e88f3fe..f9e1e3d89ef6 100644 --- a/src/coreclr/src/dlls/mscoree/mscoree.cpp +++ b/src/coreclr/src/dlls/mscoree/mscoree.cpp @@ -444,7 +444,7 @@ HRESULT SetInternalSystemDirectory() } #if defined(CROSSGEN_COMPILE) -void SetMscorlibPath(LPCWSTR wzSystemDirectory) +void SetCoreLibPath(LPCWSTR wzSystemDirectory) { DWORD len = (DWORD)wcslen(wzSystemDirectory); bool appendSeparator = wzSystemDirectory[len-1] != DIRECTORY_SEPARATOR_CHAR_W; diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h index 331f8e122108..bfe02b7db9da 100644 --- a/src/coreclr/src/gc/gcinterface.h +++ b/src/coreclr/src/gc/gcinterface.h @@ -396,7 +396,7 @@ typedef enum * They are currently used for EnC for adding new field members to existing instantiations under EnC modes where * the primary object is the original instantiation and the secondary represents the added field. * - * They are also used to implement the ConditionalWeakTable class in mscorlib.dll. If you want to use + * They are also used to implement the managed ConditionalWeakTable class. If you want to use * these from managed code, they are exposed to BCL through the managed DependentHandle class. * * @@ -587,7 +587,7 @@ class IGCHeap { /* =========================================================================== - BCL routines. These are routines that are directly exposed by mscorlib + BCL routines. These are routines that are directly exposed by CoreLib as a part of the `System.GC` class. These routines behave in the same manner as the functions on `System.GC`. =========================================================================== @@ -640,14 +640,14 @@ class IGCHeap { virtual int GetGcLatencyMode() = 0; // Sets the current GC latency mode. newLatencyMode has already been - // verified by mscorlib to be valid. + // verified by CoreLib to be valid. virtual int SetGcLatencyMode(int newLatencyMode) = 0; // Gets the current LOH compaction mode. virtual int GetLOHCompactionMode() = 0; // Sets the current LOH compaction mode. newLOHCompactionMode has - // already been verified by mscorlib to be valid. + // already been verified by CoreLib to be valid. virtual void SetLOHCompactionMode(int newLOHCompactionMode) = 0; // Registers for a full GC notification, raising a notification if the gen 2 or diff --git a/src/coreclr/src/inc/corcompile.h b/src/coreclr/src/inc/corcompile.h index f02a7a1475d0..82308d7b899a 100644 --- a/src/coreclr/src/inc/corcompile.h +++ b/src/coreclr/src/inc/corcompile.h @@ -1412,7 +1412,7 @@ class ICorCompileInfo // So, the host must call StartupAsCompilationProcess before compiling // any code, and Shutdown after finishing. // - // The arguments control which native image of mscorlib to use. + // The arguments control which native image of CoreLib to use. // This matters for hardbinding. // @@ -1548,8 +1548,8 @@ class ICorCompileInfo mdFieldDef *token ) = 0; - // Get the loader module for mscorlib - virtual CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib() = 0; + // Get the loader module for CoreLib + virtual CORINFO_MODULE_HANDLE GetLoaderModuleForCoreLib() = 0; // Get the loader module for a type (where the type is regarded as // living for the purposes of loading, unloading, and ngen). diff --git a/src/coreclr/src/inc/cordebug.idl b/src/coreclr/src/inc/cordebug.idl index 02c98f25d8a1..efecf3b55063 100644 --- a/src/coreclr/src/inc/cordebug.idl +++ b/src/coreclr/src/inc/cordebug.idl @@ -2361,7 +2361,7 @@ interface ICorDebugAppDomain4 : IUnknown * Assembly interface * An ICorDebugAssembly instance corresponds to a a managed assembly loaded * into a specific AppDomain in the CLR. For assemblies shared between multiple - * AppDomains (eg. mscorlib), there will be a separate ICorDebugAssembly instance + * AppDomains (eg. CoreLib), there will be a separate ICorDebugAssembly instance * per AppDomain in which it is used. * ------------------------------------------------------------------------- */ [ @@ -5220,7 +5220,7 @@ interface ICorDebugRuntimeUnwindableFrame : ICorDebugFrame * specific AppDomain. Normally this is an executable or a DLL, but it may also be * some other file of a multi-module assembly. There is an ICorDebugModule instance * for each AppDomain a module is loaded into, even in the case of shared modules like - * mscorlib. + * CoreLib. */ [ diff --git a/src/coreclr/src/inc/corerror.xml b/src/coreclr/src/inc/corerror.xml index 94fe6a1ddcea..b1a0b5b53ca0 100644 --- a/src/coreclr/src/inc/corerror.xml +++ b/src/coreclr/src/inc/corerror.xml @@ -2201,12 +2201,6 @@ File is PE32 - - NGEN_E_SYS_ASM_NI_MISSING - "NGen cannot proceed because Mscorlib.dll does not have a native image" - Compiling any assembly other than mscorlib in the absence of mscorlib.ni.dll is not allowed. - - CLDB_E_INTERNALERROR @@ -2249,8 +2243,8 @@ CLR_E_BIND_SYS_ASM_NI_MISSING - "Could not use native image because Mscorlib.dll is missing a native image" - Returned when loading an assembly that only has a native image and no IL and cannot hardbind to mscorlib.ni.dll. + "Could not use native image because System.Private.CoreLib.dll is missing a native image" + Returned when loading an assembly that only has a native image and no IL and cannot hardbind to System.Private.CoreLib.ni.dll. diff --git a/src/coreclr/src/inc/corexcep.h b/src/coreclr/src/inc/corexcep.h index faca6b49c593..e1c00b50b321 100644 --- a/src/coreclr/src/inc/corexcep.h +++ b/src/coreclr/src/inc/corexcep.h @@ -13,7 +13,7 @@ // All COM+ exceptions are expressed as a RaiseException with this exception // code. If you change this value, you must also change -// mscorlib\src\system\Exception.cs's _COMPlusExceptionCode value. +// Exception.cs's _COMPlusExceptionCode value. #define EXCEPTION_MSVC 0xe06d7363 // 0xe0000000 | 'msc' diff --git a/src/coreclr/src/inc/corpriv.h b/src/coreclr/src/inc/corpriv.h index 52cf63a0ee07..fb0b39924cc8 100644 --- a/src/coreclr/src/inc/corpriv.h +++ b/src/coreclr/src/inc/corpriv.h @@ -235,7 +235,7 @@ typedef enum CorElementTypeZapSig // where the encoding/decoding takes place. ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG = 0x3d, - ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for [mscorlib]System.__Canon + ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for System.__Canon ELEMENT_TYPE_MODULE_ZAPSIG = 0x3f, // zapsig encoding for external module id# } CorElementTypeZapSig; diff --git a/src/coreclr/src/inc/dacvars.h b/src/coreclr/src/inc/dacvars.h index f480851e1b27..92f3edf77855 100644 --- a/src/coreclr/src/inc/dacvars.h +++ b/src/coreclr/src/inc/dacvars.h @@ -144,7 +144,7 @@ DEFINE_DACVAR(ULONG, PTR_GcNotification, dac__g_pGcNotificationTable, ::g_pGcNot DEFINE_DACVAR(ULONG, PTR_EEConfig, dac__g_pConfig, ::g_pConfig) -DEFINE_DACVAR(ULONG, MscorlibBinder, dac__g_Mscorlib, ::g_Mscorlib) +DEFINE_DACVAR(ULONG, CoreLibBinder, dac__g_CoreLib, ::g_CoreLib) #if defined(PROFILING_SUPPORTED) || defined(PROFILING_SUPPORTED_DATA) DEFINE_DACVAR(ULONG, ProfControlBlock, dac__g_profControlBlock, ::g_profControlBlock) diff --git a/src/coreclr/src/inc/random.h b/src/coreclr/src/inc/random.h index 53cc17d64908..f2501c356832 100644 --- a/src/coreclr/src/inc/random.h +++ b/src/coreclr/src/inc/random.h @@ -5,8 +5,7 @@ // // -// Defines a random number generator, initially from the System.Random code in the BCL. If you notice any problems, -// please compare to the implementation in src\mscorlib\src\system\random.cs. +// Defines a random number generator, initially from the System.Random code in the BCL. // // Main advantages over rand() are: // diff --git a/src/coreclr/src/inc/zapper.h b/src/coreclr/src/inc/zapper.h index ba4f65b15dd9..b88d4d51b676 100644 --- a/src/coreclr/src/inc/zapper.h +++ b/src/coreclr/src/inc/zapper.h @@ -285,7 +285,7 @@ class Zapper ~Zapper(); - // The arguments control which native image of mscorlib to use. + // The arguments control which native image of CoreLib to use. // This matters for hardbinding. void InitEE(BOOL fForceDebug, BOOL fForceProfile, BOOL fForceInstrument); void LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT ICorJitCompiler** ppICorJitCompiler); diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index ccfd7567f46a..8cb0422a41e9 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -4873,7 +4873,7 @@ void CodeGen::genPushCalleeSavedRegisters() // - Generate fully interruptible code for loops that contains calls // - Generate fully interruptible code for leaf methods // - // Given the limited benefit from this optimization (<10k for mscorlib NGen image), the extra complexity + // Given the limited benefit from this optimization (<10k for CoreLib NGen image), the extra complexity // is not worth it. // rsPushRegs |= RBM_LR; // We must save the return address (in the LR register) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 9b7a3d24191f..e1698611978e 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -9012,7 +9012,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX { #if 0 // Switching between size & speed has measurable throughput impact - // (3.5% on NGen mscorlib when measured). It used to be enabled for + // (3.5% on NGen CoreLib when measured). It used to be enabled for // DEBUG, but should generate identical code between CHK & RET builds, // so that's not acceptable. // TODO-Throughput: Figure out what to do about size vs. speed & throughput. diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index f09c0e71fe06..f375d1196605 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -7250,7 +7250,7 @@ bool Compiler::fgIsThrow(GenTree* tree) return true; } - // TODO-CQ: there are a bunch of managed methods in [mscorlib]System.ThrowHelper + // TODO-CQ: there are a bunch of managed methods in System.ThrowHelper // that would be nice to recognize. return false; diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 6280e1be9d77..9bb531527d9a 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -7768,7 +7768,7 @@ var_types Compiler::impImportCall(OPCODE opcode, // If this is a call to JitTestLabel.Mark, do "early inlining", and record the test attribute. // This recognition should really be done by knowing the methHnd of the relevant Mark method(s). - // These should be in mscorlib.h, and available through a JIT/EE interface call. + // These should be in corelib.h, and available through a JIT/EE interface call. const char* modName; const char* className; const char* methodName; diff --git a/src/coreclr/src/jit/inline.cpp b/src/coreclr/src/jit/inline.cpp index 9b4d6f168614..759a6e366181 100644 --- a/src/coreclr/src/jit/inline.cpp +++ b/src/coreclr/src/jit/inline.cpp @@ -1624,7 +1624,7 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent) // Root context will be null if we're not optimizing the method. // - // Note there are cases of this in mscorlib even in release builds, + // Note there are cases of this in System.Private.CoreLib even in release builds, // eg Task.NotifyDebuggerOfWaitCompletion. // // For such methods there aren't any inlines. diff --git a/src/coreclr/src/jit/inlinepolicy.cpp b/src/coreclr/src/jit/inlinepolicy.cpp index 8852991cf200..09a029f99663 100644 --- a/src/coreclr/src/jit/inlinepolicy.cpp +++ b/src/coreclr/src/jit/inlinepolicy.cpp @@ -1700,7 +1700,7 @@ void DiscretionaryPolicy::MethodInfoObservations(CORINFO_METHOD_INFO* methodInfo // 0.100 * m_CalleeNativeSizeEstimate + // -0.100 * m_CallsiteNativeSizeEstimate // -// On the inlines in CoreCLR's mscorlib, release windows x64, this +// On the inlines in CoreCLR's CoreLib, release windows x64, this // yields scores of R=0.42, MSE=228, and MAE=7.25. // // This estimate can be improved slighly by refitting, resulting in diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 5952db77f919..5266da117cf8 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -592,7 +592,7 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) * * TODO-XArch-CQ: (Low-pri): Jit64 generates in-line code of 8 instructions for (i) above. * There are hardly any occurrences of this conversion operation in platform - * assemblies or in CQ perf benchmarks (1 occurrence in mscorlib, microsoft.jscript, + * assemblies or in CQ perf benchmarks (1 occurrence in corelib, microsoft.jscript, * 1 occurence in Roslyn and no occurrences in system, system.core, system.numerics * system.windows.forms, scimark, fractals, bio mums). If we ever find evidence that * doing this optimization is a win, should consider generating in-lined code. diff --git a/src/coreclr/src/jit/scopeinfo.cpp b/src/coreclr/src/jit/scopeinfo.cpp index 5fc7bca119f4..77d8233cac63 100644 --- a/src/coreclr/src/jit/scopeinfo.cpp +++ b/src/coreclr/src/jit/scopeinfo.cpp @@ -1673,7 +1673,7 @@ void CodeGen::psiEndProlog() We still report all the arguments at the very start of the method so that the user can see the arguments at the very start of the method (offset=0). - Disabling this decreased the debug maps in mscorlib by 10% (01/2003) + Disabling this decreased the debug maps in CoreLib by 10% (01/2003) */ #if 0 diff --git a/src/coreclr/src/jit/ssabuilder.cpp b/src/coreclr/src/jit/ssabuilder.cpp index d562065bf216..62efd8696dac 100644 --- a/src/coreclr/src/jit/ssabuilder.cpp +++ b/src/coreclr/src/jit/ssabuilder.cpp @@ -1656,8 +1656,6 @@ bool SsaBuilder::IncludeInSsa(unsigned lclNum) // - SSA doesn't allow a single node to contain multiple SSA definitions. // - and PROMOTION_TYPE_DEPENDEDNT fields are never candidates for a register. // - // Example mscorlib method: CompatibilitySwitches:IsCompatibilitySwitchSet - // return false; } else if (varDsc->lvIsStructField && m_pCompiler->lvaGetDesc(varDsc->lvParentLcl)->lvIsMultiRegRet) diff --git a/src/coreclr/src/jit/unwind.h b/src/coreclr/src/jit/unwind.h index 5541450e0ef7..f510eb6f1d82 100644 --- a/src/coreclr/src/jit/unwind.h +++ b/src/coreclr/src/jit/unwind.h @@ -150,7 +150,7 @@ class UnwindCodesBase class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase { - // UPC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 34. + // UPC_LOCAL_COUNT is the amount of memory local to this class. For ARM CoreLib, the maximum size is 34. // Here is a histogram of other interesting sizes: // <=16 79% // <=24 96% @@ -314,7 +314,7 @@ class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase { - // UEC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 6, + // UEC_LOCAL_COUNT is the amount of memory local to this class. For ARM CoreLib, the maximum size is 6, // while 89% of epilogs fit in 4. So, set it to 4 to maintain array alignment and hit most cases. static const int UEC_LOCAL_COUNT = 4; diff --git a/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc b/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc index f51e77ae1245..783d1adafb10 100644 --- a/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc +++ b/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc @@ -314,14 +314,13 @@ BEGIN MSG_FOR_URT_HR(CORDBG_E_UNSUPPORTED_DELEGATE) "The delegate contains a delegate currently not supported by the API." MSG_FOR_URT_HR(PEFMT_E_64BIT) "File is PE32+." MSG_FOR_URT_HR(PEFMT_E_32BIT) "File is PE32" - MSG_FOR_URT_HR(NGEN_E_SYS_ASM_NI_MISSING) "NGen cannot proceed because Mscorlib.dll does not have a native image" MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW) "The bound assembly has a version that is lower than that of the request." MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH) "The assembly version has a public key token that does not match that of the request." MSG_FOR_URT_HR(CLR_E_BIND_IMAGE_UNAVAILABLE) "The requested image was not found or is unavailable." MSG_FOR_URT_HR(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT) "The provided identity format is not recognized." MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_NOT_FOUND) "A binding for the specified assembly name was not found." MSG_FOR_URT_HR(CLR_E_BIND_TYPE_NOT_FOUND) "A binding for the specified type name was not found." - MSG_FOR_URT_HR(CLR_E_BIND_SYS_ASM_NI_MISSING) "Could not use native image because Mscorlib.dll is missing a native image" + MSG_FOR_URT_HR(CLR_E_BIND_SYS_ASM_NI_MISSING) "Could not use native image because System.Private.CoreLib.dll is missing a native image" MSG_FOR_URT_HR(CLR_E_BIND_NI_SECURITY_FAILURE) "Native image was generated in a different trust level than present at runtime" MSG_FOR_URT_HR(CLR_E_BIND_NI_DEP_IDENTITY_MISMATCH) "Native image identity mismatch with respect to its dependencies" MSG_FOR_URT_HR(CLR_E_GC_OOM) "Failfast due to an OOM during a GC" diff --git a/src/coreclr/src/pal/prebuilt/inc/corerror.h b/src/coreclr/src/pal/prebuilt/inc/corerror.h index 31ba2d9c4554..0fe7c75d2d24 100644 --- a/src/coreclr/src/pal/prebuilt/inc/corerror.h +++ b/src/coreclr/src/pal/prebuilt/inc/corerror.h @@ -385,7 +385,6 @@ #define CORDBG_E_UNSUPPORTED_DELEGATE EMAKEHR(0x1c68) #define PEFMT_E_64BIT EMAKEHR(0x1d02) #define PEFMT_E_32BIT EMAKEHR(0x1d0b) -#define NGEN_E_SYS_ASM_NI_MISSING EMAKEHR(0x1f06) #define CLDB_E_INTERNALERROR EMAKEHR(0x1fff) #define CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW EMAKEHR(0x2000) #define CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH EMAKEHR(0x2001) diff --git a/src/coreclr/src/pal/src/locale/utf8.cpp b/src/coreclr/src/pal/src/locale/utf8.cpp index b8a6f7ad5d6f..63bfc8661715 100644 --- a/src/coreclr/src/pal/src/locale/utf8.cpp +++ b/src/coreclr/src/pal/src/locale/utf8.cpp @@ -10,7 +10,7 @@ Module Name: unicode/utf8.c Abstract: - Functions to encode and decode UTF-8 strings. This is a port of the C# version from mscorlib. + Functions to encode and decode UTF-8 strings. This is a port of the C# version from Utf8Encoding.cs. Revision History: diff --git a/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp b/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp index 4119399b3618..36924c3c30a2 100644 --- a/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp +++ b/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp @@ -3,11 +3,6 @@ //#include "stdafx.h" #include "resultbuffer.h" -// -//#using -// -//using namespace System; - ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize) { diff --git a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp index e99e31ff31d3..32e8f92b3e08 100644 --- a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp +++ b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp @@ -3,11 +3,6 @@ //#include "stdafx.h" #include "resultbuffer.h" -// -//#using -// -//using namespace System; - ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize) { diff --git a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp index e99e31ff31d3..32e8f92b3e08 100644 --- a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp +++ b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp @@ -3,11 +3,6 @@ //#include "stdafx.h" #include "resultbuffer.h" -// -//#using -// -//using namespace System; - ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize) { diff --git a/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs b/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs index 0b9f35726a13..57a3353a805d 100644 --- a/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs +++ b/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs @@ -81,7 +81,7 @@ public enum CorElementType : byte // where the encoding/decoding takes place. ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG = 0x3d, - ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for [mscorlib]System.__Canon + ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for System.__Canon ELEMENT_TYPE_MODULE_ZAPSIG = 0x3f, // zapsig encoding for external module id# ELEMENT_TYPE_HANDLE = 64, diff --git a/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs b/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs index f9ab4c106055..35dca8644ac9 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs @@ -63,7 +63,7 @@ public static MethodIL EmitIL(MethodDesc method) // // Ordinary volatile loads and stores only guarantee atomicity for pointer-sized (or smaller) data. // So, on 32-bit platforms we must use Interlocked operations instead for the 64-bit types. - // The implementation in mscorlib already does this, so we will only substitute a new + // The implementation in CoreLib already does this, so we will only substitute a new // IL body if we're running on a 64-bit platform. // case TypeFlags.Int64 when method.Context.Target.PointerSize == 8: diff --git a/src/coreclr/src/tools/crossgen/CMakeLists.txt b/src/coreclr/src/tools/crossgen/CMakeLists.txt index bf37a9cc75e5..8d861b68df52 100644 --- a/src/coreclr/src/tools/crossgen/CMakeLists.txt +++ b/src/coreclr/src/tools/crossgen/CMakeLists.txt @@ -50,7 +50,7 @@ target_link_libraries(crossgen ${CLRJIT_CROSSGEN} gcinfo_crossgen corzap_crossgen - mscorlib_crossgen + corelib_crossgen utilcode_crossgen ) diff --git a/src/coreclr/src/tools/crossgen/crossgen.cpp b/src/coreclr/src/tools/crossgen/crossgen.cpp index 41da650119d8..803ea5aff6e7 100644 --- a/src/coreclr/src/tools/crossgen/crossgen.cpp +++ b/src/coreclr/src/tools/crossgen/crossgen.cpp @@ -35,7 +35,7 @@ enum ReturnValues STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzDiasymreaderPath); STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, SIZE_T customBaseAddress=0, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr); void SetSvcLogger(ICorSvcLogger *pCorSvcLogger); -void SetMscorlibPath(LPCWSTR wzSystemDirectory); +void SetCoreLibPath(LPCWSTR wzSystemDirectory); /* --------------------------------------------------------------------------- * * Console stuff @@ -257,7 +257,7 @@ bool StringEndsWith(LPCWSTR pwzString, LPCWSTR pwzCandidate) // When using the Phone binding model (TrustedPlatformAssemblies), automatically // detect which path CoreLib.[ni.]dll lies in. // -bool ComputeMscorlibPathFromTrustedPlatformAssemblies(SString& pwzMscorlibPath, LPCWSTR pwzTrustedPlatformAssemblies) +bool ComputeCoreLibPathFromTrustedPlatformAssemblies(SString& pwzCoreLibPath, LPCWSTR pwzTrustedPlatformAssemblies) { LPWSTR wszTrustedPathCopy = new WCHAR[wcslen(pwzTrustedPlatformAssemblies) + 1]; wcscpy_s(wszTrustedPathCopy, wcslen(pwzTrustedPlatformAssemblies) + 1, pwzTrustedPlatformAssemblies); @@ -277,11 +277,11 @@ bool ComputeMscorlibPathFromTrustedPlatformAssemblies(SString& pwzMscorlibPath, if (StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W CoreLibName_IL_W) || StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W CoreLibName_NI_W)) { - pwzMscorlibPath.Set(wszSingleTrustedPath); - SString::Iterator pwzSeparator = pwzMscorlibPath.End(); + pwzCoreLibPath.Set(wszSingleTrustedPath); + SString::Iterator pwzSeparator = pwzCoreLibPath.End(); bool retval = true; - if (!SUCCEEDED(CopySystemDirectory(pwzMscorlibPath, pwzMscorlibPath))) + if (!SUCCEEDED(CopySystemDirectory(pwzCoreLibPath, pwzCoreLibPath))) { retval = false; } @@ -318,7 +318,7 @@ void PopulateTPAList(SString path, LPCWSTR pwszMask, SString &refTPAList, bool f // No NIs are supported when creating NI images (other than NI of System.Private.CoreLib.dll). if (!fCreatePDB) { - // Only CoreLib's ni.dll should be in the TPAList for the compilation of non-mscorlib assemblies. + // Only CoreLib's ni.dll should be in the TPAList for the compilation of non-CoreLib assemblies. if (StringEndsWith((LPWSTR)pwszFilename, W(".ni.dll"))) { fAddFileToTPAList = false; @@ -837,10 +837,10 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) if (pwzTrustedPlatformAssemblies != nullptr) { - if (ComputeMscorlibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, pwzTrustedPlatformAssemblies)) + if (ComputeCoreLibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, pwzTrustedPlatformAssemblies)) { pwzPlatformAssembliesPaths = wzTrustedPathRoot.GetUnicode(); - SetMscorlibPath(pwzPlatformAssembliesPaths); + SetCoreLibPath(pwzPlatformAssembliesPaths); } } diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index fb36f5ca9b6e..23b2e91f6b1b 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -316,6 +316,7 @@ set(VM_SOURCES_WKS comthreadpool.cpp comutilnative.cpp comwaithandle.cpp + corelib.cpp # true customattribute.cpp custommarshalerinfo.cpp autotrace.cpp @@ -370,7 +371,6 @@ set(VM_SOURCES_WKS marshalnative.cpp methodtablebuilder.cpp mlinfo.cpp - mscorlib.cpp # true multicorejit.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true' multicorejitplayer.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true' nativeeventsource.cpp @@ -491,7 +491,7 @@ set(VM_HEADERS_WKS marshalnative.h methodtablebuilder.h mlinfo.h - mscorlib.h + corelib.h multicorejit.h multicorejitimpl.h nativeeventsource.h diff --git a/src/coreclr/src/vm/amd64/asmconstants.h b/src/coreclr/src/vm/amd64/asmconstants.h index a073179f8121..8ef508e42988 100644 --- a/src/coreclr/src/vm/amd64/asmconstants.h +++ b/src/coreclr/src/vm/amd64/asmconstants.h @@ -486,7 +486,7 @@ ASMCONSTANTS_C_ASSERT(OFFSET__TEB__ThreadLocalStoragePointer == offsetof(TEB, Th #define DELEGATE_FIELD_OFFSET__METHOD_AUX 0x20 ASMCONSTANTS_RUNTIME_ASSERT(DELEGATE_FIELD_OFFSET__METHOD_AUX == Object::GetOffsetOfFirstField() + - MscorlibBinder::GetFieldOffset(FIELD__DELEGATE__METHOD_PTR_AUX)); + CoreLibBinder::GetFieldOffset(FIELD__DELEGATE__METHOD_PTR_AUX)); #define ASM_LARGE_OBJECT_SIZE 85000 diff --git a/src/coreclr/src/vm/appdomain.cpp b/src/coreclr/src/vm/appdomain.cpp index 8f5b4153d8e5..1ba7c47cd50a 100644 --- a/src/coreclr/src/vm/appdomain.cpp +++ b/src/coreclr/src/vm/appdomain.cpp @@ -928,7 +928,7 @@ OBJECTREF AppDomain::GetMissingObject() if (!m_hndMissing) { // Get the field - FieldDesc *pValueFD = MscorlibBinder::GetField(FIELD__MISSING__VALUE); + FieldDesc *pValueFD = CoreLibBinder::GetField(FIELD__MISSING__VALUE); pValueFD->CheckRunClassInitThrowing(); @@ -1268,7 +1268,7 @@ void SystemDomain::Init() DWORD size = 0; - // Get the install directory so we can find mscorlib + // Get the install directory so we can find CoreLib hr = GetInternalSystemDirectory(NULL, &size); if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) ThrowHR(hr); @@ -1307,7 +1307,7 @@ void SystemDomain::Init() } #endif - // Finish loading mscorlib now. + // Finish loading CoreLib now. m_pSystemAssembly->GetDomainAssembly()->EnsureActive(); } @@ -1424,36 +1424,36 @@ void SystemDomain::LoadBaseSystemClasses() // the globals in this function before finishing the load. m_pSystemAssembly = DefaultDomain()->LoadDomainAssembly(NULL, m_pSystemFile, FILE_LOAD_POST_LOADLIBRARY)->GetCurrentAssembly(); - // Set up binder for mscorlib - MscorlibBinder::AttachModule(m_pSystemAssembly->GetManifestModule()); + // Set up binder for CoreLib + CoreLibBinder::AttachModule(m_pSystemAssembly->GetManifestModule()); // Load Object - g_pObjectClass = MscorlibBinder::GetClass(CLASS__OBJECT); + g_pObjectClass = CoreLibBinder::GetClass(CLASS__OBJECT); // Now that ObjectClass is loaded, we can set up // the system for finalizers. There is no point in deferring this, since we need // to know this before we allocate our first object. - g_pObjectFinalizerMD = MscorlibBinder::GetMethod(METHOD__OBJECT__FINALIZE); + g_pObjectFinalizerMD = CoreLibBinder::GetMethod(METHOD__OBJECT__FINALIZE); - g_pCanonMethodTableClass = MscorlibBinder::GetClass(CLASS____CANON); + g_pCanonMethodTableClass = CoreLibBinder::GetClass(CLASS____CANON); // NOTE: !!!IMPORTANT!!! ValueType and Enum MUST be loaded one immediately after // the other, because we have coded MethodTable::IsChildValueType // in such a way that it depends on this behaviour. // Load the ValueType class - g_pValueTypeClass = MscorlibBinder::GetClass(CLASS__VALUE_TYPE); + g_pValueTypeClass = CoreLibBinder::GetClass(CLASS__VALUE_TYPE); // Load the enum class - g_pEnumClass = MscorlibBinder::GetClass(CLASS__ENUM); + g_pEnumClass = CoreLibBinder::GetClass(CLASS__ENUM); _ASSERTE(!g_pEnumClass->IsValueType()); // Load System.RuntimeType - g_pRuntimeTypeClass = MscorlibBinder::GetClass(CLASS__CLASS); + g_pRuntimeTypeClass = CoreLibBinder::GetClass(CLASS__CLASS); _ASSERTE(g_pRuntimeTypeClass->IsFullyLoaded()); // Load Array class - g_pArrayClass = MscorlibBinder::GetClass(CLASS__ARRAY); + g_pArrayClass = CoreLibBinder::GetClass(CLASS__ARRAY); // Calling a method on IList for an array requires redirection to a method on // the SZArrayHelper class. Retrieving such methods means calling @@ -1461,31 +1461,31 @@ void SystemDomain::LoadBaseSystemClasses() // the corresponding method on SZArrayHelper. This basically results in a class // load due to a method call, which the debugger cannot handle, so we pre-load // the SZArrayHelper class here. - g_pSZArrayHelperClass = MscorlibBinder::GetClass(CLASS__SZARRAYHELPER); + g_pSZArrayHelperClass = CoreLibBinder::GetClass(CLASS__SZARRAYHELPER); // Load ByReference class // // NOTE: ByReference must be the first by-ref-like system type to be loaded, // because MethodTable::ClassifyEightBytesWithManagedLayout depends on it. - g_pByReferenceClass = MscorlibBinder::GetClass(CLASS__BYREFERENCE); + g_pByReferenceClass = CoreLibBinder::GetClass(CLASS__BYREFERENCE); // Load Nullable class - g_pNullableClass = MscorlibBinder::GetClass(CLASS__NULLABLE); + g_pNullableClass = CoreLibBinder::GetClass(CLASS__NULLABLE); // Load the Object array class. g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT] = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pObjectClass)); - // We have delayed allocation of mscorlib's static handles until we load the object class - MscorlibBinder::GetModule()->AllocateRegularStaticHandles(DefaultDomain()); + // We have delayed allocation of CoreLib's static handles until we load the object class + CoreLibBinder::GetModule()->AllocateRegularStaticHandles(DefaultDomain()); // Make sure all primitive types are loaded for (int et = ELEMENT_TYPE_VOID; et <= ELEMENT_TYPE_R8; et++) - MscorlibBinder::LoadPrimitiveType((CorElementType)et); + CoreLibBinder::LoadPrimitiveType((CorElementType)et); - MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_I); - MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_U); + CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_I); + CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_U); - g_TypedReferenceMT = MscorlibBinder::GetClass(CLASS__TYPED_REFERENCE); + g_TypedReferenceMT = CoreLibBinder::GetClass(CLASS__TYPED_REFERENCE); // unfortunately, the following cannot be delay loaded since the jit // uses it to compute method attributes within a function that cannot @@ -1493,8 +1493,8 @@ void SystemDomain::LoadBaseSystemClasses() // where a complus exception can be thrown. It is unfortunate, because // we know that the delegate class and multidelegate class are always // guaranteed to be found. - g_pDelegateClass = MscorlibBinder::GetClass(CLASS__DELEGATE); - g_pMulticastDelegateClass = MscorlibBinder::GetClass(CLASS__MULTICAST_DELEGATE); + g_pDelegateClass = CoreLibBinder::GetClass(CLASS__DELEGATE); + g_pMulticastDelegateClass = CoreLibBinder::GetClass(CLASS__MULTICAST_DELEGATE); #ifndef CROSSGEN_COMPILE CrossLoaderAllocatorHashSetup::EnsureTypesLoaded(); @@ -1508,45 +1508,45 @@ void SystemDomain::LoadBaseSystemClasses() #endif // CROSSGEN_COMPILE // used by IsImplicitInterfaceOfSZArray - MscorlibBinder::GetClass(CLASS__IENUMERABLEGENERIC); - MscorlibBinder::GetClass(CLASS__ICOLLECTIONGENERIC); - MscorlibBinder::GetClass(CLASS__ILISTGENERIC); - MscorlibBinder::GetClass(CLASS__IREADONLYCOLLECTIONGENERIC); - MscorlibBinder::GetClass(CLASS__IREADONLYLISTGENERIC); + CoreLibBinder::GetClass(CLASS__IENUMERABLEGENERIC); + CoreLibBinder::GetClass(CLASS__ICOLLECTIONGENERIC); + CoreLibBinder::GetClass(CLASS__ILISTGENERIC); + CoreLibBinder::GetClass(CLASS__IREADONLYCOLLECTIONGENERIC); + CoreLibBinder::GetClass(CLASS__IREADONLYLISTGENERIC); // Load String - g_pStringClass = MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_STRING); + g_pStringClass = CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_STRING); #ifdef FEATURE_UTF8STRING // Load Utf8String - g_pUtf8StringClass = MscorlibBinder::GetClass(CLASS__UTF8_STRING); + g_pUtf8StringClass = CoreLibBinder::GetClass(CLASS__UTF8_STRING); #endif // FEATURE_UTF8STRING #ifndef CROSSGEN_COMPILE ECall::PopulateManagedStringConstructors(); #endif // CROSSGEN_COMPILE - g_pExceptionClass = MscorlibBinder::GetClass(CLASS__EXCEPTION); - g_pOutOfMemoryExceptionClass = MscorlibBinder::GetException(kOutOfMemoryException); - g_pStackOverflowExceptionClass = MscorlibBinder::GetException(kStackOverflowException); - g_pExecutionEngineExceptionClass = MscorlibBinder::GetException(kExecutionEngineException); - g_pThreadAbortExceptionClass = MscorlibBinder::GetException(kThreadAbortException); + g_pExceptionClass = CoreLibBinder::GetClass(CLASS__EXCEPTION); + g_pOutOfMemoryExceptionClass = CoreLibBinder::GetException(kOutOfMemoryException); + g_pStackOverflowExceptionClass = CoreLibBinder::GetException(kStackOverflowException); + g_pExecutionEngineExceptionClass = CoreLibBinder::GetException(kExecutionEngineException); + g_pThreadAbortExceptionClass = CoreLibBinder::GetException(kThreadAbortException); - g_pThreadClass = MscorlibBinder::GetClass(CLASS__THREAD); + g_pThreadClass = CoreLibBinder::GetClass(CLASS__THREAD); #ifdef FEATURE_COMINTEROP - g_pBaseCOMObject = MscorlibBinder::GetClass(CLASS__COM_OBJECT); + g_pBaseCOMObject = CoreLibBinder::GetClass(CLASS__COM_OBJECT); #endif - g_pIDynamicInterfaceCastableInterface = MscorlibBinder::GetClass(CLASS__IDYNAMICINTERFACECASTABLE); + g_pIDynamicInterfaceCastableInterface = CoreLibBinder::GetClass(CLASS__IDYNAMICINTERFACECASTABLE); #ifdef FEATURE_ICASTABLE - g_pICastableInterface = MscorlibBinder::GetClass(CLASS__ICASTABLE); + g_pICastableInterface = CoreLibBinder::GetClass(CLASS__ICASTABLE); #endif // FEATURE_ICASTABLE // Make sure that FCall mapping for Monitor.Enter is initialized. We need it in case Monitor.Enter is used only as JIT helper. // For more details, see comment in code:JITutil_MonEnterWorker around "__me = GetEEFuncEntryPointMacro(JIT_MonEnter)". - ECall::GetFCallImpl(MscorlibBinder::GetMethod(METHOD__MONITOR__ENTER)); + ECall::GetFCallImpl(CoreLibBinder::GetMethod(METHOD__MONITOR__ENTER)); #ifdef PROFILING_SUPPORTED // Note that g_profControlBlock.fBaseSystemClassesLoaded must be set to TRUE only after @@ -1559,7 +1559,7 @@ void SystemDomain::LoadBaseSystemClasses() #if defined(_DEBUG) && !defined(CROSSGEN_COMPILE) if (!NingenEnabled()) { - g_Mscorlib.Check(); + g_CoreLib.Check(); } #endif @@ -1567,8 +1567,8 @@ void SystemDomain::LoadBaseSystemClasses() if (GCStress::IsEnabled()) { // Setting up gc coverage requires the base system classes - // to be initialized. So we have deferred it until now for mscorlib. - Module *pModule = MscorlibBinder::GetModule(); + // to be initialized. So we have deferred it until now for CoreLib. + Module *pModule = CoreLibBinder::GetModule(); _ASSERTE(pModule->IsSystem()); if(pModule->HasNativeImage()) { @@ -1666,7 +1666,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth) MethodTable* pCaller = pMeth->GetMethodTable(); - // All Reflection Invocation methods are defined in mscorlib.dll + // All Reflection Invocation methods are defined in CoreLib if (!pCaller->GetModule()->IsSystem()) return false; @@ -1707,7 +1707,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth) // Make sure all types are loaded so that we can use faster GetExistingClass() for (unsigned i = 0; i < NumItems(reflectionInvocationTypes); i++) { - MscorlibBinder::GetClass(reflectionInvocationTypes[i]); + CoreLibBinder::GetClass(reflectionInvocationTypes[i]); } VolatileStore(&fInited, true); @@ -1717,7 +1717,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth) { for (unsigned i = 0; i < NumItems(reflectionInvocationTypes); i++) { - if (MscorlibBinder::GetExistingClass(reflectionInvocationTypes[i]) == pCaller) + if (CoreLibBinder::GetExistingClass(reflectionInvocationTypes[i]) == pCaller) return true; } } @@ -1889,7 +1889,7 @@ StackWalkAction SystemDomain::CallersMethodCallbackWithStackMark(CrawlFrame* pCf // Skipping reflection frames. We don't need to be quite as exhaustive here // as the security or reflection stack walking code since we know this logic - // is only invoked for selected methods in mscorlib itself. So we're + // is only invoked for selected methods in CoreLib itself. So we're // reasonably sure we won't have any sensitive methods late bound invoked on // constructors, properties or events. This leaves being invoked via // MethodInfo, Type or Delegate (and depending on which invoke overload is @@ -3162,8 +3162,8 @@ DomainFile *AppDomain::LoadDomainFile(FileLoadLock *pLock, FileLoadLevel targetL // Make sure we release the lock on exit FileLoadLockRefHolder lockRef(pLock); - // We need to perform the early steps of loading mscorlib without a domain transition. This is - // important for bootstrapping purposes - we need to get mscorlib at least partially loaded + // We need to perform the early steps of loading CoreLib without a domain transition. This is + // important for bootstrapping purposes - we need to get CoreLib at least partially loaded // into a domain before we can run serialization code to do the transition. // // Note that we cannot do this in general for all assemblies, because some of the security computations @@ -3499,7 +3499,7 @@ void AppDomain::SetupSharedStatics() // Because we are allocating/referencing objects, need to be in cooperative mode GCX_COOP(); - DomainLocalModule *pLocalModule = MscorlibBinder::GetModule()->GetDomainLocalModule(); + DomainLocalModule *pLocalModule = CoreLibBinder::GetModule()->GetDomainLocalModule(); // This is a convenient place to initialize String.Empty. // It is treated as intrinsic by the JIT as so the static constructor would never run. @@ -3508,7 +3508,7 @@ void AppDomain::SetupSharedStatics() // String should not have any static constructors. _ASSERTE(g_pStringClass->IsClassPreInited()); - FieldDesc * pEmptyStringFD = MscorlibBinder::GetField(FIELD__STRING__EMPTY); + FieldDesc * pEmptyStringFD = CoreLibBinder::GetField(FIELD__STRING__EMPTY); OBJECTREF* pEmptyStringHandle = (OBJECTREF*) ((TADDR)pLocalModule->GetPrecomputedGCStaticsBasePointer()+pEmptyStringFD->GetOffset()); SetObjectReference( pEmptyStringHandle, StringObject::GetEmptyString()); @@ -3876,9 +3876,9 @@ BOOL AppDomain::IsCached(AssemblySpec *pSpec) { WRAPPER_NO_CONTRACT; - // Check to see if this fits our rather loose idea of a reference to mscorlib. + // Check to see if this fits our rather loose idea of a reference to CoreLib. // If so, don't use fusion to bind it - do it ourselves. - if (pSpec->IsMscorlib()) + if (pSpec->IsCoreLib()) return TRUE; return m_AssemblyCache.Contains(pSpec); @@ -3906,9 +3906,9 @@ PEAssembly* AppDomain::FindCachedFile(AssemblySpec* pSpec, BOOL fThrow /*=TRUE*/ } CONTRACTL_END; - // Check to see if this fits our rather loose idea of a reference to mscorlib. + // Check to see if this fits our rather loose idea of a reference to CoreLib. // If so, don't use fusion to bind it - do it ourselves. - if (fThrow && pSpec->IsMscorlib()) + if (fThrow && pSpec->IsCoreLib()) { CONSISTENCY_CHECK(SystemDomain::System()->SystemAssembly() != NULL); PEAssembly *pFile = SystemDomain::System()->SystemFile(); @@ -4002,15 +4002,15 @@ PEAssembly * AppDomain::BindAssemblySpec( if (bindResult.Found()) { - if (SystemDomain::SystemFile() && bindResult.IsMscorlib()) + if (SystemDomain::SystemFile() && bindResult.IsCoreLib()) { - // Avoid rebinding to another copy of mscorlib + // Avoid rebinding to another copy of CoreLib result = SystemDomain::SystemFile(); result.SuppressRelease(); // Didn't get a refcount } else { - // IsSystem on the PEFile should be false, even for mscorlib satellites + // IsSystem on the PEFile should be false, even for CoreLib satellites result = PEAssembly::Open(&bindResult, FALSE); } @@ -4034,7 +4034,7 @@ PEAssembly * AppDomain::BindAssemblySpec( // return an assembly that does not match, and this can cause recursive resource lookups during error // reporting. The CoreLib satellite assembly is loaded from relative locations based on the culture, see // AssemblySpec::Bind(). - if (!pSpec->IsMscorlibSatellite()) + if (!pSpec->IsCoreLibSatellite()) { // Trigger the resolve event also for non-throw situation. AssemblySpec NewSpec(this); @@ -4258,7 +4258,7 @@ void AppDomain::RaiseLoadingAssemblyEvent(DomainAssembly *pAssembly) EX_TRY { - if (MscorlibBinder::GetField(FIELD__ASSEMBLYLOADCONTEXT__ASSEMBLY_LOAD)->GetStaticOBJECTREF() != NULL) + if (CoreLibBinder::GetField(FIELD__ASSEMBLYLOADCONTEXT__ASSEMBLY_LOAD)->GetStaticOBJECTREF() != NULL) { struct _gc { OBJECTREF orThis; @@ -4342,7 +4342,7 @@ AppDomain::RaiseUnhandledExceptionEvent(OBJECTREF *pThrowable, BOOL isTerminatin _ASSERTE(this == GetThread()->GetDomain()); - OBJECTREF orDelegate = MscorlibBinder::GetField(FIELD__APPCONTEXT__UNHANDLED_EXCEPTION)->GetStaticOBJECTREF(); + OBJECTREF orDelegate = CoreLibBinder::GetField(FIELD__APPCONTEXT__UNHANDLED_EXCEPTION)->GetStaticOBJECTREF(); if (orDelegate == NULL) return FALSE; @@ -5346,7 +5346,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB BinderTracing::ResolutionAttemptedOperation tracer{pAssemblyName, 0 /*binderID*/, pManagedAssemblyLoadContextToBindWithin, hr}; // Allocate an AssemblyName managed object - _gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME)); + _gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME)); // Initialize the AssemblyName object from the AssemblySpec spec.AssemblyNameInit(&_gcRefs.oRefAssemblyName, NULL); diff --git a/src/coreclr/src/vm/appdomain.hpp b/src/coreclr/src/vm/appdomain.hpp index 8a73d95c8fcf..a84bd6a6d31b 100644 --- a/src/coreclr/src/vm/appdomain.hpp +++ b/src/coreclr/src/vm/appdomain.hpp @@ -2737,7 +2737,6 @@ class SystemDomain : public BaseDomain #endif // DACCESS_COMPILE //**************************************************************************************** - // Routines to deal with the base library (currently mscorlib.dll) LPCWSTR BaseLibrary() { WRAPPER_NO_CONTRACT; @@ -2750,11 +2749,11 @@ class SystemDomain : public BaseDomain { WRAPPER_NO_CONTRACT; - // See if it is the installation path to mscorlib + // See if it is the installation path to CoreLib if (path.EqualsCaseInsensitive(m_BaseLibrary)) return TRUE; - // Or, it might be the GAC location of mscorlib + // Or, it might be the GAC location of CoreLib if (System()->SystemAssembly() != NULL && path.EqualsCaseInsensitive(System()->SystemAssembly()->GetManifestFile()->GetPath())) return TRUE; @@ -2766,7 +2765,7 @@ class SystemDomain : public BaseDomain { WRAPPER_NO_CONTRACT; - // See if it is the installation path to mscorlib.resources + // See if it is the installation path to corelib.resources SString s(SString::Ascii,g_psBaseLibrarySatelliteAssemblyName); if (path.EqualsCaseInsensitive(s)) return TRUE; @@ -2842,7 +2841,7 @@ class SystemDomain : public BaseDomain #ifdef FEATURE_PREJIT protected: - // These flags let the correct native image of mscorlib to be loaded. + // These flags let the correct native image of CoreLib to be loaded. // This is important for hardbinding to it SVAL_DECL(BOOL, s_fForceDebug); diff --git a/src/coreclr/src/vm/appdomainnative.cpp b/src/coreclr/src/vm/appdomainnative.cpp index 9df486ba46ff..2a2a8c561aca 100644 --- a/src/coreclr/src/vm/appdomainnative.cpp +++ b/src/coreclr/src/vm/appdomainnative.cpp @@ -60,7 +60,7 @@ FCIMPL0(Object*, AppDomainNative::GetLoadedAssemblies) HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - MethodTable * pAssemblyClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY); + MethodTable * pAssemblyClass = CoreLibBinder::GetClass(CLASS__ASSEMBLY); AppDomain * pApp = GetAppDomain(); diff --git a/src/coreclr/src/vm/array.cpp b/src/coreclr/src/vm/array.cpp index dd35b491e9d7..767c2ccb0b02 100644 --- a/src/coreclr/src/vm/array.cpp +++ b/src/coreclr/src/vm/array.cpp @@ -765,7 +765,7 @@ class ArrayOpLinker : public ILStubLinker DWORD dwTotalLocalNum = NewLocal(ELEMENT_TYPE_I4); DWORD dwLengthLocalNum = NewLocal(ELEMENT_TYPE_I4); - mdToken tokRawData = GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + mdToken tokRawData = GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); ILCodeLabel * pRangeExceptionLabel = NewCodeLabel(); ILCodeLabel * pRangeExceptionLabel1 = NewCodeLabel(); @@ -979,14 +979,14 @@ class ArrayOpLinker : public ILStubLinker m_pCode->EmitLabel(pRangeExceptionLabel1); // Assumes that there is one "int" pushed on the stack m_pCode->EmitPOP(); - mdToken tokIndexOutOfRangeCtorExcep = GetToken((MscorlibBinder::GetException(kIndexOutOfRangeException))->GetDefaultConstructor()); + mdToken tokIndexOutOfRangeCtorExcep = GetToken((CoreLibBinder::GetException(kIndexOutOfRangeException))->GetDefaultConstructor()); m_pCode->EmitLabel(pRangeExceptionLabel); m_pCode->EmitNEWOBJ(tokIndexOutOfRangeCtorExcep, 0); m_pCode->EmitTHROW(); if(pTypeMismatchExceptionLabel != NULL) { - mdToken tokTypeMismatchExcepCtor = GetToken((MscorlibBinder::GetException(kArrayTypeMismatchException))->GetDefaultConstructor()); + mdToken tokTypeMismatchExcepCtor = GetToken((CoreLibBinder::GetException(kArrayTypeMismatchException))->GetDefaultConstructor()); m_pCode->EmitLabel(pTypeMismatchExceptionLabel); m_pCode->EmitNEWOBJ(tokTypeMismatchExcepCtor, 0); @@ -1273,18 +1273,18 @@ BOOL IsImplicitInterfaceOfSZArray(MethodTable *pInterfaceMT) PRECONDITION(pInterfaceMT->IsInterface()); PRECONDITION(pInterfaceMT->HasInstantiation()); - // Is target interface Anything in mscorlib? + // Is target interface Anything in CoreLib? if (!pInterfaceMT->HasInstantiation() || !pInterfaceMT->GetModule()->IsSystem()) return FALSE; unsigned rid = pInterfaceMT->GetTypeDefRid(); // Is target interface IList or one of its ancestors, or IReadOnlyList? - return (rid == MscorlibBinder::GetExistingClass(CLASS__ILISTGENERIC)->GetTypeDefRid() || - rid == MscorlibBinder::GetExistingClass(CLASS__ICOLLECTIONGENERIC)->GetTypeDefRid() || - rid == MscorlibBinder::GetExistingClass(CLASS__IENUMERABLEGENERIC)->GetTypeDefRid() || - rid == MscorlibBinder::GetExistingClass(CLASS__IREADONLYCOLLECTIONGENERIC)->GetTypeDefRid() || - rid == MscorlibBinder::GetExistingClass(CLASS__IREADONLYLISTGENERIC)->GetTypeDefRid()); + return (rid == CoreLibBinder::GetExistingClass(CLASS__ILISTGENERIC)->GetTypeDefRid() || + rid == CoreLibBinder::GetExistingClass(CLASS__ICOLLECTIONGENERIC)->GetTypeDefRid() || + rid == CoreLibBinder::GetExistingClass(CLASS__IENUMERABLEGENERIC)->GetTypeDefRid() || + rid == CoreLibBinder::GetExistingClass(CLASS__IREADONLYCOLLECTIONGENERIC)->GetTypeDefRid() || + rid == CoreLibBinder::GetExistingClass(CLASS__IREADONLYLISTGENERIC)->GetTypeDefRid()); } //---------------------------------------------------------------------------------- @@ -1324,10 +1324,10 @@ MethodDesc* GetActualImplementationForArrayGenericIListOrIReadOnlyListMethod(Met unsigned int inheritanceDepth = pItfcMeth->GetMethodTable()->GetNumInterfaces() - 1; PREFIX_ASSUME(0 <= inheritanceDepth && inheritanceDepth < NumItems(startingMethod)); - MethodDesc *pGenericImplementor = MscorlibBinder::GetMethod((BinderMethodID)(startingMethod[inheritanceDepth] + slot)); + MethodDesc *pGenericImplementor = CoreLibBinder::GetMethod((BinderMethodID)(startingMethod[inheritanceDepth] + slot)); // The most common reason for this assert is that the order of the SZArrayHelper methods in - // mscorlib.h does not match the order they are implemented on the generic interfaces. + // corelib.h does not match the order they are implemented on the generic interfaces. _ASSERTE(pGenericImplementor == MemberLoader::FindMethodByName(g_pSZArrayHelperClass, pItfcMeth->GetName())); // OPTIMIZATION: For any method other than GetEnumerator(), we can safely substitute diff --git a/src/coreclr/src/vm/assemblyname.cpp b/src/coreclr/src/vm/assemblyname.cpp index 60b46cfc6449..3ccb15140f2b 100644 --- a/src/coreclr/src/vm/assemblyname.cpp +++ b/src/coreclr/src/vm/assemblyname.cpp @@ -45,7 +45,7 @@ FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameU if (gc.filename->GetStringLength() == 0) COMPlusThrow(kArgumentException, W("Argument_EmptyFileName")); - gc.result = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME)); + gc.result = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME)); /////////////////////////////////////////////// diff --git a/src/coreclr/src/vm/assemblynative.cpp b/src/coreclr/src/vm/assemblynative.cpp index b5701e8bcbbe..f73697d5a3ac 100644 --- a/src/coreclr/src/vm/assemblynative.cpp +++ b/src/coreclr/src/vm/assemblynative.cpp @@ -170,7 +170,7 @@ Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImag DWORD dwMessageID = IDS_EE_FILELOAD_ERROR_GENERIC; - // Set the caller's assembly to be mscorlib + // Set the caller's assembly to be CoreLib DomainAssembly *pCallersAssembly = SystemDomain::System()->SystemAssembly()->GetDomainAssembly(); PEAssembly *pParentAssembly = pCallersAssembly->GetFile(); @@ -705,7 +705,7 @@ void QCALLTYPE AssemblyNative::GetModules(QCall::AssemblyHandle pAssembly, BOOL GCPROTECT_BEGIN(orModules); // Return the modules - orModules = (PTRARRAYREF)AllocateObjectArray(modules.GetCount(), MscorlibBinder::GetClass(CLASS__MODULE)); + orModules = (PTRARRAYREF)AllocateObjectArray(modules.GetCount(), CoreLibBinder::GetClass(CLASS__MODULE)); for(COUNT_T i = 0; i < modules.GetCount(); i++) { @@ -889,7 +889,7 @@ void QCALLTYPE AssemblyNative::GetExportedTypes(QCall::AssemblyHandle pAssembly, GCPROTECT_BEGIN(orTypes); // Return the types - orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), MscorlibBinder::GetClass(CLASS__TYPE)); + orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), CoreLibBinder::GetClass(CLASS__TYPE)); for(COUNT_T i = 0; i < types.GetCount(); i++) { @@ -960,7 +960,7 @@ void QCALLTYPE AssemblyNative::GetForwardedTypes(QCall::AssemblyHandle pAssembly GCPROTECT_BEGIN(orTypes); // Return the types - orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), MscorlibBinder::GetClass(CLASS__TYPE)); + orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), CoreLibBinder::GetClass(CLASS__TYPE)); for(COUNT_T i = 0; i < types.GetCount(); i++) { @@ -1051,7 +1051,7 @@ FCIMPL1(Object*, AssemblyNative::GetReferencedAssemblies, AssemblyBaseObject * p IMDInternalImport *pImport = pAssembly->GetAssembly()->GetManifestImport(); - MethodTable* pAsmNameClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME); + MethodTable* pAsmNameClass = CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME); HENUMInternalHolder phEnum(pImport); DWORD dwCount = 0; diff --git a/src/coreclr/src/vm/assemblyspec.cpp b/src/coreclr/src/vm/assemblyspec.cpp index ad035b2daf62..946f5856f7ca 100644 --- a/src/coreclr/src/vm/assemblyspec.cpp +++ b/src/coreclr/src/vm/assemblyspec.cpp @@ -244,7 +244,7 @@ void AssemblySpec::InitializeSpec(PEAssembly * pFile) { // We should aways having the binding context in the PEAssembly. The only exception to this are the following: // - // 1) when we are here during EEStartup and loading mscorlib.dll. + // 1) when we are here during EEStartup and loading CoreLib. // 2) We are dealing with dynamic assemblies _ASSERTE((pExpectedBinder != NULL) || pFile->IsSystem() || pFile->IsDynamic()); SetBindingContext(pExpectedBinder); @@ -423,7 +423,7 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn if ((m_context.usMajorVersion != (USHORT) -1) && (m_context.usMinorVersion != (USHORT) -1)) { - MethodTable* pVersion = MscorlibBinder::GetClass(CLASS__VERSION); + MethodTable* pVersion = CoreLibBinder::GetClass(CLASS__VERSION); // version gc.Version = AllocateObject(pVersion); @@ -495,7 +495,7 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn // cultureinfo if (m_context.szLocale) { - MethodTable* pCI = MscorlibBinder::GetClass(CLASS__CULTURE_INFO); + MethodTable* pCI = CoreLibBinder::GetClass(CLASS__CULTURE_INFO); gc.CultureInfo = AllocateObject(pCI); gc.Locale = StringObject::NewString(m_context.szLocale); @@ -1029,7 +1029,7 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter // Check if the AssemblySpec already has specified its binding context. This will be set for assemblies that are // attempted to be explicitly bound using AssemblyLoadContext LoadFrom* methods. - if(!pSpec->IsAssemblySpecForMscorlib()) + if(!pSpec->IsAssemblySpecForCoreLib()) pBinderContextForLookup = pSpec->GetBindingContext(); else { @@ -1046,9 +1046,9 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter if (fGetBindingContextFromParent) { - // MScorlib does not have a binding context associated with it and its lookup will only be done + // CoreLib does not have a binding context associated with it and its lookup will only be done // using its AssemblySpec hash. - if (!pSpec->IsAssemblySpecForMscorlib()) + if (!pSpec->IsAssemblySpecForCoreLib()) { pBinderContextForLookup = pSpec->GetBindingContextFromParentAssembly(pSpecDomain); pSpec->SetBindingContext(pBinderContextForLookup); @@ -1453,7 +1453,7 @@ BOOL AssemblySpecBindingCache::StoreException(AssemblySpec *pSpec, Exception* pE pBinderToSaveException = pSpec->GetBindingContext(); if (pBinderToSaveException == NULL) { - if (!pSpec->IsAssemblySpecForMscorlib()) + if (!pSpec->IsAssemblySpecForCoreLib()) { pBinderToSaveException = pSpec->GetBindingContextFromParentAssembly(pSpec->GetAppDomain()); UINT_PTR binderID = 0; diff --git a/src/coreclr/src/vm/baseassemblyspec.cpp b/src/coreclr/src/vm/baseassemblyspec.cpp index 864dd2ec44b0..5a57c0ba5d3e 100644 --- a/src/coreclr/src/vm/baseassemblyspec.cpp +++ b/src/coreclr/src/vm/baseassemblyspec.cpp @@ -73,7 +73,7 @@ VOID BaseAssemblySpec::CloneFieldsToStackingAllocator( StackingAllocator* alloc) } #ifndef DACCESS_COMPILE -BOOL BaseAssemblySpec::IsMscorlib() +BOOL BaseAssemblySpec::IsCoreLib() { CONTRACTL { @@ -106,7 +106,7 @@ BOOL BaseAssemblySpec::IsMscorlib() ( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) ); } -BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib() +BOOL BaseAssemblySpec::IsAssemblySpecForCoreLib() { CONTRACTL { @@ -118,28 +118,28 @@ BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib() } CONTRACTL_END; - BOOL fIsAssemblySpecForMscorlib = FALSE; + BOOL fIsAssemblySpecForCoreLib = FALSE; if (m_pAssemblyName) { size_t iNameLen = strlen(m_pAssemblyName); - fIsAssemblySpecForMscorlib = ( (iNameLen >= CoreLibNameLen) && + fIsAssemblySpecForCoreLib = ( (iNameLen >= CoreLibNameLen) && ( (!_stricmp(m_pAssemblyName, g_psBaseLibrary)) || ( (!_strnicmp(m_pAssemblyName, g_psBaseLibraryName, CoreLibNameLen)) && ( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) ); } - return fIsAssemblySpecForMscorlib; + return fIsAssemblySpecForCoreLib; } -#define MSCORLIB_PUBLICKEY g_rbTheSilverlightPlatformKey +#define CORELIB_PUBLICKEY g_rbTheSilverlightPlatformKey -// A satellite assembly for mscorlib is named "mscorlib.resources" or -// mscorlib.debug.resources.dll and uses the same public key as mscorlib. +// A satellite assembly for CoreLib is named "System.Private.CoreLib.resources" or +// System.Private.CoreLib.debug.resources.dll and uses the same public key as CoreLib. // It does not necessarily have the same version, and the Culture will // always be set to something like "jp-JP". -BOOL BaseAssemblySpec::IsMscorlibSatellite() const +BOOL BaseAssemblySpec::IsCoreLibSatellite() const { CONTRACTL { @@ -168,13 +168,13 @@ BOOL BaseAssemblySpec::IsMscorlibSatellite() const // More of bug 213471 size_t iNameLen = strlen(m_pAssemblyName); - // we allow name to be of the form mscorlib.resources.dll only - BOOL r = ( (m_cbPublicKeyOrToken == sizeof(MSCORLIB_PUBLICKEY)) && + // we allow name to be of the form System.Private.CoreLib.resources.dll only + BOOL r = ( (m_cbPublicKeyOrToken == sizeof(CORELIB_PUBLICKEY)) && (iNameLen >= CoreLibSatelliteNameLen) && (!SString::_strnicmp(m_pAssemblyName, g_psBaseLibrarySatelliteAssemblyName, CoreLibSatelliteNameLen)) && ( (iNameLen == CoreLibSatelliteNameLen) || (m_pAssemblyName[CoreLibSatelliteNameLen] == ',') ) ); - r = r && ( memcmp(m_pbPublicKeyOrToken,MSCORLIB_PUBLICKEY,sizeof(MSCORLIB_PUBLICKEY)) == 0); + r = r && ( memcmp(m_pbPublicKeyOrToken,CORELIB_PUBLICKEY,sizeof(CORELIB_PUBLICKEY)) == 0); return r; } diff --git a/src/coreclr/src/vm/baseassemblyspec.h b/src/coreclr/src/vm/baseassemblyspec.h index 180ce86e119f..150368c1c447 100644 --- a/src/coreclr/src/vm/baseassemblyspec.h +++ b/src/coreclr/src/vm/baseassemblyspec.h @@ -79,7 +79,7 @@ class BaseAssemblySpec return m_pBindingContext; } - BOOL IsAssemblySpecForMscorlib(); + BOOL IsAssemblySpecForCoreLib(); HRESULT ParseName(); DWORD Hash(); @@ -106,8 +106,8 @@ class BaseAssemblySpec BOOL IsStrongNamed() const; BOOL HasPublicKey() const; BOOL HasPublicKeyToken() const; - BOOL IsMscorlibSatellite() const; - BOOL IsMscorlib(); + BOOL IsCoreLibSatellite() const; + BOOL IsCoreLib(); // Returns true inline BOOL HasUniqueIdentity() const diff --git a/src/coreclr/src/vm/baseassemblyspec.inl b/src/coreclr/src/vm/baseassemblyspec.inl index 5a6759506f5a..5e1496b5986e 100644 --- a/src/coreclr/src/vm/baseassemblyspec.inl +++ b/src/coreclr/src/vm/baseassemblyspec.inl @@ -320,7 +320,7 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare // If the assemblySpec contains the binding context, then check if they match. - if (!(pSpec->IsAssemblySpecForMscorlib() && IsAssemblySpecForMscorlib())) + if (!(pSpec->IsAssemblySpecForCoreLib() && IsAssemblySpecForCoreLib())) { if (!AreSameBinderInstance(pSpec->m_pBindingContext, m_pBindingContext)) { diff --git a/src/coreclr/src/vm/binder.cpp b/src/coreclr/src/vm/binder.cpp index bef7b479bc60..3dbd86605967 100644 --- a/src/coreclr/src/vm/binder.cpp +++ b/src/coreclr/src/vm/binder.cpp @@ -28,13 +28,13 @@ // // Retrieve structures from ID. // -NOINLINE PTR_MethodTable MscorlibBinder::LookupClass(BinderClassID id) +NOINLINE PTR_MethodTable CoreLibBinder::LookupClass(BinderClassID id) { WRAPPER_NO_CONTRACT; - return (&g_Mscorlib)->LookupClassLocal(id); + return (&g_CoreLib)->LookupClassLocal(id); } -PTR_MethodTable MscorlibBinder::GetClassLocal(BinderClassID id) +PTR_MethodTable CoreLibBinder::GetClassLocal(BinderClassID id) { WRAPPER_NO_CONTRACT; @@ -44,7 +44,7 @@ PTR_MethodTable MscorlibBinder::GetClassLocal(BinderClassID id) return pMT; } -PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id) +PTR_MethodTable CoreLibBinder::LookupClassLocal(BinderClassID id) { CONTRACTL { @@ -59,11 +59,11 @@ PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id) PTR_MethodTable pMT = NULL; - // Binder methods are used for loading "known" types from mscorlib.dll. Thus they are unlikely to be part + // Binder methods are used for loading "known" types. Thus they are unlikely to be part // of a recursive cycle. This is used too broadly to force manual overrides at every callsite. OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - const MscorlibClassDescription *d = m_classDescriptions + (int)id; + const CoreLibClassDescription *d = m_classDescriptions + (int)id; pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name).AsMethodTable(); @@ -76,13 +76,13 @@ PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id) return pMT; } -NOINLINE MethodDesc * MscorlibBinder::LookupMethod(BinderMethodID id) +NOINLINE MethodDesc * CoreLibBinder::LookupMethod(BinderMethodID id) { WRAPPER_NO_CONTRACT; - return (&g_Mscorlib)->LookupMethodLocal(id); + return (&g_CoreLib)->LookupMethodLocal(id); } -MethodDesc * MscorlibBinder::GetMethodLocal(BinderMethodID id) +MethodDesc * CoreLibBinder::GetMethodLocal(BinderMethodID id) { WRAPPER_NO_CONTRACT; @@ -92,7 +92,7 @@ MethodDesc * MscorlibBinder::GetMethodLocal(BinderMethodID id) return pMD; } -MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id) +MethodDesc * CoreLibBinder::LookupMethodLocal(BinderMethodID id) { CONTRACTL { @@ -108,10 +108,10 @@ MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id) #ifndef DACCESS_COMPILE MethodDesc * pMD = NULL; - const MscorlibMethodDescription *d = m_methodDescriptions + (id - 1); + const CoreLibMethodDescription *d = m_methodDescriptions + (id - 1); MethodTable * pMT = GetClassLocal(d->classID); - _ASSERTE(pMT != NULL && "Couldn't find a type in mscorlib!"); + _ASSERTE(pMT != NULL && "Couldn't find a type in System.Private.CoreLib!"); if (d->sig != NULL) { @@ -136,13 +136,13 @@ MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id) #endif } -NOINLINE FieldDesc * MscorlibBinder::LookupField(BinderFieldID id) +NOINLINE FieldDesc * CoreLibBinder::LookupField(BinderFieldID id) { WRAPPER_NO_CONTRACT; - return (&g_Mscorlib)->LookupFieldLocal(id); + return (&g_CoreLib)->LookupFieldLocal(id); } -FieldDesc * MscorlibBinder::GetFieldLocal(BinderFieldID id) +FieldDesc * CoreLibBinder::GetFieldLocal(BinderFieldID id) { WRAPPER_NO_CONTRACT; @@ -152,7 +152,7 @@ FieldDesc * MscorlibBinder::GetFieldLocal(BinderFieldID id) return pFD; } -FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id) +FieldDesc * CoreLibBinder::LookupFieldLocal(BinderFieldID id) { CONTRACTL { @@ -167,7 +167,7 @@ FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id) FieldDesc * pFD = NULL; - const MscorlibFieldDescription *d = m_fieldDescriptions + (id - 1); + const CoreLibFieldDescription *d = m_fieldDescriptions + (id - 1); MethodTable * pMT = GetClassLocal(d->classID); @@ -182,7 +182,7 @@ FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id) return pFD; } -NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id) +NOINLINE PTR_MethodTable CoreLibBinder::LookupClassIfExist(BinderClassID id) { CONTRACTL { @@ -192,18 +192,18 @@ NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id) MODE_ANY; PRECONDITION(id != CLASS__NIL); - PRECONDITION(id <= (&g_Mscorlib)->m_cClasses); + PRECONDITION(id <= (&g_CoreLib)->m_cClasses); } CONTRACTL_END; // Run the class loader in non-load mode. ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE(); - // Binder methods are used for loading "known" types from mscorlib.dll. Thus they are unlikely to be part + // Binder methods are used for loading "known" types. Thus they are unlikely to be part // of a recursive cycle. This is used too broadly to force manual overrides at every callsite. OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - const MscorlibClassDescription *d = (&g_Mscorlib)->m_classDescriptions + (int)id; + const CoreLibClassDescription *d = (&g_CoreLib)->m_classDescriptions + (int)id; PTR_MethodTable pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name, ClassLoader::ReturnNullIfNotFound, ClassLoader::DontLoadTypes, CLASS_LOAD_UNRESTOREDTYPEKEY).AsMethodTable(); @@ -212,13 +212,13 @@ NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id) #ifndef DACCESS_COMPILE if ((pMT != NULL) && pMT->IsFullyLoaded()) - VolatileStore(&(g_Mscorlib.m_pClasses[id]), pMT); + VolatileStore(&(g_CoreLib.m_pClasses[id]), pMT); #endif return pMT; } -Signature MscorlibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig) +Signature CoreLibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig) { CONTRACTL { @@ -245,10 +245,10 @@ Signature MscorlibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig) } #endif - return (&g_Mscorlib)->GetSignatureLocal(pHardcodedSig); + return (&g_CoreLib)->GetSignatureLocal(pHardcodedSig); } -Signature MscorlibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig) +Signature CoreLibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig) { CONTRACTL { @@ -262,12 +262,12 @@ Signature MscorlibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig) #ifdef CROSSGEN_COMPILE return GetModule()->m_pBinder->GetSignatureLocal(pHardcodedSig); #else - return (&g_Mscorlib)->GetSignatureLocal(pHardcodedSig); + return (&g_CoreLib)->GetSignatureLocal(pHardcodedSig); #endif } // Get the metasig, do a one-time conversion if necessary -Signature MscorlibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig) +Signature CoreLibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig) { CONTRACTL { @@ -311,7 +311,7 @@ Signature MscorlibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig) #ifndef DACCESS_COMPILE -bool MscorlibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder) +bool CoreLibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder) { bool bSomethingResolved = false; @@ -389,7 +389,7 @@ bool MscorlibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder) // Resolve type references in the hardcoded metasig. // Returns a new signature with type refences resolved. //------------------------------------------------------------------ -void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSigBuilder) +void CoreLibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSigBuilder) { CONTRACTL { @@ -427,7 +427,7 @@ void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSig _ASSERTE(bSomethingResolved); } -const BYTE* MscorlibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig) +const BYTE* CoreLibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig) { CONTRACTL { @@ -469,7 +469,7 @@ const BYTE* MscorlibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, c #endif // #ifndef DACCESS_COMPILE #ifdef _DEBUG -void MscorlibBinder::TriggerGCUnderStress() +void CoreLibBinder::TriggerGCUnderStress() { CONTRACTL { @@ -498,7 +498,7 @@ void MscorlibBinder::TriggerGCUnderStress() } #endif // _DEBUG -DWORD MscorlibBinder::GetFieldOffset(BinderFieldID id) +DWORD CoreLibBinder::GetFieldOffset(BinderFieldID id) { WRAPPER_NO_CONTRACT; @@ -507,10 +507,10 @@ DWORD MscorlibBinder::GetFieldOffset(BinderFieldID id) #ifndef DACCESS_COMPILE -CrstStatic MscorlibBinder::s_SigConvertCrst; +CrstStatic CoreLibBinder::s_SigConvertCrst; /*static*/ -void MscorlibBinder::Startup() +void CoreLibBinder::Startup() { WRAPPER_NO_CONTRACT s_SigConvertCrst.Init(CrstSigConvert); @@ -521,20 +521,20 @@ void MscorlibBinder::Startup() // NoClass is used to suppress check for unmanaged and managed size match #define NoClass char[USHRT_MAX] -const MscorlibBinder::OffsetAndSizeCheck MscorlibBinder::OffsetsAndSizes[] = +const CoreLibBinder::OffsetAndSizeCheck CoreLibBinder::OffsetsAndSizes[] = { #define DEFINE_CLASS_U(nameSpace, stringName, unmanagedType) \ { PTR_CSTR((TADDR) g_ ## nameSpace ## NS ), PTR_CUTF8((TADDR) # stringName), sizeof(unmanagedType), 0, 0, 0 }, #define DEFINE_FIELD_U(stringName, unmanagedContainingType, unmanagedOffset) \ { 0, 0, 0, PTR_CUTF8((TADDR) # stringName), offsetof(unmanagedContainingType, unmanagedOffset), sizeof(((unmanagedContainingType*)1)->unmanagedOffset) }, - #include "mscorlib.h" + #include "corelib.h" }; // -// check the basic consistency between mscorlib and mscorwks +// check the basic consistency between CoreLib and VM // -void MscorlibBinder::Check() +void CoreLibBinder::Check() { STANDARD_VM_CONTRACT; @@ -566,7 +566,7 @@ void MscorlibBinder::Check() else if (p->fieldName != NULL) { - // This assert will fire if there is DEFINE_FIELD_U macro without preceeding DEFINE_CLASS_U macro in mscorlib.h + // This assert will fire if there is DEFINE_FIELD_U macro without preceeding DEFINE_CLASS_U macro in corelib.h _ASSERTE(pMT != NULL); FieldDesc * pFD = MemberLoader::FindField(pMT, p->fieldName, NULL, 0, NULL); @@ -876,32 +876,32 @@ static void FCallCheckSignature(MethodDesc* pMD, PCODE pImpl) #endif // CHECK_FCALL_SIGNATURE // -// extended check of consistency between mscorlib and mscorwks: -// - verifies that all references from mscorlib to mscorwks are present -// - verifies that all references from mscorwks to mscorlib are present +// extended check of consistency between CoreLib and VM: +// - verifies that all references from CoreLib to VM are present +// - verifies that all references from VM to CoreLib are present // - limited detection of mismatches between managed and unmanaged fcall signatures // -void MscorlibBinder::CheckExtended() +void CoreLibBinder::CheckExtended() { STANDARD_VM_CONTRACT; - // check the consistency of BCL and VM + // check the consistency of CoreLib and VM // note: it is not enabled by default because of it is time consuming and // changes the bootstrap sequence of the EE if (!CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ConsistencyCheck)) return; // - // VM referencing BCL (mscorlib.h) + // VM referencing CoreLib (corelib.h) // for (BinderClassID cID = (BinderClassID) 1; (int)cID < m_cClasses; cID = (BinderClassID) (cID + 1)) { bool fError = false; EX_TRY { - if (MscorlibBinder::GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes + if (CoreLibBinder::GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes { - if (NULL == MscorlibBinder::GetClass(cID)) + if (NULL == CoreLibBinder::GetClass(cID)) { fError = true; } @@ -915,17 +915,17 @@ void MscorlibBinder::CheckExtended() if (fError) { - printf("CheckExtended: VM expects type to exist: %s.%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID)); + printf("CheckExtended: VM expects type to exist: %s.%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID)); } } - for (BinderMethodID mID = (BinderMethodID) 1; mID < (BinderMethodID) MscorlibBinder::m_cMethods; mID = (BinderMethodID) (mID + 1)) + for (BinderMethodID mID = (BinderMethodID) 1; mID < (BinderMethodID) CoreLibBinder::m_cMethods; mID = (BinderMethodID) (mID + 1)) { bool fError = false; BinderClassID cID = m_methodDescriptions[mID-1].classID; EX_TRY { - if (NULL == MscorlibBinder::GetMethod(mID)) + if (NULL == CoreLibBinder::GetMethod(mID)) { fError = true; } @@ -938,17 +938,17 @@ void MscorlibBinder::CheckExtended() if (fError) { - printf("CheckExtended: VM expects method to exist: %s.%s::%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID), MscorlibBinder::GetMethodName(mID)); + printf("CheckExtended: VM expects method to exist: %s.%s::%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID), CoreLibBinder::GetMethodName(mID)); } } - for (BinderFieldID fID = (BinderFieldID) 1; fID < (BinderFieldID) MscorlibBinder::m_cFields; fID = (BinderFieldID) (fID + 1)) + for (BinderFieldID fID = (BinderFieldID) 1; fID < (BinderFieldID) CoreLibBinder::m_cFields; fID = (BinderFieldID) (fID + 1)) { bool fError = false; BinderClassID cID = m_fieldDescriptions[fID-1].classID; EX_TRY { - if (NULL == MscorlibBinder::GetField(fID)) + if (NULL == CoreLibBinder::GetField(fID)) { fError = true; } @@ -961,17 +961,17 @@ void MscorlibBinder::CheckExtended() if (fError) { - printf("CheckExtended: VM expects field to exist: %s.%s::%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID), MscorlibBinder::GetFieldName(fID)); + printf("CheckExtended: VM expects field to exist: %s.%s::%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID), CoreLibBinder::GetFieldName(fID)); } } // - // BCL referencing VM (ecall.cpp) + // CoreLib referencing VM (ecalllist.h) // SetSHash usedECallIds; HRESULT hr = S_OK; - Module *pModule = MscorlibBinder::m_pModule; + Module *pModule = CoreLibBinder::m_pModule; IMDInternalImport *pInternalImport = pModule->GetMDImport(); HENUMInternal hEnum; @@ -1014,7 +1014,7 @@ void MscorlibBinder::CheckExtended() { pszClassName = pszNameSpace = "Invalid TypeDef record"; } - printf("CheckExtended: Unable to load class from mscorlib: %s.%s\n", pszNameSpace, pszClassName); + printf("CheckExtended: Unable to load class from System.Private.CoreLib: %s.%s\n", pszNameSpace, pszClassName); } EX_END_CATCH(SwallowAllExceptions) @@ -1099,7 +1099,7 @@ void MscorlibBinder::CheckExtended() #define ASMCONSTANTS_RUNTIME_ASSERT(cond) _ASSERTE(cond) #include "asmconstants.h" - _ASSERTE(sizeof(VARIANT) == MscorlibBinder::GetClass(CLASS__NATIVEVARIANT)->GetNativeSize()); + _ASSERTE(sizeof(VARIANT) == CoreLibBinder::GetClass(CLASS__NATIVEVARIANT)->GetNativeSize()); printf("CheckExtended: completed without exception.\n"); @@ -1109,45 +1109,45 @@ void MscorlibBinder::CheckExtended() #endif // _DEBUG && !CROSSGEN_COMPILE -extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[]; -extern const USHORT c_nMscorlibClassDescriptions; +extern const CoreLibClassDescription c_rgCoreLibClassDescriptions[]; +extern const USHORT c_nCoreLibClassDescriptions; -extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[]; -extern const USHORT c_nMscorlibMethodDescriptions; +extern const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[]; +extern const USHORT c_nCoreLibMethodDescriptions; -extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[]; -extern const USHORT c_nMscorlibFieldDescriptions; +extern const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[]; +extern const USHORT c_nCoreLibFieldDescriptions; #ifdef CROSSGEN_COMPILE -namespace CrossGenMscorlib +namespace CrossGenCoreLib { - extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[]; - extern const USHORT c_nMscorlibClassDescriptions; + extern const CoreLibClassDescription c_rgCoreLibClassDescriptions[]; + extern const USHORT c_nCoreLibClassDescriptions; - extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[]; - extern const USHORT c_nMscorlibMethodDescriptions; + extern const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[]; + extern const USHORT c_nCoreLibMethodDescriptions; - extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[]; - extern const USHORT c_nMscorlibFieldDescriptions; + extern const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[]; + extern const USHORT c_nCoreLibFieldDescriptions; }; #endif -void MscorlibBinder::AttachModule(Module * pModule) +void CoreLibBinder::AttachModule(Module * pModule) { STANDARD_VM_CONTRACT; - MscorlibBinder * pGlobalBinder = &g_Mscorlib; + CoreLibBinder * pGlobalBinder = &g_CoreLib; pGlobalBinder->SetDescriptions(pModule, - c_rgMscorlibClassDescriptions, c_nMscorlibClassDescriptions, - c_rgMscorlibMethodDescriptions, c_nMscorlibMethodDescriptions, - c_rgMscorlibFieldDescriptions, c_nMscorlibFieldDescriptions); + c_rgCoreLibClassDescriptions, c_nCoreLibClassDescriptions, + c_rgCoreLibMethodDescriptions, c_nCoreLibMethodDescriptions, + c_rgCoreLibFieldDescriptions, c_nCoreLibFieldDescriptions); #if defined(FEATURE_PREJIT) && !defined(CROSSGEN_COMPILE) - MscorlibBinder * pPersistedBinder = pModule->m_pBinder; + CoreLibBinder * pPersistedBinder = pModule->m_pBinder; if (pPersistedBinder != NULL - // Do not use persisted binder for profiling native images. See comment in code:MscorlibBinder::Fixup. + // Do not use persisted binder for profiling native images. See comment in code:CoreLibBinder::Fixup. && !(pModule->GetNativeImage()->GetNativeVersionInfo()->wConfigFlags & CORCOMPILE_CONFIG_PROFILING)) { pGlobalBinder->m_pClasses = pPersistedBinder->m_pClasses; @@ -1162,14 +1162,14 @@ void MscorlibBinder::AttachModule(Module * pModule) pGlobalBinder->AllocateTables(); #ifdef CROSSGEN_COMPILE - MscorlibBinder * pTargetBinder = (MscorlibBinder *)(void *) + CoreLibBinder * pTargetBinder = (CoreLibBinder *)(void *) pModule->GetAssembly()->GetLowFrequencyHeap() - ->AllocMem(S_SIZE_T(sizeof(MscorlibBinder))); + ->AllocMem(S_SIZE_T(sizeof(CoreLibBinder))); pTargetBinder->SetDescriptions(pModule, - CrossGenMscorlib::c_rgMscorlibClassDescriptions, CrossGenMscorlib::c_nMscorlibClassDescriptions, - CrossGenMscorlib::c_rgMscorlibMethodDescriptions, CrossGenMscorlib::c_nMscorlibMethodDescriptions, - CrossGenMscorlib::c_rgMscorlibFieldDescriptions, CrossGenMscorlib::c_nMscorlibFieldDescriptions); + CrossGenCoreLib::c_rgCoreLibClassDescriptions, CrossGenCoreLib::c_nCoreLibClassDescriptions, + CrossGenCoreLib::c_rgCoreLibMethodDescriptions, CrossGenCoreLib::c_nCoreLibMethodDescriptions, + CrossGenCoreLib::c_rgCoreLibFieldDescriptions, CrossGenCoreLib::c_nCoreLibFieldDescriptions); pTargetBinder->AllocateTables(); @@ -1179,10 +1179,10 @@ void MscorlibBinder::AttachModule(Module * pModule) #endif } -void MscorlibBinder::SetDescriptions(Module * pModule, - const MscorlibClassDescription * pClassDescriptions, USHORT nClasses, - const MscorlibMethodDescription * pMethodDescriptions, USHORT nMethods, - const MscorlibFieldDescription * pFieldDescriptions, USHORT nFields) +void CoreLibBinder::SetDescriptions(Module * pModule, + const CoreLibClassDescription * pClassDescriptions, USHORT nClasses, + const CoreLibMethodDescription * pMethodDescriptions, USHORT nMethods, + const CoreLibFieldDescription * pFieldDescriptions, USHORT nFields) { LIMITED_METHOD_CONTRACT; @@ -1198,7 +1198,7 @@ void MscorlibBinder::SetDescriptions(Module * pModule, m_cFields = nFields; } -void MscorlibBinder::AllocateTables() +void CoreLibBinder::AllocateTables() { STANDARD_VM_CONTRACT; @@ -1220,20 +1220,20 @@ void MscorlibBinder::AllocateTables() // ZeroMemory(m_pFields, m_cFieldRIDs * sizeof(*m_pFields)); } -PTR_MethodTable MscorlibBinder::LoadPrimitiveType(CorElementType et) +PTR_MethodTable CoreLibBinder::LoadPrimitiveType(CorElementType et) { STANDARD_VM_CONTRACT; - PTR_MethodTable pMT = g_Mscorlib.m_pClasses[et]; + PTR_MethodTable pMT = g_CoreLib.m_pClasses[et]; // Primitive types hit cyclic reference on binder during type loading so we have to load them in two steps if (pMT == NULL) { - const MscorlibClassDescription *d = (&g_Mscorlib)->m_classDescriptions + (int)et; + const CoreLibClassDescription *d = (&g_CoreLib)->m_classDescriptions + (int)et; pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name, ClassLoader::ThrowIfNotFound, ClassLoader::LoadTypes, CLASS_LOAD_APPROXPARENTS).AsMethodTable(); - g_Mscorlib.m_pClasses[et] = pMT; + g_CoreLib.m_pClasses[et] = pMT; ClassLoader::EnsureLoaded(pMT); } @@ -1242,7 +1242,7 @@ PTR_MethodTable MscorlibBinder::LoadPrimitiveType(CorElementType et) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION -void MscorlibBinder::BindAll() +void CoreLibBinder::BindAll() { STANDARD_VM_CONTRACT; @@ -1259,11 +1259,11 @@ void MscorlibBinder::BindAll() GetFieldLocal(fID); } -void MscorlibBinder::Save(DataImage *image) +void CoreLibBinder::Save(DataImage *image) { STANDARD_VM_CONTRACT; - image->StoreStructure(this, sizeof(MscorlibBinder), + image->StoreStructure(this, sizeof(CoreLibBinder), DataImage::ITEM_BINDER); image->StoreStructure(m_pClasses, m_cClasses * sizeof(*m_pClasses), @@ -1276,15 +1276,15 @@ void MscorlibBinder::Save(DataImage *image) DataImage::ITEM_BINDER_ITEMS); } -void MscorlibBinder::Fixup(DataImage *image) +void CoreLibBinder::Fixup(DataImage *image) { STANDARD_VM_CONTRACT; - image->FixupPointerField(this, offsetof(MscorlibBinder, m_pModule)); + image->FixupPointerField(this, offsetof(CoreLibBinder, m_pModule)); int i; - image->FixupPointerField(this, offsetof(MscorlibBinder, m_pClasses)); + image->FixupPointerField(this, offsetof(CoreLibBinder, m_pClasses)); for (i = 1; i < m_cClasses; i++) { #if _DEBUG @@ -1304,7 +1304,7 @@ void MscorlibBinder::Fixup(DataImage *image) image->FixupPointerField(m_pClasses, i * sizeof(m_pClasses[0])); } - image->FixupPointerField(this, offsetof(MscorlibBinder, m_pMethods)); + image->FixupPointerField(this, offsetof(CoreLibBinder, m_pMethods)); for (i = 1; i < m_cMethods; i++) { #if _DEBUG @@ -1318,15 +1318,15 @@ void MscorlibBinder::Fixup(DataImage *image) image->FixupPointerField(m_pMethods, i * sizeof(m_pMethods[0])); } - image->FixupPointerField(this, offsetof(MscorlibBinder, m_pFields)); + image->FixupPointerField(this, offsetof(CoreLibBinder, m_pFields)); for (i = 1; i < m_cFields; i++) { image->FixupPointerField(m_pFields, i * sizeof(m_pFields[0])); } - image->ZeroPointerField(this, offsetof(MscorlibBinder, m_classDescriptions)); - image->ZeroPointerField(this, offsetof(MscorlibBinder, m_methodDescriptions)); - image->ZeroPointerField(this, offsetof(MscorlibBinder, m_fieldDescriptions)); + image->ZeroPointerField(this, offsetof(CoreLibBinder, m_classDescriptions)); + image->ZeroPointerField(this, offsetof(CoreLibBinder, m_methodDescriptions)); + image->ZeroPointerField(this, offsetof(CoreLibBinder, m_fieldDescriptions)); } #endif // FEATURE_NATIVE_IMAGE_GENERATION @@ -1335,17 +1335,17 @@ void MscorlibBinder::Fixup(DataImage *image) #ifdef DACCESS_COMPILE void -MscorlibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) +CoreLibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) { SUPPORTS_DAC; DAC_ENUM_DTHIS(); DacEnumMemoryRegion(dac_cast(m_classDescriptions), - m_cClasses * sizeof(MscorlibClassDescription)); + m_cClasses * sizeof(CoreLibClassDescription)); DacEnumMemoryRegion(dac_cast(m_methodDescriptions), - (m_cMethods - 1) * sizeof(MscorlibMethodDescription)); + (m_cMethods - 1) * sizeof(CoreLibMethodDescription)); DacEnumMemoryRegion(dac_cast(m_fieldDescriptions), - (m_cFields - 1) * sizeof(MscorlibFieldDescription)); + (m_cFields - 1) * sizeof(CoreLibFieldDescription)); if (m_pModule.IsValid()) { @@ -1362,4 +1362,4 @@ MscorlibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) #endif // #ifdef DACCESS_COMPILE -GVAL_IMPL(MscorlibBinder, g_Mscorlib); +GVAL_IMPL(CoreLibBinder, g_CoreLib); diff --git a/src/coreclr/src/vm/binder.h b/src/coreclr/src/vm/binder.h index 24db64e33fd1..4ff115d2b557 100644 --- a/src/coreclr/src/vm/binder.h +++ b/src/coreclr/src/vm/binder.h @@ -33,7 +33,7 @@ struct HardCodedMetaSig // Use the Binder objects to avoid doing unnecessary name lookup // (esp. in the prejit case) // -// E.g. MscorlibBinder::GetClass(CLASS__APP_DOMAIN); +// E.g. CoreLibBinder::GetClass(CLASS__APP_DOMAIN); // // BinderClassIDs are of the form CLASS__XXX @@ -45,9 +45,9 @@ enum BinderClassID #undef TYPEINFO #define DEFINE_CLASS(i,n,s) CLASS__ ## i, -#include "mscorlib.h" +#include "corelib.h" - CLASS__MSCORLIB_COUNT, + CLASS__CORELIB_COUNT, // Aliases for element type classids CLASS__NIL = CLASS__ELEMENT_TYPE_END, @@ -80,9 +80,9 @@ enum BinderMethodID : int METHOD__NIL = 0, #define DEFINE_METHOD(c,i,s,g) METHOD__ ## c ## __ ## i, -#include "mscorlib.h" +#include "corelib.h" - METHOD__MSCORLIB_COUNT, + METHOD__CORELIB_COUNT, }; // BinderFieldIDs are of the form FIELD__XXX__YYY, @@ -93,31 +93,31 @@ enum BinderFieldID FIELD__NIL = 0, #define DEFINE_FIELD(c,i,s) FIELD__ ## c ## __ ## i, -#include "mscorlib.h" +#include "corelib.h" - FIELD__MSCORLIB_COUNT, + FIELD__CORELIB_COUNT, }; -struct MscorlibClassDescription +struct CoreLibClassDescription { PTR_CSTR nameSpace; PTR_CSTR name; }; -struct MscorlibMethodDescription +struct CoreLibMethodDescription { BinderClassID classID; PTR_CSTR name; PTR_HARDCODEDMETASIG sig; }; -struct MscorlibFieldDescription +struct CoreLibFieldDescription { BinderClassID classID; PTR_CSTR name; }; -class MscorlibBinder +class CoreLibBinder { public: #ifdef DACCESS_COMPILE @@ -134,7 +134,7 @@ class MscorlibBinder // // Retrieve structures from ID. // - // Note that none of the MscorlibBinder methods trigger static + // Note that none of the CoreLibBinder methods trigger static // constructors. The JITed code takes care of triggering them. // static PTR_MethodTable GetClass(BinderClassID id); @@ -189,24 +189,24 @@ class MscorlibBinder static MethodTable *GetException(RuntimeExceptionKind kind) { WRAPPER_NO_CONTRACT; - _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib. - BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT); + _ASSERTE(kind < kLastException); + BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT); return GetClass(id); } static BOOL IsException(MethodTable *pMT, RuntimeExceptionKind kind) { WRAPPER_NO_CONTRACT; - _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib. - BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT); + _ASSERTE(kind < kLastException); + BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT); return dac_cast(GetClassIfExist(id)) == dac_cast(pMT); } static LPCUTF8 GetExceptionName(RuntimeExceptionKind kind) { WRAPPER_NO_CONTRACT; - _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib. - BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT); + _ASSERTE(kind < kLastException); + BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT); return GetClassName(id); } @@ -281,9 +281,9 @@ class MscorlibBinder const BYTE* ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig); void SetDescriptions(Module * pModule, - const MscorlibClassDescription * pClassDescriptions, USHORT nClasses, - const MscorlibMethodDescription * pMethodDescriptions, USHORT nMethods, - const MscorlibFieldDescription * pFieldDescriptions, USHORT nFields); + const CoreLibClassDescription * pClassDescriptions, USHORT nClasses, + const CoreLibMethodDescription * pMethodDescriptions, USHORT nMethods, + const CoreLibFieldDescription * pFieldDescriptions, USHORT nFields); void AllocateTables(); @@ -298,9 +298,9 @@ class MscorlibBinder DPTR(PTR_FieldDesc) m_pFields; // This is necessary to avoid embeding copy of the descriptions into mscordacwks - DPTR(const MscorlibClassDescription) m_classDescriptions; - DPTR(const MscorlibMethodDescription) m_methodDescriptions; - DPTR(const MscorlibFieldDescription) m_fieldDescriptions; + DPTR(const CoreLibClassDescription) m_classDescriptions; + DPTR(const CoreLibMethodDescription) m_methodDescriptions; + DPTR(const CoreLibFieldDescription) m_fieldDescriptions; USHORT m_cClasses; USHORT m_cMethods; @@ -330,9 +330,9 @@ class MscorlibBinder // Global bound modules: // -GVAL_DECL(MscorlibBinder, g_Mscorlib); +GVAL_DECL(CoreLibBinder, g_CoreLib); -FORCEINLINE PTR_MethodTable MscorlibBinder::GetClass(BinderClassID id) +FORCEINLINE PTR_MethodTable CoreLibBinder::GetClass(BinderClassID id) { CONTRACTL { @@ -341,21 +341,21 @@ FORCEINLINE PTR_MethodTable MscorlibBinder::GetClass(BinderClassID id) INJECT_FAULT(ThrowOutOfMemory()); PRECONDITION(id != CLASS__NIL); - PRECONDITION((&g_Mscorlib)->m_cClasses > 0); // Make sure mscorlib has been loaded. - PRECONDITION(id <= (&g_Mscorlib)->m_cClasses); + PRECONDITION((&g_CoreLib)->m_cClasses > 0); // Make sure CoreLib has been loaded. + PRECONDITION(id <= (&g_CoreLib)->m_cClasses); } CONTRACTL_END; // Force a GC here under stress because type loading could trigger GC nondeterminsticly INDEBUG(TriggerGCUnderStress()); - PTR_MethodTable pMT = VolatileLoad(&((&g_Mscorlib)->m_pClasses[id])); + PTR_MethodTable pMT = VolatileLoad(&((&g_CoreLib)->m_pClasses[id])); if (pMT == NULL) return LookupClass(id); return pMT; } -FORCEINLINE MethodDesc * MscorlibBinder::GetMethod(BinderMethodID id) +FORCEINLINE MethodDesc * CoreLibBinder::GetMethod(BinderMethodID id) { CONTRACTL { @@ -364,20 +364,20 @@ FORCEINLINE MethodDesc * MscorlibBinder::GetMethod(BinderMethodID id) INJECT_FAULT(ThrowOutOfMemory()); PRECONDITION(id != METHOD__NIL); - PRECONDITION(id <= (&g_Mscorlib)->m_cMethods); + PRECONDITION(id <= (&g_CoreLib)->m_cMethods); } CONTRACTL_END; // Force a GC here under stress because type loading could trigger GC nondeterminsticly INDEBUG(TriggerGCUnderStress()); - MethodDesc * pMD = VolatileLoad(&((&g_Mscorlib)->m_pMethods[id])); + MethodDesc * pMD = VolatileLoad(&((&g_CoreLib)->m_pMethods[id])); if (pMD == NULL) return LookupMethod(id); return pMD; } -FORCEINLINE FieldDesc * MscorlibBinder::GetField(BinderFieldID id) +FORCEINLINE FieldDesc * CoreLibBinder::GetField(BinderFieldID id) { CONTRACTL { @@ -386,44 +386,44 @@ FORCEINLINE FieldDesc * MscorlibBinder::GetField(BinderFieldID id) INJECT_FAULT(ThrowOutOfMemory()); PRECONDITION(id != FIELD__NIL); - PRECONDITION(id <= (&g_Mscorlib)->m_cFields); + PRECONDITION(id <= (&g_CoreLib)->m_cFields); } CONTRACTL_END; // Force a GC here under stress because type loading could trigger GC nondeterminsticly INDEBUG(TriggerGCUnderStress()); - FieldDesc * pFD = VolatileLoad(&((&g_Mscorlib)->m_pFields[id])); + FieldDesc * pFD = VolatileLoad(&((&g_CoreLib)->m_pFields[id])); if (pFD == NULL) return LookupField(id); return pFD; } -FORCEINLINE PTR_MethodTable MscorlibBinder::GetExistingClass(BinderClassID id) +FORCEINLINE PTR_MethodTable CoreLibBinder::GetExistingClass(BinderClassID id) { LIMITED_METHOD_DAC_CONTRACT; - PTR_MethodTable pMT = (&g_Mscorlib)->m_pClasses[id]; + PTR_MethodTable pMT = (&g_CoreLib)->m_pClasses[id]; _ASSERTE(pMT != NULL); return pMT; } -FORCEINLINE MethodDesc * MscorlibBinder::GetExistingMethod(BinderMethodID id) +FORCEINLINE MethodDesc * CoreLibBinder::GetExistingMethod(BinderMethodID id) { LIMITED_METHOD_DAC_CONTRACT; - MethodDesc * pMD = (&g_Mscorlib)->m_pMethods[id]; + MethodDesc * pMD = (&g_CoreLib)->m_pMethods[id]; _ASSERTE(pMD != NULL); return pMD; } -FORCEINLINE FieldDesc * MscorlibBinder::GetExistingField(BinderFieldID id) +FORCEINLINE FieldDesc * CoreLibBinder::GetExistingField(BinderFieldID id) { LIMITED_METHOD_DAC_CONTRACT; - FieldDesc * pFD = (&g_Mscorlib)->m_pFields[id]; + FieldDesc * pFD = (&g_CoreLib)->m_pFields[id]; _ASSERTE(pFD != NULL); return pFD; } -FORCEINLINE PTR_MethodTable MscorlibBinder::GetClassIfExist(BinderClassID id) +FORCEINLINE PTR_MethodTable CoreLibBinder::GetClassIfExist(BinderClassID id) { CONTRACTL { @@ -433,68 +433,68 @@ FORCEINLINE PTR_MethodTable MscorlibBinder::GetClassIfExist(BinderClassID id) MODE_ANY; PRECONDITION(id != CLASS__NIL); - PRECONDITION(id <= (&g_Mscorlib)->m_cClasses); + PRECONDITION(id <= (&g_CoreLib)->m_cClasses); } CONTRACTL_END; - PTR_MethodTable pMT = VolatileLoad(&((&g_Mscorlib)->m_pClasses[id])); + PTR_MethodTable pMT = VolatileLoad(&((&g_CoreLib)->m_pClasses[id])); if (pMT == NULL) return LookupClassIfExist(id); return pMT; } -FORCEINLINE PTR_Module MscorlibBinder::GetModule() +FORCEINLINE PTR_Module CoreLibBinder::GetModule() { LIMITED_METHOD_DAC_CONTRACT; - PTR_Module pModule = (&g_Mscorlib)->m_pModule; + PTR_Module pModule = (&g_CoreLib)->m_pModule; _ASSERTE(pModule != NULL); return pModule; } -FORCEINLINE LPCUTF8 MscorlibBinder::GetClassNameSpace(BinderClassID id) +FORCEINLINE LPCUTF8 CoreLibBinder::GetClassNameSpace(BinderClassID id) { LIMITED_METHOD_CONTRACT; _ASSERTE(id != CLASS__NIL); - _ASSERTE(id <= (&g_Mscorlib)->m_cClasses); - return (&g_Mscorlib)->m_classDescriptions[id].nameSpace; + _ASSERTE(id <= (&g_CoreLib)->m_cClasses); + return (&g_CoreLib)->m_classDescriptions[id].nameSpace; } -FORCEINLINE LPCUTF8 MscorlibBinder::GetClassName(BinderClassID id) +FORCEINLINE LPCUTF8 CoreLibBinder::GetClassName(BinderClassID id) { LIMITED_METHOD_CONTRACT; _ASSERTE(id != CLASS__NIL); - _ASSERTE(id <= (&g_Mscorlib)->m_cClasses); - return (&g_Mscorlib)->m_classDescriptions[id].name; + _ASSERTE(id <= (&g_CoreLib)->m_cClasses); + return (&g_CoreLib)->m_classDescriptions[id].name; } -FORCEINLINE LPCUTF8 MscorlibBinder::GetMethodName(BinderMethodID id) +FORCEINLINE LPCUTF8 CoreLibBinder::GetMethodName(BinderMethodID id) { LIMITED_METHOD_CONTRACT; _ASSERTE(id != METHOD__NIL); - _ASSERTE(id <= (&g_Mscorlib)->m_cMethods); - return (&g_Mscorlib)->m_methodDescriptions[id-1].name; + _ASSERTE(id <= (&g_CoreLib)->m_cMethods); + return (&g_CoreLib)->m_methodDescriptions[id-1].name; } -FORCEINLINE LPHARDCODEDMETASIG MscorlibBinder::GetMethodSig(BinderMethodID id) +FORCEINLINE LPHARDCODEDMETASIG CoreLibBinder::GetMethodSig(BinderMethodID id) { LIMITED_METHOD_CONTRACT; _ASSERTE(id != METHOD__NIL); - _ASSERTE(id <= (&g_Mscorlib)->m_cMethods); - return (&g_Mscorlib)->m_methodDescriptions[id-1].sig; + _ASSERTE(id <= (&g_CoreLib)->m_cMethods); + return (&g_CoreLib)->m_methodDescriptions[id-1].sig; } -FORCEINLINE LPCUTF8 MscorlibBinder::GetFieldName(BinderFieldID id) +FORCEINLINE LPCUTF8 CoreLibBinder::GetFieldName(BinderFieldID id) { LIMITED_METHOD_CONTRACT; _ASSERTE(id != FIELD__NIL); - _ASSERTE(id <= (&g_Mscorlib)->m_cFields); - return (&g_Mscorlib)->m_fieldDescriptions[id-1].name; + _ASSERTE(id <= (&g_CoreLib)->m_cFields); + return (&g_CoreLib)->m_fieldDescriptions[id-1].name; } #endif // _BINDERMODULE_H_ diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 25e2cc44385e..910cc060f74a 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -285,11 +285,11 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT * _ASSERTE(!NingenEnabled() && "You cannot invoke managed code inside the ngen compilation process."); - // If we're invoking an mscorlib method, lift the restriction on type load limits. Calls into mscorlib are + // If we're invoking an CoreLib method, lift the restriction on type load limits. Calls into CoreLib are // typically calls into specific and controlled helper methods for security checks and other linktime tasks. // // @todo: In an ideal world, we would require each of those sites to do the override rather than disabling - // the assert broadly here. However, by limiting the override to mscorlib methods, we should still be able + // the assert broadly here. However, by limiting the override to CoreLib methods, we should still be able // to effectively enforce the more general rule about loader recursion. MAYBE_OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED, m_pMD->GetModule()->IsSystem()); diff --git a/src/coreclr/src/vm/callhelpers.h b/src/coreclr/src/vm/callhelpers.h index a2503f15bb10..4640413d2889 100644 --- a/src/coreclr/src/vm/callhelpers.h +++ b/src/coreclr/src/vm/callhelpers.h @@ -154,12 +154,12 @@ class MethodDescCallSite #endif public: - // Used to avoid touching metadata for mscorlib methods. + // Used to avoid touching metadata for CoreLib methods. // instance methods must pass in the 'this' object // static methods must pass null MethodDescCallSite(BinderMethodID id, OBJECTREF* porProtectedThis = NULL) : m_pMD( - MscorlibBinder::GetMethod(id) + CoreLibBinder::GetMethod(id) ), m_methodSig(id), m_argIt(&m_methodSig) @@ -174,12 +174,12 @@ class MethodDescCallSite DefaultInit(porProtectedThis); } - // Used to avoid touching metadata for mscorlib methods. + // Used to avoid touching metadata for CoreLib methods. // instance methods must pass in the 'this' object // static methods must pass null MethodDescCallSite(BinderMethodID id, OBJECTHANDLE hThis) : m_pMD( - MscorlibBinder::GetMethod(id) + CoreLibBinder::GetMethod(id) ), m_methodSig(id), m_argIt(&m_methodSig) @@ -558,14 +558,14 @@ enum DispatchCallSimpleFlags PCODE __pSlot = VolatileLoad(&s_pAddr##id); \ if ( __pSlot == NULL ) \ { \ - MethodDesc *pMeth = MscorlibBinder::GetMethod(id); \ + MethodDesc *pMeth = CoreLibBinder::GetMethod(id); \ _ASSERTE(pMeth); \ __pSlot = pMeth->GetMultiCallableAddrOfCode(); \ VolatileStore(&s_pAddr##id, __pSlot); \ } #define PREPARE_VIRTUAL_CALLSITE(id, objref) \ - MethodDesc *__pMeth = MscorlibBinder::GetMethod(id); \ + MethodDesc *__pMeth = CoreLibBinder::GetMethod(id); \ PCODE __pSlot = __pMeth->GetCallTarget(&objref); #define PREPARE_VIRTUAL_CALLSITE_USING_METHODDESC(pMD, objref) \ @@ -590,7 +590,7 @@ enum DispatchCallSimpleFlags WORD __slot = VolatileLoad(&s_slot##id); \ if (__slot == MethodTable::NO_SLOT) \ { \ - MethodDesc *pMeth = MscorlibBinder::GetMethod(id); \ + MethodDesc *pMeth = CoreLibBinder::GetMethod(id); \ _ASSERTE(pMeth); \ __slot = pMeth->GetSlot(); \ VolatileStore(&s_slot##id, __slot); \ diff --git a/src/coreclr/src/vm/callsiteinspect.cpp b/src/coreclr/src/vm/callsiteinspect.cpp index eeb9678e9655..3773580bd0a5 100644 --- a/src/coreclr/src/vm/callsiteinspect.cpp +++ b/src/coreclr/src/vm/callsiteinspect.cpp @@ -53,7 +53,7 @@ namespace if (ELEMENT_TYPE_PTR == eType) COMPlusThrow(kNotSupportedException); - MethodTable *pMT = MscorlibBinder::GetElementType(eType); + MethodTable *pMT = CoreLibBinder::GetElementType(eType); OBJECTREF pObj = pMT->Allocate(); if (fIsByRef) @@ -337,7 +337,7 @@ void CallsiteInspect::GetCallsiteArgs( // Allocate all needed arrays for callsite arg details gc.Args = (PTRARRAYREF)AllocateObjectArray(numArgs, g_pObjectClass); - MethodTable *typeMT = MscorlibBinder::GetClass(CLASS__TYPE); + MethodTable *typeMT = CoreLibBinder::GetClass(CLASS__TYPE); gc.ArgsTypes = (PTRARRAYREF)AllocateObjectArray(numArgs, typeMT); gc.ArgsIsByRef = (BOOLARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_BOOLEAN, numArgs); diff --git a/src/coreclr/src/vm/castcache.cpp b/src/coreclr/src/vm/castcache.cpp index b4a201626752..6613c6fe5c9b 100644 --- a/src/coreclr/src/vm/castcache.cpp +++ b/src/coreclr/src/vm/castcache.cpp @@ -124,7 +124,7 @@ void CastCache::Initialize() } CONTRACTL_END; - FieldDesc* pTableField = MscorlibBinder::GetField(FIELD__CASTHELPERS__TABLE); + FieldDesc* pTableField = CoreLibBinder::GetField(FIELD__CASTHELPERS__TABLE); GCX_COOP(); s_pTableRef = (BASEARRAYREF*)pTableField->GetCurrentStaticAddress(); diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 75d1f0bd0c2d..663c5a46ad2f 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -481,7 +481,7 @@ void Module::InitializeNativeImage(AllocMemTracker* pamTracker) if (GCStress::IsEnabled()) { // Setting up gc coverage requires the base system classes - // to be initialized. So we must defer this for mscorlib. + // to be initialized. So we must defer this for CoreLib. if(!IsSystem()) { SetupGcCoverageForNativeImage(this); @@ -1512,11 +1512,11 @@ static bool IsLikelyDependencyOf(Module * pModule, Module * pOtherModule) if (!pOtherModule->IsLowLevelSystemAssemblyByName()) return true; - // Every module depends upon mscorlib + // Every module depends upon CoreLib if (pModule->IsSystem()) return true; - // mscorlib does not depend upon any other module + // CoreLib does not depend upon any other module if (pOtherModule->IsSystem()) return false; } @@ -1526,7 +1526,7 @@ static bool IsLikelyDependencyOf(Module * pModule, Module * pOtherModule) return false; } - // At this point neither pModule or pOtherModule is mscorlib + // At this point neither pModule or pOtherModule is CoreLib #ifndef DACCESS_COMPILE // @@ -1591,8 +1591,8 @@ PTR_Module Module::ComputePreferredZapModuleHelper( RETURN dac_cast(pOpenModule); } - // The initial value of pCurrentPZM is the pDefinitionModule or mscorlib - Module* pCurrentPZM = (pDefinitionModule != NULL) ? pDefinitionModule : MscorlibBinder::GetModule(); + // The initial value of pCurrentPZM is the pDefinitionModule or CoreLib + Module* pCurrentPZM = (pDefinitionModule != NULL) ? pDefinitionModule : CoreLibBinder::GetModule(); bool preferredZapModuleBasedOnValueType = false; for (DWORD i = 0; i < totalArgs; i++) @@ -1626,7 +1626,7 @@ PTR_Module Module::ComputePreferredZapModuleHelper( // pCurrentPZM is a dependency of pParamPZM // and pParamPZM is not a dependency of pCurrentPZM // - // note that the second condition is alway true when pCurrentPZM is mscorlib + // note that the second condition is alway true when pCurrentPZM is CoreLib // if (!IsLikelyDependencyOf(pParamPZM, pCurrentPZM)) { @@ -2691,7 +2691,7 @@ ModuleIndex Module::AllocateModuleIndex() // For various reasons, the IDs issued by the IdDispenser start at 1. // Domain neutral module IDs have historically started at 0, and we - // have always assigned ID 0 to mscorlib. Thus, to make it so that + // have always assigned ID 0 to CoreLib. Thus, to make it so that // domain neutral module IDs start at 0, we will subtract 1 from the // ID that we got back from the ID dispenser. ModuleIndex index((SIZE_T)(val-1)); @@ -2861,7 +2861,7 @@ void Module::SetDomainFile(DomainFile *pDomainFile) m_ModuleID->SetDomainFile(pDomainFile); // Allocate static handles now. - // NOTE: Bootstrapping issue with mscorlib - we will manually allocate later + // NOTE: Bootstrapping issue with CoreLib - we will manually allocate later // If the assembly is collectible, we don't initialize static handles for them // as it is currently initialized through the DomainLocalModule::PopulateClass in MethodTable::CheckRunClassInitThrowing // (If we don't do this, it would allocate here unused regular static handles that will be overridden later) @@ -4207,10 +4207,10 @@ OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain, bool bNe } /* Unfortunately, this assert won't work in some cases of generics, consider the following scenario: - 1) Generic type in mscorlib. + 1) Generic type in CoreLib. 2) Instantiation of generic (1) (via valuetype) in another module 3) other module now holds a copy of the code of the generic for that particular instantiation - however, it is resolving the string literals against mscorlib, which breaks the invariant + however, it is resolving the string literals against CoreLib, which breaks the invariant this assert was based on (no string fixups against other modules). In fact, with NoStringInterning, our behavior is not very intuitive. */ @@ -4758,7 +4758,7 @@ DomainAssembly * Module::LoadAssembly(mdAssemblyRef kAssemblyRef) if (pDomainAssembly != NULL) { _ASSERTE( - pDomainAssembly->IsSystem() || // GetAssemblyIfLoaded will not find mscorlib (see AppDomain::FindCachedFile) + pDomainAssembly->IsSystem() || // GetAssemblyIfLoaded will not find CoreLib (see AppDomain::FindCachedFile) !pDomainAssembly->IsLoaded() || // GetAssemblyIfLoaded will not find not-yet-loaded assemblies GetAssemblyIfLoaded(kAssemblyRef, NULL, FALSE, pDomainAssembly->GetFile()->GetHostAssembly()) != NULL); // GetAssemblyIfLoaded should find all remaining cases diff --git a/src/coreclr/src/vm/ceeload.h b/src/coreclr/src/vm/ceeload.h index 27c4c8f485ff..b963624fb566 100644 --- a/src/coreclr/src/vm/ceeload.h +++ b/src/coreclr/src/vm/ceeload.h @@ -157,7 +157,7 @@ typedef DPTR(struct LookupMapBase) PTR_LookupMapBase; // // This still leaves the problem of runtime lookup performance. Touches to the cold section of a LookupMap // aren't all that critical (after all the data is meant to be cold), but looking up the last entry of a map -// with 22 thousand entries (roughly what the MethodDefToDesc map in mscorlib is sized at at the time of +// with 22 thousand entries (roughly what the MethodDefToDesc map in CoreLib is sized at at the time of // writing) is still likely to so inefficient as to be noticeable. Remember that the issue is that we have to // decode all predecessor entries in order to compute the value of a given entry in the table. // @@ -170,7 +170,7 @@ typedef DPTR(struct LookupMapBase) PTR_LookupMapBase; // // The main areas in which this algorithm can be tuned are the number of bits used as an index into the // encoding lengths table (kLookupMapLengthBits) and the frequency with which entries are bookmarked in the -// index (kLookupMapIndexStride). The current values have been set based on looking at models of mscorlib, +// index (kLookupMapIndexStride). The current values have been set based on looking at models of CoreLib, // PresentationCore and PresentationFramework built from the actual ridmap data in their ngen images and // methodically trying different values in order to maximize compression or balance size versus likely runtime // performance. An alternative strategy was considered using direct (non-length prefix) encoding of the @@ -1597,8 +1597,8 @@ class Module PTR_EEClassHashTable m_pAvailableClassesCaseIns; // Pointer to binder, if we have one - friend class MscorlibBinder; - PTR_MscorlibBinder m_pBinder; + friend class CoreLibBinder; + PTR_CoreLibBinder m_pBinder; public: BOOL IsCollectible() diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index d1212844c5cf..4da222caca08 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -283,8 +283,8 @@ HRESULT EnsureEEStarted() HRESULT hr = E_FAIL; - // On non x86 platforms, when we load mscorlib.dll during EEStartup, we will - // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for mscorlib.dll. We are + // On non x86 platforms, when we load CoreLib during EEStartup, we will + // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for CoreLib. We are // far enough in startup that this is allowed, however we don't want to // re-start the startup code so we need to check to see if startup has // been initiated or completed before we call EEStartup. @@ -824,7 +824,7 @@ void EEStartupHelper() AccessCheckOptions::Startup(); - MscorlibBinder::Startup(); + CoreLibBinder::Startup(); Stub::Init(); StubLinkerCPU::Init(); @@ -1030,8 +1030,8 @@ void EEStartupHelper() SystemDomain::SystemModule()->ExpandAll(); } - // Perform mscorlib consistency check if requested - g_Mscorlib.CheckExtended(); + // Perform CoreLib consistency check if requested + g_CoreLib.CheckExtended(); #endif // _DEBUG @@ -1107,7 +1107,7 @@ LONG FilterStartupException(PEXCEPTION_POINTERS p, PVOID pv) // EEStartup is responsible for all the one time intialization of the runtime. Some of the highlights of // what it does include // * Creates the default and shared, appdomains. -// * Loads mscorlib.dll and loads up the fundamental types (System.Object ...) +// * Loads System.Private.CoreLib and loads up the fundamental types (System.Object ...) // // see code:EEStartup#TableOfContents for more on the runtime in general. // see code:#EEShutdown for a analagous routine run during shutdown. diff --git a/src/coreclr/src/vm/cgensys.h b/src/coreclr/src/vm/cgensys.h index 53e21461304d..7c732316695e 100644 --- a/src/coreclr/src/vm/cgensys.h +++ b/src/coreclr/src/vm/cgensys.h @@ -143,7 +143,7 @@ BOOL GetAnyThunkTarget (T_CONTEXT *pctx, TADDR *pTarget, TADDR *pTargetMethodDes // // ResetProcessorStateHolder saves/restores processor state around calls to -// mscorlib during exception handling. +// CoreLib during exception handling. // class ResetProcessorStateHolder { diff --git a/src/coreclr/src/vm/classcompat.cpp b/src/coreclr/src/vm/classcompat.cpp index aab4e63d5ccc..4f00fbf94481 100644 --- a/src/coreclr/src/vm/classcompat.cpp +++ b/src/coreclr/src/vm/classcompat.cpp @@ -3010,49 +3010,6 @@ VOID MethodTableBuilder::AllocateMethodWorkingMemory() } bmtVT->pParentMethodTable = bmtParent->pParentMethodTable; } - -#if 0 - // @todo: Figure out the right way to override Equals for value - // types only. - // - // This is broken because - // (a) g_pObjectClass->FindMethod("Equals", &gsig_IM_Obj_RetBool); will return - // the EqualsValue method - // (b) When mscorlib has been preloaded (and thus the munge already done - // ahead of time), we cannot easily find both methods - // to compute EqualsAddr & EqualsSlot - // - // For now, the Equals method has a runtime check to see if it's - // comparing value types. - // - - // If it is a value type, over ride a few of the base class methods. - if (IsValueClass()) - { - static WORD EqualsSlot; - - // If we haven't been through here yet, get some stuff from the Object class definition. - if (EqualsSlot == NULL) - { - // Get the slot of the Equals method. - MethodDesc *pEqualsMD = g_pObjectClass->FindMethod("Equals", &gsig_IM_Obj_RetBool); - THROW_BAD_FORMAT_MAYBE(pEqualsMD != NULL, 0, this); - EqualsSlot = pEqualsMD->GetSlot(); - - // Get the address of the EqualsValue method. - MethodDesc *pEqualsValueMD = g_pObjectClass->FindMethod("EqualsValue", &gsig_IM_Obj_RetBool); - THROW_BAD_FORMAT_MAYBE(pEqualsValueMD != NULL, 0, this); - - // Patch the EqualsValue method desc in a dangerous way to - // look like the Equals method desc. - pEqualsValueMD->SetSlot(EqualsSlot); - pEqualsValueMD->SetMemberDef(pEqualsMD->GetMemberDef()); - } - - // Override the valuetype "Equals" with "EqualsValue". - bmtVT->SetMethodDescForSlot(EqualsSlot, EqualsSlot); - } -#endif // 0 } if (NumDeclaredMethods() > 0) diff --git a/src/coreclr/src/vm/classlayoutinfo.cpp b/src/coreclr/src/vm/classlayoutinfo.cpp index a9c932886a8b..e5f9345c8832 100644 --- a/src/coreclr/src/vm/classlayoutinfo.cpp +++ b/src/coreclr/src/vm/classlayoutinfo.cpp @@ -903,16 +903,16 @@ EEClassNativeLayoutInfo* EEClassNativeLayoutInfo::CollectNativeLayoutFieldMetada // from the managed size and alignment. // Crossgen scenarios block Vector from even being loaded, so only do this check when not in crossgen. #ifndef CROSSGEN_COMPILE - if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTORT))) + if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTORT))) { pNativeLayoutInfo->m_size = pEEClassLayoutInfo->GetManagedSize(); pNativeLayoutInfo->m_alignmentRequirement = pEEClassLayoutInfo->m_ManagedLargestAlignmentRequirementOfAllMembers; } else #endif - if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR64T)) || - pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR128T)) || - pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR256T))) + if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR64T)) || + pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR128T)) || + pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR256T))) { pNativeLayoutInfo->m_alignmentRequirement = pEEClassLayoutInfo->m_ManagedLargestAlignmentRequirementOfAllMembers; } diff --git a/src/coreclr/src/vm/clrex.cpp b/src/coreclr/src/vm/clrex.cpp index 0965a32c3dae..04a8d5b9be7d 100644 --- a/src/coreclr/src/vm/clrex.cpp +++ b/src/coreclr/src/vm/clrex.cpp @@ -189,7 +189,7 @@ OBJECTREF CLRException::GetThrowable() // CreateThrowable() and is being caught in this EX_TRY/EX_CATCH.) // If that exception is the same as the one for which this GetThrowable() // was called, we're in a recursive situation. - // Since the CreateThrowable() call should return a type from mscorlib, + // Since the CreateThrowable() call should return a type from CoreLib, // there really shouldn't be much opportunity for error. We could be // out of memory, we could overflow the stack, or the runtime could // be in a weird state(the thread could be aborted as well). @@ -1071,7 +1071,7 @@ void EEException::GetMessage(SString &result) return; // Otherwise, report the class's generic message - LPCUTF8 pszExceptionName = MscorlibBinder::GetExceptionName(m_kind); + LPCUTF8 pszExceptionName = CoreLibBinder::GetExceptionName(m_kind); result.SetUTF8(pszExceptionName); } @@ -1092,7 +1092,7 @@ OBJECTREF EEException::CreateThrowable() _ASSERTE(g_pPreallocatedOutOfMemoryException != NULL); static int allocCount = 0; - MethodTable *pMT = MscorlibBinder::GetException(m_kind); + MethodTable *pMT = CoreLibBinder::GetException(m_kind); ThreadPreventAsyncHolder preventAsyncHolder(m_kind == kThreadAbortException); @@ -1218,7 +1218,7 @@ void EEResourceException::GetMessage(SString &result) // result.Printf("%s (message resource %s)", - MscorlibBinder::GetExceptionName(m_kind), m_resourceName.GetUnicode()); + CoreLibBinder::GetExceptionName(m_kind), m_resourceName.GetUnicode()); } BOOL EEResourceException::GetThrowableMessage(SString &result) @@ -1420,7 +1420,7 @@ OBJECTREF EEArgumentException::CreateThrowable() ResMgrGetString(m_resourceName, &prot.s1); GCPROTECT_BEGIN(prot); - MethodTable *pMT = MscorlibBinder::GetException(m_kind); + MethodTable *pMT = CoreLibBinder::GetException(m_kind); prot.pThrowable = AllocateObject(pMT); MethodDesc* pMD = MemberLoader::FindMethod(prot.pThrowable->GetMethodTable(), @@ -1547,7 +1547,7 @@ OBJECTREF EETypeLoadException::CreateThrowable() } CONTRACTL_END; - MethodTable *pMT = MscorlibBinder::GetException(kTypeLoadException); + MethodTable *pMT = CoreLibBinder::GetException(kTypeLoadException); struct _gc { OBJECTREF pNewException; @@ -1752,7 +1752,7 @@ OBJECTREF EEFileLoadException::CreateThrowable() GCPROTECT_BEGIN(gc); gc.pNewFileString = StringObject::NewString(m_name); - gc.pNewException = AllocateObject(MscorlibBinder::GetException(m_kind)); + gc.pNewException = AllocateObject(CoreLibBinder::GetException(m_kind)); MethodDesc* pMD = MemberLoader::FindMethod(gc.pNewException->GetMethodTable(), COR_CTOR_METHOD_NAME, &gsig_IM_Str_Int_RetVoid); diff --git a/src/coreclr/src/vm/clsload.cpp b/src/coreclr/src/vm/clsload.cpp index 2b8165aa630f..01278d32f8f2 100644 --- a/src/coreclr/src/vm/clsload.cpp +++ b/src/coreclr/src/vm/clsload.cpp @@ -63,7 +63,7 @@ // Some useful effects of this rule (for ngen purposes) are: // // * G lives in the module defining G -// * non-mscorlib instantiations of mscorlib-defined generic types live in the module +// * non-CoreLib instantiations of CoreLib-defined generic types live in the module // of the instantiation (when only one module is invloved in the instantiation) // @@ -138,9 +138,9 @@ PTR_Module ClassLoader::ComputeLoaderModuleWorker( if (pLoaderModule == NULL) { - CONSISTENCY_CHECK(MscorlibBinder::GetModule() && MscorlibBinder::GetModule()->IsSystem()); + CONSISTENCY_CHECK(CoreLibBinder::GetModule() && CoreLibBinder::GetModule()->IsSystem()); - pLoaderModule = MscorlibBinder::GetModule(); + pLoaderModule = CoreLibBinder::GetModule(); } if (FALSE) @@ -250,7 +250,7 @@ PTR_Module ClassLoader::ComputeLoaderModuleForCompilation( // We're a little stuck - we can't force the item into an NGEN image at this point. So just bail out // and use the loader module we've computed without recording the choice. The loader module should always - // be mscorlib in this case. + // be CoreLib in this case. AppDomain * pAppDomain = GetAppDomain(); if (!pAppDomain->IsCompilationDomain() || !pAppDomain->ToCompilationDomain()->GetTargetModule()) @@ -3282,7 +3282,7 @@ TypeHandle ClassLoader::CreateTypeHandleForTypeKey(TypeKey* pKey, AllocMemTracke // let * type have a method table // System.UIntPtr's method table is used for types like int*, void *, string * etc. if (kind == ELEMENT_TYPE_PTR) - templateMT = MscorlibBinder::GetElementType(ELEMENT_TYPE_U); + templateMT = CoreLibBinder::GetElementType(ELEMENT_TYPE_U); else templateMT = NULL; diff --git a/src/coreclr/src/vm/comcallablewrapper.cpp b/src/coreclr/src/vm/comcallablewrapper.cpp index 6fca4a141d60..aa3068af22b7 100644 --- a/src/coreclr/src/vm/comcallablewrapper.cpp +++ b/src/coreclr/src/vm/comcallablewrapper.cpp @@ -1253,17 +1253,17 @@ BOOL SimpleComCallWrapper::SupportsIReflect(MethodTable *pClass) if (pClass == g_pRuntimeTypeClass) return FALSE; - if (MscorlibBinder::IsClass(pClass, CLASS__TYPE_BUILDER)) + if (CoreLibBinder::IsClass(pClass, CLASS__TYPE_BUILDER)) return FALSE; - if (MscorlibBinder::IsClass(pClass, CLASS__TYPE)) + if (CoreLibBinder::IsClass(pClass, CLASS__TYPE)) return FALSE; - if (MscorlibBinder::IsClass(pClass, CLASS__ENUM_BUILDER)) + if (CoreLibBinder::IsClass(pClass, CLASS__ENUM_BUILDER)) return FALSE; // Check to see if the MethodTable associated with the wrapper implements IExpando. - return pClass->ImplementsInterface(MscorlibBinder::GetClass(CLASS__IREFLECT)); + return pClass->ImplementsInterface(CoreLibBinder::GetClass(CLASS__IREFLECT)); } //-------------------------------------------------------------------------- @@ -1282,7 +1282,7 @@ BOOL SimpleComCallWrapper::SupportsIExpando(MethodTable *pClass) CONTRACTL_END; // Check to see if the MethodTable associated with the wrapper implements IExpando. - return pClass->ImplementsInterface(MscorlibBinder::GetClass(CLASS__IEXPANDO)); + return pClass->ImplementsInterface(CoreLibBinder::GetClass(CLASS__IEXPANDO)); } // NOINLINE to prevent RCWHolder from forcing caller to push/pop an FS:0 handler @@ -4480,11 +4480,11 @@ BOOL ComCallWrapperTemplate::IsSafeTypeForMarshalling() // System.Reflection.MethodBody, and System.Reflection.ParameterInfo. // Some interesting derived types that get blocked as a result are: // System.Type, System.Reflection.TypeInfo, System.Reflection.MethodInfo, and System.Reflection.FieldInfo - if (pMt->CanCastToClass(MscorlibBinder::GetClass(CLASS__ASSEMBLYBASE)) || - pMt->CanCastToClass(MscorlibBinder::GetClass(CLASS__MEMBER)) || - pMt->CanCastToClass(MscorlibBinder::GetClass(CLASS__MODULEBASE)) || - pMt->CanCastToClass(MscorlibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)) || - pMt->CanCastToClass(MscorlibBinder::GetClass(CLASS__PARAMETER))) + if (pMt->CanCastToClass(CoreLibBinder::GetClass(CLASS__ASSEMBLYBASE)) || + pMt->CanCastToClass(CoreLibBinder::GetClass(CLASS__MEMBER)) || + pMt->CanCastToClass(CoreLibBinder::GetClass(CLASS__MODULEBASE)) || + pMt->CanCastToClass(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)) || + pMt->CanCastToClass(CoreLibBinder::GetClass(CLASS__PARAMETER))) { isSafe = FALSE; } @@ -5040,7 +5040,7 @@ ComMethodTable *ComCallWrapperTemplate::InitializeForInterface(MethodTable *pPar // update pItfMT in case code:CreateComMethodTableForInterface decided to redirect the interface pItfMT = pItfComMT->GetMethodTable(); - if (pItfMT == MscorlibBinder::GetExistingClass(CLASS__ICUSTOM_QUERYINTERFACE)) + if (pItfMT == CoreLibBinder::GetExistingClass(CLASS__ICUSTOM_QUERYINTERFACE)) { m_flags |= enum_ImplementsICustomQueryInterface; } @@ -5152,7 +5152,7 @@ ComCallWrapperTemplate* ComCallWrapperTemplate::CreateTemplate(TypeHandle thClas // Eagerly create the interface CMTs. // when iterate the interfaces implemented by the methodtable, we can check whether // the interface supports ICustomQueryInterface. - MscorlibBinder::GetClass(CLASS__ICUSTOM_QUERYINTERFACE); + CoreLibBinder::GetClass(CLASS__ICUSTOM_QUERYINTERFACE); it.Reset(); while (it.Next()) @@ -5401,7 +5401,7 @@ MethodDesc * ComCallWrapperTemplate::GetICustomQueryInterfaceGetInterfaceMD() if (m_pICustomQueryInterfaceGetInterfaceMD == NULL) m_pICustomQueryInterfaceGetInterfaceMD = m_thClass.GetMethodTable()->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_QUERYINTERFACE__GET_INTERFACE), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_QUERYINTERFACE__GET_INTERFACE), TRUE /* throwOnConflict */); RETURN m_pICustomQueryInterfaceGetInterfaceMD; } diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 625513bf9cd3..9c5b48cc8ce7 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -2197,7 +2197,7 @@ FCIMPL1(PCODE, COMDelegate::GetMulticastInvoke, Object* refThisIn) // Get count of delegates pCode->EmitLoadThis(); - pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_COUNT))); + pCode->EmitLDFLD(pCode->GetToken(CoreLibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_COUNT))); pCode->EmitSTLOC(dwInvocationCountNum); // initialize counter @@ -2220,7 +2220,7 @@ FCIMPL1(PCODE, COMDelegate::GetMulticastInvoke, Object* refThisIn) // Load next delegate from array using LoopCounter as index pCode->EmitLoadThis(); - pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST))); + pCode->EmitLDFLD(pCode->GetToken(CoreLibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST))); pCode->EmitLDLOC(dwLoopCounterNum); pCode->EmitLDELEM_REF(); @@ -2371,7 +2371,7 @@ PCODE COMDelegate::GetWrapperInvoke(MethodDesc* pMD) // Load the "real" delegate pCode->EmitLoadThis(); - pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST))); + pCode->EmitLDFLD(pCode->GetToken(CoreLibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST))); // Load the arguments UINT paramCount = 0; @@ -2955,17 +2955,17 @@ MethodDesc* COMDelegate::GetDelegateCtor(TypeHandle delegateType, MethodDesc *pT { // case 3 if (isCollectible) - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_VIRTUAL_DISPATCH); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_VIRTUAL_DISPATCH); else - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_VIRTUAL_DISPATCH); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_VIRTUAL_DISPATCH); } else { // case 2, 6 if (isCollectible) - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_OPENED); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_OPENED); else - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_OPENED); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_OPENED); } Stub *pShuffleThunk = NULL; if (!pTargetMethod->IsStatic() && pTargetMethod->HasRetBuffArg() && IsRetBuffPassedAsFirstArg()) @@ -3000,21 +3000,21 @@ MethodDesc* COMDelegate::GetDelegateCtor(TypeHandle delegateType, MethodDesc *pT pTargetMethod->GetMethodTable()->IsValueType() && !pTargetMethod->IsUnboxingStub(); if (needsRuntimeInfo) - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_RT_CLOSED); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_RT_CLOSED); else { if (!isStatic) - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_CLOSED); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_CLOSED); else { if (isCollectible) { - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_CLOSED_STATIC); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_COLLECTIBLE_CLOSED_STATIC); pCtorData->pArg3 = pTargetMethodLoaderAllocator->GetLoaderAllocatorObjectHandle(); } else { - pRealCtor = MscorlibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_CLOSED_STATIC); + pRealCtor = CoreLibBinder::GetMethod(METHOD__MULTICAST_DELEGATE__CTOR_CLOSED_STATIC); } } } @@ -3149,7 +3149,7 @@ static void TryConstructUnhandledExceptionArgs(OBJECTREF *pThrowable, EX_TRY { - MethodTable *pMT = MscorlibBinder::GetClass(CLASS__UNHANDLED_EVENTARGS); + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__UNHANDLED_EVENTARGS); *pOutEventArgs = AllocateObject(pMT); MethodDescCallSite ctor(METHOD__UNHANDLED_EVENTARGS__CTOR, pOutEventArgs); diff --git a/src/coreclr/src/vm/commodule.cpp b/src/coreclr/src/vm/commodule.cpp index 0575cb9b2618..a1f2e27d2496 100644 --- a/src/coreclr/src/vm/commodule.cpp +++ b/src/coreclr/src/vm/commodule.cpp @@ -958,7 +958,7 @@ Object* GetTypesInner(Module* pModule) if (pModule->IsResource()) { - refArrClasses = (PTRARRAYREF) AllocateObjectArray(0, MscorlibBinder::GetClass(CLASS__CLASS)); + refArrClasses = (PTRARRAYREF) AllocateObjectArray(0, CoreLibBinder::GetClass(CLASS__CLASS)); RETURN(OBJECTREFToObject(refArrClasses)); } @@ -976,7 +976,7 @@ Object* GetTypesInner(Module* pModule) // Allocate the COM+ array bSystemAssembly = (pModule->GetAssembly() == SystemDomain::SystemAssembly()); AllocSize = dwNumTypeDefs; - refArrClasses = (PTRARRAYREF) AllocateObjectArray(AllocSize, MscorlibBinder::GetClass(CLASS__CLASS)); + refArrClasses = (PTRARRAYREF) AllocateObjectArray(AllocSize, CoreLibBinder::GetClass(CLASS__CLASS)); int curPos = 0; OBJECTREF throwable = 0; diff --git a/src/coreclr/src/vm/common.h b/src/coreclr/src/vm/common.h index ab73f6746f45..992c6a70b2cc 100644 --- a/src/coreclr/src/vm/common.h +++ b/src/coreclr/src/vm/common.h @@ -144,7 +144,7 @@ typedef DPTR(class MethodDesc) PTR_MethodDesc; typedef DPTR(class MethodDescChunk) PTR_MethodDescChunk; typedef DPTR(class MethodImpl) PTR_MethodImpl; typedef DPTR(class MethodTable) PTR_MethodTable; -typedef DPTR(class MscorlibBinder) PTR_MscorlibBinder; +typedef DPTR(class CoreLibBinder) PTR_CoreLibBinder; typedef VPTR(class Module) PTR_Module; typedef DPTR(class NDirectMethodDesc) PTR_NDirectMethodDesc; typedef DPTR(class Thread) PTR_Thread; diff --git a/src/coreclr/src/vm/compatibilityswitch.cpp b/src/coreclr/src/vm/compatibilityswitch.cpp index 3b36f58a9d24..49ce4a400c6e 100644 --- a/src/coreclr/src/vm/compatibilityswitch.cpp +++ b/src/coreclr/src/vm/compatibilityswitch.cpp @@ -6,7 +6,7 @@ #include "clrconfig.h" #include "compatibilityswitch.h" -FCIMPL2(StringObject*, CompatibilitySwitch::GetValue, StringObject* switchNameUNSAFE, CLR_BOOL onlyDB) { +FCIMPL1(StringObject*, CompatibilitySwitch::GetValue, StringObject* switchNameUNSAFE) { CONTRACTL { FCALL_CHECK; } @@ -23,20 +23,7 @@ FCIMPL2(StringObject*, CompatibilitySwitch::GetValue, StringObject* switchNameUN HELPER_METHOD_FRAME_BEGIN_RET_1(name); CLRConfig::ConfigStringInfo info; info.name = name->GetBuffer(); - if(onlyDB) - { - // for public managed apis we ignore checking in registry/config/env - // only check in windows appcompat DB - info.options = CLRConfig::IgnoreEnv | - CLRConfig::IgnoreHKLM | - CLRConfig::IgnoreHKCU; - } - else - { - // for mscorlib (i.e. which use internal apis) also check in - // registry/config/env in addition to windows appcompat DB - info.options = CLRConfig::EEConfig_default; - } + info.options = CLRConfig::EEConfig_default; LPWSTR strVal = CLRConfig::GetConfigValue(info); refName = StringObject::NewString(strVal); HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/compatibilityswitch.h b/src/coreclr/src/vm/compatibilityswitch.h index 810455ebaa5e..bd291ee3e442 100644 --- a/src/coreclr/src/vm/compatibilityswitch.h +++ b/src/coreclr/src/vm/compatibilityswitch.h @@ -15,7 +15,7 @@ class CompatibilitySwitch { public: - static FCDECL2(StringObject*, GetValue, StringObject *switchNameUNSAFE, CLR_BOOL onlyDB); + static FCDECL1(StringObject*, GetValue, StringObject *switchNameUNSAFE); }; diff --git a/src/coreclr/src/vm/compile.cpp b/src/coreclr/src/vm/compile.cpp index 28716467474e..492079e9d22d 100644 --- a/src/coreclr/src/vm/compile.cpp +++ b/src/coreclr/src/vm/compile.cpp @@ -276,7 +276,7 @@ HRESULT CEECompileInfo::LoadAssemblyByPath( AssemblySpec spec; spec.InitializeSpec(TokenFromRid(1, mdtAssembly), pImage->GetMDImport(), NULL); - if (spec.IsMscorlib()) + if (spec.IsCoreLib()) { pAssembly = SystemDomain::System()->SystemAssembly(); } @@ -424,18 +424,13 @@ HRESULT CEECompileInfo::SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE assembl if (!pAssembly->IsSystem()) { - // It is possible to get through a compile without calling BindAssemblySpec on mscorlib. This - // is because refs to mscorlib are short circuited in a number of places. So, we will explicitly + // It is possible to get through a compile without calling BindAssemblySpec on CoreLib. This + // is because refs to CoreLib are short circuited in a number of places. So, we will explicitly // add it to our dependencies. - AssemblySpec mscorlib; - mscorlib.InitializeSpec(SystemDomain::SystemFile()); - GetAppDomain()->BindAssemblySpec(&mscorlib,TRUE); - - if (!IsReadyToRunCompilation() && !SystemDomain::SystemFile()->HasNativeImage()) - { - return NGEN_E_SYS_ASM_NI_MISSING; - } + AssemblySpec corelib; + corelib.InitializeSpec(SystemDomain::SystemFile()); + GetAppDomain()->BindAssemblySpec(&corelib,TRUE); } if (IsReadyToRunCompilation() && !pModule->GetFile()->IsILOnly()) @@ -1326,7 +1321,7 @@ void CEECompileInfo::EncodeClass( COOPERATIVE_TRANSITION_END(); } -CORINFO_MODULE_HANDLE CEECompileInfo::GetLoaderModuleForMscorlib() +CORINFO_MODULE_HANDLE CEECompileInfo::GetLoaderModuleForCoreLib() { STANDARD_VM_CONTRACT; @@ -1634,7 +1629,7 @@ void CEECompileInfo::EncodeGenericSignature( { STANDARD_VM_CONTRACT; - Module * pInfoModule = MscorlibBinder::GetModule(); + Module * pInfoModule = CoreLibBinder::GetModule(); SigPointer ptr((PCCOR_SIGNATURE)signature); @@ -4819,7 +4814,7 @@ static void SpecializeComparer(SString& ss, Instantiation& inst) // Override the default ObjectComparer for special cases // if (elemTypeHnd.CanCastTo( - TypeHandle(MscorlibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(Instantiation(&elemTypeHnd, 1)))) + TypeHandle(CoreLibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(Instantiation(&elemTypeHnd, 1)))) { ss.Set(W("System.Collections.Generic.GenericComparer`1")); return; @@ -4829,7 +4824,7 @@ static void SpecializeComparer(SString& ss, Instantiation& inst) { Instantiation nullableInst = elemTypeHnd.AsMethodTable()->GetInstantiation(); if (nullableInst[0].CanCastTo( - TypeHandle(MscorlibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(nullableInst))) + TypeHandle(CoreLibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(nullableInst))) { ss.Set(W("System.Collections.Generic.NullableComparer`1")); inst = nullableInst; @@ -4874,7 +4869,7 @@ static void SpecializeEqualityComparer(SString& ss, Instantiation& inst) // Override the default ObjectEqualityComparer for special cases // if (elemTypeHnd.CanCastTo( - TypeHandle(MscorlibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(Instantiation(&elemTypeHnd, 1)))) + TypeHandle(CoreLibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(Instantiation(&elemTypeHnd, 1)))) { ss.Set(W("System.Collections.Generic.GenericEqualityComparer`1")); return; @@ -4884,7 +4879,7 @@ static void SpecializeEqualityComparer(SString& ss, Instantiation& inst) { Instantiation nullableInst = elemTypeHnd.AsMethodTable()->GetInstantiation(); if (nullableInst[0].CanCastTo( - TypeHandle(MscorlibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(nullableInst))) + TypeHandle(CoreLibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(nullableInst))) { ss.Set(W("System.Collections.Generic.NullableEqualityComparer`1")); inst = nullableInst; @@ -4925,7 +4920,7 @@ void CEEPreloader::ApplyTypeDependencyProductionsForType(TypeHandle t) pMT = pMT->GetCanonicalMethodTable(); - // The TypeDependencyAttribute attribute is currently only allowed on mscorlib types + // The TypeDependencyAttribute attribute is currently only allowed on CoreLib types // Don't even look for the attribute on types in other assemblies. if(!pMT->GetModule()->IsSystem()) { return; @@ -5004,7 +4999,7 @@ void CEEPreloader::ApplyTypeDependencyProductionsForType(TypeHandle t) TypeHandle typicalDepTH = TypeName::GetTypeUsingCASearchRules(ss.GetUnicode(), pMT->GetAssembly()); _ASSERTE(!typicalDepTH.IsNull()); - // This attribute is currently only allowed to refer to mscorlib types + // This attribute is currently only allowed to refer to CoreLib types _ASSERTE(typicalDepTH.GetModule()->IsSystem()); if (!typicalDepTH.GetModule()->IsSystem()) continue; @@ -5012,7 +5007,7 @@ void CEEPreloader::ApplyTypeDependencyProductionsForType(TypeHandle t) // For IList, ICollection, IEnumerable, IReadOnlyCollection & IReadOnlyList, include SZArrayHelper's // generic methods (or at least the relevant ones) in the ngen image in // case someone casts a T[] to an IList (or ICollection or IEnumerable, etc). - if (MscorlibBinder::IsClass(typicalDepTH.AsMethodTable(), CLASS__SZARRAYHELPER)) + if (CoreLibBinder::IsClass(typicalDepTH.AsMethodTable(), CLASS__SZARRAYHELPER)) { #ifdef FEATURE_FULL_NGEN if (pMT->GetNumGenericArgs() != 1 || !pMT->IsInterface()) { @@ -5091,14 +5086,14 @@ void CEEPreloader::ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceM METHOD__SZARRAYHELPER__REMOVEAT, // Last method of IList }; - // Assuming the binder ID's are properly laid out in mscorlib.h + // Assuming the binder ID's are properly laid out in corelib.h #if _DEBUG for(unsigned int i=0; i < NumItems(LastMethodOnGenericArrayInterfaces) - 1; i++) { _ASSERTE(LastMethodOnGenericArrayInterfaces[i] < LastMethodOnGenericArrayInterfaces[i+1]); } #endif - MethodTable* pExactMT = MscorlibBinder::GetClass(CLASS__SZARRAYHELPER); + MethodTable* pExactMT = CoreLibBinder::GetClass(CLASS__SZARRAYHELPER); // Subtract one from the non-generic IEnumerable that the generic IEnumerable // inherits from. @@ -5114,7 +5109,7 @@ void CEEPreloader::ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceM if (SZArrayHelperMethodIDs[i] > LastMethodOnGenericArrayInterfaces[inheritanceDepth]) continue; - MethodDesc * pPrimaryMD = MscorlibBinder::GetMethod(SZArrayHelperMethodIDs[i]); + MethodDesc * pPrimaryMD = CoreLibBinder::GetMethod(SZArrayHelperMethodIDs[i]); MethodDesc * pInstantiatedMD = MethodDesc::FindOrCreateAssociatedMethodDesc(pPrimaryMD, pExactMT, false, Instantiation(&elemTypeHnd, 1), false); @@ -6272,7 +6267,7 @@ CorCompileILRegion CEEPreloader::GetILRegion(mdMethodDef token) else if (MethodIsVisibleOutsideItsAssembly(pMD)) { - // We are inlining only leaf methods, except for mscorlib. Thus we can assume that only methods + // We are inlining only leaf methods, except for CoreLib. Thus we can assume that only methods // visible outside its assembly are likely to be inlined. region = CORCOMPILE_ILREGION_INLINEABLE; } @@ -6611,7 +6606,7 @@ HRESULT CompilationDomain::AddDependencyEntry(PEAssembly *pFile, if (pFile) { DomainAssembly *pAssembly = GetAppDomain()->LoadDomainAssembly(NULL, pFile, FILE_LOAD_CREATE); - // Note that this can trigger an assembly load (of mscorlib) + // Note that this can trigger an assembly load (of CoreLib) pAssembly->GetOptimizedIdentitySignature(&pDependency->signAssemblyDef); @@ -6642,17 +6637,17 @@ HRESULT CompilationDomain::AddDependency(AssemblySpec *pRefSpec, // This assert prevents dependencies from silently being loaded without being recorded. _ASSERTE(m_pEmit); - // Normalize any reference to mscorlib; we don't want to record other non-canonical - // mscorlib references in the ngen image since fusion doesn't understand how to bind them. + // Normalize any reference to CoreLib; we don't want to record other non-canonical + // CoreLib references in the ngen image since fusion doesn't understand how to bind them. // (Not to mention the fact that they are redundant.) AssemblySpec spec; - if (pRefSpec->IsMscorlib()) + if (pRefSpec->IsCoreLib()) { - _ASSERTE(pFile); // mscorlib had better not be missing + _ASSERTE(pFile); // CoreLib had better not be missing if (!pFile) return E_UNEXPECTED; - // Don't store a binding from mscorlib to itself. + // Don't store a binding from CoreLib to itself. if (m_pTargetAssembly == SystemDomain::SystemAssembly()) return S_OK; @@ -6661,8 +6656,8 @@ HRESULT CompilationDomain::AddDependency(AssemblySpec *pRefSpec, } else if (m_pTargetAssembly == NULL && pFile) { - // If target assembly is still NULL, we must be loading either the target assembly or mscorlib. - // Mscorlib is already handled above, so we must be loading the target assembly if we get here. + // If target assembly is still NULL, we must be loading either the target assembly or CoreLib. + // CoreLib is already handled above, so we must be loading the target assembly if we get here. // Use the assembly name given in the target assembly so that the native image is deterministic // regardless of how the target assembly is specified on the command line. spec.InitializeSpec(pFile); @@ -6761,7 +6756,7 @@ BOOL CompilationDomain::CanEagerBindToZapFile(Module *targetModule, BOOL limitTo // // CoreCLR does not have attributes for fine grained eager binding control. - // We hard bind to mscorlib.dll only. + // We hard bind to CoreLib only. // return targetModule->IsSystem(); } diff --git a/src/coreclr/src/vm/compile.h b/src/coreclr/src/vm/compile.h index 7e858b1a25a4..a04e19307f3e 100644 --- a/src/coreclr/src/vm/compile.h +++ b/src/coreclr/src/vm/compile.h @@ -303,7 +303,7 @@ class CEECompileInfo : public ICorCompileInfo LPWSTR *pHardBindList, DWORD cHardBindList); - CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib(); + CORINFO_MODULE_HANDLE GetLoaderModuleForCoreLib(); CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableType(CORINFO_CLASS_HANDLE classHandle); CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableMethod(CORINFO_METHOD_HANDLE methodHandle); CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableField(CORINFO_FIELD_HANDLE fieldHandle); diff --git a/src/coreclr/src/vm/comsynchronizable.cpp b/src/coreclr/src/vm/comsynchronizable.cpp index d8cdfe8d6626..687dbabcbc90 100644 --- a/src/coreclr/src/vm/comsynchronizable.cpp +++ b/src/coreclr/src/vm/comsynchronizable.cpp @@ -227,7 +227,7 @@ void ThreadNative::KickOffThread_Worker(LPVOID ptr) _ASSERTE(pMeth); MethodDescCallSite invokeMethod(pMeth, &gc.orDelegate); - if (MscorlibBinder::IsClass(gc.orDelegate->GetMethodTable(), CLASS__PARAMETERIZEDTHREADSTART)) + if (CoreLibBinder::IsClass(gc.orDelegate->GetMethodTable(), CLASS__PARAMETERIZEDTHREADSTART)) { //Parameterized ThreadStart ARG_SLOT arg[2]; @@ -1392,7 +1392,7 @@ FCIMPL1(Object*, ThreadNative::GetThreadDeserializationTracker, StackCrawlMark* // To avoid reflection trying to bypass deserialization tracking, check the caller // and only allow SerializationInfo to call into this method. MethodTable* pCallerMT = SystemDomain::GetCallersType(stackMark); - if (pCallerMT != MscorlibBinder::GetClass(CLASS__SERIALIZATION_INFO)) + if (pCallerMT != CoreLibBinder::GetClass(CLASS__SERIALIZATION_INFO)) { COMPlusThrowArgumentException(W("stackMark"), NULL); } diff --git a/src/coreclr/src/vm/comthreadpool.cpp b/src/coreclr/src/vm/comthreadpool.cpp index be3a5a3c0d31..edb8e33a2c62 100644 --- a/src/coreclr/src/vm/comthreadpool.cpp +++ b/src/coreclr/src/vm/comthreadpool.cpp @@ -342,7 +342,7 @@ RegisterWaitForSingleObjectCallback_Worker(LPVOID ptr) orState = ObjectFromHandle(((DelegateInfo*) args->delegateInfo)->m_stateHandle); #ifdef _DEBUG - MethodDesc *pMeth = MscorlibBinder::GetMethod(METHOD__TPWAITORTIMER_HELPER__PERFORM_WAITORTIMER_CALLBACK); + MethodDesc *pMeth = CoreLibBinder::GetMethod(METHOD__TPWAITORTIMER_HELPER__PERFORM_WAITORTIMER_CALLBACK); LogCall(pMeth,"RWSOCallback"); #endif @@ -601,7 +601,7 @@ VOID BindIoCompletionCallBack_Worker(LPVOID args) // we set processed to TRUE, now it's our responsibility to guarantee proper cleanup #ifdef _DEBUG - MethodDesc *pMeth = MscorlibBinder::GetMethod(METHOD__IOCB_HELPER__PERFORM_IOCOMPLETION_CALLBACK); + MethodDesc *pMeth = CoreLibBinder::GetMethod(METHOD__IOCB_HELPER__PERFORM_IOCOMPLETION_CALLBACK); LogCall(pMeth,"IOCallback"); #endif @@ -769,7 +769,7 @@ void AppDomainTimerCallback_Worker(LPVOID ptr) CONTRACTL_END; #ifdef _DEBUG - MethodDesc *pMeth = MscorlibBinder::GetMethod(METHOD__TIMER_QUEUE__APPDOMAIN_TIMER_CALLBACK); + MethodDesc *pMeth = CoreLibBinder::GetMethod(METHOD__TIMER_QUEUE__APPDOMAIN_TIMER_CALLBACK); LogCall(pMeth,"AppDomainTimerCallback"); #endif diff --git a/src/coreclr/src/vm/comutilnative.cpp b/src/coreclr/src/vm/comutilnative.cpp index 98344d4afb7f..5f14adaeda71 100644 --- a/src/coreclr/src/vm/comutilnative.cpp +++ b/src/coreclr/src/vm/comutilnative.cpp @@ -1750,7 +1750,7 @@ static BOOL HasOverriddenMethod(MethodTable* mt, MethodTable* classMT, WORD meth if (!classMT->IsZapped()) { - // If mscorlib is JITed, the slots can be patched and thus we need to compare the actual MethodDescs + // If CoreLib is JITed, the slots can be patched and thus we need to compare the actual MethodDescs // to detect match reliably if (MethodTable::GetMethodDescForSlotAddress(actual) == MethodTable::GetMethodDescForSlotAddress(base)) { @@ -1784,9 +1784,9 @@ static BOOL CanCompareBitsOrUseFastGetHashCode(MethodTable* mt) return FALSE; } - MethodTable* valueTypeMT = MscorlibBinder::GetClass(CLASS__VALUE_TYPE); - WORD slotEquals = MscorlibBinder::GetMethod(METHOD__VALUE_TYPE__EQUALS)->GetSlot(); - WORD slotGetHashCode = MscorlibBinder::GetMethod(METHOD__VALUE_TYPE__GET_HASH_CODE)->GetSlot(); + MethodTable* valueTypeMT = CoreLibBinder::GetClass(CLASS__VALUE_TYPE); + WORD slotEquals = CoreLibBinder::GetMethod(METHOD__VALUE_TYPE__EQUALS)->GetSlot(); + WORD slotGetHashCode = CoreLibBinder::GetMethod(METHOD__VALUE_TYPE__GET_HASH_CODE)->GetSlot(); // Check the input type. if (HasOverriddenMethod(mt, valueTypeMT, slotEquals) @@ -2116,7 +2116,7 @@ static bool HasOverriddenStreamMethod(MethodTable * pMT, WORD slot) if (!g_pStreamMT->IsZapped()) { - // If mscorlib is JITed, the slots can be patched and thus we need to compare the actual MethodDescs + // If CoreLib is JITed, the slots can be patched and thus we need to compare the actual MethodDescs // to detect match reliably if (MethodTable::GetMethodDescForSlotAddress(actual) == MethodTable::GetMethodDescForSlotAddress(base)) return false; @@ -2135,9 +2135,9 @@ FCIMPL1(FC_BOOL_RET, StreamNative::HasOverriddenBeginEndRead, Object *stream) if (g_pStreamMT == NULL || g_slotBeginRead == 0 || g_slotEndRead == 0) { HELPER_METHOD_FRAME_BEGIN_RET_1(stream); - g_pStreamMT = MscorlibBinder::GetClass(CLASS__STREAM); - g_slotBeginRead = MscorlibBinder::GetMethod(METHOD__STREAM__BEGIN_READ)->GetSlot(); - g_slotEndRead = MscorlibBinder::GetMethod(METHOD__STREAM__END_READ)->GetSlot(); + g_pStreamMT = CoreLibBinder::GetClass(CLASS__STREAM); + g_slotBeginRead = CoreLibBinder::GetMethod(METHOD__STREAM__BEGIN_READ)->GetSlot(); + g_slotEndRead = CoreLibBinder::GetMethod(METHOD__STREAM__END_READ)->GetSlot(); HELPER_METHOD_FRAME_END(); } @@ -2157,9 +2157,9 @@ FCIMPL1(FC_BOOL_RET, StreamNative::HasOverriddenBeginEndWrite, Object *stream) if (g_pStreamMT == NULL || g_slotBeginWrite == 0 || g_slotEndWrite == 0) { HELPER_METHOD_FRAME_BEGIN_RET_1(stream); - g_pStreamMT = MscorlibBinder::GetClass(CLASS__STREAM); - g_slotBeginWrite = MscorlibBinder::GetMethod(METHOD__STREAM__BEGIN_WRITE)->GetSlot(); - g_slotEndWrite = MscorlibBinder::GetMethod(METHOD__STREAM__END_WRITE)->GetSlot(); + g_pStreamMT = CoreLibBinder::GetClass(CLASS__STREAM); + g_slotBeginWrite = CoreLibBinder::GetMethod(METHOD__STREAM__BEGIN_WRITE)->GetSlot(); + g_slotEndWrite = CoreLibBinder::GetMethod(METHOD__STREAM__END_WRITE)->GetSlot(); HELPER_METHOD_FRAME_END(); } diff --git a/src/coreclr/src/vm/coreassemblyspec.cpp b/src/coreclr/src/vm/coreassemblyspec.cpp index 0a9471ec74c8..e9857a9b388c 100644 --- a/src/coreclr/src/vm/coreassemblyspec.cpp +++ b/src/coreclr/src/vm/coreassemblyspec.cpp @@ -91,7 +91,7 @@ VOID AssemblySpec::Bind(AppDomain *pAppDomain, STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pResult)); PRECONDITION(CheckPointer(pAppDomain)); - PRECONDITION(IsMscorlib() == FALSE); // This should never be called for MSCORLIB (explicit loading) + PRECONDITION(IsCoreLib() == FALSE); // This should never be called for CoreLib (explicit loading) } CONTRACTL_END; @@ -116,7 +116,7 @@ VOID AssemblySpec::Bind(AppDomain *pAppDomain, ReleaseHolder pPrivAsm; _ASSERTE(pBinder != NULL); - if (m_wszCodeBase == NULL && IsMscorlibSatellite()) + if (m_wszCodeBase == NULL && IsCoreLibSatellite()) { StackSString sSystemDirectory(SystemDomain::System()->SystemDirectory()); StackSString tmpString; diff --git a/src/coreclr/src/vm/coreclr/corebindresult.h b/src/coreclr/src/vm/coreclr/corebindresult.h index db6559d038ad..3c8b1cb282c1 100644 --- a/src/coreclr/src/vm/coreclr/corebindresult.h +++ b/src/coreclr/src/vm/coreclr/corebindresult.h @@ -40,7 +40,7 @@ struct CoreBindResult : public IUnknown BOOL Found(); PEImage* GetPEImage(); - BOOL IsMscorlib(); + BOOL IsCoreLib(); void GetBindAssembly(ICLRPrivAssembly** ppAssembly); #ifdef FEATURE_PREJIT BOOL HasNativeImage(); diff --git a/src/coreclr/src/vm/coreclr/corebindresult.inl b/src/coreclr/src/vm/coreclr/corebindresult.inl index 1568ccbe9e15..10f367b3f483 100644 --- a/src/coreclr/src/vm/coreclr/corebindresult.inl +++ b/src/coreclr/src/vm/coreclr/corebindresult.inl @@ -18,7 +18,7 @@ inline BOOL CoreBindResult::Found() return (m_pAssembly!=NULL); }; -inline BOOL CoreBindResult::IsMscorlib() +inline BOOL CoreBindResult::IsCoreLib() { CONTRACTL { @@ -30,7 +30,7 @@ inline BOOL CoreBindResult::IsMscorlib() BINDER_SPACE::Assembly* pAssembly = BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(m_pAssembly); #ifndef CROSSGEN_COMPILE - return pAssembly->GetAssemblyName()->IsMscorlib(); + return pAssembly->GetAssemblyName()->IsCoreLib(); #else return (pAssembly->GetPath()).EndsWithCaseInsensitive(SString(CoreLibName_IL_W)); #endif diff --git a/src/coreclr/src/vm/mscorlib.cpp b/src/coreclr/src/vm/corelib.cpp similarity index 88% rename from src/coreclr/src/vm/mscorlib.cpp rename to src/coreclr/src/vm/corelib.cpp index 70eeb9ba7563..4562e2e12ed2 100644 --- a/src/coreclr/src/vm/mscorlib.cpp +++ b/src/coreclr/src/vm/corelib.cpp @@ -4,20 +4,20 @@ // -// This file defines tables for references between VM and mscorlib. +// This file defines tables for references between VM and corelib. // // When compiling crossgen, this file is compiled with the FEATURE_XXX define settings matching the target. // It allows us to strip features (e.g. refection only load) from crossgen without stripping them from the target. // -#ifdef CROSSGEN_MSCORLIB +#ifdef CROSSGEN_CORELIB // Use minimal set of headers for crossgen #include "windows.h" #include "corinfo.h" #else #include "common.h" #include "ecall.h" -#endif // CROSSGEN_MSCORLIB +#endif // CROSSGEN_CORELIB #ifndef CROSSGEN_COMPILE // @@ -88,10 +88,10 @@ #include "tailcallhelp.h" -#endif // CROSSGEN_MSCORLIB +#endif // CROSSGEN_CORELIB -#ifdef CROSSGEN_MSCORLIB +#ifdef CROSSGEN_CORELIB /////////////////////////////////////////////////////////////////////////////// // @@ -106,7 +106,7 @@ enum { FCFuncFlag_EndOfArray = 0x01, FCFuncFlag_HasSignature = 0x02, FCFuncFlag_Unreferenced = 0x04, // Suppress unused fcall check - FCFuncFlag_QCall = 0x08, // QCall - mscorlib.dll to mscorwks.dll transition implemented as PInvoke + FCFuncFlag_QCall = 0x08, // QCall - CoreLib to VM transition implemented as PInvoke }; struct ECClass @@ -129,9 +129,9 @@ enum BinderClassID #undef TYPEINFO #define DEFINE_CLASS(i,n,s) CLASS__ ## i, -#include "mscorlib.h" +#include "corelib.h" - CLASS__MSCORLIB_COUNT, + CLASS__CORELIB_COUNT, CLASS__VOID = CLASS__ELEMENT_TYPE_VOID, CLASS__BOOLEAN = CLASS__ELEMENT_TYPE_BOOLEAN, @@ -153,31 +153,31 @@ enum BinderClassID CLASS__OBJECT = CLASS__ELEMENT_TYPE_OBJECT }; -struct MscorlibClassDescription +struct CoreLibClassDescription { LPCSTR nameSpace; LPCSTR name; }; -struct MscorlibMethodDescription +struct CoreLibMethodDescription { BinderClassID classID; LPCSTR name; const HardCodedMetaSig * sig; }; -struct MscorlibFieldDescription +struct CoreLibFieldDescription { BinderClassID classID; LPCSTR name; }; -#endif // CROSSGEN_MSCORLIB +#endif // CROSSGEN_CORELIB -#ifdef CROSSGEN_MSCORLIB +#ifdef CROSSGEN_CORELIB // When compiling crossgen this namespace creates the second version of the tables than matches the target -namespace CrossGenMscorlib { +namespace CrossGenCoreLib { #endif @@ -321,20 +321,20 @@ enum _gsigc { /////////////////////////////////////////////////////////////////////////////// // -// Mscorlib binder +// CoreLib binder // // Extern definitions so that binder.cpp can see these tables -extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[]; -extern const USHORT c_nMscorlibClassDescriptions; +extern const CoreLibClassDescription c_rgCoreLibClassDescriptions[]; +extern const USHORT c_nCoreLibClassDescriptions; -extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[]; -extern const USHORT c_nMscorlibMethodDescriptions; +extern const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[]; +extern const USHORT c_nCoreLibMethodDescriptions; -extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[]; -extern const USHORT c_nMscorlibFieldDescriptions; +extern const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[]; +extern const USHORT c_nCoreLibFieldDescriptions; -const MscorlibClassDescription c_rgMscorlibClassDescriptions[] = +const CoreLibClassDescription c_rgCoreLibClassDescriptions[] = { #define TYPEINFO(e,ns,c,s,g,ia,ip,if,im,gv) { ns, c }, #include "cortypeinfo.h" @@ -342,29 +342,29 @@ const MscorlibClassDescription c_rgMscorlibClassDescriptions[] = #define DEFINE_CLASS(i,n,s) { g_ ## n ## NS, # s }, #include "namespace.h" - #include "mscorlib.h" + #include "corelib.h" - // Include all exception types here that are defined in mscorlib. Omit exceptions defined elsewhere. + // Include all exception types here that are defined in corelib. Omit exceptions defined elsewhere. #define DEFINE_EXCEPTION(ns, reKind, bHRformessage, ...) { ns , # reKind }, #include "rexcep.h" }; -const USHORT c_nMscorlibClassDescriptions = NumItems(c_rgMscorlibClassDescriptions); +const USHORT c_nCoreLibClassDescriptions = NumItems(c_rgCoreLibClassDescriptions); #define gsig_NoSig (*(HardCodedMetaSig *)NULL) -const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[] = +const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[] = { #define DEFINE_METHOD(c,i,s,g) { CLASS__ ## c , # s, & gsig_ ## g }, - #include "mscorlib.h" + #include "corelib.h" }; -const USHORT c_nMscorlibMethodDescriptions = NumItems(c_rgMscorlibMethodDescriptions) + 1; +const USHORT c_nCoreLibMethodDescriptions = NumItems(c_rgCoreLibMethodDescriptions) + 1; -const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[] = +const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[] = { #define DEFINE_FIELD(c,i,s) { CLASS__ ## c , # s }, - #include "mscorlib.h" + #include "corelib.h" }; -const USHORT c_nMscorlibFieldDescriptions = NumItems(c_rgMscorlibFieldDescriptions) + 1; +const USHORT c_nCoreLibFieldDescriptions = NumItems(c_rgCoreLibFieldDescriptions) + 1; /////////////////////////////////////////////////////////////////////////////// // @@ -375,7 +375,7 @@ const USHORT c_nMscorlibFieldDescriptions = NumItems(c_rgMscorlibFieldDescriptio EXTERN_C const LPVOID gPalGlobalizationNative[]; // When compiling crossgen, we only need the target version of the ecall tables -#if !defined(CROSSGEN_COMPILE) || defined(CROSSGEN_MSCORLIB) +#if !defined(CROSSGEN_COMPILE) || defined(CROSSGEN_CORELIB) #ifdef CROSSGEN_COMPILE @@ -433,9 +433,9 @@ const ECClass c_rgECClasses[] = const int c_nECClasses = NumItems(c_rgECClasses); -#endif // !CROSSGEN_COMPILE && CROSSGEN_MSCORLIB +#endif // !CROSSGEN_COMPILE && CROSSGEN_CORELIB -#ifdef CROSSGEN_MSCORLIB -}; // namespace CrossGenMscorlib +#ifdef CROSSGEN_CORELIB +}; // namespace CrossGenCoreLib #endif diff --git a/src/coreclr/src/vm/mscorlib.h b/src/coreclr/src/vm/corelib.h similarity index 99% rename from src/coreclr/src/vm/mscorlib.h rename to src/coreclr/src/vm/corelib.h index fd2578fcaea8..f6ad66da1a07 100644 --- a/src/coreclr/src/vm/mscorlib.h +++ b/src/coreclr/src/vm/corelib.h @@ -1,6 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// This file contains the classes, methods, and field used by the EE from mscorlib +// This file contains the classes, methods, and field used by the EE from corelib // // To use this, define one of the following macros & include the file like so: @@ -8,7 +8,7 @@ // #define DEFINE_CLASS(id, nameSpace, stringName) CLASS__ ## id, // #define DEFINE_METHOD(classId, id, stringName, gSign) // #define DEFINE_FIELD(classId, id, stringName) -// #include "mscorlib.h" +// #include "corelib.h" // // Note: To determine if the namespace you want to use in DEFINE_CLASS is supported or not, // examine vm\namespace.h. If it is not present, define it there and then proceed to use it below. diff --git a/src/coreclr/src/vm/crossgen/CMakeLists.txt b/src/coreclr/src/vm/crossgen/CMakeLists.txt index a0b321a00e33..e8083ca860f8 100644 --- a/src/coreclr/src/vm/crossgen/CMakeLists.txt +++ b/src/coreclr/src/vm/crossgen/CMakeLists.txt @@ -22,6 +22,7 @@ set(VM_CROSSGEN_SOURCES ../contractimpl.cpp ../coreassemblyspec.cpp ../corebindresult.cpp + ../corelib.cpp ../crossgencompile.cpp ../custommarshalerinfo.cpp ../dataimage.cpp @@ -60,7 +61,6 @@ set(VM_CROSSGEN_SOURCES ../methodtable.cpp ../methodtablebuilder.cpp ../mlinfo.cpp - ../mscorlib.cpp ../nativeimage.cpp ../olevariant.cpp ../pefile.cpp @@ -115,6 +115,7 @@ set(VM_CROSSGEN_HEADERS ../comdelegate.h ../compile.h ../contractimpl.h + ../corelib.h ../custommarshalerinfo.h ../dataimage.h ../debuginfostore.h @@ -154,7 +155,6 @@ set(VM_CROSSGEN_HEADERS ../methodtablebuilder.h ../methodtablebuilder.inl ../mlinfo.h - ../mscorlib.h ../olevariant.h ../pefile.h ../pefile.inl @@ -259,18 +259,18 @@ add_dependencies(cee_crossgen eventing_headers) set_target_properties(cee_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE) target_precompile_header(TARGET cee_crossgen HEADER common.h) if (MSVC) - # mscorlib.cpp does not compile with precompiled header file - set_source_files_properties(../mscorlib.cpp PROPERTIES COMPILE_FLAGS "/Y-") + # corelib.cpp does not compile with precompiled header file + set_source_files_properties(../corelib.cpp PROPERTIES COMPILE_FLAGS "/Y-") endif() -add_library_clr(mscorlib_crossgen ../mscorlib.cpp) -add_dependencies(mscorlib_crossgen eventing_headers) -target_compile_definitions(mscorlib_crossgen +add_library_clr(corelib_crossgen ../corelib.cpp) +add_dependencies(corelib_crossgen eventing_headers) +target_compile_definitions(corelib_crossgen PRIVATE EnC_SUPPORTED FEATURE_EVENT_TRACE FEATURE_MULTICOREJIT - CROSSGEN_MSCORLIB) + CROSSGEN_CORELIB) -set_target_properties(mscorlib_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE) +set_target_properties(corelib_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE) diff --git a/src/coreclr/src/vm/crossloaderallocatorhash.inl b/src/coreclr/src/vm/crossloaderallocatorhash.inl index 1eb55509a87b..dab0f50f806e 100644 --- a/src/coreclr/src/vm/crossloaderallocatorhash.inl +++ b/src/coreclr/src/vm/crossloaderallocatorhash.inl @@ -291,7 +291,7 @@ template LAHASHKEYTOTRACKERSREF hashKeyToTrackers; OBJECTREF keyValueStore; - if (hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)hashKeyEntry; keyValueStore = hashKeyToTrackers->_laLocalKeyValueStore; @@ -321,7 +321,7 @@ template LAHASHKEYTOTRACKERSREF hashKeyToTrackers; OBJECTREF keyValueStore; - if (hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)hashKeyEntry; keyValueStore = hashKeyToTrackers->_laLocalKeyValueStore; @@ -376,7 +376,7 @@ void CrossLoaderAllocatorHash::Add(TKey key, TValue value, LoaderAllocat if (pLoaderAllocatorOfValue != m_pLoaderAllocator) { - gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)AllocateObject(MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)); + gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)AllocateObject(CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)); SetObjectReference(&gc.hashKeyToTrackers->_laLocalKeyValueStore, gc.keyValueStore); gc.hashKeyEntry = gc.hashKeyToTrackers; } @@ -394,7 +394,7 @@ void CrossLoaderAllocatorHash::Add(TKey key, TValue value, LoaderAllocat { gc.keyToTrackersHash.GetElement(index, gc.hashKeyEntry); - if (gc.hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (gc.hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)gc.hashKeyEntry; gc.keyValueStore = gc.hashKeyToTrackers->_laLocalKeyValueStore; @@ -431,7 +431,7 @@ void CrossLoaderAllocatorHash::Add(TKey key, TValue value, LoaderAllocat if (gc.hashKeyToTrackers == NULL) { // Nothing has yet caused the trackers proxy object to be setup. Create it now, and update the keyToTrackersHash - gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)AllocateObject(MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)); + gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)AllocateObject(CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)); SetObjectReference(&gc.hashKeyToTrackers->_laLocalKeyValueStore, gc.keyValueStore); gc.hashKeyEntry = gc.hashKeyToTrackers; gc.keyToTrackersHash.SetElement(index, gc.hashKeyEntry); @@ -508,7 +508,7 @@ void CrossLoaderAllocatorHash::Remove(TKey key, TValue value, LoaderAllo { gc.keyToTrackersHash.GetElement(index, gc.hashKeyEntry); - if (gc.hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (gc.hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)gc.hashKeyEntry; gc.keyValueStore = gc.hashKeyToTrackers->_laLocalKeyValueStore; @@ -602,7 +602,7 @@ bool CrossLoaderAllocatorHash::VisitValuesOfKey(TKey key, Visitor &visit // We have an entry in the hashtable for the key/dependenthandle. gc.keyToTrackersHash.GetElement(index, gc.hashKeyEntry); - if (gc.hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (gc.hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)gc.hashKeyEntry; gc.keyValueStore = gc.hashKeyToTrackers->_laLocalKeyValueStore; @@ -621,7 +621,7 @@ bool CrossLoaderAllocatorHash::VisitValuesOfKey(TKey key, Visitor &visit { // Is there a single dependenttracker here, or a set. - if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) + if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) { gc.dependentTracker = (LAHASHDEPENDENTHASHTRACKERREF)gc.hashKeyToTrackers->_trackerOrTrackerSet; result = VisitTracker(key, gc.dependentTracker, visitor); @@ -785,7 +785,7 @@ void CrossLoaderAllocatorHash::RemoveAll(TKey key) // We have an entry in the hashtable for the key/dependenthandle. gc.keyToTrackersHash.GetElement(index, gc.hashKeyEntry); - if (gc.hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (gc.hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)gc.hashKeyEntry; gc.keyValueStore = gc.hashKeyToTrackers->_laLocalKeyValueStore; @@ -801,7 +801,7 @@ void CrossLoaderAllocatorHash::RemoveAll(TKey key) { // Is there a single dependenttracker here, or a set. - if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) + if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) { gc.dependentTracker = (LAHASHDEPENDENTHASHTRACKERREF)gc.hashKeyToTrackers->_trackerOrTrackerSet; DeleteEntryTracker(key, gc.dependentTracker); @@ -972,7 +972,7 @@ template GCPROTECT_BEGIN(gc); { - if (gc.hashKeyEntry->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) + if (gc.hashKeyEntry->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHKEYTOTRACKERS)) { gc.hashKeyToTrackers = (LAHASHKEYTOTRACKERSREF)gc.hashKeyEntry; gc.keyValueStore = gc.hashKeyToTrackers->_laLocalKeyValueStore; @@ -1028,14 +1028,14 @@ template { STANDARD_VM_CONTRACT; - // Force these types to be loaded, so that the hashtable logic can use MscorlibBinder::GetExistingClass + // Force these types to be loaded, so that the hashtable logic can use CoreLibBinder::GetExistingClass // throughout and avoid lock ordering issues - MscorlibBinder::GetClass(CLASS__LAHASHKEYTOTRACKERS); - MscorlibBinder::GetClass(CLASS__LAHASHDEPENDENTHASHTRACKER); - MscorlibBinder::GetClass(CLASS__GCHEAPHASH); - TypeHandle elemType = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_I1)); + CoreLibBinder::GetClass(CLASS__LAHASHKEYTOTRACKERS); + CoreLibBinder::GetClass(CLASS__LAHASHDEPENDENTHASHTRACKER); + CoreLibBinder::GetClass(CLASS__GCHEAPHASH); + TypeHandle elemType = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_I1)); TypeHandle typHnd = ClassLoader::LoadArrayTypeThrowing(elemType, ELEMENT_TYPE_SZARRAY, 0); - elemType = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_OBJECT)); + elemType = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_OBJECT)); typHnd = ClassLoader::LoadArrayTypeThrowing(elemType, ELEMENT_TYPE_SZARRAY, 0); } @@ -1052,14 +1052,14 @@ void CrossLoaderAllocatorHash::EnsureManagedObjectsInitted() if (m_loaderAllocatorToDependentTrackerHash == NULL) { - OBJECTREF laToDependentHandleHashObject = AllocateObject(MscorlibBinder::GetExistingClass(CLASS__GCHEAPHASH)); + OBJECTREF laToDependentHandleHashObject = AllocateObject(CoreLibBinder::GetExistingClass(CLASS__GCHEAPHASH)); m_loaderAllocatorToDependentTrackerHash = m_pLoaderAllocator->GetDomain()->CreateHandle(laToDependentHandleHashObject); m_pLoaderAllocator->RegisterHandleForCleanup(m_loaderAllocatorToDependentTrackerHash); } if (m_keyToDependentTrackersHash == NULL) { - OBJECTREF m_keyToDependentTrackersHashObject = AllocateObject(MscorlibBinder::GetExistingClass(CLASS__GCHEAPHASH)); + OBJECTREF m_keyToDependentTrackersHashObject = AllocateObject(CoreLibBinder::GetExistingClass(CLASS__GCHEAPHASH)); m_keyToDependentTrackersHash = m_pLoaderAllocator->GetDomain()->CreateHandle(m_keyToDependentTrackersHashObject); m_pLoaderAllocator->RegisterHandleForCleanup(m_keyToDependentTrackersHash); } @@ -1096,8 +1096,8 @@ LAHASHDEPENDENTHASHTRACKERREF CrossLoaderAllocatorHash::GetDependentTrac } else { - gc.dependentTracker = (LAHASHDEPENDENTHASHTRACKERREF)AllocateObject(MscorlibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)); - gc.GCHeapHashForKeyToValueStore = (GCHEAPHASHOBJECTREF)AllocateObject(MscorlibBinder::GetExistingClass(CLASS__GCHEAPHASH)); + gc.dependentTracker = (LAHASHDEPENDENTHASHTRACKERREF)AllocateObject(CoreLibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)); + gc.GCHeapHashForKeyToValueStore = (GCHEAPHASHOBJECTREF)AllocateObject(CoreLibBinder::GetExistingClass(CLASS__GCHEAPHASH)); OBJECTREF exposedObject = pLoaderAllocator->GetExposedObject(); if (exposedObject == NULL) @@ -1105,7 +1105,7 @@ LAHASHDEPENDENTHASHTRACKERREF CrossLoaderAllocatorHash::GetDependentTrac if (m_globalDependentTrackerRootHandle == NULL) { // Global LoaderAllocator does not have an exposed object, so create a fake one - exposedObject = AllocateObject(MscorlibBinder::GetExistingClass(CLASS__OBJECT)); + exposedObject = AllocateObject(CoreLibBinder::GetExistingClass(CLASS__OBJECT)); m_globalDependentTrackerRootHandle = GetAppDomain()->CreateHandle(exposedObject); m_pLoaderAllocator->RegisterHandleForCleanup(m_globalDependentTrackerRootHandle); } @@ -1162,7 +1162,7 @@ GCHEAPHASHOBJECTREF CrossLoaderAllocatorHash::GetKeyToValueCrossLAHashFo gc.dependentTracker = GetDependentTrackerForLoaderAllocator(pValueLoaderAllocator); SetObjectReference(&gc.hashKeyToTrackers->_trackerOrTrackerSet, gc.dependentTracker); } - else if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == MscorlibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) + else if (gc.hashKeyToTrackers->_trackerOrTrackerSet->GetMethodTable() == CoreLibBinder::GetExistingClass(CLASS__LAHASHDEPENDENTHASHTRACKER)) { gc.dependentTrackerMaybe = (LAHASHDEPENDENTHASHTRACKERREF)gc.hashKeyToTrackers->_trackerOrTrackerSet; if (gc.dependentTrackerMaybe->IsTrackerFor(pValueLoaderAllocator)) @@ -1181,7 +1181,7 @@ GCHEAPHASHOBJECTREF CrossLoaderAllocatorHash::GetKeyToValueCrossLAHashFo { // Allocate the dependent tracker hash // Fill with the existing dependentTrackerMaybe, and gc.DependentTracker - gc.dependentTrackerHash = GCHeapHashDependentHashTrackerHash(AllocateObject(MscorlibBinder::GetExistingClass(CLASS__GCHEAPHASH))); + gc.dependentTrackerHash = GCHeapHashDependentHashTrackerHash(AllocateObject(CoreLibBinder::GetExistingClass(CLASS__GCHEAPHASH))); LoaderAllocator *pLoaderAllocatorKey = gc.dependentTracker->GetLoaderAllocatorUnsafe(); gc.dependentTrackerHash.Add(&pLoaderAllocatorKey, [&gc](PTRARRAYREF arr, INT32 index) { diff --git a/src/coreclr/src/vm/customattribute.cpp b/src/coreclr/src/vm/customattribute.cpp index a06cbf0cb9e8..b8fe16ebf4a1 100644 --- a/src/coreclr/src/vm/customattribute.cpp +++ b/src/coreclr/src/vm/customattribute.cpp @@ -169,7 +169,7 @@ CustomAttributeManagedValues Attribute::GetManagedCaValue(CaValue* pCaVal) if (length != (ULONG)-1) { - gc.array = (CaValueArrayREF)AllocateSzArray(TypeHandle(MscorlibBinder::GetClass(CLASS__CUSTOM_ATTRIBUTE_ENCODED_ARGUMENT)).MakeSZArray(), length); + gc.array = (CaValueArrayREF)AllocateSzArray(TypeHandle(CoreLibBinder::GetClass(CLASS__CUSTOM_ATTRIBUTE_ENCODED_ARGUMENT)).MakeSZArray(), length); CustomAttributeValue* pValues = gc.array->GetDirectPointerToNonObjectElements(); for (COUNT_T i = 0; i < length; i ++) @@ -929,9 +929,9 @@ FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObjec { // load the proper type so that code in managed knows which property to load if (fieldType == SERIALIZATION_TYPE_STRING) - *pType = MscorlibBinder::GetElementType(ELEMENT_TYPE_STRING)->GetManagedClassObject(); + *pType = CoreLibBinder::GetElementType(ELEMENT_TYPE_STRING)->GetManagedClassObject(); else if (fieldType == SERIALIZATION_TYPE_TYPE) - *pType = MscorlibBinder::GetClass(CLASS__TYPE)->GetManagedClassObject(); + *pType = CoreLibBinder::GetClass(CLASS__TYPE)->GetManagedClassObject(); } break; case SERIALIZATION_TYPE_SZARRAY: @@ -942,9 +942,9 @@ FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObjec { _ASSERTE(!bObjectCreated); if (arrayType == SERIALIZATION_TYPE_STRING) - nullTH = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_STRING)); + nullTH = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_STRING)); else if (arrayType == SERIALIZATION_TYPE_TYPE) - nullTH = TypeHandle(MscorlibBinder::GetClass(CLASS__TYPE)); + nullTH = TypeHandle(CoreLibBinder::GetClass(CLASS__TYPE)); else if (arrayType == SERIALIZATION_TYPE_TAGGED_OBJECT) nullTH = TypeHandle(g_pObjectClass); ReadArray(pCtorAssembly, arrayType, arraySize, nullTH, &pBlob, pBlobEnd, pModule, (BASEARRAYREF*)value); @@ -955,17 +955,17 @@ FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObjec switch (arrayType) { case SERIALIZATION_TYPE_STRING: - arrayTH = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_STRING)); + arrayTH = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_STRING)); break; case SERIALIZATION_TYPE_TYPE: - arrayTH = TypeHandle(MscorlibBinder::GetClass(CLASS__TYPE)); + arrayTH = TypeHandle(CoreLibBinder::GetClass(CLASS__TYPE)); break; case SERIALIZATION_TYPE_TAGGED_OBJECT: arrayTH = TypeHandle(g_pObjectClass); break; default: if (SERIALIZATION_TYPE_BOOLEAN <= arrayType && arrayType <= SERIALIZATION_TYPE_R8) - arrayTH = TypeHandle(MscorlibBinder::GetElementType((CorElementType)arrayType)); + arrayTH = TypeHandle(CoreLibBinder::GetElementType((CorElementType)arrayType)); } if (!arrayTH.IsNull()) { @@ -977,7 +977,7 @@ FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObjec } default: if (SERIALIZATION_TYPE_BOOLEAN <= fieldType && fieldType <= SERIALIZATION_TYPE_R8) - pMTValue = MscorlibBinder::GetElementType((CorElementType)fieldType); + pMTValue = CoreLibBinder::GetElementType((CorElementType)fieldType); else if(fieldType == SERIALIZATION_TYPE_ENUM) fieldType = (CorSerializationType)pMTValue->GetInternalCorElementType(); else @@ -1027,12 +1027,12 @@ TypeHandle COMCustomAttribute::GetTypeHandleFromBlob(Assembly *pCtorAssembly, case SERIALIZATION_TYPE_U8: case SERIALIZATION_TYPE_R8: case SERIALIZATION_TYPE_STRING: - pMTType = MscorlibBinder::GetElementType((CorElementType)objType); + pMTType = CoreLibBinder::GetElementType((CorElementType)objType); RtnTypeHnd = TypeHandle(pMTType); break; case ELEMENT_TYPE_CLASS: - pMTType = MscorlibBinder::GetClass(CLASS__TYPE); + pMTType = CoreLibBinder::GetClass(CLASS__TYPE); RtnTypeHnd = TypeHandle(pMTType); break; @@ -1386,7 +1386,7 @@ ARG_SLOT COMCustomAttribute::GetDataFromBlob(Assembly *pCtorAssembly, goto stringType; else if (pMT == g_pObjectClass) goto typeObject; - else if (MscorlibBinder::IsClass(pMT, CLASS__TYPE)) + else if (CoreLibBinder::IsClass(pMT, CLASS__TYPE)) goto typeType; } diff --git a/src/coreclr/src/vm/custommarshalerinfo.cpp b/src/coreclr/src/vm/custommarshalerinfo.cpp index 8396b4520def..67acbff136ec 100644 --- a/src/coreclr/src/vm/custommarshalerinfo.cpp +++ b/src/coreclr/src/vm/custommarshalerinfo.cpp @@ -43,7 +43,7 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type // Make sure the custom marshaller implements ICustomMarshaler. - if (!hndCustomMarshalerType.GetMethodTable()->CanCastToInterface(MscorlibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))) + if (!hndCustomMarshalerType.GetMethodTable()->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))) { DefineFullyQualifiedNameForClassW() COMPlusThrow(kApplicationException, @@ -304,7 +304,7 @@ MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); - _ASSERTE(pMT->CanCastToInterface(MscorlibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); + _ASSERTE(pMT->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); MethodDesc *pMD = NULL; @@ -312,28 +312,28 @@ MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods { case CustomMarshalerMethods_MarshalNativeToManaged: pMD = pMT->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), TRUE /* throwOnConflict */); break; case CustomMarshalerMethods_MarshalManagedToNative: pMD = pMT->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), TRUE /* throwOnConflict */); break; case CustomMarshalerMethods_CleanUpNativeData: pMD = pMT->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA), TRUE /* throwOnConflict */); break; case CustomMarshalerMethods_CleanUpManagedData: pMD = pMT->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), TRUE /* throwOnConflict */); break; case CustomMarshalerMethods_GetNativeDataSize: pMD = pMT->GetMethodDescForInterfaceMethod( - MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE), + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE), TRUE /* throwOnConflict */); break; case CustomMarshalerMethods_GetInstance: diff --git a/src/coreclr/src/vm/debugdebugger.cpp b/src/coreclr/src/vm/debugdebugger.cpp index ad76de48d20f..29e6e3b8d6f7 100644 --- a/src/coreclr/src/vm/debugdebugger.cpp +++ b/src/coreclr/src/vm/debugdebugger.cpp @@ -51,7 +51,7 @@ // internal BCL helpful function doing permission check. From bucketing perspetive it is // more preferable to report the user managed code that invokes Debugger.Break instead. // -// User managed code is managed code in non-system assembly. Currently, only mscorlib.dll +// User managed code is managed code in non-system assembly. Currently, only CoreLib // is marked as system assembly. // //---------------------------------------------------------------------------- @@ -578,7 +578,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, if (pISymUnmanagedReader != NULL) { // Found a ISymUnmanagedReader for the regular PDB so don't attempt to - // read it as a portable PDB in mscorlib's StackFrameHelper. + // read it as a portable PDB in CoreLib's StackFrameHelper. fPortablePDB = FALSE; ReleaseHolder pISymUnmanagedMethod; diff --git a/src/coreclr/src/vm/dispatchinfo.cpp b/src/coreclr/src/vm/dispatchinfo.cpp index 76ee48ff6a92..b44062c796d4 100644 --- a/src/coreclr/src/vm/dispatchinfo.cpp +++ b/src/coreclr/src/vm/dispatchinfo.cpp @@ -432,7 +432,7 @@ ComMTMethodProps * DispatchMemberInfo::GetMemberProps(OBJECTREF MemberInfoObj, C GCPROTECT_BEGIN(MemberInfoObj); { MethodTable *pMemberInfoClass = MemberInfoObj->GetMethodTable(); - if (MscorlibBinder::IsClass(pMemberInfoClass, CLASS__METHOD)) + if (CoreLibBinder::IsClass(pMemberInfoClass, CLASS__METHOD)) { // Retrieve the MethodDesc from the MethodInfo. MethodDescCallSite getMethodHandle(METHOD__METHOD_BASE__GET_METHODDESC, &MemberInfoObj); @@ -441,7 +441,7 @@ ComMTMethodProps * DispatchMemberInfo::GetMemberProps(OBJECTREF MemberInfoObj, C if (pMeth) pMemberProps = pMemberMap->GetMethodProps(pMeth->GetMemberDef(), pMeth->GetModule()); } - else if (MscorlibBinder::IsClass(pMemberInfoClass, CLASS__RT_FIELD_INFO)) + else if (CoreLibBinder::IsClass(pMemberInfoClass, CLASS__RT_FIELD_INFO)) { MethodDescCallSite getFieldHandle(METHOD__RTFIELD__GET_FIELDHANDLE, &MemberInfoObj); ARG_SLOT arg = ObjToArgSlot(MemberInfoObj); @@ -449,7 +449,7 @@ ComMTMethodProps * DispatchMemberInfo::GetMemberProps(OBJECTREF MemberInfoObj, C if (pFld) pMemberProps = pMemberMap->GetMethodProps(pFld->GetMemberDef(), pFld->GetModule()); } - else if (MscorlibBinder::IsClass(pMemberInfoClass, CLASS__PROPERTY)) + else if (CoreLibBinder::IsClass(pMemberInfoClass, CLASS__PROPERTY)) { MethodDescCallSite getToken(METHOD__PROPERTY__GET_TOKEN, &MemberInfoObj); ARG_SLOT arg = ObjToArgSlot(MemberInfoObj); @@ -672,7 +672,7 @@ void DispatchMemberInfo::DetermineCultureAwareness() CONTRACTL_END; // Load the LCIDConversionAttribute type. - MethodTable * pLcIdConvAttrClass = MscorlibBinder::GetClass(CLASS__LCID_CONVERSION_TYPE); + MethodTable * pLcIdConvAttrClass = CoreLibBinder::GetClass(CLASS__LCID_CONVERSION_TYPE); // Check to see if the attribute is set. OBJECTREF MemberInfoObj = GetMemberInfoObject(); @@ -739,7 +739,7 @@ void DispatchMemberInfo::SetUpParamMarshalerInfo() { MethodTable *pMemberInfoMT = MemberInfoObj->GetMethodTable(); - if (MscorlibBinder::IsClass(pMemberInfoMT, CLASS__METHOD)) + if (CoreLibBinder::IsClass(pMemberInfoMT, CLASS__METHOD)) { MethodDescCallSite getMethodHandle(METHOD__METHOD_BASE__GET_METHODDESC, &MemberInfoObj); ARG_SLOT arg = ObjToArgSlot(MemberInfoObj); @@ -747,11 +747,11 @@ void DispatchMemberInfo::SetUpParamMarshalerInfo() if (pMeth) SetUpMethodMarshalerInfo(pMeth, FALSE); } - else if (MscorlibBinder::IsClass(pMemberInfoMT, CLASS__FIELD)) + else if (CoreLibBinder::IsClass(pMemberInfoMT, CLASS__FIELD)) { // We don't support non-default marshalling behavior for field getter/setter stubs invoked via IDispatch. } - else if (MscorlibBinder::IsClass(pMemberInfoMT, CLASS__PROPERTY)) + else if (CoreLibBinder::IsClass(pMemberInfoMT, CLASS__PROPERTY)) { BOOL isGetter = FALSE; MethodDescCallSite getSetter(METHOD__PROPERTY__GET_SETTER, &MemberInfoObj); @@ -2540,7 +2540,7 @@ bool DispatchInfo::IsPropertyAccessorVisible(bool fIsSetter, OBJECTREF* pMemberI MethodTable *pMemberInfoClass = (*pMemberInfo)->GetMethodTable(); - if (MscorlibBinder::IsClass(pMemberInfoClass, CLASS__PROPERTY)) + if (CoreLibBinder::IsClass(pMemberInfoClass, CLASS__PROPERTY)) { // Get the property's MethodDesc MethodDesc* pMDForProperty = NULL; @@ -2606,14 +2606,14 @@ MethodDesc* DispatchInfo::GetFieldInfoMD(BinderMethodID Method, TypeHandle hndFi MethodDesc *pMD; // If the current class is the standard implementation then return the cached method desc - if (MscorlibBinder::IsClass(hndFieldInfoType.GetMethodTable(), CLASS__FIELD)) + if (CoreLibBinder::IsClass(hndFieldInfoType.GetMethodTable(), CLASS__FIELD)) { - pMD = MscorlibBinder::GetMethod(Method); + pMD = CoreLibBinder::GetMethod(Method); } else { pMD = MemberLoader::FindMethod(hndFieldInfoType.GetMethodTable(), - MscorlibBinder::GetMethodName(Method), MscorlibBinder::GetMethodSig(Method)); + CoreLibBinder::GetMethodName(Method), CoreLibBinder::GetMethodSig(Method)); } _ASSERTE(pMD && "Unable to find specified FieldInfo method"); @@ -2635,14 +2635,14 @@ MethodDesc* DispatchInfo::GetPropertyInfoMD(BinderMethodID Method, TypeHandle hn MethodDesc *pMD; // If the current class is the standard implementation then return the cached method desc if present. - if (MscorlibBinder::IsClass(hndPropInfoType.GetMethodTable(), CLASS__PROPERTY)) + if (CoreLibBinder::IsClass(hndPropInfoType.GetMethodTable(), CLASS__PROPERTY)) { - pMD = MscorlibBinder::GetMethod(Method); + pMD = CoreLibBinder::GetMethod(Method); } else { pMD = MemberLoader::FindMethod(hndPropInfoType.GetMethodTable(), - MscorlibBinder::GetMethodName(Method), MscorlibBinder::GetMethodSig(Method)); + CoreLibBinder::GetMethodName(Method), CoreLibBinder::GetMethodSig(Method)); } _ASSERTE(pMD && "Unable to find specified PropertyInfo method"); @@ -2664,14 +2664,14 @@ MethodDesc* DispatchInfo::GetMethodInfoMD(BinderMethodID Method, TypeHandle hndM MethodDesc *pMD; // If the current class is the standard implementation then return the cached method desc. - if (MscorlibBinder::IsClass(hndMethodInfoType.GetMethodTable(), CLASS__METHOD)) + if (CoreLibBinder::IsClass(hndMethodInfoType.GetMethodTable(), CLASS__METHOD)) { - pMD = MscorlibBinder::GetMethod(Method); + pMD = CoreLibBinder::GetMethod(Method); } else { pMD = MemberLoader::FindMethod(hndMethodInfoType.GetMethodTable(), - MscorlibBinder::GetMethodName(Method), MscorlibBinder::GetMethodSig(Method)); + CoreLibBinder::GetMethodName(Method), CoreLibBinder::GetMethodSig(Method)); } _ASSERTE(pMD && "Unable to find specified MethodInfo method"); @@ -2691,7 +2691,7 @@ MethodDesc* DispatchInfo::GetCustomAttrProviderMD(TypeHandle hndCustomAttrProvid CONTRACT_END; MethodTable *pMT = hndCustomAttrProvider.AsMethodTable(); - MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICUSTOM_ATTR_PROVIDER__GET_CUSTOM_ATTRIBUTES), TRUE /* throwOnConflict */); + MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(CoreLibBinder::GetMethod(METHOD__ICUSTOM_ATTR_PROVIDER__GET_CUSTOM_ATTRIBUTES), TRUE /* throwOnConflict */); // Return the specified method desc. RETURN pMD; @@ -2889,7 +2889,7 @@ OBJECTREF DispatchInfo::GetOleAutBinder() if (m_hndOleAutBinder) return ObjectFromHandle(m_hndOleAutBinder); - MethodTable *pOleAutBinderClass = MscorlibBinder::GetClass(CLASS__OLE_AUT_BINDER); + MethodTable *pOleAutBinderClass = CoreLibBinder::GetClass(CLASS__OLE_AUT_BINDER); // Allocate an instance of the OleAutBinder class. OBJECTREF OleAutBinder = AllocateObject(pOleAutBinderClass); @@ -3021,7 +3021,7 @@ MethodDesc* DispatchInfo::GetInvokeMemberMD() } CONTRACT_END; - RETURN MscorlibBinder::GetMethod(METHOD__CLASS__INVOKE_MEMBER); + RETURN CoreLibBinder::GetMethod(METHOD__CLASS__INVOKE_MEMBER); } // Virtual method to retrieve the object associated with this DispatchInfo that @@ -3526,7 +3526,7 @@ MethodDesc* DispatchExInfo::GetIReflectMD(BinderMethodID Method) CONTRACT_END; MethodTable *pMT = m_pSimpleWrapperOwner->GetMethodTable(); - MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method), TRUE /* throwOnConflict */); + MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(CoreLibBinder::GetMethod(Method), TRUE /* throwOnConflict */); // Return the specified method desc. RETURN pMD; @@ -3546,7 +3546,7 @@ MethodDesc* DispatchExInfo::GetIExpandoMD(BinderMethodID Method) CONTRACT_END; MethodTable *pMT = m_pSimpleWrapperOwner->GetMethodTable(); - MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method), TRUE /* throwOnConflict */); + MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(CoreLibBinder::GetMethod(Method), TRUE /* throwOnConflict */); // Return the specified method desc. RETURN pMD; diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 752fbd016f23..1802705362ad 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -365,7 +365,7 @@ class ILStubState : public StubState pcs->EmitCALL(METHOD__CULTURE_INFO__GET_CURRENT_CULTURE, 0, 1); // save the current culture - LocalDesc locDescCulture(MscorlibBinder::GetClass(CLASS__CULTURE_INFO)); + LocalDesc locDescCulture(CoreLibBinder::GetClass(CLASS__CULTURE_INFO)); DWORD dwCultureLocalNum = pcs->NewLocal(locDescCulture); pcs->EmitSTLOC(dwCultureLocalNum); @@ -653,7 +653,7 @@ class ILStubState : public StubState MetaSig nsig( GetStubTargetMethodSig(), GetStubTargetMethodSigLength(), - MscorlibBinder::GetModule(), + CoreLibBinder::GetModule(), &typeContext); CorElementType type; @@ -881,7 +881,7 @@ class ILStubState : public StubState PCCOR_SIGNATURE pManagedSig; ULONG cManagedSig; - IMDInternalImport* pIMDI = MscorlibBinder::GetModule()->GetMDImport(); + IMDInternalImport* pIMDI = CoreLibBinder::GetModule()->GetMDImport(); pStubMD->GetSig(&pManagedSig, &cManagedSig); @@ -1246,7 +1246,7 @@ class StructMarshal_ILStubState : public ILStubState pCleanupStartLabel = pcsSetup->NewCodeLabel(); pReturnLabel = pcsSetup->NewCodeLabel(); - dwExceptionDispatchInfoLocal = pcsSetup->NewLocal(MscorlibBinder::GetClass(CLASS__EXCEPTION_DISPATCH_INFO)); + dwExceptionDispatchInfoLocal = pcsSetup->NewLocal(CoreLibBinder::GetClass(CLASS__EXCEPTION_DISPATCH_INFO)); pcsSetup->EmitLDNULL(); pcsSetup->EmitSTLOC(dwExceptionDispatchInfoLocal); @@ -1880,7 +1880,7 @@ void NDirectStubLinker::NeedsCleanupList() SetCleanupNeeded(); // we setup a new local that will hold the cleanup work list - LocalDesc desc(MscorlibBinder::GetClass(CLASS__CLEANUP_WORK_LIST_ELEMENT)); + LocalDesc desc(CoreLibBinder::GetClass(CLASS__CLEANUP_WORK_LIST_ELEMENT)); m_dwCleanupWorkListLocalNum = NewLocal(desc); } } @@ -1936,7 +1936,7 @@ void NDirectStubLinker::Begin(DWORD dwStubFlags) m_pcsDispatch->EmitADD(); m_pcsDispatch->EmitLDIND_I(); // get OBJECTHANDLE m_pcsDispatch->EmitLDIND_REF(); // get Delegate object - m_pcsDispatch->EmitLDFLD(GetToken(MscorlibBinder::GetField(FIELD__DELEGATE__TARGET))); + m_pcsDispatch->EmitLDFLD(GetToken(CoreLibBinder::GetField(FIELD__DELEGATE__TARGET))); } } @@ -2133,7 +2133,7 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth { if (SF_IsDelegateStub(dwStubFlags)) // reverse P/Invoke via delegate { - int tokDelegate_methodPtr = pcsEmit->GetToken(MscorlibBinder::GetField(FIELD__DELEGATE__METHOD_PTR)); + int tokDelegate_methodPtr = pcsEmit->GetToken(CoreLibBinder::GetField(FIELD__DELEGATE__METHOD_PTR)); EmitLoadStubContext(pcsEmit, dwStubFlags); pcsEmit->EmitLDC(offsetof(UMEntryThunk, m_pObjectHandle)); @@ -4341,7 +4341,7 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi // so we have to special-case it here. // If a type doesn't have a native representation, we won't set this flag. // We'll throw an exception later when setting up the marshalling. - if (pRetMT != MscorlibBinder::GetClass(CLASS__DATE_TIME) && pRetMT->HasLayout() && IsUnmanagedValueTypeReturnedByRef(pRetMT->GetNativeSize())) + if (pRetMT != CoreLibBinder::GetClass(CLASS__DATE_TIME) && pRetMT->HasLayout() && IsUnmanagedValueTypeReturnedByRef(pRetMT->GetNativeSize())) { ndirectflags |= NDirectMethodDesc::kStdCallWithRetBuf; } @@ -5170,7 +5170,7 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) LocalDesc i4(ELEMENT_TYPE_I4); sigBuilder.NewArg(&i4); - LocalDesc cleanupWorkList(MscorlibBinder::GetClass(CLASS__CLEANUP_WORK_LIST_ELEMENT)); + LocalDesc cleanupWorkList(CoreLibBinder::GetClass(CLASS__CLEANUP_WORK_LIST_ELEMENT)); cleanupWorkList.MakeByRef(); sigBuilder.NewArg(&cleanupWorkList); diff --git a/src/coreclr/src/vm/domainfile.cpp b/src/coreclr/src/vm/domainfile.cpp index 2740c1881fab..a398b1a92cda 100644 --- a/src/coreclr/src/vm/domainfile.cpp +++ b/src/coreclr/src/vm/domainfile.cpp @@ -286,7 +286,7 @@ CHECK DomainFile::CheckLoaded() if (IsLoaded()) CHECK_OK; - // Mscorlib is allowed to run managed code much earlier than other + // CoreLib is allowed to run managed code much earlier than other // assemblies for bootstrapping purposes. This is because it has no // dependencies, security checks, and doesn't rely on loader notifications. @@ -314,7 +314,7 @@ CHECK DomainFile::CheckActivated() if (IsActive()) CHECK_OK; - // Mscorlib is allowed to run managed code much earlier than other + // CoreLib is allowed to run managed code much earlier than other // assemblies for bootstrapping purposes. This is because it has no // dependencies, security checks, and doesn't rely on loader notifications. @@ -423,11 +423,11 @@ OBJECTREF DomainFile::GetExposedModuleObject() if (GetFile()->IsDynamic()) { - refClass = (REFLECTMODULEBASEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__MODULE_BUILDER)); + refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE_BUILDER)); } else { - refClass = (REFLECTMODULEBASEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__MODULE)); + refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE)); } refClass->SetModule(m_pModule); @@ -645,7 +645,7 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly) // - // CoreCLR hard binds to mscorlib.dll only. Avoid going through the full load. + // CoreCLR hard binds to CoreLib only. Avoid going through the full load. // #ifdef _DEBUG @@ -653,7 +653,7 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly) name.InitializeSpec(pDependency->dwAssemblyRef, ((pManifestNativeImage != NULL) ? pManifestNativeImage : pNativeImage)->GetNativeMDImport(), GetDomainAssembly()); - _ASSERTE(name.IsMscorlib()); + _ASSERTE(name.IsCoreLib()); #endif PEAssembly * pDependencyFile = SystemDomain::SystemFile(); @@ -753,8 +753,8 @@ BOOL DomainFile::IsZapRequired() } else if (IsSystem()) { - // mscorlib gets loaded before the CompilationDomain gets created. - // However, we may be ngening mscorlib itself + // CoreLib gets loaded before the CompilationDomain gets created. + // However, we may be ngening CoreLib itself fileIsBeingNGened = true; } @@ -1226,12 +1226,12 @@ OBJECTREF DomainAssembly::GetExposedAssemblyObject() // This is unnecessary because the managed InternalAssemblyBuilder object // should have already been created at the time of DefineDynamicAssembly OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - pMT = MscorlibBinder::GetClass(CLASS__INTERNAL_ASSEMBLY_BUILDER); + pMT = CoreLibBinder::GetClass(CLASS__INTERNAL_ASSEMBLY_BUILDER); } else { OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - pMT = MscorlibBinder::GetClass(CLASS__ASSEMBLY); + pMT = CoreLibBinder::GetClass(CLASS__ASSEMBLY); } // Will be TRUE only if LoaderAllocator managed object was already collected and therefore we should @@ -1793,7 +1793,7 @@ BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage) spec.InitializeSpec(this->GetFile()); // The assembly spec should have the binding context associated with it - _ASSERTE(spec.GetBindingContext() || spec.IsAssemblySpecForMscorlib()); + _ASSERTE(spec.GetBindingContext() || spec.IsAssemblySpecForCoreLib()); CORCOMPILE_VERSION_INFO *pVersionInfo = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo(); @@ -1818,7 +1818,7 @@ BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage) AssemblySpec name; name.InitializeSpec(pDependencies->dwAssemblyDef, pNativeImage->GetNativeMDImport(), this); - if (!name.IsAssemblySpecForMscorlib()) + if (!name.IsAssemblySpecForCoreLib()) { // We just initialized the assembly spec for the NI dependency. This will not have binding context // associated with it, so set it from that of the parent. diff --git a/src/coreclr/src/vm/domainfile.h b/src/coreclr/src/vm/domainfile.h index 2f1439b403fd..b3a0da389abd 100644 --- a/src/coreclr/src/vm/domainfile.h +++ b/src/coreclr/src/vm/domainfile.h @@ -445,7 +445,7 @@ enum ReasonForRejectingNativeImage { ReasonForRejectingNativeImage_NoNiForManifestModule = 0x101, ReasonForRejectingNativeImage_DependencyNotNative = 0x102, - ReasonForRejectingNativeImage_MscorlibNotNative = 0x103, + ReasonForRejectingNativeImage_CoreLibNotNative = 0x103, ReasonForRejectingNativeImage_FailedSecurityCheck = 0x104, ReasonForRejectingNativeImage_DependencyIdentityMismatch = 0x105, ReasonForRejectingNativeImage_CannotShareNiAssemblyNotDomainNeutral = 0x106, diff --git a/src/coreclr/src/vm/dwreport.cpp b/src/coreclr/src/vm/dwreport.cpp index 895ecbbadb53..58aadd134e81 100644 --- a/src/coreclr/src/vm/dwreport.cpp +++ b/src/coreclr/src/vm/dwreport.cpp @@ -1096,7 +1096,7 @@ ContractFailureKind GetContractFailureKind(OBJECTREF obj) PTR_MethodTable pMT = obj->GetMethodTable(); - if (MscorlibBinder::IsException(pMT, kContractException)) + if (CoreLibBinder::IsException(pMT, kContractException)) return CONTRACTEXCEPTIONREF(obj)->GetContractFailureKind(); // there are cases where the code contracts rewriter will use a ContractException @@ -1111,7 +1111,7 @@ ContractFailureKind GetContractFailureKind(OBJECTREF obj) ContractFailureKind result = CONTRACT_FAILURE_INVARIANT; // first compare the exception name. - PTR_MethodTable pContractExceptionMT = MscorlibBinder::GetClassIfExist(CLASS__CONTRACTEXCEPTION); + PTR_MethodTable pContractExceptionMT = CoreLibBinder::GetClassIfExist(CLASS__CONTRACTEXCEPTION); _ASSERTE(pContractExceptionMT); if (pContractExceptionMT) diff --git a/src/coreclr/src/vm/ecall.cpp b/src/coreclr/src/vm/ecall.cpp index 94a80c3c4a94..a86d12c4b434 100644 --- a/src/coreclr/src/vm/ecall.cpp +++ b/src/coreclr/src/vm/ecall.cpp @@ -16,12 +16,12 @@ #ifndef DACCESS_COMPILE #ifdef CROSSGEN_COMPILE -namespace CrossGenMscorlib +namespace CrossGenCoreLib { extern const ECClass c_rgECClasses[]; extern const int c_nECClasses; }; -using namespace CrossGenMscorlib; +using namespace CrossGenCoreLib; #else // CROSSGEN_COMPILE extern const ECClass c_rgECClasses[]; extern const int c_nECClasses; @@ -53,7 +53,7 @@ Utf8String, but String is similar.) add any void-returning metasig declarations if they haven't already been defined elsewhere. search "String_RetUtf8Str" for an example of how to do this. -- src/vm/mscorlib.h, search "DEFINE_CLASS(UTF8_STRING" and add the new DEFINE_METHOD +- src/vm/corelib.h, search "DEFINE_CLASS(UTF8_STRING" and add the new DEFINE_METHOD declarations for the Utf8String-returning Ctor methods, referencing the new metasig declarations. **********/ @@ -118,7 +118,7 @@ void ECall::PopulateManagedStringConstructors() _ASSERTE(g_pStringClass != NULL); for (int i = 0; i < NumberOfStringConstructors; i++) { - MethodDesc* pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__STRING__CTORF_FIRST + i)); + MethodDesc* pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__STRING__CTORF_FIRST + i)); _ASSERTE(pMD != NULL); PCODE pDest = pMD->GetMultiCallableAddrOfCode(); @@ -130,7 +130,7 @@ void ECall::PopulateManagedStringConstructors() _ASSERTE(g_pUtf8StringClass != NULL); for (int i = 0; i < NumberOfUtf8StringConstructors; i++) { - MethodDesc* pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__UTF8STRING__CTORF_FIRST + i)); + MethodDesc* pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__UTF8STRING__CTORF_FIRST + i)); _ASSERTE(pMD != NULL); PCODE pDest = pMD->GetMultiCallableAddrOfCode(); @@ -148,7 +148,7 @@ void ECall::PopulateManagedCastHelpers() STANDARD_VM_CONTRACT; - MethodDesc* pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFANY)); + MethodDesc* pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFANY)); PCODE pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFANY, pDest); // array cast uses the "ANY" helper @@ -158,16 +158,16 @@ void ECall::PopulateManagedCastHelpers() // When interface table uses indirect references, just set interface casts to "ANY" helper SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFINTERFACE, pDest); #else - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFINTERFACE)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFINTERFACE)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFINTERFACE, pDest); #endif - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFCLASS)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFCLASS)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFCLASS, pDest); - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTANY)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTANY)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_CHKCASTANY, pDest); // array cast uses the "ANY" helper @@ -177,20 +177,20 @@ void ECall::PopulateManagedCastHelpers() // When interface table uses indirect references, just set interface casts to "ANY" handler SetJitHelperFunction(CORINFO_HELP_CHKCASTINTERFACE, pDest); #else - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTINTERFACE)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTINTERFACE)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_CHKCASTINTERFACE, pDest); #endif - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTCLASS)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTCLASS)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_CHKCASTCLASS, pDest); - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTCLASSSPECIAL)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTCLASSSPECIAL)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_CHKCASTCLASS_SPECIAL, pDest); - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__UNBOX)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__UNBOX)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_UNBOX, pDest); @@ -203,14 +203,14 @@ void ECall::PopulateManagedCastHelpers() //TODO: revise if this specialcasing is still needed when crossgen supports tailcall optimizations // see: https://github.com/dotnet/runtime/issues/5857 - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__STELEMREF)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__STELEMREF)); pMD->DoPrestub(NULL); // This helper is marked AggressiveOptimization and its native code is in its final form. // Get the code directly to avoid PreStub indirection. pDest = pMD->GetNativeCode(); SetJitHelperFunction(CORINFO_HELP_ARRADDR_ST, pDest); - pMD = MscorlibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__LDELEMAREF)); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__LDELEMAREF)); pMD->DoPrestub(NULL); // This helper is marked AggressiveOptimization and its native code is in its final form. // Get the code directly to avoid PreStub indirection. @@ -344,11 +344,11 @@ static INT FindECIndexForMethod(MethodDesc *pMD, const LPVOID* impls) if (cur->HasSignature()) { - Signature sig = MscorlibBinder::GetTargetSignature(cur->m_pMethodSig); + Signature sig = CoreLibBinder::GetTargetSignature(cur->m_pMethodSig); //@GENERICS: none of these methods belong to generic classes so there is no instantiation info to pass in if (!MetaSig::CompareMethodSigs(pMethodSig, cbMethodSigLen, pModule, NULL, - sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), NULL, FALSE)) + sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule(), NULL, FALSE)) { continue; } @@ -461,7 +461,7 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // We need to set up the ECFunc properly. We don't want to use the pMD passed in, // since it may disappear. Instead, use the stable one on Delegate. Remember // that this is 1:M between the FCall and the pMDs. - return GetFCallImpl(MscorlibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE)); + return GetFCallImpl(CoreLibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE)); } // COM imported classes have special constructors @@ -498,16 +498,16 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // // You'll see this assert in several situations, almost all being the fault of whomever // last touched a particular ecall or fcall method, either here or in the classlibs. - // However, you must also ensure you don't have stray copies of mscorlib.dll on your machine. + // However, you must also ensure you don't have stray copies of System.Private.CoreLib.dll on your machine. // 1) You forgot to add your class to c_rgECClasses, the list of classes w/ ecall & fcall methods. // 2) You forgot to add your particular method to the ECFunc array for your class. // 3) You misspelled the name of your function and/or classname. // 4) The signature of the managed function doesn't match the hardcoded metadata signature // listed in your ECFunc array. The hardcoded metadata sig is only necessary to disambiguate // overloaded ecall functions - usually you can leave it set to NULL. - // 5) Your copy of mscorlib.dll & mscoree.dll are out of sync - rebuild both. - // 6) You've loaded the wrong copy of mscorlib.dll. In msdev's debug menu, - // select the "Modules..." dialog. Verify the path for mscorlib is right. + // 5) Your copy of System.Private.CoreLib.dll & coreclr.dll are out of sync - rebuild both. + // 6) You've loaded the wrong copy of System.Private.CoreLib.dll. In Visual Studio's debug menu, + // select the "Modules..." dialog. Verify the path for System.Private.CoreLib is right. // 7) Someone mucked around with how the signatures in metasig.h are parsed, changing the // interpretation of a part of the signature (this is very rare & extremely unlikely, // but has happened at least once). @@ -631,7 +631,7 @@ BOOL ECall::CheckUnusedECalls(SetSHash& usedIDs) if (!usedIDs.Contains(id)) { - printf("CheckMscorlibExtended: Unused ecall found: %s.%s::%s\n", pECClass->m_szNameSpace, c_rgECClasses[ImplsIndex].m_szClassName, ptr->m_szMethodName); + printf("CheckCoreLibExtended: Unused ecall found: %s.%s::%s\n", pECClass->m_szNameSpace, c_rgECClasses[ImplsIndex].m_szClassName, ptr->m_szMethodName); fUnusedFCallsFound = TRUE; continue; } @@ -641,7 +641,7 @@ BOOL ECall::CheckUnusedECalls(SetSHash& usedIDs) if (fUnreferencedType) { - printf("CheckMscorlibExtended: Unused type found: %s.%s\n", c_rgECClasses[ImplsIndex].m_szNameSpace, c_rgECClasses[ImplsIndex].m_szClassName); + printf("CheckCoreLibExtended: Unused type found: %s.%s\n", c_rgECClasses[ImplsIndex].m_szNameSpace, c_rgECClasses[ImplsIndex].m_szClassName); fUnusedFCallsFound = TRUE; continue; } @@ -803,7 +803,7 @@ CorInfoIntrinsics ECall::GetIntrinsicID(MethodDesc* pMD) return(CORINFO_INTRINSIC_Illegal); } - // All intrinsic live in mscorlib.dll (FindECFuncForMethod does not work for non-mscorlib intrinsics) + // All intrinsic live in CoreLib (FindECFuncForMethod does not work for non-CoreLib intrinsics) if (!pMD->GetModule()->IsSystem()) { return(CORINFO_INTRINSIC_Illegal); diff --git a/src/coreclr/src/vm/ecall.h b/src/coreclr/src/vm/ecall.h index b677cfe1d183..19b875382870 100644 --- a/src/coreclr/src/vm/ecall.h +++ b/src/coreclr/src/vm/ecall.h @@ -37,7 +37,7 @@ enum { FCFuncFlag_EndOfArray = 0x01, FCFuncFlag_HasSignature = 0x02, FCFuncFlag_Unreferenced = 0x04, // Suppress unused fcall check - FCFuncFlag_QCall = 0x08, // QCall - mscorlib.dll to mscorwks.dll transition implemented as PInvoke + FCFuncFlag_QCall = 0x08, // QCall - CoreLib to VM transition implemented as PInvoke }; struct ECFunc { diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 3312004c73ea..e4896f2000f6 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -415,7 +415,7 @@ FCFuncStart(gCOMClassWriter) FCFuncEnd() FCFuncStart(gCompatibilitySwitchFuncs) - FCFuncElement("GetValueInternalCall", CompatibilitySwitch::GetValue) + FCFuncElement("GetValueInternal", CompatibilitySwitch::GetValue) FCFuncEnd() FCFuncStart(gMdUtf8String) diff --git a/src/coreclr/src/vm/eedbginterfaceimpl.cpp b/src/coreclr/src/vm/eedbginterfaceimpl.cpp index 469c2221f47b..002250d72825 100644 --- a/src/coreclr/src/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/src/vm/eedbginterfaceimpl.cpp @@ -930,7 +930,7 @@ TypeHandle EEDbgInterfaceImpl::FindLoadedElementType(CorElementType et) // Lookup operations run the class loader in non-load mode. ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE(); - MethodTable *m = MscorlibBinder::GetElementType(et); + MethodTable *m = CoreLibBinder::GetElementType(et); return TypeHandle(m); } @@ -1021,7 +1021,7 @@ TypeHandle EEDbgInterfaceImpl::LoadElementType(CorElementType et) } CONTRACTL_END; - MethodTable *m = MscorlibBinder::GetElementType(et); + MethodTable *m = CoreLibBinder::GetElementType(et); if (m == NULL) { diff --git a/src/coreclr/src/vm/encee.cpp b/src/coreclr/src/vm/encee.cpp index 7852863a4bfb..a230ae29bb48 100644 --- a/src/coreclr/src/vm/encee.cpp +++ b/src/coreclr/src/vm/encee.cpp @@ -1107,7 +1107,7 @@ EnCAddedField *EnCAddedField::Allocate(OBJECTREF thisPointer, EnCFieldDesc *pFD) // the OBJECTREF address so we need to hand out something else that is hooked up to the handle. GCPROTECT_BEGIN(thisPointer); - MethodTable *pHelperMT = MscorlibBinder::GetClass(CLASS__ENC_HELPER); + MethodTable *pHelperMT = CoreLibBinder::GetClass(CLASS__ENC_HELPER); pEntry->m_FieldData = pDomain->CreateDependentHandle(thisPointer, AllocateObject(pHelperMT)); GCPROTECT_END(); @@ -1139,7 +1139,7 @@ EnCAddedField *EnCAddedField::Allocate(OBJECTREF thisPointer, EnCFieldDesc *pFD) GCPROTECT_BEGIN (obj); // Get a FieldDesc for the object reference field in the EnC helper object (warning: triggers) - FieldDesc *pHelperField = MscorlibBinder::GetField(FIELD__ENC_HELPER__OBJECT_REFERENCE); + FieldDesc *pHelperField = CoreLibBinder::GetField(FIELD__ENC_HELPER__OBJECT_REFERENCE); // store the empty boxed object into the helper object IGCHandleManager *mgr = GCHandleUtilities::GetGCHandleManager(); @@ -1260,7 +1260,7 @@ PTR_CBYTE EnCSyncBlockInfo::ResolveField(OBJECTREF thisPointer, EnCFieldDesc *pF // We _HAVE_ to call GetExistingField b/c (a) we can't throw exceptions, and // (b) we _DON'T_ want to run class init code, either. - pHelperFieldDesc = MscorlibBinder::GetExistingField(FIELD__ENC_HELPER__OBJECT_REFERENCE); + pHelperFieldDesc = CoreLibBinder::GetExistingField(FIELD__ENC_HELPER__OBJECT_REFERENCE); if (pHelperFieldDesc == NULL) { return NULL; @@ -1348,7 +1348,7 @@ PTR_CBYTE EnCSyncBlockInfo::ResolveOrAllocateField(OBJECTREF thisPointer, EnCFie FieldDesc * pHelperField = NULL; GCPROTECT_BEGIN (pHelper); - pHelperField = MscorlibBinder::GetField(FIELD__ENC_HELPER__OBJECT_REFERENCE); + pHelperField = CoreLibBinder::GetField(FIELD__ENC_HELPER__OBJECT_REFERENCE); GCPROTECT_END (); return GetEnCFieldAddrFromHelperFieldDesc(pHelperField, pHelper, pFD); diff --git a/src/coreclr/src/vm/eventpipeevent.cpp b/src/coreclr/src/vm/eventpipeevent.cpp index 62d97c07820f..79c56d8bef79 100644 --- a/src/coreclr/src/vm/eventpipeevent.cpp +++ b/src/coreclr/src/vm/eventpipeevent.cpp @@ -74,7 +74,7 @@ BYTE *EventPipeEvent::BuildMinimumMetadata() BYTE *minmumMetadata = new BYTE[MinimumMetadataLength]; BYTE *currentPtr = minmumMetadata; - // the order of fields is defined in coreclr\src\mscorlib\shared\System\Diagnostics\Tracing\EventSource.cs DefineEventPipeEvents method + // the order of fields is defined in EventSource.cs DefineEventPipeEvents method memcpy(currentPtr, &m_eventID, sizeof(m_eventID)); currentPtr += sizeof(m_eventID); diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index 2fe726af2997..67a134072397 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -4729,7 +4729,7 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept _ASSERTE(pExInfo != NULL); bIsNestedException = (pExInfo->GetPreviousExceptionTracker() != NULL); bIsCLSCompliant = IsException((gc.exceptionObj)->GetMethodTable()) && - ((gc.exceptionObj)->GetMethodTable() != MscorlibBinder::GetException(kRuntimeWrappedException)); + ((gc.exceptionObj)->GetMethodTable() != CoreLibBinder::GetException(kRuntimeWrappedException)); // A rethrown exception is also a nested exception // but since we have a separate flag for it, lets unset the nested flag diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 2366aea21e7d..258f3aedf004 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -357,11 +357,11 @@ void SetExceptionAVParameters( // No return. GCPROTECT_BEGIN(throwable) { // This should only be called for AccessViolationException - _ASSERTE(MscorlibBinder::GetException(kAccessViolationException) == throwable->GetMethodTable()); + _ASSERTE(CoreLibBinder::GetException(kAccessViolationException) == throwable->GetMethodTable()); - FieldDesc *pFD_ip = MscorlibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__IP); - FieldDesc *pFD_target = MscorlibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__TARGET); - FieldDesc *pFD_access = MscorlibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__ACCESSTYPE); + FieldDesc *pFD_ip = CoreLibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__IP); + FieldDesc *pFD_target = CoreLibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__TARGET); + FieldDesc *pFD_access = CoreLibBinder::GetField(FIELD__ACCESS_VIOLATION_EXCEPTION__ACCESSTYPE); _ASSERTE(pFD_ip->GetFieldType() == ELEMENT_TYPE_I); _ASSERTE(pFD_target->GetFieldType() == ELEMENT_TYPE_I); @@ -456,12 +456,12 @@ void WrapNonCompliantException(OBJECTREF *ppThrowable) { // idempotent operations, so the race condition is okay. if (pMT_RuntimeWrappedException == NULL) - pMT_RuntimeWrappedException = MscorlibBinder::GetException(kRuntimeWrappedException); + pMT_RuntimeWrappedException = CoreLibBinder::GetException(kRuntimeWrappedException); if (pFD_WrappedException == NULL) - pFD_WrappedException = MscorlibBinder::GetField(FIELD__RUNTIME_WRAPPED_EXCEPTION__WRAPPED_EXCEPTION); + pFD_WrappedException = CoreLibBinder::GetField(FIELD__RUNTIME_WRAPPED_EXCEPTION__WRAPPED_EXCEPTION); - OBJECTREF orWrapper = AllocateObject(MscorlibBinder::GetException(kRuntimeWrappedException)); + OBJECTREF orWrapper = AllocateObject(CoreLibBinder::GetException(kRuntimeWrappedException)); GCPROTECT_BEGIN(orWrapper); @@ -577,7 +577,7 @@ void CreateTypeInitializationExceptionObject(LPCWSTR pTypeThatFailed, // in the code that follows. if (!isAlreadyCreating.GetValue()) { pThread->SetIsCreatingTypeInitException(); - pMT = MscorlibBinder::GetException(kTypeInitializationException); + pMT = CoreLibBinder::GetException(kTypeInitializationException); methodID = METHOD__TYPE_INIT_EXCEPTION__STR_EX_CTOR; } else { @@ -3490,9 +3490,7 @@ BOOL IsExceptionOfType(RuntimeExceptionKind reKind, OBJECTREF *pThrowable) MethodTable *pThrowableMT = (*pThrowable)->GetMethodTable(); - // IsExceptionOfType is supported for mscorlib exception types only - _ASSERTE(reKind <= kLastExceptionInMscorlib); - return MscorlibBinder::IsException(pThrowableMT, reKind); + return CoreLibBinder::IsException(pThrowableMT, reKind); } BOOL IsAsyncThreadException(OBJECTREF *pThrowable) { @@ -10895,7 +10893,7 @@ BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable switch (dwExceptionCode) { case STATUS_ACCESS_VIOLATION: - if (throwable != NULL && MscorlibBinder::IsException(throwable->GetMethodTable(), kNullReferenceException)) + if (throwable != NULL && CoreLibBinder::IsException(throwable->GetMethodTable(), kNullReferenceException)) return FALSE; break; case STATUS_STACK_OVERFLOW: @@ -10972,7 +10970,7 @@ void ExceptionNotifications::GetEventArgsForNotification(ExceptionNotificationHa switch(notificationType) { case FirstChanceExceptionHandler: - pMTEventArgs = MscorlibBinder::GetClass(CLASS__FIRSTCHANCE_EVENTARGS); + pMTEventArgs = CoreLibBinder::GetClass(CLASS__FIRSTCHANCE_EVENTARGS); idEventArgsCtor = METHOD__FIRSTCHANCE_EVENTARGS__CTOR; break; default: @@ -11037,7 +11035,7 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN // Do we have handler(s) of the specific type wired up? if (notificationType == FirstChanceExceptionHandler) { - return MscorlibBinder::GetField(FIELD__APPCONTEXT__FIRST_CHANCE_EXCEPTION)->GetStaticOBJECTREF() != NULL; + return CoreLibBinder::GetField(FIELD__APPCONTEXT__FIRST_CHANCE_EXCEPTION)->GetStaticOBJECTREF() != NULL; } else { @@ -11135,7 +11133,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa // Get the reference to the delegate based upon the type of notification if (notificationType == FirstChanceExceptionHandler) { - gc.oNotificationDelegate = MscorlibBinder::GetField(FIELD__APPCONTEXT__FIRST_CHANCE_EXCEPTION)->GetStaticOBJECTREF(); + gc.oNotificationDelegate = CoreLibBinder::GetField(FIELD__APPCONTEXT__FIRST_CHANCE_EXCEPTION)->GetStaticOBJECTREF(); } else { diff --git a/src/coreclr/src/vm/field.cpp b/src/coreclr/src/vm/field.cpp index b3d4bde947a0..8256640de063 100644 --- a/src/coreclr/src/vm/field.cpp +++ b/src/coreclr/src/vm/field.cpp @@ -878,7 +878,7 @@ REFLECTFIELDREF FieldDesc::GetStubFieldInfo() CONTRACTL_END; REFLECTFIELDREF retVal; - REFLECTFIELDREF fieldRef = (REFLECTFIELDREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBFIELDINFO)); + REFLECTFIELDREF fieldRef = (REFLECTFIELDREF)AllocateObject(CoreLibBinder::GetClass(CLASS__STUBFIELDINFO)); GCPROTECT_BEGIN(fieldRef); fieldRef->SetField(this); diff --git a/src/coreclr/src/vm/fieldmarshaler.cpp b/src/coreclr/src/vm/fieldmarshaler.cpp index c7b5910e54a5..4b1b7abc39ca 100644 --- a/src/coreclr/src/vm/fieldmarshaler.cpp +++ b/src/coreclr/src/vm/fieldmarshaler.cpp @@ -129,15 +129,15 @@ VOID ParseNativeType(Module* pModule, #endif break; case MarshalInfo::MARSHAL_TYPE_CURRENCY: - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__CURRENCY)); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__CURRENCY)); break; case MarshalInfo::MARSHAL_TYPE_DECIMAL: // The decimal type can't be blittable since the managed and native alignment requirements differ. // Native needs 8-byte alignment since one field is a 64-bit integer, but managed only needs 4-byte alignment since all fields are ints. - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__NATIVEDECIMAL)); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__NATIVEDECIMAL)); break; case MarshalInfo::MARSHAL_TYPE_GUID: - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__GUID)); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__GUID)); break; case MarshalInfo::MARSHAL_TYPE_DATE: *pNFD = NativeFieldDescriptor(pFD, NativeFieldCategory::FLOAT, sizeof(double), sizeof(double)); @@ -168,7 +168,7 @@ VOID ParseNativeType(Module* pModule, break; #ifdef FEATURE_COMINTEROP case MarshalInfo::MARSHAL_TYPE_OBJECT: - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__NATIVEVARIANT)); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__NATIVEVARIANT)); break; #endif case MarshalInfo::MARSHAL_TYPE_SAFEHANDLE: @@ -184,17 +184,17 @@ VOID ParseNativeType(Module* pModule, if (pMT->IsEnum()) { - pMT = MscorlibBinder::GetElementType(pMT->GetInternalCorElementType()); + pMT = CoreLibBinder::GetElementType(pMT->GetInternalCorElementType()); } *pNFD = NativeFieldDescriptor(pFD, OleVariant::GetNativeMethodTableForVarType(mops.elementType, pMT), mops.additive); break; } case MarshalInfo::MARSHAL_TYPE_FIXED_CSTR: - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__BYTE), pargs->fs.fixedStringLength); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__BYTE), pargs->fs.fixedStringLength); break; case MarshalInfo::MARSHAL_TYPE_FIXED_WSTR: - *pNFD = NativeFieldDescriptor(pFD, MscorlibBinder::GetClass(CLASS__UINT16), pargs->fs.fixedStringLength); + *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__UINT16), pargs->fs.fixedStringLength); break; case MarshalInfo::MARSHAL_TYPE_UNKNOWN: default: @@ -269,7 +269,7 @@ bool IsFieldBlittable( { isBlittable = false; } - else if (valueTypeHandle.GetMethodTable() == MscorlibBinder::GetClass(CLASS__DECIMAL)) + else if (valueTypeHandle.GetMethodTable() == CoreLibBinder::GetClass(CLASS__DECIMAL)) { // The alignment requirements of the managed System.Decimal type do not match the native DECIMAL type. // As a result, a field of type System.Decimal can't be blittable. diff --git a/src/coreclr/src/vm/gchelpers.cpp b/src/coreclr/src/vm/gchelpers.cpp index 5a8877423a0d..d08a74783920 100644 --- a/src/coreclr/src/vm/gchelpers.cpp +++ b/src/coreclr/src/vm/gchelpers.cpp @@ -757,7 +757,7 @@ OBJECTREF AllocatePrimitiveArray(CorElementType type, DWORD cElements) // Fetch the proper array type if (g_pPredefinedArrayTypes[type] == NULL) { - TypeHandle elemType = TypeHandle(MscorlibBinder::GetElementType(type)); + TypeHandle elemType = TypeHandle(CoreLibBinder::GetElementType(type)); TypeHandle typHnd = ClassLoader::LoadArrayTypeThrowing(elemType, ELEMENT_TYPE_SZARRAY, 0); g_pPredefinedArrayTypes[type] = typHnd; } diff --git a/src/coreclr/src/vm/gdbjit.cpp b/src/coreclr/src/vm/gdbjit.cpp index 9e12ec4b3cbf..1f358eb2d68b 100644 --- a/src/coreclr/src/vm/gdbjit.cpp +++ b/src/coreclr/src/vm/gdbjit.cpp @@ -171,7 +171,7 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, refTypeInfo.SuppressRelease(); TypeInfoBase* lengthTypeInfo = GetTypeInfoFromTypeHandle( - TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)), pTypeMap, method); + TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_I4)), pTypeMap, method); TypeInfoBase* valTypeInfo = GetTypeInfoFromTypeHandle(typeHandle.GetArrayElementTypeHandle(), pTypeMap, method); info->m_array_type = new ArrayTypeInfo(typeHandle, 1, valTypeInfo); @@ -188,7 +188,7 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, if (pMT->GetRank() != 1) { - TypeHandle dwordArray(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)); + TypeHandle dwordArray(CoreLibBinder::GetElementType(ELEMENT_TYPE_I4)); info->m_array_bounds_type = new ArrayTypeInfo(dwordArray.MakeSZArray(), pMT->GetRank(), lengthTypeInfo); info->members[2].m_member_name = new char[9]; strcpy(info->members[2].m_member_name, "m_Bounds"); diff --git a/src/coreclr/src/vm/genericdict.cpp b/src/coreclr/src/vm/genericdict.cpp index b378f9225792..1fb05846c3c4 100644 --- a/src/coreclr/src/vm/genericdict.cpp +++ b/src/coreclr/src/vm/genericdict.cpp @@ -977,11 +977,11 @@ Dictionary::PopulateEntry( Module * pContainingZapModule = ExecutionManager::FindZapModule(dac_cast(signature)); - zapSigContext = ZapSig::Context(MscorlibBinder::GetModule(), (void *)pContainingZapModule, ZapSig::NormalTokens); + zapSigContext = ZapSig::Context(CoreLibBinder::GetModule(), (void *)pContainingZapModule, ZapSig::NormalTokens); pZapSigContext = (pContainingZapModule != NULL) ? &zapSigContext : NULL; } - Module * pLookupModule = (isReadyToRunModule) ? pZapSigContext->pInfoModule : MscorlibBinder::GetModule(); + Module * pLookupModule = (isReadyToRunModule) ? pZapSigContext->pInfoModule : CoreLibBinder::GetModule(); if (pMT != NULL) { diff --git a/src/coreclr/src/vm/ilmarshalers.cpp b/src/coreclr/src/vm/ilmarshalers.cpp index 8f57b1cf1569..0e74014a45f1 100644 --- a/src/coreclr/src/vm/ilmarshalers.cpp +++ b/src/coreclr/src/vm/ilmarshalers.cpp @@ -19,7 +19,7 @@ LocalDesc ILReflectionObjectMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(GetManagedTypeBinderID())); + return LocalDesc(CoreLibBinder::GetClass(GetManagedTypeBinderID())); } LocalDesc ILReflectionObjectMarshaler::GetNativeType() @@ -33,7 +33,7 @@ void ILReflectionObjectMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* p { STANDARD_VM_CONTRACT; - int tokObject__m_handle = pslILEmit->GetToken(MscorlibBinder::GetField(GetObjectFieldID())); + int tokObject__m_handle = pslILEmit->GetToken(CoreLibBinder::GetField(GetObjectFieldID())); int tokStruct__m_object = 0; BinderFieldID structField = GetStructureFieldID(); @@ -41,7 +41,7 @@ void ILReflectionObjectMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* p // marshaling a struct referring to an object containing a handle. if (structField != 0) { - tokStruct__m_object = pslILEmit->GetToken(MscorlibBinder::GetField(structField)); + tokStruct__m_object = pslILEmit->GetToken(CoreLibBinder::GetField(structField)); } ILCodeLabel* pNullLabel = pslILEmit->NewCodeLabel(); @@ -379,7 +379,7 @@ void ILWSTRMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit) LocalDesc locDesc = GetManagedType(); locDesc.MakePinned(); DWORD dwPinnedLocal = pslILEmit->NewLocal(locDesc); - int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__STRING__M_FIRST_CHAR)); + int fieldDef = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__STRING__M_FIRST_CHAR)); ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); pslILEmit->EmitLoadNullPtr(); @@ -509,7 +509,7 @@ void ILOptimizedAllocMarshaler::EmitClearNative(ILCodeStream* pslILEmit) LocalDesc ILUTF8BufferMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__STRING_BUILDER)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__STRING_BUILDER)); } void ILUTF8BufferMarshaler::EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) @@ -659,7 +659,7 @@ LocalDesc ILWSTRBufferMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__STRING_BUILDER)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__STRING_BUILDER)); } void ILWSTRBufferMarshaler::EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) @@ -860,7 +860,7 @@ LocalDesc ILCSTRBufferMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__STRING_BUILDER)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__STRING_BUILDER)); } void ILCSTRBufferMarshaler::EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) @@ -885,7 +885,7 @@ void ILCSTRBufferMarshaler::EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) // stack: capacity - pslILEmit->EmitLDSFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE))); + pslILEmit->EmitLDSFLD(pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE))); pslILEmit->EmitMUL_OVF(); // stack: capacity_in_bytes @@ -1141,7 +1141,7 @@ LocalDesc ILObjectMarshaler::GetNativeType() { STANDARD_VM_CONTRACT; - return LocalDesc(TypeHandle(MscorlibBinder::GetClass(CLASS__NATIVEVARIANT))); + return LocalDesc(TypeHandle(CoreLibBinder::GetClass(CLASS__NATIVEVARIANT))); } LocalDesc ILObjectMarshaler::GetManagedType() @@ -1238,7 +1238,7 @@ LocalDesc ILDateMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__DATE_TIME)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__DATE_TIME)); } void ILDateMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) @@ -1279,14 +1279,14 @@ LocalDesc ILCurrencyMarshaler::GetNativeType() { STANDARD_VM_CONTRACT; - return LocalDesc(TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY))); + return LocalDesc(TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY))); } LocalDesc ILCurrencyMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL))); + return LocalDesc(TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL))); } @@ -1295,7 +1295,7 @@ void ILCurrencyMarshaler::EmitReInitNative(ILCodeStream* pslILEmit) STANDARD_VM_CONTRACT; EmitLoadNativeHomeAddr(pslILEmit); - pslILEmit->EmitINITOBJ(pslILEmit->GetToken(TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY)))); + pslILEmit->EmitINITOBJ(pslILEmit->GetToken(TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY)))); } void ILCurrencyMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) @@ -2075,7 +2075,7 @@ void ILCSTRMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) pslILEmit->EmitADD(); // (String.Length + 2) * GetMaxDBCSCharByteSize() - pslILEmit->EmitLDSFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE))); + pslILEmit->EmitLDSFLD(pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE))); pslILEmit->EmitMUL_OVF(); // BufSize = (String.Length + 2) * GetMaxDBCSCharByteSize() @@ -2336,7 +2336,7 @@ void ILBlittablePtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslIL ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); UINT uNativeSize = m_pargs->m_pMT->GetNativeSize(); - int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + int fieldDef = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); EmitLoadNativeValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); @@ -2358,7 +2358,7 @@ void ILBlittablePtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslIL ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); UINT uNativeSize = m_pargs->m_pMT->GetNativeSize(); - int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + int fieldDef = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); @@ -2478,7 +2478,7 @@ void ILBlittableLayoutClassMarshaler::EmitConvertContentsCLRToNative(ILCodeStrea ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); UINT uNativeSize = m_pargs->m_pMT->GetNativeSize(); - int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + int fieldDef = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); EmitLoadNativeHomeAddr(pslILEmit); pslILEmit->EmitLDC(0); @@ -2504,7 +2504,7 @@ void ILBlittableLayoutClassMarshaler::EmitConvertContentsNativeToCLR(ILCodeStrea STANDARD_VM_CONTRACT; UINT uNativeSize = m_pargs->m_pMT->GetNativeSize(); - int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + int fieldDef = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(m_pargs->m_pMT)); pslILEmit->EmitCALL(METHOD__TYPE__GET_TYPE_FROM_HANDLE, 1, 1); @@ -2550,11 +2550,11 @@ MarshalerOverrideStatus ILHandleRefMarshaler::ArgumentOverride(NDirectStubLinker // HandleRefs are valuetypes, so pinning is not needed. // The argument address is on the stack and will not move. - mdFieldDef handleField = pcsDispatch->GetToken(MscorlibBinder::GetField(FIELD__HANDLE_REF__HANDLE)); + mdFieldDef handleField = pcsDispatch->GetToken(CoreLibBinder::GetField(FIELD__HANDLE_REF__HANDLE)); pcsDispatch->EmitLDARG(argidx); pcsDispatch->EmitLDFLD(handleField); - mdFieldDef wrapperField = pcsUnmarshal->GetToken(MscorlibBinder::GetField(FIELD__HANDLE_REF__WRAPPER)); + mdFieldDef wrapperField = pcsUnmarshal->GetToken(CoreLibBinder::GetField(FIELD__HANDLE_REF__WRAPPER)); pcsUnmarshal->EmitLDARG(argidx); pcsUnmarshal->EmitLDFLD(wrapperField); pcsUnmarshal->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0); @@ -2606,7 +2606,7 @@ void ILSafeHandleMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEm EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(failureLabel); EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitLDFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE))); + pslILEmit->EmitLDFLD(pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE))); EmitLoadNativeValue(pslILEmit); pslILEmit->EmitBEQ(successLabel); pslILEmit->EmitLabel(failureLabel); @@ -2659,7 +2659,7 @@ MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinke // Grab the token for the native handle field embedded inside the SafeHandle. We'll be using it to direct access the // native handle later. - mdToken tkNativeHandleField = pslIL->GetToken(MscorlibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE)); + mdToken tkNativeHandleField = pslIL->GetToken(CoreLibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE)); // The high level logic (note that the parameter may be in, out or both): // 1) If this is an input parameter we need to AddRef the SafeHandle and schedule a Release cleanup item. @@ -2883,7 +2883,7 @@ ILSafeHandleMarshaler::ReturnOverride( pslIL->EmitNEWOBJ(pslIL->GetToken(pMDCtor), 0); pslIL->EmitSTLOC(dwReturnHandleLocal); - mdToken tkNativeHandleField = pslPostIL->GetToken(MscorlibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE)); + mdToken tkNativeHandleField = pslPostIL->GetToken(CoreLibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE)); // 3) create local to hold returned handle DWORD dwReturnNativeHandleLocal = pslIL->NewLocal(ELEMENT_TYPE_I); @@ -2948,7 +2948,7 @@ void ILCriticalHandleMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* psl _ASSERTE(IsFieldMarshal(m_dwMarshalFlags)); EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitLDFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE))); + pslILEmit->EmitLDFLD(pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE))); EmitStoreNativeValue(pslILEmit); } @@ -2962,7 +2962,7 @@ void ILCriticalHandleMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* psl EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(failureLabel); EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitLDFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE))); + pslILEmit->EmitLDFLD(pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE))); EmitLoadNativeValue(pslILEmit); pslILEmit->EmitBEQ(successLabel); pslILEmit->EmitLabel(failureLabel); @@ -3000,7 +3000,7 @@ MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(NDirectStubL // Grab the token for the native handle field embedded inside the CriticalHandle. We'll be using it to direct access // the native handle later. - mdToken tkNativeHandleField = pslIL->GetToken(MscorlibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE)); + mdToken tkNativeHandleField = pslIL->GetToken(CoreLibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE)); if (byref) { @@ -3218,7 +3218,7 @@ ILCriticalHandleMarshaler::ReturnOverride( pslIL->EmitNEWOBJ(pslIL->GetToken(pMDCtor), 0); pslIL->EmitSTLOC(dwReturnHandleLocal); - mdToken tkNativeHandleField = pslPostIL->GetToken(MscorlibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE)); + mdToken tkNativeHandleField = pslPostIL->GetToken(CoreLibBinder::GetField(FIELD__CRITICAL_HANDLE__HANDLE)); // 3) create local to hold returned handle DWORD dwReturnNativeHandleLocal = pslIL->NewLocal(ELEMENT_TYPE_I); @@ -3376,7 +3376,7 @@ LocalDesc ILArgIteratorMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__ARG_ITERATOR)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__ARG_ITERATOR)); } bool ILArgIteratorMarshaler::SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) @@ -3432,7 +3432,7 @@ LocalDesc ILArrayWithOffsetMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__ARRAY_WITH_OFFSET)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__ARRAY_WITH_OFFSET)); } bool ILArrayWithOffsetMarshaler::SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) @@ -3461,8 +3461,8 @@ void ILArrayWithOffsetMarshaler::EmitConvertSpaceAndContentsCLRToNativeTemp(ILCo } CONTRACTL_END; - int tokArrayWithOffset_m_array = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_ARRAY)); - int tokArrayWithOffset_m_count = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_COUNT)); + int tokArrayWithOffset_m_array = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_ARRAY)); + int tokArrayWithOffset_m_count = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_COUNT)); ILCodeLabel* pNonNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel* pSlowAllocPathLabel = pslILEmit->NewCodeLabel(); @@ -3507,7 +3507,7 @@ void ILArrayWithOffsetMarshaler::EmitConvertSpaceAndContentsCLRToNativeTemp(ILCo // Convert the contents // - int tokArrayWithOffset_m_offset = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_OFFSET)); + int tokArrayWithOffset_m_offset = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_OFFSET)); ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); @@ -3560,7 +3560,7 @@ void ILArrayWithOffsetMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* ps } CONTRACTL_END; - int tokArrayWithOffset_m_array = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_ARRAY)); + int tokArrayWithOffset_m_array = pslILEmit->GetToken(CoreLibBinder::GetField(FIELD__ARRAY_WITH_OFFSET__M_ARRAY)); ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel(); @@ -3655,7 +3655,7 @@ void ILAsAnyMarshalerBase::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) } CONTRACTL_END; - LocalDesc marshalerType(MscorlibBinder::GetClass(CLASS__ASANY_MARSHALER)); + LocalDesc marshalerType(CoreLibBinder::GetClass(CLASS__ASANY_MARSHALER)); m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(marshalerType); DWORD dwTmpLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I); diff --git a/src/coreclr/src/vm/ilmarshalers.h b/src/coreclr/src/vm/ilmarshalers.h index 2b4e6078518e..c08f4f3efc49 100644 --- a/src/coreclr/src/vm/ilmarshalers.h +++ b/src/coreclr/src/vm/ilmarshalers.h @@ -1891,14 +1891,14 @@ class ILCopyMarshalerKnownStruct : public ILCopyMarshalerBase STANDARD_VM_CONTRACT; EmitLoadNativeHomeAddr(pslILEmit); - pslILEmit->EmitINITOBJ(pslILEmit->GetToken(MscorlibBinder::GetClass(CLASS__ID))); + pslILEmit->EmitINITOBJ(pslILEmit->GetToken(CoreLibBinder::GetClass(CLASS__ID))); } virtual LocalDesc GetNativeType() { STANDARD_VM_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__ID)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__ID)); } }; @@ -1972,7 +1972,7 @@ class ILReflectionObjectMarshaler : public ILMarshaler // marshaling a struct referring to an object containing a handle. if (structField != 0) { - int tokStruct__m_object = pslILEmit->GetToken(MscorlibBinder::GetField(structField)); + int tokStruct__m_object = pslILEmit->GetToken(CoreLibBinder::GetField(structField)); EmitLoadManagedHomeAddr(pslILEmit); pslILEmit->EmitLDFLD(tokStruct__m_object); } @@ -2280,7 +2280,7 @@ class ILSafeHandleMarshaler : public ILMarshaler LocalDesc GetManagedType() override { LIMITED_METHOD_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__SAFE_HANDLE)); } LocalDesc GetNativeType() override @@ -2324,7 +2324,7 @@ class ILCriticalHandleMarshaler : public ILMarshaler LocalDesc GetManagedType() override { LIMITED_METHOD_CONTRACT; - return LocalDesc(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__CRITICAL_HANDLE)); } LocalDesc GetNativeType() override @@ -2501,7 +2501,7 @@ class ILValueClassPtrMarshaler : public ILMarshaler // // value class // - return LocalDesc(MscorlibBinder::GetClass(CLASS__ID)); + return LocalDesc(CoreLibBinder::GetClass(CLASS__ID)); } bool NeedsClearNative() override @@ -2541,7 +2541,7 @@ class ILValueClassPtrMarshaler : public ILMarshaler { EmitLoadNativeValue(pslILEmit); // dest EmitLoadManagedHomeAddr(pslILEmit); // src - pslILEmit->EmitCPOBJ(pslILEmit->GetToken(MscorlibBinder::GetClass(CLASS__ID))); + pslILEmit->EmitCPOBJ(pslILEmit->GetToken(CoreLibBinder::GetClass(CLASS__ID))); } else { @@ -2554,7 +2554,7 @@ class ILValueClassPtrMarshaler : public ILMarshaler { STANDARD_VM_CONTRACT; - int tokType = pslILEmit->GetToken(MscorlibBinder::GetClass(CLASS__ID)); + int tokType = pslILEmit->GetToken(CoreLibBinder::GetClass(CLASS__ID)); ILCodeLabel *pNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel *pJoinLabel = pslILEmit->NewCodeLabel(); @@ -3302,13 +3302,13 @@ class ILMngdMarshaler : public ILMarshaler EmitCallMngdMarshalerMethod(pslILEmit, GetClearManagedMethod()); } - virtual MethodDesc *GetConvertSpaceToManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertSpaceToManaged == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idConvertSpaceToManaged)); } - virtual MethodDesc *GetConvertContentsToManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertContentsToManaged == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idConvertContentsToManaged)); } - virtual MethodDesc *GetConvertSpaceToNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertSpaceToNative == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idConvertSpaceToNative)); } - virtual MethodDesc *GetConvertContentsToNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertContentsToNative == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idConvertContentsToNative)); } - virtual MethodDesc *GetClearNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idClearNative == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idClearNative)); } - virtual MethodDesc *GetClearNativeContentsMethod() { WRAPPER_NO_CONTRACT; return (m_idClearNativeContents == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idClearNativeContents)); } - virtual MethodDesc *GetClearManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idClearManaged == METHOD__NIL ? NULL : MscorlibBinder::GetMethod(m_idClearManaged)); } + virtual MethodDesc *GetConvertSpaceToManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertSpaceToManaged == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idConvertSpaceToManaged)); } + virtual MethodDesc *GetConvertContentsToManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertContentsToManaged == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idConvertContentsToManaged)); } + virtual MethodDesc *GetConvertSpaceToNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertSpaceToNative == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idConvertSpaceToNative)); } + virtual MethodDesc *GetConvertContentsToNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idConvertContentsToNative == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idConvertContentsToNative)); } + virtual MethodDesc *GetClearNativeMethod() { WRAPPER_NO_CONTRACT; return (m_idClearNative == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idClearNative)); } + virtual MethodDesc *GetClearNativeContentsMethod() { WRAPPER_NO_CONTRACT; return (m_idClearNativeContents == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idClearNativeContents)); } + virtual MethodDesc *GetClearManagedMethod() { WRAPPER_NO_CONTRACT; return (m_idClearManaged == METHOD__NIL ? NULL : CoreLibBinder::GetMethod(m_idClearManaged)); } const BinderMethodID m_idConvertSpaceToManaged; const BinderMethodID m_idConvertContentsToManaged; diff --git a/src/coreclr/src/vm/ilstubcache.cpp b/src/coreclr/src/vm/ilstubcache.cpp index fb9e0ea1eaf3..64bd551b2c12 100644 --- a/src/coreclr/src/vm/ilstubcache.cpp +++ b/src/coreclr/src/vm/ilstubcache.cpp @@ -421,7 +421,7 @@ MethodTable* ILStubCache::GetOrCreateStubMethodTable(Module* pModule) // // We're relying on the fact that a VASigCookie may only mention types within the // corresponding module used to qualify the signature and the fact that interop -// stubs may only reference mscorlib code or code related to a type mentioned in +// stubs may only reference CoreLib code or code related to a type mentioned in // the signature. Both of these are true unless the sig is allowed to contain // ELEMENT_TYPE_INTERNAL, which may refer to any type. // diff --git a/src/coreclr/src/vm/interoputil.cpp b/src/coreclr/src/vm/interoputil.cpp index 0a58c8144e7a..fc2fb3c7e1e9 100644 --- a/src/coreclr/src/vm/interoputil.cpp +++ b/src/coreclr/src/vm/interoputil.cpp @@ -317,7 +317,7 @@ void GetCultureInfoForLCID(LCID lcid, OBJECTREF *pCultureObj) GCPROTECT_BEGIN(CultureObj) { // Allocate a CultureInfo with the specified LCID. - CultureObj = AllocateObject(MscorlibBinder::GetClass(CLASS__CULTURE_INFO)); + CultureObj = AllocateObject(CoreLibBinder::GetClass(CLASS__CULTURE_INFO)); MethodDescCallSite cultureInfoCtor(METHOD__CULTURE_INFO__INT_CTOR, &CultureObj); @@ -3145,7 +3145,7 @@ void DispInvokeConvertObjectToVariant(OBJECTREF *pSrcObj, VARIANT *pDestVar, Byr V_VT(pDestVar) = VT_VARIANT | VT_BYREF; pDestVar->pvarVal = &pByrefArgInfo->m_Val; } - else if (MscorlibBinder::IsClass((*pSrcObj)->GetMethodTable(), CLASS__VARIANT_WRAPPER)) + else if (CoreLibBinder::IsClass((*pSrcObj)->GetMethodTable(), CLASS__VARIANT_WRAPPER)) { OBJECTREF WrappedObj = (*((VARIANTWRAPPEROBJECTREF*)pSrcObj))->GetWrappedObject(); GCPROTECT_BEGIN(WrappedObj) diff --git a/src/coreclr/src/vm/interpreter.cpp b/src/coreclr/src/vm/interpreter.cpp index b4f5a0dbf45b..ef14373dfcfe 100644 --- a/src/coreclr/src/vm/interpreter.cpp +++ b/src/coreclr/src/vm/interpreter.cpp @@ -9077,7 +9077,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T } // Plus some other calls that we're going to treat "like" intrinsics... - if (methToCall == MscorlibBinder::GetMethod(METHOD__STUBHELPERS__SET_LAST_ERROR)) + if (methToCall == CoreLibBinder::GetMethod(METHOD__STUBHELPERS__SET_LAST_ERROR)) { // If we're interpreting a method that calls "SetLastError", it's very likely that the call(i) whose // error we're trying to capture was performed with MethodDescCallSite machinery that itself trashes @@ -10281,7 +10281,7 @@ void Interpreter::CallI() } else { - pMD = MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT); // A random static method. + pMD = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT); // A random static method. } MethodDescCallSite mdcs(pMD, &mSig, ftnPtr); #if 0 diff --git a/src/coreclr/src/vm/invokeutil.cpp b/src/coreclr/src/vm/invokeutil.cpp index 7c1790821db7..44ef6b97aac4 100644 --- a/src/coreclr/src/vm/invokeutil.cpp +++ b/src/coreclr/src/vm/invokeutil.cpp @@ -53,7 +53,7 @@ BOOL InvokeUtil::IsVoidPtr(TypeHandle th) if (!th.IsPointer()) return FALSE; - return th.AsTypeDesc()->GetTypeParam() == MscorlibBinder::GetElementType(ELEMENT_TYPE_VOID); + return th.AsTypeDesc()->GetTypeParam() == CoreLibBinder::GetElementType(ELEMENT_TYPE_VOID); } OBJECTREF InvokeUtil::CreatePointer(TypeHandle th, void * p) @@ -70,7 +70,7 @@ OBJECTREF InvokeUtil::CreatePointer(TypeHandle th, void * p) OBJECTREF refObj = NULL; GCPROTECT_BEGIN(refObj); - refObj = AllocateObject(MscorlibBinder::GetClass(CLASS__POINTER)); + refObj = AllocateObject(CoreLibBinder::GetClass(CLASS__POINTER)); ((ReflectionPointer *)OBJECTREFToObject(refObj))->_ptr = p; @@ -299,9 +299,9 @@ void InvokeUtil::CopyArg(TypeHandle th, OBJECTREF *pObjUNSAFE, ArgDestination *a *(PVOID *)pArgDst = 0; } else { - if (rObj->GetMethodTable() == MscorlibBinder::GetClassIfExist(CLASS__POINTER) && type == ELEMENT_TYPE_PTR) + if (rObj->GetMethodTable() == CoreLibBinder::GetClassIfExist(CLASS__POINTER) && type == ELEMENT_TYPE_PTR) *(PVOID *)pArgDst = GetPointerValue(rObj); - else if (rObj->GetTypeHandle().AsMethodTable() == MscorlibBinder::GetElementType(ELEMENT_TYPE_I)) + else if (rObj->GetTypeHandle().AsMethodTable() == CoreLibBinder::GetElementType(ELEMENT_TYPE_I)) { ARG_SLOT slot; CreatePrimitiveValue(oType, oType, rObj, &slot); @@ -592,7 +592,7 @@ void InvokeUtil::ValidField(TypeHandle th, OBJECTREF* value) // handle pointers if (type == ELEMENT_TYPE_PTR || type == ELEMENT_TYPE_FNPTR) { - if (MscorlibBinder::IsClass((*value)->GetMethodTable(), CLASS__POINTER) && type == ELEMENT_TYPE_PTR) { + if (CoreLibBinder::IsClass((*value)->GetMethodTable(), CLASS__POINTER) && type == ELEMENT_TYPE_PTR) { TypeHandle srcTH = GetPointerType(*value); if (!IsVoidPtr(th)) { @@ -601,7 +601,7 @@ void InvokeUtil::ValidField(TypeHandle th, OBJECTREF* value) } return; } - else if (MscorlibBinder::IsClass((*value)->GetMethodTable(), CLASS__INTPTR)) { + else if (CoreLibBinder::IsClass((*value)->GetMethodTable(), CLASS__INTPTR)) { return; } @@ -696,7 +696,7 @@ OBJECTREF InvokeUtil::CreateObjectAfterInvoke(TypeHandle th, void * pValue) { { LPVOID capturedValue = *(LPVOID*)pValue; INDEBUG(pValue = (LPVOID)(size_t)0xcccccccc); // We're about to allocate a GC object - can no longer trust pValue - obj = AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I)); + obj = AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I)); *(LPVOID*)(obj->UnBox()) = capturedValue; } break; @@ -736,7 +736,7 @@ OBJECTREF InvokeUtil::CreateClassLoadExcept(OBJECTREF* classes, OBJECTREF* excep } gc; ZeroMemory(&gc, sizeof(gc)); - MethodTable *pVMClassLoadExcept = MscorlibBinder::GetException(kReflectionTypeLoadException); + MethodTable *pVMClassLoadExcept = CoreLibBinder::GetException(kReflectionTypeLoadException); gc.o = AllocateObject(pVMClassLoadExcept); GCPROTECT_BEGIN(gc); ARG_SLOT args[4]; @@ -786,7 +786,7 @@ OBJECTREF InvokeUtil::CreateTargetExcept(OBJECTREF* except) { OBJECTREF o; OBJECTREF oRet = 0; - MethodTable *pVMTargetExcept = MscorlibBinder::GetException(kTargetInvocationException); + MethodTable *pVMTargetExcept = CoreLibBinder::GetException(kTargetInvocationException); o = AllocateObject(pVMTargetExcept); GCPROTECT_BEGIN(o); ARG_SLOT args[2]; @@ -1055,7 +1055,7 @@ void InvokeUtil::SetValidField(CorElementType fldType, break; case ELEMENT_TYPE_PTR: // pointers - if (*valueObj != 0 && MscorlibBinder::IsClass((*valueObj)->GetMethodTable(), CLASS__POINTER)) { + if (*valueObj != 0 && CoreLibBinder::IsClass((*valueObj)->GetMethodTable(), CLASS__POINTER)) { valueptr = GetPointerValue(*valueObj); if (pField->IsStatic()) pField->SetStaticValuePtr(valueptr); @@ -1291,7 +1291,7 @@ OBJECTREF InvokeUtil::GetFieldValue(FieldDesc* pField, TypeHandle fieldType, OBJ else value = pField->GetValuePtr(*target); - MethodTable *pIntPtrMT = MscorlibBinder::GetClass(CLASS__INTPTR); + MethodTable *pIntPtrMT = CoreLibBinder::GetClass(CLASS__INTPTR); obj = AllocateObject(pIntPtrMT); CopyValueClass(obj->UnBox(), &value, pIntPtrMT); break; diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index e955b3dadec4..9e3c9180ef0b 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -626,7 +626,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getTokenTypeAsHandle (CORINFO_RESOLVED_TOKEN * pRe classID = CLASS__FIELD_HANDLE; } - tokenType = CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(classID)); + tokenType = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(classID)); EE_TO_JIT_TRANSITION(); @@ -1365,25 +1365,25 @@ bool CEEInfo::tryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken) } /*********************************************************************/ -// We have a few frequently used constants in mscorlib that are defined as +// We have a few frequently used constants in CoreLib that are defined as // readonly static fields for historic reasons. Check for them here and // allow them to be treated as actual constants by the JIT. static CORINFO_FIELD_ACCESSOR getFieldIntrinsic(FieldDesc * field) { STANDARD_VM_CONTRACT; - if (MscorlibBinder::GetField(FIELD__STRING__EMPTY) == field) + if (CoreLibBinder::GetField(FIELD__STRING__EMPTY) == field) { return CORINFO_FIELD_INTRINSIC_EMPTY_STRING; } else - if ((MscorlibBinder::GetField(FIELD__INTPTR__ZERO) == field) || - (MscorlibBinder::GetField(FIELD__UINTPTR__ZERO) == field)) + if ((CoreLibBinder::GetField(FIELD__INTPTR__ZERO) == field) || + (CoreLibBinder::GetField(FIELD__UINTPTR__ZERO) == field)) { return CORINFO_FIELD_INTRINSIC_ZERO; } else - if (MscorlibBinder::GetField(FIELD__BITCONVERTER__ISLITTLEENDIAN) == field) + if (CoreLibBinder::GetField(FIELD__BITCONVERTER__ISLITTLEENDIAN) == field) { return CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN; } @@ -4247,16 +4247,16 @@ CORINFO_CLASS_HANDLE CEEInfo::getBuiltinClass(CorInfoClassId classId) result = CORINFO_CLASS_HANDLE(g_TypedReferenceMT); break; case CLASSID_TYPE_HANDLE: - result = CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(CLASS__TYPE_HANDLE)); + result = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__TYPE_HANDLE)); break; case CLASSID_FIELD_HANDLE: - result = CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(CLASS__FIELD_HANDLE)); + result = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__FIELD_HANDLE)); break; case CLASSID_METHOD_HANDLE: - result = CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(CLASS__METHOD_HANDLE)); + result = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__METHOD_HANDLE)); break; case CLASSID_ARGUMENT_HANDLE: - result = CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(CLASS__ARGUMENT_HANDLE)); + result = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__ARGUMENT_HANDLE)); break; case CLASSID_STRING: result = CORINFO_CLASS_HANDLE(g_pStringClass); @@ -5193,10 +5193,10 @@ void CEEInfo::getCallInfo( // null since the virtual method resolves to System.Enum's implementation and that's a reference type. // We can't do this for any other method since ToString and Equals have different semantics for enums // and their underlying type. - if (pMD->GetSlot() == MscorlibBinder::GetMethod(METHOD__OBJECT__GET_HASH_CODE)->GetSlot()) + if (pMD->GetSlot() == CoreLibBinder::GetMethod(METHOD__OBJECT__GET_HASH_CODE)->GetSlot()) { // Pretend this was a "constrained. UnderlyingType" instruction prefix - constrainedType = TypeHandle(MscorlibBinder::GetElementType(constrainedType.GetVerifierCorElementType())); + constrainedType = TypeHandle(CoreLibBinder::GetElementType(constrainedType.GetVerifierCorElementType())); // Native image signature encoder will use this field. It needs to match that pretended type, a bogus signature // would be produced otherwise. @@ -6817,8 +6817,8 @@ void CEEInfo::setMethodAttribs ( } else { - // Don't cache inlining hints inside mscorlib during NGen of other assemblies, - // since mscorlib is loaded domain neutral and will survive worker process recycling, + // Don't cache inlining hints inside CoreLib during NGen of other assemblies, + // since CoreLib is loaded domain neutral and will survive worker process recycling, // causing determinism problems. Module * pModule = ftn->GetModule(); if (pModule->IsSystem() && pModule->HasNativeImage()) @@ -6903,8 +6903,8 @@ mdToken FindGenericMethodArgTypeSpec(IMDInternalImport* pInternalImport) /********************************************************************* IL is the most efficient and portable way to implement certain low level methods -in mscorlib.dll. Unfortunately, there is no good way to link IL into mscorlib.dll today. -Until we find a good way to link IL into mscorlib.dll, we will provide the IL implementation here. +in CoreLib. Unfortunately, there is no good way to link IL into CoreLib today. +Until we find a good way to link IL into CoreLib, we will provide the IL implementation here. - All IL intrinsincs are members of System.Runtime.CompilerServices.JitHelpers class - All IL intrinsincs should be kept very simple. Implement the minimal reusable version of @@ -6919,11 +6919,11 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, { STANDARD_VM_CONTRACT; - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__UNSAFE)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__UNSAFE)); mdMethodDef tk = ftn->GetMemberDef(); - if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_POINTER)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__AS_POINTER)->GetMemberDef()) { // Return the argument that was passed in. static const BYTE ilcode[] = { CEE_LDARG_0, CEE_CONV_U, CEE_RET }; @@ -6934,13 +6934,13 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__SIZEOF)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__SIZEOF)->GetMemberDef()) { _ASSERTE(ftn->HasMethodInstantiation()); Instantiation inst = ftn->GetMethodInstantiation(); _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); static BYTE ilcode[] = { CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0, CEE_RET }; @@ -6956,10 +6956,10 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__OBJECT_AS)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_REF_POINTER)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_REF_IN)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__OBJECT_AS)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__AS_REF_POINTER)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__AS_REF_IN)->GetMemberDef()) { // Return the argument that was passed in. static const BYTE ilcode[] = { CEE_LDARG_0, CEE_RET }; @@ -6970,10 +6970,10 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_ADD)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__PTR_ADD)->GetMemberDef()) { - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); static BYTE ilcode[] = { CEE_LDARG_1, CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0, @@ -6995,9 +6995,9 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_INTPTR_ADD)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_INTPTR_ADD)->GetMemberDef()) { - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); static BYTE ilcode[] = { CEE_LDARG_1, CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0, @@ -7018,7 +7018,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD_BYTE_OFFSET)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD_BYTE_OFFSET)->GetMemberDef()) { static BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_ADD, CEE_RET }; @@ -7029,7 +7029,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ARE_SAME)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_ARE_SAME)->GetMemberDef()) { // Compare the two arguments static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CEQ & 0xFF), CEE_RET }; @@ -7040,7 +7040,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_GREATER_THAN)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_GREATER_THAN)->GetMemberDef()) { // Compare the two arguments static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CGT_UN & 0xFF), CEE_RET }; @@ -7051,7 +7051,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_LESS_THAN)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_LESS_THAN)->GetMemberDef()) { // Compare the two arguments static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CLT_UN & 0xFF), CEE_RET }; @@ -7062,7 +7062,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_NULLREF)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_NULLREF)->GetMemberDef()) { static const BYTE ilcode[] = { CEE_LDC_I4_0, CEE_CONV_U, CEE_RET }; methInfo->ILCode = const_cast(ilcode); @@ -7072,7 +7072,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_NULL)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_NULL)->GetMemberDef()) { // 'ldnull' opcode would produce type o, and we can't compare & against o (ECMA-335, Table III.4). // However, we can compare & against native int, so we'll use that instead. @@ -7085,7 +7085,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_INIT_BLOCK_UNALIGNED)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_INIT_BLOCK_UNALIGNED)->GetMemberDef()) { static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 0x01, CEE_PREFIX1, (CEE_INITBLK & 0xFF), CEE_RET }; methInfo->ILCode = const_cast(ilcode); @@ -7095,7 +7095,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_BYTE_OFFSET)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_BYTE_OFFSET)->GetMemberDef()) { static const BYTE ilcode[] = { @@ -7112,13 +7112,13 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_READ_UNALIGNED)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_READ_UNALIGNED)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_READ_UNALIGNED)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__PTR_READ_UNALIGNED)->GetMemberDef()) { _ASSERTE(ftn->HasMethodInstantiation()); Instantiation inst = ftn->GetMethodInstantiation(); _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); static const BYTE ilcode[] { @@ -7135,13 +7135,13 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_WRITE_UNALIGNED)->GetMemberDef() || - tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_WRITE_UNALIGNED)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_WRITE_UNALIGNED)->GetMemberDef() || + tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__PTR_WRITE_UNALIGNED)->GetMemberDef()) { _ASSERTE(ftn->HasMethodInstantiation()); Instantiation inst = ftn->GetMethodInstantiation(); _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); static const BYTE ilcode[] { @@ -7159,7 +7159,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__SKIPINIT)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__SKIPINIT)->GetMemberDef()) { static BYTE ilcode[] = { CEE_RET }; @@ -7179,13 +7179,13 @@ bool getILIntrinsicImplementationForMemoryMarshal(MethodDesc * ftn, { STANDARD_VM_CONTRACT; - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__MEMORY_MARSHAL)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__MEMORY_MARSHAL)); mdMethodDef tk = ftn->GetMemberDef(); - if (tk == MscorlibBinder::GetMethod(METHOD__MEMORY_MARSHAL__GET_ARRAY_DATA_REFERENCE)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__MEMORY_MARSHAL__GET_ARRAY_DATA_REFERENCE)->GetMemberDef()) { - mdToken tokRawSzArrayData = MscorlibBinder::GetField(FIELD__RAW_ARRAY_DATA__DATA)->GetMemberDef(); + mdToken tokRawSzArrayData = CoreLibBinder::GetField(FIELD__RAW_ARRAY_DATA__DATA)->GetMemberDef(); static BYTE ilcode[] = { CEE_LDARG_0, CEE_LDFLDA,0,0,0,0, @@ -7213,7 +7213,7 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn, STANDARD_VM_CONTRACT; // - // This replaces the implementations of Volatile.* in mscorlib with more efficient ones. + // This replaces the implementations of Volatile.* in CoreLib with more efficient ones. // We do this because we cannot otherwise express these in C#. What we *want* to do is // to treat the byref args to these methods as "volatile." In pseudo-C#, this would look // like: @@ -7227,7 +7227,7 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn, // we substitute raw IL bodies for these methods that use the correct volatile instructions. // - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__VOLATILE)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__VOLATILE)); const size_t VolatileMethodBodySize = 6; @@ -7276,7 +7276,7 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn, // // Ordinary volatile loads and stores only guarantee atomicity for pointer-sized (or smaller) data. // So, on 32-bit platforms we must use Interlocked operations instead for the 64-bit types. - // The implementation in mscorlib already does this, so we will only substitute a new + // The implementation in CoreLib already does this, so we will only substitute a new // IL body if we're running on a 64-bit platform. // IN_TARGET_64BIT(VOLATILE_IMPL(Long, CEE_LDIND_I8, CEE_STIND_I8)) @@ -7287,7 +7287,7 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn, mdMethodDef md = ftn->GetMemberDef(); for (unsigned i = 0; i < NumItems(volatileImpls); i++) { - if (md == MscorlibBinder::GetMethod(volatileImpls[i].methodId)->GetMemberDef()) + if (md == CoreLibBinder::GetMethod(volatileImpls[i].methodId)->GetMemberDef()) { methInfo->ILCode = const_cast(volatileImpls[i].body); methInfo->ILCodeSize = VolatileMethodBodySize; @@ -7306,14 +7306,14 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn, { STANDARD_VM_CONTRACT; - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__INTERLOCKED)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__INTERLOCKED)); // We are only interested if ftn's token and CompareExchange token match - if (ftn->GetMemberDef() != MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_T)->GetMemberDef()) + if (ftn->GetMemberDef() != CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_T)->GetMemberDef()) return false; // Get MethodDesc for non-generic System.Threading.Interlocked.CompareExchange() - MethodDesc* cmpxchgObject = MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT); + MethodDesc* cmpxchgObject = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT); // Setup up the body of the method static BYTE il[] = { @@ -7346,11 +7346,11 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, { STANDARD_VM_CONTRACT; - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__RUNTIME_HELPERS)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__RUNTIME_HELPERS)); mdMethodDef tk = ftn->GetMemberDef(); - if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_REFERENCE_OR_CONTAINS_REFERENCES)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_REFERENCE_OR_CONTAINS_REFERENCES)->GetMemberDef()) { _ASSERTE(ftn->HasMethodInstantiation()); Instantiation inst = ftn->GetMethodInstantiation(); @@ -7378,7 +7378,7 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, return true; } - if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_BITWISE_EQUATABLE)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_BITWISE_EQUATABLE)->GetMemberDef()) { _ASSERTE(ftn->HasMethodInstantiation()); Instantiation inst = ftn->GetMethodInstantiation(); @@ -7396,22 +7396,22 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, // n.b. This doesn't imply that the type's CompareTo method can be memcmp-implemented, // as a method like CompareTo may need to take a type's signedness into account. - if (methodTable == MscorlibBinder::GetClass(CLASS__BOOLEAN) - || methodTable == MscorlibBinder::GetClass(CLASS__BYTE) - || methodTable == MscorlibBinder::GetClass(CLASS__SBYTE) + if (methodTable == CoreLibBinder::GetClass(CLASS__BOOLEAN) + || methodTable == CoreLibBinder::GetClass(CLASS__BYTE) + || methodTable == CoreLibBinder::GetClass(CLASS__SBYTE) #ifdef FEATURE_UTF8STRING - || methodTable == MscorlibBinder::GetClass(CLASS__CHAR8) + || methodTable == CoreLibBinder::GetClass(CLASS__CHAR8) #endif // FEATURE_UTF8STRING - || methodTable == MscorlibBinder::GetClass(CLASS__CHAR) - || methodTable == MscorlibBinder::GetClass(CLASS__INT16) - || methodTable == MscorlibBinder::GetClass(CLASS__UINT16) - || methodTable == MscorlibBinder::GetClass(CLASS__INT32) - || methodTable == MscorlibBinder::GetClass(CLASS__UINT32) - || methodTable == MscorlibBinder::GetClass(CLASS__INT64) - || methodTable == MscorlibBinder::GetClass(CLASS__UINT64) - || methodTable == MscorlibBinder::GetClass(CLASS__INTPTR) - || methodTable == MscorlibBinder::GetClass(CLASS__UINTPTR) - || methodTable == MscorlibBinder::GetClass(CLASS__RUNE) + || methodTable == CoreLibBinder::GetClass(CLASS__CHAR) + || methodTable == CoreLibBinder::GetClass(CLASS__INT16) + || methodTable == CoreLibBinder::GetClass(CLASS__UINT16) + || methodTable == CoreLibBinder::GetClass(CLASS__INT32) + || methodTable == CoreLibBinder::GetClass(CLASS__UINT32) + || methodTable == CoreLibBinder::GetClass(CLASS__INT64) + || methodTable == CoreLibBinder::GetClass(CLASS__UINT64) + || methodTable == CoreLibBinder::GetClass(CLASS__INTPTR) + || methodTable == CoreLibBinder::GetClass(CLASS__UINTPTR) + || methodTable == CoreLibBinder::GetClass(CLASS__RUNE) || methodTable->IsEnum()) { methInfo->ILCode = const_cast(returnTrue); @@ -7428,9 +7428,9 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, return true; } - if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__GET_METHOD_TABLE)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__GET_METHOD_TABLE)->GetMemberDef()) { - mdToken tokRawData = MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)->GetMemberDef(); + mdToken tokRawData = CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)->GetMemberDef(); // In the CLR, an object is laid out as follows. // [ object_header || MethodTable* (64-bit pointer) || instance_data ] @@ -7465,7 +7465,7 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, return true; } - if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__ENUM_EQUALS)->GetMemberDef()) + if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__ENUM_EQUALS)->GetMemberDef()) { // Normally we would follow the above pattern and unconditionally replace the IL, // relying on generic type constraints to guarantee that it will only ever be instantiated @@ -7505,7 +7505,7 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, return true; } } - else if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__ENUM_COMPARE_TO)->GetMemberDef()) + else if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__ENUM_COMPARE_TO)->GetMemberDef()) { // The the comment above on why this is is not an unconditional replacement. This case handles // Enums backed by 8 byte values. @@ -7526,12 +7526,12 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, { static BYTE ilcode[8][9]; - TypeHandle thUnderlyingType = MscorlibBinder::GetElementType(et); + TypeHandle thUnderlyingType = CoreLibBinder::GetElementType(et); - TypeHandle thIComparable = TypeHandle(MscorlibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(Instantiation(&thUnderlyingType, 1)); + TypeHandle thIComparable = TypeHandle(CoreLibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(Instantiation(&thUnderlyingType, 1)); MethodDesc* pCompareToMD = thUnderlyingType.AsMethodTable()->GetMethodDescForInterfaceMethod( - thIComparable, MscorlibBinder::GetMethod(METHOD__ICOMPARABLEGENERIC__COMPARE_TO), TRUE /* throwOnConflict */); + thIComparable, CoreLibBinder::GetMethod(METHOD__ICOMPARABLEGENERIC__COMPARE_TO), TRUE /* throwOnConflict */); // Call CompareTo method on the primitive type int tokCompareTo = pCompareToMD->GetMemberDef(); @@ -7567,10 +7567,10 @@ bool getILIntrinsicImplementationForActivator(MethodDesc* ftn, { STANDARD_VM_CONTRACT; - _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__ACTIVATOR)); + _ASSERTE(CoreLibBinder::IsClass(ftn->GetMethodTable(), CLASS__ACTIVATOR)); // We are only interested if ftn's token and CreateInstance token match - if (ftn->GetMemberDef() != MscorlibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_INSTANCE_OF_T)->GetMemberDef()) + if (ftn->GetMemberDef() != CoreLibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_INSTANCE_OF_T)->GetMemberDef()) return false; _ASSERTE(ftn->HasMethodInstantiation()); @@ -7584,7 +7584,7 @@ bool getILIntrinsicImplementationForActivator(MethodDesc* ftn, return false; // Replace the body with implementation that just returns "default" - MethodDesc* createDefaultInstance = MscorlibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_DEFAULT_INSTANCE_OF_T); + MethodDesc* createDefaultInstance = CoreLibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_DEFAULT_INSTANCE_OF_T); COR_ILMETHOD_DECODER header(createDefaultInstance->GetILHeader(FALSE), createDefaultInstance->GetMDImport(), NULL); getMethodInfoILMethodHeaderHelper(&header, methInfo); *pSig = SigPointer(header.LocalVarSig, header.cbLocalVarSig); @@ -7627,27 +7627,27 @@ getMethodInfoHelper( if (ftn->IsJitIntrinsic()) { - if (MscorlibBinder::IsClass(pMT, CLASS__UNSAFE)) + if (CoreLibBinder::IsClass(pMT, CLASS__UNSAFE)) { fILIntrinsic = getILIntrinsicImplementationForUnsafe(ftn, methInfo); } - else if (MscorlibBinder::IsClass(pMT, CLASS__MEMORY_MARSHAL)) + else if (CoreLibBinder::IsClass(pMT, CLASS__MEMORY_MARSHAL)) { fILIntrinsic = getILIntrinsicImplementationForMemoryMarshal(ftn, methInfo); } - else if (MscorlibBinder::IsClass(pMT, CLASS__INTERLOCKED)) + else if (CoreLibBinder::IsClass(pMT, CLASS__INTERLOCKED)) { fILIntrinsic = getILIntrinsicImplementationForInterlocked(ftn, methInfo); } - else if (MscorlibBinder::IsClass(pMT, CLASS__VOLATILE)) + else if (CoreLibBinder::IsClass(pMT, CLASS__VOLATILE)) { fILIntrinsic = getILIntrinsicImplementationForVolatile(ftn, methInfo); } - else if (MscorlibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS)) + else if (CoreLibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS)) { fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo); } - else if (MscorlibBinder::IsClass(pMT, CLASS__ACTIVATOR)) + else if (CoreLibBinder::IsClass(pMT, CLASS__ACTIVATOR)) { SigPointer localSig; fILIntrinsic = getILIntrinsicImplementationForActivator(ftn, methInfo, &localSig); @@ -7879,8 +7879,8 @@ bool containsStackCrawlMarkLocal(MethodDesc* ftn) mdToken token; IfFailThrow(ptr.GetToken(&token)); - // We are inside mscorlib - simple token match is sufficient - if (token == MscorlibBinder::GetClass(CLASS__STACKCRAWMARK)->GetCl()) + // We are inside CoreLib - simple token match is sufficient + if (token == CoreLibBinder::GetClass(CLASS__STACKCRAWMARK)->GetCl()) return TRUE; } @@ -8785,16 +8785,16 @@ CorInfoIntrinsics CEEInfo::getIntrinsicID(CORINFO_METHOD_HANDLE methodHnd, *pMustExpand = true; } } - else if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__SPAN))) + else if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__SPAN))) { - if (method->HasSameMethodDefAs(MscorlibBinder::GetMethod(METHOD__SPAN__GET_ITEM))) + if (method->HasSameMethodDefAs(CoreLibBinder::GetMethod(METHOD__SPAN__GET_ITEM))) { result = CORINFO_INTRINSIC_Span_GetItem; } } - else if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__READONLY_SPAN))) + else if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__READONLY_SPAN))) { - if (method->HasSameMethodDefAs(MscorlibBinder::GetMethod(METHOD__READONLY_SPAN__GET_ITEM))) + if (method->HasSameMethodDefAs(CoreLibBinder::GetMethod(METHOD__READONLY_SPAN__GET_ITEM))) { result = CORINFO_INTRINSIC_ReadOnlySpan_GetItem; } @@ -9117,18 +9117,18 @@ CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClassHelper(CORINFO_CLAS TypeHandle elemTypeHnd(elemType); // Special case for byte - if (elemTypeHnd.AsMethodTable()->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__ELEMENT_TYPE_U1))) + if (elemTypeHnd.AsMethodTable()->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__ELEMENT_TYPE_U1))) { - return CORINFO_CLASS_HANDLE(MscorlibBinder::GetClass(CLASS__BYTE_EQUALITYCOMPARER)); + return CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__BYTE_EQUALITYCOMPARER)); } // Else we'll need to find the appropriate instantation Instantiation inst(&elemTypeHnd, 1); // If T implements IEquatable - if (elemTypeHnd.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(inst))) + if (elemTypeHnd.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(inst))) { - TypeHandle resultTh = ((TypeHandle)MscorlibBinder::GetClass(CLASS__GENERIC_EQUALITYCOMPARER)).Instantiate(inst); + TypeHandle resultTh = ((TypeHandle)CoreLibBinder::GetClass(CLASS__GENERIC_EQUALITYCOMPARER)).Instantiate(inst); return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable()); } @@ -9136,7 +9136,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClassHelper(CORINFO_CLAS if (Nullable::IsNullableType(elemTypeHnd)) { Instantiation nullableInst = elemTypeHnd.AsMethodTable()->GetInstantiation(); - TypeHandle nullableComparer = TypeHandle(MscorlibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(nullableInst); + TypeHandle nullableComparer = TypeHandle(CoreLibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(nullableInst); if (nullableInst[0].CanCastTo(nullableComparer)) { return CORINFO_CLASS_HANDLE(nullableComparer.GetMethodTable()); @@ -9163,7 +9163,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClassHelper(CORINFO_CLAS case ELEMENT_TYPE_I8: case ELEMENT_TYPE_U8: { - targetClass = MscorlibBinder::GetClass(CLASS__ENUM_EQUALITYCOMPARER); + targetClass = CoreLibBinder::GetClass(CLASS__ENUM_EQUALITYCOMPARER); break; } @@ -9179,7 +9179,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClassHelper(CORINFO_CLAS } // Default case - TypeHandle resultTh = ((TypeHandle)MscorlibBinder::GetClass(CLASS__OBJECT_EQUALITYCOMPARER)).Instantiate(inst); + TypeHandle resultTh = ((TypeHandle)CoreLibBinder::GetClass(CLASS__OBJECT_EQUALITYCOMPARER)).Instantiate(inst); return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable()); } @@ -13551,7 +13551,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, if (CORCOMPILE_IS_PCODE_TAGGED(result)) { // There is a rare case where the function entrypoint may not be aligned. This could happen only for FCalls, - // only on x86 and only if we failed to hardbind the fcall (e.g. ngen image for mscorlib.dll does not exist + // only on x86 and only if we failed to hardbind the fcall (e.g. ngen image for CoreLib does not exist // and /nodependencies flag for ngen was used). The function entrypoints should be aligned in all other cases. // // We will wrap the unaligned method entrypoint by funcptr stub with aligned entrypoint. diff --git a/src/coreclr/src/vm/loaderallocator.cpp b/src/coreclr/src/vm/loaderallocator.cpp index 0119f6510f46..71f4a814be39 100644 --- a/src/coreclr/src/vm/loaderallocator.cpp +++ b/src/coreclr/src/vm/loaderallocator.cpp @@ -1008,7 +1008,7 @@ void LoaderAllocator::SetupManagedTracking(LOADERALLOCATORREF * pKeepLoaderAlloc // Initialize managed loader allocator reference holder // - MethodTable *pMT = MscorlibBinder::GetClass(CLASS__LOADERALLOCATOR); + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__LOADERALLOCATOR); *pKeepLoaderAllocatorAlive = (LOADERALLOCATORREF)AllocateObject(pMT); diff --git a/src/coreclr/src/vm/managedmdimport.cpp b/src/coreclr/src/vm/managedmdimport.cpp index 973fa8ad44f6..6bea537f1c8e 100644 --- a/src/coreclr/src/vm/managedmdimport.cpp +++ b/src/coreclr/src/vm/managedmdimport.cpp @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: Re-implement with MC++ if we ever compile any mscorlib code with that - - #include "common.h" #include "mlinfo.h" diff --git a/src/coreclr/src/vm/memberload.cpp b/src/coreclr/src/vm/memberload.cpp index 8df00c959c34..eec23198c21c 100644 --- a/src/coreclr/src/vm/memberload.cpp +++ b/src/coreclr/src/vm/memberload.cpp @@ -1198,9 +1198,9 @@ MemberLoader::FindMethod(MethodTable * pMT, LPCUTF8 pwzName, LPHARDCODEDMETASIG MODE_ANY; } CONTRACTL_END; - Signature sig = MscorlibBinder::GetSignature(pwzSignature); + Signature sig = CoreLibBinder::GetSignature(pwzSignature); - return FindMethod(pMT, pwzName, sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), flags); + return FindMethod(pMT, pwzName, sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule(), flags); } //******************************************************************************* @@ -1389,9 +1389,9 @@ MemberLoader::FindConstructor(MethodTable * pMT, LPHARDCODEDMETASIG pwzSignature } CONTRACTL_END - Signature sig = MscorlibBinder::GetSignature(pwzSignature); + Signature sig = CoreLibBinder::GetSignature(pwzSignature); - return FindConstructor(pMT, sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule()); + return FindConstructor(pMT, sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule()); } //******************************************************************************* diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index 72d01593b1fd..e378fad4affe 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -5750,7 +5750,7 @@ REFLECTMETHODREF MethodDesc::GetStubMethodInfo() CONTRACTL_END; REFLECTMETHODREF retVal; - REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(MscorlibBinder::GetClass(CLASS__STUBMETHODINFO)); + REFLECTMETHODREF methodRef = (REFLECTMETHODREF)AllocateObject(CoreLibBinder::GetClass(CLASS__STUBMETHODINFO)); GCPROTECT_BEGIN(methodRef); methodRef->SetMethod(this); diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index c19dcc73ddab..2d7fdc6e20bc 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -2511,7 +2511,7 @@ class StoredSigMethodDesc : public MethodDesc { public: // Put the sig RVA in here - this allows us to avoid - // touching the method desc table when mscorlib is prejitted. + // touching the method desc table when CoreLib is prejitted. RelativePointer m_pSig; DWORD m_cSig; @@ -3071,7 +3071,7 @@ class NDirectMethodDesc : public MethodDesc return (ndirect.m_wFlags & kThisCall) != 0; } - // Returns TRUE if this MethodDesc is internal call from mscorlib to mscorwks + // Returns TRUE if this MethodDesc is internal call from CoreLib to VM BOOL IsQCall() const { LIMITED_METHOD_DAC_CONTRACT; diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 6c687345da16..485b82674311 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -3246,7 +3246,7 @@ void MethodTable::DoRunClassInitThrowing() // managed code to re-enter into this codepath, causing a locking order violation. pInitLock.Release(); - if (MscorlibBinder::GetException(kTypeInitializationException) != gc.pInitException->GetMethodTable()) + if (CoreLibBinder::GetException(kTypeInitializationException) != gc.pInitException->GetMethodTable()) { DefineFullyQualifiedNameForClassWOnStack(); LPCWSTR wszName = GetFullyQualifiedNameForClassW(this); @@ -3350,7 +3350,7 @@ void MethodTable::DoRunClassInitThrowing() GetLoaderAllocator()->RegisterFailedTypeInitForCleanup(pEntry); } - _ASSERTE(g_pThreadAbortExceptionClass == MscorlibBinder::GetException(kThreadAbortException)); + _ASSERTE(g_pThreadAbortExceptionClass == CoreLibBinder::GetException(kThreadAbortException)); if(gc.pInnerException->GetMethodTable() == g_pThreadAbortExceptionClass) { @@ -5964,7 +5964,7 @@ CorElementType MethodTable::GetInternalCorElementType() break; case enum_flag_Category_PrimitiveValueType: - // This path should only be taken for the builtin mscorlib types + // This path should only be taken for the builtin CoreLib types // and primitive valuetypes ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 82a4b5003d2e..aa72eb1f899d 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -565,9 +565,9 @@ MethodTableBuilder::LoadApproxInterfaceMap() bmtGenerics->Debug_GetTypicalMethodTable()->Debug_HasInjectedInterfaceDuplicates(); if (GetModule() == g_pObjectClass->GetModule()) - { // mscorlib has some weird hardcoded information about interfaces (e.g. + { // CoreLib has some weird hardcoded information about interfaces (e.g. // code:CEEPreloader::ApplyTypeDependencyForSZArrayHelper), so we don't inject duplicates into - // mscorlib types + // CoreLib types bmtInterface->dbg_fShouldInjectInterfaceDuplicates = FALSE; } } @@ -1350,7 +1350,7 @@ MethodTableBuilder::BuildMethodTableThrowing( )); #endif // _DEBUG - // If this is mscorlib, then don't perform some sanity checks on the layout + // If this is CoreLib, then don't perform some sanity checks on the layout bmtProp->fNoSanityChecks = pModule->IsSystem() || #ifdef FEATURE_READYTORUN // No sanity checks for ready-to-run compiled images if possible @@ -3004,7 +3004,7 @@ MethodTableBuilder::EnumerateClassMethods() } //@GENERICS: // Generic methods or methods in generic classes - // may not be part of a COM Import class, PInvoke, internal call outside mscorlib. + // may not be part of a COM Import class, PInvoke, internal call outside CoreLib. if ((bmtGenerics->GetNumGenericArgs() != 0 || numGenericMethodArgs != 0) && ( #ifdef FEATURE_COMINTEROP @@ -3514,7 +3514,7 @@ VOID MethodTableBuilder::AllocateWorkingSlotTables() // This is broken because // (a) g_pObjectClass->FindMethod("Equals", &gsig_IM_Obj_RetBool); will return // the EqualsValue method - // (b) When mscorlib has been preloaded (and thus the munge already done + // (b) When CoreLib has been preloaded (and thus the munge already done // ahead of time), we cannot easily find both methods // to compute EqualsAddr & EqualsSlot // @@ -4871,15 +4871,15 @@ MethodTableBuilder::ValidateMethods() Signature sig; - sig = MscorlibBinder::GetSignature(&gsig_SM_RetVoid); + sig = CoreLibBinder::GetSignature(&gsig_SM_RetVoid); - MethodSignature cctorSig(MscorlibBinder::GetModule(), + MethodSignature cctorSig(CoreLibBinder::GetModule(), COR_CCTOR_METHOD_NAME, sig.GetRawSig(), sig.GetRawSigLen()); - sig = MscorlibBinder::GetSignature(&gsig_IM_RetVoid); + sig = CoreLibBinder::GetSignature(&gsig_IM_RetVoid); - MethodSignature defaultCtorSig(MscorlibBinder::GetModule(), + MethodSignature defaultCtorSig(CoreLibBinder::GetModule(), COR_CTOR_METHOD_NAME, sig.GetRawSig(), sig.GetRawSigLen()); @@ -10396,7 +10396,6 @@ MethodTableBuilder::SetupMethodTable2( if (GetModule()->IsSystem()) { - // we are in mscorlib CheckForSystemTypes(); } @@ -11041,7 +11040,7 @@ VOID MethodTableBuilder::CheckForSpecialTypes() IMDInternalImport *pMDImport = pModule->GetMDImport(); // Check to see if this type is a managed standard interface. All the managed - // standard interfaces live in mscorlib.dll so checking for that first + // standard interfaces live in CoreLib so checking for that first // makes the strcmp that comes afterwards acceptable. if (pModule->IsSystem()) { diff --git a/src/coreclr/src/vm/mlinfo.cpp b/src/coreclr/src/vm/mlinfo.cpp index c4c479cb6d42..36b07edcfce3 100644 --- a/src/coreclr/src/vm/mlinfo.cpp +++ b/src/coreclr/src/vm/mlinfo.cpp @@ -1929,7 +1929,7 @@ MarshalInfo::MarshalInfo(Module* pModule, } } #endif // FEATURE_COMINTEROP - else if (sigTH.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE)))) + else if (sigTH.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__SAFE_HANDLE)))) { if (nativeType != NATIVE_TYPE_DEFAULT) { @@ -1939,7 +1939,7 @@ MarshalInfo::MarshalInfo(Module* pModule, m_args.m_pMT = m_pMT; m_type = MARSHAL_TYPE_SAFEHANDLE; } - else if (sigTH.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) + else if (sigTH.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) { if (nativeType != NATIVE_TYPE_DEFAULT) { @@ -2304,14 +2304,14 @@ MarshalInfo::MarshalInfo(Module* pModule, && (!m_pMT->IsBlittable() || (m_pMT->HasSameTypeDefAs(g_pNullableClass) || m_pMT->HasSameTypeDefAs(g_pByReferenceClass) - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__SPAN)) - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__READONLY_SPAN)) - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR64T)) - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR128T)) - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR256T)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__SPAN)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__READONLY_SPAN)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR64T)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR128T)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR256T)) #ifndef CROSSGEN_COMPILE // Crossgen scenarios block Vector from even being loaded - || m_pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTORT)) + || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTORT)) #endif // !CROSSGEN_COMPILE ))) { @@ -4359,26 +4359,26 @@ void ArrayMarshalInfo::InitElementInfo(CorNativeType arrayNativeType, MarshalInf } #endif // FEATURE_COMINTEROP } - else if (m_thElement.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE)))) + else if (m_thElement.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__SAFE_HANDLE)))) { // Array's of SAFEHANDLEs are not supported. ReportInvalidArrayMarshalInfo(IDS_EE_BADMARSHAL_SAFEHANDLEARRAY); } - else if (m_thElement.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) + else if (m_thElement.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) { // Array's of CRITICALHANDLEs are not supported. ReportInvalidArrayMarshalInfo(IDS_EE_BADMARSHAL_CRITICALHANDLEARRAY); } else if (etElement == ELEMENT_TYPE_VALUETYPE) { - if (m_thElement == TypeHandle(MscorlibBinder::GetClass(CLASS__DATE_TIME))) + if (m_thElement == TypeHandle(CoreLibBinder::GetClass(CLASS__DATE_TIME))) { if (ntElement == NATIVE_TYPE_STRUCT || ntElement == NATIVE_TYPE_DEFAULT) m_vtElement = VT_DATE; else ReportInvalidArrayMarshalInfo(IDS_EE_BADMARSHAL_DATETIMEARRAY); } - else if (m_thElement == TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL))) + else if (m_thElement == TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL))) { if (ntElement == NATIVE_TYPE_STRUCT || ntElement == NATIVE_TYPE_DEFAULT) m_vtElement = VT_DECIMAL; @@ -4395,7 +4395,7 @@ void ArrayMarshalInfo::InitElementInfo(CorNativeType arrayNativeType, MarshalInf } } #ifdef FEATURE_COMINTEROP - else if (m_thElement == TypeHandle(MscorlibBinder::GetClass(CLASS__ERROR_WRAPPER))) + else if (m_thElement == TypeHandle(CoreLibBinder::GetClass(CLASS__ERROR_WRAPPER))) { m_vtElement = VT_ERROR; } diff --git a/src/coreclr/src/vm/nativeoverlapped.cpp b/src/coreclr/src/vm/nativeoverlapped.cpp index 0657febc366d..46a8600d3ddf 100644 --- a/src/coreclr/src/vm/nativeoverlapped.cpp +++ b/src/coreclr/src/vm/nativeoverlapped.cpp @@ -102,7 +102,7 @@ FCIMPL1(LPOVERLAPPED, AllocateNativeOverlapped, OverlappedDataObject* overlapped if (g_pOverlappedDataClass == NULL) { - g_pOverlappedDataClass = MscorlibBinder::GetClass(CLASS__OVERLAPPEDDATA); + g_pOverlappedDataClass = CoreLibBinder::GetClass(CLASS__OVERLAPPEDDATA); // We have optimization to avoid creating event if IO is in default domain. This depends on default domain // can not be unloaded. } diff --git a/src/coreclr/src/vm/object.cpp b/src/coreclr/src/vm/object.cpp index 8966075d5005..55375739ae9b 100644 --- a/src/coreclr/src/vm/object.cpp +++ b/src/coreclr/src/vm/object.cpp @@ -187,9 +187,7 @@ TypeHandle Object::GetGCSafeTypeHandleIfPossible() const // MT of the innermost element is not getting unloaded. This then ensures the // MT of the original object (i.e., array) itself must not be getting // unloaded either, since the MTs of arrays and of their elements are - // allocated on the same loader heap, except the case where the array is - // Object[], in which case its MT is in mscorlib and thus doesn't unload. - + // allocated on the same loader allocator. Module * pLoaderModule = pMT->GetLoaderModule(); // Don't look up types that are unloading due to Collectible Assemblies. Haven't been @@ -1536,7 +1534,7 @@ void Nullable::CheckFieldOffsets(TypeHandle nullableType) MethodTable* nullableMT = nullableType.GetMethodTable(); // insure that the managed version of the table is the same as the - // unmanaged. Note that we can't do this in mscorlib.h because this + // unmanaged. Note that we can't do this in corelib.h because this // class is generic and field layout depends on the instantiation. _ASSERTE(nullableMT->GetNumInstanceFields() == 2); diff --git a/src/coreclr/src/vm/object.h b/src/coreclr/src/vm/object.h index 5d6c3c3981eb..2acb6e334f5a 100644 --- a/src/coreclr/src/vm/object.h +++ b/src/coreclr/src/vm/object.h @@ -993,7 +993,7 @@ class BaseObjectWithCachedData : public Object // this hasn't yet been defined. class ReflectClassBaseObject : public BaseObjectWithCachedData { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: OBJECTREF m_keepalive; @@ -1123,7 +1123,7 @@ class Utf8StringObject : public Object // type that does not sufficiently match this data structure. class ReflectMethodObject : public BaseObjectWithCachedData { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: OBJECTREF m_object; @@ -1166,7 +1166,7 @@ class ReflectMethodObject : public BaseObjectWithCachedData // type that does not sufficiently match this data structure. class ReflectFieldObject : public BaseObjectWithCachedData { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: OBJECTREF m_object; @@ -1204,7 +1204,7 @@ class ReflectFieldObject : public BaseObjectWithCachedData // class ReflectModuleBaseObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: // READ ME: @@ -1255,7 +1255,7 @@ typedef SafeHandle * SAFEHANDLEREF; class ThreadBaseObject; class SynchronizationContextObject: public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; private: // These field are also defined in the managed representation. (SecurityContext.cs)If you // add or change these field you must also change the managed code so that @@ -1304,7 +1304,7 @@ __inline bool IsCultureEnglishOrInvariant(LPCWSTR localeName) class CultureInfoBaseObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; private: OBJECTREF _compareInfo; @@ -1342,7 +1342,7 @@ class ThreadBaseObject : public Object { friend class ClrDataAccess; friend class ThreadNative; - friend class MscorlibBinder; + friend class CoreLibBinder; friend class Object; private: @@ -1459,7 +1459,7 @@ class MarshalByRefObjectBaseObject : public Object class AssemblyBaseObject : public Object { friend class Assembly; - friend class MscorlibBinder; + friend class CoreLibBinder; protected: // READ ME: @@ -1507,7 +1507,7 @@ NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembl #endif // defined(TARGET_X86) && !defined(TARGET_UNIX) class AssemblyLoadContextBaseObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: // READ ME: @@ -1553,7 +1553,7 @@ class AssemblyNameBaseObject : public Object { friend class AssemblyNative; friend class AppDomainNative; - friend class MscorlibBinder; + friend class CoreLibBinder; protected: // READ ME: @@ -1592,7 +1592,7 @@ class AssemblyNameBaseObject : public Object // class VersionBaseObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: // READ ME: @@ -1720,7 +1720,7 @@ CHARARRAYREF AllocateCharArray(DWORD dwArrayLength); //------------------------------------------------------------- class ComObject : public MarshalByRefObjectBaseObject { - friend class MscorlibBinder; + friend class CoreLibBinder; protected: @@ -1992,7 +1992,7 @@ typedef BStrWrapper* BSTRWRAPPEROBJECTREF; class SafeHandle : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; private: // READ ME: @@ -2042,7 +2042,7 @@ typedef Holder SafeHandleH class CriticalHandle : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; private: // READ ME: @@ -2072,7 +2072,7 @@ typedef CriticalHandle * CRITICALHANDLEREF; // Base class for WaitHandle class WaitHandleBase :public MarshalByRefObjectBaseObject { - friend class MscorlibBinder; + friend class CoreLibBinder; public: __inline LPVOID GetWaitHandle() { @@ -2096,7 +2096,7 @@ typedef WaitHandleBase* WAITHANDLEREF; class DelegateObject : public Object { friend class CheckAsmOffsets; - friend class MscorlibBinder; + friend class CoreLibBinder; public: BOOL IsWrapperDelegate() { LIMITED_METHOD_CONTRACT; return _methodPtrAux == NULL; } @@ -2316,7 +2316,7 @@ class StackTraceArray class LoaderAllocatorScoutObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; friend class LoaderAllocatorObject; protected: @@ -2331,7 +2331,7 @@ typedef LoaderAllocatorScoutObject* LOADERALLOCATORSCOUTREF; class LoaderAllocatorObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; public: PTRARRAYREF GetHandleTable() @@ -2393,7 +2393,7 @@ typedef DPTR(class ExceptionObject) PTR_ExceptionObject; #include "pshpack4.h" class ExceptionObject : public Object { - friend class MscorlibBinder; + friend class CoreLibBinder; public: void SetHResult(HRESULT hr) @@ -2617,7 +2617,7 @@ enum ContractFailureKind typedef DPTR(class ContractExceptionObject) PTR_ContractExceptionObject; class ContractExceptionObject : public ExceptionObject { - friend class MscorlibBinder; + friend class CoreLibBinder; public: ContractFailureKind GetContractFailureKind() @@ -2742,7 +2742,7 @@ class GCHeapHashObject : public Object friend class JIT_TrialAlloc; friend class CheckAsmOffsets; friend class COMString; - friend class MscorlibBinder; + friend class CoreLibBinder; private: BASEARRAYREF _data; @@ -2799,7 +2799,7 @@ class LAHashDependentHashTrackerObject : public Object friend class ClrDataAccess; #endif friend class CheckAsmOffsets; - friend class MscorlibBinder; + friend class CoreLibBinder; private: OBJECTHANDLE _dependentHandle; @@ -2837,7 +2837,7 @@ class LAHashKeyToTrackersObject : public Object friend class ClrDataAccess; #endif friend class CheckAsmOffsets; - friend class MscorlibBinder; + friend class CoreLibBinder; public: // _trackerOrTrackerSet is either a reference to a LAHashDependentHashTracker, or to a GCHeapHash of LAHashDependentHashTracker objects. diff --git a/src/coreclr/src/vm/olevariant.cpp b/src/coreclr/src/vm/olevariant.cpp index 1755add7d5e7..d4d256e01329 100644 --- a/src/coreclr/src/vm/olevariant.cpp +++ b/src/coreclr/src/vm/olevariant.cpp @@ -260,13 +260,13 @@ VARTYPE OleVariant::GetVarTypeForComVariant(VariantData *pComVariant) #ifdef FEATURE_COMINTEROP // SafeHandle's or CriticalHandle's cannot be stored in VARIANT's. - if (pMT->CanCastToClass(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE))) + if (pMT->CanCastToClass(CoreLibBinder::GetClass(CLASS__SAFE_HANDLE))) COMPlusThrow(kArgumentException, IDS_EE_SH_IN_VARIANT_NOT_SUPPORTED); - if (pMT->CanCastToClass(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE))) + if (pMT->CanCastToClass(CoreLibBinder::GetClass(CLASS__CRITICAL_HANDLE))) COMPlusThrow(kArgumentException, IDS_EE_CH_IN_VARIANT_NOT_SUPPORTED); // VariantWrappers cannot be stored in VARIANT's. - if (MscorlibBinder::IsClass(pMT, CLASS__VARIANT_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__VARIANT_WRAPPER)) COMPlusThrow(kArgumentException, IDS_EE_VAR_WRAP_IN_VAR_NOT_SUPPORTED); // We are dealing with a normal object (not a wrapper) so we will @@ -311,37 +311,37 @@ VARTYPE OleVariant::GetVarTypeForTypeHandle(TypeHandle type) return VT_VARIANT; // We need to make sure the CVClasses table is populated. - if(MscorlibBinder::IsClass(pMT, CLASS__DATE_TIME)) + if(CoreLibBinder::IsClass(pMT, CLASS__DATE_TIME)) return VT_DATE; - if(MscorlibBinder::IsClass(pMT, CLASS__DECIMAL)) + if(CoreLibBinder::IsClass(pMT, CLASS__DECIMAL)) return VT_DECIMAL; #ifdef HOST_64BIT - if (MscorlibBinder::IsClass(pMT, CLASS__INTPTR)) + if (CoreLibBinder::IsClass(pMT, CLASS__INTPTR)) return VT_I8; - if (MscorlibBinder::IsClass(pMT, CLASS__UINTPTR)) + if (CoreLibBinder::IsClass(pMT, CLASS__UINTPTR)) return VT_UI8; #else - if (MscorlibBinder::IsClass(pMT, CLASS__INTPTR)) + if (CoreLibBinder::IsClass(pMT, CLASS__INTPTR)) return VT_INT; - if (MscorlibBinder::IsClass(pMT, CLASS__UINTPTR)) + if (CoreLibBinder::IsClass(pMT, CLASS__UINTPTR)) return VT_UINT; #endif #ifdef FEATURE_COMINTEROP - if (MscorlibBinder::IsClass(pMT, CLASS__DISPATCH_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__DISPATCH_WRAPPER)) return VT_DISPATCH; - if (MscorlibBinder::IsClass(pMT, CLASS__UNKNOWN_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__UNKNOWN_WRAPPER)) return VT_UNKNOWN; - if (MscorlibBinder::IsClass(pMT, CLASS__ERROR_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__ERROR_WRAPPER)) return VT_ERROR; - if (MscorlibBinder::IsClass(pMT, CLASS__CURRENCY_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__CURRENCY_WRAPPER)) return VT_CY; - if (MscorlibBinder::IsClass(pMT, CLASS__BSTR_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__BSTR_WRAPPER)) return VT_BSTR; // VariantWrappers cannot be stored in VARIANT's. - if (MscorlibBinder::IsClass(pMT, CLASS__VARIANT_WRAPPER)) + if (CoreLibBinder::IsClass(pMT, CLASS__VARIANT_WRAPPER)) COMPlusThrow(kArgumentException, IDS_EE_COM_UNSUPPORTED_SIG); #endif // FEATURE_COMINTEROP @@ -357,9 +357,9 @@ VARTYPE OleVariant::GetVarTypeForTypeHandle(TypeHandle type) #ifdef FEATURE_COMINTEROP // There is no VT corresponding to SafeHandles as they cannot be stored in // VARIANTs or Arrays. The same applies to CriticalHandle. - if (type.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE)))) + if (type.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__SAFE_HANDLE)))) COMPlusThrow(kArgumentException, IDS_EE_COM_UNSUPPORTED_SIG); - if (type.CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) + if (type.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__CRITICAL_HANDLE)))) COMPlusThrow(kArgumentException, IDS_EE_COM_UNSUPPORTED_SIG); if (pMT->IsInterface()) @@ -639,15 +639,15 @@ TypeHandle OleVariant::GetArrayForVarType(VARTYPE vt, TypeHandle elemType, unsig break; case VT_CY: - baseType = TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL)); + baseType = TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL)); break; case VT_DATE: - baseType = TypeHandle(MscorlibBinder::GetClass(CLASS__DATE_TIME)); + baseType = TypeHandle(CoreLibBinder::GetClass(CLASS__DATE_TIME)); break; case VT_DECIMAL: - baseType = TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL)); + baseType = TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL)); break; case VT_VARIANT: @@ -702,7 +702,7 @@ TypeHandle OleVariant::GetArrayForVarType(VARTYPE vt, TypeHandle elemType, unsig } if (baseType.IsNull()) - baseType = TypeHandle(MscorlibBinder::GetElementType(baseElement)); + baseType = TypeHandle(CoreLibBinder::GetElementType(baseElement)); _ASSERTE(!baseType.IsNull()); @@ -806,21 +806,21 @@ MethodTable* OleVariant::GetNativeMethodTableForVarType(VARTYPE vt, MethodTable* if (vt & VT_ARRAY) { - return MscorlibBinder::GetClass(CLASS__INTPTR); + return CoreLibBinder::GetClass(CLASS__INTPTR); } switch (vt) { case VT_DATE: - return MscorlibBinder::GetClass(CLASS__DOUBLE); + return CoreLibBinder::GetClass(CLASS__DOUBLE); case VT_CY: - return MscorlibBinder::GetClass(CLASS__CURRENCY); + return CoreLibBinder::GetClass(CLASS__CURRENCY); case VTHACK_WINBOOL: - return MscorlibBinder::GetClass(CLASS__INT32); + return CoreLibBinder::GetClass(CLASS__INT32); case VT_BOOL: - return MscorlibBinder::GetClass(CLASS__INT16); + return CoreLibBinder::GetClass(CLASS__INT16); case VTHACK_CBOOL: - return MscorlibBinder::GetClass(CLASS__BYTE); + return CoreLibBinder::GetClass(CLASS__BYTE); case VT_DISPATCH: case VT_UNKNOWN: case VT_LPSTR: @@ -829,19 +829,19 @@ MethodTable* OleVariant::GetNativeMethodTableForVarType(VARTYPE vt, MethodTable* case VT_USERDEFINED: case VT_SAFEARRAY: case VT_CARRAY: - return MscorlibBinder::GetClass(CLASS__INTPTR); + return CoreLibBinder::GetClass(CLASS__INTPTR); case VT_VARIANT: - return MscorlibBinder::GetClass(CLASS__NATIVEVARIANT); + return CoreLibBinder::GetClass(CLASS__NATIVEVARIANT); case VTHACK_ANSICHAR: - return MscorlibBinder::GetClass(CLASS__BYTE); + return CoreLibBinder::GetClass(CLASS__BYTE); case VT_UI2: // When CharSet = CharSet.Unicode, System.Char arrays are marshaled as VT_UI2. // However, since System.Char itself is CharSet.Ansi, the native size of // System.Char is 1 byte instead of 2. So here we explicitly return System.UInt16's // MethodTable to ensure the correct size. - return MscorlibBinder::GetClass(CLASS__UINT16); + return CoreLibBinder::GetClass(CLASS__UINT16); case VT_DECIMAL: - return MscorlibBinder::GetClass(CLASS__NATIVEDECIMAL); + return CoreLibBinder::GetClass(CLASS__NATIVEDECIMAL); default: PREFIX_ASSUME(pManagedMT != NULL); return pManagedMT; @@ -1136,7 +1136,7 @@ void VariantData::NewVariant(VariantData * const& dest, const CVTypes type, INT6 case CV_NULL: { - FieldDesc * pFD = MscorlibBinder::GetField(FIELD__NULL__VALUE); + FieldDesc * pFD = CoreLibBinder::GetField(FIELD__NULL__VALUE); _ASSERTE(pFD); pFD->CheckRunClassInitThrowing(); @@ -2520,7 +2520,7 @@ void OleVariant::MarshalDecimalVariantOleToCom(VARIANT *pOleVariant, } CONTRACTL_END; - OBJECTREF pDecimalRef = AllocateObject(MscorlibBinder::GetClass(CLASS__DECIMAL)); + OBJECTREF pDecimalRef = AllocateObject(CoreLibBinder::GetClass(CLASS__DECIMAL)); DECIMAL* pDecimal = (DECIMAL *) pDecimalRef->UnBox(); *pDecimal = V_DECIMAL(pOleVariant); @@ -2563,7 +2563,7 @@ void OleVariant::MarshalDecimalVariantOleRefToCom(VARIANT *pOleVariant, } CONTRACTL_END; - OBJECTREF pDecimalRef = AllocateObject(MscorlibBinder::GetClass(CLASS__DECIMAL)); + OBJECTREF pDecimalRef = AllocateObject(CoreLibBinder::GetClass(CLASS__DECIMAL)); DECIMAL* pDecimal = (DECIMAL *) pDecimalRef->UnBox(); *pDecimal = *V_DECIMALREF(pOleVariant); @@ -2781,7 +2781,7 @@ void OleVariant::MarshalOleVariantForObject(OBJECTREF * const & pObj, VARIANT *p else { MethodTable *pMT = (*pObj)->GetMethodTable(); - if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)) + if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I4)) { V_I4(pOle) = *(LONG*)( (*pObj)->GetData() ); V_VT(pOle) = VT_I4; @@ -2802,52 +2802,52 @@ void OleVariant::MarshalOleVariantForObject(OBJECTREF * const & pObj, VARIANT *p V_VT(pOle) = VT_BSTR; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I2)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I2)) { V_I2(pOle) = *(SHORT*)( (*pObj)->GetData() ); V_VT(pOle) = VT_I2; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I1)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I1)) { V_I1(pOle) = *(CHAR*)( (*pObj)->GetData() ); V_VT(pOle) = VT_I1; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U4)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) { V_UI4(pOle) = *(ULONG*)( (*pObj)->GetData() ); V_VT(pOle) = VT_UI4; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U2)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U2)) { V_UI2(pOle) = *(USHORT*)( (*pObj)->GetData() ); V_VT(pOle) = VT_UI2; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) { V_UI1(pOle) = *(BYTE*)( (*pObj)->GetData() ); V_VT(pOle) = VT_UI1; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_R4)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_R4)) { V_R4(pOle) = *(FLOAT*)( (*pObj)->GetData() ); V_VT(pOle) = VT_R4; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_R8)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_R8)) { V_R8(pOle) = *(DOUBLE*)( (*pObj)->GetData() ); V_VT(pOle) = VT_R8; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) { V_BOOL(pOle) = *(U1*)( (*pObj)->GetData() ) ? VARIANT_TRUE : VARIANT_FALSE; V_VT(pOle) = VT_BOOL; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I)) { *(LPVOID*)&(V_INT(pOle)) = *(LPVOID*)( (*pObj)->GetData() ); V_VT(pOle) = VT_INT; } - else if (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U)) + else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U)) { *(LPVOID*)&(V_UINT(pOle)) = *(LPVOID*)( (*pObj)->GetData() ); V_VT(pOle) = VT_UINT; @@ -2972,49 +2972,49 @@ HRESULT OleVariant::MarshalCommonOleRefVariantForObject(OBJECTREF *pObj, VARIANT // Let's try to handle the common trivial cases quickly first before // running the generalized stuff. MethodTable *pMT = (*pObj) == NULL ? NULL : (*pObj)->GetMethodTable(); - if ( (V_VT(pOle) == (VT_BYREF | VT_I4) || V_VT(pOle) == (VT_BYREF | VT_UI4)) && (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I4) || pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U4)) ) + if ( (V_VT(pOle) == (VT_BYREF | VT_I4) || V_VT(pOle) == (VT_BYREF | VT_UI4)) && (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I4) || pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_I4REF(pOle)) = *(LONG*)( (*pObj)->GetData() ); } - else if ( (V_VT(pOle) == (VT_BYREF | VT_I2) || V_VT(pOle) == (VT_BYREF | VT_UI2)) && (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I2) || pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U2)) ) + else if ( (V_VT(pOle) == (VT_BYREF | VT_I2) || V_VT(pOle) == (VT_BYREF | VT_UI2)) && (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I2) || pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U2)) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_I2REF(pOle)) = *(SHORT*)( (*pObj)->GetData() ); } - else if ( (V_VT(pOle) == (VT_BYREF | VT_I1) || V_VT(pOle) == (VT_BYREF | VT_UI1)) && (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I1) || pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) ) + else if ( (V_VT(pOle) == (VT_BYREF | VT_I1) || V_VT(pOle) == (VT_BYREF | VT_UI1)) && (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I1) || pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_I1REF(pOle)) = *(CHAR*)( (*pObj)->GetData() ); } - else if ( V_VT(pOle) == (VT_BYREF | VT_R4) && pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_R4) ) + else if ( V_VT(pOle) == (VT_BYREF | VT_R4) && pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_R4) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_R4REF(pOle)) = *(FLOAT*)( (*pObj)->GetData() ); } - else if ( V_VT(pOle) == (VT_BYREF | VT_R8) && pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_R8) ) + else if ( V_VT(pOle) == (VT_BYREF | VT_R8) && pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_R8) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_R8REF(pOle)) = *(DOUBLE*)( (*pObj)->GetData() ); } - else if ( V_VT(pOle) == (VT_BYREF | VT_BOOL) && pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN) ) + else if ( V_VT(pOle) == (VT_BYREF | VT_BOOL) && pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. *(V_BOOLREF(pOle)) = ( *(U1*)( (*pObj)->GetData() ) ) ? VARIANT_TRUE : VARIANT_FALSE; } - else if ( (V_VT(pOle) == (VT_BYREF | VT_INT) || V_VT(pOle) == (VT_BYREF | VT_UINT)) && (pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_I4) || pMT == MscorlibBinder::GetElementType(ELEMENT_TYPE_U4)) ) + else if ( (V_VT(pOle) == (VT_BYREF | VT_INT) || V_VT(pOle) == (VT_BYREF | VT_UINT)) && (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I4) || pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) ) { // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. @@ -3122,112 +3122,112 @@ void OleVariant::MarshalObjectForOleVariant(const VARIANT * pOle, OBJECTREF * co case VT_I4: case VT_INT: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I4)) ); *(LONG*)((*pObj)->GetData()) = V_I4(pOle); break; case VT_BYREF|VT_I4: case VT_BYREF|VT_INT: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I4)) ); *(LONG*)((*pObj)->GetData()) = *(V_I4REF(pOle)); break; case VT_UI4: case VT_UINT: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) ); *(ULONG*)((*pObj)->GetData()) = V_UI4(pOle); break; case VT_BYREF|VT_UI4: case VT_BYREF|VT_UINT: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) ); *(ULONG*)((*pObj)->GetData()) = *(V_UI4REF(pOle)); break; case VT_I2: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I2)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I2)) ); (*(SHORT*)((*pObj)->GetData())) = V_I2(pOle); break; case VT_BYREF|VT_I2: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I2)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I2)) ); *(SHORT*)((*pObj)->GetData()) = *(V_I2REF(pOle)); break; case VT_UI2: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U2)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U2)) ); *(USHORT*)((*pObj)->GetData()) = V_UI2(pOle); break; case VT_BYREF|VT_UI2: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U2)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U2)) ); *(USHORT*)((*pObj)->GetData()) = *(V_UI2REF(pOle)); break; case VT_I1: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I1)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I1)) ); *(CHAR*)((*pObj)->GetData()) = V_I1(pOle); break; case VT_BYREF|VT_I1: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I1)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_I1)) ); *(CHAR*)((*pObj)->GetData()) = *(V_I1REF(pOle)); break; case VT_UI1: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) ); *(BYTE*)((*pObj)->GetData()) = V_UI1(pOle); break; case VT_BYREF|VT_UI1: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) ); *(BYTE*)((*pObj)->GetData()) = *(V_UI1REF(pOle)); break; case VT_R4: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_R4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_R4)) ); *(FLOAT*)((*pObj)->GetData()) = V_R4(pOle); break; case VT_BYREF|VT_R4: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_R4)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_R4)) ); *(FLOAT*)((*pObj)->GetData()) = *(V_R4REF(pOle)); break; case VT_R8: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_R8)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_R8)) ); *(DOUBLE*)((*pObj)->GetData()) = V_R8(pOle); break; case VT_BYREF|VT_R8: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_R8)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_R8)) ); *(DOUBLE*)((*pObj)->GetData()) = *(V_R8REF(pOle)); break; case VT_BOOL: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) ); *(VARIANT_BOOL*)((*pObj)->GetData()) = V_BOOL(pOle) ? 1 : 0; break; case VT_BYREF|VT_BOOL: SetObjectReference( pObj, - AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) ); + AllocateObject(CoreLibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) ); *(VARIANT_BOOL*)((*pObj)->GetData()) = *(V_BOOLREF(pOle)) ? 1 : 0; break; @@ -3800,7 +3800,7 @@ void OleVariant::MarshalCurrencyVariantOleToCom(VARIANT *pOleVariant, } CONTRACTL_END; - OBJECTREF pDecimalRef = AllocateObject(MscorlibBinder::GetClass(CLASS__DECIMAL)); + OBJECTREF pDecimalRef = AllocateObject(CoreLibBinder::GetClass(CLASS__DECIMAL)); DECIMAL DecVal; // Convert the currency to a decimal. @@ -3848,7 +3848,7 @@ void OleVariant::MarshalCurrencyVariantOleRefToCom(VARIANT *pOleVariant, } CONTRACTL_END; - OBJECTREF pDecimalRef = AllocateObject(MscorlibBinder::GetClass(CLASS__DECIMAL)); + OBJECTREF pDecimalRef = AllocateObject(CoreLibBinder::GetClass(CLASS__DECIMAL)); DECIMAL DecVal; // Convert the currency to a decimal. @@ -4867,16 +4867,16 @@ BOOL OleVariant::IsArrayOfWrappers(BASEARRAYREF *pArray, BOOL *pbOfInterfaceWrap if (!hndElemType.IsTypeDesc()) { - if (hndElemType == TypeHandle(MscorlibBinder::GetClass(CLASS__DISPATCH_WRAPPER)) || - hndElemType == TypeHandle(MscorlibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) + if (hndElemType == TypeHandle(CoreLibBinder::GetClass(CLASS__DISPATCH_WRAPPER)) || + hndElemType == TypeHandle(CoreLibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) { *pbOfInterfaceWrappers = TRUE; return TRUE; } - if (hndElemType == TypeHandle(MscorlibBinder::GetClass(CLASS__ERROR_WRAPPER)) || - hndElemType == TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY_WRAPPER)) || - hndElemType == TypeHandle(MscorlibBinder::GetClass(CLASS__BSTR_WRAPPER))) + if (hndElemType == TypeHandle(CoreLibBinder::GetClass(CLASS__ERROR_WRAPPER)) || + hndElemType == TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY_WRAPPER)) || + hndElemType == TypeHandle(CoreLibBinder::GetClass(CLASS__BSTR_WRAPPER))) { *pbOfInterfaceWrappers = FALSE; return TRUE; @@ -4906,20 +4906,20 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) BASEARRAYREF RetArray = NULL; // Retrieve the element type handle for the array to create. - if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__DISPATCH_WRAPPER))) + if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__DISPATCH_WRAPPER))) hndElemType = TypeHandle(g_pObjectClass); - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) hndElemType = TypeHandle(g_pObjectClass); - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__BSTR_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__BSTR_WRAPPER))) hndElemType = TypeHandle(g_pStringClass); - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__ERROR_WRAPPER))) - hndElemType = TypeHandle(MscorlibBinder::GetClass(CLASS__INT32)); + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__ERROR_WRAPPER))) + hndElemType = TypeHandle(CoreLibBinder::GetClass(CLASS__INT32)); - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) - hndElemType = TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL)); + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) + hndElemType = TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL)); else _ASSERTE(!"Invalid wrapper type"); @@ -4961,7 +4961,7 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) { SIZE_T NumComponents = (*pArray)->GetNumComponents(); - if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__DISPATCH_WRAPPER))) + if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__DISPATCH_WRAPPER))) { DISPATCHWRAPPEROBJECTREF *pSrc = (DISPATCHWRAPPEROBJECTREF *)(*pArray)->GetDataPtr(); DISPATCHWRAPPEROBJECTREF *pSrcEnd = pSrc + NumComponents; @@ -4969,7 +4969,7 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) for (; pSrc < pSrcEnd; pSrc++, pDest++) SetObjectReference(pDest, (*pSrc) != NULL ? (*pSrc)->GetWrappedObject() : NULL); } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) { UNKNOWNWRAPPEROBJECTREF *pSrc = (UNKNOWNWRAPPEROBJECTREF *)(*pArray)->GetDataPtr(); UNKNOWNWRAPPEROBJECTREF *pSrcEnd = pSrc + NumComponents; @@ -4977,7 +4977,7 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) for (; pSrc < pSrcEnd; pSrc++, pDest++) SetObjectReference(pDest, (*pSrc) != NULL ? (*pSrc)->GetWrappedObject() : NULL); } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__ERROR_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__ERROR_WRAPPER))) { ERRORWRAPPEROBJECTREF *pSrc = (ERRORWRAPPEROBJECTREF *)(*pArray)->GetDataPtr(); ERRORWRAPPEROBJECTREF *pSrcEnd = pSrc + NumComponents; @@ -4985,7 +4985,7 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) for (; pSrc < pSrcEnd; pSrc++, pDest++) *pDest = (*pSrc) != NULL ? (*pSrc)->GetErrorCode() : NULL; } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) { CURRENCYWRAPPEROBJECTREF *pSrc = (CURRENCYWRAPPEROBJECTREF *)(*pArray)->GetDataPtr(); CURRENCYWRAPPEROBJECTREF *pSrcEnd = pSrc + NumComponents; @@ -4998,7 +4998,7 @@ BASEARRAYREF OleVariant::ExtractWrappedObjectsFromArray(BASEARRAYREF *pArray) memset(pDest, 0, sizeof(DECIMAL)); } } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__BSTR_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__BSTR_WRAPPER))) { BSTRWRAPPEROBJECTREF *pSrc = (BSTRWRAPPEROBJECTREF *)(*pArray)->GetDataPtr(); BSTRWRAPPEROBJECTREF *pSrcEnd = pSrc + NumComponents; @@ -5034,22 +5034,22 @@ TypeHandle OleVariant::GetWrappedArrayElementType(BASEARRAYREF *pArray) TypeHandle hndWrapperType = (*pArray)->GetArrayElementTypeHandle(); TypeHandle pWrappedObjType; - if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__DISPATCH_WRAPPER)) || - hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) + if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__DISPATCH_WRAPPER)) || + hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__UNKNOWN_WRAPPER))) { // There's no need to traverse the array up front. We'll use the default interface // for each element in code:OleVariant::MarshalInterfaceArrayComToOleHelper. pWrappedObjType = TypeHandle(g_pObjectClass); } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__ERROR_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__ERROR_WRAPPER))) { - pWrappedObjType = TypeHandle(MscorlibBinder::GetClass(CLASS__INT32)); + pWrappedObjType = TypeHandle(CoreLibBinder::GetClass(CLASS__INT32)); } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__CURRENCY_WRAPPER))) { - pWrappedObjType = TypeHandle(MscorlibBinder::GetClass(CLASS__DECIMAL)); + pWrappedObjType = TypeHandle(CoreLibBinder::GetClass(CLASS__DECIMAL)); } - else if (hndWrapperType == TypeHandle(MscorlibBinder::GetClass(CLASS__BSTR_WRAPPER))) + else if (hndWrapperType == TypeHandle(CoreLibBinder::GetClass(CLASS__BSTR_WRAPPER))) { pWrappedObjType = TypeHandle(g_pStringClass); } diff --git a/src/coreclr/src/vm/olevariant.h b/src/coreclr/src/vm/olevariant.h index dfc846e2731b..d8f49f7e23df 100644 --- a/src/coreclr/src/vm/olevariant.h +++ b/src/coreclr/src/vm/olevariant.h @@ -75,7 +75,7 @@ inline TypeHandle GetTypeHandleForCVType(CVTypes elemType) } CONTRACT_END; - RETURN TypeHandle(MscorlibBinder::GetClass(CVTypeToBinderClassID[elemType])); + RETURN TypeHandle(CoreLibBinder::GetClass(CVTypeToBinderClassID[elemType])); } // Use this very carefully. There is not a direct mapping between @@ -116,7 +116,7 @@ extern CVTypes CorElementTypeToCVTypes(CorElementType type); struct VariantData { - friend class MscorlibBinder; + friend class CoreLibBinder; public: static void NewVariant(VariantData * const& dest, const CVTypes type, INT64 data diff --git a/src/coreclr/src/vm/packedfields.inl b/src/coreclr/src/vm/packedfields.inl index 16544acd2208..aa070fdbcbbf 100644 --- a/src/coreclr/src/vm/packedfields.inl +++ b/src/coreclr/src/vm/packedfields.inl @@ -144,7 +144,7 @@ public: // to encode zero-valued fields with zero bits. Is this is deemed an important optimization in the // future we could always given up on a simple linear mapping of the size field and use a lookup // table to map values encoded into the real sizes. Experiments with EEClass packed fields over - // mscorlib show that this currently doesn't yield us much benefit, primarily due to the DWORD + // CoreLib show that this currently doesn't yield us much benefit, primarily due to the DWORD // round-up size semantic, which implies we'd need a lot more optimization than this to reduce the // average structure size below the next DWORD threshhold. BitVectorSet(dwOffset, kMaxLengthBits, dwFieldLength - 1); diff --git a/src/coreclr/src/vm/pefile.h b/src/coreclr/src/vm/pefile.h index 2ee625206163..383fb53de053 100644 --- a/src/coreclr/src/vm/pefile.h +++ b/src/coreclr/src/vm/pefile.h @@ -626,7 +626,7 @@ class PEAssembly : public PEFile PEImage * pPEImageNI, ICLRPrivAssembly * pHostAssembly); - // This opens the canonical mscorlib.dll + // This opens the canonical System.Private.CoreLib.dll static PEAssembly *OpenSystem(IUnknown *pAppCtx); #ifdef DACCESS_COMPILE virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); diff --git a/src/coreclr/src/vm/perfmap.cpp b/src/coreclr/src/vm/perfmap.cpp index 9fa9af72c67c..8eb8925f7e0b 100644 --- a/src/coreclr/src/vm/perfmap.cpp +++ b/src/coreclr/src/vm/perfmap.cpp @@ -401,7 +401,7 @@ NativeImagePerfMap::NativeImagePerfMap(Assembly * pAssembly, BSTR pDestPath) GetNativeImageSignature(pAssembly->GetManifestFile(), wszSignature, lengthof(wszSignature)); // Build the path to the perfmap file, which consists of .ni..map. - // Example: /tmp/mscorlib.ni.{GUID}.map + // Example: /tmp/System.Private.CoreLib.ni.{GUID}.map SString sDestPerfMapPath; sDestPerfMapPath.Printf("%S%s.ni.%S.map", pDestPath, lpcSimpleName, wszSignature); diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index dd7ca44aaf9d..e6ff77ab239b 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -1485,7 +1485,7 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM CreateInstantiatingILStubTargetSig(pTargetMD, typeContext, &stubSigBuilder); // 2. Emit the method body - mdToken tokRawData = pCode->GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); + mdToken tokRawData = pCode->GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)); // 2.1 Push the thisptr // We need to skip over the MethodTable* @@ -2412,7 +2412,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl // // In this IL stub implementation we call the native method kernel32!GetFileAttributes, // and then we immediately try to save the Last Error code by calling the - // mscorlib method System.StubHelpers.StubHelpers.SetLastError(). + // CoreLib method System.StubHelpers.StubHelpers.SetLastError(). // // However when we are coming from a precompiled IL Stub in an ngen image // we must use an ExternalMethodFixup to find the target address of @@ -3384,7 +3384,7 @@ PCODE DynamicHelperFixup(TransitionBlock * pTransitionBlock, TADDR * pCell, DWOR } else { - target = ECall::GetFCallImpl(MscorlibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE)); + target = ECall::GetFCallImpl(CoreLibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE)); ctorData.pArg3 = NULL; } diff --git a/src/coreclr/src/vm/qcall.cpp b/src/coreclr/src/vm/qcall.cpp index e46ab2268c6b..497cdff7adf0 100644 --- a/src/coreclr/src/vm/qcall.cpp +++ b/src/coreclr/src/vm/qcall.cpp @@ -70,7 +70,7 @@ void QCall::ObjectHandleOnStack::SetGuidArray(const GUID * p, COUNT_T length) GCX_COOP(); - ::TypeHandle typeHandle = MscorlibBinder::GetClass(CLASS__GUID); + ::TypeHandle typeHandle = CoreLibBinder::GetClass(CLASS__GUID); BASEARRAYREF arr = (BASEARRAYREF) AllocateSzArray(typeHandle.MakeSZArray(), length); memcpyNoGCRefs(arr->GetDataPtr(), p, length * sizeof(GUID)); Set(arr); diff --git a/src/coreclr/src/vm/qcall.h b/src/coreclr/src/vm/qcall.h index 581aefe4cf83..2517f59953bb 100644 --- a/src/coreclr/src/vm/qcall.h +++ b/src/coreclr/src/vm/qcall.h @@ -13,8 +13,8 @@ // QCALLS // -// QCalls are internal calls from managed code in mscorlib.dll to unmanaged code in mscorwks.dll. QCalls are very much like -// a normal P/Invoke from mscorlib.dll to mscorwks.dll. +// QCalls are internal calls from managed code in CoreLib to unmanaged code in VM. QCalls are very much like +// a normal P/Invoke from CoreLib to VM. // // Unlike FCalls, QCalls will marshal all arguments as unmanaged types like a normal P/Invoke. QCall also switch to preemptive // GC mode like a normal P/Invoke. These two features should make QCalls easier to write reliably compared to FCalls. diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 59a643192d19..4ea56e358a74 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -200,7 +200,7 @@ FCIMPL2(FC_BOOL_RET, ReflectionInvocation::CanValueSpecialCast, ReflectClassBase // the field type is a pointer if (targetCorElement == ELEMENT_TYPE_PTR || targetCorElement == ELEMENT_TYPE_FNPTR) { // the object must be an IntPtr or a System.Reflection.Pointer - if (valueType == TypeHandle(MscorlibBinder::GetClass(CLASS__INTPTR))) { + if (valueType == TypeHandle(CoreLibBinder::GetClass(CLASS__INTPTR))) { // // it's an IntPtr, it's good. } @@ -1679,7 +1679,7 @@ FCIMPL5(void, RuntimeFieldHandle::SetValueDirect, ReflectFieldObject *pFieldUNSA case ELEMENT_TYPE_PTR: // pointers if (gc.oValue != 0) { value = 0; - if (MscorlibBinder::IsClass(gc.oValue->GetMethodTable(), CLASS__POINTER)) { + if (CoreLibBinder::IsClass(gc.oValue->GetMethodTable(), CLASS__POINTER)) { value = (size_t) InvokeUtil::GetPointerValue(gc.oValue); #ifdef _MSC_VER #pragma warning(disable: 4267) //work-around for compiler @@ -2368,7 +2368,7 @@ FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingType, ReflectClassBas OBJECTREF result = NULL; HELPER_METHOD_FRAME_BEGIN_RET_0(); - MethodTable *pMT = MscorlibBinder::GetElementType(th.AsMethodTable()->GetInternalCorElementType()); + MethodTable *pMT = CoreLibBinder::GetElementType(th.AsMethodTable()->GetInternalCorElementType()); result = pMT->GetManagedClassObject(); HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/rexcep.h b/src/coreclr/src/vm/rexcep.h index 03cfa3617f9a..da7686af64e1 100644 --- a/src/coreclr/src/vm/rexcep.h +++ b/src/coreclr/src/vm/rexcep.h @@ -279,14 +279,4 @@ DEFINE_EXCEPTION(g_SystemNS, OutOfMemoryException, false, E DEFINE_EXCEPTION(g_SystemNS, ArgumentNullException, false, E_POINTER) -#define kLastExceptionInMscorlib kArgumentNullException - -// -// All exceptions defined in other .NET Framework assemblies have to be at the end -// - - - -// Please see comments on at the top of this list - #undef DEFINE_EXCEPTION diff --git a/src/coreclr/src/vm/runtimecallablewrapper.cpp b/src/coreclr/src/vm/runtimecallablewrapper.cpp index 05bbc24938bf..16d7e5e86302 100644 --- a/src/coreclr/src/vm/runtimecallablewrapper.cpp +++ b/src/coreclr/src/vm/runtimecallablewrapper.cpp @@ -2248,9 +2248,9 @@ HRESULT RCW::SafeQueryInterfaceRemoteAware(REFIID iid, IUnknown** ppResUnk) #endif //#ifndef CROSSGEN_COMPILE // Helper method to allow us to compare a MethodTable against a known method table -// from mscorlib. If the mscorlib type isn't loaded, we don't load it because we +// from CoreLib. If the CoreLib type isn't loaded, we don't load it because we // know that it can't be the MethodTable we're curious about. -static bool MethodTableHasSameTypeDefAsMscorlibClass(MethodTable* pMT, BinderClassID classId) +static bool MethodTableHasSameTypeDefAsCoreLibClass(MethodTable* pMT, BinderClassID classId) { CONTRACTL { @@ -2260,11 +2260,11 @@ static bool MethodTableHasSameTypeDefAsMscorlibClass(MethodTable* pMT, BinderCla } CONTRACTL_END; - MethodTable* pMT_MscorlibClass = MscorlibBinder::GetClassIfExist(classId); - if (pMT_MscorlibClass == NULL) + MethodTable* pMT_CoreLibClass = CoreLibBinder::GetClassIfExist(classId); + if (pMT_CoreLibClass == NULL) return false; - return (pMT->HasSameTypeDefAs(pMT_MscorlibClass) != FALSE); + return (pMT->HasSameTypeDefAs(pMT_CoreLibClass) != FALSE); } #ifndef CROSSGEN_COMPILE @@ -2542,7 +2542,7 @@ bool RCW::SupportsMngStdInterface(MethodTable *pItfMT) // If the requested interface is IEnumerable then we need to check to see if the // COM object implements IDispatch and has a member with DISPID_NEWENUM. - if (pItfMT == MscorlibBinder::GetClass(CLASS__IENUMERABLE)) + if (pItfMT == CoreLibBinder::GetClass(CLASS__IENUMERABLE)) { SafeComHolder pDisp = GetIDispatch(); if (pDisp) @@ -2824,7 +2824,7 @@ void ComObject::ThrowInvalidCastException(OBJECTREF *pObj, MethodTable *pCastToM COMPlusThrow(kInvalidCastException, IDS_EE_RCW_INVALIDCAST_EVENTITF, strHRDescription.GetUnicode(), strComObjClassName.GetUnicode(), strCastToName.GetUnicode(), strIID, strSrcItfIID); } - else if (thCastTo == TypeHandle(MscorlibBinder::GetClass(CLASS__IENUMERABLE))) + else if (thCastTo == TypeHandle(CoreLibBinder::GetClass(CLASS__IENUMERABLE))) { COMPlusThrow(kInvalidCastException, IDS_EE_RCW_INVALIDCAST_IENUMERABLE, strHRDescription.GetUnicode(), strComObjClassName.GetUnicode(), strCastToName.GetUnicode(), strIID); diff --git a/src/coreclr/src/vm/runtimehandles.cpp b/src/coreclr/src/vm/runtimehandles.cpp index b34ee5c6023a..14787a7faefc 100644 --- a/src/coreclr/src/vm/runtimehandles.cpp +++ b/src/coreclr/src/vm/runtimehandles.cpp @@ -736,7 +736,7 @@ PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer } GCPROTECT_BEGIN(refArray); - TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType)); + TypeHandle thRuntimeType = TypeHandle(CoreLibBinder::GetClass(arrayElemType)); TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY); refArray = (PTRARRAYREF)AllocateSzArray(arrayHandle, numTypeHandles); @@ -1954,7 +1954,7 @@ FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatu // modifiers now that we know how long they should be. sp = argument; - MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE); + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cMods); @@ -2466,10 +2466,10 @@ FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodOb if (pILHeader) { - MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); + MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); - MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); + MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); Module* pModule = pMethod->GetModule(); @@ -2489,7 +2489,7 @@ FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodOb } } - gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); + gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); diff --git a/src/coreclr/src/vm/safehandle.cpp b/src/coreclr/src/vm/safehandle.cpp index 44c1f40766e5..38ee027a41f2 100644 --- a/src/coreclr/src/vm/safehandle.cpp +++ b/src/coreclr/src/vm/safehandle.cpp @@ -41,10 +41,10 @@ void SafeHandle::Init() // methods involves calling .GetMethod which can fail, we are doing this // eagerly here, Otherwise we will have to do it at the time of the call, // and this could be at risk if .GetMethod failed. - MethodDesc* pMD = MscorlibBinder::GetMethod(METHOD__SAFE_HANDLE__GET_IS_INVALID); + MethodDesc* pMD = CoreLibBinder::GetMethod(METHOD__SAFE_HANDLE__GET_IS_INVALID); s_IsInvalidHandleMethodSlot = pMD->GetSlot(); - pMD = MscorlibBinder::GetMethod(METHOD__SAFE_HANDLE__RELEASE_HANDLE); + pMD = CoreLibBinder::GetMethod(METHOD__SAFE_HANDLE__RELEASE_HANDLE); s_ReleaseHandleMethodSlot = pMD->GetSlot(); } diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index ee42a4e56404..1d3fbbd746c1 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -728,12 +728,12 @@ MetaSig::MetaSig(BinderMethodID id) } CONTRACTL_END - Signature sig = MscorlibBinder::GetMethodSignature(id); + Signature sig = CoreLibBinder::GetMethodSignature(id); - _ASSERTE(MethodDescMatchesSig(MscorlibBinder::GetMethod(id), - sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule())); + _ASSERTE(MethodDescMatchesSig(CoreLibBinder::GetMethod(id), + sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule())); - Init(sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), NULL); + Init(sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule(), NULL); } MetaSig::MetaSig(LPHARDCODEDMETASIG pwzMetaSig) @@ -748,9 +748,9 @@ MetaSig::MetaSig(LPHARDCODEDMETASIG pwzMetaSig) } CONTRACTL_END - Signature sig = MscorlibBinder::GetSignature(pwzMetaSig); + Signature sig = CoreLibBinder::GetSignature(pwzMetaSig); - Init(sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), NULL); + Init(sig.GetRawSig(), sig.GetRawSigLen(), CoreLibBinder::GetModule(), NULL); } // Helper constructor that constructs a field signature MetaSig from a FieldDesc @@ -1086,7 +1086,7 @@ TypeHandle SigPointer::GetTypeHandleThrowing( // case ELEMENT_TYPE_STRING = 0x0e, // case ELEMENT_TYPE_OBJECT = 0x1c, // - thRet = TypeHandle(MscorlibBinder::GetElementType(typ)); + thRet = TypeHandle(CoreLibBinder::GetElementType(typ)); } else { @@ -1479,7 +1479,7 @@ TypeHandle SigPointer::GetTypeHandleThrowing( { if (TypeFromToken(typeToken) == mdtTypeRef) { - loadedType = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_VOID)); + loadedType = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_VOID)); thRet = loadedType; break; } @@ -2372,7 +2372,7 @@ CorElementType SigPointer::PeekElemTypeNormalized(Module* pModule, const SigType TypeHandle th = GetTypeHandleThrowing(pModule, pTypeContext, ClassLoader::LoadTypes, CLASS_LOAD_APPROXPARENTS, TRUE); if(th.IsNull()) { - th = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_VOID)); + th = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_VOID)); } type = th.GetInternalCorElementType(); @@ -4613,9 +4613,9 @@ MetaSig::CompareElementTypeToToken( } return CompareTypeTokens( - MscorlibBinder::GetElementType(Type1)->GetCl(), + CoreLibBinder::GetElementType(Type1)->GetCl(), tk2, - MscorlibBinder::GetModule(), + CoreLibBinder::GetModule(), pModule2, pVisited); } // MetaSig::CompareElementTypeToToken @@ -4765,10 +4765,10 @@ BOOL MetaSig::CompareVariableConstraints(const Substitution *pSubst1, // a) are vacuous, and // b) may be implicit (ie. absent) in the overriden variable's declaration if (!(CompareTypeDefOrRefOrSpec(pModule1, tkConstraintType1, NULL, - MscorlibBinder::GetModule(), g_pObjectClass->GetCl(), NULL, NULL) || + CoreLibBinder::GetModule(), g_pObjectClass->GetCl(), NULL, NULL) || (((specialConstraints1 & gpNotNullableValueTypeConstraint) != 0) && (CompareTypeDefOrRefOrSpec(pModule1, tkConstraintType1, NULL, - MscorlibBinder::GetModule(), g_pValueTypeClass->GetCl(), NULL, NULL))))) + CoreLibBinder::GetModule(), g_pValueTypeClass->GetCl(), NULL, NULL))))) { HENUMInternalHolder hEnum2(pInternalImport2); mdGenericParamConstraint tkConstraint2; diff --git a/src/coreclr/src/vm/siginfo.hpp b/src/coreclr/src/vm/siginfo.hpp index 7f3fa8b6647b..c2f68e1dd755 100644 --- a/src/coreclr/src/vm/siginfo.hpp +++ b/src/coreclr/src/vm/siginfo.hpp @@ -566,7 +566,7 @@ class MetaSig MetaSig(FieldDesc *pFD, TypeHandle declaringType = TypeHandle()); - // Used to avoid touching metadata for mscorlib methods. Nb. only use for non-generic methods. + // Used to avoid touching metadata for CoreLib methods. Nb. only use for non-generic methods. MetaSig(BinderMethodID id); MetaSig(LPHARDCODEDMETASIG pwzMetaSig); diff --git a/src/coreclr/src/vm/staticallocationhelpers.inl b/src/coreclr/src/vm/staticallocationhelpers.inl index eba82d7ad24a..a9047ba8f871 100644 --- a/src/coreclr/src/vm/staticallocationhelpers.inl +++ b/src/coreclr/src/vm/staticallocationhelpers.inl @@ -20,7 +20,7 @@ static CorElementType ParseMetadataForStaticsIsValueTypeEnum(Module * pModule, I if (TypeFromToken(tk) != mdtTypeDef) { // At this point, we would have to load other assemblies. The only one we have guaranteed - // to be there is mscorlib. + // to be there is CoreLib. return ELEMENT_TYPE_END; } diff --git a/src/coreclr/src/vm/stubgen.cpp b/src/coreclr/src/vm/stubgen.cpp index 1be173a1888c..d11d969fb36d 100644 --- a/src/coreclr/src/vm/stubgen.cpp +++ b/src/coreclr/src/vm/stubgen.cpp @@ -133,7 +133,7 @@ void ILStubLinker::DumpIL_FormatToken(mdToken token, SString &strTokenFormatting sig.GetSignature(&pSig, &cbSig); } - IMDInternalImport * pIMDI = MscorlibBinder::GetModule()->GetMDImport(); + IMDInternalImport * pIMDI = CoreLibBinder::GetModule()->GetMDImport(); CQuickBytes sigStr; PrettyPrintSig(pSig, cbSig, "", &sigStr, pIMDI, NULL); @@ -1822,28 +1822,28 @@ void ILCodeStream::EmitUNALIGNED(BYTE alignment) void ILCodeStream::EmitNEWOBJ(BinderMethodID id, int numInArgs) { STANDARD_VM_CONTRACT; - EmitNEWOBJ(GetToken(MscorlibBinder::GetMethod(id)), numInArgs); + EmitNEWOBJ(GetToken(CoreLibBinder::GetMethod(id)), numInArgs); } void ILCodeStream::EmitCALL(BinderMethodID id, int numInArgs, int numRetArgs) { STANDARD_VM_CONTRACT; - EmitCALL(GetToken(MscorlibBinder::GetMethod(id)), numInArgs, numRetArgs); + EmitCALL(GetToken(CoreLibBinder::GetMethod(id)), numInArgs, numRetArgs); } void ILCodeStream::EmitLDFLD(BinderFieldID id) { STANDARD_VM_CONTRACT; - EmitLDFLD(GetToken(MscorlibBinder::GetField(id))); + EmitLDFLD(GetToken(CoreLibBinder::GetField(id))); } void ILCodeStream::EmitSTFLD(BinderFieldID id) { STANDARD_VM_CONTRACT; - EmitSTFLD(GetToken(MscorlibBinder::GetField(id))); + EmitSTFLD(GetToken(CoreLibBinder::GetField(id))); } void ILCodeStream::EmitLDFLDA(BinderFieldID id) { STANDARD_VM_CONTRACT; - EmitLDFLDA(GetToken(MscorlibBinder::GetField(id))); + EmitLDFLDA(GetToken(CoreLibBinder::GetField(id))); } void ILStubLinker::SetHasThis (bool fHasThis) @@ -1881,7 +1881,7 @@ void ILCodeStream::EmitArgIteratorCreateAndLoad() // // we insert the ArgIterator in the same spot that the VASigCookie will go for sanity // - LocalDesc aiLoc(MscorlibBinder::GetClass(CLASS__ARG_ITERATOR)); + LocalDesc aiLoc(CoreLibBinder::GetClass(CLASS__ARG_ITERATOR)); int aiLocNum; aiLocNum = NewLocal(aiLoc); @@ -1895,7 +1895,7 @@ void ILCodeStream::EmitArgIteratorCreateAndLoad() aiLoc.ElementType[0] = ELEMENT_TYPE_BYREF; aiLoc.ElementType[1] = ELEMENT_TYPE_INTERNAL; aiLoc.cbType = 2; - aiLoc.InternalToken = MscorlibBinder::GetClass(CLASS__ARG_ITERATOR); + aiLoc.InternalToken = CoreLibBinder::GetClass(CLASS__ARG_ITERATOR); SetStubTargetArgType(&aiLoc, false); } diff --git a/src/coreclr/src/vm/tailcallhelp.cpp b/src/coreclr/src/vm/tailcallhelp.cpp index 70dee8e5d867..0db1330b7b3c 100644 --- a/src/coreclr/src/vm/tailcallhelp.cpp +++ b/src/coreclr/src/vm/tailcallhelp.cpp @@ -119,7 +119,7 @@ MethodDesc* TailCallHelp::GetOrLoadTailCallDispatcherMD() CONTRACTL_END; if (s_tailCallDispatcherMD == NULL) - s_tailCallDispatcherMD = MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__DISPATCH_TAILCALLS); + s_tailCallDispatcherMD = CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__DISPATCH_TAILCALLS); return s_tailCallDispatcherMD; } @@ -183,7 +183,7 @@ void TailCallHelp::LayOutArgBuffer( bool thisParamByRef = (calleeMD != NULL) ? calleeMD->GetMethodTable()->IsValueType() : thisArgByRef; if (thisParamByRef) { - thisHnd = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) + thisHnd = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) .MakeByRef(); } else @@ -226,16 +226,16 @@ TypeHandle TailCallHelp::NormalizeSigType(TypeHandle tyHnd) } if (CorTypeInfo::IsObjRef(ety)) { - return TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_OBJECT)); + return TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_OBJECT)); } if (tyHnd.IsPointer() || tyHnd.IsFnPtrType()) { - return TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_I)); + return TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_I)); } if (tyHnd.IsByRef()) { - return TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_U1)) + return TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_U1)) .MakeByRef(); } diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 32cc52c6f220..58ff01c6be7e 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1992,7 +1992,7 @@ void Thread::HandleThreadStartupFailure() GCPROTECT_BEGIN(args); - MethodTable *pMT = MscorlibBinder::GetException(kThreadStartException); + MethodTable *pMT = CoreLibBinder::GetException(kThreadStartException); args.pThrowable = AllocateObject(pMT); MethodDescCallSite exceptionCtor(METHOD__THREAD_START_EXCEPTION__EX_CTOR); @@ -7844,7 +7844,7 @@ OBJECTREF Thread::GetCulture(BOOL bUICulture) } CONTRACTL_END; - // This is the case when we're building mscorlib and haven't yet created + // This is the case when we're building CoreLib and haven't yet created // the system assembly. if (SystemDomain::System()->SystemAssembly()==NULL || g_fForbidEnterEE) { return NULL; @@ -8591,7 +8591,7 @@ OBJECTHANDLE Thread::GetOrCreateDeserializationTracker() _ASSERTE(this == GetThread()); - MethodTable* pMT = MscorlibBinder::GetClass(CLASS__DESERIALIZATION_TRACKER); + MethodTable* pMT = CoreLibBinder::GetClass(CLASS__DESERIALIZATION_TRACKER); m_DeserializationTracker = CreateGlobalStrongHandle(AllocateObject(pMT)); _ASSERTE(m_DeserializationTracker != NULL); diff --git a/src/coreclr/src/vm/threads.h b/src/coreclr/src/vm/threads.h index b835b4a6321c..a56bd5e4757c 100644 --- a/src/coreclr/src/vm/threads.h +++ b/src/coreclr/src/vm/threads.h @@ -977,7 +977,7 @@ struct PortableTailCallFrame class TailCallTls { - friend class MscorlibBinder; + friend class CoreLibBinder; PortableTailCallFrame* m_frame; char* m_argBuffer; diff --git a/src/coreclr/src/vm/typedesc.inl b/src/coreclr/src/vm/typedesc.inl index c6fbf654f094..d2b9f2b0f41e 100644 --- a/src/coreclr/src/vm/typedesc.inl +++ b/src/coreclr/src/vm/typedesc.inl @@ -22,7 +22,7 @@ inline PTR_MethodTable TypeDesc::GetMethodTable() { return NULL; if (GetInternalCorElementType() == ELEMENT_TYPE_FNPTR) - return MscorlibBinder::GetElementType(ELEMENT_TYPE_U); + return CoreLibBinder::GetElementType(ELEMENT_TYPE_U); _ASSERTE(HasTypeParam()); ParamTypeDesc* asParam = dac_cast(this); diff --git a/src/coreclr/src/vm/typehandle.cpp b/src/coreclr/src/vm/typehandle.cpp index 754f842ea700..7883071fee28 100644 --- a/src/coreclr/src/vm/typehandle.cpp +++ b/src/coreclr/src/vm/typehandle.cpp @@ -1174,7 +1174,7 @@ OBJECTREF TypeHandle::GetManagedClassObject() const case ELEMENT_TYPE_FNPTR: // A function pointer is mapped into typeof(IntPtr). It results in a loss of information. - return MscorlibBinder::GetElementType(ELEMENT_TYPE_I)->GetManagedClassObject(); + return CoreLibBinder::GetElementType(ELEMENT_TYPE_I)->GetManagedClassObject(); default: _ASSERTE(!"Bad Element Type"); diff --git a/src/coreclr/src/vm/typehandle.inl b/src/coreclr/src/vm/typehandle.inl index ba66ee3b02f4..e566d7c831e0 100644 --- a/src/coreclr/src/vm/typehandle.inl +++ b/src/coreclr/src/vm/typehandle.inl @@ -277,7 +277,7 @@ FORCEINLINE OBJECTREF TypeHandle::GetManagedClassObjectFast() const case ELEMENT_TYPE_FNPTR: // A function pointer is mapped into typeof(IntPtr). It results in a loss of information. - o = MscorlibBinder::GetElementType(ELEMENT_TYPE_I)->GetManagedClassObjectIfExists(); + o = CoreLibBinder::GetElementType(ELEMENT_TYPE_I)->GetManagedClassObjectIfExists(); break; default: diff --git a/src/coreclr/src/vm/typeparse.cpp b/src/coreclr/src/vm/typeparse.cpp index 1b69d0d815d0..007ef0813bc4 100644 --- a/src/coreclr/src/vm/typeparse.cpp +++ b/src/coreclr/src/vm/typeparse.cpp @@ -91,7 +91,7 @@ SAFEHANDLE TypeName::GetSafeHandle() GCPROTECT_BEGIN(objSafeHandle); - objSafeHandle = (SAFEHANDLE)AllocateObject(MscorlibBinder::GetClass(CLASS__SAFE_TYPENAMEPARSER_HANDLE)); + objSafeHandle = (SAFEHANDLE)AllocateObject(CoreLibBinder::GetClass(CLASS__SAFE_TYPENAMEPARSER_HANDLE)); MethodDescCallSite strCtor(METHOD__SAFE_TYPENAMEPARSER_HANDLE__CTOR); @@ -226,7 +226,7 @@ void QCALLTYPE TypeName::QGetTypeArguments(TypeName * pTypeName, QCall::ObjectHa GCPROTECT_BEGIN(pReturnArguments); - pReturnArguments = (PTRARRAYREF)AllocateObjectArray(count, MscorlibBinder::GetClass(CLASS__SAFE_TYPENAMEPARSER_HANDLE)); + pReturnArguments = (PTRARRAYREF)AllocateObjectArray(count, CoreLibBinder::GetClass(CLASS__SAFE_TYPENAMEPARSER_HANDLE)); for (COUNT_T i = 0; i < count; i++) { @@ -795,7 +795,7 @@ BOOL TypeName::TypeNameParser::NESTNAME() // if szTypeName is not ASM-qualified, we will search for the types in the following order: // - in pRequestingAssembly (if not NULL). pRequestingAssembly is the assembly that contained // the custom attribute from which the typename was derived. -// - in mscorlib.dll +// - in CoreLib // - raise an AssemblyResolveEvent() in the current appdomain // // pRequestingAssembly may be NULL. In that case, the "visibility" check will simply check that diff --git a/src/coreclr/src/vm/typeparse.h b/src/coreclr/src/vm/typeparse.h index 39e4211635d0..3cf1df6ceb1e 100644 --- a/src/coreclr/src/vm/typeparse.h +++ b/src/coreclr/src/vm/typeparse.h @@ -304,7 +304,7 @@ class TypeName // if szTypeName is not ASM-qualified, we will search for the types in the following order: // - in pRequestingAssembly (if not NULL). pRequestingAssembly is the assembly that contained // the custom attribute from which the typename was derived. - // - in mscorlib.dll + // - in CoreLib // - raise an AssemblyResolveEvent() in the current appdomain // // pRequestingAssembly may be NULL. In that case, the "visibility" check will simply check that diff --git a/src/coreclr/src/vm/weakreferencenative.cpp b/src/coreclr/src/vm/weakreferencenative.cpp index da6036abb15b..4d56975daa06 100644 --- a/src/coreclr/src/vm/weakreferencenative.cpp +++ b/src/coreclr/src/vm/weakreferencenative.cpp @@ -439,7 +439,7 @@ FCIMPL3(void, WeakReferenceNative::Create, WeakReferenceObject * pThisUNSAFE, Ob COMPlusThrow(kNullReferenceException); if (pWeakReferenceMT == NULL) - pWeakReferenceMT = MscorlibBinder::GetClass(CLASS__WEAKREFERENCE); + pWeakReferenceMT = CoreLibBinder::GetClass(CLASS__WEAKREFERENCE); _ASSERTE(gc.pThis->GetMethodTable()->CanCastToClass(pWeakReferenceMT)); diff --git a/src/coreclr/src/vm/wks/CMakeLists.txt b/src/coreclr/src/vm/wks/CMakeLists.txt index bd675204bd78..8141137330e6 100644 --- a/src/coreclr/src/vm/wks/CMakeLists.txt +++ b/src/coreclr/src/vm/wks/CMakeLists.txt @@ -12,8 +12,8 @@ add_library_clr(cee_wks_core OBJECT ${VM_SOURCES_WKS} ${VM_SOURCES_WKS_ARCH_ASM} target_precompile_header(TARGET cee_wks_core HEADER common.h) if (MSVC) - # mscorlib.cpp does not compile with precompiled header file - set_source_files_properties(../mscorlib.cpp PROPERTIES COMPILE_FLAGS "/Y-") + # corelib.cpp does not compile with precompiled header file + set_source_files_properties(../corelib.cpp PROPERTIES COMPILE_FLAGS "/Y-") endif() add_dependencies(cee_wks_core eventing_headers) diff --git a/src/coreclr/src/zap/zapimage.cpp b/src/coreclr/src/zap/zapimage.cpp index bcd02a3b2c42..e1139427f268 100644 --- a/src/coreclr/src/zap/zapimage.cpp +++ b/src/coreclr/src/zap/zapimage.cpp @@ -2210,10 +2210,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h BOOL ZapImage::ShouldCompileMethodDef(mdMethodDef md) { DWORD partialNGenStressVal = PartialNGenStressPercentage(); - if (partialNGenStressVal && - // Module::AddCerListToRootTable has problems if mscorlib.dll is - // a partial ngen image - m_hModule != m_zapper->m_pEECompileInfo->GetLoaderModuleForMscorlib()) + if (partialNGenStressVal) { _ASSERTE(partialNGenStressVal <= 100); DWORD methodPercentageVal = (md % 100) + 1; @@ -2315,10 +2312,7 @@ BOOL ZapImage::ShouldCompileMethodDef(mdMethodDef md) BOOL ZapImage::ShouldCompileInstantiatedMethod(CORINFO_METHOD_HANDLE handle) { DWORD partialNGenStressVal = PartialNGenStressPercentage(); - if (partialNGenStressVal && - // Module::AddCerListToRootTable has problems if mscorlib.dll is - // a partial ngen image - m_hModule != m_zapper->m_pEECompileInfo->GetLoaderModuleForMscorlib()) + if (partialNGenStressVal) { _ASSERTE(partialNGenStressVal <= 100); DWORD methodPercentageVal = (m_zapper->m_pEEJitInfo->getMethodHash(handle) % 100) + 1; diff --git a/src/coreclr/src/zap/zapper.cpp b/src/coreclr/src/zap/zapper.cpp index 5b999a82f0e6..f232719b8d4e 100644 --- a/src/coreclr/src/zap/zapper.cpp +++ b/src/coreclr/src/zap/zapper.cpp @@ -805,10 +805,10 @@ BOOL Zapper::IsAssembly(LPCWSTR path) void Zapper::SetContextInfo(LPCWSTR assemblyName) { - // A special case: If we're compiling mscorlib, ignore m_exeName and don't set any context. - // There can only be one mscorlib in the runtime, independent of any context. If we don't - // check for mscorlib, and isExe == true, then CompilationDomain::SetContextInfo will call - // into mscorlib and cause the resulting mscorlib.ni.dll to be slightly different (checked + // A special case: If we're compiling CoreLib, ignore m_exeName and don't set any context. + // There can only be one CoreLib in the runtime, independent of any context. If we don't + // check for CoreLib, and isExe == true, then CompilationDomain::SetContextInfo will call + // into CoreLib and cause the resulting System.Private.CoreLib.ni.dll to be slightly different (checked // build only). if (assemblyName != NULL && _wcsnicmp(assemblyName, CoreLibName_W, CoreLibNameLen) == 0 && (wcslen(assemblyName) == CoreLibNameLen || assemblyName[CoreLibNameLen] == W(','))) { @@ -975,18 +975,18 @@ HRESULT Zapper::Compile(LPCWSTR string, CORCOMPILE_NGEN_SIGNATURE * pNativeImage { HRESULT hr = S_OK; - bool fMscorlib = false; + bool fCoreLib = false; LPCWSTR fileName = PathFindFileName(string); if (fileName != NULL && SString::_wcsicmp(fileName, g_pwBaseLibrary) == 0) { - fMscorlib = true; + fCoreLib = true; } - if (fMscorlib) + if (fCoreLib) { // - // Disallow use of native image to force a new native image generation for mscorlib + // Disallow use of native image to force a new native image generation for CoreLib // g_fAllowNativeImages = false; } @@ -1180,7 +1180,7 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) // That way the actual support checks will always be jitted. // We only do this for CoreLib because forgetting to wrap intrinsics under IsSupported // checks can lead to illegal instruction traps (instead of a nice managed exception). - if (m_pEECompileInfo->GetAssemblyModule(m_hAssembly) == m_pEECompileInfo->GetLoaderModuleForMscorlib()) + if (m_pEECompileInfo->GetAssemblyModule(m_hAssembly) == m_pEECompileInfo->GetLoaderModuleForCoreLib()) { m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD); diff --git a/src/coreclr/src/zap/zapreadytorun.cpp b/src/coreclr/src/zap/zapreadytorun.cpp index 27d79b3121d3..e36d4aee6eaf 100644 --- a/src/coreclr/src/zap/zapreadytorun.cpp +++ b/src/coreclr/src/zap/zapreadytorun.cpp @@ -741,7 +741,7 @@ void ZapImage::OutputAttributePresenceFilter(IMDInternalImport * pMDImport) // present. Other assemblies *MAY* benefit from this feature, but it doesn't show // as useful at this time. - if (m_hModule != m_zapper->m_pEECompileInfo->GetLoaderModuleForMscorlib()) + if (m_hModule != m_zapper->m_pEECompileInfo->GetLoaderModuleForCoreLib()) return; SArray table; From 29e9b5b7fd95231d9cd9d3ae351404e63cbb6d5a Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 28 Jul 2020 19:11:00 -0400 Subject: [PATCH 111/755] [interp] Add null checks to STIND opcodes. (#40041) --- src/mono/mono/mini/interp/interp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 8d86279fd07e..68f82f52c5f5 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -4592,31 +4592,37 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs MINT_IN_BREAK; } MINT_IN_CASE(MINT_STIND_REF) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; mono_gc_wbarrier_generic_store_internal (sp->data.p, sp [1].data.o); MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_I1) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; * (gint8 *) sp->data.p = (gint8)sp[1].data.i; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_I2) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; * (gint16 *) sp->data.p = (gint16)sp[1].data.i; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_I4) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; * (gint32 *) sp->data.p = sp[1].data.i; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_I) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; * (mono_i *) sp->data.p = (mono_i)sp[1].data.p; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_I8) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; #ifdef NO_UNALIGNED_ACCESS @@ -4627,11 +4633,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs * (gint64 *) sp->data.p = sp[1].data.l; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_R4) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; * (float *) sp->data.p = sp[1].data.f_r4; MINT_IN_BREAK; MINT_IN_CASE(MINT_STIND_R8) + NULL_CHECK (sp [-2].data.p); ++ip; sp -= 2; #ifdef NO_UNALIGNED_ACCESS From 227757ae75bdd480e26ec218a488603cb6e11ea3 Mon Sep 17 00:00:00 2001 From: yowl Date: Tue, 28 Jul 2020 18:16:45 -0500 Subject: [PATCH 112/755] Negate find_object GetConservativeGC logic. (#39905) --- src/coreclr/src/gc/gc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 9cc20ad740e2..ea08dd1612d2 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -18090,12 +18090,12 @@ uint8_t* gc_heap::find_object (uint8_t* interior) { // this is a pointer to a UOH object heap_segment* seg = find_segment (interior, FALSE); - if (seg + if (seg) + { #ifdef FEATURE_CONSERVATIVE_GC - && (GCConfig::GetConservativeGC() || interior <= heap_segment_allocated(seg)) + if (interior >= heap_segment_allocated(seg)) + return 0; #endif - ) - { // If interior falls within the first free object at the beginning of a generation, // we don't have brick entry for it, and we may incorrectly treat it as on large object heap. int align_const = get_alignment_constant (heap_segment_read_only_p (seg) From 26b818b462cfabaa5c975553a88ed298fdc672fd Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 28 Jul 2020 19:15:05 -0700 Subject: [PATCH 113/755] Fix creating RegionInfo object using names with different casing. (#40052) --- .../System/Globalization/RegionInfoTests.cs | 18 ++++++++++++++++++ .../src/System/Globalization/CultureData.cs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs index 2cb86dc56da2..84cc05e35627 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs @@ -79,6 +79,24 @@ public void CurrentRegion_Windows() }).Dispose(); } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + // We are testing with "no" as it match a neutral culture name. We want ensure this not conflict with region name. + [InlineData("no")] + [InlineData("No")] + [InlineData("NO")] + public void ValidateUsingCasedRegionName(string regionName) + { + RemoteExecutor.Invoke(name => + { + // It is important to do this test in the following order because we have internal cache for regions. + // creating the region with the original input name should be the first to do to ensure not cached before. + string resultedName = new RegionInfo(name).Name; + string expectedName = new RegionInfo(name.ToUpperInvariant()).Name; + Assert.Equal(expectedName, resultedName); + }, regionName).Dispose(); + } + [Theory] [InlineData("en-US", "United States")] [OuterLoop("May fail on machines with multiple language packs installed")] // see https://github.com/dotnet/runtime/issues/30132 diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 6c0dbe168797..939c16e4d8d9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -152,7 +152,7 @@ internal partial class CultureData /// private static Dictionary RegionNames => s_regionNames ??= - new Dictionary(257 /* prime */) + new Dictionary(257 /* prime */, StringComparer.OrdinalIgnoreCase) { { "001", "en-001" }, { "029", "en-029" }, From e671f57b1b8a6efc8febc023a59fdb0a76b5d286 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jul 2020 05:06:52 +0200 Subject: [PATCH 114/755] Add Unsafe.IsNullRef and Unsafe.NullRef (#40008) Co-authored-by: Adeel Mujahid Co-authored-by: Jan Kotas --- .../System.Runtime.CompilerServices.Unsafe.cs | 2 + .../System.Runtime.CompilerServices.Unsafe.il | 20 +++++ ...System.Runtime.CompilerServices.Unsafe.xml | 12 +++ .../tests/UnsafeTests.cs | 84 ++++++++++++++++++- 4 files changed, 115 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs b/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs index ae977a0cdc33..99c28c3a28b0 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs @@ -35,6 +35,8 @@ public static void InitBlockUnaligned(ref byte startAddress, byte value, uint by public static unsafe void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } public static bool IsAddressGreaterThan(ref T left, ref T right) { throw null; } public static bool IsAddressLessThan(ref T left, ref T right) { throw null; } + public static bool IsNullRef(ref T source) { throw null; } + public static ref T NullRef() { throw null; } public static T ReadUnaligned(ref byte source) { throw null; } public static unsafe T ReadUnaligned(void* source) { throw null; } public static unsafe T Read(void* source) { throw null; } diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index 8740fafec41a..51e4105a138f 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -458,6 +458,26 @@ ret } // end of method Unsafe::IsAddressLessThan + .method public hidebysig static bool IsNullRef(!!T& source) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.0 + ldc.i4.0 + conv.u + ceq + ret + } // end of method Unsafe::IsNullRef + + .method public hidebysig static !!T& NullRef() cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 1 + ldc.i4.0 + conv.u + ret + } // end of method Unsafe::NullRef + } // end of class System.Runtime.CompilerServices.Unsafe .class private auto ansi sealed beforefieldinit System.Runtime.Versioning.NonVersionableAttribute diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml index 1aef90cb9d2e..1979a5cb9705 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml @@ -233,6 +233,18 @@ or the objects being referenced must both be pinned; or both references must represent unmanaged pointers; otherwise the result is undefined. + + + Returns if a given reference to a value of type is a null reference. + + The reference to check. + This check is conceptually similar to "(void*)(&source) == nullptr". + + + + Returns a reference to a value of type that is a null reference. + + Copies bytes from the source address to the destination address. diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index 88473528f108..34b0140aa23c 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -413,7 +413,7 @@ public static void ByteOffsetStackByte4() public static unsafe void AsRef() { byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 }; - fixed (byte * p = b) + fixed (byte* p = b) { ref int r = ref Unsafe.AsRef(p); Assert.Equal(0x42424242, r); @@ -839,7 +839,7 @@ public static void SkipInit() Unsafe.SkipInit(out double doubleValue); // Validate that calling on user-defined unmanaged structs works. - + Unsafe.SkipInit(out Byte4 byte4Value); Unsafe.SkipInit(out Byte4Short2 byte4Short2Value); Unsafe.SkipInit(out Byte512 byte512Value); @@ -931,6 +931,84 @@ public static void SkipInit_PreservesPrevious() Unsafe.SkipInit(out stringValue); Assert.Equal("25", stringValue); } + + [Fact] + public static unsafe void IsNullRef_NotNull() + { + // Validate that calling with a primitive type works. + + int intValue = 5; + Assert.False(Unsafe.IsNullRef(ref intValue)); + + // Validate that calling on user-defined unmanaged structs works. + + Int32Double int32DoubleValue = default; + Assert.False(Unsafe.IsNullRef(ref int32DoubleValue)); + + // Validate that calling on reference types works. + + object objectValue = new object(); + Assert.False(Unsafe.IsNullRef(ref objectValue)); + + string stringValue = nameof(IsNullRef_NotNull); + Assert.False(Unsafe.IsNullRef(ref stringValue)); + + // Validate on ref created from a pointer + + int* p = (int*)1; + Assert.False(Unsafe.IsNullRef(ref Unsafe.AsRef(p))); + } + + [Fact] + public static unsafe void IsNullRef_Null() + { + // Validate that calling with a primitive type works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.AsRef(null))); + + // Validate that calling on user-defined unmanaged structs works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.AsRef(null))); + + // Validate that calling on reference types works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.AsRef(null))); + Assert.True(Unsafe.IsNullRef(ref Unsafe.AsRef(null))); + + // Validate on ref created from a pointer + + int* p = (int*)0; + Assert.True(Unsafe.IsNullRef(ref Unsafe.AsRef(p))); + } + + [Fact] + public static unsafe void NullRef() + { + // Validate that calling with a primitive type works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.NullRef())); + + // Validate that calling on user-defined unmanaged structs works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.NullRef())); + + // Validate that calling on reference types works. + + Assert.True(Unsafe.IsNullRef(ref Unsafe.NullRef())); + Assert.True(Unsafe.IsNullRef(ref Unsafe.NullRef())); + + // Validate that pinning results in a null pointer + + fixed (void* p = &Unsafe.NullRef()) + { + Assert.True(p == (void*)0); + } + + // Validate that dereferencing a null ref throws a NullReferenceException + + Assert.Throws(() => Unsafe.NullRef() = 42); + Assert.Throws(() => Unsafe.NullRef()); + } } [StructLayout(LayoutKind.Explicit)] @@ -968,7 +1046,7 @@ public unsafe struct Byte512 public fixed byte Bytes[512]; } - [StructLayout(LayoutKind.Explicit, Size=16)] + [StructLayout(LayoutKind.Explicit, Size = 16)] public unsafe struct Int32Double { [FieldOffset(0)] From 3eda592cf49e3b8fb64ea0cc595fdae83a50dd83 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 29 Jul 2020 07:05:31 +0200 Subject: [PATCH 115/755] [browser][wasm] Configuring request options in Browser WebAssembly (#39182) * [browser][wasm] Initial addition of configuring request options in Browser WebAssembly * Fix key code. Not what was proposed * Add TryGetValue and Set as per proposal * Add missing obsolete attribute * Address review comments * Update tests to use Options and not obsolete Properties. * Implement IDictionary explicitly * Update tests to use Options and not obsolete Properties. * Add HttpRequestOptions source to the System.Net.Http.Unit.Tests project to fix build. * Address review comments - explicit * Fix build error cannot convert from 'string' to 'System.Net.Http.HttpRequestOptionsKey' * Add tests for HttpRequestOptions * Fix test build * Add special case code for NETFRAMEWORK for API change. * #endif out of place fix * #endif out of place fix --- ...tFactoryServiceCollectionExtensionsTest.cs | 86 ++++ .../System.Net.Http/ref/System.Net.Http.cs | 33 ++ .../src/System.Net.Http.csproj | 4 +- .../BrowserHttpHandler/BrowserHttpHandler.cs | 14 +- .../src/System/Net/Http/HttpRequestMessage.cs | 17 +- .../src/System/Net/Http/HttpRequestOptions.cs | 56 +++ .../System/Net/Http/HttpRequestOptionsKey.cs | 16 + .../FunctionalTests/HttpRequestMessageTest.cs | 2 +- .../System.Net.Http.Unit.Tests.csproj | 4 + ...me.InteropServices.JavaScript.Tests.csproj | 1 + .../JavaScript/Http/HttpRequestMessageTest.cs | 376 ++++++++++++++++++ 11 files changed, 591 insertions(+), 18 deletions(-) create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptions.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptionsKey.cs create mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs index 6e526dbdad57..fec6276e6ce2 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs @@ -948,6 +948,7 @@ public async Task AddHttpClient_MessageHandler_SingletonDependency() var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/"); var response = await client.HttpClient.SendAsync(request); +#if NETFRAMEWORK Assert.Same( services.GetRequiredService(), request.Properties[nameof(SingletonService)]); @@ -955,6 +956,18 @@ public async Task AddHttpClient_MessageHandler_SingletonDependency() Assert.Same( client.Service, request.Properties[nameof(SingletonService)]); +#else +#nullable enable + request.Options.TryGetValue(new HttpRequestOptionsKey(nameof(SingletonService)), out SingletonService? optService); +#nullable disable + Assert.Same( + services.GetRequiredService(), + optService); + + Assert.Same( + client.Service, + optService); +#endif } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -979,6 +992,7 @@ public async Task AddHttpClient_MessageHandler_Scope_SingletonDependency() var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/"); var response = await client.HttpClient.SendAsync(request); +#if NETFRAMEWORK Assert.Same( services.GetRequiredService(), request.Properties[nameof(SingletonService)]); @@ -990,6 +1004,23 @@ public async Task AddHttpClient_MessageHandler_Scope_SingletonDependency() Assert.Same( client.Service, request.Properties[nameof(SingletonService)]); +#else +#nullable enable + request.Options.TryGetValue(new HttpRequestOptionsKey(nameof(SingletonService)), out SingletonService? optService); +#nullable disable + + Assert.Same( + services.GetRequiredService(), + optService); + + Assert.Same( + scope.ServiceProvider.GetRequiredService(), + optService); + + Assert.Same( + client.Service, + optService); +#endif } } @@ -1035,6 +1066,7 @@ public async Task AddHttpClient_MessageHandler_Scope_ScopedDependency() var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/"); var response = await client.HttpClient.SendAsync(request); +#if NETFRAMEWORK Assert.NotSame( scope.ServiceProvider.GetRequiredService(), request.Properties[nameof(ScopedService)]); @@ -1046,6 +1078,22 @@ public async Task AddHttpClient_MessageHandler_Scope_ScopedDependency() Assert.NotSame( client.Service, request.Properties[nameof(ScopedService)]); +#else +#nullable enable + request.Options.TryGetValue(new HttpRequestOptionsKey(nameof(ScopedService)), out ScopedService? optService); +#nullable disable + Assert.NotSame( + scope.ServiceProvider.GetRequiredService(), + optService); + + Assert.Same( + scope.ServiceProvider.GetRequiredService(), + client.Service); + + Assert.NotSame( + client.Service, + optService); +#endif } } @@ -1069,6 +1117,7 @@ public async Task AddHttpClient_MessageHandler_TransientDependency() var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/"); var response = await client.HttpClient.SendAsync(request); +#if NETFRAMEWORK Assert.NotSame( services.GetRequiredService(), request.Properties[nameof(TransientService)]); @@ -1076,6 +1125,18 @@ public async Task AddHttpClient_MessageHandler_TransientDependency() Assert.NotSame( client.Service, request.Properties[nameof(TransientService)]); +#else +#nullable enable + request.Options.TryGetValue(new HttpRequestOptionsKey(nameof(TransientService)), out TransientService? optService); +#nullable disable + Assert.NotSame( + services.GetRequiredService(), + optService); + + Assert.NotSame( + client.Service, + optService); +#endif } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -1100,6 +1161,7 @@ public async Task AddHttpClient_MessageHandler_Scope_TransientDependency() var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/"); var response = await client.HttpClient.SendAsync(request); +#if NETFRAMEWORK Assert.NotSame( services.GetRequiredService(), request.Properties[nameof(TransientService)]); @@ -1107,6 +1169,18 @@ public async Task AddHttpClient_MessageHandler_Scope_TransientDependency() Assert.NotSame( client.Service, request.Properties[nameof(TransientService)]); +#else +#nullable enable + request.Options.TryGetValue(new HttpRequestOptionsKey(nameof(TransientService)), out TransientService? optService); +#nullable disable + Assert.NotSame( + services.GetRequiredService(), + optService); + + Assert.NotSame( + client.Service, + optService); +#endif } } @@ -1304,7 +1378,11 @@ public HandlerWithSingletonService(SingletonService service) protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { +#if NETFRAMEWORK request.Properties[nameof(SingletonService)] = Service; +#else + request.Options.Set(new HttpRequestOptionsKey(nameof(SingletonService)), Service); +#endif return Task.FromResult(new HttpResponseMessage()); } } @@ -1320,7 +1398,11 @@ public HandlerWithScopedService(ScopedService service) protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { +#if NETFRAMEWORK request.Properties[nameof(ScopedService)] = Service; +#else + request.Options.Set(new HttpRequestOptionsKey(nameof(ScopedService)), Service); +#endif return Task.FromResult(new HttpResponseMessage()); } } @@ -1336,7 +1418,11 @@ public HandlerWithTransientService(TransientService service) protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { +#if NETFRAMEWORK request.Properties[nameof(TransientService)] = Service; +#else + request.Options.Set(new HttpRequestOptionsKey(nameof(TransientService)), Service); +#endif return Task.FromResult(new HttpResponseMessage()); } } diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 31db0e5b710b..8e2c957c6f5f 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -4,6 +4,8 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ +using System.Diagnostics.CodeAnalysis; + namespace System.Net.Http { public partial class ByteArrayContent : System.Net.Http.HttpContent @@ -212,13 +214,44 @@ public HttpRequestMessage(System.Net.Http.HttpMethod method, System.Uri? request public System.Net.Http.HttpContent? Content { get { throw null; } set { } } public System.Net.Http.Headers.HttpRequestHeaders Headers { get { throw null; } } public System.Net.Http.HttpMethod Method { get { throw null; } set { } } + [Obsolete("Use Options instead.")] public System.Collections.Generic.IDictionary Properties { get { throw null; } } + public HttpRequestOptions Options { get { throw null; } } public System.Uri? RequestUri { get { throw null; } set { } } public System.Version Version { get { throw null; } set { } } public void Dispose() { } protected virtual void Dispose(bool disposing) { } public override string ToString() { throw null; } } + + public readonly struct HttpRequestOptionsKey + { + public HttpRequestOptionsKey(string key) {} + public string Key { get { throw null; } } + } + + public sealed class HttpRequestOptions : System.Collections.Generic.IDictionary + { + void System.Collections.Generic.IDictionary.Add(string key, object? value) { throw null; } + System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get { throw null; } } + System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get { throw null; } } + bool System.Collections.Generic.IDictionary.Remove(string key) { throw null; } + bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) { throw null; } + bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object? value) { throw null; } + object? System.Collections.Generic.IDictionary.this[string key] { get { throw null; } set { } } + void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) { throw null; } + void System.Collections.Generic.ICollection>.Clear() { throw null; } + bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) { throw null; } + bool System.Collections.Generic.IDictionary.ContainsKey(string key) { throw null; } + void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { throw null; } + int System.Collections.Generic.ICollection>.Count { get { throw null; } } + bool System.Collections.Generic.ICollection>.IsReadOnly { get { throw null; } } + System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + public bool TryGetValue(HttpRequestOptionsKey key, [MaybeNullWhen(false)] out TValue value) { throw null; } + public void Set(HttpRequestOptionsKey key, TValue value) { throw null; } + } + public partial class HttpResponseMessage : System.IDisposable { public HttpResponseMessage() { } 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 57326769d64a..60e0afeb2525 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -1,4 +1,4 @@ - + win true @@ -45,6 +45,8 @@ + + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs index 4a6c5b26fbca..5b026591ab5c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs @@ -32,6 +32,9 @@ internal sealed class BrowserHttpHandler : HttpMessageHandler private static readonly JSObject? s_fetch = (JSObject)System.Runtime.InteropServices.JavaScript.Runtime.GetGlobalObject("fetch"); private static readonly JSObject? s_window = (JSObject)System.Runtime.InteropServices.JavaScript.Runtime.GetGlobalObject("window"); + private static readonly HttpRequestOptionsKey EnableStreamingResponse = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); + private static readonly HttpRequestOptionsKey> FetchOptions = new HttpRequestOptionsKey>("WebAssemblyFetchOptions"); + /// /// Gets whether the current Browser supports streaming responses /// @@ -133,8 +136,7 @@ protected internal override async Task SendAsync(HttpReques { var requestObject = new JSObject(); - if (request.Properties.TryGetValue("WebAssemblyFetchOptions", out object? fetchOptionsValue) && - fetchOptionsValue is IDictionary fetchOptions) + if (request.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptions)) { foreach (KeyValuePair item in fetchOptions) { @@ -225,9 +227,13 @@ protected internal override async Task SendAsync(HttpReques HttpResponseMessage httpResponse = new HttpResponseMessage((HttpStatusCode)status.Status); - bool streamingEnabled = request.Properties.TryGetValue("WebAssemblyEnableStreamingResponse", out object? streamingEnabledValue) && (bool)(streamingEnabledValue ?? false); + bool streamingEnabled = false; + if (StreamingSupported) + { + request.Options.TryGetValue(EnableStreamingResponse, out streamingEnabled); + } - httpResponse.Content = StreamingSupported && streamingEnabled + httpResponse.Content = streamingEnabled ? new StreamContent(wasmHttpReadStream = new WasmHttpReadStream(status)) : (HttpContent)new BrowserHttpContent(status); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs index 3cbb1d058c39..83ee09fd1781 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs @@ -24,7 +24,7 @@ public class HttpRequestMessage : IDisposable private Version _version; private HttpContent? _content; private bool _disposed; - private IDictionary? _properties; + private HttpRequestOptions? _options; public Version Version { @@ -111,17 +111,10 @@ public HttpRequestHeaders Headers internal bool HasHeaders => _headers != null; - public IDictionary Properties - { - get - { - if (_properties == null) - { - _properties = new Dictionary(); - } - return _properties; - } - } + [Obsolete("Use Options instead.")] + public IDictionary Properties => Options; + + public HttpRequestOptions Options => _options ??= new HttpRequestOptions(); public HttpRequestMessage() : this(HttpMethod.Get, (Uri?)null) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptions.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptions.cs new file mode 100644 index 000000000000..195eb0d10fe6 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptions.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace System.Net.Http +{ + public sealed class HttpRequestOptions : IDictionary + { + private Dictionary Options { get; } = new Dictionary(); + object? IDictionary.this[string key] + { + get + { + return Options[key]; + } + set + { + Options[key] = value; + } + } + ICollection IDictionary.Keys => Options.Keys; + ICollection IDictionary.Values => Options.Values; + int ICollection>.Count => Options.Count; + bool ICollection>.IsReadOnly => ((IDictionary)Options).IsReadOnly; + void IDictionary.Add(string key, object? value) => Options.Add(key, value); + void ICollection>.Add(KeyValuePair item) => ((IDictionary)Options).Add(item); + void ICollection>.Clear() => Options.Clear(); + bool ICollection>.Contains(KeyValuePair item) => ((IDictionary)Options).Contains(item); + bool IDictionary.ContainsKey(string key) => Options.ContainsKey(key); + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) => + ((IDictionary)Options).CopyTo(array, arrayIndex); + IEnumerator> IEnumerable>.GetEnumerator() => Options.GetEnumerator(); + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => ((System.Collections.IEnumerable)Options).GetEnumerator(); + bool IDictionary.Remove(string key) => Options.Remove(key); + bool ICollection>.Remove(KeyValuePair item) => ((IDictionary)Options).Remove(item); + bool IDictionary.TryGetValue(string key, out object? value) => Options.TryGetValue(key, out value); + public bool TryGetValue(HttpRequestOptionsKey key, [MaybeNullWhen(false)] out TValue value) + { + if (Options.TryGetValue(key.Key, out object? _value) && _value is TValue tvalue) + { + value = tvalue; + return true; + } + + value = default(TValue); + return false; + } + + public void Set(HttpRequestOptionsKey key, TValue value) + { + Options[key.Key] = value; + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptionsKey.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptionsKey.cs new file mode 100644 index 000000000000..f51f8ebf162f --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestOptionsKey.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace System.Net.Http +{ + public readonly struct HttpRequestOptionsKey + { + public string Key { get; } + public HttpRequestOptionsKey(string key) + { + Key = key; + } + } +} diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs index 5e8928b7db9f..8f5ff80d998d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs @@ -154,7 +154,7 @@ public void Properties_SetPropertiesAndGetTheirValue_MatchingValues() Assert.Equal(version, rm.Version); Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Properties); + Assert.NotNull(rm.Options); } [Fact] diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index cde8ce72f86e..1a1199ad91fd 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -206,6 +206,10 @@ Link="ProductionCode\System\Net\Http\RequestRetryType.cs" /> + + --> + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs new file mode 100644 index 000000000000..80a8cd126f15 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs @@ -0,0 +1,376 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Net.Http.Headers; +using System.Net.Http; +using System.Net; +using System.Threading.Tasks; + +using Xunit; +using Xunit.Abstractions; + +namespace System.Runtime.InteropServices.JavaScript.Http.Tests +{ + public class HttpRequestMessageTest + { + private readonly Version _expectedRequestMessageVersion = HttpVersion.Version11; + private HttpRequestOptionsKey EnableStreamingResponse = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); +#nullable enable + private HttpRequestOptionsKey> FetchOptions = new HttpRequestOptionsKey>("WebAssemblyFetchOptions"); +#nullable disable + + [Fact] + public void Ctor_Default_CorrectDefaults() + { + var rm = new HttpRequestMessage(); + + Assert.Equal(HttpMethod.Get, rm.Method); + Assert.Null(rm.Content); + Assert.Null(rm.RequestUri); + } + + [Fact] + public void Ctor_RelativeStringUri_CorrectValues() + { + var rm = new HttpRequestMessage(HttpMethod.Post, "/relative"); + + Assert.Equal(HttpMethod.Post, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + Assert.Equal(new Uri("/relative", UriKind.Relative), rm.RequestUri); + } + + [Fact] + public void Ctor_AbsoluteStringUri_CorrectValues() + { + var rm = new HttpRequestMessage(HttpMethod.Post, "http://host/absolute/"); + + Assert.Equal(HttpMethod.Post, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + Assert.Equal(new Uri("http://host/absolute/"), rm.RequestUri); + } + + [Fact] + public void Ctor_NullStringUri_Accepted() + { + var rm = new HttpRequestMessage(HttpMethod.Put, (string)null); + + Assert.Null(rm.RequestUri); + Assert.Equal(HttpMethod.Put, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + } + + [Fact] + public void Ctor_RelativeUri_CorrectValues() + { + var uri = new Uri("/relative", UriKind.Relative); + var rm = new HttpRequestMessage(HttpMethod.Post, uri); + + Assert.Equal(HttpMethod.Post, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + Assert.Equal(uri, rm.RequestUri); + } + + [Fact] + public void Ctor_AbsoluteUri_CorrectValues() + { + var uri = new Uri("http://host/absolute/"); + var rm = new HttpRequestMessage(HttpMethod.Post, uri); + + Assert.Equal(HttpMethod.Post, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + Assert.Equal(uri, rm.RequestUri); + } + + [Fact] + public void Ctor_NullUri_Accepted() + { + var rm = new HttpRequestMessage(HttpMethod.Put, (Uri)null); + + Assert.Null(rm.RequestUri); + Assert.Equal(HttpMethod.Put, rm.Method); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Null(rm.Content); + } + + [Fact] + public void Ctor_NullMethod_ThrowsArgumentNullException() + { + Assert.Throws(() => new HttpRequestMessage(null, "http://example.com")); + } + + [Fact] + public void Ctor_NonHttpUri_ThrowsArgumentException() + { + AssertExtensions.Throws("requestUri", () => new HttpRequestMessage(HttpMethod.Put, "ftp://example.com")); + } + + [Fact] + public void Dispose_DisposeObject_ContentGetsDisposedAndSettersWillThrowButGettersStillWork() + { + var rm = new HttpRequestMessage(HttpMethod.Get, "http://example.com"); + var content = new MockContent(); + rm.Content = content; + Assert.False(content.IsDisposed); + + rm.Dispose(); + rm.Dispose(); // Multiple calls don't throw. + + Assert.True(content.IsDisposed); + Assert.Throws(() => { rm.Method = HttpMethod.Put; }); + Assert.Throws(() => { rm.RequestUri = null; }); + Assert.Throws(() => { rm.Version = new Version(1, 0); }); + Assert.Throws(() => { rm.Content = null; }); + + // Property getters should still work after disposing. + Assert.Equal(HttpMethod.Get, rm.Method); + Assert.Equal(new Uri("http://example.com"), rm.RequestUri); + Assert.Equal(_expectedRequestMessageVersion, rm.Version); + Assert.Equal(content, rm.Content); + } + + [Fact] + public void Properties_SetOptionsAndGetTheirValue_MatchingValues() + { + var rm = new HttpRequestMessage(); + + var content = new MockContent(); + var uri = new Uri("https://example.com"); + var version = new Version(1, 0); + var method = new HttpMethod("custom"); + + rm.Content = content; + rm.Method = method; + rm.RequestUri = uri; + rm.Version = version; + + Assert.Equal(content, rm.Content); + Assert.Equal(uri, rm.RequestUri); + Assert.Equal(method, rm.Method); + Assert.Equal(version, rm.Version); + + Assert.NotNull(rm.Headers); + Assert.NotNull(rm.Options); + } + +#nullable enable + [Fact] + public void Properties_SetOptionsAndGetTheirValue_Set_FetchOptions() + { + var rm = new HttpRequestMessage(); + + var content = new MockContent(); + var uri = new Uri("https://example.com"); + var version = new Version(1, 0); + var method = new HttpMethod("custom"); + + rm.Content = content; + rm.Method = method; + rm.RequestUri = uri; + rm.Version = version; + + var fetchme = new Dictionary(); + fetchme.Add("hic", null); + fetchme.Add("sunt", 4444); + fetchme.Add("dracones", new List()); + rm.Options.Set(FetchOptions, fetchme); + + Assert.Equal(content, rm.Content); + Assert.Equal(uri, rm.RequestUri); + Assert.Equal(method, rm.Method); + Assert.Equal(version, rm.Version); + + Assert.NotNull(rm.Headers); + Assert.NotNull(rm.Options); + + rm.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptionsValue); + Assert.NotNull(fetchOptionsValue); + if (fetchOptionsValue != null) + { + foreach (var item in fetchOptionsValue) + { + Assert.True(fetchme.ContainsKey(item.Key)); + } + } + } +#nullable disable + +#nullable enable + [Fact] + public void Properties_SetOptionsAndGetTheirValue_NotSet_FetchOptions() + { + var rm = new HttpRequestMessage(); + + var content = new MockContent(); + var uri = new Uri("https://example.com"); + var version = new Version(1, 0); + var method = new HttpMethod("custom"); + + rm.Content = content; + rm.Method = method; + rm.RequestUri = uri; + rm.Version = version; + + Assert.Equal(content, rm.Content); + Assert.Equal(uri, rm.RequestUri); + Assert.Equal(method, rm.Method); + Assert.Equal(version, rm.Version); + + Assert.NotNull(rm.Headers); + Assert.NotNull(rm.Options); + + rm.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptionsValue); + Assert.Null(fetchOptionsValue); + } +#nullable disable + + [Fact] + public void Properties_SetOptionsAndGetTheirValue_Set_EnableStreamingResponse() + { + var rm = new HttpRequestMessage(); + + var content = new MockContent(); + var uri = new Uri("https://example.com"); + var version = new Version(1, 0); + var method = new HttpMethod("custom"); + + rm.Content = content; + rm.Method = method; + rm.RequestUri = uri; + rm.Version = version; + + rm.Options.Set(EnableStreamingResponse, true); + + Assert.Equal(content, rm.Content); + Assert.Equal(uri, rm.RequestUri); + Assert.Equal(method, rm.Method); + Assert.Equal(version, rm.Version); + + Assert.NotNull(rm.Headers); + Assert.NotNull(rm.Options); + + rm.Options.TryGetValue(EnableStreamingResponse, out bool streamingEnabledValue); + Assert.True(streamingEnabledValue); + } + + [Fact] + public void Properties_SetOptionsAndGetTheirValue_NotSet_EnableStreamingResponse() + { + var rm = new HttpRequestMessage(); + + var content = new MockContent(); + var uri = new Uri("https://example.com"); + var version = new Version(1, 0); + var method = new HttpMethod("custom"); + + rm.Content = content; + rm.Method = method; + rm.RequestUri = uri; + rm.Version = version; + + Assert.Equal(content, rm.Content); + Assert.Equal(uri, rm.RequestUri); + Assert.Equal(method, rm.Method); + Assert.Equal(version, rm.Version); + + Assert.NotNull(rm.Headers); + Assert.NotNull(rm.Options); + + rm.Options.TryGetValue(EnableStreamingResponse, out bool streamingEnabledValue); + Assert.False(streamingEnabledValue); + } + + [Fact] + public void RequestUri_SetNonHttpUri_ThrowsArgumentException() + { + var rm = new HttpRequestMessage(); + AssertExtensions.Throws("value", () => { rm.RequestUri = new Uri("ftp://example.com"); }); + } + + [Fact] + public void Version_SetToNull_ThrowsArgumentNullException() + { + var rm = new HttpRequestMessage(); + Assert.Throws(() => { rm.Version = null; }); + } + + [Fact] + public void Method_SetToNull_ThrowsArgumentNullException() + { + var rm = new HttpRequestMessage(); + Assert.Throws(() => { rm.Method = null; }); + } + + [Fact] + public void ToString_DefaultAndNonDefaultInstance_DumpAllFields() + { + var rm = new HttpRequestMessage(); + string expected = + "Method: GET, RequestUri: '', Version: " + + _expectedRequestMessageVersion.ToString(2) + + $", Content: , Headers:{Environment.NewLine}{{{Environment.NewLine}}}"; + Assert.Equal(expected, rm.ToString()); + + rm.Method = HttpMethod.Put; + rm.RequestUri = new Uri("http://a.com/"); + rm.Version = new Version(1, 0); + rm.Content = new StringContent("content"); + + // Note that there is no Content-Length header: The reason is that the value for Content-Length header + // doesn't get set by StringContent..ctor, but only if someone actually accesses the ContentLength property. + Assert.Equal( + "Method: PUT, RequestUri: 'http://a.com/', Version: 1.0, Content: " + typeof(StringContent).ToString() + ", Headers:" + Environment.NewLine + + $"{{{Environment.NewLine}" + + " Content-Type: text/plain; charset=utf-8" + Environment.NewLine + + "}", rm.ToString()); + + rm.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain", 0.2)); + rm.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml", 0.1)); + rm.Headers.Add("Custom-Request-Header", "value1"); + rm.Content.Headers.Add("Custom-Content-Header", "value2"); + + Assert.Equal( + "Method: PUT, RequestUri: 'http://a.com/', Version: 1.0, Content: " + typeof(StringContent).ToString() + ", Headers:" + Environment.NewLine + + "{" + Environment.NewLine + + " Accept: text/plain; q=0.2" + Environment.NewLine + + " Accept: text/xml; q=0.1" + Environment.NewLine + + " Custom-Request-Header: value1" + Environment.NewLine + + " Content-Type: text/plain; charset=utf-8" + Environment.NewLine + + " Custom-Content-Header: value2" + Environment.NewLine + + "}", rm.ToString()); + } + + #region Helper methods + + private class MockContent : HttpContent + { + public bool IsDisposed { get; private set; } + + protected override bool TryComputeLength(out long length) + { + throw new NotImplementedException(); + } + +#nullable enable + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) + { +#nullable disable + throw new NotImplementedException(); + } + + protected override void Dispose(bool disposing) + { + IsDisposed = true; + base.Dispose(disposing); + } + } + + #endregion + } +} From 7ffdb13cb27c59062b8bec0f4080042468748c20 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 28 Jul 2020 22:56:41 -0700 Subject: [PATCH 116/755] Assert that we don't get the value we don't want instead of attempting to check for a specific error code. Fixes #39955 (#40019) --- .../tests/Enumeration/ErrorHandlingTests.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs b/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs index e6858057bf4f..2c330cb0b2e7 100644 --- a/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs +++ b/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs @@ -73,8 +73,11 @@ public void NotFoundErrorIsExpected() // Make sure we're returning the native error as expected (and not the PAL error on Unix) using (LastError le = new LastError(Path.GetRandomFileName())) { - // Conveniently ERROR_FILE_NOT_FOUND and ENOENT are both 0x2 - Assert.Equal(2, le.Error); + // while ERROR_FILE_NOT_FOUND/ENOENT have predictable values on Windows, Linux and Mac, + // we can't rely on ENOENT having the same value on other platforms. Instead, assert + // that we didn't get the PAL error because we know its value. + const int PAL_Error_ENOENT = 0x1002D; + Assert.NotEqual(PAL_Error_ENOENT, le.Error); } } From 5049c296911ef4b99b686dfe068b305e5c28b495 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 28 Jul 2020 22:57:13 -0700 Subject: [PATCH 117/755] Update threadpool callback error messages to fix #38803 (#40000) --- src/mono/mono/mini/mini-wasm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 3b914a03fddf..e60d77f49250 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -604,13 +604,13 @@ tp_cb (void) mono_runtime_try_invoke (method, NULL, NULL, &exc, error); if (!is_ok (error)) { - printf ("tp callback failed due to %s\n", mono_error_get_message (error)); + printf ("ThreadPool Callback failed due to error: %s\n", mono_error_get_message (error)); mono_error_cleanup (error); } if (exc) { char *type_name = mono_type_get_full_name (mono_object_class (exc)); - printf ("tp callback threw a %s\n", type_name); + printf ("ThreadPool Callback threw an unhandled exception of type %s\n", type_name); g_free (type_name); } } From a352aefc8980dbf5a0eb383bae33d88aeff01b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Wed, 29 Jul 2020 10:16:04 +0200 Subject: [PATCH 118/755] Disabled outerloop test. (#40045) --- .../System.Net.Http/tests/FunctionalTests/HttpClientTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs index 5a23a73ef5f2..0074a06bc657 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs @@ -873,6 +873,7 @@ await server.AcceptConnectionAsync(async connection => [Fact] [OuterLoop] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39056")] public async Task Send_TimeoutRequestContent_Throws() { await LoopbackServer.CreateClientAndServerAsync( From 6ab00b4821b1a4bf60e12ab17e0afe214291b247 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Wed, 29 Jul 2020 12:10:35 +0300 Subject: [PATCH 119/755] [wasm] Re-enable some tests in the System.Net.WebSockets.Tests namespace (#40004) There is no repro for https://github.com/dotnet/runtime/issues/38807 at the moment so the related tests have been enabled. Two tests have been disabled due to PNSE (see https://github.com/dotnet/runtime/pull/39346). Fixes: https://github.com/dotnet/runtime/issues/38807 The test run result: `Tests run: 177, Errors: 0, Failures: 0, Skipped: 0.` --- .../Common/tests/System/Net/WebSockets/WebSocketCreateTest.cs | 2 ++ .../tests/WebSocketProtocolTests.cs | 1 - src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/WebSockets/WebSocketCreateTest.cs b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketCreateTest.cs index b48bfb0c183c..f22a8add7d96 100644 --- a/src/libraries/Common/tests/System/Net/WebSockets/WebSocketCreateTest.cs +++ b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketCreateTest.cs @@ -101,6 +101,7 @@ public async Task ReceiveAsync_UTF8SplitAcrossMultipleBuffers_ValidDataReceived( } [Theory] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Net.Sockets is not supported on this platform. [ActiveIssue("https://github.com/dotnet/runtime/issues/34690", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [InlineData(0b_1000_0001, 0b_0_000_0001, false)] // fin + text, no mask + length == 1 [InlineData(0b_1100_0001, 0b_0_000_0001, true)] // fin + rsv1 + text, no mask + length == 1 @@ -147,6 +148,7 @@ public async Task ReceiveAsync_InvalidFrameHeader_AbortsAndThrowsException(byte } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Net.Sockets is not supported on this platform. [ActiveIssue("https://github.com/dotnet/runtime/issues/34690", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public async Task ReceiveAsync_ServerSplitHeader_ValidDataReceived() { diff --git a/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/WebSocketProtocolTests.cs b/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/WebSocketProtocolTests.cs index 7266ac96e287..1d8aecbda9db 100644 --- a/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/WebSocketProtocolTests.cs +++ b/src/libraries/System.Net.WebSockets.WebSocketProtocol/tests/WebSocketProtocolTests.cs @@ -6,7 +6,6 @@ namespace System.Net.WebSockets.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/38807", TestPlatforms.Browser)] public sealed class WebSocketProtocolCreateTests : WebSocketCreateTest { protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) => diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs index 892404f040d9..ad738a00ec86 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs @@ -6,7 +6,6 @@ namespace System.Net.WebSockets.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/38807", TestPlatforms.Browser)] public sealed class WebSocketTests : WebSocketCreateTest { protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) => From e5f149b791617854655d884d36d9ee019a8155b4 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Wed, 29 Jul 2020 05:19:08 -0400 Subject: [PATCH 120/755] [mono] Disable cfgdir config on Windows netcore builds (#40005) This was already disabled with autotools, but I forgot to update winconfig.h as well. --- src/mono/winconfig.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/winconfig.h b/src/mono/winconfig.h index f062d0a69595..7d429a86e8a9 100644 --- a/src/mono/winconfig.h +++ b/src/mono/winconfig.h @@ -67,6 +67,9 @@ #ifndef DISABLE_DLLMAP #define DISABLE_DLLMAP 1 #endif +#ifndef DISABLE_CFGDIR_CONFIG +#define DISABLE_CFGDIR_CONFIG 1 +#endif #endif /* Disable runtime state dumping */ From b2c7585ba82a2248e7d0afb956c3f17cfbb6d6e7 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Wed, 29 Jul 2020 02:47:49 -0700 Subject: [PATCH 121/755] Redirect DllImport of hostpolicy to the main executable when it's embedded (#40014) --- src/coreclr/src/dlls/mscoree/unixinterface.cpp | 17 +++++++++++++++-- src/coreclr/src/vm/ceemain.cpp | 4 ++++ src/coreclr/src/vm/dllimport.cpp | 18 ++++++++++++++++++ .../corehost/cli/hostpolicy/coreclr.cpp | 3 ++- .../corehost/cli/hostpolicy/coreclr.h | 1 + .../cli/hostpolicy/hostpolicy_context.cpp | 14 +++++++++++++- .../cli/hostpolicy/static/CMakeLists.txt | 2 ++ 7 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/dlls/mscoree/unixinterface.cpp b/src/coreclr/src/dlls/mscoree/unixinterface.cpp index def877265312..e23ece987224 100644 --- a/src/coreclr/src/dlls/mscoree/unixinterface.cpp +++ b/src/coreclr/src/dlls/mscoree/unixinterface.cpp @@ -27,6 +27,9 @@ typedef NewArrayHolder ConstWStringHolder; // Specifies whether coreclr is embedded or standalone extern bool g_coreclr_embedded; +// Specifies whether hostpolicy is embedded in executable or standalone +extern bool g_hostpolicy_embedded; + // Holder for array of wide strings class ConstWStringArrayHolder : public NewArrayHolder { @@ -116,7 +119,8 @@ static void ConvertConfigPropertiesToUnicode( int propertyCount, LPCWSTR** propertyKeysWRef, LPCWSTR** propertyValuesWRef, - BundleProbe** bundleProbe) + BundleProbe** bundleProbe, + bool* hostPolicyEmbedded) { LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[propertyCount]; ASSERTE_ALL_BUILDS(propertyKeysW != nullptr); @@ -135,6 +139,11 @@ static void ConvertConfigPropertiesToUnicode( // is passed in as the value of "BUNDLE_PROBE" property (encoded as a string). *bundleProbe = (BundleProbe*)_wcstoui64(propertyValuesW[propertyIndex], nullptr, 0); } + else if (strcmp(propertyKeys[propertyIndex], "HOSTPOLICY_EMBEDDED") == 0) + { + // The HOSTPOLICY_EMBEDDED property indicates if the executable has hostpolicy statically linked in + *hostPolicyEmbedded = (wcscmp(propertyValuesW[propertyIndex], W("true")) == 0); + } } *propertyKeysWRef = propertyKeysW; @@ -177,6 +186,7 @@ int coreclr_initialize( LPCWSTR* propertyKeysW; LPCWSTR* propertyValuesW; BundleProbe* bundleProbe = nullptr; + bool hostPolicyEmbedded = false; ConvertConfigPropertiesToUnicode( propertyKeys, @@ -184,7 +194,8 @@ int coreclr_initialize( propertyCount, &propertyKeysW, &propertyValuesW, - &bundleProbe); + &bundleProbe, + &hostPolicyEmbedded); #ifdef TARGET_UNIX DWORD error = PAL_InitializeCoreCLR(exePath, g_coreclr_embedded); @@ -198,6 +209,8 @@ int coreclr_initialize( } #endif + g_hostpolicy_embedded = hostPolicyEmbedded; + ReleaseHolder host; hr = CorHost2::CreateObject(IID_ICLRRuntimeHost4, (void**)&host); diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 4da222caca08..962ba0d2298a 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -240,10 +240,14 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface); #endif // !CROSSGEN_COMPILE // g_coreclr_embedded indicates that coreclr is linked directly into the program +// g_hostpolicy_embedded indicates that the hostpolicy library is linked directly into the executable +// Note: that it can happen that the hostpolicy is embedded but coreclr isn't (on Windows singlefilehost is built that way) #ifdef CORECLR_EMBEDDED bool g_coreclr_embedded = true; +bool g_hostpolicy_embedded = true; // We always embed hostpolicy if coreclr is also embedded #else bool g_coreclr_embedded = false; +bool g_hostpolicy_embedded = false; // In this case the value may come from a runtime property and may change #endif // Remember how the last startup of EE went. diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 1802705362ad..9a99718582fd 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -54,6 +54,9 @@ using namespace clr::fs; // Specifies whether coreclr is embedded or standalone extern bool g_coreclr_embedded; +// Specifies whether hostpolicy is embedded in executable or standalone +extern bool g_hostpolicy_embedded; + // remove when we get an updated SDK #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 @@ -6331,6 +6334,21 @@ namespace } #endif + if (g_hostpolicy_embedded) + { +#ifdef TARGET_WINDOWS + if (wcscmp(wszLibName, W("hostpolicy.dll")) == 0) + { + return WszGetModuleHandle(NULL); + } +#else + if (wcscmp(wszLibName, W("libhostpolicy")) == 0) + { + return PAL_LoadLibraryDirect(NULL); + } +#endif + } + AppDomain* pDomain = GetAppDomain(); DWORD loadWithAlteredPathFlags = GetLoadWithAlteredSearchPathFlag(); bool libNameIsRelativePath = Path::IsRelative(wszLibName); diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.cpp b/src/installer/corehost/cli/hostpolicy/coreclr.cpp index a54d04e8714f..d9564ac8fa67 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.cpp +++ b/src/installer/corehost/cli/hostpolicy/coreclr.cpp @@ -147,7 +147,8 @@ namespace _X("APP_PATHS"), _X("APP_NI_PATHS"), _X("RUNTIME_IDENTIFIER"), - _X("BUNDLE_PROBE") + _X("BUNDLE_PROBE"), + _X("HOSTPOLICY_EMBEDDED") }; static_assert((sizeof(PropertyNameMapping) / sizeof(*PropertyNameMapping)) == static_cast(common_property::Last), "Invalid property count"); diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.h b/src/installer/corehost/cli/hostpolicy/coreclr.h index 9567fb9cab72..c086ba56e10b 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.h +++ b/src/installer/corehost/cli/hostpolicy/coreclr.h @@ -66,6 +66,7 @@ enum class common_property AppNIPaths, RuntimeIdentifier, BundleProbe, + HostPolicyEmbedded, // Sentinel value - new values should be defined above Last }; diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp index 05c61bb78064..f7daa5d84587 100644 --- a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp +++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp @@ -231,8 +231,20 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a pal::stringstream_t ptr_stream; ptr_stream << "0x" << std::hex << (size_t)(&bundle_probe); - coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str()); + if (!coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str())) + { + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + return StatusCode::LibHostDuplicateProperty; + } + } + +#if defined(HOSTPOLICY_EMBEDDED) + if (!coreclr_properties.add(common_property::HostPolicyEmbedded, _X("true"))) + { + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + return StatusCode::LibHostDuplicateProperty; } +#endif return StatusCode::Success; } diff --git a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt index 3ee012f475dd..fcf95656f5fb 100644 --- a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt +++ b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt @@ -46,3 +46,5 @@ set(HEADERS set(SKIP_VERSIONING 1) set(BUILD_OBJECT_LIBRARY 1) include(../../lib_static.cmake) + +add_definitions(-DHOSTPOLICY_EMBEDDED) From e10da01d6557be2238ab55218f947001a3b35e57 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 29 Jul 2020 02:55:56 -0700 Subject: [PATCH 122/755] WASM: Enable GetAssemblyNameTest_ValidAssembly and add hook to include custom files into vfs (#40032) --- eng/testing/tests.mobile.targets | 15 ++------------- .../tests/System.Reflection.Metadata.Tests.csproj | 3 +++ ...em.Reflection.MetadataLoadContext.Tests.csproj | 5 +++++ .../tests/System.Reflection.Tests.csproj | 4 ++++ .../tests/AssemblyLoadContextTest.cs | 1 - .../tests/System.Runtime.Loader.Tests.csproj | 3 +++ 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index c69aa634b71d..84b8337494a4 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -132,24 +132,13 @@ + + - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj index 68a69ab158b7..1703956fc6c5 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj @@ -74,4 +74,9 @@ + + + + + diff --git a/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj b/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj index f96a3551aa4b..8db00f6e9dd4 100644 --- a/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj +++ b/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj @@ -64,4 +64,8 @@ + + + + diff --git a/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs b/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs index 290cb3ca06b3..3979d76aeadb 100644 --- a/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs @@ -18,7 +18,6 @@ public partial class AssemblyLoadContextTest private const string TestAssemblyNotSupported = "System.Runtime.Loader.Test.AssemblyNotSupported"; [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39379", TestPlatforms.Browser)] public static void GetAssemblyNameTest_ValidAssembly() { var expectedName = typeof(AssemblyLoadContextTest).Assembly.GetName(); diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index c595a1ca1a94..f43714d9365d 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -30,4 +30,7 @@ + + + \ No newline at end of file From 9df596f2fa9a538a95dc555d99faf1ebac050af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Wed, 29 Jul 2020 12:41:42 +0200 Subject: [PATCH 123/755] Do not test sockets handler fix on WinHttpHandler. (#40070) --- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 687fa61ab06d..b764d2419e09 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -2119,7 +2119,7 @@ await server.AcceptConnectionAsync(async connection => [Fact] public async Task SendAsync_Expect100Continue_RequestBodyFails_ThrowsContentException() { - if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) + if (IsWinHttpHandler) { return; } @@ -2137,7 +2137,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => HttpRequestMessage initialMessage = new HttpRequestMessage(HttpMethod.Post, uri) { Version = UseVersion }; initialMessage.Content = new ThrowingContent(() => new ThrowingContentException()); initialMessage.Headers.ExpectContinue = true; - Exception exception = await Assert.ThrowsAsync(() => client.SendAsync(TestAsync, initialMessage)); + await Assert.ThrowsAsync(() => client.SendAsync(TestAsync, initialMessage)); clientFinished.SetResult(true); } From 8b5467e1ea0aa2bc5aa4a4281b71e5299d8c0af1 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Wed, 29 Jul 2020 04:31:25 -0700 Subject: [PATCH 124/755] BindAsync -> ListenAsync (#40068) BindAsync -> ListenAsync --- .../VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs | 2 +- .../System.Net.Connections/ref/System.Net.Connections.cs | 2 +- .../src/System/Net/Connections/ConnectionListenerFactory.cs | 2 +- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs index 0a47a258057e..b25a612479e5 100644 --- a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs +++ b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkConnectionListenerFactory.cs @@ -20,7 +20,7 @@ public static ConnectionFactory GetConnectionFactory(ConnectionListener listener return factory; } - public override ValueTask BindAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) + public override ValueTask ListenAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) return ValueTask.FromCanceled(cancellationToken); return new ValueTask(new VirtualConnectionListener(endPoint)); diff --git a/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs b/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs index c82551e09dc8..6eaa384fdc7e 100644 --- a/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs +++ b/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs @@ -61,7 +61,7 @@ protected virtual void Dispose(bool disposing) { } public abstract partial class ConnectionListenerFactory : System.IAsyncDisposable, System.IDisposable { protected ConnectionListenerFactory() { } - public abstract System.Threading.Tasks.ValueTask BindAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + public abstract System.Threading.Tasks.ValueTask ListenAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); public void Dispose() { } protected virtual void Dispose(bool disposing) { } public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs index d208f05a5d47..7e6339d9d677 100644 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs +++ b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs @@ -11,7 +11,7 @@ namespace System.Net.Connections /// public abstract class ConnectionListenerFactory : IAsyncDisposable, IDisposable { - public abstract ValueTask BindAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); + public abstract ValueTask ListenAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); public void Dispose() { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 356dff6de0fb..c8d6078a1381 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -114,7 +114,7 @@ public SocketsHttpHandler_ConnectionFactoryTest(ITestOutputHelper output) : base public async Task CustomConnectionFactory_AsyncRequest_Success() { await using ConnectionListenerFactory listenerFactory = new VirtualNetworkConnectionListenerFactory(); - await using ConnectionListener listener = await listenerFactory.BindAsync(endPoint: null); + await using ConnectionListener listener = await listenerFactory.ListenAsync(endPoint: null); await using ConnectionFactory connectionFactory = VirtualNetworkConnectionListenerFactory.GetConnectionFactory(listener); // TODO: if GenericLoopbackOptions actually worked for HTTP/1 LoopbackServer we could just use that and pass in to CreateConnectionAsync. From bb82d679dc1aff1c26bc93aaea3dd9e8f274df5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 29 Jul 2020 16:44:16 +0200 Subject: [PATCH 125/755] [wasm] Remove unused icalls for Environment properties (#40079) They are no longer needed after https://github.com/dotnet/runtime/pull/38996 since we return values in managed code now. --- src/mono/mono/metadata/icall-decl.h | 2 ++ src/mono/mono/metadata/icall-def-netcore.h | 3 --- src/mono/mono/metadata/icall.c | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index 1bb8ab1cfa67..2c153f8cd6c9 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -159,7 +159,9 @@ ICALL_EXPORT gint64 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollect ICALL_EXPORT gint64 ves_icall_System_Threading_Timer_GetTimeMonotonic (void); ICALL_EXPORT gpointer ves_icall_System_GCHandle_GetAddrOfPinnedObject (MonoGCHandle handle); ICALL_EXPORT int ves_icall_Interop_Sys_DoubleToString (double, char*, char*, int); +#if !ENABLE_NETCORE ICALL_EXPORT int ves_icall_System_Environment_get_Platform (void); +#endif ICALL_EXPORT int ves_icall_System_GC_GetCollectionCount (int); ICALL_EXPORT int ves_icall_System_GC_GetMaxGeneration (void); ICALL_EXPORT gint64 ves_icall_System_GC_GetAllocatedBytesForCurrentThread (void); diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index ee55fbbc7fc2..8e3a61820b65 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -94,11 +94,8 @@ HANDLES(ENV_2, "GetCommandLineArgs", ves_icall_System_Environment_GetCommandLine HANDLES(ENV_3, "GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames, MonoArray, 0, ()) NOHANDLES(ICALL(ENV_4, "GetProcessorCount", ves_icall_System_Environment_get_ProcessorCount)) NOHANDLES(ICALL(ENV_9, "get_ExitCode", mono_environment_exitcode_get)) -HANDLES(ENV_11, "get_MachineName", ves_icall_System_Environment_get_MachineName, MonoString, 0, ()) -NOHANDLES(ICALL(ENV_13, "get_Platform", ves_icall_System_Environment_get_Platform)) NOHANDLES(ICALL(ENV_15, "get_TickCount", ves_icall_System_Environment_get_TickCount)) NOHANDLES(ICALL(ENV_15a, "get_TickCount64", ves_icall_System_Environment_get_TickCount64)) -HANDLES(ENV_16, "get_UserName", ves_icall_System_Environment_get_UserName, MonoString, 0, ()) HANDLES(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native, MonoString, 1, (const_char_ptr)) NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index c58854c2532e..479ba5e95cbc 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -7523,6 +7523,7 @@ ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxyHandle tp /* System.Environment */ +#ifndef ENABLE_NETCORE MonoStringHandle ves_icall_System_Environment_get_UserName (MonoError *error) { @@ -7606,6 +7607,7 @@ ves_icall_System_Environment_get_Platform (void) { return mono_icall_get_platform (); } +#endif /* !ENABLE_NETCORE */ #ifndef HOST_WIN32 static MonoStringHandle From 5c344f67645a3e659e1c5416c1ebf88b5d224aae Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 29 Jul 2020 09:07:23 -0700 Subject: [PATCH 126/755] JIT: ensure fgFirstBB has appropriate flags (#40038) This fixes an issue where release jits might sometimes generate bad GC info. Keeping it minimal for now so we can consider servicing preview 8. See #39023 for details. --- src/coreclr/src/jit/flowgraph.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index f375d1196605..fb0c8f231385 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -175,6 +175,8 @@ void Compiler::fgInit() #ifdef FEATURE_SIMD fgPreviousCandidateSIMDFieldAsgStmt = nullptr; #endif + + fgHasSwitch = false; } bool Compiler::fgHaveProfileData() @@ -476,7 +478,8 @@ void Compiler::fgEnsureFirstBBisScratch() noway_assert(fgLastBB != nullptr); - block->bbFlags |= (BBF_INTERNAL | BBF_IMPORTED); + // Set the expected flags + block->bbFlags |= (BBF_INTERNAL | BBF_IMPORTED | BBF_JMP_TARGET | BBF_HAS_LABEL); // This new first BB has an implicit ref, and no others. block->bbRefs = 1; From 38c97928216f5917e73b64db7301640cf1430c93 Mon Sep 17 00:00:00 2001 From: Olivia Chen <51934529+ooooolivia@users.noreply.github.com> Date: Wed, 29 Jul 2020 09:50:54 -0700 Subject: [PATCH 127/755] Split Perf Helix Workitem (#39859) * wip * split perf jobs into test categories * add test category to run-performance-job.yml * correct space * add space to parameter var * add $ * fix yaml * revert extraparameters * replace crossgen runkind * change micro_mono tag * remove space --- eng/common/performance/crossgen_perf.proj | 81 +++++++++++++++++++ ...helixpublish.proj => microbenchmarks.proj} | 52 ------------ .../templates/steps/perf-send-to-helix.yml | 10 ++- eng/pipelines/coreclr/perf.yml | 28 +++++++ eng/pipelines/coreclr/templates/perf-job.yml | 8 +- .../coreclr/templates/run-performance-job.yml | 9 ++- 6 files changed, 127 insertions(+), 61 deletions(-) create mode 100644 eng/common/performance/crossgen_perf.proj rename eng/common/performance/{perfhelixpublish.proj => microbenchmarks.proj} (67%) diff --git a/eng/common/performance/crossgen_perf.proj b/eng/common/performance/crossgen_perf.proj new file mode 100644 index 000000000000..3c8c33d7055c --- /dev/null +++ b/eng/common/performance/crossgen_perf.proj @@ -0,0 +1,81 @@ + + + + py -3 + $(HelixPreCommands);call %HELIX_CORRELATION_PAYLOAD%\performance\tools\machine-setup.cmd;set PYTHONPATH=%HELIX_WORKITEM_PAYLOAD%\scripts%3B%HELIX_WORKITEM_PAYLOAD% + %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts + $HELIX_CORRELATION_PAYLOAD + $(BaseDirectory)/performance + + + + $(PerformanceDirectory)/scripts/benchmarks_ci.py --csproj $(PerformanceDirectory)/$(TargetCsproj) + --dotnet-versions $DOTNET_VERSION --cli-source-info args --cli-branch $PERFLAB_BRANCH --cli-commit-sha $PERFLAB_HASH --cli-repository https://github.com/$PERFLAB_REPO --cli-source-timestamp $PERFLAB_BUILDTIMESTAMP + python3 + $(BaseDirectory)/Core_Root/corerun + $(HelixPreCommands);chmod +x $(PerformanceDirectory)/tools/machine-setup.sh;. $(PerformanceDirectory)/tools/machine-setup.sh + $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts + $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts_Baseline + $(PerformanceDirectory)/src/tools/ResultsComparer/ResultsComparer.csproj + $(PerformanceDirectory)/tools/dotnet/$(Architecture)/dotnet + %25 + $HELIX_WORKITEM_ROOT/testResults.xml + + + + + %(Identity) + + + + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory)\ScenarioCorrelation + $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --composite %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\framework-r2r.dll.rsp --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + 1:00 + + + \ No newline at end of file diff --git a/eng/common/performance/perfhelixpublish.proj b/eng/common/performance/microbenchmarks.proj similarity index 67% rename from eng/common/performance/perfhelixpublish.proj rename to eng/common/performance/microbenchmarks.proj index 272366da95fc..185522fc739c 100644 --- a/eng/common/performance/perfhelixpublish.proj +++ b/eng/common/performance/microbenchmarks.proj @@ -137,56 +137,4 @@ 4:00 - - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --composite %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\framework-r2r.dll.rsp --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - 1:00 - - - \ No newline at end of file diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml index b3ea9acf1f16..1e3bed764cfa 100644 --- a/eng/common/templates/steps/perf-send-to-helix.yml +++ b/eng/common/templates/steps/perf-send-to-helix.yml @@ -1,10 +1,11 @@ # Please remember to update the documentation if you make changes to these parameters! parameters: + ProjectFile: '' # required -- project file that specifies the helix workitems HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list 0of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group HelixPreCommands: '' # optional -- commands to run before Helix work item execution HelixPostCommands: '' # optional -- commands to run after Helix work item execution WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects @@ -18,9 +19,10 @@ parameters: DisplayNamePrefix: 'Send job to Helix' # optional -- rename the beginning of the displayName of the steps in AzDO condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + steps: - - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\perfhelixpublish.proj /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog + - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\${{ parameters.ProjectFile }} /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog displayName: ${{ parameters.DisplayNamePrefix }} (Windows) env: BuildConfig: $(_BuildConfig) @@ -42,7 +44,7 @@ steps: SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/perfhelixpublish.proj /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/${{ parameters.ProjectFile }} /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog displayName: ${{ parameters.DisplayNamePrefix }} (Unix) env: BuildConfig: $(_BuildConfig) diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index 149eb1aed6fb..cb97c408514f 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -43,6 +43,7 @@ jobs: # - template: /eng/pipelines/common/checkout-job.yml +# build coreclr and libraries - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml @@ -54,6 +55,7 @@ jobs: jobParameters: testGroup: perf +# build mono - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/mono/templates/build-job.yml @@ -62,6 +64,7 @@ jobs: platforms: - Linux_x64 +# run mono perf job - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml @@ -73,7 +76,10 @@ jobs: testGroup: perf liveLibrariesBuildConfig: Release runtimeType: mono + projectFile: microbenchmarks.proj + runKind: micro_mono +# run mono interpreter job (private CI only) - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -87,7 +93,10 @@ jobs: liveLibrariesBuildConfig: Release runtimeType: mono codeGenType: 'Interpreter' + projectFile: microbenchmarks.proj + runKind: micro_mono +# run coreclr microbenchmarks perf job - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml @@ -100,3 +109,22 @@ jobs: jobParameters: testGroup: perf liveLibrariesBuildConfig: Release + projectFile: microbenchmarks.proj + runKind: micro + +# run coreclr crossgen perf job +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: coreclr + platforms: + #- Linux_x64 + - Windows_NT_x64 + - Windows_NT_x86 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + projectFile: crossgen_perf.proj + runKind: crossgen_scenarios + diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index d0cc3cee0a52..57df1c0dcb63 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -11,6 +11,8 @@ parameters: runtimeType: 'coreclr' pool: '' codeGenType: 'JIT' + projetFile: '' + runKind: '' ### Perf job @@ -21,8 +23,8 @@ jobs: - template: run-performance-job.yml parameters: # Compute job name from template parameters - jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}_{5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType) }} - displayName: ${{ format('Performance {0}{1} {2} {3} {4} {5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType) }} + jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}_{5}_{6}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind) }} + displayName: ${{ format('Performance {0}{1} {2} {3} {4} {5} {6}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind) }} pool: ${{ parameters.pool }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} @@ -32,6 +34,8 @@ jobs: liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} runtimeType: ${{ parameters.runtimeType }} codeGenType: ${{ parameters.codeGenType }} + projectFile: ${{ parameters.projectFile }} + runKind: ${{ parameters.runKind }} # Test job depends on the corresponding build job dependsOn: - ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 7dadb9bd5eee..3d34f5a67a14 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -18,6 +18,8 @@ parameters: liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run runtimeType: 'coreclr' # optional -- Sets the runtime as coreclr or mono codeGenType: 'JIT' # optional -- Decides on the codegen technology if running on mono + projectFile: '' # required -- project file to build helix workitems + runKind: '' # required -- test category jobs: - template: xplat-pipeline-job.yml @@ -102,11 +104,11 @@ jobs: _Framework: ${{ framework }} steps: - ${{ parameters.steps }} - - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal)$(Interpreter) -Framework $(_Framework) ${{ parameters.extraSetupParameters }} + - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal)$(Interpreter) -Framework $(_Framework) -Kind ${{ parameters.runKind }} ${{ parameters.extraSetupParameters }} displayName: Performance Setup (Windows) condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT')) continueOnError: ${{ parameters.continueOnError }} - - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal)$(Interpreter) --framework $(_Framework) ${{ parameters.extraSetupParameters }} + - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal)$(Interpreter) --framework $(_Framework) --kind ${{ parameters.runKind }} ${{ parameters.extraSetupParameters }} displayName: Performance Setup (Unix) condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) continueOnError: ${{ parameters.continueOnError }} @@ -132,10 +134,11 @@ jobs: WorkItemTimeout: 4:00 # 4 hours WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions + ProjectFile: ${{ parameters.projectFile }} - task: PublishPipelineArtifact@1 displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'Performance_Run_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.runtimeType }}_${{ parameters.codeGenType }}' + artifactName: 'Performance_Run_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.runtimeType }}_${{ parameters.codeGenType }}_${{ parameters.runKind }}' continueOnError: true condition: always() From 1f8e0a11e56534bd3183bbb81efd166e958a9dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Wed, 29 Jul 2020 19:37:59 +0200 Subject: [PATCH 128/755] Crossgen2 composite GC stress pipeline (#39949) --- eng/pipelines/coreclr/crossgen2-gcstress.yml | 60 +++++++++++++++++++ .../tests/src/CLRTest.CrossGen.targets | 24 ++++++++ 2 files changed, 84 insertions(+) create mode 100644 eng/pipelines/coreclr/crossgen2-gcstress.yml diff --git a/eng/pipelines/coreclr/crossgen2-gcstress.yml b/eng/pipelines/coreclr/crossgen2-gcstress.yml new file mode 100644 index 000000000000..7942e747e26f --- /dev/null +++ b/eng/pipelines/coreclr/crossgen2-gcstress.yml @@ -0,0 +1,60 @@ +trigger: none + +pr: none + +schedules: +- cron: "0 6 * * 0,1" + displayName: Sat and Sun at 10:00 PM (UTC-8:00) + branches: + include: + - master + always: true + +jobs: +# +# Checkout repository +# +- template: /eng/pipelines/common/checkout-job.yml + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml + buildConfig: checked + platforms: + - Linux_x64 + - Linux_arm64 + - OSX_x64 + - Windows_NT_x64 + - Windows_NT_arm64 + - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64 + jobParameters: + testGroup: gcstress-extra + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/templates/runtimes/build-test-job.yml + buildConfig: checked + platforms: + - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64 + jobParameters: + testGroup: gcstress-extra + liveLibrariesBuildConfig: Release + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: checked + platforms: + - Linux_x64 + - Linux_arm64 + - OSX_x64 + - Windows_NT_x64 + - Windows_NT_arm64 + jobParameters: + testGroup: gcstress-extra + readyToRun: true + crossgen2: true + compositeBuildMode: true + displayNameArgs: Composite + liveLibrariesBuildConfig: Release diff --git a/src/coreclr/tests/src/CLRTest.CrossGen.targets b/src/coreclr/tests/src/CLRTest.CrossGen.targets index a11043761403..926f6ec6d151 100644 --- a/src/coreclr/tests/src/CLRTest.CrossGen.targets +++ b/src/coreclr/tests/src/CLRTest.CrossGen.targets @@ -84,6 +84,14 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then __ResponseFile="$__OutputFile.rsp" rm $__ResponseFile + // Suppress the GC stress COMPlus for the duration of Crossgen2 execution + local gcStressModeToRestore = $COMPlus_GCStress; + local heapVerifyModeToRestore = $COMPlus_HeapVerify; + local readyToRunModeToRestore = $COMPlus_ReadyToRun; + export COMPlus_GCStress= + export COMPlus_HeapVerify= + export COMPlus_ReadyToRun= + __Command=$_DebuggerFullPath # Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path if [ ! -z ${__TestDotNetCmd+x} ] %3B then @@ -109,6 +117,10 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then echo "Running CrossGen2: $__Command" $__Command __cg2ExitCode=$? + + export COMPlus_GCStress=$gcStressModeToRestore + export COMPlus_HeapVerify=$heapVerifyModeToRestore + export COMPlus_ReadyToRun=$readyToRunModeToRestore } if [ ! -z ${CompositeBuildMode+x} ]%3B then @@ -212,6 +224,14 @@ if defined RunCrossGen2 ( set __ResponseFile=!__OutputFile!.rsp del /Q !__ResponseFile! + REM Suppress GC stress mode for the duration of Crossgen2 execution + set __gcStressModeToRestore=!COMPlus_GCStress! + set COMPlus_GCStress= + set __heapVerifyModeToRestore=!COMPlus_HeapVerify! + set COMPlus_HeapVerify= + set __readyToRunModeToRestore=!COMPlus_ReadyToRun! + set COMPlus_ReadyToRun= + set __Command=!_DebuggerFullPath! REM Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path if defined __TestDotNetCmd ( @@ -237,6 +257,10 @@ if defined RunCrossGen2 ( echo "!__Command!" call !__Command! set CrossGen2Status=!ERRORLEVEL! + set COMPlus_GCStress=!__gcStressModeToRestore! + set COMPlus_HeapVerify=!__heapVerifyModeToRestore! + set COMPlus_ReadyToRun=!__readyToRunModeToRestore! + Exit /b 0 :DoneCrossgen2Operations From 8bc62c4e096d31bd3524a78f4afc71b7e85e15d5 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 29 Jul 2020 10:44:43 -0700 Subject: [PATCH 129/755] Add more configurations to runtimeconfig.json (#40036) --- src/coreclr/src/gc/gcconfig.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/coreclr/src/gc/gcconfig.h b/src/coreclr/src/gc/gcconfig.h index 085562f56dd4..7d667b6a15ea 100644 --- a/src/coreclr/src/gc/gcconfig.h +++ b/src/coreclr/src/gc/gcconfig.h @@ -75,7 +75,7 @@ class GCConfigStringHolder BOOL_CONFIG (LogEnabled, "GCLogEnabled", NULL, false, "Specifies if you want to turn on logging in GC") \ BOOL_CONFIG (ConfigLogEnabled, "GCConfigLogEnabled", NULL, false, "Specifies the name of the GC config log file") \ BOOL_CONFIG (GCNumaAware, "GCNumaAware", NULL, true, "Enables numa allocations in the GC") \ - BOOL_CONFIG (GCCpuGroup, "GCCpuGroup", NULL, false, "Enables CPU groups in the GC") \ + BOOL_CONFIG (GCCpuGroup, "GCCpuGroup", "System.GC.CpuGroup", false, "Enables CPU groups in the GC") \ BOOL_CONFIG (GCLargePages, "GCLargePages", "System.GC.LargePages", false, "Enables using Large Pages in the GC") \ INT_CONFIG (HeapVerifyLevel, "HeapVerify", NULL, HEAPVERIFY_NONE, "When set verifies the integrity of the managed heap on entry and exit of each GC") \ INT_CONFIG (LOHCompactionMode, "GCLOHCompact", NULL, 0, "Specifies the LOH compaction mode") \ @@ -92,13 +92,13 @@ class GCConfigStringHolder INT_CONFIG (LogFileSize, "GCLogFileSize", NULL, 0, "Specifies the GC log file size") \ INT_CONFIG (CompactRatio, "GCCompactRatio", NULL, 0, "Specifies the ratio compacting GCs vs sweeping") \ INT_CONFIG (GCHeapAffinitizeMask, "GCHeapAffinitizeMask", "System.GC.HeapAffinitizeMask", 0, "Specifies processor mask for Server GC threads") \ - STRING_CONFIG(GCHeapAffinitizeRanges, "GCHeapAffinitizeRanges", NULL, "Specifies list of processors for Server GC threads. The format is a comma separated " \ + STRING_CONFIG(GCHeapAffinitizeRanges, "GCHeapAffinitizeRanges", "System.GC.HeapAffinitizeRanges", "Specifies list of processors for Server GC threads. The format is a comma separated " \ "list of processor numbers or ranges of processor numbers. On Windows, each entry is " \ "prefixed by the CPU group number. Example: Unix - 1,3,5,7-9,12, Windows - 0:1,1:7-9") \ - INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", NULL, 0, "The percent for GC to consider as high memory") \ + INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \ INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \ INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \ - INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", NULL, 0, "Specifies a hard limit for the GC heap") \ + INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \ INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \ INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \ STRING_CONFIG(LogFile, "GCLogFile", NULL, "Specifies the name of the GC log file") \ @@ -122,13 +122,13 @@ class GCConfigStringHolder INT_CONFIG (BGCFLEnableTBH, "BGCFLEnableTBH", NULL, 0, "Enables TBH") \ INT_CONFIG (BGCFLEnableFF, "BGCFLEnableFF", NULL, 0, "Enables FF") \ INT_CONFIG (BGCG2RatioStep, "BGCG2RatioStep", NULL, 5, "Ratio correction factor for ML loop") \ - INT_CONFIG (GCHeapHardLimitSOH, "GCHeapHardLimitSOH", NULL, 0, "Specifies a hard limit for the GC heap SOH") \ - INT_CONFIG (GCHeapHardLimitLOH, "GCHeapHardLimitLOH", NULL, 0, "Specifies a hard limit for the GC heap LOH") \ - INT_CONFIG (GCHeapHardLimitPOH, "GCHeapHardLimitPOH", NULL, 0, "Specifies a hard limit for the GC heap POH") \ - INT_CONFIG (GCHeapHardLimitSOHPercent, "GCHeapHardLimitSOHPercent", NULL, 0, "Specifies the GC heap SOH usage as a percentage of the total memory") \ - INT_CONFIG (GCHeapHardLimitLOHPercent, "GCHeapHardLimitLOHPercent", NULL, 0, "Specifies the GC heap LOH usage as a percentage of the total memory") \ - INT_CONFIG (GCHeapHardLimitPOHPercent, "GCHeapHardLimitPOHPercent", NULL, 0, "Specifies the GC heap POH usage as a percentage of the total memory") \ - INT_CONFIG (GCEnabledInstructionSets, "GCEnabledInstructionSets", NULL, -1, "Specifies whether GC can use AVX2 or AVX512F - 0 for neither, 1 for AVX2, 3 for AVX512F")\ + INT_CONFIG (GCHeapHardLimitSOH, "GCHeapHardLimitSOH", "System.GC.HeapHardLimitSOH", 0, "Specifies a hard limit for the GC heap SOH") \ + INT_CONFIG (GCHeapHardLimitLOH, "GCHeapHardLimitLOH", "System.GC.HeapHardLimitLOH", 0, "Specifies a hard limit for the GC heap LOH") \ + INT_CONFIG (GCHeapHardLimitPOH, "GCHeapHardLimitPOH", "System.GC.HeapHardLimitPOH", 0, "Specifies a hard limit for the GC heap POH") \ + INT_CONFIG (GCHeapHardLimitSOHPercent, "GCHeapHardLimitSOHPercent", "System.GC.HeapHardLimitSOHPercent", 0, "Specifies the GC heap SOH usage as a percentage of the total memory") \ + INT_CONFIG (GCHeapHardLimitLOHPercent, "GCHeapHardLimitLOHPercent", "System.GC.HeapHardLimitLOHPercent", 0, "Specifies the GC heap LOH usage as a percentage of the total memory") \ + INT_CONFIG (GCHeapHardLimitPOHPercent, "GCHeapHardLimitPOHPercent", "System.GC.HeapHardLimitPOHPercent", 0, "Specifies the GC heap POH usage as a percentage of the total memory") \ + INT_CONFIG (GCEnabledInstructionSets, "GCEnabledInstructionSets", NULL, -1, "Specifies whether GC can use AVX2 or AVX512F - 0 for neither, 1 for AVX2, 3 for AVX512F")\ // This class is responsible for retreiving configuration information // for how the GC should operate. From 652297c318b491420d6d2828073ea97eaee99d7e Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 29 Jul 2020 10:57:58 -0700 Subject: [PATCH 130/755] Re-enable test as issue was fixed (#40026) --- src/coreclr/tests/issues.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index ac5addebf4b3..2438937a5f05 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -935,9 +935,6 @@ https://github.com/dotnet/runtime/issues/615 - - https://github.com/dotnet/runtime/issues/37579 - https://github.com/dotnet/runtime/issues/34316 From 564426051c8ec46051ee29048650cdae39c62d48 Mon Sep 17 00:00:00 2001 From: Prashanth Govindarajan Date: Wed, 29 Jul 2020 11:02:03 -0700 Subject: [PATCH 131/755] Narrow four utf16 chars to ascii and write to buffer (#39508) * Shims * shim * Cherry-pick * NarrowFourUtf16CharsToAsciiAndWriteToBuffer * Address comments * Nit --- .../src/System/Text/ASCIIUtility.cs | 10 ++++++++++ .../src/System/Runtime/Intrinsics/Intrinsics.Shims.cs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 7628f6f89b45..76075a5e66dc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -1003,6 +1003,16 @@ private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputB Vector128 vecNarrow = Sse2.PackUnsignedSaturate(vecWide, vecWide).AsUInt32(); Unsafe.WriteUnaligned(ref outputBuffer, Sse2.ConvertToUInt32(vecNarrow)); } + else if (AdvSimd.IsSupported) + { + // Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes + // [ b0 b1 b2 b3 * * * * ], then writes 4 bytes (32 bits) to the destination. + + Vector128 vecWide = Vector128.CreateScalarUnsafe(value).AsInt16(); + Vector64 lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(vecWide); + Unsafe.WriteUnaligned(ref outputBuffer, lower.AsUInt32().ToScalar()); + } + else { if (BitConverter.IsLittleEndian) 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 fa4602b33f42..ff020e0259cf 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 @@ -9,6 +9,8 @@ internal static class Vector64 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(); + public static Vector64 GetLower(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException(); + public static Vector64 AsUInt64(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException(); } internal readonly struct Vector64 where T : struct @@ -21,6 +23,8 @@ internal static class Vector128 public static Vector128 Create(short value) => throw new PlatformNotSupportedException(); public static Vector128 Create(ulong value) => throw new PlatformNotSupportedException(); public static Vector128 Create(ushort value) => throw new PlatformNotSupportedException(); + public static Vector128 Create(byte value) => throw new PlatformNotSupportedException(); + public static Vector128 Create(uint value) => throw new PlatformNotSupportedException(); public static Vector128 CreateScalarUnsafe(ulong value) => throw new PlatformNotSupportedException(); public static Vector128 AsByte(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException(); public static Vector128 AsInt16(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException(); From b262f0bd2e57c528241609aa47bc4eb99a865336 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Wed, 29 Jul 2020 14:50:59 -0400 Subject: [PATCH 132/755] Add config var to allow disabling automatic CPU group assignment for threads (#38568) - When CPU groups are enabled through config, some new threads (Thread.Start, thread pool threads) are automatically assigned to a CPU group, starting with the process' CPU group and once it is filled up, assigning new threads to a different CPU group. An app may have native components that also use threads, and may want to do its own thread-spreading (for instance in DllMain), this config allows such apps to disable the automatic CPU group assignment which would otherwise override an assignment made in DllMain. The new config var does not affect GC threads. - This was requested for .NET Framework, porting to .NET Core as well --- src/coreclr/src/inc/clrconfigvalues.h | 3 ++- src/coreclr/src/inc/utilcode.h | 2 ++ src/coreclr/src/utilcode/util.cpp | 25 +++++++++++++++++-------- src/coreclr/src/vm/threads.cpp | 20 ++++++++++++++------ 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index ddb1db3ce647..48f9ce51fe2a 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -553,6 +553,8 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSusp RETAIL_CONFIG_DWORD_INFO(INTERNAL_DefaultStackSize, W("DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).") RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger, W("Thread_DeadThreadCountThresholdForGCTrigger"), 75, "In the heuristics to clean up dead threads, this threshold must be reached before triggering a GC will be considered. Set to 0 to disable triggering a GC based on dead threads.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds, W("Thread_DeadThreadGCTriggerPeriodMilliseconds"), 1000 * 60 * 30, "In the heuristics to clean up dead threads, this much time must have elapsed since the previous max-generation GC before triggering another GC will be considered") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies whether to query and use CPU group information for determining the processor count.") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_AssignCpuGroups, W("Thread_AssignCpuGroups"), 1, "Specifies whether to automatically distribute threads created by the CLR across CPU Groups. Effective only when Thread_UseAllCpuGroups and GCCpuGroup are enabled.") /// /// Threadpool @@ -568,7 +570,6 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("Thread #else // !TARGET_ARM64 RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("ThreadPool_UnfairSemaphoreSpinLimit"), 0x46, "Maximum number of spins a thread pool worker thread performs before waiting for work") #endif // TARGET_ARM64 -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies if to automatically distribute thread across CPU Groups") CONFIG_DWORD_INFO(INTERNAL_ThreadpoolTickCountAdjustment, W("ThreadpoolTickCountAdjustment"), 0, "") diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index f411acb7e66a..bc3fb9377e29 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -1272,6 +1272,7 @@ class CPUGroupInfo static WORD m_nProcessors; static BOOL m_enableGCCPUGroups; static BOOL m_threadUseAllCpuGroups; + static BOOL m_threadAssignCpuGroups; static WORD m_initialGroup; static CPU_Group_Info *m_CPUGroupInfoArray; static bool s_hadSingleProcessorAtStartup; @@ -1285,6 +1286,7 @@ class CPUGroupInfo static void EnsureInitialized(); static BOOL CanEnableGCCPUGroups(); static BOOL CanEnableThreadUseAllCpuGroups(); + static BOOL CanAssignCpuGroupsToThreads(); static WORD GetNumActiveProcessors(); static void GetGroupForProcessor(WORD processor_number, WORD *group_number, WORD *group_processor_number); diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp index d697946beb8f..ef35f09b1772 100644 --- a/src/coreclr/src/utilcode/util.cpp +++ b/src/coreclr/src/utilcode/util.cpp @@ -850,6 +850,7 @@ BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr, /*static*/ BOOL CPUGroupInfo::m_enableGCCPUGroups = FALSE; /*static*/ BOOL CPUGroupInfo::m_threadUseAllCpuGroups = FALSE; +/*static*/ BOOL CPUGroupInfo::m_threadAssignCpuGroups = FALSE; /*static*/ WORD CPUGroupInfo::m_nGroups = 0; /*static*/ WORD CPUGroupInfo::m_nProcessors = 0; /*static*/ WORD CPUGroupInfo::m_initialGroup = 0; @@ -991,6 +992,7 @@ DWORD LCM(DWORD u, DWORD v) #if !defined(FEATURE_REDHAWK) && (defined(TARGET_AMD64) || defined(TARGET_ARM64)) BOOL enableGCCPUGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_GCCpuGroup) != 0; BOOL threadUseAllCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_UseAllCpuGroups) != 0; + BOOL threadAssignCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_AssignCpuGroups) != 0; if (!enableGCCPUGroups) return; @@ -1006,10 +1008,11 @@ DWORD LCM(DWORD u, DWORD v) CPUGroupInfo::GetThreadGroupAffinity(GetCurrentThread(), &groupAffinity); m_initialGroup = groupAffinity.Group; - // only enable CPU groups if more than one group exists - BOOL hasMultipleGroups = m_nGroups > 1; - m_enableGCCPUGroups = enableGCCPUGroups && hasMultipleGroups; - m_threadUseAllCpuGroups = threadUseAllCpuGroups && hasMultipleGroups; + // only enable CPU groups if more than one group exists + BOOL hasMultipleGroups = m_nGroups > 1; + m_enableGCCPUGroups = enableGCCPUGroups && hasMultipleGroups; + m_threadUseAllCpuGroups = threadUseAllCpuGroups && hasMultipleGroups; + m_threadAssignCpuGroups = threadAssignCpuGroups && hasMultipleGroups; #endif // TARGET_AMD64 || TARGET_ARM64 // Determine if the process is affinitized to a single processor (or if the system has a single processor) @@ -1164,8 +1167,8 @@ DWORD LCM(DWORD u, DWORD v) WORD i, minGroup = 0; DWORD minWeight = 0; - // m_enableGCCPUGroups and m_threadUseAllCpuGroups must be TRUE - _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups); + // m_enableGCCPUGroups, m_threadUseAllCpuGroups, and m_threadAssignCpuGroups must be TRUE + _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups && m_threadAssignCpuGroups); for (i = 0; i < m_nGroups; i++) { @@ -1204,8 +1207,8 @@ DWORD LCM(DWORD u, DWORD v) { LIMITED_METHOD_CONTRACT; #if (defined(TARGET_AMD64) || defined(TARGET_ARM64)) - // m_enableGCCPUGroups and m_threadUseAllCpuGroups must be TRUE - _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups); + // m_enableGCCPUGroups, m_threadUseAllCpuGroups, and m_threadAssignCpuGroups must be TRUE + _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups && m_threadAssignCpuGroups); WORD group = gf->Group; m_CPUGroupInfoArray[group].activeThreadWeight -= m_CPUGroupInfoArray[group].groupWeight; @@ -1238,6 +1241,12 @@ BOOL CPUGroupInfo::GetCPUGroupRange(WORD group_number, WORD* group_begin, WORD* LIMITED_METHOD_CONTRACT; return m_threadUseAllCpuGroups; } + +/*static*/ BOOL CPUGroupInfo::CanAssignCpuGroupsToThreads() +{ + LIMITED_METHOD_CONTRACT; + return m_threadAssignCpuGroups; +} #endif // HOST_WINDOWS //****************************************************************************** diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 58ff01c6be7e..ab09248fadc0 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -510,10 +510,14 @@ void Thread::ChooseThreadCPUGroupAffinity() GC_TRIGGERS; } CONTRACTL_END; -#ifndef TARGET_UNIX - if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups()) - return; +#ifndef TARGET_UNIX + if (!CPUGroupInfo::CanEnableGCCPUGroups() || + !CPUGroupInfo::CanEnableThreadUseAllCpuGroups() || + !CPUGroupInfo::CanAssignCpuGroupsToThreads()) + { + return; + } //Borrow the ThreadStore Lock here: Lock ThreadStore before distributing threads ThreadStoreLockHolder TSLockHolder(TRUE); @@ -541,10 +545,14 @@ void Thread::ClearThreadCPUGroupAffinity() GC_NOTRIGGER; } CONTRACTL_END; -#ifndef TARGET_UNIX - if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups()) - return; +#ifndef TARGET_UNIX + if (!CPUGroupInfo::CanEnableGCCPUGroups() || + !CPUGroupInfo::CanEnableThreadUseAllCpuGroups() || + !CPUGroupInfo::CanAssignCpuGroupsToThreads()) + { + return; + } ThreadStoreLockHolder TSLockHolder(TRUE); From 357fdff5398db486eaa6015ca83b5fc0bf8567f0 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 29 Jul 2020 21:12:17 +0200 Subject: [PATCH 133/755] Fix TestUtilities IsTestProject being set to true inside VS (#40089) --- src/libraries/Common/tests/TestUtilities/TestUtilities.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index 8b6dd4699023..564607865138 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -1,6 +1,8 @@ true + + false + 1 $HELIX_DUMP_FOLDER/coredump.%d.dmp diff --git a/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs b/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs index 0d9c4ab88985..e2d08676ec59 100644 --- a/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs +++ b/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs @@ -205,7 +205,6 @@ public class CoreclrTestWrapperLib static bool CollectCrashDump(Process process, string path) { - ProcessStartInfo createdumpInfo = null; string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT"); string createdumpPath = Path.Combine(coreRoot, "createdump"); string arguments = $"--name \"{path}\" {process.Id} --withheap"; @@ -220,6 +219,7 @@ static bool CollectCrashDump(Process process, string path) { createdump.StartInfo.FileName = "sudo"; createdump.StartInfo.Arguments = $"{createdumpPath} " + arguments; + createdump.StartInfo.EnvironmentVariables.Add("COMPlus_DbgEnableElfDumpOnMacOS", "1"); } createdump.StartInfo.UseShellExecute = false; From 90f0c9322778fffc06545dd0b3d5afee6e7db98e Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 29 Jul 2020 23:39:02 +0200 Subject: [PATCH 138/755] Fix CoreLib build when building libraries solutions (#40097) If a project that is part of solution has a ProjectReference to CoreLib, the Platform property was set to AnyCPU and CoreLib was built with the wrong Platform/Platform_Target. --- src/libraries/Directory.Build.targets | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 95dae2669d8e..cc196f26392a 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -176,7 +176,8 @@ true - $(UndefineProperties);TargetFramework + + $(UndefineProperties);TargetFramework;Platform Configuration=$(CoreCLRConfiguration) rax); + // The lower two bits are used to indicate whether struct args are floating point or integer + if (flags & 1) + { + pData->buffer[0] = pData->flt0; + pData->buffer[1] = (flags & 2) ? pData->flt1 : pData->rax; + } + else + { + pData->buffer[0] = pData->rax; + pData->buffer[1] = (flags & 2) ? pData->flt0 : pData->rdx; + } + + return pData->buffer; } - else - return NULL; +#endif // UNIX_AMD64_ABI + + if (ELEMENT_TYPE_R4 == t || ELEMENT_TYPE_R8 == t) + { + pData->rax = pData->flt0; + } + + return &(pData->rax); } #undef PROFILE_ENTER diff --git a/src/coreclr/src/vm/arm/asmhelpers.S b/src/coreclr/src/vm/arm/asmhelpers.S index dbc7baa9a175..dcdfda4df350 100644 --- a/src/coreclr/src/vm/arm/asmhelpers.S +++ b/src/coreclr/src/vm/arm/asmhelpers.S @@ -366,134 +366,87 @@ LEAF_ENTRY JIT_ProfilerEnterLeaveTailcallStub, _TEXT bx lr LEAF_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT -// -// EXTERN_C void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID); -// -NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler - PROLOG_PUSH "{r4, r5, r7, r11, lr}" - PROLOG_STACK_SAVE_OFFSET r7, #8 - - // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order - - // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier - // UINT32 r1; - // void *r11; - // void *Pc; - // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7) - // { - // UINT32 s[16]; - // UINT64 d[8]; - // }; - // FunctionID functionId; - // void *probeSp; // stack pointer of managed function - // void *profiledSp; // location of arguments on stack - // LPVOID hiddenArg; - // UINT32 flags; - movw r4, #1 - push { /* flags */ r4 } - movw r4, #0 - push { /* hiddenArg */ r4 } - add r5, r11, #8 - push { /* profiledSp */ r5 } - add r5, sp, #32 - push { /* probeSp */ r5 } - push { /* functionId */ r0 } +#define PROFILE_ENTER 1 +#define PROFILE_LEAVE 2 +#define PROFILE_TAILCALL 4 +// size of profiler data structure plus alignment padding +#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 104+4 + +// typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA +// { +// UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier +// UINT32 r1; +// void *R11; +// void *Pc; +// union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7) +// { +// UINT32 s[16]; +// UINT64 d[8]; +// }; +// FunctionID functionId; +// void *probeSp; // stack pointer of managed function +// void *profiledSp; // location of arguments on stack +// LPVOID hiddenArg; +// UINT32 flags; +// } PROFILE_PLATFORM_SPECIFIC_DATA, *PPROFILE_PLATFORM_SPECIFIC_DATA; + +.macro GenerateProfileHelper helper, flags +NESTED_ENTRY \helper\()Naked, _TEXT, NoHandler + PROLOG_PUSH "{r0,r3,r9,r12}" + + // for the 5 arguments that do not need popped plus 4 bytes of alignment + alloc_stack 6*4 + + // push fp regs vpush.64 { d0 - d7 } - push { lr } - push { r11 } - push { /* return value, r4 is NULL */ r4 } - push { /* return value, r4 is NULL */ r4 } - mov r1, sp - bl C_FUNC(ProfileEnter) - EPILOG_STACK_RESTORE_OFFSET r7, #8 - EPILOG_POP "{r4, r5, r7, r11, pc}" -NESTED_END ProfileEnterNaked, _TEXT -// -// EXTERN_C void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID); -// -NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler - PROLOG_PUSH "{r1, r2, r4, r5, r7, r11, lr}" - PROLOG_STACK_SAVE_OFFSET r7, #16 - - // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order - - // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier - // UINT32 r1; - // void *r11; - // void *Pc; - // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7) - // { - // UINT32 s[16]; - // UINT64 d[8]; - // }; - // FunctionID functionId; - // void *probeSp; // stack pointer of managed function - // void *profiledSp; // location of arguments on stack - // LPVOID hiddenArg; - // UINT32 flags; - movw r4, #2 - push { /* flags */ r4 } - movw r4, #0 - push { /* hiddenArg */ r4 } - add r5, r11, #8 - push { /* profiledSp */ r5 } - add r5, sp, #40 - push { /* probeSp */ r5 } - push { /* functionId */ r0 } - vpush.64 { d0 - d7 } - push { lr } - push { r11 } - push { r1 } - push { r0 } - mov r1, sp - bl C_FUNC(ProfileLeave) - EPILOG_STACK_RESTORE_OFFSET r7, #16 - EPILOG_POP "{r1, r2, r4, r5, r7, r11, pc}" -NESTED_END ProfileLeaveNaked, _TEXT + // next three fields pc, r11, r1 + push { r1, r11, lr} -// -// EXTERN_C void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID); -// -NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler - PROLOG_PUSH "{r1, r2, r4, r5, r7, r11, lr}" - PROLOG_STACK_SAVE_OFFSET r7, #16 - - // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order - - // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier - // UINT32 r1; - // void *r11; - // void *Pc; - // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7) - // { - // UINT32 s[16]; - // UINT64 d[8]; - // }; - // FunctionID functionId; - // void *probeSp; // stack pointer of managed function - // void *profiledSp; // location of arguments on stack - // LPVOID hiddenArg; - // UINT32 flags; - movw r4, #2 - push { /* flags */ r4 } - movw r4, #0 - push { /* hiddenArg */ r4 } - add r5, r11, #8 - push { /* profiledSp */ r5 } - add r5, sp, #40 - push { /* probeSp */ r5 } - push { /* functionId */ r0 } - vpush.64 { d0 - d7 } - push { lr } - push { r11 } - push { r1 } - push { r0 } + // return value is in r2 instead of r0 because functionID is passed in r0 + push { r2 } + + CHECK_STACK_ALIGNMENT + + // set the other args, starting with functionID + str r0, [sp, #80] + + // probeSp is the original sp when this stub was called + add r2, sp, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA+20 + str r2, [sp, #84] + + // get the address of the arguments from the frame pointer, store in profiledSp + add r2, r11, #8 + str r2, [sp, #88] + + // clear hiddenArg + movw r2, #0 + str r2, [sp, #92] + + // set the flag to indicate what hook this is + movw r2, \flags + str r2, [sp, #96] + + // sp is the address of PROFILE_PLATFORM_SPECIFIC_DATA, then call to C++ mov r1, sp - bl C_FUNC(ProfileTailcall) - EPILOG_STACK_RESTORE_OFFSET r7, #16 - EPILOG_POP "{r1, r2, r4, r5, r7, r11, pc}" -NESTED_END ProfileTailcallNaked, _TEXT + bl C_FUNC(\helper) + + // restore all our regs + pop { r2 } + pop { r1, r11, lr} + vpop.64 { d0 - d7 } + + free_stack 6*4 + + EPILOG_POP "{r0,r3,r9,r12}" + + bx lr +NESTED_END \helper\()Naked, _TEXT +.endm + +GenerateProfileHelper ProfileEnter, PROFILE_ENTER +GenerateProfileHelper ProfileLeave, PROFILE_LEAVE +GenerateProfileHelper ProfileTailcall, PROFILE_TAILCALL #endif diff --git a/src/coreclr/src/vm/arm/profiler.cpp b/src/coreclr/src/vm/arm/profiler.cpp index 8bcd075fe986..670dedb8ca8c 100644 --- a/src/coreclr/src/vm/arm/profiler.cpp +++ b/src/coreclr/src/vm/arm/profiler.cpp @@ -144,7 +144,7 @@ Stack for the above call will look as follows (stack growing downwards): Thread::VirtualUnwindCallFrame(&ctx); // add the prespill register(r0-r3) size to get the stack pointer of previous function - _ASSERTE(pData->profiledSp == (void*)(ctx.Sp - 4*4)); + _ASSERTE(pData->profiledSp == (void*)(ctx.Sp - 4*4) || pData->profiledSp == (void*)(ctx.Sp - 6*4)); } #endif // _DEBUG diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S index 9ff8203f22f4..a8b0a7c07873 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.S +++ b/src/coreclr/src/vm/arm64/asmhelpers.S @@ -1200,7 +1200,7 @@ LEAF_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT #define PROFILE_ENTER 1 #define PROFILE_LEAVE 2 #define PROFILE_TAILCALL 4 -#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 256 +#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 272 // ------------------------------------------------------------------ .macro GenerateProfileHelper helper, flags diff --git a/src/coreclr/src/vm/arm64/asmhelpers.asm b/src/coreclr/src/vm/arm64/asmhelpers.asm index 1250bd326520..2f9227b1d80d 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.asm +++ b/src/coreclr/src/vm/arm64/asmhelpers.asm @@ -1427,7 +1427,7 @@ CallHelper2 #define PROFILE_ENTER 1 #define PROFILE_LEAVE 2 #define PROFILE_TAILCALL 4 - #define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 256 + #define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 272 ; ------------------------------------------------------------------ MACRO diff --git a/src/coreclr/src/vm/arm64/profiler.cpp b/src/coreclr/src/vm/arm64/profiler.cpp index 64bd9603c877..ba35eb103eec 100644 --- a/src/coreclr/src/vm/arm64/profiler.cpp +++ b/src/coreclr/src/vm/arm64/profiler.cpp @@ -10,6 +10,9 @@ #define PROFILE_LEAVE 2 #define PROFILE_TAILCALL 4 +// Scratch space to store HFA return values (max 16 bytes) +#define PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE 16 + typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA { void* Fp; @@ -23,6 +26,7 @@ typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA void* hiddenArg; UINT32 flags; UINT32 unused; + BYTE buffer[PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE]; } PROFILE_PLATFORM_SPECIFIC_DATA, *PPROFILE_PLATFORM_SPECIFIC_DATA; UINT_PTR ProfileGetIPFromPlatformSpecificHandle(void* pPlatformSpecificHandle) @@ -45,7 +49,8 @@ void ProfileSetFunctionIDInPlatformSpecificHandle(void* pPlatformSpecificHandle, } ProfileArgIterator::ProfileArgIterator(MetaSig* pSig, void* pPlatformSpecificHandle) - : m_argIterator(pSig) + : m_argIterator(pSig), + m_bufferPos(0) { WRAPPER_NO_CONTRACT; @@ -235,8 +240,44 @@ LPVOID ProfileArgIterator::GetReturnBufferAddr(void) } } - if (m_argIterator.GetFPReturnSize() != 0) - { + UINT fpReturnSize = m_argIterator.GetFPReturnSize(); + if (fpReturnSize != 0) + { + TypeHandle thReturnValueType; + m_argIterator.GetSig()->GetReturnTypeNormalized(&thReturnValueType); + if (!thReturnValueType.IsNull() && thReturnValueType.IsHFA()) + { + UINT hfaFieldSize = fpReturnSize / 4; + UINT totalSize = m_argIterator.GetSig()->GetReturnTypeSize(); + _ASSERTE(totalSize % hfaFieldSize == 0); + _ASSERTE(totalSize <= 16); + + BYTE *dest = pData->buffer; + for (UINT floatRegIdx = 0; floatRegIdx < totalSize / hfaFieldSize; ++floatRegIdx) + { + if (hfaFieldSize == 4) + { + *(UINT32*)dest = *(UINT32*)&pData->floatArgumentRegisters.q[floatRegIdx]; + dest += 4; + } + else + { + _ASSERTE(hfaFieldSize == 8); + *(UINT64*)dest = *(UINT64*)&pData->floatArgumentRegisters.q[floatRegIdx]; + dest += 8; + } + + if (floatRegIdx > 8) + { + // There's only space for 8 arguments in buffer + _ASSERTE(FALSE); + break; + } + } + + return pData->buffer; + } + return &pData->floatArgumentRegisters.q[0]; } diff --git a/src/coreclr/src/vm/proftoeeinterfaceimpl.h b/src/coreclr/src/vm/proftoeeinterfaceimpl.h index 2fbfb8e80376..de5b75a3434d 100644 --- a/src/coreclr/src/vm/proftoeeinterfaceimpl.h +++ b/src/coreclr/src/vm/proftoeeinterfaceimpl.h @@ -56,9 +56,9 @@ class ProfileArgIterator private: void *m_handle; ArgIterator m_argIterator; -#ifdef UNIX_AMD64_ABI +#if defined(UNIX_AMD64_ABI) || defined(TARGET_ARM64) UINT64 m_bufferPos; -#endif // UNIX_AMD64_ABI +#endif // defined(UNIX_AMD64_ABI) || defined(TARGET_ARM64) public: ProfileArgIterator(MetaSig * pMetaSig, void* platformSpecificHandle); @@ -74,9 +74,12 @@ class ProfileArgIterator return m_argIterator.NumFixedArgs(); } -#ifdef UNIX_AMD64_ABI +#if defined(UNIX_AMD64_ABI) + // On certain architectures we can pass args in non-sequential registers, + // this function will copy the struct so it is laid out as it would be in memory + // so it can be passed to the profiler LPVOID CopyStructFromRegisters(); -#endif // UNIX_AMD64_ABI +#endif // defined(UNIX_AMD64_ABI) // // After initialization, this method is called repeatedly until it diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index dc65eef1590d..e21987966398 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1640,6 +1640,12 @@ needs triage + + needs triage + + + needs triage + needs triage diff --git a/src/tests/profiler/common/ProfilerTestRunner.cs b/src/tests/profiler/common/ProfilerTestRunner.cs index 4600f1f1f2d7..bb5bae9d9092 100644 --- a/src/tests/profiler/common/ProfilerTestRunner.cs +++ b/src/tests/profiler/common/ProfilerTestRunner.cs @@ -33,10 +33,11 @@ public static int Run(string profileePath, arguments = profileePath + " RunTest " + profileeArguments; program = GetCorerunPath(); + string profilerPath = GetProfilerPath(); if (!profileeOptions.HasFlag(ProfileeOptions.NoStartupAttach)) { envVars.Add("CORECLR_ENABLE_PROFILING", "1"); - envVars.Add("CORECLR_PROFILER_PATH", GetProfilerPath()); + envVars.Add("CORECLR_PROFILER_PATH", profilerPath); envVars.Add("CORECLR_PROFILER", "{" + profilerClsid + "}"); } @@ -48,7 +49,8 @@ public static int Run(string profileePath, envVars.Add("COMPlus_JITMinOpts", "0"); } - string profilerPath = GetProfilerPath(); + envVars.Add("Profiler_Test_Name", testName); + if(!File.Exists(profilerPath)) { LogTestFailure("Profiler library not found at expected path: " + profilerPath); diff --git a/src/tests/profiler/elt/slowpathcommon.cs b/src/tests/profiler/elt/slowpathcommon.cs new file mode 100644 index 000000000000..eab383d0ff00 --- /dev/null +++ b/src/tests/profiler/elt/slowpathcommon.cs @@ -0,0 +1,169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace SlowPathELTTests +{ + [StructLayout(LayoutKind.Sequential)] + public struct IntegerStruct + { + public int x; + public int y; + + public IntegerStruct(int x, int y) + { + this.x = x; + this.y = y; + } + + public override String ToString() + { + return $"x={x} y={y}"; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct FloatingPointStruct + { + public double d1; + public double d2; + + public FloatingPointStruct(double d1, double d2) + { + this.d1 = d1; + this.d2 = d2; + } + + public override String ToString() + { + return $"d1={d1} d2={d2}"; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct MixedStruct + { + public int x; + public double d; + + public MixedStruct(int x, double d) + { + this.x = x; + this.d = d; + } + + public override String ToString() + { + return $"x={x} d={d}"; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct LargeStruct + { + public int x0; + public double d0; + public int x1; + public double d1; + public int x2; + public double d2; + public int x3; + public double d3; + + public LargeStruct(int x0, + double d0, + int x1, + double d1, + int x2, + double d2, + int x3, + double d3) + { + this. x0 = x0; + this.d0 = d0; + this.x1 = x1; + this.d1 = d1; + this.x2 = x2; + this.d2 = d2; + this.x3 = x3; + this.d3 = d3; + } + + public override String ToString() + { + return $"x0={x0} d0={d0} x1={x1} d1={d1} x2={x2} d2={d2} x3={x3} d3={d3}"; + } + } + + public class SlowPathELTHelpers + { + public static int RunTest() + { + Console.WriteLine($"SimpleArgsFunc returned {SimpleArgsFunc(-123, -4.3f, "Hello, test!")}"); + + Console.WriteLine($"MixedStructFunc returned {MixedStructFunc(new MixedStruct(1, 1))}"); + + Console.WriteLine($"LargeStructFunc returned {LargeStructFunc(new LargeStruct(0, 0, 1, 1, 2, 2, 3, 3))}"); + + Console.WriteLine($"IntegerStructFunc returned {IntegerStructFunc(new IntegerStruct(14, 256))}"); + + Console.WriteLine($"FloatingPointStructFunc returned {FloatingPointStructFunc(new FloatingPointStruct(13.0, 145.2))}"); + + Console.WriteLine($"DoubleRetFunc returned {DoubleRetFunc()}"); + + return 100; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static string SimpleArgsFunc(int x, float y, String str) + { + Console.WriteLine($"x={x} y={y} str={str}"); + return "Hello from SimpleArgsFunc!"; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static MixedStruct MixedStructFunc(MixedStruct ss) + { + Console.WriteLine($"ss={ss}"); + ss.x = 4; + return ss; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static int LargeStructFunc(LargeStruct ls) + { + Console.WriteLine($"ls={ls}"); + return 3; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static IntegerStruct IntegerStructFunc(IntegerStruct its) + { + its.x = 21; + return its; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static FloatingPointStruct FloatingPointStructFunc(FloatingPointStruct fps) + { + fps.d2 = 256.8; + return fps; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static double DoubleRetFunc() + { + return 13.0; + } + } +} diff --git a/src/tests/profiler/elt/slowpathcommon.csproj b/src/tests/profiler/elt/slowpathcommon.csproj new file mode 100644 index 000000000000..869ebc2c1fab --- /dev/null +++ b/src/tests/profiler/elt/slowpathcommon.csproj @@ -0,0 +1,11 @@ + + + Library + BuildOnly + true + 0 + + + + + diff --git a/src/tests/profiler/elt/slowpatheltenter.cs b/src/tests/profiler/elt/slowpatheltenter.cs new file mode 100644 index 000000000000..83d6bb56e6e6 --- /dev/null +++ b/src/tests/profiler/elt/slowpatheltenter.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Profiler.Tests; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace SlowPathELTTests +{ + class SlowPathELTEnter + { + static readonly Guid EventPipeWritingProfilerGuid = new Guid("0B36296B-EC47-44DA-8320-DC5E3071DD06"); + + public static int Main(string[] args) + { + if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) + { + return SlowPathELTHelpers.RunTest(); + } + + return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, + testName: "ELTSlowPathEnter", + profilerClsid: EventPipeWritingProfilerGuid); + } + } +} diff --git a/src/tests/profiler/elt/slowpatheltenter.csproj b/src/tests/profiler/elt/slowpatheltenter.csproj new file mode 100644 index 000000000000..8d2ac3058e83 --- /dev/null +++ b/src/tests/profiler/elt/slowpatheltenter.csproj @@ -0,0 +1,17 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + + + + + + + + + diff --git a/src/tests/profiler/elt/slowpatheltleave.cs b/src/tests/profiler/elt/slowpatheltleave.cs new file mode 100644 index 000000000000..da8fd03ec386 --- /dev/null +++ b/src/tests/profiler/elt/slowpatheltleave.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Profiler.Tests; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace SlowPathELTTests +{ + class SlowPathELTLeave + { + static readonly Guid EventPipeWritingProfilerGuid = new Guid("0B36296B-EC47-44DA-8320-DC5E3071DD06"); + + public static int Main(string[] args) + { + if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) + { + return SlowPathELTHelpers.RunTest(); + } + + return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, + testName: "ELTSlowPathLeave", + profilerClsid: EventPipeWritingProfilerGuid); + } + } +} diff --git a/src/tests/profiler/elt/slowpatheltleave.csproj b/src/tests/profiler/elt/slowpatheltleave.csproj new file mode 100644 index 000000000000..8d2ac3058e83 --- /dev/null +++ b/src/tests/profiler/elt/slowpatheltleave.csproj @@ -0,0 +1,17 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + + + + + + + + + diff --git a/src/tests/profiler/native/CMakeLists.txt b/src/tests/profiler/native/CMakeLists.txt index 3af1b28a4fbf..a742c928bfc3 100644 --- a/src/tests/profiler/native/CMakeLists.txt +++ b/src/tests/profiler/native/CMakeLists.txt @@ -10,8 +10,16 @@ set(EVENTPIPE_SOURCES eventpipeprofiler/eventpipemetadatareader.cpp) set(METADATAGETDISPENSER_SOURCES metadatagetdispenser/metadatagetdispenser.cpp) set(GETAPPDOMAINSTATICADDRESS_SOURCES getappdomainstaticaddress/getappdomainstaticaddress.cpp) - -set(SOURCES ${GCBASIC_SOURCES} ${REJIT_SOURCES} ${EVENTPIPE_SOURCES} ${METADATAGETDISPENSER_SOURCES} ${GETAPPDOMAINSTATICADDRESS_SOURCES} profiler.def profiler.cpp classfactory.cpp dllmain.cpp guids.cpp) +set(ELT_SOURCES eltprofiler/slowpatheltprofiler.cpp) + +set(SOURCES + ${GCBASIC_SOURCES} + ${REJIT_SOURCES} + ${EVENTPIPE_SOURCES} + ${METADATAGETDISPENSER_SOURCES} + ${GETAPPDOMAINSTATICADDRESS_SOURCES} + ${ELT_SOURCES} + profiler.def profiler.cpp classfactory.cpp dllmain.cpp guids.cpp) include_directories(../../../coreclr/src/pal/prebuilt/inc) diff --git a/src/tests/profiler/native/classfactory.cpp b/src/tests/profiler/native/classfactory.cpp index dc5cc2feea02..301e91dde442 100644 --- a/src/tests/profiler/native/classfactory.cpp +++ b/src/tests/profiler/native/classfactory.cpp @@ -8,6 +8,7 @@ #include "eventpipeprofiler/eventpipewritingprofiler.h" #include "metadatagetdispenser/metadatagetdispenser.h" #include "getappdomainstaticaddress/getappdomainstaticaddress.h" +#include "eltprofiler/slowpatheltprofiler.h" ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid) { @@ -61,7 +62,8 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI new EventPipeReadingProfiler(), new EventPipeWritingProfiler(), new MetaDataGetDispenser(), - new GetAppDomainStaticAddress() + new GetAppDomainStaticAddress(), + new SlowPathELTProfiler() // add new profilers here }; diff --git a/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.cpp b/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.cpp new file mode 100644 index 000000000000..8f858cdb0899 --- /dev/null +++ b/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.cpp @@ -0,0 +1,499 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#define NOMINMAX + +#include "slowpatheltprofiler.h" +#include +#include +#include +#include + +using std::shared_ptr; +using std::vector; +using std::wcout; +using std::endl; + +shared_ptr SlowPathELTProfiler::s_profiler; + +#ifndef WIN32 +#define UINT_PTR_FORMAT "lx" +#define PROFILER_STUB EXTERN_C __attribute__((visibility("hidden"))) void STDMETHODCALLTYPE +#else // WIN32 +#define UINT_PTR_FORMAT "llx" +#define PROFILER_STUB EXTERN_C void STDMETHODCALLTYPE +#endif // WIN32 + +PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo) +{ + SlowPathELTProfiler::s_profiler->EnterCallback(functionId, eltInfo); +} + +PROFILER_STUB LeaveStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo) +{ + SlowPathELTProfiler::s_profiler->LeaveCallback(functionId, eltInfo); +} + +PROFILER_STUB TailcallStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo) +{ + SlowPathELTProfiler::s_profiler->TailcallCallback(functionId, eltInfo); +} + +GUID SlowPathELTProfiler::GetClsid() +{ + // {0B36296B-EC47-44DA-8320-DC5E3071DD06} + GUID clsid = { 0x0B36296B, 0xEC47, 0x44DA, { 0x83, 0x20, 0xDC, 0x5E, 0x30, 0x71, 0xDD, 0x06 } }; + return clsid; +} + +HRESULT SlowPathELTProfiler::Initialize(IUnknown* pICorProfilerInfoUnk) +{ + Profiler::Initialize(pICorProfilerInfoUnk); + + HRESULT hr = S_OK; + constexpr ULONG bufferSize = 1024; + ULONG envVarLen = 0; + WCHAR envVar[bufferSize]; + if (FAILED(hr = pCorProfilerInfo->GetEnvironmentVariable(WCHAR("Profiler_Test_Name"), + bufferSize, + &envVarLen, + envVar))) + { + wcout << L"Failed to get test name hr=" << std::hex << hr << endl; + _failures++; + return hr; + } + + size_t nullCharPos = std::min(bufferSize - 1, envVarLen); + envVar[nullCharPos] = 0; + if (wcscmp(envVar, WCHAR("ELTSlowPathEnter")) == 0) + { + wcout << L"Testing enter hooks" << endl; + _testType = TestType::EnterHooks; + } + else if (wcscmp(envVar, WCHAR("ELTSlowPathLeave")) == 0) + { + wcout << L"Testing leave hooks" << endl; + _testType = TestType::LeaveHooks; + } + else + { + wcout << L"Unknown test type" << endl; + _failures++; + return E_FAIL; + } + + SlowPathELTProfiler::s_profiler = shared_ptr(this); + + if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_ENTERLEAVE + | COR_PRF_ENABLE_FUNCTION_ARGS + | COR_PRF_ENABLE_FUNCTION_RETVAL + | COR_PRF_ENABLE_FRAME_INFO, + 0))) + { + wcout << L"FAIL: IpCorProfilerInfo::SetEventMask2() failed hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + + hr = this->pCorProfilerInfo->SetEnterLeaveFunctionHooks3WithInfo(EnterStub, LeaveStub, TailcallStub); + if (hr != S_OK) + { + wcout << L"SetEnterLeaveFunctionHooks3WithInfo failed with hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + + return S_OK; +} + +HRESULT SlowPathELTProfiler::Shutdown() +{ + Profiler::Shutdown(); + + if (_testType == TestType::EnterHooks) + { + if (_failures == 0 + && _testType == TestType::EnterHooks + && _sawSimpleFuncEnter + && _sawMixedStructFuncEnter + && _sawLargeStructFuncEnter) + { + wcout << L"PROFILER TEST PASSES" << endl; + } + else + { + wcout << L"TEST FAILED _failures=" << _failures.load() << L", _sawSimpleFuncEnter=" << _sawSimpleFuncEnter + << L", _sawMixedStructFuncEnter=" << _sawMixedStructFuncEnter << L", _sawLargeStructFuncEnter=" + << _sawLargeStructFuncEnter << endl; + } + } + else if (_testType == TestType::LeaveHooks) + { + if (_failures == 0 + && _testType == TestType::LeaveHooks + && _sawSimpleFuncLeave + && _sawMixedStructFuncLeave + && _sawLargeStructFuncLeave + && _sawIntegerStructFuncLeave + && _sawFloatingPointStructFuncLeave + && _sawDoubleRetFuncLeave) + { + wcout << L"PROFILER TEST PASSES" << endl; + } + else + { + wcout << L"TEST FAILED _failures=" << _failures.load() << L", _sawSimpleFuncLeave=" << _sawSimpleFuncLeave + << L", _sawMixedStructFuncLeave=" << _sawMixedStructFuncLeave << L", _sawLargeStructFuncLeave=" + << _sawLargeStructFuncLeave << L"_sawIntegerStructFuncLeave=" << _sawIntegerStructFuncLeave + << L"_sawFloatingPointStructFuncLeave=" << _sawFloatingPointStructFuncLeave + << L"_sawDoubleRetFuncLeave=" << _sawDoubleRetFuncLeave << endl; + } + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE SlowPathELTProfiler::EnterCallback(FunctionIDOrClientID functionIdOrClientID, COR_PRF_ELT_INFO eltInfo) +{ + if (_testType != TestType::EnterHooks) + { + return S_OK; + } + + COR_PRF_FRAME_INFO frameInfo; + ULONG pcbArgumentInfo = 0; + NewArrayHolder pArgumentInfoBytes; + COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo = NULL; + + HRESULT hr = pCorProfilerInfo->GetFunctionEnter3Info(functionIdOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, NULL); + if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) + { + wcout << L"GetFunctionEnter3Info 1 failed with hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + else if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) + { + pArgumentInfoBytes = new BYTE[pcbArgumentInfo]; + pArgumentInfo = reinterpret_cast((BYTE *)pArgumentInfoBytes); + hr = pCorProfilerInfo->GetFunctionEnter3Info(functionIdOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, pArgumentInfo); + if(FAILED(hr)) + { + wcout << L"GetFunctionEnter3Info 2 failed with hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + } + + String functionName = GetFunctionIDName(functionIdOrClientID.functionID); + if (functionName == WCHAR("SimpleArgsFunc")) + { + _sawSimpleFuncEnter = true; + + int x = -123; + float f = -4.3f; + const WCHAR *str = WCHAR("Hello, test!"); + + vector expectedValues = { { sizeof(int), (void *)&x, [&](UINT_PTR ptr){ return ValidateInt(ptr, x); } }, + { sizeof(float), (void *)&f, [&](UINT_PTR ptr){ return ValidateFloat(ptr, f); } }, + { sizeof(UINT_PTR), (void *)str, [&](UINT_PTR ptr){ return ValidateString(ptr, str); } } }; + + hr = ValidateFunctionArgs(pArgumentInfo, functionName, expectedValues); + } + else if (functionName == WCHAR("MixedStructFunc")) + { + _sawMixedStructFuncEnter = true; + + // On linux structs can be split with some in int registers and some in float registers + // so a struct with interleaved ints/doubles is interesting. + MixedStruct ss = { 1, 1.0 }; + vector expectedValues = { { sizeof(MixedStruct), (void *)&ss, [&](UINT_PTR ptr){ return ValidateMixedStruct(ptr, ss); } } }; + + hr = ValidateFunctionArgs(pArgumentInfo, functionName, expectedValues); + } + else if (functionName == WCHAR("LargeStructFunc")) + { + _sawLargeStructFuncEnter = true; + + LargeStruct ls = { 0, 0.0, 1, 1.0, 2, 2.0, 3, 3.0 }; + vector expectedValues = { { sizeof(LargeStruct), (void *)&ls, [&](UINT_PTR ptr){ return ValidateLargeStruct(ptr, ls); } } };; + + hr = ValidateFunctionArgs(pArgumentInfo, functionName, expectedValues); + } + + return hr; +} + +HRESULT STDMETHODCALLTYPE SlowPathELTProfiler::LeaveCallback(FunctionIDOrClientID functionIdOrClientID, COR_PRF_ELT_INFO eltInfo) +{ + if (_testType != TestType::LeaveHooks) + { + return S_OK; + } + + COR_PRF_FRAME_INFO frameInfo; + COR_PRF_FUNCTION_ARGUMENT_RANGE * pRetvalRange = new COR_PRF_FUNCTION_ARGUMENT_RANGE; + HRESULT hr = pCorProfilerInfo->GetFunctionLeave3Info(functionIdOrClientID.functionID, eltInfo, &frameInfo, pRetvalRange); + if (FAILED(hr)) + { + wcout << L"GetFunctionLeave3Info failed hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + + String functionName = GetFunctionIDName(functionIdOrClientID.functionID); + if (functionName == WCHAR("SimpleArgsFunc")) + { + _sawSimpleFuncLeave = true; + + const WCHAR *str = WCHAR("Hello from SimpleArgsFunc!"); + + ExpectedArgValue simpleRetValue = { sizeof(UINT_PTR), (void *)str, [&](UINT_PTR ptr){ return ValidateString(ptr, str); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, simpleRetValue); + } + else if (functionName == WCHAR("MixedStructFunc")) + { + _sawMixedStructFuncLeave = true; + + MixedStruct ss = { 4, 1.0 }; + ExpectedArgValue MixedStructRetValue = { sizeof(MixedStruct), (void *)&ss, [&](UINT_PTR ptr){ return ValidateMixedStruct(ptr, ss); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, MixedStructRetValue); + } + else if (functionName == WCHAR("LargeStructFunc")) + { + _sawLargeStructFuncLeave = true; + + int32_t val = 3; + ExpectedArgValue largeStructRetValue = { sizeof(int32_t), (void *)&val, [&](UINT_PTR ptr){ return ValidateInt(ptr, val); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, largeStructRetValue); + } + else if (functionName == WCHAR("IntegerStructFunc")) + { + _sawIntegerStructFuncLeave = true; + + IntegerStruct is = { 21, 256 }; + ExpectedArgValue integerStructRetValue = { sizeof(IntegerStruct), (void *)&is, [&](UINT_PTR ptr){ return ValidateIntegerStruct(ptr, is); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, integerStructRetValue); + } + else if (functionName == WCHAR("FloatingPointStructFunc")) + { + _sawFloatingPointStructFuncLeave = true; + + FloatingPointStruct fps = { 13.0, 256.8 }; + ExpectedArgValue floatingPointStructRetValue = { sizeof(FloatingPointStruct), (void *)&fps, [&](UINT_PTR ptr){ return ValidateFloatingPointStruct(ptr, fps); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, floatingPointStructRetValue); + } + else if (functionName == WCHAR("DoubleRetFunc")) + { + _sawDoubleRetFuncLeave = true; + + double d = 13.0; + ExpectedArgValue doubleRetValue = { sizeof(double), (void *)&d, [&](UINT_PTR ptr){ return ValidateDouble(ptr, d); } }; + hr = ValidateOneArgument(pRetvalRange, functionName, 0, doubleRetValue); + } + + return hr; +} + +HRESULT STDMETHODCALLTYPE SlowPathELTProfiler::TailcallCallback(FunctionIDOrClientID functionIdOrClientID, COR_PRF_ELT_INFO eltInfo) +{ + COR_PRF_FRAME_INFO frameInfo; + HRESULT hr = pCorProfilerInfo->GetFunctionTailcall3Info(functionIdOrClientID.functionID, eltInfo, &frameInfo); + if (FAILED(hr)) + { + wcout << L"GetFunctionTailcall3Info failed hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + + // Tailcalls don't happen on debug builds, and there's no arguments to verify from GetFunctionTailcallinfo3 + + return hr; +} + +void SlowPathELTProfiler::PrintBytes(const BYTE *bytes, size_t length) +{ + for (size_t i = 0; i < length; ++i) + { + wcout << std::setfill(L'0') << std::setw(2) << std::uppercase << std::hex << bytes[i]; + + if (i > 1 && (i + 1) % 4 == 0) + { + wcout << " "; + } + } + + wcout << endl; +} + +bool SlowPathELTProfiler::ValidateInt(UINT_PTR ptr, int expected) +{ + if (ptr == NULL) + { + return false; + } + + return *(int *)ptr == expected; +} + +bool SlowPathELTProfiler::ValidateFloat(UINT_PTR ptr, float expected) +{ + if (ptr == NULL) + { + return false; + } + + return *(float *)ptr == expected; +} + +bool SlowPathELTProfiler::ValidateDouble(UINT_PTR ptr, double expected) +{ + if (ptr == NULL) + { + return false; + } + + return *(double *)ptr == expected; +} + +bool SlowPathELTProfiler::ValidateString(UINT_PTR ptr, const WCHAR *expected) +{ + if (ptr == NULL || *(void **)ptr == NULL) + { + return false; + } + + ULONG lengthOffset = 0; + ULONG bufferOffset = 0; + HRESULT hr = pCorProfilerInfo->GetStringLayout2(&lengthOffset, &bufferOffset); + if (FAILED(hr)) + { + wcout << L"GetStringLayout2 failed hr=0x" << std::hex << hr << endl; + _failures++; + return hr; + } + + UINT_PTR strReference = *((UINT_PTR *)ptr) + bufferOffset; + WCHAR *strPtr = (WCHAR *)strReference; + if (wcscmp(strPtr, expected) != 0) + { + _failures++; + return false; + } + + return true; +} + +bool SlowPathELTProfiler::ValidateMixedStruct(UINT_PTR ptr, MixedStruct expected) +{ + if (ptr == NULL) + { + return false; + } + + MixedStruct lhs = *(MixedStruct *)ptr; + return lhs.x == expected.x && lhs.d == expected.d; +} + +bool SlowPathELTProfiler::ValidateLargeStruct(UINT_PTR ptr, LargeStruct expected) +{ + if (ptr == NULL) + { + return false; + } + + LargeStruct lhs = *(LargeStruct *)ptr; + return lhs.x0 == expected.x0 + && lhs.x1 == expected.x1 + && lhs.x2 == expected.x2 + && lhs.x3 == expected.x3 + && lhs.d0 == expected.d0 + && lhs.d1 == expected.d1 + && lhs.d2 == expected.d2 + && lhs.d3 == expected.d3; +} + +bool SlowPathELTProfiler::ValidateFloatingPointStruct(UINT_PTR ptr, FloatingPointStruct expected) +{ + if (ptr == NULL) + { + return false; + } + + FloatingPointStruct lhs = *(FloatingPointStruct *)ptr; + return lhs.d1 == expected.d1 && lhs.d2 == expected.d2; +} + +bool SlowPathELTProfiler::ValidateIntegerStruct(UINT_PTR ptr, IntegerStruct expected) +{ + if (ptr == NULL) + { + return false; + } + + IntegerStruct lhs = *(IntegerStruct *)ptr; + return lhs.x == expected.x && lhs.y == expected.y; +} + + +HRESULT SlowPathELTProfiler::ValidateOneArgument(COR_PRF_FUNCTION_ARGUMENT_RANGE *pArgRange, + String functionName, + size_t argPos, + ExpectedArgValue expectedValue) +{ + if (pArgRange->length != expectedValue.length) + { + wcout << L"Argument " << argPos << L" for function " << functionName << " expected length " << expectedValue.length + << L" but got length " << pArgRange->length << endl; + _failures++; + return E_FAIL; + } + + if (!expectedValue.func(pArgRange->startAddress)) + { + wcout << L"Argument " << argPos << L" for function " << functionName << L" did not match." << endl; + _failures++; + + // Print out the bytes so you don't have to debug if something mismatches + BYTE *expectedBytes = (BYTE *)expectedValue.value; + wcout << L"Expected bytes: "; + PrintBytes(expectedBytes, expectedValue.length); + + BYTE *actualBytes = (BYTE *)pArgRange->startAddress; + wcout << L"Actual bytes : "; + PrintBytes(actualBytes, pArgRange->length); + + return E_FAIL; + } + + return S_OK; +} + +HRESULT SlowPathELTProfiler::ValidateFunctionArgs(COR_PRF_FUNCTION_ARGUMENT_INFO *pArgInfo, + String functionName, + vector expectedArgValues) +{ + size_t expectedArgCount = expectedArgValues.size(); + + if (pArgInfo->numRanges != expectedArgCount) + { + wcout << L"Expected " << expectedArgCount << L" args for " << functionName << L" but got " << pArgInfo->numRanges << endl; + _failures++; + return E_FAIL; + } + + for (size_t i = 0; i < expectedArgCount; ++i) + { + ExpectedArgValue expectedValue = expectedArgValues[i]; + COR_PRF_FUNCTION_ARGUMENT_RANGE *pArgRange = &(pArgInfo->ranges[i]); + + HRESULT hr = ValidateOneArgument(pArgRange, functionName, i, expectedValue); + if (FAILED(hr)) + { + return hr; + } + } + + return S_OK; +} diff --git a/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.h b/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.h new file mode 100644 index 000000000000..254ba12d6e66 --- /dev/null +++ b/src/tests/profiler/native/eltprofiler/slowpatheltprofiler.h @@ -0,0 +1,115 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +#include +#include +#include +#include "../profiler.h" + +typedef bool (*validateFunc)(void *pMem); + +typedef struct +{ + size_t length; + void *value; + std::function func; +} ExpectedArgValue; + +typedef struct +{ + int x; + double d; +} MixedStruct; + +typedef struct +{ + int x0; + double d0; + int x1; + double d1; + int x2; + double d2; + int x3; + double d3; +} LargeStruct; + +typedef struct +{ + int x; + int y; +} IntegerStruct; + +typedef struct +{ + double d1; + double d2; +} FloatingPointStruct; + +class SlowPathELTProfiler : public Profiler +{ +public: + static std::shared_ptr s_profiler; + + SlowPathELTProfiler() : Profiler(), + _failures(0), + _sawSimpleFuncEnter(false), + _sawMixedStructFuncEnter(false), + _sawLargeStructFuncEnter(false), + _sawSimpleFuncLeave(false), + _sawMixedStructFuncLeave(false), + _sawLargeStructFuncLeave(false), + _testType(TestType::Unknown) + {} + + virtual GUID GetClsid(); + virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk); + virtual HRESULT STDMETHODCALLTYPE Shutdown(); + + + HRESULT STDMETHODCALLTYPE EnterCallback(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo); + HRESULT STDMETHODCALLTYPE LeaveCallback(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo); + HRESULT STDMETHODCALLTYPE TailcallCallback(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo); + +private: + enum class TestType + { + EnterHooks, + LeaveHooks, + Unknown + }; + + std::atomic _failures; + bool _sawSimpleFuncEnter; + bool _sawMixedStructFuncEnter; + bool _sawLargeStructFuncEnter; + bool _sawSimpleFuncLeave; + bool _sawMixedStructFuncLeave; + bool _sawLargeStructFuncLeave; + bool _sawIntegerStructFuncLeave; + bool _sawFloatingPointStructFuncLeave; + bool _sawDoubleRetFuncLeave; + + TestType _testType; + + void PrintBytes(const BYTE *bytes, size_t length); + + bool ValidateInt(UINT_PTR ptr, int expected); + bool ValidateFloat(UINT_PTR ptr, float expected); + bool ValidateDouble(UINT_PTR ptr, double expected); + bool ValidateString(UINT_PTR ptr, const WCHAR *expected); + bool ValidateMixedStruct(UINT_PTR ptr, MixedStruct expected); + bool ValidateLargeStruct(UINT_PTR ptr, LargeStruct expected); + bool ValidateFloatingPointStruct(UINT_PTR ptr, FloatingPointStruct expected); + bool ValidateIntegerStruct(UINT_PTR ptr, IntegerStruct expected); + + HRESULT ValidateOneArgument(COR_PRF_FUNCTION_ARGUMENT_RANGE *pArgRange, + String functionName, + size_t argPos, + ExpectedArgValue expectedValue); + + HRESULT ValidateFunctionArgs(COR_PRF_FUNCTION_ARGUMENT_INFO *pArgInfo, + String name, + std::vector expectedArgValues); +}; diff --git a/src/tests/profiler/native/profiler.cpp b/src/tests/profiler/native/profiler.cpp index 3600788ccdf8..2dae0d1e7d4f 100644 --- a/src/tests/profiler/native/profiler.cpp +++ b/src/tests/profiler/native/profiler.cpp @@ -21,12 +21,13 @@ HRESULT STDMETHODCALLTYPE Profiler::Initialize(IUnknown *pICorProfilerInfoUnk) printf("Profiler.dll!Profiler::Initialize\n"); fflush(stdout); - HRESULT queryInterfaceResult = pICorProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo9), reinterpret_cast(&this->pCorProfilerInfo)); + HRESULT queryInterfaceResult = pICorProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo11), reinterpret_cast(&this->pCorProfilerInfo)); if (FAILED(queryInterfaceResult)) { printf("Profiler.dll!Profiler::Initialize failed to QI for ICorProfilerInfo.\n"); pICorProfilerInfoUnk = NULL; } + return S_OK; } diff --git a/src/tests/profiler/native/profiler.h b/src/tests/profiler/native/profiler.h index 490e9c9ced09..bb7651d018d7 100644 --- a/src/tests/profiler/native/profiler.h +++ b/src/tests/profiler/native/profiler.h @@ -3,6 +3,8 @@ #pragma once +#define NOMINMAX + #include #include #include "cor.h" @@ -108,7 +110,7 @@ class Profiler : public ICorProfilerCallback10 String GetModuleIDName(ModuleID modId); public: - ICorProfilerInfo9* pCorProfilerInfo; + ICorProfilerInfo11* pCorProfilerInfo; Profiler(); virtual ~Profiler(); diff --git a/src/tests/profiler/native/profilerstring.h b/src/tests/profiler/native/profilerstring.h index a45edbd05626..d7b63758369f 100644 --- a/src/tests/profiler/native/profilerstring.h +++ b/src/tests/profiler/native/profilerstring.h @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef _WIN32 #define WCHAR(str) L##str @@ -23,7 +24,6 @@ // here is to provide the easy ones to avoid all the copying and transforming. If more complex // string operations become necessary we should either write them in C++ or convert the string to // 32 bit and call the c runtime ones. -using std::max; #define WCHAR(str) u##str inline size_t wcslen(const char16_t *str) @@ -80,7 +80,7 @@ class String size_t otherLen = wcslen(other) + 1; if (buffer == nullptr || otherLen > bufferLen) { - bufferLen = max(DefaultStringLength, otherLen); + bufferLen = std::max(DefaultStringLength, otherLen); if (buffer != nullptr) { delete[] buffer; @@ -225,21 +225,23 @@ class String if (bufferLen > printBufferLen) { - delete[] printBuffer; - printBuffer = nullptr; - printBufferLen = 0; - } + if (printBuffer != nullptr) + { + delete[] printBuffer; + } - if (printBuffer == nullptr) - { printBuffer = new wchar_t[bufferLen]; + printBufferLen = bufferLen; } for (size_t i = 0; i < bufferLen; ++i) { - printBuffer[i] = (wchar_t)buffer[i]; + printBuffer[i] = CAST_CHAR(buffer[i]); } + // Make sure it's null terminated + printBuffer[bufferLen - 1] = '\0'; + return printBuffer; } From b165cbb5094bd6b75da3b80019681e07d2fe5a28 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Wed, 29 Jul 2020 15:33:18 -0700 Subject: [PATCH 140/755] Add BinaryFormatter auditing EventSource (#39874) --- ...em.Runtime.Serialization.Formatters.csproj | 1 + .../Formatters/Binary/BinaryFormatter.Core.cs | 21 +- .../Binary/BinaryFormatterEventSource.cs | 102 +++++++++ .../Formatters/Binary/BinaryObjectInfo.cs | 7 +- .../tests/BinaryFormatterEventSourceTests.cs | 216 ++++++++++++++++++ ...time.Serialization.Formatters.Tests.csproj | 5 +- 6 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatterEventSource.cs create mode 100644 src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterEventSourceTests.cs diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj index dba845f2eeb9..124a497c4637 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj @@ -61,6 +61,7 @@ + diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.Core.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.Core.cs index 95f281f63397..939b78ad9535 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.Core.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.Core.cs @@ -39,6 +39,7 @@ public object Deserialize(Stream serializationStream) }; try { + BinaryFormatterEventSource.Log.DeserializationStart(); var parser = new BinaryParser(serializationStream, reader); return reader.Deserialize(parser); } @@ -50,6 +51,10 @@ public object Deserialize(Stream serializationStream) { throw new SerializationException(SR.Serialization_CorruptedStream, e); } + finally + { + BinaryFormatterEventSource.Log.DeserializationStop(); + } } [Obsolete(Obsoletions.BinaryFormatterMessage, DiagnosticId = Obsoletions.BinaryFormatterDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] @@ -73,10 +78,18 @@ public void Serialize(Stream serializationStream, object graph) _assemblyFormat = _assemblyFormat, }; - var sow = new ObjectWriter(_surrogates, _context, formatterEnums, _binder); - BinaryFormatterWriter binaryWriter = new BinaryFormatterWriter(serializationStream, sow, _typeFormat); - sow.Serialize(graph, binaryWriter); - _crossAppDomainArray = sow._crossAppDomainArray; + try + { + BinaryFormatterEventSource.Log.SerializationStart(); + var sow = new ObjectWriter(_surrogates, _context, formatterEnums, _binder); + BinaryFormatterWriter binaryWriter = new BinaryFormatterWriter(serializationStream, sow, _typeFormat); + sow.Serialize(graph, binaryWriter); + _crossAppDomainArray = sow._crossAppDomainArray; + } + finally + { + BinaryFormatterEventSource.Log.SerializationStop(); + } } } } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatterEventSource.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatterEventSource.cs new file mode 100644 index 000000000000..ca8efd4c0978 --- /dev/null +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatterEventSource.cs @@ -0,0 +1,102 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.Tracing; + +namespace System.Runtime.Serialization.Formatters.Binary +{ + [EventSource( + Name = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatterEventSource")] + internal sealed class BinaryFormatterEventSource : EventSource + { + private const int EventId_SerializationStart = 10; + private const int EventId_SerializationStop = 11; + private const int EventId_SerializingObject = 12; + private const int EventId_DeserializationStart = 20; + private const int EventId_DeserializationStop = 21; + private const int EventId_DeserializingObject = 22; + + public static readonly BinaryFormatterEventSource Log = new BinaryFormatterEventSource(); + + private BinaryFormatterEventSource() + { + } + + [Event(EventId_SerializationStart, Opcode = EventOpcode.Start, Keywords = Keywords.Serialization, Level = EventLevel.Informational, ActivityOptions = EventActivityOptions.Recursive)] + public void SerializationStart() + { + if (IsEnabled(EventLevel.Informational, Keywords.Serialization)) + { + WriteEvent(EventId_SerializationStart); + } + } + + [Event(EventId_SerializationStop, Opcode = EventOpcode.Stop, Keywords = Keywords.Serialization, Level = EventLevel.Informational)] + public void SerializationStop() + { + if (IsEnabled(EventLevel.Informational, Keywords.Serialization)) + { + WriteEvent(EventId_SerializationStop); + } + } + + [NonEvent] + public void SerializingObject(Type type) + { + Debug.Assert(type != null); + + if (IsEnabled(EventLevel.Informational, Keywords.Serialization)) + { + SerializingObject(type.AssemblyQualifiedName); + } + } + + [Event(EventId_SerializingObject, Keywords = Keywords.Serialization, Level = EventLevel.Informational)] + private void SerializingObject(string? typeName) + { + WriteEvent(EventId_SerializingObject, typeName); + } + + [Event(EventId_DeserializationStart, Opcode = EventOpcode.Start, Keywords = Keywords.Deserialization, Level = EventLevel.Informational, ActivityOptions = EventActivityOptions.Recursive)] + public void DeserializationStart() + { + if (IsEnabled(EventLevel.Informational, Keywords.Deserialization)) + { + WriteEvent(EventId_DeserializationStart); + } + } + + [Event(EventId_DeserializationStop, Opcode = EventOpcode.Stop, Keywords = Keywords.Deserialization, Level = EventLevel.Informational)] + public void DeserializationStop() + { + if (IsEnabled(EventLevel.Informational, Keywords.Deserialization)) + { + WriteEvent(EventId_DeserializationStop); + } + } + + [NonEvent] + public void DeserializingObject(Type type) + { + Debug.Assert(type != null); + + if (IsEnabled(EventLevel.Informational, Keywords.Deserialization)) + { + DeserializingObject(type.AssemblyQualifiedName); + } + } + + [Event(EventId_DeserializingObject, Keywords = Keywords.Deserialization, Level = EventLevel.Informational)] + private void DeserializingObject(string? typeName) + { + WriteEvent(EventId_DeserializingObject, typeName); + } + + public class Keywords + { + public const EventKeywords Serialization = (EventKeywords)1; + public const EventKeywords Deserialization = (EventKeywords)2; + } + } +} diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectInfo.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectInfo.cs index c87d6a6fad60..64f4e6ddcd83 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectInfo.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectInfo.cs @@ -268,8 +268,11 @@ private void InitMemberInfo() internal string GetAssemblyString() => _binderAssemblyString ?? _cache._assemblyString; - private void InvokeSerializationBinder(SerializationBinder? binder) => + private void InvokeSerializationBinder(SerializationBinder? binder) + { + BinaryFormatterEventSource.Log.SerializingObject(_objectType!); binder?.BindToName(_objectType!, out _binderAssemblyString, out _binderTypeName); + } internal void GetMemberInfo(out string[]? outMemberNames, out Type[]? outMemberTypes, out object?[]? outMemberData) { @@ -392,6 +395,8 @@ internal void Init(Type? objectType, string[] memberNames, Type[]? memberTypes, private void InitReadConstructor(Type objectType, ISurrogateSelector? surrogateSelector, StreamingContext context) { + BinaryFormatterEventSource.Log.DeserializingObject(objectType); + if (objectType.IsArray) { InitNoMembers(); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterEventSourceTests.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterEventSourceTests.cs new file mode 100644 index 000000000000..805b1ad4df48 --- /dev/null +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterEventSourceTests.cs @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; +using System.Threading; +using Xunit; + +namespace System.Runtime.Serialization.Formatters.Tests +{ + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public static class BinaryFormatterEventSourceTests + { + private const string BinaryFormatterEventSourceName = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatterEventSource"; + + [Fact] + public static void RecordsSerialization() + { + using LoggingEventListener listener = new LoggingEventListener(); + + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(Stream.Null, CreatePerson()); + string[] capturedLog = listener.CaptureLog(); + + string[] expected = new string[] + { + "SerializationStart [Start, 00000001]: ", + "SerializingObject [Info, 00000001]: " + typeof(Person).AssemblyQualifiedName, + "SerializingObject [Info, 00000001]: " + typeof(Address).AssemblyQualifiedName, + "SerializationStop [Stop, 00000001]: ", + }; + + Assert.Equal(expected, capturedLog); + } + + [Fact] + public static void RecordsDeserialization() + { + MemoryStream ms = new MemoryStream(); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(ms, CreatePerson()); + ms.Position = 0; + + using LoggingEventListener listener = new LoggingEventListener(); + formatter.Deserialize(ms); + string[] capturedLog = listener.CaptureLog(); + + string[] expected = new string[] + { + "DeserializationStart [Start, 00000002]: ", + "DeserializingObject [Info, 00000002]: " + typeof(Person).AssemblyQualifiedName, + "DeserializingObject [Info, 00000002]: " + typeof(Address).AssemblyQualifiedName, + "DeserializationStop [Stop, 00000002]: ", + }; + + Assert.Equal(expected, capturedLog); + } + + [Fact] + public static void RecordsNestedSerializationCalls() + { + // First, serialization + + using LoggingEventListener listener = new LoggingEventListener(); + + MemoryStream ms = new MemoryStream(); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(ms, new ClassWithNestedDeserialization()); + string[] capturedLog = listener.CaptureLog(); + ms.Position = 0; + + string[] expected = new string[] + { + "SerializationStart [Start, 00000001]: ", + "SerializingObject [Info, 00000001]: " + typeof(ClassWithNestedDeserialization).AssemblyQualifiedName, + "SerializationStart [Start, 00000001]: ", + "SerializingObject [Info, 00000001]: " + typeof(Address).AssemblyQualifiedName, + "SerializationStop [Stop, 00000001]: ", + "SerializationStop [Stop, 00000001]: ", + }; + + Assert.Equal(expected, capturedLog); + listener.ClearLog(); + + // Then, deserialization + + ms.Position = 0; + formatter.Deserialize(ms); + capturedLog = listener.CaptureLog(); + + expected = new string[] + { + "DeserializationStart [Start, 00000002]: ", + "DeserializingObject [Info, 00000002]: " + typeof(ClassWithNestedDeserialization).AssemblyQualifiedName, + "DeserializationStart [Start, 00000002]: ", + "DeserializingObject [Info, 00000002]: " + typeof(Address).AssemblyQualifiedName, + "DeserializationStop [Stop, 00000002]: ", + "DeserializationStop [Stop, 00000002]: ", + }; + + Assert.Equal(expected, capturedLog); + } + + private static Person CreatePerson() + { + return new Person() + { + Name = "Some Chap", + HomeAddress = new Address() + { + Street = "123 Anywhere Ln", + City = "Anywhere ST 00000 United States" + } + }; + } + + private sealed class LoggingEventListener : EventListener + { + private readonly Thread _activeThread = Thread.CurrentThread; + private readonly List _log = new List(); + + private void AddToLog(FormattableString message) + { + _log.Add(FormattableString.Invariant(message)); + } + + // Captures the current log + public string[] CaptureLog() + { + return _log.ToArray(); + } + + public void ClearLog() + { + _log.Clear(); + } + + protected override void OnEventSourceCreated(EventSource eventSource) + { + if (eventSource.Name == BinaryFormatterEventSourceName) + { + EnableEvents(eventSource, EventLevel.Verbose); + } + + base.OnEventSourceCreated(eventSource); + } + + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + // The test project is parallelized. We want to filter to only events that fired + // on the current thread, otherwise we could throw off the test results. + + if (Thread.CurrentThread != _activeThread) + { + return; + } + + AddToLog($"{eventData.EventName} [{eventData.Opcode}, {(int)eventData.Keywords & int.MaxValue:X8}]: {ParsePayload(eventData.Payload)}"); + base.OnEventWritten(eventData); + } + + private static string ParsePayload(IReadOnlyCollection collection) + { + if (collection?.Count > 0) + { + return string.Join("; ", collection.Select(o => o?.ToString() ?? "")); + } + else + { + return ""; + } + } + } + + [Serializable] + private class Person + { + public string Name { get; set; } + public Address HomeAddress { get; set; } + } + + [Serializable] + private class Address + { + public string Street { get; set; } + public string City { get; set; } + } + + [Serializable] + public class ClassWithNestedDeserialization : ISerializable + { + public ClassWithNestedDeserialization() + { + } + + protected ClassWithNestedDeserialization(SerializationInfo info, StreamingContext context) + { + byte[] serializedData = (byte[])info.GetValue("SomeField", typeof(byte[])); + MemoryStream ms = new MemoryStream(serializedData); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Deserialize(ms); // should deserialize an 'Address' instance + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + MemoryStream ms = new MemoryStream(); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(ms, new Address()); + info.AddValue("SomeField", ms.ToArray()); + } + } + } +} diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj b/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj index 7e37cb04eed7..f86214238289 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj @@ -16,7 +16,6 @@ - @@ -33,6 +32,10 @@ + + + + From 264aac3c09c050353862d1161c73a74770a3e7b4 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 29 Jul 2020 17:01:44 -0700 Subject: [PATCH 141/755] Re-enable ThreadStartBool_1 test for crossgen2 compilation (#40098) --- src/coreclr/tests/issues.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index e21987966398..3a966079238f 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -884,9 +884,6 @@ - - https://github.com/dotnet/runtime/issues/33887 - https://github.com/dotnet/runtime/issues/38291 From 44add552b4cea659bcfa64ab154e1c06b0257eeb Mon Sep 17 00:00:00 2001 From: Roman Marusyk Date: Thu, 30 Jul 2020 03:32:51 +0300 Subject: [PATCH 142/755] Remove dead resource strings from Microsoft.VisualBasic.Core (#40053) --- .../src/Resources/Strings.resx | 111 ------------------ 1 file changed, 111 deletions(-) diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Resources/Strings.resx b/src/libraries/Microsoft.VisualBasic.Core/src/Resources/Strings.resx index 26d02a1974d3..140af06cdf94 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Resources/Strings.resx @@ -572,15 +572,6 @@ Locale id '{0}' is not supported on this system. - - Process '{0}' was not found. - - - 'ReDim' cannot change the number of dimensions. - - - 'ReDim' can only change the rightmost dimension. - Conversion from type '{0}' to type '{1}' is not valid. @@ -725,18 +716,6 @@ Late bound calls to file system methods in the Visual Basic runtime are not permitted. - - Deserialization data is corrupt. The CultureInfo for this Collection is missing. - - - Deserialization data is corrupt. The keys for this Collection are missing. - - - Deserialization data is corrupt. The values for this Collection are missing. - - - Deserialization data is corrupt. The keys and values arrays have different sizes. - Method invocation failed because '{0}' cannot be called with these arguments:{1} @@ -839,12 +818,6 @@ Empty placeholder to adjust for 1-based array. - - No mouse is present. - - - No mouse wheel is present. - Could not find special directory '{0}'. @@ -920,75 +893,6 @@ Argument '{0}' cannot be an empty string or Nothing. - - Property {0} cannot be set to Nothing. - - - Cannot determine the amount of available disk space. - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - - - The value of {0} must be a positive number. - - - BaseFileName cannot be Nothing or an empty String. - - - The value of {0} must be greater than or equal to 1000. - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - - - The ConnectionTimeout must be greater than 0. - - - Unable to ping because a network connection is not available. - - - The address for UploadFile needs to include a file name. - - - destinationFileName needs to include a file name. - - - Downloading {0} - - - Uploading {0} - - - Downloading {0} to {1} - - - Uploading {0} to {1} - - - Could not obtain memory information due to internal error. - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - - - An unexpected error has occurred because an operating system resource required for single instance startup cannot be acquired. - - - A startup form has not been specified. - - - This single-instance application could not connect to the original instance. - - - Splash screen and main form cannot be the same form. - NumberOfChars must be greater than zero. @@ -1034,24 +938,9 @@ TextFieldParser does not support delimiters that contain end-of-line characters. - - Environment variable is not defined: '{0}'. - - - The form referred to itself during construction from a default instance, which led to infinite recursion. Within the Form's constructor refer to the form using 'Me.' - - - An error occurred creating the form. See Exception.InnerException for details. The error is: {0} - - - Current target framework does not support web operations. - UI not available for copy or move - - UI not available for delete - Method requires System.Windows.Forms. From ad90f7ab81b99fab7ca4891c3943021827e66315 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Wed, 29 Jul 2020 19:33:37 -0700 Subject: [PATCH 143/755] Fix dummy OBJ/BLK/IND nodes. (#39824) * Add a repro. * Add a helper function `fgTryRemoveNonLocal`. * Fix the issue. * extract `gtChangeOperToNullCheck`. * update comments. --- src/coreclr/src/jit/compiler.cpp | 16 ++++ src/coreclr/src/jit/compiler.h | 4 + src/coreclr/src/jit/gentree.cpp | 12 +-- src/coreclr/src/jit/importer.cpp | 5 +- src/coreclr/src/jit/liveness.cpp | 77 ++++++++++++++----- .../JitBlue/Runtime_39737/Runtime_39737.cs | 26 +++++++ .../Runtime_39737/Runtime_39737.csproj | 13 ++++ 7 files changed, 124 insertions(+), 29 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.csproj diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index cb129b36c584..4e1140efe426 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -9285,3 +9285,19 @@ bool Compiler::lvaIsOSRLocal(unsigned varNum) return false; } + +//------------------------------------------------------------------------------ +// gtChangeOperToNullCheck: helper to change tree oper to a NULLCHECK. +// +// Arguments: +// tree - the node to change; +// basicBlock - basic block of the node. +// +void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block) +{ + assert(tree->OperIs(GT_FIELD, GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK)); + tree->ChangeOper(GT_NULLCHECK); + tree->ChangeType(TYP_BYTE); + block->bbFlags |= BBF_HAS_NULLCHECK; + optMethodFlags |= OMF_HAS_NULLCHECK; +} diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 011a2afa7872..183e84cf6989 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -2701,6 +2701,8 @@ class Compiler GenTree* gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock); + void gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block); + GenTreeArgList* gtNewArgList(GenTree* op); GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2); GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2, GenTree* op3); @@ -4633,6 +4635,8 @@ class Compiler void fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALARG_TP volatileVars); + bool fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange); + bool fgRemoveDeadStore(GenTree** pTree, LclVarDsc* varDsc, VARSET_VALARG_TP life, diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index ca5c6d4df7fb..2e0e96a0e9a6 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -13782,16 +13782,13 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions // For struct types read the first byte of the // source struct; there's no need to read the // entire thing, and no place to put it. - assert(copySrc->gtOper == GT_OBJ || copySrc->gtOper == GT_IND || copySrc->gtOper == GT_FIELD); + assert(copySrc->OperIs(GT_OBJ, GT_IND, GT_FIELD)); copyStmt->SetRootNode(copySrc); if (options == BR_REMOVE_AND_NARROW || options == BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE) { JITDUMP(" to read first byte of struct via modified [%06u]\n", dspTreeID(copySrc)); - copySrc->ChangeOper(GT_NULLCHECK); - copySrc->gtType = TYP_BYTE; - compCurBB->bbFlags |= BBF_HAS_NULLCHECK; - optMethodFlags |= OMF_HAS_NULLCHECK; + gtChangeOperToNullCheck(copySrc, compCurBB); } else { @@ -15970,6 +15967,11 @@ void Compiler::gtExtractSideEffList(GenTree* expr, if (m_compiler->gtNodeHasSideEffects(node, m_flags)) { m_sideEffects.Push(node); + if (node->OperIsBlk() && !node->OperIsStoreBlk()) + { + JITDUMP("Replace an unused OBJ/BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); + m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); + } return Compiler::WALK_SKIP_SUBTREES; } diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 9bb531527d9a..d1111583e32a 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -13247,10 +13247,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // via an underlying address, just null check the address. if (op1->OperIs(GT_FIELD, GT_IND, GT_OBJ)) { - op1->ChangeOper(GT_NULLCHECK); - block->bbFlags |= BBF_HAS_NULLCHECK; - optMethodFlags |= OMF_HAS_NULLCHECK; - op1->gtType = TYP_BYTE; + gtChangeOperToNullCheck(op1, block); } else { diff --git a/src/coreclr/src/jit/liveness.cpp b/src/coreclr/src/jit/liveness.cpp index feb8f23a222e..504a6c0fc37f 100644 --- a/src/coreclr/src/jit/liveness.cpp +++ b/src/coreclr/src/jit/liveness.cpp @@ -2109,40 +2109,77 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR break; case GT_NOP: + { // NOTE: we need to keep some NOPs around because they are referenced by calls. See the dead store // removal code above (case GT_STORE_LCL_VAR) for more explanation. if ((node->gtFlags & GTF_ORDER_SIDEEFF) != 0) { break; } - __fallthrough; + fgTryRemoveNonLocal(node, &blockRange); + } + break; - default: - assert(!node->OperIsLocal()); - if (!node->IsValue() || node->IsUnusedValue()) + case GT_BLK: + case GT_OBJ: + case GT_DYN_BLK: + { + bool removed = fgTryRemoveNonLocal(node, &blockRange); + if (!removed && node->IsUnusedValue()) { - // We are only interested in avoiding the removal of nodes with direct side-effects - // (as opposed to side effects of their children). - // This default case should never include calls or assignments. - assert(!node->OperRequiresAsgFlag() && !node->OperIs(GT_CALL)); - if (!node->gtSetFlags() && !node->OperMayThrow(this)) - { - JITDUMP("Removing dead node:\n"); - DISPNODE(node); - - node->VisitOperands([](GenTree* operand) -> GenTree::VisitResult { - operand->SetUnusedValue(); - return GenTree::VisitResult::Continue; - }); - - blockRange.Remove(node); - } + // IR doesn't expect dummy uses of `GT_OBJ/BLK/DYN_BLK`. + JITDUMP("Replace an unused OBJ/BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); + gtChangeOperToNullCheck(node, block); } + } + break; + + default: + fgTryRemoveNonLocal(node, &blockRange); break; } } } +//--------------------------------------------------------------------- +// fgTryRemoveNonLocal - try to remove a node if it is unused and has no direct +// side effects. +// +// Arguments +// node - the non-local node to try; +// blockRange - the block range that contains the node. +// +// Return value: +// None +// +// Notes: local nodes are processed independently and are not expected in this function. +// +bool Compiler::fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange) +{ + assert(!node->OperIsLocal()); + if (!node->IsValue() || node->IsUnusedValue()) + { + // We are only interested in avoiding the removal of nodes with direct side effects + // (as opposed to side effects of their children). + // This default case should never include calls or assignments. + assert(!node->OperRequiresAsgFlag() && !node->OperIs(GT_CALL)); + if (!node->gtSetFlags() && !node->OperMayThrow(this)) + { + JITDUMP("Removing dead node:\n"); + DISPNODE(node); + + node->VisitOperands([](GenTree* operand) -> GenTree::VisitResult { + operand->SetUnusedValue(); + return GenTree::VisitResult::Continue; + }); + + blockRange->Remove(node); + return true; + } + } + return false; +} + // fgRemoveDeadStore - remove a store to a local which has no exposed uses. // // pTree - GenTree** to local, including store-form local or local addr (post-rationalize) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.cs b/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.cs new file mode 100644 index 000000000000..226404918b16 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.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. + +// The test was deleting the hardware intrinsic leaving unconsumed GT_OBJ on top of the stack +// that was leading to an assert failure. + +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System; + +class Runtime_39403 +{ + public static int Main() + { + if (Sse41.IsSupported) + { + Vector128 left = Vector128.Create(1); + Vector128 right = Vector128.Create(2); + ref var rightRef = ref right; + Vector128 mask = Vector128.Create(3); + Sse41.BlendVariable(left, rightRef, mask); + } + return 100; + } +} + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.csproj new file mode 100644 index 000000000000..5d49e8d49736 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39737/Runtime_39737.csproj @@ -0,0 +1,13 @@ + + + Exe + + + + True + True + + + + + From 3edfaadbe7407e9ad66e9932253ab8157ae8f47b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 30 Jul 2020 09:42:08 +0200 Subject: [PATCH 144/755] Minor fix in library build instruction (#40109) --- docs/workflow/building/libraries/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md index 7f8c12b108e1..1c114c935aeb 100644 --- a/docs/workflow/building/libraries/README.md +++ b/docs/workflow/building/libraries/README.md @@ -83,7 +83,7 @@ For more details on the build settings see [project-guidelines](../../../coding- If you invoke the `build` script without any actions, the default action chain `-restore -build` is executed. -By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `-subset libtests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh -subset libs.tests -test`. To specify just the libraries, use `-subset libs`. +By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `-subset libs.tests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh -subset libs.tests -test`. To specify just the libraries, use `-subset libs`. **Examples** - Building in release mode for platform x64 (restore and build are implicit here as no actions are passed in) From c205ed0d0d170ced4e12fb60e0c2c2dc6f8df095 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 30 Jul 2020 09:58:05 +0200 Subject: [PATCH 145/755] Support dotnet pack on libs src project (#40107) * Support dotnet pack on libs src project * Update eng/packaging.targets Co-authored-by: Santiago Fernandez Madero --- eng/packaging.targets | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/eng/packaging.targets b/eng/packaging.targets index e0f7edaeac7f..0891a5a2f9f4 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -26,4 +26,16 @@ '$(_excludeCompile)' == 'true' and '%(Dependency.Identity)' != '_._'" /> - \ No newline at end of file + + + $(MSBuildProjectDirectory)\..\pkg\$(MSBuildProjectName).pkgproj + + _BuildPkgProj + + + + + + From 02e872ef3cf48c7fbdccc10bd52386c28b7a8676 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Thu, 30 Jul 2020 10:36:38 +0200 Subject: [PATCH 146/755] Implement Header encoding selectors on SocketsHttpHandler (#39468) * Expose HeaderEncodingSelectors on SocketsHttpHandler * Implement header encoding selectors in SocketsHttpHandler * Add header encoding tests * Add summaries for new APIs * Use Stream.Write(byte[], int, int) overloads for framework compat * Add dummy API implementation to browser target * HPack/QPack fixes * Move HeaderEncodingSelector delegate to namespace, add TContext * Encoding fixes * Remove unused using * Simplify test * HttpConnection PR feedback * Simplify fast-path detection --- .../aspnetcore/Http2/Hpack/HPackEncoder.cs | 140 ++++++++++++------ .../aspnetcore/Http3/QPack/QPackEncoder.cs | 111 +++++++++++--- .../System/Net/Http/GenericLoopbackServer.cs | 4 +- .../tests/System/Net/Http/HPackEncoder.cs | 19 ++- .../Net/Http/Http2LoopbackConnection.cs | 2 +- .../System/Net/Http/Http3LoopbackStream.cs | 2 +- .../tests/System/Net/Http/LoopbackServer.cs | 84 +++++++++-- .../tests/System/Net/Http/QPackTestEncoder.cs | 12 +- .../System.Net.Http/ref/System.Net.Http.cs | 3 + .../src/System.Net.Http.csproj | 1 + .../BrowserHttpHandler/SocketsHttpHandler.cs | 12 ++ .../System/Net/Http/HeaderEncodingSelector.cs | 15 ++ .../Net/Http/Headers/HeaderDescriptor.cs | 5 +- .../SocketsHttpHandler/Http2Connection.cs | 34 +++-- .../Http/SocketsHttpHandler/Http2Stream.cs | 8 +- .../SocketsHttpHandler/Http3RequestStream.cs | 37 +++-- .../Http/SocketsHttpHandler/HttpConnection.cs | 71 +++++++-- .../SocketsHttpHandler/HttpConnectionBase.cs | 13 +- .../HttpConnectionSettings.cs | 5 + .../SocketsHttpHandler/SocketsHttpHandler.cs | 31 +++- .../HttpClientHandlerTest.Headers.cs | 128 ++++++++++++++++ .../UnitTests/HPack/HPackRoundtripTests.cs | 41 +++-- .../UnitTests/Headers/HeaderEncodingTest.cs | 37 +++++ .../UnitTests/Headers/KnownHeadersTest.cs | 8 +- .../System.Net.Http.Unit.Tests.csproj | 1 + 25 files changed, 656 insertions(+), 168 deletions(-) create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/HeaderEncodingSelector.cs create mode 100644 src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs index d2fbc52232a9..4c3ac2952704 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs @@ -4,6 +4,7 @@ #nullable enable using System.Collections.Generic; using System.Diagnostics; +using System.Text; namespace System.Net.Http.HPack { @@ -96,7 +97,7 @@ public static bool EncodeLiteralHeaderFieldWithoutIndexing(int index, string val if (IntegerEncoder.Encode(index, 4, destination, out int indexLength)) { Debug.Assert(indexLength >= 1); - if (EncodeStringLiteral(value, destination.Slice(indexLength), out int nameLength)) + if (EncodeStringLiteral(value, valueEncoding: null, destination.Slice(indexLength), out int nameLength)) { bytesWritten = indexLength + nameLength; return true; @@ -128,7 +129,7 @@ public static bool EncodeLiteralHeaderFieldNeverIndexing(int index, string value if (IntegerEncoder.Encode(index, 4, destination, out int indexLength)) { Debug.Assert(indexLength >= 1); - if (EncodeStringLiteral(value, destination.Slice(indexLength), out int nameLength)) + if (EncodeStringLiteral(value, valueEncoding: null, destination.Slice(indexLength), out int nameLength)) { bytesWritten = indexLength + nameLength; return true; @@ -160,7 +161,7 @@ public static bool EncodeLiteralHeaderFieldIndexing(int index, string value, Spa if (IntegerEncoder.Encode(index, 6, destination, out int indexLength)) { Debug.Assert(indexLength >= 1); - if (EncodeStringLiteral(value, destination.Slice(indexLength), out int nameLength)) + if (EncodeStringLiteral(value, valueEncoding: null, destination.Slice(indexLength), out int nameLength)) { bytesWritten = indexLength + nameLength; return true; @@ -276,7 +277,7 @@ private static bool EncodeLiteralHeaderNewNameCore(byte mask, string name, strin { destination[0] = mask; if (EncodeLiteralHeaderName(name, destination.Slice(1), out int nameLength) && - EncodeStringLiteral(value, destination.Slice(1 + nameLength), out int valueLength)) + EncodeStringLiteral(value, valueEncoding: null, destination.Slice(1 + nameLength), out int valueLength)) { bytesWritten = 1 + nameLength + valueLength; return true; @@ -289,6 +290,11 @@ private static bool EncodeLiteralHeaderNewNameCore(byte mask, string name, strin /// Encodes a "Literal Header Field without Indexing - New Name". public static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, ReadOnlySpan values, string separator, Span destination, out int bytesWritten) + { + return EncodeLiteralHeaderFieldWithoutIndexingNewName(name, values, separator, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, ReadOnlySpan values, string separator, Encoding? valueEncoding, Span destination, out int bytesWritten) { // From https://tools.ietf.org/html/rfc7541#section-6.2.2 // ------------------------------------------------------ @@ -309,7 +315,7 @@ public static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, R { destination[0] = 0; if (EncodeLiteralHeaderName(name, destination.Slice(1), out int nameLength) && - EncodeStringLiterals(values, separator, destination.Slice(1 + nameLength), out int valueLength)) + EncodeStringLiterals(values, separator, valueEncoding, destination.Slice(1 + nameLength), out int valueLength)) { bytesWritten = 1 + nameLength + valueLength; return true; @@ -395,27 +401,20 @@ private static bool EncodeLiteralHeaderName(string value, Span destination return false; } - private static bool EncodeStringLiteralValue(string value, Span destination, out int bytesWritten) + private static void EncodeValueStringPart(string value, Span destination) { - if (value.Length <= destination.Length) + Debug.Assert(destination.Length >= value.Length); + + for (int i = 0; i < value.Length; i++) { - for (int i = 0; i < value.Length; i++) + char c = value[i]; + if ((c & 0xFF80) != 0) { - char c = value[i]; - if ((c & 0xFF80) != 0) - { - throw new HttpRequestException(SR.net_http_request_invalid_char_encoding); - } - - destination[i] = (byte)c; + throw new HttpRequestException(SR.net_http_request_invalid_char_encoding); } - bytesWritten = value.Length; - return true; + destination[i] = (byte)c; } - - bytesWritten = 0; - return false; } public static bool EncodeStringLiteral(ReadOnlySpan value, Span destination, out int bytesWritten) @@ -453,6 +452,11 @@ public static bool EncodeStringLiteral(ReadOnlySpan value, Span dest } public static bool EncodeStringLiteral(string value, Span destination, out int bytesWritten) + { + return EncodeStringLiteral(value, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeStringLiteral(string value, Encoding? valueEncoding, Span destination, out int bytesWritten) { // From https://tools.ietf.org/html/rfc7541#section-5.2 // ------------------------------------------------------ @@ -466,13 +470,28 @@ public static bool EncodeStringLiteral(string value, Span destination, out if (destination.Length != 0) { destination[0] = 0; // TODO: Use Huffman encoding - if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + + int encodedStringLength = valueEncoding is null || ReferenceEquals(valueEncoding, Encoding.Latin1) + ? value.Length + : valueEncoding.GetByteCount(value); + + if (IntegerEncoder.Encode(encodedStringLength, 7, destination, out int integerLength)) { Debug.Assert(integerLength >= 1); - - if (EncodeStringLiteralValue(value, destination.Slice(integerLength), out int valueLength)) + destination = destination.Slice(integerLength); + if (encodedStringLength <= destination.Length) { - bytesWritten = integerLength + valueLength; + if (valueEncoding is null) + { + EncodeValueStringPart(value, destination); + } + else + { + int written = valueEncoding.GetBytes(value, destination); + Debug.Assert(written == encodedStringLength); + } + + bytesWritten = integerLength + encodedStringLength; return true; } } @@ -502,56 +521,87 @@ public static bool EncodeDynamicTableSizeUpdate(int value, Span destinatio } public static bool EncodeStringLiterals(ReadOnlySpan values, string? separator, Span destination, out int bytesWritten) + { + return EncodeStringLiterals(values, separator, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeStringLiterals(ReadOnlySpan values, string? separator, Encoding? valueEncoding, Span destination, out int bytesWritten) { bytesWritten = 0; if (values.Length == 0) { - return EncodeStringLiteral("", destination, out bytesWritten); + return EncodeStringLiteral("", valueEncoding: null, destination, out bytesWritten); } else if (values.Length == 1) { - return EncodeStringLiteral(values[0], destination, out bytesWritten); + return EncodeStringLiteral(values[0], valueEncoding, destination, out bytesWritten); } if (destination.Length != 0) { - int valueLength = 0; + Debug.Assert(separator != null); + int valueLength; // Calculate length of all parts and separators. - foreach (string part in values) + if (valueEncoding is null || ReferenceEquals(valueEncoding, Encoding.Latin1)) { - valueLength = checked((int)(valueLength + part.Length)); + valueLength = checked((int)(values.Length - 1) * separator.Length); + foreach (string part in values) + { + valueLength = checked((int)(valueLength + part.Length)); + } + } + else + { + valueLength = checked((int)(values.Length - 1) * valueEncoding.GetByteCount(separator)); + foreach (string part in values) + { + valueLength = checked((int)(valueLength + valueEncoding.GetByteCount(part))); + } } - - Debug.Assert(separator != null); - valueLength = checked((int)(valueLength + (values.Length - 1) * separator.Length)); destination[0] = 0; if (IntegerEncoder.Encode(valueLength, 7, destination, out int integerLength)) { Debug.Assert(integerLength >= 1); - - int encodedLength = 0; - for (int j = 0; j < values.Length; j++) + destination = destination.Slice(integerLength); + if (destination.Length >= valueLength) { - if (j != 0 && !EncodeStringLiteralValue(separator, destination.Slice(integerLength), out encodedLength)) + if (valueEncoding is null) { - return false; + string value = values[0]; + EncodeValueStringPart(value, destination); + destination = destination.Slice(value.Length); + + for (int i = 1; i < values.Length; i++) + { + EncodeValueStringPart(separator, destination); + destination = destination.Slice(separator.Length); + + value = values[i]; + EncodeValueStringPart(value, destination); + destination = destination.Slice(value.Length); + } } + else + { + int written = valueEncoding.GetBytes(values[0], destination); + destination = destination.Slice(written); - integerLength += encodedLength; + for (int i = 1; i < values.Length; i++) + { + written = valueEncoding.GetBytes(separator, destination); + destination = destination.Slice(written); - if (!EncodeStringLiteralValue(values[j], destination.Slice(integerLength), out encodedLength)) - { - return false; + written = valueEncoding.GetBytes(values[i], destination); + destination = destination.Slice(written); + } } - integerLength += encodedLength; + bytesWritten = integerLength + valueLength; + return true; } - - bytesWritten = integerLength; - return true; } } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs index be43dc3bc716..68e04ed2d4ce 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Net.Http.HPack; +using System.Text; namespace System.Net.Http.QPack { @@ -59,6 +60,11 @@ public static byte[] EncodeStaticIndexedHeaderFieldToArray(int index) // - T is constant 1 here, indicating a static table reference. // - H is constant 0 here, as we do not yet perform Huffman coding. public static bool EncodeLiteralHeaderFieldWithStaticNameReference(int index, string value, Span destination, out int bytesWritten) + { + return EncodeLiteralHeaderFieldWithStaticNameReference(index, value, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeLiteralHeaderFieldWithStaticNameReference(int index, string value, Encoding? valueEncoding, Span destination, out int bytesWritten) { // Requires at least two bytes (one for name reference header, one for value length) if (destination.Length >= 2) @@ -68,7 +74,7 @@ public static bool EncodeLiteralHeaderFieldWithStaticNameReference(int index, st { destination = destination.Slice(headerBytesWritten); - if (EncodeValueString(value, destination, out int valueBytesWritten)) + if (EncodeValueString(value, valueEncoding, destination, out int valueBytesWritten)) { bytesWritten = headerBytesWritten + valueBytesWritten; return true; @@ -81,7 +87,7 @@ public static bool EncodeLiteralHeaderFieldWithStaticNameReference(int index, st } /// - /// Encodes just the name part of a Literal Header Field With Static Name Reference. Must call after to encode the header's value. + /// Encodes just the name part of a Literal Header Field With Static Name Reference. Must call after to encode the header's value. /// public static byte[] EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(int index) { @@ -119,7 +125,12 @@ public static byte[] EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(int // - H is constant 0 here, as we do not yet perform Huffman coding. public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, string value, Span destination, out int bytesWritten) { - if (EncodeNameString(name, destination, out int nameLength) && EncodeValueString(value, destination.Slice(nameLength), out int valueLength)) + return EncodeLiteralHeaderFieldWithoutNameReference(name, value, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, string value, Encoding? valueEncoding, Span destination, out int bytesWritten) + { + if (EncodeNameString(name, destination, out int nameLength) && EncodeValueString(value, valueEncoding, destination.Slice(nameLength), out int valueLength)) { bytesWritten = nameLength + valueLength; return true; @@ -136,7 +147,12 @@ public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, str /// public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, ReadOnlySpan values, string valueSeparator, Span destination, out int bytesWritten) { - if (EncodeNameString(name, destination, out int nameLength) && EncodeValueString(values, valueSeparator, destination.Slice(nameLength), out int valueLength)) + return EncodeLiteralHeaderFieldWithoutNameReference(name, values, valueSeparator, valueEncoding: null, destination, out bytesWritten); + } + + public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, ReadOnlySpan values, string valueSeparator, Encoding? valueEncoding, Span destination, out int bytesWritten) + { + if (EncodeNameString(name, destination, out int nameLength) && EncodeValueString(values, valueSeparator, valueEncoding, destination.Slice(nameLength), out int valueLength)) { bytesWritten = nameLength + valueLength; return true; @@ -147,7 +163,7 @@ public static bool EncodeLiteralHeaderFieldWithoutNameReference(string name, Rea } /// - /// Encodes just the value part of a Literawl Header Field Without Static Name Reference. Must call after to encode the header's value. + /// Encodes just the value part of a Literawl Header Field Without Static Name Reference. Must call after to encode the header's value. /// public static byte[] EncodeLiteralHeaderFieldWithoutNameReferenceToArray(string name) { @@ -169,19 +185,32 @@ public static byte[] EncodeLiteralHeaderFieldWithoutNameReferenceToArray(string return temp.Slice(0, bytesWritten).ToArray(); } - private static bool EncodeValueString(string s, Span buffer, out int length) + private static bool EncodeValueString(string s, Encoding? valueEncoding, Span buffer, out int length) { if (buffer.Length != 0) { buffer[0] = 0; - if (IntegerEncoder.Encode(s.Length, 7, buffer, out int nameLength)) + + int encodedStringLength = valueEncoding is null || ReferenceEquals(valueEncoding, Encoding.Latin1) + ? s.Length + : valueEncoding.GetByteCount(s); + + if (IntegerEncoder.Encode(encodedStringLength, 7, buffer, out int nameLength)) { buffer = buffer.Slice(nameLength); - if (buffer.Length >= s.Length) + if (buffer.Length >= encodedStringLength) { - EncodeValueStringPart(s, buffer); + if (valueEncoding is null) + { + EncodeValueStringPart(s, buffer); + } + else + { + int written = valueEncoding.GetBytes(s, buffer); + Debug.Assert(written == encodedStringLength); + } - length = nameLength + s.Length; + length = nameLength + encodedStringLength; return true; } } @@ -195,25 +224,42 @@ private static bool EncodeValueString(string s, Span buffer, out int lengt /// Encodes a value by concatenating a collection of strings, separated by a separator string. /// public static bool EncodeValueString(ReadOnlySpan values, string? separator, Span buffer, out int length) + { + return EncodeValueString(values, separator, valueEncoding: null, buffer, out length); + } + + public static bool EncodeValueString(ReadOnlySpan values, string? separator, Encoding? valueEncoding, Span buffer, out int length) { if (values.Length == 1) { - return EncodeValueString(values[0], buffer, out length); + return EncodeValueString(values[0], valueEncoding, buffer, out length); } if (values.Length == 0) { // TODO: this will be called with a string array from HttpHeaderCollection. Can we ever get a 0-length array from that? Assert if not. - return EncodeValueString(string.Empty, buffer, out length); + return EncodeValueString(string.Empty, valueEncoding: null, buffer, out length); } if (buffer.Length > 0) { Debug.Assert(separator != null); - int valueLength = separator.Length * (values.Length - 1); - for (int i = 0; i < values.Length; ++i) + int valueLength; + if (valueEncoding is null || ReferenceEquals(valueEncoding, Encoding.Latin1)) + { + valueLength = separator.Length * (values.Length - 1); + foreach (string part in values) + { + valueLength += part.Length; + } + } + else { - valueLength += values[i].Length; + valueLength = valueEncoding.GetByteCount(separator) * (values.Length - 1); + foreach (string part in values) + { + valueLength += valueEncoding.GetByteCount(part); + } } buffer[0] = 0; @@ -222,18 +268,35 @@ public static bool EncodeValueString(ReadOnlySpan values, string? separa buffer = buffer.Slice(nameLength); if (buffer.Length >= valueLength) { - string value = values[0]; - EncodeValueStringPart(value, buffer); - buffer = buffer.Slice(value.Length); - - for (int i = 1; i < values.Length; ++i) + if (valueEncoding is null) { - EncodeValueStringPart(separator, buffer); - buffer = buffer.Slice(separator.Length); - - value = values[i]; + string value = values[0]; EncodeValueStringPart(value, buffer); buffer = buffer.Slice(value.Length); + + for (int i = 1; i < values.Length; i++) + { + EncodeValueStringPart(separator, buffer); + buffer = buffer.Slice(separator.Length); + + value = values[i]; + EncodeValueStringPart(value, buffer); + buffer = buffer.Slice(value.Length); + } + } + else + { + int written = valueEncoding.GetBytes(values[0], buffer); + buffer = buffer.Slice(written); + + for (int i = 1; i < values.Length; i++) + { + written = valueEncoding.GetBytes(separator, buffer); + buffer = buffer.Slice(written); + + written = valueEncoding.GetBytes(values[i], buffer); + buffer = buffer.Slice(written); + } } length = nameLength + valueLength; diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index d15ab88b2618..899b90922de8 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -106,13 +106,15 @@ public struct HttpHeaderData public string Value { get; } public bool HuffmanEncoded { get; } public byte[] Raw { get; } + public Encoding ValueEncoding { get; } - public HttpHeaderData(string name, string value, bool huffmanEncoded = false, byte[] raw = null) + public HttpHeaderData(string name, string value, bool huffmanEncoded = false, byte[] raw = null, Encoding valueEncoding = null) { Name = name; Value = value; HuffmanEncoded = huffmanEncoded; Raw = raw; + ValueEncoding = valueEncoding; } public override string ToString() => Name == null ? "" : (Name + ": " + (Value ?? string.Empty)); diff --git a/src/libraries/Common/tests/System/Net/Http/HPackEncoder.cs b/src/libraries/Common/tests/System/Net/Http/HPackEncoder.cs index bbdf89f223c2..9ecaf44f7237 100644 --- a/src/libraries/Common/tests/System/Net/Http/HPackEncoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/HPackEncoder.cs @@ -51,7 +51,7 @@ public static int EncodeHeader(int headerIndex, Span headerBlock) public static int EncodeHeader(int nameIdx, string value, HPackFlags flags, Span headerBlock) { Debug.Assert(nameIdx > 0); - return EncodeHeaderImpl(nameIdx, null, value, flags, headerBlock); + return EncodeHeaderImpl(nameIdx, null, value, valueEncoding: null, flags, headerBlock); } /// @@ -63,10 +63,15 @@ public static int EncodeHeader(int nameIdx, string value, HPackFlags flags, Span /// The number of bytes written to . public static int EncodeHeader(string name, string value, HPackFlags flags, Span headerBlock) { - return EncodeHeaderImpl(0, name, value, flags, headerBlock); + return EncodeHeader(name, value, valueEncoding: null, flags, headerBlock); } - private static int EncodeHeaderImpl(int nameIdx, string name, string value, HPackFlags flags, Span headerBlock) + public static int EncodeHeader(string name, string value, Encoding valueEncoding, HPackFlags flags, Span headerBlock) + { + return EncodeHeaderImpl(0, name, value, valueEncoding, flags, headerBlock); + } + + private static int EncodeHeaderImpl(int nameIdx, string name, string value, Encoding valueEncoding, HPackFlags flags, Span headerBlock) { const HPackFlags IndexingMask = HPackFlags.NeverIndexed | HPackFlags.NewIndexed | HPackFlags.WithoutIndexing; @@ -97,16 +102,16 @@ private static int EncodeHeaderImpl(int nameIdx, string name, string value, HPac if (name != null) { - bytesGenerated += EncodeString(name, headerBlock.Slice(bytesGenerated), (flags & HPackFlags.HuffmanEncodeName) != 0); + bytesGenerated += EncodeString(name, Encoding.ASCII, headerBlock.Slice(bytesGenerated), (flags & HPackFlags.HuffmanEncodeName) != 0); } - bytesGenerated += EncodeString(value, headerBlock.Slice(bytesGenerated), (flags & HPackFlags.HuffmanEncodeValue) != 0); + bytesGenerated += EncodeString(value, valueEncoding, headerBlock.Slice(bytesGenerated), (flags & HPackFlags.HuffmanEncodeValue) != 0); return bytesGenerated; } - public static int EncodeString(string value, Span headerBlock, bool huffmanEncode) + public static int EncodeString(string value, Encoding valueEncoding, Span headerBlock, bool huffmanEncode) { - byte[] data = Encoding.ASCII.GetBytes(value); + byte[] data = (valueEncoding ?? Encoding.ASCII).GetBytes(value); byte prefix; if (!huffmanEncode) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index ad60410c03ba..9ee647968482 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -662,7 +662,7 @@ public async Task SendResponseHeadersAsync(int streamId, bool endStream = true, { foreach (HttpHeaderData headerData in headers) { - bytesGenerated += HPackEncoder.EncodeHeader(headerData.Name, headerData.Value, headerData.HuffmanEncoded ? HPackFlags.HuffmanEncode : HPackFlags.None, headerBlock.AsSpan(bytesGenerated)); + bytesGenerated += HPackEncoder.EncodeHeader(headerData.Name, headerData.Value, headerData.ValueEncoding, headerData.HuffmanEncoded ? HPackFlags.HuffmanEncode : HPackFlags.None, headerBlock.AsSpan(bytesGenerated)); } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs index f13cbd6d958a..d0e8d433ec70 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs @@ -78,7 +78,7 @@ public async Task SendHeadersFrameAsync(IEnumerable headers) foreach (HttpHeaderData header in headers) { - bytesWritten += QPackTestEncoder.EncodeHeader(buffer.AsSpan(bytesWritten), header.Name, header.Value, header.HuffmanEncoded ? QPackFlags.HuffmanEncode : QPackFlags.None); + bytesWritten += QPackTestEncoder.EncodeHeader(buffer.AsSpan(bytesWritten), header.Name, header.Value, header.ValueEncoding, header.HuffmanEncoded ? QPackFlags.HuffmanEncode : QPackFlags.None); } await SendFrameAsync(HeadersFrame, buffer.AsMemory(0, bytesWritten)).ConfigureAwait(false); diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 76c8459a136e..2d34c3bc8753 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -15,6 +15,9 @@ namespace System.Net.Test.Common { public sealed partial class LoopbackServer : GenericLoopbackServer, IDisposable { + private static readonly byte[] s_newLineBytes = new byte[] { (byte)'\r', (byte)'\n' }; + private static readonly byte[] s_colonSpaceBytes = new byte[] { (byte)':', (byte)' ' }; + private Socket _listenSocket; private Options _options; private Uri _uri; @@ -532,6 +535,16 @@ public string ReadLine() } public async Task ReadLineAsync() + { + byte[] lineBytes = await ReadLineBytesAsync().ConfigureAwait(false); + + if (lineBytes is null) + return null; + + return Encoding.ASCII.GetString(lineBytes); + } + + private async Task ReadLineBytesAsync() { int index = 0; int startSearch = _readStart; @@ -578,7 +591,7 @@ public async Task ReadLineAsync() if (_readBuffer[_readStart + stringLength] == '\n') { stringLength--; } if (_readBuffer[_readStart + stringLength] == '\r') { stringLength--; } - string line = System.Text.Encoding.ASCII.GetString(_readBuffer, _readStart, stringLength + 1); + byte[] line = _readBuffer.AsSpan(_readStart, stringLength + 1).ToArray(); _readStart = index + 1; return line; } @@ -625,6 +638,32 @@ public async Task> ReadRequestHeaderAsync() return lines; } + private async Task> ReadRequestHeaderBytesAsync() + { + var lines = new List(); + + byte[] line; + + while (true) + { + line = await ReadLineBytesAsync().ConfigureAwait(false); + + if (line is null || line.Length == 0) + { + break; + } + + lines.Add(line); + } + + if (line == null) + { + throw new IOException("Unexpected EOF trying to read request header"); + } + + return lines; + } + public async Task SendResponseAsync(string response) { await _writer.WriteAsync(response).ConfigureAwait(false); @@ -663,24 +702,24 @@ public async Task> ReadRequestHeaderAndSendResponseAsync(HttpStatus public override async Task ReadRequestDataAsync(bool readBody = true) { - List headerLines = null; HttpRequestData requestData = new HttpRequestData(); - headerLines = await ReadRequestHeaderAsync().ConfigureAwait(false); + List headerLines = await ReadRequestHeaderBytesAsync().ConfigureAwait(false); // Parse method and path - string[] splits = headerLines[0].Split(' '); + string[] splits = Encoding.ASCII.GetString(headerLines[0]).Split(' '); requestData.Method = splits[0]; requestData.Path = splits[1]; // Convert header lines to key/value pairs // Skip first line since it's the status line - foreach (var line in headerLines.Skip(1)) + foreach (byte[] lineBytes in headerLines.Skip(1)) { + string line = Encoding.ASCII.GetString(lineBytes); int offset = line.IndexOf(':'); string name = line.Substring(0, offset); string value = line.Substring(offset + 1).TrimStart(); - requestData.Headers.Add(new HttpHeaderData(name, value)); + requestData.Headers.Add(new HttpHeaderData(name, value, raw: lineBytes)); } if (requestData.Method != "GET") @@ -760,7 +799,7 @@ public override async Task ReadRequestBodyAsync() public override async Task SendResponseAsync(HttpStatusCode? statusCode = HttpStatusCode.OK, IList headers = null, string content = null, bool isFinal = true, int requestId = 0) { - string headerString = null; + MemoryStream headerBytes = new MemoryStream(); int contentLength = -1; bool isChunked = false; bool hasContentLength = false; @@ -785,22 +824,39 @@ public override async Task SendResponseAsync(HttpStatusCode? statusCode = HttpSt isChunked = true; } - headerString = headerString + $"{headerData.Name}: {headerData.Value}\r\n"; + byte[] nameBytes = Encoding.ASCII.GetBytes(headerData.Name); + headerBytes.Write(nameBytes, 0, nameBytes.Length); + headerBytes.Write(s_colonSpaceBytes, 0, s_colonSpaceBytes.Length); + + byte[] valueBytes = (headerData.ValueEncoding ?? Encoding.ASCII).GetBytes(headerData.Value); + headerBytes.Write(valueBytes, 0, valueBytes.Length); + headerBytes.Write(s_newLineBytes, 0, s_newLineBytes.Length); } } bool endHeaders = content != null || isFinal; if (statusCode != null) { - // If we need to send status line, prepped it to headers and possibly add missing headers to the end. - headerString = + byte[] temp = headerBytes.ToArray(); + + headerBytes.SetLength(0); + + byte[] headerStartBytes = Encoding.ASCII.GetBytes( $"HTTP/1.1 {(int)statusCode} {GetStatusDescription((HttpStatusCode)statusCode)}\r\n" + - (!hasContentLength && !isChunked && content != null ? $"Content-length: {content.Length}\r\n" : "") + - headerString + - (endHeaders ? "\r\n" : ""); + (!hasContentLength && !isChunked && content != null ? $"Content-length: {content.Length}\r\n" : "")); + + headerBytes.Write(headerStartBytes, 0, headerStartBytes.Length); + headerBytes.Write(temp, 0, temp.Length); + + if (endHeaders) + { + headerBytes.Write(s_newLineBytes, 0, s_newLineBytes.Length); + } } - await SendResponseAsync(headerString).ConfigureAwait(false); + headerBytes.Position = 0; + await headerBytes.CopyToAsync(_stream).ConfigureAwait(false); + if (content != null) { await SendResponseBodyAsync(content, isFinal: isFinal, requestId: requestId).ConfigureAwait(false); diff --git a/src/libraries/Common/tests/System/Net/Http/QPackTestEncoder.cs b/src/libraries/Common/tests/System/Net/Http/QPackTestEncoder.cs index 3df439e4dfa5..a73f42067bcb 100644 --- a/src/libraries/Common/tests/System/Net/Http/QPackTestEncoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/QPackTestEncoder.cs @@ -49,7 +49,7 @@ public static int EncodeHeader(Span buffer, int nameValueIdx, QPackFlags f return EncodeInteger(buffer, nameValueIdx, prefix, prefixMask); } - public static int EncodeHeader(Span buffer, int nameIdx, string value, QPackFlags flags = QPackFlags.StaticIndex) + public static int EncodeHeader(Span buffer, int nameIdx, string value, Encoding valueEncoding, QPackFlags flags = QPackFlags.StaticIndex) { byte prefix, prefixMask; @@ -76,12 +76,12 @@ public static int EncodeHeader(Span buffer, int nameIdx, string value, QPa } int nameLen = EncodeInteger(buffer, nameIdx, prefix, prefixMask); - int valueLen = EncodeString(buffer.Slice(nameLen), value, flags.HasFlag(QPackFlags.HuffmanEncodeValue)); + int valueLen = EncodeString(buffer.Slice(nameLen), value, valueEncoding, flags.HasFlag(QPackFlags.HuffmanEncodeValue)); return nameLen + valueLen; } - public static int EncodeHeader(Span buffer, string name, string value, QPackFlags flags = QPackFlags.None) + public static int EncodeHeader(Span buffer, string name, string value, Encoding valueEncoding, QPackFlags flags = QPackFlags.None) { byte[] data = Encoding.ASCII.GetBytes(name); byte prefix; @@ -116,14 +116,14 @@ public static int EncodeHeader(Span buffer, string name, string value, QPa bytesGenerated += data.Length; // write value string. - bytesGenerated += EncodeString(buffer.Slice(bytesGenerated), value, flags.HasFlag(QPackFlags.HuffmanEncodeValue)); + bytesGenerated += EncodeString(buffer.Slice(bytesGenerated), value, valueEncoding, flags.HasFlag(QPackFlags.HuffmanEncodeValue)); return bytesGenerated; } - public static int EncodeString(Span buffer, string value, bool huffmanCoded = false) + public static int EncodeString(Span buffer, string value, Encoding valueEncoding, bool huffmanCoded = false) { - return HPackEncoder.EncodeString(value, buffer, huffmanCoded); + return HPackEncoder.EncodeString(value, valueEncoding, buffer, huffmanCoded); } public static int EncodeInteger(Span buffer, int value, byte prefix, byte prefixMask) diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 8e2c957c6f5f..8f72cd9665e7 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -39,6 +39,7 @@ public partial class FormUrlEncodedContent : System.Net.Http.ByteArrayContent public FormUrlEncodedContent(System.Collections.Generic.IEnumerable> nameValueCollection) : base (default(byte[])) { } protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } } + public delegate System.Text.Encoding? HeaderEncodingSelector(string headerName, TContext context); public partial class HttpClient : System.Net.Http.HttpMessageInvoker { public HttpClient() : base (default(System.Net.Http.HttpMessageHandler)) { } @@ -346,7 +347,9 @@ public SocketsHttpHandler() { } public bool PreAuthenticate { get { throw null; } set { } } public System.Collections.Generic.IDictionary Properties { get { throw null; } } public System.Net.IWebProxy? Proxy { get { throw null; } set { } } + public System.Net.Http.HeaderEncodingSelector? RequestHeaderEncodingSelector { get { throw null; } set { } } public System.TimeSpan ResponseDrainTimeout { get { throw null; } set { } } + public System.Net.Http.HeaderEncodingSelector? ResponseHeaderEncodingSelector { get { throw null; } set { } } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public System.Net.Security.SslClientAuthenticationOptions SslOptions { get { throw null; } set { } } public bool UseCookies { get { throw null; } set { } } 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 60e0afeb2525..a30bc93858d5 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -29,6 +29,7 @@ + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs index 657d0033984c..8c462eea5f0c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs @@ -142,6 +142,18 @@ public Func Properties => throw new PlatformNotSupportedException(); + public HeaderEncodingSelector? RequestHeaderEncodingSelector + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public HeaderEncodingSelector? ResponseHeaderEncodingSelector + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + protected internal override Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) => throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HeaderEncodingSelector.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HeaderEncodingSelector.cs new file mode 100644 index 000000000000..cb984b838cb5 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HeaderEncodingSelector.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; + +namespace System.Net.Http +{ + /// + /// Represents a method that specifies the to use when interpreting header values. + /// + /// Name of the header to specify the for. + /// The we are enoding/decoding the headers for. + /// to use or to use the default behavior. + public delegate Encoding? HeaderEncodingSelector(string headerName, TContext context); +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs index 8970f78f1664..229490b5432d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Text; using System.Text.Unicode; namespace System.Net.Http.Headers @@ -116,7 +117,7 @@ public HeaderDescriptor AsCustomHeader() return new HeaderDescriptor(_knownHeader.Name); } - public string GetHeaderValue(ReadOnlySpan headerValue) + public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEncoding) { if (headerValue.Length == 0) { @@ -156,7 +157,7 @@ public string GetHeaderValue(ReadOnlySpan headerValue) } } - return HttpRuleParser.DefaultHttpEncoding.GetString(headerValue); + return (valueEncoding ?? HttpRuleParser.DefaultHttpEncoding).GetString(headerValue); } internal static string? GetKnownContentType(ReadOnlySpan contentTypeValue) 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 1bd39f4ca9ba..c9ad97f65dbc 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 @@ -974,12 +974,12 @@ private void WriteIndexedHeader(int index, string value, ref ArrayBuffer headerB headerBuffer.Commit(bytesWritten); } - private void WriteLiteralHeader(string name, ReadOnlySpan values, ref ArrayBuffer headerBuffer) + private void WriteLiteralHeader(string name, ReadOnlySpan values, Encoding? valueEncoding, ref ArrayBuffer headerBuffer) { if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(name)}={name}, {nameof(values)}={string.Join(", ", values.ToArray())}"); int bytesWritten; - while (!HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewName(name, values, HttpHeaderParser.DefaultSeparator, headerBuffer.AvailableSpan, out bytesWritten)) + while (!HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewName(name, values, HttpHeaderParser.DefaultSeparator, valueEncoding, headerBuffer.AvailableSpan, out bytesWritten)) { headerBuffer.EnsureAvailableSpace(headerBuffer.AvailableLength + 1); } @@ -987,12 +987,12 @@ private void WriteLiteralHeader(string name, ReadOnlySpan values, ref Ar headerBuffer.Commit(bytesWritten); } - private void WriteLiteralHeaderValues(ReadOnlySpan values, string? separator, ref ArrayBuffer headerBuffer) + private void WriteLiteralHeaderValues(ReadOnlySpan values, string? separator, Encoding? valueEncoding, ref ArrayBuffer headerBuffer) { if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(values)}={string.Join(separator, values.ToArray())}"); int bytesWritten; - while (!HPackEncoder.EncodeStringLiterals(values, separator, headerBuffer.AvailableSpan, out bytesWritten)) + while (!HPackEncoder.EncodeStringLiterals(values, separator, valueEncoding, headerBuffer.AvailableSpan, out bytesWritten)) { headerBuffer.EnsureAvailableSpace(headerBuffer.AvailableLength + 1); } @@ -1000,12 +1000,12 @@ private void WriteLiteralHeaderValues(ReadOnlySpan values, string? separ headerBuffer.Commit(bytesWritten); } - private void WriteLiteralHeaderValue(string value, ref ArrayBuffer headerBuffer) + private void WriteLiteralHeaderValue(string value, Encoding? valueEncoding, ref ArrayBuffer headerBuffer) { if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(value)}={value}"); int bytesWritten; - while (!HPackEncoder.EncodeStringLiteral(value, headerBuffer.AvailableSpan, out bytesWritten)) + while (!HPackEncoder.EncodeStringLiteral(value, valueEncoding, headerBuffer.AvailableSpan, out bytesWritten)) { headerBuffer.EnsureAvailableSpace(headerBuffer.AvailableLength + 1); } @@ -1026,7 +1026,7 @@ private void WriteBytes(ReadOnlySpan bytes, ref ArrayBuffer headerBuffer) headerBuffer.Commit(bytes.Length); } - private void WriteHeaderCollection(HttpHeaders headers, ref ArrayBuffer headerBuffer) + private void WriteHeaderCollection(HttpRequestMessage request, HttpHeaders headers, ref ArrayBuffer headerBuffer) { if (NetEventSource.Log.IsEnabled()) Trace(""); @@ -1035,6 +1035,8 @@ private void WriteHeaderCollection(HttpHeaders headers, ref ArrayBuffer headerBu return; } + HeaderEncodingSelector? encodingSelector = _pool.Settings._requestHeaderEncodingSelector; + ref string[]? tmpHeaderValuesArray = ref t_headerValues; foreach (KeyValuePair header in headers.HeaderStore) { @@ -1042,6 +1044,8 @@ private void WriteHeaderCollection(HttpHeaders headers, ref ArrayBuffer headerBu Debug.Assert(headerValuesCount > 0, "No values for header??"); ReadOnlySpan headerValues = tmpHeaderValuesArray.AsSpan(0, headerValuesCount); + Encoding? valueEncoding = encodingSelector?.Invoke(header.Key.Name, request); + KnownHeader? knownHeader = header.Key.KnownHeader; if (knownHeader != null) { @@ -1058,7 +1062,7 @@ private void WriteHeaderCollection(HttpHeaders headers, ref ArrayBuffer headerBu if (string.Equals(value, "trailers", StringComparison.OrdinalIgnoreCase)) { WriteBytes(knownHeader.Http2EncodedName, ref headerBuffer); - WriteLiteralHeaderValue(value, ref headerBuffer); + WriteLiteralHeaderValue(value, valueEncoding, ref headerBuffer); break; } } @@ -1081,13 +1085,13 @@ private void WriteHeaderCollection(HttpHeaders headers, ref ArrayBuffer headerBu } } - WriteLiteralHeaderValues(headerValues, separator, ref headerBuffer); + WriteLiteralHeaderValues(headerValues, separator, valueEncoding, ref headerBuffer); } } else { // The header is not known: fall back to just encoding the header name and value(s). - WriteLiteralHeader(header.Key.Name, headerValues, ref headerBuffer); + WriteLiteralHeader(header.Key.Name, headerValues, valueEncoding, ref headerBuffer); } } } @@ -1142,7 +1146,7 @@ private void WriteHeaders(HttpRequestMessage request, ref ArrayBuffer headerBuff if (request.HasHeaders) { - WriteHeaderCollection(request.Headers, ref headerBuffer); + WriteHeaderCollection(request, request.Headers, ref headerBuffer); } // Determine cookies to send. @@ -1152,7 +1156,9 @@ private void WriteHeaders(HttpRequestMessage request, ref ArrayBuffer headerBuff if (cookiesFromContainer != string.Empty) { WriteBytes(KnownHeaders.Cookie.Http2EncodedName, ref headerBuffer); - WriteLiteralHeaderValue(cookiesFromContainer, ref headerBuffer); + + Encoding? cookieEncoding = _pool.Settings._requestHeaderEncodingSelector?.Invoke(KnownHeaders.Cookie.Name, request); + WriteLiteralHeaderValue(cookiesFromContainer, cookieEncoding, ref headerBuffer); } } @@ -1163,12 +1169,12 @@ private void WriteHeaders(HttpRequestMessage request, ref ArrayBuffer headerBuff if (normalizedMethod.MustHaveRequestBody) { WriteBytes(KnownHeaders.ContentLength.Http2EncodedName, ref headerBuffer); - WriteLiteralHeaderValue("0", ref headerBuffer); + WriteLiteralHeaderValue("0", valueEncoding: null, ref headerBuffer); } } else { - WriteHeaderCollection(request.Content.Headers, ref headerBuffer); + WriteHeaderCollection(request, request.Content.Headers, ref headerBuffer); } } 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 5ac829bbe3dc..254fec2cd30e 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 @@ -542,24 +542,26 @@ public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name))); } + Encoding? valueEncoding = _connection._pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, _request); + // Note we ignore the return value from TryAddWithoutValidation; // if the header can't be added, we silently drop it. if (_responseProtocolState == ResponseProtocolState.ExpectingTrailingHeaders) { Debug.Assert(_trailers != null); - string headerValue = descriptor.GetHeaderValue(value); + string headerValue = descriptor.GetHeaderValue(value, valueEncoding); _trailers.TryAddWithoutValidation((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue); } else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content) { Debug.Assert(_response != null && _response.Content != null); - string headerValue = descriptor.GetHeaderValue(value); + string headerValue = descriptor.GetHeaderValue(value, valueEncoding); _response.Content.Headers.TryAddWithoutValidation(descriptor, headerValue); } else { Debug.Assert(_response != null); - string headerValue = _connection.GetResponseHeaderValueWithCaching(descriptor, value); + string headerValue = _connection.GetResponseHeaderValueWithCaching(descriptor, value, valueEncoding); _response.Headers.TryAddWithoutValidation((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue); } } 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 07c2840be7e4..72e8090e76d9 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 @@ -548,7 +548,8 @@ private void BufferHeaders(HttpRequestMessage request) string cookiesFromContainer = _connection.Pool.Settings._cookieContainer!.GetCookieHeader(request.RequestUri); if (cookiesFromContainer != string.Empty) { - BufferLiteralHeaderWithStaticNameReference(H3StaticTable.Cookie, cookiesFromContainer); + Encoding? valueEncoding = _connection.Pool.Settings._requestHeaderEncodingSelector?.Invoke(HttpKnownHeaderNames.Cookie, request); + BufferLiteralHeaderWithStaticNameReference(H3StaticTable.Cookie, cookiesFromContainer, valueEncoding); } } @@ -590,12 +591,16 @@ private void BufferHeaderCollection(HttpHeaders headers) return; } + HeaderEncodingSelector? encodingSelector = _connection.Pool.Settings._requestHeaderEncodingSelector; + foreach (KeyValuePair header in headers.HeaderStore) { int headerValuesCount = HttpHeaders.GetValuesAsStrings(header.Key, header.Value, ref _headerValues); Debug.Assert(headerValuesCount > 0, "No values for header??"); ReadOnlySpan headerValues = _headerValues.AsSpan(0, headerValuesCount); + Encoding? valueEncoding = encodingSelector?.Invoke(header.Key.Name, _request); + KnownHeader? knownHeader = header.Key.KnownHeader; if (knownHeader != null) { @@ -612,7 +617,7 @@ private void BufferHeaderCollection(HttpHeaders headers) { if (string.Equals(value, "trailers", StringComparison.OrdinalIgnoreCase)) { - BufferLiteralHeaderWithoutNameReference("TE", value); + BufferLiteralHeaderWithoutNameReference("TE", value, valueEncoding); break; } } @@ -635,13 +640,13 @@ private void BufferHeaderCollection(HttpHeaders headers) } } - BufferLiteralHeaderValues(headerValues, separator); + BufferLiteralHeaderValues(headerValues, separator, valueEncoding); } } else { // The header is not known: fall back to just encoding the header name and value(s). - BufferLiteralHeaderWithoutNameReference(header.Key.Name, headerValues, ", "); + BufferLiteralHeaderWithoutNameReference(header.Key.Name, headerValues, HttpHeaderParser.DefaultSeparator, valueEncoding); } } } @@ -656,40 +661,40 @@ private void BufferIndexedHeader(int index) _sendBuffer.Commit(bytesWritten); } - private void BufferLiteralHeaderWithStaticNameReference(int nameIndex, string value) + private void BufferLiteralHeaderWithStaticNameReference(int nameIndex, string value, Encoding? valueEncoding = null) { int bytesWritten; - while (!QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReference(nameIndex, value, _sendBuffer.AvailableSpan, out bytesWritten)) + while (!QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReference(nameIndex, value, valueEncoding, _sendBuffer.AvailableSpan, out bytesWritten)) { _sendBuffer.Grow(); } _sendBuffer.Commit(bytesWritten); } - private void BufferLiteralHeaderWithoutNameReference(string name, ReadOnlySpan values, string separator) + private void BufferLiteralHeaderWithoutNameReference(string name, ReadOnlySpan values, string separator, Encoding? valueEncoding) { int bytesWritten; - while (!QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(name, values, separator, _sendBuffer.AvailableSpan, out bytesWritten)) + while (!QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(name, values, separator, valueEncoding, _sendBuffer.AvailableSpan, out bytesWritten)) { _sendBuffer.Grow(); } _sendBuffer.Commit(bytesWritten); } - private void BufferLiteralHeaderWithoutNameReference(string name, string value) + private void BufferLiteralHeaderWithoutNameReference(string name, string value, Encoding? valueEncoding) { int bytesWritten; - while (!QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(name, value, _sendBuffer.AvailableSpan, out bytesWritten)) + while (!QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReference(name, value, valueEncoding, _sendBuffer.AvailableSpan, out bytesWritten)) { _sendBuffer.Grow(); } _sendBuffer.Commit(bytesWritten); } - private void BufferLiteralHeaderValues(ReadOnlySpan values, string? separator) + private void BufferLiteralHeaderValues(ReadOnlySpan values, string? separator, Encoding? valueEncoding) { int bytesWritten; - while (!QPackEncoder.EncodeValueString(values, separator, _sendBuffer.AvailableSpan, out bytesWritten)) + while (!QPackEncoder.EncodeValueString(values, separator, valueEncoding, _sendBuffer.AvailableSpan, out bytesWritten)) { _sendBuffer.Grow(); } @@ -917,7 +922,13 @@ private void OnHeader(int? staticIndex, HeaderDescriptor descriptor, string? sta } else { - string headerValue = staticValue ?? _connection.GetResponseHeaderValueWithCaching(descriptor, literalValue); + string? headerValue = staticValue; + + if (headerValue is null) + { + Encoding? encoding = _connection.Pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, _request); + headerValue = _connection.GetResponseHeaderValueWithCaching(descriptor, literalValue, encoding); + } switch (_headerState) { 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 33383a117dd1..131af80227ee 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 @@ -197,6 +197,8 @@ private void ConsumeFromRemainingBuffer(int bytesToConsume) private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFromContainer, bool async) { + Debug.Assert(_currentRequest != null); + if (headers.HeaderStore != null) { foreach (KeyValuePair header in headers.HeaderStore) @@ -215,12 +217,14 @@ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFr Debug.Assert(headerValuesCount > 0, "No values for header??"); if (headerValuesCount > 0) { - await WriteStringAsync(_headerValues[0], async).ConfigureAwait(false); + Encoding? valueEncoding = _pool.Settings._requestHeaderEncodingSelector?.Invoke(header.Key.Name, _currentRequest); + + await WriteStringAsync(_headerValues[0], async, valueEncoding).ConfigureAwait(false); if (cookiesFromContainer != null && header.Key.KnownHeader == KnownHeaders.Cookie) { await WriteTwoBytesAsync((byte)';', (byte)' ', async).ConfigureAwait(false); - await WriteStringAsync(cookiesFromContainer, async).ConfigureAwait(false); + await WriteStringAsync(cookiesFromContainer, async, valueEncoding).ConfigureAwait(false); cookiesFromContainer = null; } @@ -238,7 +242,7 @@ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFr for (int i = 1; i < headerValuesCount; i++) { await WriteAsciiStringAsync(separator, async).ConfigureAwait(false); - await WriteStringAsync(_headerValues[i], async).ConfigureAwait(false); + await WriteStringAsync(_headerValues[i], async, valueEncoding).ConfigureAwait(false); } } } @@ -251,7 +255,10 @@ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFr { await WriteAsciiStringAsync(HttpKnownHeaderNames.Cookie, async).ConfigureAwait(false); await WriteTwoBytesAsync((byte)':', (byte)' ', async).ConfigureAwait(false); - await WriteStringAsync(cookiesFromContainer, async).ConfigureAwait(false); + + Encoding? valueEncoding = _pool.Settings._requestHeaderEncodingSelector?.Invoke(HttpKnownHeaderNames.Cookie, _currentRequest); + await WriteStringAsync(cookiesFromContainer, async, valueEncoding).ConfigureAwait(false); + await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false); } } @@ -984,22 +991,25 @@ private static void ParseHeaderNameValue(HttpConnection connection, ReadOnlySpan pos++; } + Debug.Assert(response.RequestMessage != null); + Encoding? valueEncoding = connection._pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, response.RequestMessage); + // Note we ignore the return value from TryAddWithoutValidation. If the header can't be added, we silently drop it. ReadOnlySpan value = line.Slice(pos); if (isFromTrailer) { - string headerValue = descriptor.GetHeaderValue(value); + string headerValue = descriptor.GetHeaderValue(value, valueEncoding); response.TrailingHeaders.TryAddWithoutValidation((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue); } else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content) { - string headerValue = descriptor.GetHeaderValue(value); + string headerValue = descriptor.GetHeaderValue(value, valueEncoding); response.Content!.Headers.TryAddWithoutValidation(descriptor, headerValue); } else { // Request headers returned on the response must be treated as custom headers. - string headerValue = connection.GetResponseHeaderValueWithCaching(descriptor, value); + string headerValue = connection.GetResponseHeaderValueWithCaching(descriptor, value, valueEncoding); response.Headers.TryAddWithoutValidation( (descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue); @@ -1182,23 +1192,23 @@ private Task WriteBytesAsync(byte[] bytes, bool async) _writeOffset += bytes.Length; return Task.CompletedTask; } - return WriteBytesSlowAsync(bytes, async); + return WriteBytesSlowAsync(bytes, bytes.Length, async); } - private async Task WriteBytesSlowAsync(byte[] bytes, bool async) + private async Task WriteBytesSlowAsync(byte[] bytes, int length, bool async) { int offset = 0; while (true) { - int remaining = bytes.Length - offset; + int remaining = length - offset; int toCopy = Math.Min(remaining, _writeBuffer.Length - _writeOffset); Buffer.BlockCopy(bytes, offset, _writeBuffer, _writeOffset, toCopy); _writeOffset += toCopy; offset += toCopy; - Debug.Assert(offset <= bytes.Length, $"Expected {nameof(offset)} to be <= {bytes.Length}, got {offset}"); + Debug.Assert(offset <= length, $"Expected {nameof(offset)} to be <= {length}, got {offset}"); Debug.Assert(_writeOffset <= _writeBuffer.Length, $"Expected {nameof(_writeOffset)} to be <= {_writeBuffer.Length}, got {_writeOffset}"); - if (offset == bytes.Length) + if (offset == length) { break; } @@ -1235,6 +1245,43 @@ private Task WriteStringAsync(string s, bool async) return WriteStringAsyncSlow(s, async); } + private Task WriteStringAsync(string s, bool async, Encoding? encoding) + { + if (encoding is null) + { + return WriteStringAsync(s, async); + } + + // If there's enough space in the buffer to just copy all of the string's bytes, do so. + if (encoding.GetMaxByteCount(s.Length) <= _writeBuffer.Length - _writeOffset) + { + _writeOffset += encoding.GetBytes(s, _writeBuffer.AsSpan(_writeOffset)); + return Task.CompletedTask; + } + + // Otherwise, fall back to doing a normal slow string write + return WriteStringWithEncodingAsyncSlow(s, async, encoding); + } + + private async Task WriteStringWithEncodingAsyncSlow(string s, bool async, Encoding encoding) + { + // Avoid calculating the length if the rented array would be small anyway + int length = s.Length <= 512 + ? encoding.GetMaxByteCount(s.Length) + : encoding.GetByteCount(s); + + byte[] rentedBuffer = ArrayPool.Shared.Rent(length); + try + { + int written = encoding.GetBytes(s, rentedBuffer); + await WriteBytesSlowAsync(rentedBuffer, written, async).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(rentedBuffer); + } + } + private Task WriteAsciiStringAsync(string s, bool async) { // If there's enough space in the buffer to just copy all of the string's bytes, do so. 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 b4b0aa19fbad..df8191b74027 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 @@ -7,6 +7,7 @@ using System.Net.Http.Headers; using System.Net.Security; using System.Runtime.CompilerServices; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -20,19 +21,19 @@ internal abstract class HttpConnectionBase : IHttpTrace private string? _lastServerHeaderValue; /// Uses , but first special-cases several known headers for which we can use caching. - public string GetResponseHeaderValueWithCaching(HeaderDescriptor descriptor, ReadOnlySpan value) + public string GetResponseHeaderValueWithCaching(HeaderDescriptor descriptor, ReadOnlySpan value, Encoding? valueEncoding) { return - ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Date) ? GetOrAddCachedValue(ref _lastDateHeaderValue, descriptor, value) : - ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Server) ? GetOrAddCachedValue(ref _lastServerHeaderValue, descriptor, value) : - descriptor.GetHeaderValue(value); + ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Date) ? GetOrAddCachedValue(ref _lastDateHeaderValue, descriptor, value, valueEncoding) : + ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Server) ? GetOrAddCachedValue(ref _lastServerHeaderValue, descriptor, value, valueEncoding) : + descriptor.GetHeaderValue(value, valueEncoding); - static string GetOrAddCachedValue([NotNull] ref string? cache, HeaderDescriptor descriptor, ReadOnlySpan value) + static string GetOrAddCachedValue([NotNull] ref string? cache, HeaderDescriptor descriptor, ReadOnlySpan value, Encoding? encoding) { string? lastValue = cache; if (lastValue is null || !ByteArrayHelpers.EqualsOrdinalAscii(lastValue, value)) { - cache = lastValue = descriptor.GetHeaderValue(value); + cache = lastValue = descriptor.GetHeaderValue(value, encoding); } return lastValue; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 558e6cf1572a..507af88f3aea 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -46,6 +46,9 @@ internal sealed class HttpConnectionSettings internal TimeSpan _expect100ContinueTimeout = HttpHandlerDefaults.DefaultExpect100ContinueTimeout; internal TimeSpan _connectTimeout = HttpHandlerDefaults.DefaultConnectTimeout; + internal HeaderEncodingSelector? _requestHeaderEncodingSelector; + internal HeaderEncodingSelector? _responseHeaderEncodingSelector; + internal Version _maxHttpVersion; internal bool _allowUnencryptedHttp2; @@ -110,6 +113,8 @@ public HttpConnectionSettings CloneAndNormalize() _useProxy = _useProxy, _allowUnencryptedHttp2 = _allowUnencryptedHttp2, _assumePrenegotiatedHttp3ForTesting = _assumePrenegotiatedHttp3ForTesting, + _requestHeaderEncodingSelector = _requestHeaderEncodingSelector, + _responseHeaderEncodingSelector = _responseHeaderEncodingSelector, _enableMultipleHttp2Connections = _enableMultipleHttp2Connections, _connectionFactory = _connectionFactory, _plaintextFilter = _plaintextFilter diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index de391e98b161..8eb5a9290750 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Net.Connections; using System.Net.Security; using System.Threading; using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; -using System.Net.Connections; +using System.Text; namespace System.Net.Http { @@ -319,6 +320,34 @@ public Func Properties => _settings._properties ?? (_settings._properties = new Dictionary()); + /// + /// Gets or sets a callback that returns the to encode the value for the specified request header name, + /// or to use the default behavior. + /// + public HeaderEncodingSelector? RequestHeaderEncodingSelector + { + get => _settings._requestHeaderEncodingSelector; + set + { + CheckDisposedOrStarted(); + _settings._requestHeaderEncodingSelector = value; + } + } + + /// + /// Gets or sets a callback that returns the to decode the value for the specified response header name, + /// or to use the default behavior. + /// + public HeaderEncodingSelector? ResponseHeaderEncodingSelector + { + get => _settings._responseHeaderEncodingSelector; + set + { + CheckDisposedOrStarted(); + _settings._responseHeaderEncodingSelector = value; + } + } + protected override void Dispose(bool disposing) { if (disposing && !_disposed) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs index afffb680a942..3ed0f554fc06 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Net.Http.Headers; using System.Net.Test.Common; +using System.Text; using System.Threading.Tasks; using Xunit; @@ -332,5 +333,132 @@ await server.HandleRequestAsync(headers: new[] }); }); } + + private static readonly (string Name, Encoding ValueEncoding, string[] Values)[] s_nonAsciiHeaders = new[] + { + ("foo", Encoding.ASCII, new[] { "bar" }), + ("header-0", Encoding.UTF8, new[] { "\uD83D\uDE03", "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A" }), + ("Cache-Control", Encoding.UTF8, new[] { "no-cache" }), + ("header-1", Encoding.UTF8, new[] { "\uD83D\uDE03" }), + ("Some-Header1", Encoding.Latin1, new[] { "\uD83D\uDE03", "UTF8-best-fit-to-latin1" }), + ("Some-Header2", Encoding.Latin1, new[] { "\u00FF", "\u00C4nd", "Ascii\u00A9" }), + ("Some-Header3", Encoding.ASCII, new[] { "\u00FF", "\u00C4nd", "Ascii\u00A9", "Latin1-best-fit-to-ascii" }), + ("header-2", Encoding.UTF8, new[] { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A" }), + ("header-3", Encoding.UTF8, new[] { "\uFFFD" }), + ("header-4", Encoding.UTF8, new[] { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A", "\uD83D\uDE03" }), + ("Cookie", Encoding.UTF8, new[] { "Cookies", "\uD83C\uDF6A", "everywhere" }), + ("Set-Cookie", Encoding.UTF8, new[] { "\uD83C\uDDF8\uD83C\uDDEE" }), + ("header-5", Encoding.UTF8, new[] { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A", "foo", "\uD83D\uDE03", "bar" }), + ("bar", Encoding.UTF8, new[] { "foo" }) + }; + + [Fact] + public async Task SendAsync_CustomRequestEncodingSelector_CanSendNonAsciiHeaderValues() + { + await LoopbackServerFactory.CreateClientAndServerAsync( + async uri => + { + var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri) + { + Version = UseVersion + }; + + foreach ((string name, _, string[] values) in s_nonAsciiHeaders) + { + requestMessage.Headers.Add(name, values); + } + + List seenHeaderNames = new List(); + + using HttpClientHandler handler = CreateHttpClientHandler(); + var underlyingHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); + + underlyingHandler.RequestHeaderEncodingSelector = (name, request) => + { + Assert.NotNull(name); + Assert.Same(request, requestMessage); + seenHeaderNames.Add(name); + return Assert.Single(s_nonAsciiHeaders, h => h.Name.Equals(name, StringComparison.OrdinalIgnoreCase)).ValueEncoding; + }; + + using HttpClient client = CreateHttpClient(handler); + + await client.SendAsync(requestMessage); + + foreach ((string name, _, _) in s_nonAsciiHeaders) + { + Assert.Contains(name, seenHeaderNames); + } + }, + async server => + { + HttpRequestData requestData = await server.HandleRequestAsync(); + + Assert.All(requestData.Headers, + h => Assert.False(h.HuffmanEncoded, "Expose raw decoded bytes once HuffmanEncoding is supported")); + + foreach ((string name, Encoding valueEncoding, string[] values) in s_nonAsciiHeaders) + { + byte[] valueBytes = valueEncoding.GetBytes(string.Join(", ", values)); + Assert.Single(requestData.Headers, + h => h.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && h.Raw.AsSpan().IndexOf(valueBytes) != -1); + } + }); + } + + [Fact] + public async Task SendAsync_CustomResponseEncodingSelector_CanReceiveNonAsciiHeaderValues() + { + await LoopbackServerFactory.CreateClientAndServerAsync( + async uri => + { + var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri) + { + Version = UseVersion + }; + + List seenHeaderNames = new List(); + + using HttpClientHandler handler = CreateHttpClientHandler(); + var underlyingHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); + + underlyingHandler.ResponseHeaderEncodingSelector = (name, request) => + { + Assert.NotNull(name); + Assert.Same(request, requestMessage); + seenHeaderNames.Add(name); + + if (s_nonAsciiHeaders.Any(h => h.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) + { + return Assert.Single(s_nonAsciiHeaders, h => h.Name.Equals(name, StringComparison.OrdinalIgnoreCase)).ValueEncoding; + } + + // Not one of our custom headers + return null; + }; + + using HttpClient client = CreateHttpClient(handler); + + using HttpResponseMessage response = await client.SendAsync(requestMessage); + + foreach ((string name, Encoding valueEncoding, string[] values) in s_nonAsciiHeaders) + { + Assert.Contains(name, seenHeaderNames); + IEnumerable receivedValues = Assert.Single(response.Headers, h => h.Key.Equals(name, StringComparison.OrdinalIgnoreCase)).Value; + string value = Assert.Single(receivedValues); + + string expected = valueEncoding.GetString(valueEncoding.GetBytes(string.Join(", ", values))); + Assert.Equal(expected, value, StringComparer.OrdinalIgnoreCase); + } + }, + async server => + { + List headerData = s_nonAsciiHeaders + .Select(h => new HttpHeaderData(h.Name, string.Join(", ", h.Values), valueEncoding: h.ValueEncoding)) + .ToList(); + + await server.HandleRequestAsync(headers: headerData); + }); + } } } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs b/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs index 730cab367c4b..3fd84d6a4abb 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs @@ -14,25 +14,35 @@ namespace System.Net.Http.Unit.Tests.HPack { public class HPackRoundtripTests { - public static IEnumerable TestHeaders() { - yield return new object[] { new HttpRequestHeaders() { { "header", "value" } } }; - yield return new object[] { new HttpRequestHeaders() { { "header", new[] { "value1", "value2" } } } }; + yield return new object[] { new HttpRequestHeaders() { { "header", "value" } }, null }; + yield return new object[] { new HttpRequestHeaders() { { "header", "value" } }, Encoding.ASCII }; + yield return new object[] { new HttpRequestHeaders() { { "header", new[] { "value1", "value2" } } }, null }; + yield return new object[] { new HttpRequestHeaders() { { "header", new[] { "value1", "value2" } } }, Encoding.ASCII }; yield return new object[] { new HttpRequestHeaders() { { "header-0", new[] { "value1", "value2" } }, { "header-0", "value3" }, { "header-1", "value1" }, { "header-2", new[] { "value1", "value2" } }, - } }; + }, null }; + yield return new object[] { new HttpRequestHeaders() { { "header", "foo" } }, Encoding.UTF8 }; + yield return new object[] { new HttpRequestHeaders() { { "header", "\uD83D\uDE03" } }, Encoding.UTF8 }; + yield return new object[] { new HttpRequestHeaders() + { + { "header-0", new[] { "\uD83D\uDE03", "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A" } }, + { "header-1", "\uD83D\uDE03" }, + { "header-2", "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A" }, + { "header-3", new[] { "\uD83D\uDE03", "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A" } } + }, Encoding.UTF8 }; } [Theory, MemberData(nameof(TestHeaders))] - public void HPack_HeaderEncodeDecodeRoundtrip_ShouldMatchOriginalInput(HttpHeaders headers) + public void HPack_HeaderEncodeDecodeRoundtrip_ShouldMatchOriginalInput(HttpHeaders headers, Encoding? valueEncoding) { - Memory encoding = HPackEncode(headers); - HttpHeaders decodedHeaders = HPackDecode(encoding); + Memory encoding = HPackEncode(headers, valueEncoding); + HttpHeaders decodedHeaders = HPackDecode(encoding, valueEncoding); // Assert: decoded headers are structurally equal to original headers Assert.Equal(headers.Count(), decodedHeaders.Count()); @@ -44,7 +54,7 @@ public void HPack_HeaderEncodeDecodeRoundtrip_ShouldMatchOriginalInput(HttpHeade } // adapted from Header serialization code in Http2Connection.cs - private static Memory HPackEncode(HttpHeaders headers) + private static Memory HPackEncode(HttpHeaders headers, Encoding? valueEncoding) { var buffer = new ArrayBuffer(4); FillAvailableSpaceWithOnes(buffer); @@ -101,7 +111,7 @@ void WriteBytes(ReadOnlySpan bytes) void WriteLiteralHeaderValues(ReadOnlySpan values, string separator) { int bytesWritten; - while (!HPackEncoder.EncodeStringLiterals(values, separator, buffer.AvailableSpan, out bytesWritten)) + while (!HPackEncoder.EncodeStringLiterals(values, separator, valueEncoding, buffer.AvailableSpan, out bytesWritten)) { buffer.EnsureAvailableSpace(buffer.AvailableLength + 1); FillAvailableSpaceWithOnes(buffer); @@ -113,7 +123,7 @@ void WriteLiteralHeaderValues(ReadOnlySpan values, string separator) void WriteLiteralHeader(string name, ReadOnlySpan values) { int bytesWritten; - while (!HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewName(name, values, HttpHeaderParser.DefaultSeparator, buffer.AvailableSpan, out bytesWritten)) + while (!HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewName(name, values, HttpHeaderParser.DefaultSeparator, valueEncoding, buffer.AvailableSpan, out bytesWritten)) { buffer.EnsureAvailableSpace(buffer.AvailableLength + 1); FillAvailableSpaceWithOnes(buffer); @@ -127,12 +137,12 @@ void WriteLiteralHeader(string name, ReadOnlySpan values) } // adapted from header deserialization code in Http2Connection.cs - private static HttpHeaders HPackDecode(Memory memory) + private static HttpHeaders HPackDecode(Memory memory, Encoding? valueEncoding) { var header = new HttpRequestHeaders(); var hpackDecoder = new HPackDecoder(maxDynamicTableSize: 0, maxHeadersLength: HttpHandlerDefaults.DefaultMaxResponseHeadersLength * 1024); - hpackDecoder.Decode(memory.Span, true, new HeaderHandler(header)); + hpackDecoder.Decode(memory.Span, true, new HeaderHandler(header, valueEncoding)); return header; } @@ -140,9 +150,12 @@ private static HttpHeaders HPackDecode(Memory memory) private class HeaderHandler : IHttpHeadersHandler { HttpRequestHeaders _headers; - public HeaderHandler(HttpRequestHeaders headers) + Encoding? _valueEncoding; + + public HeaderHandler(HttpRequestHeaders headers, Encoding? valueEncoding) { _headers = headers; + _valueEncoding = valueEncoding; } public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) @@ -152,7 +165,7 @@ public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name))); } - string headerValue = descriptor.GetHeaderValue(value); + string headerValue = descriptor.GetHeaderValue(value, _valueEncoding); _headers.TryAddWithoutValidation(descriptor, headerValue.Split(',').Select(x => x.Trim())); } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs new file mode 100644 index 000000000000..d7f41e0deeee --- /dev/null +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Http.Headers; +using System.Text; +using Xunit; + +namespace System.Net.Http.Tests +{ + public class HeaderEncodingTest + { + [Theory] + [InlineData("")] + [InlineData("foo")] + [InlineData("\uD83D\uDE03")] + [InlineData("\0")] + [InlineData("\x01")] + [InlineData("\xFF")] + [InlineData("\uFFFF")] + [InlineData("\uFFFD")] + [InlineData("\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A")] + public void RoundTripsUtf8(string input) + { + byte[] encoded = Encoding.UTF8.GetBytes(input); + + Assert.True(HeaderDescriptor.TryGet("custom-header", out HeaderDescriptor descriptor)); + Assert.Null(descriptor.KnownHeader); + string roundtrip = descriptor.GetHeaderValue(encoded, Encoding.UTF8); + Assert.Equal(input, roundtrip); + + Assert.True(HeaderDescriptor.TryGet("Cache-Control", out descriptor)); + Assert.NotNull(descriptor.KnownHeader); + roundtrip = descriptor.GetHeaderValue(encoded, Encoding.UTF8); + Assert.Equal(input, roundtrip); + } + } +} diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs index a87760246048..78fada7218b4 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs @@ -222,11 +222,11 @@ static void Validate(KnownHeader knownHeader, string value) { Assert.NotNull(knownHeader); - string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray()); + string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); Assert.NotNull(v1); Assert.Equal(value, v1, StringComparer.OrdinalIgnoreCase); - string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray()); + string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); Assert.Same(v1, v2); } } @@ -239,8 +239,8 @@ public void GetKnownHeaderValue_Unknown_NotFound(string name, string value) KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(name); Assert.NotNull(knownHeader); - string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray()); - string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray()); + string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); + string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); Assert.Equal(value, v1); Assert.Equal(value, v2); Assert.NotSame(v1, v2); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 1a1199ad91fd..f5419d0faf48 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -273,6 +273,7 @@ + From b7f809d7e37f8dade15fc6aa588565d3f0ee20a6 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 30 Jul 2020 15:29:30 +0200 Subject: [PATCH 147/755] Update docs for packaging and other nits (#40134) * Update docs for packaging and other nits --- docs/coding-guidelines/project-guidelines.md | 44 ++++++------------- docs/workflow/building/libraries/README.md | 44 +++++++++++-------- .../libraries/webassembly-instructions.md | 17 ++++--- 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index 60afda9ea793..afc05f4037b2 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -1,39 +1,33 @@ # Build Project Guidelines -In order to work in dotnet/runtime repo you must first run build.cmd/sh from the root of the repo at least -once before you can iterate and work on a given library project. +In order to work in the dotnet/runtime repo you must first run build.cmd/sh from the root of the repo at least once before you can iterate and work on a given library project. ## Behind the scenes with build.cmd/sh -- Setup tools (currently done in restore in build.cmd/sh) +- Restore tools - Restore external dependencies - CoreCLR - Copy to `bin\runtime\$(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)` - Build targeting pack - Build src\libraries\ref.proj which builds all references assembly projects. For reference assembly project information see [ref](#ref) - Build product - Build src\libraries\src.proj which builds all the source library projects. For source library project information see [src](#src). -- Sign product - - Build src\sign.proj # Build Pivots Below is a list of all the various options we pivot the project builds on: -- **Target Frameworks:** NetFx (aka Desktop), netstandard (aka dotnet/Portable), NETCoreApp (aka .NET Core) -- **Platform Runtimes:** NetFx (aka CLR/Desktop), CoreCLR, Mono +- **Target Frameworks:** .NETFramework, .NETStandard, .NETCoreApp +- **Platform Runtimes:** .NETFramework (aka CLR/Desktop), CoreCLR, Mono - **OS:** Windows_NT, Linux, OSX, FreeBSD, AnyOS - **Flavor:** Debug, Release -- **Architecture:** x86, x64, arm, arm64, AnyCPU ## Individual build properties The following are the properties associated with each build pivot -- `$(BuildTargetFramework) -> Any .NETCoreApp, .NETStandard or .NETFramework TFM, e.g. net5.0` +- `$(BuildTargetFramework) -> Any .NETCoreApp or .NETFramework TFM, e.g. net5.0` - `$(TargetOS) -> Windows | Linux | OSX | FreeBSD | [defaults to running OS when empty]` - `$(Configuration) -> Release | [defaults to Debug when empty]` - `$(TargetArchitecture) - x86 | x64 | arm | arm64 | [defaults to x64 when empty]` - `$(RuntimeOS) - win7 | osx10.10 | ubuntu.14.04 | [any other RID OS+version] | [defaults to running OS when empty]` See [RIDs](https://github.com/dotnet/runtime/tree/master/src/libraries/pkg/Microsoft.NETCore.Platforms) for more info. -For more information on various targets see also [.NET Standard](https://github.com/dotnet/standard/blob/master/docs/versions.md) - ## Aggregate build properties Each project will define a set of supported TargetFrameworks @@ -137,44 +131,34 @@ Reference assemblies are required for any library that has more than one impleme In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. That project can contain multiple entries in its `TargetFrameworks` property. Ref projects should use `` for its dependencies. ### ref output -The output for the ref project build will be a flat targeting pack folder in the following directory: - -`bin\ref\$(TargetFramework)` +All ref outputs should be under -
//**CONSIDER**: Do we need a specific BuildTargetFramework version of TargetFramework for this output path to ensure all projects output to same targeting path? +`bin\$(MSBuildProjectName)\ref\$(TargetFramework)` ## src In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library in various target frameworks. All supported target frameworks should be listed in the `TargetFrameworks` property. -All libraries should use `` for all their project references. That will cause them to be resolved against a targeting pack (i.e. `bin\ref\net5.0` or `\bin\ref\netstandard2.0`) based on the project target framework. There should not be any direct project references to other libraries. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts. -
//**CONSIDER**: just using Reference and use a reference to System.Private.CoreLib as a trigger to turn the other References into a ProjectReference automatically. That will allow us to have consistency where all projects just use Reference. +All libraries should use `` for all their references to libraries that compose the shared framework of the current .NETCoreApp. That will cause them to be resolved against the locally built targeting pack which is located at `artifacts\bin\microsoft.netcore.app.ref`. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts. -### src output -The output for the src product build will be a flat runtime folder into the following directory: +Other target frameworks than .NETCoreApp latest (i.e. `netstandard2.0`, `net461`, `netcoreapp3.0`) should use ProjectReference items to reference dependencies. -`bin\runtime\$(BuildSettings)` +### src output +All src outputs are under -Note: The `BuildSettings` is a global property and not the project setting because we need all projects to output to the same runtime directory no matter which compatible target framework we select and build the project with. -```$(BuildTargetFramework)-$(TargetOS)-(Configuration)-(TargetArchitecture)``` +`bin\$(MSBuildProjectName)\$(TargetFramework)` ## pkg In the pkg directory for the library there should be only **one** `.pkgproj` for the primary package for the library. If the library has platform-specific implementations those should be split into platform specific projects in a subfolder for each platform. (see [Package projects](./package-projects.md)) -TODO: Outline changes needed for pkgprojs - ## tests Similar to the src projects tests projects will define a `TargetFrameworks` property so they can list out the set of target frameworks they support. -Tests should not have any `` or `` items in their project because they will automatically reference everything in the targeting pack based on the TargetFramework they are building in. The only exception to this is a `` can be used to reference other test helper libraries or assets. - -In order to build and run a test project in a given build target framework a root level build.cmd/sh must have been completed for that build target framework first. Tests will run on the live built runtime at `bin\runtime\$(BuildSettings)`. -TODO: We need update our test host so that it can run from the shared runtime directory as well as resolve assemblies from the test output directory. +Tests don't need to reference default references which are part of the targeting packs (i.e. `mscorlib` on .NETFramework or `System.Runtime` on .NETCoreApp). Everything on top of targeting packs should be referenced via ProjectReference items for live built assets. ### tests output All test outputs should be under -`bin\tests\$(MSBuildProjectName)\$(TargetFramework)` or -`bin\tests\$(MSBuildProjectName)\netstandard2.0` +`bin\$(MSBuildProjectName)\$(TargetFramework)` ## Facades Facade are unique in that they don't have any code and instead are generated by finding a contract reference assembly with the matching identity and generating type forwards for all the types to where they live in the implementation assemblies (aka facade seeds). There are also partial facades which contain some type forwards as well as some code definitions. All the various build configurations should be contained in the one csproj file per library. diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md index 1c114c935aeb..ec0f52388e69 100644 --- a/docs/workflow/building/libraries/README.md +++ b/docs/workflow/building/libraries/README.md @@ -9,7 +9,7 @@ Here is one example of a daily workflow for a developer working mainly on the li git clean -xdf git pull upstream master & git push origin master :: Build Debug libraries on top of Release runtime: -build -subset clr+libs -runtimeConfiguration Release +build clr+libs -rc Release :: The above you may only perform once in a day, or when you pull down significant new changes. :: If you use Visual Studio, you might open System.Text.RegularExpressions.sln here. @@ -33,7 +33,7 @@ The instructions for Linux and macOS are essentially the same: git clean -xdf git pull upstream master & git push origin master # Build Debug libraries on top of Release runtime: -./build.sh -subset clr+libs -runtimeconfiguration Release +./build.sh clr+libs -rc Release # The above you may only perform once in a day, or when you pull down significant new changes. # Switch to working on a given library (RegularExpressions in this case) @@ -56,12 +56,12 @@ These example commands will build a release CoreCLR (and CoreLib), debug librari For Linux: ```bash -./build.sh -runtimeConfiguration Release +./build.sh -rc Release ``` For Windows: ```bat -./build.cmd -runtimeConfiguration Release +./build.cmd -rc Release ``` Detailed information about building and testing runtimes and the libraries is in the documents linked below. @@ -83,26 +83,20 @@ For more details on the build settings see [project-guidelines](../../../coding- If you invoke the `build` script without any actions, the default action chain `-restore -build` is executed. -By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `-subset libs.tests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh -subset libs.tests -test`. To specify just the libraries, use `-subset libs`. +By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `libs.tests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh libs.tests -test`. To specify just the libraries, use `libs`. **Examples** - Building in release mode for platform x64 (restore and build are implicit here as no actions are passed in) ```bash -./build.sh -subset libs -c Release -arch x64 +./build.sh libs -c Release -arch x64 ``` - Building the src assemblies and build and run tests (running all tests takes a considerable amount of time!) ```bash -./build.sh -subset libs -test +./build.sh libs -test ``` -- Building for different target frameworks (restore and build are implicit again as no action is passed in) -```bash -./build.sh -subset libs -framework net5.0 -./build.sh -subset libs -framework net472 -``` - -- Clean the entire solution +- Clean the entire artifacts folder ```bash ./build.sh -clean ``` @@ -199,24 +193,24 @@ You can use the same workflow for mono runtime by using `mono.corelib+libs.prete By default the libraries will attempt to build using the CoreCLR version of `System.Private.CoreLib.dll`. In order to build against the Mono version you need to use the `/p:RuntimeFlavor=Mono` argument. ``` -.\build.cmd -subset libs /p:RuntimeFlavor=Mono +.\build.cmd libs /p:RuntimeFlavor=Mono ``` ### Building all for other OSes By default, building from the root will only build the libraries for the OS you are running on. One can -build for another OS by specifying `./build.sh -subset libs -os [value]`. +build for another OS by specifying `./build.sh libs -os [value]`. Note that you cannot generally build native components for another OS but you can for managed components so if you need to do that you can do it at the individual project level or build all via passing `/p:BuildNative=false`. ### Building in Release or Debug By default, building from the root or within a project will build the libraries in Debug mode. -One can build in Debug or Release mode from the root by doing `./build.sh -subset libs -c Release` or `./build.sh -subset libs -c Debug`. +One can build in Debug or Release mode from the root by doing `./build.sh libs -c Release` or `./build.sh libs`. ### Building other Architectures -One can build 32- or 64-bit binaries or for any architecture by specifying in the root `./build.sh -subset libs -arch [value]` or in a project `/p:TargetArchitecture=[value]` after the `dotnet build` command. +One can build 32- or 64-bit binaries or for any architecture by specifying in the root `./build.sh libs -arch [value]` or in a project `/p:TargetArchitecture=[value]` after the `dotnet build` command. ## Working in Visual Studio @@ -227,3 +221,17 @@ If you are working on Windows, and use Visual Studio, you can open individual li For more details about running tests inside Visual Studio, [go here](../../testing/visualstudio.md). For more about running tests, read the [running tests](../../testing/libraries/testing.md) document. + +## Build packages +To build a library's package, simply invoke `dotnet pack` on the src project after you successfully built the .NETCoreApp vertical from root: + +``` +build libs +dotnet pack src\libraries\System.Text.Json\src\ +``` + +Same as for `dotnet build` or `dotnet publish`, you can specify the desired configuration via the `-c` flag: + +``` +dotnet pack src\libraries\System.Text.Json\src\ -c Release +``` diff --git a/docs/workflow/building/libraries/webassembly-instructions.md b/docs/workflow/building/libraries/webassembly-instructions.md index c7059cd8269e..408aa4e90827 100644 --- a/docs/workflow/building/libraries/webassembly-instructions.md +++ b/docs/workflow/building/libraries/webassembly-instructions.md @@ -34,12 +34,12 @@ The libraries build contains some native code. This includes shims over libc, op - Building in debug mode for platform wasm and Browser operating system ```bash -./build.sh --arch wasm --os Browser --subset Libs.Native --configuration Debug +./build.sh libs.native --arch wasm --os Browser ``` - Building in release mode for platform wasm and Browser operating system ```bash -./build.sh --arch wasm --os Browser --subset Libs.Native --configuration Release +./build.sh libs.native --arch wasm --os Browser -c Release ``` ## How to build mono System.Private.CoreLib @@ -48,20 +48,19 @@ If you are working on core parts of mono libraries you will probably need to bui ```bash -./build.sh --arch wasm --os Browser --configuration release --subset Mono +./build.sh mono --arch wasm --os Browser -c Release ``` To build just SPC without mono you can use the Mono.CoreLib subset. ```bash -./build.sh --arch wasm --os Browser --configuration release --subset Mono.CoreLib +./build.sh mono.corelib --arch wasm --os Browser -c Release ``` - Building the managed libraries as well: ```bash -./build.sh --arch wasm --os Browser --configuration release --subset Mono+Libs +./build.sh mono+libs --arch wasm --os Browser -c Release ``` ## Building individual libraries @@ -71,16 +70,16 @@ Individual projects and libraries can be build by specifying the build configura Building individual libraries **Examples** -- Build all projects for a given library (e.g.: System.Net.Http) including running the tests +- Build all projects for a given library (e.g.: System.Net.Http) including the tests ```bash - ./build.sh --arch wasm --os Browser --configuration release --projects src/libraries/System.Net.Http/System.Net.Http.sln + ./build.sh --arch wasm --os Browser -c Release --projects src/libraries/System.Net.Http/System.Net.Http.sln ``` - Build only the source project of a given library (e.g.: System.Net.Http) ```bash - ./build.sh --arch wasm --os Browser --configuration release --projects src/libraries/System.Net.Http/src/System.Net.Http.csproj + ./build.sh --arch wasm --os Browser -c Release --projects src/libraries/System.Net.Http/src/System.Net.Http.csproj ``` More information and examples can be found in the [libraries](./README.md#building-individual-libraries) document. From 3bef7cba80180a70c8b29875aa42dbd3f4d5080c Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 30 Jul 2020 10:05:02 -0400 Subject: [PATCH 148/755] [jit] Avoid calling mono_marshal_get_native_wrapper () too early, it needs to be called when the pinvoke method is first called. (#40063) Co-authored-by: vargaz --- src/mono/mono/mini/method-to-ir.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 56f2eca3b8cd..6d1667ffcb02 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -7233,8 +7233,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } else if ((cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) && direct_icalls_enabled (cfg, cmethod)) { direct_icall = TRUE; } else if (fsig->pinvoke) { - MonoMethod *wrapper = mono_marshal_get_native_wrapper (cmethod, TRUE, cfg->compile_aot); - fsig = mono_method_signature_internal (wrapper); + if (cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) { + /* + * Avoid calling mono_marshal_get_native_wrapper () too early, it might call managed + * callbacks on netcore. + */ + fsig = mono_metadata_signature_dup_mempool (cfg->mempool, fsig); + fsig->pinvoke = FALSE; + } else { + MonoMethod *wrapper = mono_marshal_get_native_wrapper (cmethod, TRUE, cfg->compile_aot); + fsig = mono_method_signature_internal (wrapper); + } } else if (constrained_class) { } else { fsig = mono_method_get_signature_checked (cmethod, image, token, generic_context, cfg->error); @@ -7397,8 +7406,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b int costs; gboolean always = FALSE; - if ((cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || - (cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) { + if (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) { /* Prevent inlining of methods that call wrappers */ INLINE_FAILURE ("wrapper call"); // FIXME? Does this write to cmethod impact tailcall_supported? Probably not. From 278cc9658e7b12c1cb50342c4db3c67a327393a4 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Thu, 30 Jul 2020 16:43:23 +0200 Subject: [PATCH 149/755] Telemetry doesn't log datagrams failed in send/receive (#40083) --- .../src/System/Net/Sockets/Socket.cs | 119 ++++++++---------- 1 file changed, 53 insertions(+), 66 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 08eae7dbecb7..0aefb6c64647 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -1180,8 +1180,7 @@ public int Send(IList> buffers, SocketFlags socketFlags, out // Don't log transfered byte count in case of a failure. return 0; } - - if (SocketsTelemetry.Log.IsEnabled()) + else if (SocketsTelemetry.Log.IsEnabled()) { SocketsTelemetry.Log.BytesSent(bytesTransferred); if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); @@ -1237,8 +1236,7 @@ public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, ou if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); return 0; } - - if (SocketsTelemetry.Log.IsEnabled()) + else if (SocketsTelemetry.Log.IsEnabled()) { SocketsTelemetry.Log.BytesSent(bytesTransferred); if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); @@ -1279,13 +1277,10 @@ public int Send(ReadOnlySpan buffer, SocketFlags socketFlags, out SocketEr if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); bytesTransferred = 0; } - else + else if (SocketsTelemetry.Log.IsEnabled()) { - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesSent(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); - } + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); } return bytesTransferred; @@ -1351,13 +1346,10 @@ public int SendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, UpdateStatusAfterSocketErrorAndThrowException(errorCode); } - else + else if (SocketsTelemetry.Log.IsEnabled()) { - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesSent(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); - } + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); } if (_rightEndPoint == null) @@ -1437,11 +1429,6 @@ public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffer, offset, size, socketFlags, out bytesTransferred); - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1452,6 +1439,11 @@ public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); return 0; } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } if (NetEventSource.Log.IsEnabled()) NetEventSource.DumpBuffer(this, buffer, offset, bytesTransferred); @@ -1475,11 +1467,6 @@ public int Receive(Span buffer, SocketFlags socketFlags, out SocketError e int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffer, socketFlags, out bytesTransferred); - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1489,6 +1476,11 @@ public int Receive(Span buffer, SocketFlags socketFlags, out SocketError e if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); bytesTransferred = 0; } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } return bytesTransferred; } @@ -1529,11 +1521,6 @@ public int Receive(IList> buffers, SocketFlags socketFlags, o int bytesTransferred; errorCode = SocketPal.Receive(_handle, buffers, socketFlags, out bytesTransferred); - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); @@ -1544,6 +1531,11 @@ public int Receive(IList> buffers, SocketFlags socketFlags, o if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); return 0; } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } return bytesTransferred; } @@ -1595,19 +1587,18 @@ public int ReceiveMessageFrom(byte[] buffer, int offset, int size, ref SocketFla Internals.SocketAddress receiveAddress; int bytesTransferred; SocketError errorCode = SocketPal.ReceiveMessageFrom(this, _handle, buffer, offset, size, ref socketFlags, socketAddress, out receiveAddress, out ipPacketInformation, out bytesTransferred); - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); - // Throw an appropriate SocketException if the native call fails. if (errorCode != SocketError.Success && errorCode != SocketError.MessageSize) { UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (errorCode == SocketError.Success && SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } if (!socketAddressOriginal.Equals(receiveAddress)) { @@ -1676,14 +1667,8 @@ public int ReceiveFrom(byte[] buffer, int offset, int size, SocketFlags socketFl int bytesTransferred; SocketError errorCode = SocketPal.ReceiveFrom(_handle, buffer, offset, size, socketFlags, socketAddress.Buffer, ref socketAddress.InternalSize, out bytesTransferred); - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred); - // If the native call fails we'll throw a SocketException. SocketException? socketException = null; if (errorCode != SocketError.Success) @@ -1697,6 +1682,11 @@ public int ReceiveFrom(byte[] buffer, int offset, int size, SocketFlags socketFl throw socketException; } } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } if (!socketAddressOriginal.Equals(socketAddress)) { @@ -2641,6 +2631,7 @@ public int EndSend(IAsyncResult asyncResult, out SocketError errorCode) // Throw an appropriate SocketException if the native call failed asynchronously. errorCode = (SocketError)castedAsyncResult.ErrorCode; + if (errorCode != SocketError.Success) { UpdateSendSocketErrorForDisposed(ref errorCode); @@ -2649,8 +2640,7 @@ public int EndSend(IAsyncResult asyncResult, out SocketError errorCode) if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); return 0; } - - if (SocketsTelemetry.Log.IsEnabled()) + else if (SocketsTelemetry.Log.IsEnabled()) { SocketsTelemetry.Log.BytesSent(bytesTransferred); if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); @@ -2830,13 +2820,10 @@ public int EndSendTo(IAsyncResult asyncResult) UpdateSendSocketErrorForDisposed(ref errorCode); UpdateStatusAfterSocketErrorAndThrowException(errorCode); } - else + else if (SocketsTelemetry.Log.IsEnabled()) { - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesSent(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); - } + SocketsTelemetry.Log.BytesSent(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramSent(); } return bytesTransferred; @@ -3062,11 +3049,6 @@ public int EndReceive(IAsyncResult asyncResult, out SocketError errorCode) int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } // Throw an appropriate SocketException if the native call failed asynchronously. errorCode = (SocketError)castedAsyncResult.ErrorCode; @@ -3079,6 +3061,11 @@ public int EndReceive(IAsyncResult asyncResult, out SocketError errorCode) if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, new SocketException((int)errorCode)); return 0; } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } return bytesTransferred; } @@ -3223,11 +3210,6 @@ public int EndReceiveMessageFrom(IAsyncResult asyncResult, ref SocketFlags socke int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } // Update socket address size. castedAsyncResult.SocketAddress!.InternalSize = castedAsyncResult.GetSocketAddressSize(); @@ -3252,6 +3234,11 @@ public int EndReceiveMessageFrom(IAsyncResult asyncResult, ref SocketFlags socke { UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (errorCode == SocketError.Success && SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } socketFlags = castedAsyncResult.SocketFlags; ipPacketInformation = castedAsyncResult.IPPacketInformation; @@ -3431,11 +3418,6 @@ public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint) int bytesTransferred = castedAsyncResult.InternalWaitForCompletionInt32Result(); castedAsyncResult.EndCalled = true; - if (SocketsTelemetry.Log.IsEnabled()) - { - SocketsTelemetry.Log.BytesReceived(bytesTransferred); - if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); - } // Update socket address size. castedAsyncResult.SocketAddress!.InternalSize = castedAsyncResult.GetSocketAddressSize(); @@ -3460,6 +3442,11 @@ public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint) { UpdateStatusAfterSocketErrorAndThrowException(errorCode); } + else if (SocketsTelemetry.Log.IsEnabled()) + { + SocketsTelemetry.Log.BytesReceived(bytesTransferred); + if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived(); + } return bytesTransferred; } From f880aad4a58b35f6ec8e243fcda5cbf9c9fd2f09 Mon Sep 17 00:00:00 2001 From: Jarret Shook Date: Thu, 30 Jul 2020 08:27:26 -0700 Subject: [PATCH 150/755] Add first fsharp test (#39871) * Add our first fsharp test This will test some newly supported codepaths in .Net 5.0 * Working test * Small change * Addressed feedback and resolve fsharp dependencies * Add a separate dependency to be restored and copied * Fix typo --- src/coreclr/tests/build.proj | 1 + src/coreclr/tests/publishdependency.targets | 1 + .../test_dependencies.fsproj | 26 + src/coreclr/tests/src/Directory.Build.props | 1 + src/coreclr/tests/src/dirs.proj | 1 + src/coreclr/tests/src/runtest.proj | 3 + .../JIT/Directed/tailcall/mutual_recursion.fs | 561 ++++++++++++++++++ .../Directed/tailcall/mutual_recursion.fsproj | 15 + 8 files changed, 609 insertions(+) create mode 100644 src/coreclr/tests/src/Common/test_dependencies_fs/test_dependencies.fsproj create mode 100644 src/tests/JIT/Directed/tailcall/mutual_recursion.fs create mode 100644 src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj diff --git a/src/coreclr/tests/build.proj b/src/coreclr/tests/build.proj index 424cd2567539..083ab2612b75 100644 --- a/src/coreclr/tests/build.proj +++ b/src/coreclr/tests/build.proj @@ -19,6 +19,7 @@ + diff --git a/src/coreclr/tests/publishdependency.targets b/src/coreclr/tests/publishdependency.targets index 1442ad037d94..2fb248218c1b 100644 --- a/src/coreclr/tests/publishdependency.targets +++ b/src/coreclr/tests/publishdependency.targets @@ -16,6 +16,7 @@ + diff --git a/src/coreclr/tests/src/Common/test_dependencies_fs/test_dependencies.fsproj b/src/coreclr/tests/src/Common/test_dependencies_fs/test_dependencies.fsproj new file mode 100644 index 000000000000..ce4a2c2b0406 --- /dev/null +++ b/src/coreclr/tests/src/Common/test_dependencies_fs/test_dependencies.fsproj @@ -0,0 +1,26 @@ + + + BuildOnly + false + $(NetCoreAppCurrent) + true + true + win-arm;win-arm64;win-x64;win-x86;$(TargetRid) + true + Release + + + + + + $(RepoRoot)src\coreclr\tests\src\Common\test_dependencies_fs\obj\project.assets.json + + + + + + + + + + diff --git a/src/coreclr/tests/src/Directory.Build.props b/src/coreclr/tests/src/Directory.Build.props index 73cb6257a0bb..4722ae5b3bb4 100644 --- a/src/coreclr/tests/src/Directory.Build.props +++ b/src/coreclr/tests/src/Directory.Build.props @@ -139,6 +139,7 @@ true C# + F# IL diff --git a/src/coreclr/tests/src/dirs.proj b/src/coreclr/tests/src/dirs.proj index 253aea50cb91..9656ac5da61c 100644 --- a/src/coreclr/tests/src/dirs.proj +++ b/src/coreclr/tests/src/dirs.proj @@ -24,6 +24,7 @@ + diff --git a/src/coreclr/tests/src/runtest.proj b/src/coreclr/tests/src/runtest.proj index f4d3e4b88571..1cb606ef520a 100644 --- a/src/coreclr/tests/src/runtest.proj +++ b/src/coreclr/tests/src/runtest.proj @@ -405,6 +405,9 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\",""). + + ] +type Point2D(x: double, y: double) = + member _.X = x + member _.Y = y + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +// F# compiler will optimize the call away +let first() = + let callee firstArg secondArg thirdArg = + if firstArg = 10 then firstArg * secondArg * thirdArg + else firstArg + secondArg + thirdArg + + let retVal = callee 10 20 30 + + if retVal <> 6000 then + printfn "Method -- Failed, expected result: 6000, calculated: %d" retVal + + -1 + else + 0 + +// F# Compiler will optimize the call away and treat this as a loop +let second() = + let rec secondCallee(iteration, firstArg, secondArg, thirdArg) = + if iteration = 0 then + firstArg + else + let mutable retVal = + if firstArg = 10 then + firstArg * secondArg * thirdArg + else + firstArg + secondArg + thirdArg + + secondCallee(iteration - 1, retVal, secondArg, thirdArg) + + let retVal = secondCallee(100, 10, 20, 30) + + if retVal <> 10950 then + printfn "Method -- Failed, expected result: 10950, calculated: %d" retVal + -2 + else + 0 + +// F# Compiler will optimize the call away and treat this as a loop +let third() = + let rec thirdCallee(iteration, firstArg, secondArg, thirdArg, point: Point2D, secondPoint: Point2D, thirdPoint: Point2D) = + if point.X <> 10.0 then -100 + else if point.Y <> 20.0 then -101 + else if secondPoint.X <> 30.0 then -102 + else if secondPoint.Y <> 40.0 then -102 + else if thirdPoint.X <> 30.0 then -103 + else if thirdPoint.Y <> 40.0 then -103 + else if iteration = 0 then + firstArg + else + let mutable retVal = + if firstArg = 10 then + firstArg * secondArg * thirdArg + else + firstArg + secondArg + thirdArg + + if retVal > 5000 then + thirdCallee(iteration - 1, retVal, secondArg, thirdArg, point, secondPoint, thirdPoint) + else + thirdCallee(iteration - 1, secondArg, thirdArg, thirdArg, point, secondPoint, thirdPoint) + + let point = Point2D(10.0, 20.0) + let secondPoint = Point2D(30.0, 40.0) + + let retVal = thirdCallee(100, 10, 20, 30, point, secondPoint, secondPoint) + + if retVal <> 10950 then + printfn "Method -- Failed, expected result: 10950, calculated: %d" retVal + -3 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a fast tail call on unix x64 as there is no stack usage +let fourth() = + let rec fourthMethodFirstCallee(iterationCount, firstArg: Point2D, secondArg: Point2D, thirdArg: Point2D, fourthArg: Point2D) = + if firstArg.X <> 10.0 then -100 + else if firstArg.Y <> 20.0 then -101 + else if secondArg.X <> 30.0 then -102 + else if secondArg.Y <> 40.0 then -103 + else if thirdArg.X <> 10.0 then -104 + else if thirdArg.Y <> 20.0 then -105 + else if fourthArg.X <> 30.0 then -106 + else if fourthArg.Y <> 40.0 then -107 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + fourthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + else + fourthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + + and fourthMethodSecondCallee(iterationCount, firstArg, secondArg, thirdArg, fourthArg) = + if firstArg.X <> 10.0 then -150 + else if firstArg.Y <> 20.0 then -151 + else if secondArg.X <> 30.0 then -152 + else if secondArg.Y <> 40.0 then -153 + else if thirdArg.X <> 10.0 then -154 + else if thirdArg.Y <> 20.0 then -155 + else if fourthArg.X <> 30.0 then -156 + else if fourthArg.Y <> 40.0 then -157 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + fourthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + else + fourthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + + let point = Point2D(10.0, 20.0) + let secondPoint = Point2D(30.0, 40.0) + + let retVal = fourthMethodFirstCallee(1000000, point, secondPoint, point, secondPoint) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -4 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a fast tail call on unix x64 as the caller and callee have equal stack size +let fifth() = + let rec fifthMethodFirstCallee(iterationCount, firstArg: Point2D, secondArg: Point2D, thirdArg: Point2D, fourthArg: Point2D, fifthArg: Point2D) = + if firstArg.X <> 10.0 then -100 + else if firstArg.Y <> 20.0 then -101 + else if secondArg.X <> 30.0 then -102 + else if secondArg.Y <> 40.0 then -103 + else if thirdArg.X <> 10.0 then -104 + else if thirdArg.Y <> 20.0 then -105 + else if fourthArg.X <> 30.0 then -106 + else if fourthArg.Y <> 40.0 then -107 + else if fifthArg.X <> 10.0 then -108 + else if fifthArg.Y <> 20.0 then -109 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + fifthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg) + else + fifthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg) + + and fifthMethodSecondCallee(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg) = + if firstArg.X <> 10.0 then -150 + else if firstArg.Y <> 20.0 then -151 + else if secondArg.X <> 30.0 then -152 + else if secondArg.Y <> 40.0 then -153 + else if thirdArg.X <> 10.0 then -154 + else if thirdArg.Y <> 20.0 then -155 + else if fourthArg.X <> 30.0 then -156 + else if fourthArg.Y <> 40.0 then -157 + else if fifthArg.X <> 10.0 then -158 + else if fifthArg.Y <> 20.0 then -159 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + fifthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg) + else + fifthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg) + + let point = Point2D(10.0, 20.0) + let secondPoint = Point2D(30.0, 40.0) + + let retVal = fifthMethodFirstCallee(1000000, point, secondPoint, point, secondPoint, point) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -5 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a tail call via helper on unix x64 as the caller has less available incoming +// arg size than the callee +let sixth() = + let rec sixthMethodFirstCallee(iterationCount, firstArg: Point2D, secondArg: Point2D, thirdArg: Point2D, fourthArg: Point2D, fifthArg: Point2D) = + if firstArg.X <> 10.0 then -100 + else if firstArg.Y <> 20.0 then -101 + else if secondArg.X <> 30.0 then -102 + else if secondArg.Y <> 40.0 then -103 + else if thirdArg.X <> 10.0 then -104 + else if thirdArg.Y <> 20.0 then -105 + else if fourthArg.X <> 30.0 then -106 + else if fourthArg.Y <> 40.0 then -107 + else if fifthArg.X <> 10.0 then -108 + else if fifthArg.Y <> 20.0 then -109 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + sixthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + else + sixthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg) + + and sixthMethodSecondCallee(iterationCount, firstArg, secondArg, thirdArg, fourthArg) = + if firstArg.X <> 10.0 then -150 + else if firstArg.Y <> 20.0 then -151 + else if secondArg.X <> 30.0 then -152 + else if secondArg.Y <> 40.0 then -153 + else if thirdArg.X <> 10.0 then -154 + else if thirdArg.Y <> 20.0 then -155 + else if fourthArg.X <> 30.0 then -156 + else if fourthArg.Y <> 40.0 then -157 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + sixthMethodSecondCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg) + else + sixthMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, thirdArg) + + let point = new Point2D(10.0, 20.0) + let secondPoint = new Point2D(30.0, 40.0) + + let retVal = sixthMethodFirstCallee(1000000, point, secondPoint, point, secondPoint, point) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -6 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a tail call via helper on unix x64 as the caller has less available incoming +// arg size than the callee +let seventh() = + let rec seventhMethodFirstCallee(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if seventhArg <> 7 then -106 + else if eighthArg <> 8 then -107 + else if ninethArg <> 9 then -108 + else if tenthArg <> 10 then -109 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + seventhMethodSecondCallee(iterationCount) + else + seventhMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) + + and seventhMethodSecondCallee(iterationCount) = + if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + seventhMethodSecondCallee(iterationCount - 1) + else + seventhMethodFirstCallee(iterationCount - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + let retVal = seventhMethodFirstCallee(1000000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -7 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a fast tail call as the caller and callee have the incoming arg size +let seventhFastTailCall() = + let rec seventhMethodFirstCalleeFastTailCall(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if seventhArg <> 7 then -106 + else if eighthArg <> 8 then -107 + else if ninethArg <> 9 then -108 + else if tenthArg <> 10 then -109 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + seventhMethodSecondCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) + else + seventhMethodFirstCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) + + and seventhMethodSecondCalleeFastTailCall(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) = + if firstArg <> 1 then -110 + else if secondArg <> 2 then -111 + else if thirdArg <> 3 then -112 + else if fourthArg <> 4 then -113 + else if fifthArg <> 5 then -114 + else if sixthArg <> 6 then -115 + else if seventhArg <> 7 then -116 + else if eighthArg <> 8 then -117 + else if ninethArg <> 9 then -118 + else if tenthArg <> 10 then -119 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + seventhMethodSecondCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) + else + seventhMethodFirstCalleeFastTailCall(iterationCount - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + let retVal = seventhMethodFirstCalleeFastTailCall(1000000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -8 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a fast tail call as the caller and callee have the incoming arg size +let seventhFastTailCallReversed() = + let rec seventhMethodFirstCalleeFastTailCallReversed(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if seventhArg <> 7 then -106 + else if eighthArg <> 8 then -107 + else if ninethArg <> 9 then -108 + else if tenthArg <> 10 then -109 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + seventhMethodSecondCalleeFastTailCallReversed(iterationCount - 1, tenthArg, ninethArg, eighthArg, seventhArg, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + else + seventhMethodFirstCalleeFastTailCallReversed(iterationCount - 1, tenthArg, ninethArg, eighthArg, seventhArg, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + + and seventhMethodSecondCalleeFastTailCallReversed(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg, seventhArg, eighthArg, ninethArg, tenthArg) = + if firstArg <> 10 then -110 + else if secondArg <> 9 then -111 + else if thirdArg <> 8 then -112 + else if fourthArg <> 7 then -113 + else if fifthArg <> 6 then -114 + else if sixthArg <> 5 then -115 + else if seventhArg <> 4 then -116 + else if eighthArg <> 3 then -117 + else if ninethArg <> 2 then -118 + else if tenthArg <> 1 then -119 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + seventhMethodSecondCalleeFastTailCallReversed(iterationCount - 1, tenthArg, ninethArg, eighthArg, seventhArg, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + else + seventhMethodFirstCalleeFastTailCallReversed(iterationCount - 1, tenthArg, ninethArg, eighthArg, seventhArg, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + + let retVal = seventhMethodFirstCalleeFastTailCallReversed(1000000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -8 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a tail call via helper on unix x64 as the caller has less available incoming +// arg size than the callee +let eight() = + let rec eightMethodFirstCallee(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + eightMethodSecondCallee(iterationCount) + else + eightMethodFirstCallee(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) + + and eightMethodSecondCallee(iterationCount) = + if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + eightMethodSecondCallee(iterationCount - 1) + else + eightMethodFirstCallee(iterationCount - 1, 1, 2, 3, 4, 5, 6) + + let retVal = eightMethodFirstCallee(1000000, 1, 2, 3, 4, 5, 6) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -9 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a tail call via helper on unix x64 as the caller has less available incoming +// arg size than the callee +let eightFastTailCall() = + let rec eightMethodFirstCalleeFastTailCall(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + eightMethodSecondCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) + else + eightMethodFirstCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) + + and eightMethodSecondCalleeFastTailCall(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + eightMethodSecondCalleeFastTailCall(iterationCount - 1, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) + else + eightMethodFirstCalleeFastTailCall(iterationCount - 1, 1, 2, 3, 4, 5, 6) + + let retVal = eightMethodFirstCalleeFastTailCall(1000000, 1, 2, 3, 4, 5, 6) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -10 + else + 0 + +// Will create a tail il instruction and force a tail call. This is will become +// a tail call via helper on unix x64 as the caller has less available incoming +// arg size than the callee +// +// Reversing the call arguments is a simple way to stress LowerFastTailCall +let eightFastTailCallReversed() = + let rec eightMethodFirstCalleeFastTailCallReversed(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) = + if firstArg <> 1 then -100 + else if secondArg <> 2 then -101 + else if thirdArg <> 3 then -102 + else if fourthArg <> 4 then -103 + else if fifthArg <> 5 then -104 + else if sixthArg <> 6 then -105 + else if iterationCount = 0 then + 100 + else if iterationCount % 2 = 0 then + eightMethodSecondCalleeFastTailCallReversed(iterationCount - 1, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + else + eightMethodFirstCalleeFastTailCallReversed(iterationCount - 1, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + + and eightMethodSecondCalleeFastTailCallReversed(iterationCount, firstArg, secondArg, thirdArg, fourthArg, fifthArg, sixthArg) = + if firstArg <> 6 then -100 + else if secondArg <> 5 then -101 + else if thirdArg <> 4 then -102 + else if fourthArg <> 3 then -103 + else if fifthArg <> 2 then -104 + else if sixthArg <> 1 then -105 + else if iterationCount = 0 then + 101 + else if iterationCount % 2 = 0 then + eightMethodSecondCalleeFastTailCallReversed(iterationCount - 1, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + else + eightMethodFirstCalleeFastTailCallReversed(iterationCount - 1, sixthArg, fifthArg, fourthArg, thirdArg, secondArg, firstArg) + + let retVal = eightMethodFirstCalleeFastTailCallReversed(1000000, 1, 2, 3, 4, 5, 6) + + if retVal <> 100 && retVal <> 101 then + printfn "Method -- Failed, expected result: 100 or 101, calculated: %d" retVal + -11 + else + 0 + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +type Driver() = + // Notes: + // + // Drive all of the different methods that will be called and account for + // timing. + member _.Start() = + let rec runMethod(iterationCount: int, cb: _ -> int) = + if iterationCount > 0 then + let retVal = cb() + + if retVal <> 0 then + retVal + else + runMethod(iterationCount - 1, cb) + else + 0 + + let runMethodWithTiming(methodName: string, worksOnlyOnNetCore5: bool, iterationCount: int, cb: _ -> int) = + let canRun = (worksOnlyOnNetCore5 && System.Environment.Version.Major > 3) || worksOnlyOnNetCore5 = false + + if canRun then + let startTime = DateTime.Now + let retVal = runMethod(iterationCount, cb) + let endTime = DateTime.Now + + let elapsedTime = (endTime - startTime).TotalMilliseconds + + if retVal <> 0 then + failwith "Incorrect method passed" + + printfn "[%s] - %fms" methodName elapsedTime + else + printfn "[%s] - skipped. Only works on .Net Core 5.0 and above" methodName + + runMethodWithTiming("FirstMethod", false, 100000, first) + runMethodWithTiming("SecondMethod", false, 100000, second) + + // ThirdMethod will SO in debug + runMethodWithTiming("ThirdMethod", false, 100000, third) + + // FourthMethod will SO in debug + runMethodWithTiming("FourthMethod", false, 10, fourth) + + // The rest of the methods require generic tailcall helper therefore + // will only work on >3.1 + + // All the following SO in debug + + runMethodWithTiming("FifthMethod", true, 10, fifth) + runMethodWithTiming("SixthMethod", true, 10, sixth) + runMethodWithTiming("SeventhMethod", true, 10, seventh) + runMethodWithTiming("SeventhMethodFastTailCall", false, 10, seventhFastTailCall) + runMethodWithTiming("SeventhMethodFastTailCallReversed", false, 10, seventhFastTailCallReversed) + runMethodWithTiming("EigthhMethod", true, 10, eight) + runMethodWithTiming("EigthMethodFastTailCall", false, 10, eightFastTailCall) + runMethodWithTiming("EigthMethodFastTailCallReversed", false, 10, eightFastTailCallReversed) + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +[] +let main argv = + let driver = Driver() + driver.Start() + + // If we have gotten to this point we have not StackOverflowed. Therefore + // consider this a passing test + 100 diff --git a/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj b/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj new file mode 100644 index 000000000000..0a9d97a4ebc2 --- /dev/null +++ b/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj @@ -0,0 +1,15 @@ + + + Exe + + + True + True + True + True + netcoreapp3.1 + + + + + From 2892bd077eb340ee9a687d94a30a759615283b91 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 30 Jul 2020 18:02:54 +0200 Subject: [PATCH 151/755] Remove AspNetCore Testing Infra that isn't used (#40091) --- .../src/CultureReplacer.cs | 79 ----- .../src/ExceptionAssertions.cs | 271 ------------------ .../src/FlakyOn.cs | 44 --- .../src/HelixQueues.cs | 21 -- .../src/HttpClientSlim.cs | 192 ------------- .../src/ITestMethodLifecycle.cs | 23 -- .../src/RepeatAttribute.cs | 27 -- .../src/RepeatContext.cs | 27 -- .../src/ReplaceCulture.cs | 70 ----- .../src/ShortClassNameAttribute.cs | 17 -- .../src/TaskExtensions.cs | 66 ----- .../src/TestContext.cs | 44 --- .../src/TestFileOutputContext.cs | 146 ---------- .../src/TestOutputDirectoryAttribute.cs | 22 -- .../src/TestPathUtilities.cs | 37 --- .../src/TestPlatformHelper.cs | 23 -- .../src/Tracing/CollectingEventListener.cs | 63 ---- .../src/Tracing/EventAssert.cs | 63 ---- .../src/Tracing/EventSourceTestBase.cs | 42 --- .../EventSourceTestCollection.cs | 13 - .../src/xunit/AspNetTestAssemblyRunner.cs | 83 ------ .../src/xunit/AspNetTestCaseRunner.cs | 33 --- .../src/xunit/AspNetTestClassRunner.cs | 44 --- .../src/xunit/AspNetTestCollectionRunner.cs | 75 ----- .../src/xunit/AspNetTestFramework.cs | 20 -- .../src/xunit/AspNetTestFrameworkExecutor.cs | 26 -- .../src/xunit/AspNetTestInvoker.cs | 84 ------ .../src/xunit/AspNetTestMethodRunner.cs | 73 ----- .../src/xunit/AspNetTestRunner.cs | 78 ----- .../src/xunit/AspNetTheoryTestCaseRunner.cs | 33 --- .../src/xunit/AssemblyFixtureAttribute.cs | 18 -- .../src/xunit/ConditionalFactAttribute.cs | 15 - .../src/xunit/ConditionalFactDiscoverer.cs | 28 -- .../src/xunit/ConditionalTheoryAttribute.cs | 15 - .../src/xunit/ConditionalTheoryDiscoverer.cs | 87 ------ .../src/xunit/DockerOnlyAttribute.cs | 38 --- ...vironmentVariableSkipConditionAttribute.cs | 95 ------ .../src/xunit/FlakyAttribute.cs | 95 ------ .../src/xunit/FlakyTraitDiscoverer.cs | 41 --- .../xunit/FrameworkSkipConditionAttribute.cs | 57 ---- .../src/xunit/IEnvironmentVariable.cs | 10 - .../src/xunit/ITestCondition.cs | 12 - .../src/xunit/MaximumOSVersionAttribute.cs | 83 ------ .../src/xunit/MinimumOsVersionAttribute.cs | 79 ----- .../src/xunit/OSSkipConditionAttribute.cs | 62 ---- .../src/xunit/OperatingSystems.cs | 15 - .../src/xunit/RuntimeFrameworks.cs | 16 -- .../src/xunit/SkipOnCIAttribute.cs | 43 --- .../src/xunit/SkipOnHelixAttribute.cs | 50 ---- .../src/xunit/SkippedTestCase.cs | 51 ---- .../src/xunit/TestMethodExtensions.cs | 34 --- .../WORKAROUND_SkippedDataRowTestCase.cs | 83 ------ .../src/xunit/WindowsVersions.cs | 49 ---- .../test/AlphabeticalOrderer.cs | 22 -- .../test/AssemblyFixtureTest.cs | 47 --- .../test/CollectingEventListenerTest.cs | 90 ------ .../test/ConditionalFactTest.cs | 66 ----- .../test/ConditionalTheoryTest.cs | 162 ----------- .../test/DockerTests.cs | 21 -- .../EnvironmentVariableSkipConditionTest.cs | 173 ----------- .../test/ExceptionAssertTest.cs | 39 --- .../test/FlakyAttributeTest.cs | 99 ------- .../test/HttpClientSlimTest.cs | 116 -------- .../test/MaximumOSVersionAttributeTest.cs | 89 ------ .../test/MaximumOSVersionTest.cs | 92 ------ .../test/MinimumOSVersionAttributeTest.cs | 77 ----- .../test/MinimumOSVersionTest.cs | 73 ----- .../test/OSSkipConditionAttributeTest.cs | 72 ----- .../test/OSSkipConditionTest.cs | 105 ------- .../test/Properties/AssemblyInfo.cs | 9 - .../test/RepeatTest.cs | 43 --- .../test/ReplaceCultureAttributeTest.cs | 66 ----- .../test/SkipOnCITests.cs | 22 -- .../test/TaskExtensionsTest.cs | 18 -- .../test/TestAssemblyFixture.cs | 10 - .../test/TestCollectionFixture.cs | 10 - .../test/TestContextTest.cs | 83 ------ .../test/TestPathUtilitiesTest.cs | 35 --- .../test/TestPlatformHelperTest.cs | 55 ---- ...oft.Extensions.Caching.Memory.Tests.csproj | 7 - .../tests/TimeExpirationTests.cs | 40 +-- ....Extensions.Configuration.Xml.Tests.csproj | 13 - .../tests/XmlConfigurationTest.cs | 22 +- ...yInjection.ExternalContainers.Tests.csproj | 4 - ...xtensions.DependencyInjection.Tests.csproj | 4 - .../ServiceCollectionServiceExtensionsTest.cs | 6 +- .../ServiceProviderServiceExtensionsTest.cs | 9 +- .../tests/DI.Tests/ServiceTableTest.cs | 16 +- ...nsions.FileProviders.Physical.Tests.csproj | 6 +- .../tests/PhysicalFileProviderTests.cs | 1 - .../src/Deployers/SelfHostDeployer.cs | 1 - ...Extensions.Hosting.Functional.Tests.csproj | 7 +- .../tests/FunctionalTests/ShutdownTests.cs | 1 - ...ft.Extensions.Logging.Testing.Tests.csproj | 2 - 94 files changed, 35 insertions(+), 4713 deletions(-) delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/CultureReplacer.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ExceptionAssertions.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/FlakyOn.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HelixQueues.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HttpClientSlim.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ITestMethodLifecycle.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatContext.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ReplaceCulture.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ShortClassNameAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestContext.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestFileOutputContext.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestOutputDirectoryAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPathUtilities.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPlatformHelper.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/CollectingEventListener.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventAssert.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventSourceTestBase.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/contentFiles/cs/netstandard2.0/EventSourceTestCollection.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestAssemblyRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCaseRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestClassRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCollectionRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFramework.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFrameworkExecutor.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestInvoker.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestMethodRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTheoryTestCaseRunner.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AssemblyFixtureAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactDiscoverer.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryDiscoverer.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/DockerOnlyAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/EnvironmentVariableSkipConditionAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyTraitDiscoverer.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FrameworkSkipConditionAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/IEnvironmentVariable.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ITestCondition.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MaximumOSVersionAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MinimumOsVersionAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OSSkipConditionAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OperatingSystems.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/RuntimeFrameworks.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnCIAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnHelixAttribute.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkippedTestCase.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/TestMethodExtensions.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WORKAROUND_SkippedDataRowTestCase.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WindowsVersions.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AlphabeticalOrderer.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AssemblyFixtureTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/CollectingEventListenerTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/DockerTests.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/EnvironmentVariableSkipConditionTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ExceptionAssertTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/FlakyAttributeTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/HttpClientSlimTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionAttributeTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionAttributeTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionAttributeTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/Properties/AssemblyInfo.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/RepeatTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ReplaceCultureAttributeTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/SkipOnCITests.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TaskExtensionsTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestAssemblyFixture.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestCollectionFixture.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestContextTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPathUtilitiesTest.cs delete mode 100644 src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPlatformHelperTest.cs diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/CultureReplacer.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/CultureReplacer.cs deleted file mode 100644 index 85122f66f43e..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/CultureReplacer.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Globalization; -using System.Threading; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class CultureReplacer : IDisposable - { - private const string _defaultCultureName = "en-GB"; - private const string _defaultUICultureName = "en-US"; - private static readonly CultureInfo _defaultCulture = new CultureInfo(_defaultCultureName); - private readonly CultureInfo _originalCulture; - private readonly CultureInfo _originalUICulture; - private readonly long _threadId; - - // Culture => Formatting of dates/times/money/etc, defaults to en-GB because en-US is the same as InvariantCulture - // We want to be able to find issues where the InvariantCulture is used, but a specific culture should be. - // - // UICulture => Language - public CultureReplacer(string culture = _defaultCultureName, string uiCulture = _defaultUICultureName) - : this(new CultureInfo(culture), new CultureInfo(uiCulture)) - { - } - - public CultureReplacer(CultureInfo culture, CultureInfo uiCulture) - { - _originalCulture = CultureInfo.CurrentCulture; - _originalUICulture = CultureInfo.CurrentUICulture; - _threadId = Thread.CurrentThread.ManagedThreadId; - CultureInfo.CurrentCulture = culture; - CultureInfo.CurrentUICulture = uiCulture; - } - - /// - /// The name of the culture that is used as the default value for CultureInfo.DefaultThreadCurrentCulture when CultureReplacer is used. - /// - public static string DefaultCultureName - { - get { return _defaultCultureName; } - } - - /// - /// The name of the culture that is used as the default value for [Thread.CurrentThread(NET45)/CultureInfo(K10)].CurrentUICulture when CultureReplacer is used. - /// - public static string DefaultUICultureName - { - get { return _defaultUICultureName; } - } - - /// - /// The culture that is used as the default value for [Thread.CurrentThread(NET45)/CultureInfo(K10)].CurrentCulture when CultureReplacer is used. - /// - public static CultureInfo DefaultCulture - { - get { return _defaultCulture; } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposing) - { - Assert.True(Thread.CurrentThread.ManagedThreadId == _threadId, - "The current thread is not the same as the thread invoking the constructor. This should never happen."); - CultureInfo.CurrentCulture = _originalCulture; - CultureInfo.CurrentUICulture = _originalUICulture; - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ExceptionAssertions.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ExceptionAssertions.cs deleted file mode 100644 index 10bc34142f86..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ExceptionAssertions.cs +++ /dev/null @@ -1,271 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Reflection; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - // TODO: eventually want: public partial class Assert : Xunit.Assert - public static class ExceptionAssert - { - /// - /// Verifies that an exception of the given type (or optionally a derived type) is thrown. - /// - /// The type of the exception expected to be thrown - /// A delegate to the code to be tested - /// The exception that was thrown, when successful - public static TException Throws(Action testCode) - where TException : Exception - { - return VerifyException(RecordException(testCode)); - } - - /// - /// Verifies that an exception of the given type is thrown. - /// Also verifies that the exception message matches. - /// - /// The type of the exception expected to be thrown - /// A delegate to the code to be tested - /// The exception message to verify - /// The exception that was thrown, when successful - public static TException Throws(Action testCode, string exceptionMessage) - where TException : Exception - { - var ex = Throws(testCode); - VerifyExceptionMessage(ex, exceptionMessage); - return ex; - } - - /// - /// Verifies that an exception of the given type is thrown. - /// Also verifies that the exception message matches. - /// - /// The type of the exception expected to be thrown - /// A delegate to the code to be tested - /// The exception message to verify - /// The exception that was thrown, when successful - public static async Task ThrowsAsync(Func testCode, string exceptionMessage) - where TException : Exception - { - // The 'testCode' Task might execute asynchronously in a different thread making it hard to enforce the thread culture. - // The correct way to verify exception messages in such a scenario would be to run the task synchronously inside of a - // culture enforced block. - var ex = await Assert.ThrowsAsync(testCode); - VerifyExceptionMessage(ex, exceptionMessage); - return ex; - } - - /// - /// Verifies that an exception of the given type is thrown. - /// Also verified that the exception message matches. - /// - /// The type of the exception expected to be thrown - /// A delegate to the code to be tested - /// The exception message to verify - /// The exception that was thrown, when successful - public static TException Throws(Func testCode, string exceptionMessage) - where TException : Exception - { - return Throws(() => { testCode(); }, exceptionMessage); - } - - /// - /// Verifies that the code throws an . - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception message to verify - /// The exception that was thrown, when successful - public static ArgumentException ThrowsArgument(Action testCode, string paramName, string exceptionMessage) - { - return ThrowsArgumentInternal(testCode, paramName, exceptionMessage); - } - - private static TException ThrowsArgumentInternal( - Action testCode, - string paramName, - string exceptionMessage) - where TException : ArgumentException - { - var ex = Throws(testCode); - if (paramName != null) - { - Assert.Equal(paramName, ex.ParamName); - } - VerifyExceptionMessage(ex, exceptionMessage, partialMatch: true); - return ex; - } - - /// - /// Verifies that the code throws an . - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception message to verify - /// The exception that was thrown, when successful - public static Task ThrowsArgumentAsync(Func testCode, string paramName, string exceptionMessage) - { - return ThrowsArgumentAsyncInternal(testCode, paramName, exceptionMessage); - } - - private static async Task ThrowsArgumentAsyncInternal( - Func testCode, - string paramName, - string exceptionMessage) - where TException : ArgumentException - { - var ex = await Assert.ThrowsAsync(testCode); - if (paramName != null) - { - Assert.Equal(paramName, ex.ParamName); - } - VerifyExceptionMessage(ex, exceptionMessage, partialMatch: true); - return ex; - } - - /// - /// Verifies that the code throws an . - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception that was thrown, when successful - public static ArgumentNullException ThrowsArgumentNull(Action testCode, string paramName) - { - var ex = Throws(testCode); - if (paramName != null) - { - Assert.Equal(paramName, ex.ParamName); - } - return ex; - } - - /// - /// Verifies that the code throws an ArgumentException with the expected message that indicates that the value cannot - /// be null or empty. - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception that was thrown, when successful - public static ArgumentException ThrowsArgumentNullOrEmpty(Action testCode, string paramName) - { - return ThrowsArgumentInternal(testCode, paramName, "Value cannot be null or empty."); - } - - /// - /// Verifies that the code throws an ArgumentException with the expected message that indicates that the value cannot - /// be null or empty. - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception that was thrown, when successful - public static Task ThrowsArgumentNullOrEmptyAsync(Func testCode, string paramName) - { - return ThrowsArgumentAsyncInternal(testCode, paramName, "Value cannot be null or empty."); - } - - /// - /// Verifies that the code throws an ArgumentNullException with the expected message that indicates that the value cannot - /// be null or empty string. - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception that was thrown, when successful - public static ArgumentException ThrowsArgumentNullOrEmptyString(Action testCode, string paramName) - { - return ThrowsArgumentInternal(testCode, paramName, "Value cannot be null or an empty string."); - } - - /// - /// Verifies that the code throws an ArgumentNullException with the expected message that indicates that the value cannot - /// be null or empty string. - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception that was thrown, when successful - public static Task ThrowsArgumentNullOrEmptyStringAsync(Func testCode, string paramName) - { - return ThrowsArgumentAsyncInternal(testCode, paramName, "Value cannot be null or an empty string."); - } - - /// - /// Verifies that the code throws an ArgumentOutOfRangeException (or optionally any exception which derives from it). - /// - /// A delegate to the code to be tested - /// The name of the parameter that should throw the exception - /// The exception message to verify - /// The actual value provided - /// The exception that was thrown, when successful - public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCode, string paramName, string exceptionMessage, object actualValue = null) - { - var ex = ThrowsArgumentInternal(testCode, paramName, exceptionMessage); - - if (paramName != null) - { - Assert.Equal(paramName, ex.ParamName); - } - - if (actualValue != null) - { - Assert.Equal(actualValue, ex.ActualValue); - } - - return ex; - } - - // We've re-implemented all the xUnit.net Throws code so that we can get this - // updated implementation of RecordException which silently unwraps any instances - // of AggregateException. In addition to unwrapping exceptions, this method ensures - // that tests are executed in with a known set of Culture and UICulture. This prevents - // tests from failing when executed on a non-English machine. - private static Exception RecordException(Action testCode) - { - try - { - using (new CultureReplacer()) - { - testCode(); - } - return null; - } - catch (Exception exception) - { - return UnwrapException(exception); - } - } - - private static Exception UnwrapException(Exception exception) - { - var aggEx = exception as AggregateException; - return aggEx != null ? aggEx.GetBaseException() : exception; - } - - private static TException VerifyException(Exception exception) - { - var tie = exception as TargetInvocationException; - if (tie != null) - { - exception = tie.InnerException; - } - Assert.NotNull(exception); - return Assert.IsAssignableFrom(exception); - } - - private static void VerifyExceptionMessage(Exception exception, string expectedMessage, bool partialMatch = false) - { - if (expectedMessage != null) - { - if (!partialMatch) - { - Assert.Equal(expectedMessage, exception.Message); - } - else - { - Assert.Contains(expectedMessage, exception.Message); - } - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/FlakyOn.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/FlakyOn.cs deleted file mode 100644 index 45b72e32926f..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/FlakyOn.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.AspNetCore.Testing -{ - public static class FlakyOn - { - public const string All = "All"; - - public static class Helix - { - public const string All = QueuePrefix + "All"; - - public const string Fedora28Amd64 = QueuePrefix + HelixQueues.Fedora28Amd64; - public const string Fedora27Amd64 = QueuePrefix + HelixQueues.Fedora27Amd64; - public const string Redhat7Amd64 = QueuePrefix + HelixQueues.Redhat7Amd64; - public const string Debian9Amd64 = QueuePrefix + HelixQueues.Debian9Amd64; - public const string Debian8Amd64 = QueuePrefix + HelixQueues.Debian8Amd64; - public const string Centos7Amd64 = QueuePrefix + HelixQueues.Centos7Amd64; - public const string Ubuntu1604Amd64 = QueuePrefix + HelixQueues.Ubuntu1604Amd64; - public const string Ubuntu1810Amd64 = QueuePrefix + HelixQueues.Ubuntu1810Amd64; - public const string macOS1012Amd64 = QueuePrefix + HelixQueues.macOS1012Amd64; - public const string Windows10Amd64 = QueuePrefix + HelixQueues.Windows10Amd64; - - private const string Prefix = "Helix:"; - private const string QueuePrefix = Prefix + "Queue:"; - } - - public static class AzP - { - public const string All = Prefix + "All"; - public const string Windows = OsPrefix + "Windows_NT"; - public const string macOS = OsPrefix + "Darwin"; - public const string Linux = OsPrefix + "Linux"; - - private const string Prefix = "AzP:"; - private const string OsPrefix = Prefix + "OS:"; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HelixQueues.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HelixQueues.cs deleted file mode 100644 index 19b9fde028ae..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HelixQueues.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing -{ - public static class HelixQueues - { - public const string Fedora28Amd64 = "Fedora.28." + Amd64Suffix; - public const string Fedora27Amd64 = "Fedora.27." + Amd64Suffix; - public const string Redhat7Amd64 = "Redhat.7." + Amd64Suffix; - public const string Debian9Amd64 = "Debian.9." + Amd64Suffix; - public const string Debian8Amd64 = "Debian.8." + Amd64Suffix; - public const string Centos7Amd64 = "Centos.7." + Amd64Suffix; - public const string Ubuntu1604Amd64 = "Ubuntu.1604." + Amd64Suffix; - public const string Ubuntu1810Amd64 = "Ubuntu.1810." + Amd64Suffix; - public const string macOS1012Amd64 = "OSX.1012." + Amd64Suffix; - public const string Windows10Amd64 = "Windows.10.Amd64.ClientRS4.VS2017.Open"; // Doesn't have the default suffix! - - private const string Amd64Suffix = "Amd64.Open"; - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HttpClientSlim.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HttpClientSlim.cs deleted file mode 100644 index 3ef092e3a392..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/HttpClientSlim.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Globalization; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Net.Security; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Security.Authentication; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Lightweight version of HttpClient implemented using Socket and SslStream. - /// - public static class HttpClientSlim - { - public static async Task GetStringAsync(string requestUri, bool validateCertificate = true) - => await GetStringAsync(new Uri(requestUri), validateCertificate).ConfigureAwait(false); - - public static async Task GetStringAsync(Uri requestUri, bool validateCertificate = true) - { - return await RetryRequest(async () => - { - using (var stream = await GetStream(requestUri, validateCertificate).ConfigureAwait(false)) - { - using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true)) - { - await writer.WriteAsync($"GET {requestUri.PathAndQuery} HTTP/1.0\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Host: {GetHost(requestUri)}\r\n").ConfigureAwait(false); - await writer.WriteAsync("\r\n").ConfigureAwait(false); - } - - return await ReadResponse(stream).ConfigureAwait(false); - } - }); - } - - internal static string GetHost(Uri requestUri) - { - var authority = requestUri.Authority; - if (requestUri.HostNameType == UriHostNameType.IPv6) - { - // Make sure there's no % scope id. https://github.com/aspnet/KestrelHttpServer/issues/2637 - var address = IPAddress.Parse(requestUri.Host); - address = new IPAddress(address.GetAddressBytes()); // Drop scope Id. - if (requestUri.IsDefaultPort) - { - authority = $"[{address}]"; - } - else - { - authority = $"[{address}]:{requestUri.Port.ToString(CultureInfo.InvariantCulture)}"; - } - } - return authority; - } - - public static async Task PostAsync(string requestUri, HttpContent content, bool validateCertificate = true) - => await PostAsync(new Uri(requestUri), content, validateCertificate).ConfigureAwait(false); - - public static async Task PostAsync(Uri requestUri, HttpContent content, bool validateCertificate = true) - { - return await RetryRequest(async () => - { - using (var stream = await GetStream(requestUri, validateCertificate)) - { - using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true)) - { - await writer.WriteAsync($"POST {requestUri.PathAndQuery} HTTP/1.0\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Host: {requestUri.Authority}\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Content-Type: {content.Headers.ContentType}\r\n").ConfigureAwait(false); - await writer.WriteAsync($"Content-Length: {content.Headers.ContentLength}\r\n").ConfigureAwait(false); - await writer.WriteAsync("\r\n").ConfigureAwait(false); - } - - await content.CopyToAsync(stream).ConfigureAwait(false); - - return await ReadResponse(stream).ConfigureAwait(false); - } - }); - } - - private static async Task ReadResponse(Stream stream) - { - using (var reader = new StreamReader(stream, Encoding.ASCII, detectEncodingFromByteOrderMarks: true, - bufferSize: 1024, leaveOpen: true)) - { - var response = await reader.ReadToEndAsync().ConfigureAwait(false); - - var status = GetStatus(response); - new HttpResponseMessage(status).EnsureSuccessStatusCode(); - - var body = response.Substring(response.IndexOf("\r\n\r\n") + 4); - return body; - } - } - - private static async Task RetryRequest(Func> retryBlock) - { - var retryCount = 1; - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - retryCount = 3; - } - - for (var retry = 0; retry < retryCount; retry++) - { - try - { - return await retryBlock().ConfigureAwait(false); - } - catch (InvalidDataException) - { - if (retry == retryCount - 1) - { - throw; - } - } - } - - // This will never be hit. - throw new NotSupportedException(); - } - - private static HttpStatusCode GetStatus(string response) - { - var statusStart = response.IndexOf(' ') + 1; - var statusEnd = response.IndexOf(' ', statusStart) - 1; - var statusLength = statusEnd - statusStart + 1; - - if (statusLength < 1) - { - throw new InvalidDataException($"No StatusCode found in '{response}'"); - } - - return (HttpStatusCode)int.Parse(response.Substring(statusStart, statusLength)); - } - - private static async Task GetStream(Uri requestUri, bool validateCertificate) - { - var socket = await GetSocket(requestUri); - var stream = new NetworkStream(socket, ownsSocket: true); - - if (requestUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) - { - var sslStream = new SslStream(stream, leaveInnerStreamOpen: false, userCertificateValidationCallback: - validateCertificate ? null : (RemoteCertificateValidationCallback)((a, b, c, d) => true)); - - await sslStream.AuthenticateAsClientAsync(requestUri.Host, clientCertificates: null, - enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12, - checkCertificateRevocation: validateCertificate).ConfigureAwait(false); - return sslStream; - } - else - { - return stream; - } - } - - public static async Task GetSocket(Uri requestUri) - { - var tcs = new TaskCompletionSource(); - - var socketArgs = new SocketAsyncEventArgs(); - socketArgs.RemoteEndPoint = new DnsEndPoint(requestUri.DnsSafeHost, requestUri.Port); - socketArgs.Completed += (s, e) => tcs.TrySetResult(e.ConnectSocket); - - // Must use static ConnectAsync(), since instance Connect() does not support DNS names on OSX/Linux. - if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, socketArgs)) - { - await tcs.Task.ConfigureAwait(false); - } - - var socket = socketArgs.ConnectSocket; - - if (socket == null) - { - throw new SocketException((int)socketArgs.SocketError); - } - else - { - return socket; - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ITestMethodLifecycle.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ITestMethodLifecycle.cs deleted file mode 100644 index 7ea0bbf88cda..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ITestMethodLifecycle.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Defines a lifecycle for attributes or classes that want to know about tests starting - /// or ending. Implement this on a test class, or attribute at the method/class/assembly level. - /// - /// - /// Requires defining as the test framework. - /// - public interface ITestMethodLifecycle - { - Task OnTestStartAsync(TestContext context, CancellationToken cancellationToken); - - Task OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatAttribute.cs deleted file mode 100644 index ca8c85c6a8df..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.ComponentModel; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Runs a test multiple times to stress flaky tests that are believed to be fixed. - /// This can be used on an assembly, class, or method name. Requires using the AspNetCore test framework. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] - public class RepeatAttribute : Attribute - { - public RepeatAttribute(int runCount = 10) - { - RunCount = runCount; - } - - /// - /// The number of times to run a test. - /// - public int RunCount { get; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatContext.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatContext.cs deleted file mode 100644 index 91aa921e07e3..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/RepeatContext.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; - -namespace Microsoft.AspNetCore.Testing -{ - public class RepeatContext - { - private static AsyncLocal _current = new AsyncLocal(); - - public static RepeatContext Current - { - get => _current.Value; - internal set => _current.Value = value; - } - - public RepeatContext(int limit) - { - Limit = limit; - } - - public int Limit { get; } - - public int CurrentIteration { get; set; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ReplaceCulture.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ReplaceCulture.cs deleted file mode 100644 index 2c2fb51d5141..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ReplaceCulture.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Globalization; -using System.Reflection; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Replaces the current culture and UI culture for the test. - /// - [AttributeUsage(AttributeTargets.Method)] - public class ReplaceCultureAttribute : BeforeAfterTestAttribute - { - private const string _defaultCultureName = "en-GB"; - private const string _defaultUICultureName = "en-US"; - private CultureInfo _originalCulture; - private CultureInfo _originalUICulture; - - /// - /// Replaces the current culture and UI culture to en-GB and en-US respectively. - /// - public ReplaceCultureAttribute() : - this(_defaultCultureName, _defaultUICultureName) - { - } - - /// - /// Replaces the current culture and UI culture based on specified values. - /// - public ReplaceCultureAttribute(string currentCulture, string currentUICulture) - { - Culture = new CultureInfo(currentCulture); - UICulture = new CultureInfo(currentUICulture); - } - - /// - /// The for the test. Defaults to en-GB. - /// - /// - /// en-GB is used here as the default because en-US is equivalent to the InvariantCulture. We - /// want to be able to find bugs where we're accidentally relying on the Invariant instead of the - /// user's culture. - /// - public CultureInfo Culture { get; } - - /// - /// The for the test. Defaults to en-US. - /// - public CultureInfo UICulture { get; } - - public override void Before(MethodInfo methodUnderTest) - { - _originalCulture = CultureInfo.CurrentCulture; - _originalUICulture = CultureInfo.CurrentUICulture; - - CultureInfo.CurrentCulture = Culture; - CultureInfo.CurrentUICulture = UICulture; - } - - public override void After(MethodInfo methodUnderTest) - { - CultureInfo.CurrentCulture = _originalCulture; - CultureInfo.CurrentUICulture = _originalUICulture; - } - } -} - diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ShortClassNameAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ShortClassNameAttribute.cs deleted file mode 100644 index ab4f0e17f9ac..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/ShortClassNameAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Used to specify that should used the - /// unqualified class name. This is needed when a fully-qualified class name exceeds - /// max path for logging. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] - public class ShortClassNameAttribute : Attribute - { - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs deleted file mode 100644 index 9cde37ec2847..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Testing -{ - public static class TaskExtensions - { - public static async Task TimeoutAfter(this Task task, TimeSpan timeout, - [CallerFilePath] string filePath = null, - [CallerLineNumber] int lineNumber = default) - { - // Don't create a timer if the task is already completed - // or the debugger is attached - if (task.IsCompleted || Debugger.IsAttached) - { - return await task; - } - - var cts = new CancellationTokenSource(); - if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token))) - { - cts.Cancel(); - return await task; - } - else - { - throw new TimeoutException(CreateMessage(timeout, filePath, lineNumber)); - } - } - - public static async Task TimeoutAfter(this Task task, TimeSpan timeout, - [CallerFilePath] string filePath = null, - [CallerLineNumber] int lineNumber = default) - { - // Don't create a timer if the task is already completed - // or the debugger is attached - if (task.IsCompleted || Debugger.IsAttached) - { - await task; - return; - } - - var cts = new CancellationTokenSource(); - if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token))) - { - cts.Cancel(); - await task; - } - else - { - throw new TimeoutException(CreateMessage(timeout, filePath, lineNumber)); - } - } - - private static string CreateMessage(TimeSpan timeout, string filePath, int lineNumber) - => string.IsNullOrEmpty(filePath) - ? $"The operation timed out after reaching the limit of {timeout.TotalMilliseconds}ms." - : $"The operation at {filePath}:{lineNumber} timed out after reaching the limit of {timeout.TotalMilliseconds}ms."; - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestContext.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestContext.cs deleted file mode 100644 index ead7052b70da..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestContext.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Reflection; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Provides access to contextual information about the running tests. Get access by - /// implementing . - /// - /// - /// Requires defining as the test framework. - /// - public sealed class TestContext - { - private Lazy _files; - - public TestContext( - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] methodArguments, - ITestOutputHelper output) - { - TestClass = testClass; - ConstructorArguments = constructorArguments; - TestMethod = testMethod; - MethodArguments = methodArguments; - Output = output; - - _files = new Lazy(() => new TestFileOutputContext(this)); - } - - public Type TestClass { get; } - public MethodInfo TestMethod { get; } - public object[] ConstructorArguments { get; } - public object[] MethodArguments { get; } - public ITestOutputHelper Output { get; } - public TestFileOutputContext FileOutput => _files.Value; - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestFileOutputContext.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestFileOutputContext.cs deleted file mode 100644 index 91e9a1b378c7..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestFileOutputContext.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Provides access to file storage for the running test. Get access by - /// implementing , and accessing . - /// - /// - /// Requires defining as the test framework. - /// - public sealed class TestFileOutputContext - { - private static char[] InvalidFileChars = new char[] - { - '\"', '<', '>', '|', '\0', - (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, - (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, - (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, - (char)31, ':', '*', '?', '\\', '/', ' ', (char)127 - }; - - private readonly TestContext _parent; - - public TestFileOutputContext(TestContext parent) - { - _parent = parent; - - TestName = GetTestMethodName(parent.TestMethod, parent.MethodArguments); - TestClassName = GetTestClassName(parent.TestClass); - - AssemblyOutputDirectory = GetAssemblyBaseDirectory(_parent.TestClass.Assembly); - if (!string.IsNullOrEmpty(AssemblyOutputDirectory)) - { - TestClassOutputDirectory = Path.Combine(AssemblyOutputDirectory, TestClassName); - } - } - - public string TestName { get; } - - public string TestClassName { get; } - - public string AssemblyOutputDirectory { get; } - - public string TestClassOutputDirectory { get; } - - public string GetUniqueFileName(string prefix, string extension) - { - if (prefix == null) - { - throw new ArgumentNullException(nameof(prefix)); - } - - if (extension != null && !extension.StartsWith(".", StringComparison.Ordinal)) - { - throw new ArgumentException("The extension must start with '.' if one is provided.", nameof(extension)); - } - - var path = Path.Combine(TestClassOutputDirectory, $"{prefix}{extension}"); - - var i = 1; - while (File.Exists(path)) - { - path = Path.Combine(TestClassOutputDirectory, $"{prefix}{i++}{extension}"); - } - - return path; - } - - // Gets the output directory without appending the TFM or assembly name. - public static string GetOutputDirectory(Assembly assembly) - { - var attribute = assembly.GetCustomAttributes().OfType().FirstOrDefault(); - return attribute?.BaseDirectory; - } - - public static string GetAssemblyBaseDirectory(Assembly assembly, string baseDirectory = null) - { - var attribute = assembly.GetCustomAttributes().OfType().FirstOrDefault(); - baseDirectory = baseDirectory ?? attribute?.BaseDirectory; - if (string.IsNullOrEmpty(baseDirectory)) - { - return string.Empty; - } - - return Path.Combine(baseDirectory, assembly.GetName().Name, attribute.TargetFramework); - } - - public static bool GetPreserveExistingLogsInOutput(Assembly assembly) - { - var attribute = assembly.GetCustomAttributes().OfType().FirstOrDefault(); - return attribute.PreserveExistingLogsInOutput; - } - - public static string GetTestClassName(Type type) - { - var shortNameAttribute = - type.GetCustomAttribute() ?? - type.Assembly.GetCustomAttribute(); - var name = shortNameAttribute == null ? type.FullName : type.Name; - - // Try to shorten the class name using the assembly name - var assemblyName = type.Assembly.GetName().Name; - if (name.StartsWith(assemblyName + ".")) - { - name = name.Substring(assemblyName.Length + 1); - } - - return name; - } - - public static string GetTestMethodName(MethodInfo method, object[] arguments) - { - var name = arguments.Aggregate(method.Name, (a, b) => $"{a}-{(b ?? "null")}"); - return RemoveIllegalFileChars(name); - } - - public static string RemoveIllegalFileChars(string s) - { - var sb = new StringBuilder(); - - foreach (var c in s) - { - if (InvalidFileChars.Contains(c)) - { - if (sb.Length > 0 && sb[sb.Length - 1] != '_') - { - sb.Append('_'); - } - } - else - { - sb.Append(c); - } - } - return sb.ToString(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestOutputDirectoryAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestOutputDirectoryAttribute.cs deleted file mode 100644 index 1a80126300ec..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestOutputDirectoryAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = true)] - public class TestOutputDirectoryAttribute : Attribute - { - public TestOutputDirectoryAttribute(string preserveExistingLogsInOutput, string targetFramework, string baseDirectory = null) - { - TargetFramework = targetFramework; - BaseDirectory = baseDirectory; - PreserveExistingLogsInOutput = bool.Parse(preserveExistingLogsInOutput); - } - - public string BaseDirectory { get; } - public string TargetFramework { get; } - public bool PreserveExistingLogsInOutput { get; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPathUtilities.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPathUtilities.cs deleted file mode 100644 index b1711ce7a956..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPathUtilities.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; - -namespace Microsoft.AspNetCore.Testing -{ - [Obsolete("This API is obsolete and the pattern its usage encouraged should not be used anymore. See https://github.com/dotnet/extensions/issues/1697 for details.")] - public class TestPathUtilities - { - public static string GetRepoRootDirectory() - { - return GetSolutionRootDirectory("Extensions"); - } - - public static string GetSolutionRootDirectory(string solution) - { - var applicationBasePath = AppContext.BaseDirectory; - var directoryInfo = new DirectoryInfo(applicationBasePath); - - do - { - var projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, $"{solution}.sln")); - if (projectFileInfo.Exists) - { - return projectFileInfo.DirectoryName; - } - - directoryInfo = directoryInfo.Parent; - } - while (directoryInfo.Parent != null); - - throw new Exception($"Solution file {solution}.sln could not be found in {applicationBasePath} or its parent directories."); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPlatformHelper.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPlatformHelper.cs deleted file mode 100644 index 4d85c00d652d..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/TestPlatformHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - public static class TestPlatformHelper - { - public static bool IsMono => - Type.GetType("Mono.Runtime") != null; - - public static bool IsWindows => - RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - public static bool IsLinux => - RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - - public static bool IsMac => - RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/CollectingEventListener.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/CollectingEventListener.cs deleted file mode 100644 index b9d392fde8d7..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/CollectingEventListener.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics.Tracing; -using System.Linq; - -namespace Microsoft.AspNetCore.Testing.Tracing -{ - public class CollectingEventListener : EventListener - { - private ConcurrentQueue _events = new ConcurrentQueue(); - - private object _lock = new object(); - - private Dictionary _existingSources = new Dictionary(StringComparer.OrdinalIgnoreCase); - private HashSet _requestedEventSources = new HashSet(); - - public void CollectFrom(string eventSourceName) - { - lock(_lock) - { - // Check if it's already been created - if(_existingSources.TryGetValue(eventSourceName, out var existingSource)) - { - // It has, so just enable it now - CollectFrom(existingSource); - } - else - { - // It hasn't, so queue this request for when it is created - _requestedEventSources.Add(eventSourceName); - } - } - } - - public void CollectFrom(EventSource eventSource) => EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); - - public IReadOnlyList GetEventsWritten() => _events.ToArray(); - - protected override void OnEventSourceCreated(EventSource eventSource) - { - lock (_lock) - { - // Add this to the list of existing sources for future CollectEventsFrom requests. - _existingSources[eventSource.Name] = eventSource; - - // Check if we have a pending request to enable it - if (_requestedEventSources.Contains(eventSource.Name)) - { - CollectFrom(eventSource); - } - } - } - - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - _events.Enqueue(eventData); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventAssert.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventAssert.cs deleted file mode 100644 index d8601cf121be..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventAssert.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics.Tracing; -using System.Linq; -using Xunit; - -namespace Microsoft.AspNetCore.Testing.Tracing -{ - public class EventAssert - { - private readonly int _expectedId; - private readonly string _expectedName; - private readonly EventLevel _expectedLevel; - private readonly IList<(string name, Action asserter)> _payloadAsserters = new List<(string, Action)>(); - - public EventAssert(int expectedId, string expectedName, EventLevel expectedLevel) - { - _expectedId = expectedId; - _expectedName = expectedName; - _expectedLevel = expectedLevel; - } - - public static void Collection(IEnumerable events, params EventAssert[] asserts) - { - Assert.Collection( - events, - asserts.Select(a => a.CreateAsserter()).ToArray()); - } - - public static EventAssert Event(int id, string name, EventLevel level) - { - return new EventAssert(id, name, level); - } - - public EventAssert Payload(string name, object expectedValue) => Payload(name, actualValue => Assert.Equal(expectedValue, actualValue)); - - public EventAssert Payload(string name, Action asserter) - { - _payloadAsserters.Add((name, asserter)); - return this; - } - - private Action CreateAsserter() => Execute; - - private void Execute(EventWrittenEventArgs evt) - { - Assert.Equal(_expectedId, evt.EventId); - Assert.Equal(_expectedName, evt.EventName); - Assert.Equal(_expectedLevel, evt.Level); - - Action CreateNameAsserter((string name, Action asserter) val) - { - return actualValue => Assert.Equal(val.name, actualValue); - } - - Assert.Collection(evt.PayloadNames, _payloadAsserters.Select(CreateNameAsserter).ToArray()); - Assert.Collection(evt.Payload, _payloadAsserters.Select(t => t.asserter).ToArray()); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventSourceTestBase.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventSourceTestBase.cs deleted file mode 100644 index 012f4d5cbd03..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/Tracing/EventSourceTestBase.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics.Tracing; -using Xunit; - -namespace Microsoft.AspNetCore.Testing.Tracing -{ - // This collection attribute is what makes the "magic" happen. It forces xunit to run all tests that inherit from this - // base class sequentially, preventing conflicts (since EventSource/EventListener is a process-global concept). - [Collection(CollectionName)] - public abstract class EventSourceTestBase : IDisposable - { - public const string CollectionName = "Microsoft.AspNetCore.Testing.Tracing.EventSourceTestCollection"; - - private readonly CollectingEventListener _listener; - - public EventSourceTestBase() - { - _listener = new CollectingEventListener(); - } - - protected void CollectFrom(string eventSourceName) - { - _listener.CollectFrom(eventSourceName); - } - - protected void CollectFrom(EventSource eventSource) - { - _listener.CollectFrom(eventSource); - } - - protected IReadOnlyList GetEvents() => _listener.GetEventsWritten(); - - public void Dispose() - { - _listener.Dispose(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/contentFiles/cs/netstandard2.0/EventSourceTestCollection.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/contentFiles/cs/netstandard2.0/EventSourceTestCollection.cs deleted file mode 100644 index 407efc8388a4..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/contentFiles/cs/netstandard2.0/EventSourceTestCollection.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing.Tracing -{ - // This file comes from Microsoft.AspNetCore.Testing and has to be defined in the test assembly. - // It enables EventSourceTestBase's parallel isolation functionality. - - [Xunit.CollectionDefinition(EventSourceTestBase.CollectionName, DisableParallelization = true)] - public class EventSourceTestCollection - { - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestAssemblyRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestAssemblyRunner.cs deleted file mode 100644 index fa954c2b97e4..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestAssemblyRunner.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class AspNetTestAssemblyRunner : XunitTestAssemblyRunner - { - private readonly Dictionary _assemblyFixtureMappings = new Dictionary(); - - public AspNetTestAssemblyRunner( - ITestAssembly testAssembly, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageSink executionMessageSink, - ITestFrameworkExecutionOptions executionOptions) - : base(testAssembly, testCases, diagnosticMessageSink, executionMessageSink, executionOptions) - { - } - - protected override async Task AfterTestAssemblyStartingAsync() - { - await base.AfterTestAssemblyStartingAsync(); - - // Find all the AssemblyFixtureAttributes on the test assembly - Aggregator.Run(() => - { - var fixturesAttributes = ((IReflectionAssemblyInfo)TestAssembly.Assembly) - .Assembly - .GetCustomAttributes(typeof(AssemblyFixtureAttribute), false) - .Cast() - .ToList(); - - // Instantiate all the fixtures - foreach (var fixtureAttribute in fixturesAttributes) - { - var ctorWithDiagnostics = fixtureAttribute.FixtureType.GetConstructor(new[] { typeof(IMessageSink) }); - if (ctorWithDiagnostics != null) - { - _assemblyFixtureMappings[fixtureAttribute.FixtureType] = Activator.CreateInstance(fixtureAttribute.FixtureType, DiagnosticMessageSink); - } - else - { - _assemblyFixtureMappings[fixtureAttribute.FixtureType] = Activator.CreateInstance(fixtureAttribute.FixtureType); - } - } - }); - } - - protected override Task BeforeTestAssemblyFinishedAsync() - { - // Dispose fixtures - foreach (var disposable in _assemblyFixtureMappings.Values.OfType()) - { - Aggregator.Run(disposable.Dispose); - } - - return base.BeforeTestAssemblyFinishedAsync(); - } - - protected override Task RunTestCollectionAsync( - IMessageBus messageBus, - ITestCollection testCollection, - IEnumerable testCases, - CancellationTokenSource cancellationTokenSource) - => new AspNetTestCollectionRunner( - _assemblyFixtureMappings, - testCollection, - testCases, - DiagnosticMessageSink, - messageBus, - TestCaseOrderer, - new ExceptionAggregator(Aggregator), - cancellationTokenSource).RunAsync(); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCaseRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCaseRunner.cs deleted file mode 100644 index 9fa8595d217e..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCaseRunner.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - internal class AspNetTestCaseRunner : XunitTestCaseRunner - { - public AspNetTestCaseRunner( - IXunitTestCase testCase, - string displayName, - string skipReason, - object[] constructorArguments, - object[] testMethodArguments, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCase, displayName, skipReason, constructorArguments, testMethodArguments, messageBus, aggregator, cancellationTokenSource) - { - } - - protected override XunitTestRunner CreateTestRunner(ITest test, IMessageBus messageBus, Type testClass, object[] constructorArguments, MethodInfo testMethod, object[] testMethodArguments, string skipReason, IReadOnlyList beforeAfterAttributes, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) - { - return new AspNetTestRunner(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, aggregator, cancellationTokenSource); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestClassRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestClassRunner.cs deleted file mode 100644 index faddd9fe1bf7..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestClassRunner.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - internal class AspNetTestClassRunner : XunitTestClassRunner - { - public AspNetTestClassRunner( - ITestClass testClass, - IReflectionTypeInfo @class, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - IDictionary collectionFixtureMappings) - : base(testClass, @class, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource, collectionFixtureMappings) - { - } - - protected override Task RunTestMethodAsync(ITestMethod testMethod, IReflectionMethodInfo method, IEnumerable testCases, object[] constructorArguments) - { - var runner = new AspNetTestMethodRunner( - testMethod, - Class, - method, - testCases, - DiagnosticMessageSink, - MessageBus, - new ExceptionAggregator(Aggregator), - CancellationTokenSource, - constructorArguments); - return runner.RunAsync(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCollectionRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCollectionRunner.cs deleted file mode 100644 index 24c2cd16ddcb..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestCollectionRunner.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class AspNetTestCollectionRunner : XunitTestCollectionRunner - { - private readonly IDictionary _assemblyFixtureMappings; - private readonly IMessageSink _diagnosticMessageSink; - - public AspNetTestCollectionRunner( - Dictionary assemblyFixtureMappings, - ITestCollection testCollection, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCollection, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource) - { - _assemblyFixtureMappings = assemblyFixtureMappings; - _diagnosticMessageSink = diagnosticMessageSink; - } - - protected override async Task AfterTestCollectionStartingAsync() - { - await base.AfterTestCollectionStartingAsync(); - - // note: We pass the assembly fixtures into the runner as ICollectionFixture<> - this seems to work OK without any - // drawbacks. It's reasonable that we could add IAssemblyFixture<> and related plumbing if it ever became required. - // - // The reason for assembly fixture is when we want to start/stop something as the project scope - tests can only be - // in one test collection at a time. - foreach (var mapping in _assemblyFixtureMappings) - { - CollectionFixtureMappings.Add(mapping.Key, mapping.Value); - } - } - - protected override Task BeforeTestCollectionFinishedAsync() - { - // We need to remove the assembly fixtures so they won't get disposed. - foreach (var mapping in _assemblyFixtureMappings) - { - CollectionFixtureMappings.Remove(mapping.Key); - } - - return base.BeforeTestCollectionFinishedAsync(); - } - - protected override Task RunTestClassAsync(ITestClass testClass, IReflectionTypeInfo @class, IEnumerable testCases) - { - var runner = new AspNetTestClassRunner( - testClass, - @class, - testCases, - DiagnosticMessageSink, - MessageBus, - TestCaseOrderer, - new ExceptionAggregator(Aggregator), - CancellationTokenSource, - CollectionFixtureMappings); - return runner.RunAsync(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFramework.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFramework.cs deleted file mode 100644 index 369dece7b125..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFramework.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class AspNetTestFramework : XunitTestFramework - { - public AspNetTestFramework(IMessageSink messageSink) - : base(messageSink) - { - } - - protected override ITestFrameworkExecutor CreateExecutor(AssemblyName assemblyName) - => new AspNetTestFrameworkExecutor(assemblyName, SourceInformationProvider, DiagnosticMessageSink); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFrameworkExecutor.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFrameworkExecutor.cs deleted file mode 100644 index ffbab11f559e..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestFrameworkExecutor.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class AspNetTestFrameworkExecutor : XunitTestFrameworkExecutor - { - public AspNetTestFrameworkExecutor(AssemblyName assemblyName, ISourceInformationProvider sourceInformationProvider, IMessageSink diagnosticMessageSink) - : base(assemblyName, sourceInformationProvider, diagnosticMessageSink) - { - } - - protected override async void RunTestCases(IEnumerable testCases, IMessageSink executionMessageSink, ITestFrameworkExecutionOptions executionOptions) - { - using (var assemblyRunner = new AspNetTestAssemblyRunner(TestAssembly, testCases, DiagnosticMessageSink, executionMessageSink, executionOptions)) - { - await assemblyRunner.RunAsync(); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestInvoker.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestInvoker.cs deleted file mode 100644 index 118c0bdecb2d..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestInvoker.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - internal class AspNetTestInvoker : XunitTestInvoker - { - public AspNetTestInvoker( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] testMethodArguments, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, beforeAfterAttributes, aggregator, cancellationTokenSource) - { - } - - protected override async Task InvokeTestMethodAsync(object testClassInstance) - { - var output = new TestOutputHelper(); - output.Initialize(MessageBus, Test); - - var context = new TestContext(TestClass, ConstructorArguments, TestMethod, TestMethodArguments, output); - var lifecycleHooks = GetLifecycleHooks(testClassInstance, TestClass, TestMethod); - - await Aggregator.RunAsync(async () => - { - foreach (var lifecycleHook in lifecycleHooks) - { - await lifecycleHook.OnTestStartAsync(context, CancellationTokenSource.Token); - } - }); - - var time = await base.InvokeTestMethodAsync(testClassInstance); - - await Aggregator.RunAsync(async () => - { - var exception = Aggregator.HasExceptions ? Aggregator.ToException() : null; - foreach (var lifecycleHook in lifecycleHooks) - { - await lifecycleHook.OnTestEndAsync(context, exception, CancellationTokenSource.Token); - } - }); - - return time; - } - - private static IEnumerable GetLifecycleHooks(object testClassInstance, Type testClass, MethodInfo testMethod) - { - foreach (var attribute in testMethod.GetCustomAttributes(inherit: true).OfType()) - { - yield return attribute; - } - - if (testClassInstance is ITestMethodLifecycle instance) - { - yield return instance; - } - - foreach (var attribute in testClass.GetCustomAttributes(inherit: true).OfType()) - { - yield return attribute; - } - - foreach (var attribute in testClass.Assembly.GetCustomAttributes(inherit: true).OfType()) - { - yield return attribute; - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestMethodRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestMethodRunner.cs deleted file mode 100644 index 35f5e09de3e9..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestMethodRunner.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing.xunit; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - internal class AspNetTestMethodRunner : XunitTestMethodRunner - { - private readonly object[] _constructorArguments; - private readonly IMessageSink _diagnosticMessageSink; - - public AspNetTestMethodRunner( - ITestMethod testMethod, - IReflectionTypeInfo @class, - IReflectionMethodInfo method, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - object[] constructorArguments) - : base(testMethod, @class, method, testCases, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource, constructorArguments) - { - _diagnosticMessageSink = diagnosticMessageSink; - _constructorArguments = constructorArguments; - } - - protected override Task RunTestCaseAsync(IXunitTestCase testCase) - { - if (testCase.GetType() == typeof(XunitTestCase)) - { - // If we get here this is a 'regular' test case, not something that represents a skipped test. - // - // We can take control of it's invocation thusly. - var runner = new AspNetTestCaseRunner( - testCase, - testCase.DisplayName, - testCase.SkipReason, - _constructorArguments, - testCase.TestMethodArguments, - MessageBus, - new ExceptionAggregator(Aggregator), - CancellationTokenSource); - return runner.RunAsync(); - } - - if (testCase.GetType() == typeof(XunitTheoryTestCase)) - { - // If we get here this is a 'regular' theory test case, not something that represents a skipped test. - // - // We can take control of it's invocation thusly. - var runner = new AspNetTheoryTestCaseRunner( - testCase, - testCase.DisplayName, - testCase.SkipReason, - _constructorArguments, - _diagnosticMessageSink, - MessageBus, - new ExceptionAggregator(Aggregator), - CancellationTokenSource); - return runner.RunAsync(); - } - - return base.RunTestCaseAsync(testCase); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestRunner.cs deleted file mode 100644 index f1f07947fac9..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTestRunner.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - internal class AspNetTestRunner : XunitTestRunner - { - public AspNetTestRunner( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] testMethodArguments, - string skipReason, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, aggregator, cancellationTokenSource) - { - } - - protected override async Task InvokeTestMethodAsync(ExceptionAggregator aggregator) - { - var repeatAttribute = GetRepeatAttribute(TestMethod); - if (repeatAttribute == null) - { - return await InvokeTestMethodCoreAsync(aggregator); - } - - var repeatContext = new RepeatContext(repeatAttribute.RunCount); - RepeatContext.Current = repeatContext; - - var timeTaken = 0.0M; - for (repeatContext.CurrentIteration = 0; repeatContext.CurrentIteration < repeatContext.Limit; repeatContext.CurrentIteration++) - { - timeTaken = await InvokeTestMethodCoreAsync(aggregator); - if (aggregator.HasExceptions) - { - return timeTaken; - } - } - - return timeTaken; - } - - private Task InvokeTestMethodCoreAsync(ExceptionAggregator aggregator) - { - var invoker = new AspNetTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource); - return invoker.RunAsync(); - } - - private RepeatAttribute GetRepeatAttribute(MethodInfo methodInfo) - { - var attributeCandidate = methodInfo.GetCustomAttribute(); - if (attributeCandidate != null) - { - return attributeCandidate; - } - - attributeCandidate = methodInfo.DeclaringType.GetCustomAttribute(); - if (attributeCandidate != null) - { - return attributeCandidate; - } - - return methodInfo.DeclaringType.Assembly.GetCustomAttribute(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTheoryTestCaseRunner.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTheoryTestCaseRunner.cs deleted file mode 100644 index f9d5810f99c6..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AspNetTheoryTestCaseRunner.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing.xunit -{ - internal class AspNetTheoryTestCaseRunner : XunitTheoryTestCaseRunner - { - public AspNetTheoryTestCaseRunner( - IXunitTestCase testCase, - string displayName, - string skipReason, - object[] constructorArguments, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCase, displayName, skipReason, constructorArguments, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource) - { - } - - protected override XunitTestRunner CreateTestRunner(ITest test, IMessageBus messageBus, Type testClass, object[] constructorArguments, MethodInfo testMethod, object[] testMethodArguments, string skipReason, IReadOnlyList beforeAfterAttributes, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) - { - return new AspNetTestRunner(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, aggregator, cancellationTokenSource); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AssemblyFixtureAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AssemblyFixtureAttribute.cs deleted file mode 100644 index 428eb0215730..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/AssemblyFixtureAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public class AssemblyFixtureAttribute : Attribute - { - public AssemblyFixtureAttribute(Type fixtureType) - { - FixtureType = fixtureType; - } - - public Type FixtureType { get; private set; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactAttribute.cs deleted file mode 100644 index 8f128fdb1e2d..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - [XunitTestCaseDiscoverer("Microsoft.AspNetCore.Testing." + nameof(ConditionalFactDiscoverer), "Microsoft.AspNetCore.Testing")] - public class ConditionalFactAttribute : FactAttribute - { - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactDiscoverer.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactDiscoverer.cs deleted file mode 100644 index 339ee1d92025..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalFactDiscoverer.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit.Abstractions; -using Xunit.Sdk; - -// Do not change this namespace without changing the usage in ConditionalFactAttribute -namespace Microsoft.AspNetCore.Testing -{ - internal class ConditionalFactDiscoverer : FactDiscoverer - { - private readonly IMessageSink _diagnosticMessageSink; - - public ConditionalFactDiscoverer(IMessageSink diagnosticMessageSink) - : base(diagnosticMessageSink) - { - _diagnosticMessageSink = diagnosticMessageSink; - } - - protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) - { - var skipReason = testMethod.EvaluateSkipConditions(); - return skipReason != null - ? new SkippedTestCase(skipReason, _diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) - : base.CreateTestCase(discoveryOptions, testMethod, factAttribute); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryAttribute.cs deleted file mode 100644 index 6030392df694..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - [XunitTestCaseDiscoverer("Microsoft.AspNetCore.Testing." + nameof(ConditionalTheoryDiscoverer), "Microsoft.AspNetCore.Testing")] - public class ConditionalTheoryAttribute : TheoryAttribute - { - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryDiscoverer.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryDiscoverer.cs deleted file mode 100644 index 2fbff9bf2e7f..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ConditionalTheoryDiscoverer.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Xunit.Abstractions; -using Xunit.Sdk; - -// Do not change this namespace without changing the usage in ConditionalTheoryAttribute -namespace Microsoft.AspNetCore.Testing -{ - internal class ConditionalTheoryDiscoverer : TheoryDiscoverer - { - public ConditionalTheoryDiscoverer(IMessageSink diagnosticMessageSink) - : base(diagnosticMessageSink) - { - } - - private sealed class OptionsWithPreEnumerationEnabled : ITestFrameworkDiscoveryOptions - { - private const string PreEnumerateTheories = "xunit.discovery.PreEnumerateTheories"; - - private readonly ITestFrameworkDiscoveryOptions _original; - - public OptionsWithPreEnumerationEnabled(ITestFrameworkDiscoveryOptions original) - => _original = original; - - public TValue GetValue(string name) - => (name == PreEnumerateTheories) ? (TValue)(object)true : _original.GetValue(name); - - public void SetValue(string name, TValue value) - => _original.SetValue(name, value); - } - - public override IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute) - => base.Discover(new OptionsWithPreEnumerationEnabled(discoveryOptions), testMethod, theoryAttribute); - - protected override IEnumerable CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute) - { - var skipReason = testMethod.EvaluateSkipConditions(); - return skipReason != null - ? new[] { new SkippedTestCase(skipReason, DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) } - : base.CreateTestCasesForTheory(discoveryOptions, testMethod, theoryAttribute); - } - - protected override IEnumerable CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow) - { - var skipReason = testMethod.EvaluateSkipConditions(); - if (skipReason == null && dataRow?.Length > 0) - { - var obj = dataRow[0]; - if (obj != null) - { - var type = obj.GetType(); - var property = type.GetProperty("Skip"); - if (property != null && property.PropertyType.Equals(typeof(string))) - { - skipReason = property.GetValue(obj) as string; - } - } - } - - return skipReason != null ? - base.CreateTestCasesForSkippedDataRow(discoveryOptions, testMethod, theoryAttribute, dataRow, skipReason) - : base.CreateTestCasesForDataRow(discoveryOptions, testMethod, theoryAttribute, dataRow); - } - - protected override IEnumerable CreateTestCasesForSkippedDataRow( - ITestFrameworkDiscoveryOptions discoveryOptions, - ITestMethod testMethod, - IAttributeInfo theoryAttribute, - object[] dataRow, - string skipReason) - { - return new[] - { - new WORKAROUND_SkippedDataRowTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, skipReason, dataRow), - }; - } - - [Obsolete] - protected override IXunitTestCase CreateTestCaseForSkippedDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow, string skipReason) - { - return new WORKAROUND_SkippedDataRowTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, skipReason, dataRow); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/DockerOnlyAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/DockerOnlyAttribute.cs deleted file mode 100644 index 0536a9dc5928..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/DockerOnlyAttribute.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public sealed class DockerOnlyAttribute : Attribute, ITestCondition - { - public string SkipReason { get; } = "This test can only run in a Docker container."; - - public bool IsMet - { - get - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // we currently don't have a good way to detect if running in a Windows container - return false; - } - - const string procFile = "/proc/1/cgroup"; - if (!File.Exists(procFile)) - { - return false; - } - - var lines = File.ReadAllLines(procFile); - // typically the last line in the file is "1:name=openrc:/docker" - return lines.Reverse().Any(l => l.EndsWith("name=openrc:/docker", StringComparison.Ordinal)); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/EnvironmentVariableSkipConditionAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/EnvironmentVariableSkipConditionAttribute.cs deleted file mode 100644 index b7dbed476b2e..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/EnvironmentVariableSkipConditionAttribute.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Linq; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Skips a test when the value of an environment variable matches any of the supplied values. - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] - public class EnvironmentVariableSkipConditionAttribute : Attribute, ITestCondition - { - private readonly string _variableName; - private readonly string[] _values; - private string _currentValue; - private readonly IEnvironmentVariable _environmentVariable; - - /// - /// Creates a new instance of . - /// - /// Name of the environment variable. - /// Value(s) of the environment variable to match for the test to be skipped - public EnvironmentVariableSkipConditionAttribute(string variableName, params string[] values) - : this(new EnvironmentVariable(), variableName, values) - { - } - - // To enable unit testing - internal EnvironmentVariableSkipConditionAttribute( - IEnvironmentVariable environmentVariable, - string variableName, - params string[] values) - { - if (environmentVariable == null) - { - throw new ArgumentNullException(nameof(environmentVariable)); - } - if (variableName == null) - { - throw new ArgumentNullException(nameof(variableName)); - } - if (values == null) - { - throw new ArgumentNullException(nameof(values)); - } - - _variableName = variableName; - _values = values; - _environmentVariable = environmentVariable; - } - - /// - /// Runs the test only if the value of the variable matches any of the supplied values. Default is True. - /// - public bool RunOnMatch { get; set; } = true; - - public bool IsMet - { - get - { - _currentValue = _environmentVariable.Get(_variableName); - var hasMatched = _values.Any(value => string.Compare(value, _currentValue, ignoreCase: true) == 0); - - if (RunOnMatch) - { - return hasMatched; - } - else - { - return !hasMatched; - } - } - } - - public string SkipReason - { - get - { - var value = _currentValue == null ? "(null)" : _currentValue; - return $"Test skipped on environment variable with name '{_variableName}' and value '{value}' " + - $"for the '{nameof(RunOnMatch)}' value of '{RunOnMatch}'."; - } - } - - private struct EnvironmentVariable : IEnvironmentVariable - { - public string Get(string name) - { - return Environment.GetEnvironmentVariable(name); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyAttribute.cs deleted file mode 100644 index a08dac81b125..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyAttribute.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Marks a test as "Flaky" so that the build will sequester it and ignore failures. - /// - /// - /// - /// This attribute works by applying xUnit.net "Traits" based on the criteria specified in the attribute - /// properties. Once these traits are applied, build scripts can include/exclude tests based on them. - /// - /// - /// All flakiness-related traits start with Flaky: and are grouped first by the process running the tests: Azure Pipelines (AzP) or Helix. - /// Then there is a segment specifying the "selector" which indicates where the test is flaky. Finally a segment specifying the value of that selector. - /// The value of these traits is always either "true" or the trait is not present. We encode the entire selector in the name of the trait because xUnit.net only - /// provides "==" and "!=" operators for traits, there is no way to check if a trait "contains" or "does not contain" a value. VSTest does support "contains" checks - /// but does not appear to support "does not contain" checks. Using this pattern means we can use simple "==" and "!=" checks to either only run flaky tests, or exclude - /// flaky tests. - /// - /// - /// - /// - /// [Fact] - /// [Flaky("...", HelixQueues.Fedora28Amd64, AzurePipelines.macOS)] - /// public void FlakyTest() - /// { - /// // Flakiness - /// } - /// - /// - /// - /// The above example generates the following facets: - /// - /// - /// - /// - /// Flaky:Helix:Queue:Fedora.28.Amd64.Open = true - /// - /// - /// Flaky:AzP:OS:Darwin = true - /// - /// - /// - /// - /// Given the above attribute, the Azure Pipelines macOS run can easily filter this test out by passing -notrait "Flaky:AzP:OS:all=true" -notrait "Flaky:AzP:OS:Darwin=true" - /// to xunit.console.exe. Similarly, it can run only flaky tests using -trait "Flaky:AzP:OS:all=true" -trait "Flaky:AzP:OS:Darwin=true" - /// - /// - [TraitDiscoverer("Microsoft.AspNetCore.Testing." + nameof(FlakyTraitDiscoverer), "Microsoft.AspNetCore.Testing")] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] - public sealed class FlakyAttribute : Attribute, ITraitAttribute - { - /// - /// Gets a URL to a GitHub issue tracking this flaky test. - /// - public string GitHubIssueUrl { get; } - - public IReadOnlyList Filters { get; } - - /// - /// Initializes a new instance of the class with the specified and a list of . If no - /// filters are provided, the test is considered flaky in all environments. - /// - /// - /// At least one filter is required. - /// - /// The URL to a GitHub issue tracking this flaky test. - /// The first filter that indicates where the test is flaky. Use a value from . - /// A list of additional filters that define where this test is flaky. Use values in . - public FlakyAttribute(string gitHubIssueUrl, string firstFilter, params string[] additionalFilters) - { - if (string.IsNullOrEmpty(gitHubIssueUrl)) - { - throw new ArgumentNullException(nameof(gitHubIssueUrl)); - } - - if (string.IsNullOrEmpty(firstFilter)) - { - throw new ArgumentNullException(nameof(firstFilter)); - } - - GitHubIssueUrl = gitHubIssueUrl; - var filters = new List(); - filters.Add(firstFilter); - filters.AddRange(additionalFilters); - Filters = filters; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyTraitDiscoverer.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyTraitDiscoverer.cs deleted file mode 100644 index 1964f20ddae2..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FlakyTraitDiscoverer.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Xunit.Abstractions; -using Xunit.Sdk; - -// Do not change this namespace without changing the usage in FlakyAttribute -namespace Microsoft.AspNetCore.Testing -{ - public class FlakyTraitDiscoverer : ITraitDiscoverer - { - public IEnumerable> GetTraits(IAttributeInfo traitAttribute) - { - if (traitAttribute is ReflectionAttributeInfo attribute && attribute.Attribute is FlakyAttribute flakyAttribute) - { - return GetTraitsCore(flakyAttribute); - } - else - { - throw new InvalidOperationException("The 'Flaky' attribute is only supported via reflection."); - } - } - - private IEnumerable> GetTraitsCore(FlakyAttribute attribute) - { - if (attribute.Filters.Count > 0) - { - foreach (var filter in attribute.Filters) - { - yield return new KeyValuePair($"Flaky:{filter}", "true"); - } - } - else - { - yield return new KeyValuePair($"Flaky:All", "true"); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FrameworkSkipConditionAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FrameworkSkipConditionAttribute.cs deleted file mode 100644 index 906f0c4d4604..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/FrameworkSkipConditionAttribute.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public class FrameworkSkipConditionAttribute : Attribute, ITestCondition - { - private readonly RuntimeFrameworks _excludedFrameworks; - - public FrameworkSkipConditionAttribute(RuntimeFrameworks excludedFrameworks) - { - _excludedFrameworks = excludedFrameworks; - } - - public bool IsMet - { - get - { - return CanRunOnThisFramework(_excludedFrameworks); - } - } - - public string SkipReason { get; set; } = "Test cannot run on this runtime framework."; - - private static bool CanRunOnThisFramework(RuntimeFrameworks excludedFrameworks) - { - if (excludedFrameworks == RuntimeFrameworks.None) - { - return true; - } - -#if NETFRAMEWORK - if (excludedFrameworks.HasFlag(RuntimeFrameworks.Mono) && - TestPlatformHelper.IsMono) - { - return false; - } - - if (excludedFrameworks.HasFlag(RuntimeFrameworks.CLR)) - { - return false; - } -#elif NETSTANDARD2_0 || NETCOREAPP - if (excludedFrameworks.HasFlag(RuntimeFrameworks.CoreCLR)) - { - return false; - } -#else -#error Target frameworks need to be updated. -#endif - return true; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/IEnvironmentVariable.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/IEnvironmentVariable.cs deleted file mode 100644 index 1fbe0320fa72..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/IEnvironmentVariable.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing -{ - internal interface IEnvironmentVariable - { - string Get(string name); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ITestCondition.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ITestCondition.cs deleted file mode 100644 index d15a78a48882..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/ITestCondition.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing -{ - public interface ITestCondition - { - bool IsMet { get; } - - string SkipReason { get; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MaximumOSVersionAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MaximumOSVersionAttribute.cs deleted file mode 100644 index 29b89212d3a6..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MaximumOSVersionAttribute.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Skips a test if the OS is the given type (Windows) and the OS version is greater than specified. - /// E.g. Specifying Window 8 skips on Win 10, but not on Linux. Combine with OSSkipConditionAttribute as needed. - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] - public class MaximumOSVersionAttribute : Attribute, ITestCondition - { - private readonly OperatingSystems _targetOS; - private readonly Version _maxVersion; - private readonly OperatingSystems _currentOS; - private readonly Version _currentVersion; - private readonly bool _skip; - - public MaximumOSVersionAttribute(OperatingSystems operatingSystem, string maxVersion) : - this(operatingSystem, Version.Parse(maxVersion), GetCurrentOS(), GetCurrentOSVersion()) - { - } - - // to enable unit testing - internal MaximumOSVersionAttribute(OperatingSystems targetOS, Version maxVersion, OperatingSystems currentOS, Version currentVersion) - { - if (targetOS != OperatingSystems.Windows) - { - throw new NotImplementedException("Max version support is only implemented for Windows."); - } - _targetOS = targetOS; - _maxVersion = maxVersion; - _currentOS = currentOS; - // We drop the 4th field because it is not significant and it messes up the comparisons. - _currentVersion = new Version(currentVersion.Major, currentVersion.Minor, - // Major and Minor are required by the parser, but if Build isn't specified then it returns -1 - // which the constructor rejects. - currentVersion.Build == -1 ? 0 : currentVersion.Build); - - // Do not skip other OS's, Use OSSkipConditionAttribute or a separate MaximumOsVersionAttribute for that. - _skip = _targetOS == _currentOS && _maxVersion < _currentVersion; - SkipReason = $"This test requires {_targetOS} {_maxVersion} or earlier."; - } - - // Since a test would be executed only if 'IsMet' is true, return false if we want to skip - public bool IsMet => !_skip; - - public string SkipReason { get; set; } - - private static OperatingSystems GetCurrentOS() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return OperatingSystems.Windows; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return OperatingSystems.Linux; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return OperatingSystems.MacOSX; - } - throw new PlatformNotSupportedException(); - } - - static private Version GetCurrentOSVersion() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return Environment.OSVersion.Version; - } - else - { - // Not implemented, but this will still be called before the OS check happens so don't throw. - return new Version(0, 0); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MinimumOsVersionAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MinimumOsVersionAttribute.cs deleted file mode 100644 index bf37323fe453..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/MinimumOsVersionAttribute.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Skips a test if the OS is the given type (Windows) and the OS version is less than specified. - /// E.g. Specifying Window 10.0 skips on Win 8, but not on Linux. Combine with OSSkipConditionAttribute as needed. - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] - public class MinimumOSVersionAttribute : Attribute, ITestCondition - { - private readonly OperatingSystems _targetOS; - private readonly Version _minVersion; - private readonly OperatingSystems _currentOS; - private readonly Version _currentVersion; - private readonly bool _skip; - - public MinimumOSVersionAttribute(OperatingSystems operatingSystem, string minVersion) : - this(operatingSystem, Version.Parse(minVersion), GetCurrentOS(), GetCurrentOSVersion()) - { - } - - // to enable unit testing - internal MinimumOSVersionAttribute(OperatingSystems targetOS, Version minVersion, OperatingSystems currentOS, Version currentVersion) - { - if (targetOS != OperatingSystems.Windows) - { - throw new NotImplementedException("Min version support is only implemented for Windows."); - } - _targetOS = targetOS; - _minVersion = minVersion; - _currentOS = currentOS; - _currentVersion = currentVersion; - - // Do not skip other OS's, Use OSSkipConditionAttribute or a separate MinimumOSVersionAttribute for that. - _skip = _targetOS == _currentOS && _minVersion > _currentVersion; - SkipReason = $"This test requires {_targetOS} {_minVersion} or later."; - } - - // Since a test would be executed only if 'IsMet' is true, return false if we want to skip - public bool IsMet => !_skip; - - public string SkipReason { get; set; } - - private static OperatingSystems GetCurrentOS() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return OperatingSystems.Windows; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return OperatingSystems.Linux; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return OperatingSystems.MacOSX; - } - throw new PlatformNotSupportedException(); - } - - static private Version GetCurrentOSVersion() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return Environment.OSVersion.Version; - } - else - { - // Not implemented, but this will still be called before the OS check happens so don't throw. - return new Version(0, 0); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OSSkipConditionAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OSSkipConditionAttribute.cs deleted file mode 100644 index 2a804e309865..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OSSkipConditionAttribute.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] - public class OSSkipConditionAttribute : Attribute, ITestCondition - { - private readonly OperatingSystems _excludedOperatingSystem; - private readonly OperatingSystems _osPlatform; - - public OSSkipConditionAttribute(OperatingSystems operatingSystem) : - this(operatingSystem, GetCurrentOS()) - { - } - - [Obsolete("Use the Minimum/MaximumOSVersionAttribute for version checks.", error: true)] - public OSSkipConditionAttribute(OperatingSystems operatingSystem, params string[] versions) : - this(operatingSystem, GetCurrentOS()) - { - } - - // to enable unit testing - internal OSSkipConditionAttribute(OperatingSystems operatingSystem, OperatingSystems osPlatform) - { - _excludedOperatingSystem = operatingSystem; - _osPlatform = osPlatform; - } - - public bool IsMet - { - get - { - var skip = (_excludedOperatingSystem & _osPlatform) == _osPlatform; - // Since a test would be excuted only if 'IsMet' is true, return false if we want to skip - return !skip; - } - } - - public string SkipReason { get; set; } = "Test cannot run on this operating system."; - - static private OperatingSystems GetCurrentOS() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return OperatingSystems.Windows; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return OperatingSystems.Linux; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return OperatingSystems.MacOSX; - } - throw new PlatformNotSupportedException(); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OperatingSystems.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OperatingSystems.cs deleted file mode 100644 index 7f04934ba65f..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/OperatingSystems.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - [Flags] - public enum OperatingSystems - { - Linux = 1, - MacOSX = 2, - Windows = 4, - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/RuntimeFrameworks.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/RuntimeFrameworks.cs deleted file mode 100644 index 274ea1357350..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/RuntimeFrameworks.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - [Flags] - public enum RuntimeFrameworks - { - None = 0, - Mono = 1 << 0, - CLR = 1 << 1, - CoreCLR = 1 << 2 - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnCIAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnCIAttribute.cs deleted file mode 100644 index c89001ee9f99..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnCIAttribute.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Skip test if running on CI - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)] - public class SkipOnCIAttribute : Attribute, ITestCondition - { - public SkipOnCIAttribute(string issueUrl = "") - { - IssueUrl = issueUrl; - } - - public string IssueUrl { get; } - - public bool IsMet - { - get - { - return !OnCI(); - } - } - - public string SkipReason - { - get - { - return $"This test is skipped on CI"; - } - } - - public static bool OnCI() => OnHelix() || OnAzdo(); - public static bool OnHelix() => !string.IsNullOrEmpty(GetTargetHelixQueue()); - public static string GetTargetHelixQueue() => Environment.GetEnvironmentVariable("helix"); - public static bool OnAzdo() => !string.IsNullOrEmpty(GetIfOnAzdo()); - public static string GetIfOnAzdo() => Environment.GetEnvironmentVariable("AGENT_OS"); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnHelixAttribute.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnHelixAttribute.cs deleted file mode 100644 index f0aa92be054c..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkipOnHelixAttribute.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Linq; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// Skip test if running on helix (or a particular helix queue). - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)] - public class SkipOnHelixAttribute : Attribute, ITestCondition - { - public SkipOnHelixAttribute(string issueUrl) - { - if (string.IsNullOrEmpty(issueUrl)) - { - throw new ArgumentException(); - } - IssueUrl = issueUrl; - } - - public string IssueUrl { get; } - - public bool IsMet - { - get - { - var skip = OnHelix() && (Queues == null || Queues.ToLowerInvariant().Split(';').Contains(GetTargetHelixQueue().ToLowerInvariant())); - return !skip; - } - } - - // Queues that should be skipped on, i.e. "Windows.10.Amd64.ClientRS4.VS2017.Open;OSX.1012.Amd64.Open" - public string Queues { get; set; } - - public string SkipReason - { - get - { - return $"This test is skipped on helix"; - } - } - - public static bool OnHelix() => !string.IsNullOrEmpty(GetTargetHelixQueue()); - - public static string GetTargetHelixQueue() => Environment.GetEnvironmentVariable("helix"); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkippedTestCase.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkippedTestCase.cs deleted file mode 100644 index 890bb35b967a..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/SkippedTestCase.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class SkippedTestCase : XunitTestCase - { - private string _skipReason; - - [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] - public SkippedTestCase() : base() - { - } - - public SkippedTestCase( - string skipReason, - IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod, - object[] testMethodArguments = null) - : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments) - { - _skipReason = skipReason; - } - - protected override string GetSkipReason(IAttributeInfo factAttribute) - => _skipReason ?? base.GetSkipReason(factAttribute); - - public override void Deserialize(IXunitSerializationInfo data) - { - _skipReason = data.GetValue(nameof(_skipReason)); - - // We need to call base after reading our value, because Deserialize will call - // into GetSkipReason. - base.Deserialize(data); - } - - public override void Serialize(IXunitSerializationInfo data) - { - base.Serialize(data); - data.AddValue(nameof(_skipReason), _skipReason); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/TestMethodExtensions.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/TestMethodExtensions.cs deleted file mode 100644 index 36b29195cb8b..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/TestMethodExtensions.cs +++ /dev/null @@ -1,34 +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 Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public static class TestMethodExtensions - { - public static string EvaluateSkipConditions(this ITestMethod testMethod) - { - var testClass = testMethod.TestClass.Class; - var assembly = testMethod.TestClass.TestCollection.TestAssembly.Assembly; - var conditionAttributes = testMethod.Method - .GetCustomAttributes(typeof(ITestCondition)) - .Concat(testClass.GetCustomAttributes(typeof(ITestCondition))) - .Concat(assembly.GetCustomAttributes(typeof(ITestCondition))) - .OfType() - .Select(attributeInfo => attributeInfo.Attribute); - - foreach (ITestCondition condition in conditionAttributes) - { - if (!condition.IsMet) - { - return condition.SkipReason; - } - } - - return null; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WORKAROUND_SkippedDataRowTestCase.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WORKAROUND_SkippedDataRowTestCase.cs deleted file mode 100644 index 22dea010c215..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WORKAROUND_SkippedDataRowTestCase.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.ComponentModel; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - // This is a workaround for https://github.com/xunit/xunit/issues/1782 - as such, this code is a copy-paste - // from xUnit with the exception of fixing the bug. - // - // This will only work with [ConditionalTheory]. - internal class WORKAROUND_SkippedDataRowTestCase : XunitTestCase - { - string skipReason; - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] - public WORKAROUND_SkippedDataRowTestCase() { } - - /// - /// Initializes a new instance of the class. - /// - /// The message sink used to send diagnostic messages - /// Default method display to use (when not customized). - /// The test method this test case belongs to. - /// The reason that this test case will be skipped - /// The arguments for the test method. - [Obsolete("Please call the constructor which takes TestMethodDisplayOptions")] - public WORKAROUND_SkippedDataRowTestCase(IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - ITestMethod testMethod, - string skipReason, - object[] testMethodArguments = null) - : this(diagnosticMessageSink, defaultMethodDisplay, TestMethodDisplayOptions.None, testMethod, skipReason, testMethodArguments) { } - - /// - /// Initializes a new instance of the class. - /// - /// The message sink used to send diagnostic messages - /// Default method display to use (when not customized). - /// Default method display options to use (when not customized). - /// The test method this test case belongs to. - /// The reason that this test case will be skipped - /// The arguments for the test method. - public WORKAROUND_SkippedDataRowTestCase(IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod, - string skipReason, - object[] testMethodArguments = null) - : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments) - { - this.skipReason = skipReason; - } - - /// - public override void Deserialize(IXunitSerializationInfo data) - { - // SkipReason has to be read before we call base.Deserialize, this is the workaround. - this.skipReason = data.GetValue("SkipReason"); - - base.Deserialize(data); - } - - /// - protected override string GetSkipReason(IAttributeInfo factAttribute) - { - return skipReason; - } - - /// - public override void Serialize(IXunitSerializationInfo data) - { - base.Serialize(data); - - data.AddValue("SkipReason", skipReason); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WindowsVersions.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WindowsVersions.cs deleted file mode 100644 index 093904689850..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/src/xunit/WindowsVersions.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.AspNetCore.Testing -{ - /// - /// https://en.wikipedia.org/wiki/Windows_10_version_history - /// - public static class WindowsVersions - { - public const string Win7 = "6.1"; - - [Obsolete("Use Win7 instead.", error: true)] - public const string Win2008R2 = Win7; - - public const string Win8 = "6.2"; - - public const string Win81 = "6.3"; - - public const string Win10 = "10.0"; - - /// - /// 1803, RS4, 17134 - /// - public const string Win10_RS4 = "10.0.17134"; - - /// - /// 1809, RS5, 17763 - /// - public const string Win10_RS5 = "10.0.17763"; - - /// - /// 1903, 19H1, 18362 - /// - public const string Win10_19H1 = "10.0.18362"; - - /// - /// 1909, 19H2, 18363 - /// - public const string Win10_19H2 = "10.0.18363"; - - /// - /// 2004, 20H1, 19033 - /// - public const string Win10_20H1 = "10.0.19033"; - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AlphabeticalOrderer.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AlphabeticalOrderer.cs deleted file mode 100644 index 34eef71dffab..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AlphabeticalOrderer.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Testing -{ - public class AlphabeticalOrderer : ITestCaseOrderer - { - public IEnumerable OrderTestCases(IEnumerable testCases) - where TTestCase : ITestCase - { - var result = testCases.ToList(); - result.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name)); - return result; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AssemblyFixtureTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AssemblyFixtureTest.cs deleted file mode 100644 index 15673ce89634..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/AssemblyFixtureTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - // We include a collection and assembly fixture to verify that they both still work. - [Collection("MyCollection")] - [TestCaseOrderer("Microsoft.AspNetCore.Testing.AlphabeticalOrderer", "Microsoft.AspNetCore.Testing.Tests")] - public class AssemblyFixtureTest - { - public AssemblyFixtureTest(TestAssemblyFixture assemblyFixture, TestCollectionFixture collectionFixture) - { - AssemblyFixture = assemblyFixture; - CollectionFixture = collectionFixture; - } - - public TestAssemblyFixture AssemblyFixture { get; } - public TestCollectionFixture CollectionFixture { get; } - - [Fact] - public void A() - { - Assert.NotNull(AssemblyFixture); - Assert.Equal(0, AssemblyFixture.Count); - - Assert.NotNull(CollectionFixture); - Assert.Equal(0, CollectionFixture.Count); - - AssemblyFixture.Count++; - CollectionFixture.Count++; - } - - [Fact] - public void B() - { - Assert.Equal(1, AssemblyFixture.Count); - Assert.Equal(1, CollectionFixture.Count); - } - } - - [CollectionDefinition("MyCollection", DisableParallelization = true)] - public class MyCollection : ICollectionFixture - { - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/CollectingEventListenerTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/CollectingEventListenerTest.cs deleted file mode 100644 index 466a14ecdd14..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/CollectingEventListenerTest.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.Tracing; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing.Tracing; -using Xunit; - -namespace Microsoft.AspNetCore.Testing.Tests -{ - // We are verifying here that when event listener tests are spread among multiple classes, they still - // work, even when run in parallel. To do that we have a bunch of tests in different classes (since - // that affects parallelism) and do some Task.Yielding in them. - public class CollectingEventListenerTests - { - public abstract class CollectingTestBase : EventSourceTestBase - { - [Fact] - public async Task CollectingEventListenerTest() - { - CollectFrom("Microsoft-AspNetCore-Testing-Test"); - - await Task.Yield(); - TestEventSource.Log.Test(); - await Task.Yield(); - TestEventSource.Log.TestWithPayload(42, 4.2); - await Task.Yield(); - - var events = GetEvents(); - EventAssert.Collection(events, - EventAssert.Event(1, "Test", EventLevel.Informational), - EventAssert.Event(2, "TestWithPayload", EventLevel.Verbose) - .Payload("payload1", 42) - .Payload("payload2", 4.2)); - } - } - - // These tests are designed to interfere with the collecting ones by running in parallel and writing events - public abstract class NonCollectingTestBase - { - [Fact] - public async Task CollectingEventListenerTest() - { - await Task.Yield(); - TestEventSource.Log.Test(); - await Task.Yield(); - TestEventSource.Log.TestWithPayload(42, 4.2); - await Task.Yield(); - } - } - - public class CollectingTests - { - public class A : CollectingTestBase { } - public class B : CollectingTestBase { } - public class C : CollectingTestBase { } - public class D : CollectingTestBase { } - public class E : CollectingTestBase { } - public class F : CollectingTestBase { } - public class G : CollectingTestBase { } - } - - public class NonCollectingTests - { - public class A : NonCollectingTestBase { } - public class B : NonCollectingTestBase { } - public class C : NonCollectingTestBase { } - public class D : NonCollectingTestBase { } - public class E : NonCollectingTestBase { } - public class F : NonCollectingTestBase { } - public class G : NonCollectingTestBase { } - } - } - - [EventSource(Name = "Microsoft-AspNetCore-Testing-Test")] - public class TestEventSource : EventSource - { - public static readonly TestEventSource Log = new TestEventSource(); - - private TestEventSource() - { - } - - [Event(eventId: 1, Level = EventLevel.Informational, Message = "Test")] - public void Test() => WriteEvent(1); - - [Event(eventId: 2, Level = EventLevel.Verbose, Message = "Test")] - public void TestWithPayload(int payload1, double payload2) => WriteEvent(2, payload1, payload2); - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs deleted file mode 100644 index c66728c0ac96..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalFactTest.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - [TestCaseOrderer("Microsoft.AspNetCore.Testing.AlphabeticalOrderer", "Microsoft.AspNetCore.Testing.Tests")] - public class ConditionalFactTest : IClassFixture - { - public ConditionalFactTest(ConditionalFactAsserter collector) - { - Asserter = collector; - } - - private ConditionalFactAsserter Asserter { get; } - - [Fact] - public void TestAlwaysRun() - { - // This is required to ensure that the type at least gets initialized. - Assert.True(true); - } - - [ConditionalFact(Skip = "Test is always skipped.")] - public void ConditionalFactSkip() - { - Assert.True(false, "This test should always be skipped."); - } - -#if NETCOREAPP - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.CLR)] - public void ThisTestMustRunOnCoreCLR() - { - Asserter.TestRan = true; - } -#elif NETFRAMEWORK - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.CoreCLR)] - public void ThisTestMustRunOnCLR() - { - Asserter.TestRan = true; - } -#else -#error Target frameworks need to be updated. -#endif - - // Test is named this way to be the lowest test in the alphabet, it relies on test ordering - [Fact] - public void ZzzzzzzEnsureThisIsTheLastTest() - { - Assert.True(Asserter.TestRan); - } - - public class ConditionalFactAsserter : IDisposable - { - public bool TestRan { get; set; } - - public void Dispose() - { - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs deleted file mode 100644 index b55264f85da2..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ConditionalTheoryTest.cs +++ /dev/null @@ -1,162 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Testing -{ - [TestCaseOrderer("Microsoft.AspNetCore.Testing.AlphabeticalOrderer", "Microsoft.AspNetCore.Testing.Tests")] - public class ConditionalTheoryTest : IClassFixture - { - public ConditionalTheoryTest(ConditionalTheoryAsserter asserter) - { - Asserter = asserter; - } - - public ConditionalTheoryAsserter Asserter { get; } - - [ConditionalTheory(Skip = "Test is always skipped.")] - [InlineData(0)] - public void ConditionalTheorySkip(int arg) - { - Assert.True(false, "This test should always be skipped."); - } - - private static int _conditionalTheoryRuns = 0; - - [ConditionalTheory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2, Skip = "Skip these data")] - public void ConditionalTheoryRunOncePerDataLine(int arg) - { - _conditionalTheoryRuns++; - Assert.True(_conditionalTheoryRuns <= 2, $"Theory should run 2 times, but ran {_conditionalTheoryRuns} times."); - } - - [ConditionalTheory, Trait("Color", "Blue")] - [InlineData(1)] - public void ConditionalTheoriesShouldPreserveTraits(int arg) - { - Assert.True(true); - } - - [ConditionalTheory(Skip = "Skip this")] - [MemberData(nameof(GetInts))] - public void ConditionalTheoriesWithSkippedMemberData(int arg) - { - Assert.True(false, "This should never run"); - } - - private static int _conditionalMemberDataRuns = 0; - - [ConditionalTheory] - [InlineData(4)] - [MemberData(nameof(GetInts))] - public void ConditionalTheoriesWithMemberData(int arg) - { - _conditionalMemberDataRuns++; - Assert.True(_conditionalTheoryRuns <= 3, $"Theory should run 2 times, but ran {_conditionalMemberDataRuns} times."); - } - - public static TheoryData GetInts - => new TheoryData { 0, 1 }; - - [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Windows)] - [OSSkipCondition(OperatingSystems.MacOSX)] - [OSSkipCondition(OperatingSystems.Linux)] - [MemberData(nameof(GetActionTestData))] - public void ConditionalTheoryWithFuncs(Func func) - { - Assert.True(false, "This should never run"); - } - - [Fact] - public void TestAlwaysRun() - { - // This is required to ensure that this type at least gets initialized. - Assert.True(true); - } - -#if NETCOREAPP - [ConditionalTheory] - [FrameworkSkipCondition(RuntimeFrameworks.CLR)] - [MemberData(nameof(GetInts))] - public void ThisTestMustRunOnCoreCLR(int value) - { - Asserter.TestRan = true; - } -#elif NETFRAMEWORK - [ConditionalTheory] - [FrameworkSkipCondition(RuntimeFrameworks.CoreCLR)] - [MemberData(nameof(GetInts))] - public void ThisTestMustRunOnCLR(int value) - { - Asserter.TestRan = true; - } -#else -#error Target frameworks need to be updated. -#endif - - // Test is named this way to be the lowest test in the alphabet, it relies on test ordering - [Fact] - public void ZzzzzzzEnsureThisIsTheLastTest() - { - Assert.True(Asserter.TestRan); - } - - public static TheoryData> GetActionTestData - => new TheoryData> - { - (i) => i * 1 - }; - - public class ConditionalTheoryAsserter : IDisposable - { - public bool TestRan { get; set; } - - public void Dispose() - { - } - } - - [ConditionalTheory] - [MemberData(nameof(SkippableData))] - public void WithSkipableData(Skippable skippable) - { - Assert.Null(skippable.Skip); - Assert.Equal(1, skippable.Data); - } - - public static TheoryData SkippableData => new TheoryData - { - new Skippable() { Data = 1 }, - new Skippable() { Data = 2, Skip = "This row should be skipped." } - }; - - public class Skippable : IXunitSerializable - { - public Skippable() { } - public int Data { get; set; } - public string Skip { get; set; } - - public void Serialize(IXunitSerializationInfo info) - { - info.AddValue(nameof(Data), Data, typeof(int)); - } - - public void Deserialize(IXunitSerializationInfo info) - { - Data = info.GetValue(nameof(Data)); - } - - public override string ToString() - { - return Data.ToString(); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/DockerTests.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/DockerTests.cs deleted file mode 100644 index eb61e7cfe058..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/DockerTests.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Microsoft.AspNetCore.Testing; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class DockerTests - { - [ConditionalFact] - [DockerOnly] - [Trait("Docker", "true")] - public void DoesNotRunOnWindows() - { - Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/EnvironmentVariableSkipConditionTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/EnvironmentVariableSkipConditionTest.cs deleted file mode 100644 index e85552780c19..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/EnvironmentVariableSkipConditionTest.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class EnvironmentVariableSkipConditionTest - { - private readonly string _skipReason = "Test skipped on environment variable with name '{0}' and value '{1}'" + - $" for the '{nameof(EnvironmentVariableSkipConditionAttribute.RunOnMatch)}' value of '{{2}}'."; - - [Theory] - [InlineData("false")] - [InlineData("")] - [InlineData(null)] - public void IsMet_DoesNotMatch(string environmentVariableValue) - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("Run", environmentVariableValue), - "Run", - "true"); - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.False(isMet); - } - - [Theory] - [InlineData("True")] - [InlineData("TRUE")] - [InlineData("true")] - public void IsMet_DoesCaseInsensitiveMatch_OnValue(string environmentVariableValue) - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("Run", environmentVariableValue), - "Run", - "true"); - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.True(isMet); - Assert.Equal( - string.Format(_skipReason, "Run", environmentVariableValue, attribute.RunOnMatch), - attribute.SkipReason); - } - - [Fact] - public void IsMet_DoesSuccessfulMatch_OnNull() - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("Run", null), - "Run", - "true", null); // skip the test when the variable 'Run' is explicitly set to 'true' or is null (default) - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.True(isMet); - Assert.Equal( - string.Format(_skipReason, "Run", "(null)", attribute.RunOnMatch), - attribute.SkipReason); - } - - [Theory] - [InlineData("false")] - [InlineData("")] - [InlineData(null)] - public void IsMet_MatchesOnMultipleSkipValues(string environmentVariableValue) - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("Run", environmentVariableValue), - "Run", - "false", "", null); - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.True(isMet); - } - - [Fact] - public void IsMet_DoesNotMatch_OnMultipleSkipValues() - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("Build", "100"), - "Build", - "125", "126"); - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.False(isMet); - } - - [Theory] - [InlineData("CentOS")] - [InlineData(null)] - [InlineData("")] - public void IsMet_Matches_WhenRunOnMatchIsFalse(string environmentVariableValue) - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("LinuxFlavor", environmentVariableValue), - "LinuxFlavor", - "Ubuntu14.04") - { - // Example: Run this test on all OSes except on "Ubuntu14.04" - RunOnMatch = false - }; - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.True(isMet); - } - - [Fact] - public void IsMet_DoesNotMatch_WhenRunOnMatchIsFalse() - { - // Arrange - var attribute = new EnvironmentVariableSkipConditionAttribute( - new TestEnvironmentVariable("LinuxFlavor", "Ubuntu14.04"), - "LinuxFlavor", - "Ubuntu14.04") - { - // Example: Run this test on all OSes except on "Ubuntu14.04" - RunOnMatch = false - }; - - // Act - var isMet = attribute.IsMet; - - // Assert - Assert.False(isMet); - } - - private struct TestEnvironmentVariable : IEnvironmentVariable - { - private readonly string _varName; - - public TestEnvironmentVariable(string varName, string value) - { - _varName = varName; - Value = value; - } - - public string Value { get; private set; } - - public string Get(string name) - { - if(string.Equals(name, _varName, System.StringComparison.OrdinalIgnoreCase)) - { - return Value; - } - return string.Empty; - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ExceptionAssertTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ExceptionAssertTest.cs deleted file mode 100644 index 52455b0694ee..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ExceptionAssertTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class ExceptionAssertTest - { - [Fact] - [ReplaceCulture("fr-FR", "fr-FR")] - public void AssertArgumentNullOrEmptyString_WorksInNonEnglishCultures() - { - // Arrange - Action action = () => - { - throw new ArgumentException("Value cannot be null or an empty string.", "foo"); - }; - - // Act and Assert - ExceptionAssert.ThrowsArgumentNullOrEmptyString(action, "foo"); - } - - [Fact] - [ReplaceCulture("fr-FR", "fr-FR")] - public void AssertArgumentOutOfRangeException_WorksInNonEnglishCultures() - { - // Arrange - Action action = () => - { - throw new ArgumentOutOfRangeException("foo", 10, "exception message."); - }; - - // Act and Assert - ExceptionAssert.ThrowsArgumentOutOfRange(action, "foo", "exception message.", 10); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/FlakyAttributeTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/FlakyAttributeTest.cs deleted file mode 100644 index db342c12b862..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/FlakyAttributeTest.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Xunit; - -namespace Microsoft.AspNetCore.Testing.Tests -{ - public class FlakyAttributeTest - { - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.All)] - public void AlwaysFlakyInCI() - { - if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HELIX")) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("AGENT_OS"))) - { - throw new Exception("Flaky!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.Helix.All)] - public void FlakyInHelixOnly() - { - if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HELIX"))) - { - throw new Exception("Flaky on Helix!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.Helix.macOS1012Amd64, FlakyOn.Helix.Fedora28Amd64)] - public void FlakyInSpecificHelixQueue() - { - // Today we don't run Extensions tests on Helix, but this test should light up when we do. - var queueName = Environment.GetEnvironmentVariable("HELIX"); - if (!string.IsNullOrEmpty(queueName)) - { - var failingQueues = new HashSet(StringComparer.OrdinalIgnoreCase) { HelixQueues.macOS1012Amd64, HelixQueues.Fedora28Amd64 }; - if (failingQueues.Contains(queueName)) - { - throw new Exception($"Flaky on Helix Queue '{queueName}' !"); - } - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.AzP.All)] - public void FlakyInAzPOnly() - { - if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("AGENT_OS"))) - { - throw new Exception("Flaky on AzP!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.AzP.Windows)] - public void FlakyInAzPWindowsOnly() - { - if (string.Equals(Environment.GetEnvironmentVariable("AGENT_OS"), "Windows_NT")) - { - throw new Exception("Flaky on AzP Windows!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.AzP.macOS)] - public void FlakyInAzPmacOSOnly() - { - if (string.Equals(Environment.GetEnvironmentVariable("AGENT_OS"), "Darwin")) - { - throw new Exception("Flaky on AzP macOS!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.AzP.Linux)] - public void FlakyInAzPLinuxOnly() - { - if (string.Equals(Environment.GetEnvironmentVariable("AGENT_OS"), "Linux")) - { - throw new Exception("Flaky on AzP Linux!"); - } - } - - [Fact(Skip = "These tests are nice when you need them but annoying when on all the time.")] - [Flaky("http://example.com", FlakyOn.AzP.Linux, FlakyOn.AzP.macOS)] - public void FlakyInAzPNonWindowsOnly() - { - var agentOs = Environment.GetEnvironmentVariable("AGENT_OS"); - if (string.Equals(agentOs, "Linux") || string.Equals(agentOs, "Darwin")) - { - throw new Exception("Flaky on AzP non-Windows!"); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/HttpClientSlimTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/HttpClientSlimTest.cs deleted file mode 100644 index 10ae3f7a5ab8..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/HttpClientSlimTest.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class HttpClientSlimTest - { - private static readonly byte[] _defaultResponse = Encoding.ASCII.GetBytes("test"); - - [Fact] - public async Task GetStringAsyncHttp() - { - using (var host = StartHost(out var address)) - { - Assert.Equal("test", await HttpClientSlim.GetStringAsync(address)); - } - } - - [Fact] - public async Task GetStringAsyncThrowsForErrorResponse() - { - using (var host = StartHost(out var address, statusCode: 500)) - { - await Assert.ThrowsAnyAsync(() => HttpClientSlim.GetStringAsync(address)); - } - } - - [Fact] - public async Task PostAsyncHttp() - { - using (var host = StartHost(out var address, handler: context => context.Request.InputStream.CopyToAsync(context.Response.OutputStream))) - { - Assert.Equal("test post", await HttpClientSlim.PostAsync(address, new StringContent("test post"))); - } - } - - [Fact] - public async Task PostAsyncThrowsForErrorResponse() - { - using (var host = StartHost(out var address, statusCode: 500)) - { - await Assert.ThrowsAnyAsync( - () => HttpClientSlim.PostAsync(address, new StringContent(""))); - } - } - - [Fact] - public void Ipv6ScopeIdsFilteredOut() - { - var requestUri = new Uri("http://[fe80::5d2a:d070:6fd6:1bac%7]:5003/"); - Assert.Equal("[fe80::5d2a:d070:6fd6:1bac]:5003", HttpClientSlim.GetHost(requestUri)); - } - - [Fact] - public void GetHostExcludesDefaultPort() - { - var requestUri = new Uri("http://[fe80::5d2a:d070:6fd6:1bac%7]:80/"); - Assert.Equal("[fe80::5d2a:d070:6fd6:1bac]", HttpClientSlim.GetHost(requestUri)); - } - - private HttpListener StartHost(out string address, int statusCode = 200, Func handler = null) - { - var listener = new HttpListener(); - var random = new Random(); - address = null; - - for (var i = 0; i < 10; i++) - { - try - { - // HttpListener doesn't support requesting port 0 (dynamic). - // Requesting port 0 from Sockets and then passing that to HttpListener is racy. - // Just keep trying until we find a free one. - address = $"http://localhost:{random.Next(1024, ushort.MaxValue)}/"; - listener.Prefixes.Add(address); - listener.Start(); - break; - } - catch (HttpListenerException) - { - // Address in use - listener.Close(); - listener = new HttpListener(); - } - } - - Assert.True(listener.IsListening, "IsListening"); - - _ = listener.GetContextAsync().ContinueWith(async task => - { - var context = task.Result; - context.Response.StatusCode = statusCode; - - if (handler == null) - { - await context.Response.OutputStream.WriteAsync(_defaultResponse, 0, _defaultResponse.Length); - } - else - { - await handler(context); - } - - context.Response.Close(); - }); - - return listener; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionAttributeTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionAttributeTest.cs deleted file mode 100644 index 1cc772ce4e36..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionAttributeTest.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class MaximumOSVersionAttributeTest - { - [Fact] - public void Linux_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MaximumOSVersionAttribute(OperatingSystems.Linux, "2.5")); - } - - [Fact] - public void Mac_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MaximumOSVersionAttribute(OperatingSystems.MacOSX, "2.5")); - } - - [Fact] - public void WindowsOrLinux_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MaximumOSVersionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, "2.5")); - } - - [Fact] - public void DoesNotSkip_ShortVersions() - { - var osSkipAttribute = new MaximumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5"), - OperatingSystems.Windows, - new Version("2.0")); - - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_EarlierVersions() - { - var osSkipAttribute = new MaximumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5.9"), - OperatingSystems.Windows, - new Version("2.0.10.12")); - - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_SameVersion() - { - var osSkipAttribute = new MaximumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5.10"), - OperatingSystems.Windows, - new Version("2.5.10.12")); - - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void Skip_LaterVersion() - { - var osSkipAttribute = new MaximumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5.11"), - OperatingSystems.Windows, - new Version("3.0.10.12")); - - Assert.False(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_WhenOnlyVersionsMatch() - { - var osSkipAttribute = new MaximumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5.10.12"), - OperatingSystems.Linux, - new Version("2.5.10.12")); - - Assert.True(osSkipAttribute.IsMet); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionTest.cs deleted file mode 100644 index 1b0586aeb99f..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MaximumOSVersionTest.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Win32; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public class MaximumOSVersionTest - { - [ConditionalFact] - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] - public void RunTest_Win7DoesRunOnWin7() - { - Assert.True( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should only be running on Win7 or Win2008R2."); - } - - [ConditionalTheory] - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] - [InlineData(1)] - public void RunTheory_Win7DoesRunOnWin7(int arg) - { - Assert.True( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should only be running on Win7 or Win2008R2."); - } - - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.CLR, SkipReason = "https://github.com/xunit/xunit/issues/2076")] - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public void RunTest_Win10_RS4() - { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); - Assert.NotNull(versionKey); - var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber"); - Assert.NotNull(currentVersion); - Assert.True(17134 >= int.Parse(currentVersion), $"Unexpected build number {currentVersion} on {Environment.OSVersion.Version}."); - } - - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.CLR, SkipReason = "https://github.com/xunit/xunit/issues/2076")] - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2)] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public void RunTest_Win10_19H2() - { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); - Assert.NotNull(versionKey); - var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber"); - Assert.NotNull(currentVersion); - Assert.True(18363 >= int.Parse(currentVersion), $"Unexpected build number {currentVersion} on {Environment.OSVersion.Version}."); - } - } - - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public class OSMaxVersionClassTest - { - [ConditionalFact] - public void TestSkipClass_Win7DoesRunOnWin7() - { - Assert.True( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should only be running on Win7 or Win2008R2."); - } - } - - // Let this one run cross plat just to check the constructor logic. - [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] - public class OSMaxVersionCrossPlatTest - { - [ConditionalFact] - public void TestSkipClass_Win7DoesRunOnWin7() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.True(Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should only be running on Win7 or Win2008R2."); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionAttributeTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionAttributeTest.cs deleted file mode 100644 index c4e1120bc854..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionAttributeTest.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class MinimumOSVersionAttributeTest - { - [Fact] - public void Linux_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MinimumOSVersionAttribute(OperatingSystems.Linux, "2.5")); - } - - [Fact] - public void Mac_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MinimumOSVersionAttribute(OperatingSystems.MacOSX, "2.5")); - } - - [Fact] - public void WindowsOrLinux_ThrowsNotImplemeneted() - { - Assert.Throws(() => new MinimumOSVersionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, "2.5")); - } - - [Fact] - public void DoesNotSkip_LaterVersions() - { - var osSkipAttribute = new MinimumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.0"), - OperatingSystems.Windows, - new Version("2.5")); - - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_SameVersion() - { - var osSkipAttribute = new MinimumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5"), - OperatingSystems.Windows, - new Version("2.5")); - - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void Skip_EarlierVersion() - { - var osSkipAttribute = new MinimumOSVersionAttribute( - OperatingSystems.Windows, - new Version("3.0"), - OperatingSystems.Windows, - new Version("2.5")); - - Assert.False(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_WhenOnlyVersionsMatch() - { - var osSkipAttribute = new MinimumOSVersionAttribute( - OperatingSystems.Windows, - new Version("2.5"), - OperatingSystems.Linux, - new Version("2.5")); - - Assert.True(osSkipAttribute.IsMet); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionTest.cs deleted file mode 100644 index ba45f1c4306d..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/MinimumOSVersionTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Win32; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class MinimumOSVersionTest - { - [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] - public void RunTest_Win8DoesNotRunOnWin7() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should not be running on Win7 or Win2008R2."); - } - - [ConditionalTheory] - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] - [InlineData(1)] - public void RunTheory_Win8DoesNotRunOnWin7(int arg) - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should not be running on Win7 or Win2008R2."); - } - - [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public void RunTest_Win10_RS4() - { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); - Assert.NotNull(versionKey); - var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber"); - Assert.NotNull(currentVersion); - Assert.True(17134 <= int.Parse(currentVersion)); - } - - [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2)] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public void RunTest_Win10_19H2() - { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); - Assert.NotNull(versionKey); - var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber"); - Assert.NotNull(currentVersion); - Assert.True(18363 <= int.Parse(currentVersion)); - } - } - - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] - public class OSMinVersionClassTest - { - [ConditionalFact] - public void TestSkipClass_Win8DoesNotRunOnWin7() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && - Environment.OSVersion.Version.ToString().StartsWith("6.1"), - "Test should not be running on Win7 or Win2008R2."); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionAttributeTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionAttributeTest.cs deleted file mode 100644 index 53e2ed774ff3..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionAttributeTest.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class OSSkipConditionAttributeTest - { - [Fact] - public void Skips_WhenOperatingSystemMatches() - { - // Act - var osSkipAttribute = new OSSkipConditionAttribute( - OperatingSystems.Windows, - OperatingSystems.Windows); - - // Assert - Assert.False(osSkipAttribute.IsMet); - } - - [Fact] - public void DoesNotSkip_WhenOperatingSystemDoesNotMatch() - { - // Act - var osSkipAttribute = new OSSkipConditionAttribute( - OperatingSystems.Linux, - OperatingSystems.Windows); - - // Assert - Assert.True(osSkipAttribute.IsMet); - } - - [Fact] - public void Skips_BothMacOSXAndLinux() - { - // Act - var osSkipAttributeLinux = new OSSkipConditionAttribute(OperatingSystems.Linux | OperatingSystems.MacOSX, OperatingSystems.Linux); - var osSkipAttributeMacOSX = new OSSkipConditionAttribute(OperatingSystems.Linux | OperatingSystems.MacOSX, OperatingSystems.MacOSX); - - // Assert - Assert.False(osSkipAttributeLinux.IsMet); - Assert.False(osSkipAttributeMacOSX.IsMet); - } - - [Fact] - public void Skips_BothMacOSXAndWindows() - { - // Act - var osSkipAttribute = new OSSkipConditionAttribute(OperatingSystems.Windows | OperatingSystems.MacOSX, OperatingSystems.Windows); - var osSkipAttributeMacOSX = new OSSkipConditionAttribute(OperatingSystems.Windows | OperatingSystems.MacOSX, OperatingSystems.MacOSX); - - // Assert - Assert.False(osSkipAttribute.IsMet); - Assert.False(osSkipAttributeMacOSX.IsMet); - } - - [Fact] - public void Skips_BothWindowsAndLinux() - { - // Act - var osSkipAttribute = new OSSkipConditionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, OperatingSystems.Windows); - var osSkipAttributeLinux = new OSSkipConditionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, OperatingSystems.Linux); - - // Assert - Assert.False(osSkipAttribute.IsMet); - Assert.False(osSkipAttributeLinux.IsMet); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionTest.cs deleted file mode 100644 index a058ade7c728..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/OSSkipConditionTest.cs +++ /dev/null @@ -1,105 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class OSSkipConditionTest - { - [ConditionalFact] - [OSSkipCondition(OperatingSystems.Linux)] - public void TestSkipLinux() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Linux), - "Test should not be running on Linux"); - } - - [ConditionalFact] - [OSSkipCondition(OperatingSystems.MacOSX)] - public void TestSkipMacOSX() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.OSX), - "Test should not be running on MacOSX."); - } - - [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows)] - public void TestSkipWindows() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows), - "Test should not be running on Windows."); - } - - [ConditionalFact] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - public void TestSkipLinuxAndMacOSX() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Linux), - "Test should not be running on Linux."); - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.OSX), - "Test should not be running on MacOSX."); - } - - [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Linux)] - [InlineData(1)] - public void TestTheorySkipLinux(int arg) - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Linux), - "Test should not be running on Linux"); - } - - [ConditionalTheory] - [OSSkipCondition(OperatingSystems.MacOSX)] - [InlineData(1)] - public void TestTheorySkipMacOS(int arg) - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.OSX), - "Test should not be running on MacOSX."); - } - - [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Windows)] - [InlineData(1)] - public void TestTheorySkipWindows(int arg) - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows), - "Test should not be running on Windows."); - } - - [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - [InlineData(1)] - public void TestTheorySkipLinuxAndMacOSX(int arg) - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Linux), - "Test should not be running on Linux."); - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.OSX), - "Test should not be running on MacOSX."); - } - } - - [OSSkipCondition(OperatingSystems.Windows)] - public class OSSkipConditionClassTest - { - [ConditionalFact] - public void TestSkipClassWindows() - { - Assert.False( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows), - "Test should not be running on Windows."); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/Properties/AssemblyInfo.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/Properties/AssemblyInfo.cs deleted file mode 100644 index 0f8d3c8a9cfb..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Testing; -using Xunit; - -[assembly: Repeat(1)] -[assembly: AssemblyFixture(typeof(TestAssemblyFixture))] -[assembly: TestFramework("Microsoft.AspNetCore.Testing.AspNetTestFramework", "Microsoft.AspNetCore.Testing")] diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/RepeatTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/RepeatTest.cs deleted file mode 100644 index e5e1d5d6d05c..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/RepeatTest.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - [Repeat] - public class RepeatTest - { - public static int _runCount = 0; - - [Fact] - [Repeat(5)] - public void RepeatLimitIsSetCorrectly() - { - Assert.Equal(5, RepeatContext.Current.Limit); - } - - [Fact] - [Repeat(5)] - public void RepeatRunsTestSpecifiedNumberOfTimes() - { - Assert.Equal(RepeatContext.Current.CurrentIteration, _runCount); - _runCount++; - } - - [Fact] - public void RepeatCanBeSetOnClass() - { - Assert.Equal(10, RepeatContext.Current.Limit); - } - } - - public class LoggedTestXunitRepeatAssemblyTests - { - [Fact] - public void RepeatCanBeSetOnAssembly() - { - Assert.Equal(1, RepeatContext.Current.Limit); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ReplaceCultureAttributeTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ReplaceCultureAttributeTest.cs deleted file mode 100644 index ff6740b80d9a..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/ReplaceCultureAttributeTest.cs +++ /dev/null @@ -1,66 +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.Globalization; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class RepalceCultureAttributeTest - { - [Fact] - public void DefaultsTo_EnGB_EnUS() - { - // Arrange - var culture = new CultureInfo("en-GB"); - var uiCulture = new CultureInfo("en-US"); - - // Act - var replaceCulture = new ReplaceCultureAttribute(); - - // Assert - Assert.Equal(culture, replaceCulture.Culture); - Assert.Equal(uiCulture, replaceCulture.UICulture); - } - - [Fact] - public void UsesSuppliedCultureAndUICulture() - { - // Arrange - var culture = "de-DE"; - var uiCulture = "fr-CA"; - - // Act - var replaceCulture = new ReplaceCultureAttribute(culture, uiCulture); - - // Assert - Assert.Equal(new CultureInfo(culture), replaceCulture.Culture); - Assert.Equal(new CultureInfo(uiCulture), replaceCulture.UICulture); - } - - [Fact] - public void BeforeAndAfterTest_ReplacesCulture() - { - // Arrange - var originalCulture = CultureInfo.CurrentCulture; - var originalUICulture = CultureInfo.CurrentUICulture; - var culture = "de-DE"; - var uiCulture = "fr-CA"; - var replaceCulture = new ReplaceCultureAttribute(culture, uiCulture); - - // Act - replaceCulture.Before(methodUnderTest: null); - - // Assert - Assert.Equal(new CultureInfo(culture), CultureInfo.CurrentCulture); - Assert.Equal(new CultureInfo(uiCulture), CultureInfo.CurrentUICulture); - - // Act - replaceCulture.After(methodUnderTest: null); - - // Assert - Assert.Equal(originalCulture, CultureInfo.CurrentCulture); - Assert.Equal(originalUICulture, CultureInfo.CurrentUICulture); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/SkipOnCITests.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/SkipOnCITests.cs deleted file mode 100644 index ee511c2bd596..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/SkipOnCITests.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.AspNetCore.Testing; -using Xunit; - -namespace Microsoft.AspNetCore.Testing.Tests -{ - public class SkipOnCITests - { - [ConditionalFact] - [SkipOnCI] - public void AlwaysSkipOnCI() - { - if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HELIX")) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("AGENT_OS"))) - { - throw new Exception("Flaky!"); - } - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TaskExtensionsTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TaskExtensionsTest.cs deleted file mode 100644 index d9f4bbe2b62a..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TaskExtensionsTest.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class TaskExtensionsTest - { - [Fact] - public async Task TimeoutAfterTest() - { - await Assert.ThrowsAsync(async () => await Task.Delay(1000).TimeoutAfter(TimeSpan.FromMilliseconds(50))); - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestAssemblyFixture.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestAssemblyFixture.cs deleted file mode 100644 index 75dddd23674b..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestAssemblyFixture.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing -{ - public class TestAssemblyFixture - { - public int Count { get; set; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestCollectionFixture.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestCollectionFixture.cs deleted file mode 100644 index 7fed04272adf..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestCollectionFixture.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.AspNetCore.Testing -{ - public class TestCollectionFixture - { - public int Count { get; set; } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestContextTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestContextTest.cs deleted file mode 100644 index 7a81f37dcac5..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestContextTest.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class TestContextTest : ITestMethodLifecycle - { - public TestContext Context { get; private set; } - - [Fact] - public void FullName_IsUsed_ByDefault() - { - Assert.Equal(GetType().FullName, Context.FileOutput.TestClassName); - } - - Task ITestMethodLifecycle.OnTestStartAsync(TestContext context, CancellationToken cancellationToken) - { - Context = context; - return Task.CompletedTask; - } - - Task ITestMethodLifecycle.OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - } -} - -namespace Microsoft.AspNetCore.Testing.Tests -{ - public class TestContextNameShorteningTest : ITestMethodLifecycle - { - public TestContext Context { get; private set; } - - [Fact] - public void NameIsShortenedWhenAssemblyNameIsAPrefix() - { - Assert.Equal(GetType().Name, Context.FileOutput.TestClassName); - } - - Task ITestMethodLifecycle.OnTestStartAsync(TestContext context, CancellationToken cancellationToken) - { - Context = context; - return Task.CompletedTask; - } - - Task ITestMethodLifecycle.OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - } -} - -namespace Microsoft.AspNetCore.Testing -{ - [ShortClassName] - public class TestContextTestClassShortNameAttributeTest : ITestMethodLifecycle - { - public TestContext Context { get; private set; } - - [Fact] - public void ShortClassNameUsedWhenShortClassNameAttributeSpecified() - { - Assert.Equal(GetType().Name, Context.FileOutput.TestClassName); - } - - Task ITestMethodLifecycle.OnTestStartAsync(TestContext context, CancellationToken cancellationToken) - { - Context = context; - return Task.CompletedTask; - } - - Task ITestMethodLifecycle.OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPathUtilitiesTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPathUtilitiesTest.cs deleted file mode 100644 index 9810db94a410..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPathUtilitiesTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class TestPathUtilitiesTest - { - // Entire test pending removal - see https://github.com/dotnet/extensions/issues/1697 -#pragma warning disable 0618 - - [Fact] - public void GetSolutionRootDirectory_ResolvesSolutionRoot() - { - // Directory.GetCurrentDirectory() gives: - // Testing\test\Microsoft.AspNetCore.Testing.Tests\bin\Debug\netcoreapp2.0 - // Testing\test\Microsoft.AspNetCore.Testing.Tests\bin\Debug\net461 - // Testing\test\Microsoft.AspNetCore.Testing.Tests\bin\Debug\net46 - var expectedPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "..")); - - Assert.Equal(expectedPath, TestPathUtilities.GetSolutionRootDirectory("Extensions")); - } - - [Fact] - public void GetSolutionRootDirectory_Throws_IfNotFound() - { - var exception = Assert.Throws(() => TestPathUtilities.GetSolutionRootDirectory("NotTesting")); - Assert.Equal($"Solution file NotTesting.sln could not be found in {AppContext.BaseDirectory} or its parent directories.", exception.Message); - } -#pragma warning restore 0618 - } -} diff --git a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPlatformHelperTest.cs b/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPlatformHelperTest.cs deleted file mode 100644 index dcecc6b32529..000000000000 --- a/src/libraries/Common/tests/Extensions/TestingUtils/Microsoft.AspNetCore.Testing/test/TestPlatformHelperTest.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Testing; -using Xunit; - -namespace Microsoft.AspNetCore.Testing -{ - public class TestPlatformHelperTest - { - [ConditionalFact] - [OSSkipCondition(OperatingSystems.MacOSX)] - [OSSkipCondition(OperatingSystems.Windows)] - public void IsLinux_TrueOnLinux() - { - Assert.True(TestPlatformHelper.IsLinux); - Assert.False(TestPlatformHelper.IsMac); - Assert.False(TestPlatformHelper.IsWindows); - } - - [ConditionalFact] - [OSSkipCondition(OperatingSystems.Linux)] - [OSSkipCondition(OperatingSystems.Windows)] - public void IsMac_TrueOnMac() - { - Assert.False(TestPlatformHelper.IsLinux); - Assert.True(TestPlatformHelper.IsMac); - Assert.False(TestPlatformHelper.IsWindows); - } - - [ConditionalFact] - [OSSkipCondition(OperatingSystems.Linux)] - [OSSkipCondition(OperatingSystems.MacOSX)] - public void IsWindows_TrueOnWindows() - { - Assert.False(TestPlatformHelper.IsLinux); - Assert.False(TestPlatformHelper.IsMac); - Assert.True(TestPlatformHelper.IsWindows); - } - - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.CLR | RuntimeFrameworks.CoreCLR | RuntimeFrameworks.None)] - public void IsMono_TrueOnMono() - { - Assert.True(TestPlatformHelper.IsMono); - } - - [ConditionalFact] - [FrameworkSkipCondition(RuntimeFrameworks.Mono)] - public void IsMono_FalseElsewhere() - { - Assert.False(TestPlatformHelper.IsMono); - } - } -} diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj index d72fff10e633..7046da24da6d 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/Microsoft.Extensions.Caching.Memory.Tests.csproj @@ -5,13 +5,6 @@ true - - - - - diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/TimeExpirationTests.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/TimeExpirationTests.cs index b35d42c92618..4a26ad05a9fd 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/TimeExpirationTests.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/TimeExpirationTests.cs @@ -3,7 +3,6 @@ using System; using System.Threading; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Internal; using Xunit; @@ -97,14 +96,8 @@ public void NegativeRelativeExpirationThrows() var key = "myKey"; var value = new object(); - ExceptionAssert.ThrowsArgumentOutOfRange(() => - { - var result = cache.Set(key, value, new MemoryCacheEntryOptions() - .SetAbsoluteExpiration(TimeSpan.FromMinutes(-1))); - }, - nameof(MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow), - "The relative expiration value must be positive.", - TimeSpan.FromMinutes(-1)); + AssertExtensions.Throws(nameof(MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow), () => + cache.Set(key, value, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(-1)))); } [Fact] @@ -115,13 +108,8 @@ public void ZeroRelativeExpirationThrows() var key = "myKey"; var value = new object(); - ExceptionAssert.ThrowsArgumentOutOfRange(() => - { - var result = cache.Set(key, value, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.Zero)); - }, - nameof(MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow), - "The relative expiration value must be positive.", - TimeSpan.Zero); + AssertExtensions.Throws(nameof(MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow), () => + cache.Set(key, value, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.Zero))); } [Fact] @@ -154,14 +142,8 @@ public void NegativeSlidingExpirationThrows() var key = "myKey"; var value = new object(); - ExceptionAssert.ThrowsArgumentOutOfRange(() => - { - var result = cache.Set(key, value, new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.FromMinutes(-1))); - }, - nameof(MemoryCacheEntryOptions.SlidingExpiration), - "The sliding expiration value must be positive.", - TimeSpan.FromMinutes(-1)); + AssertExtensions.Throws(nameof(MemoryCacheEntryOptions.SlidingExpiration), () => + cache.Set(key, value, new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(-1)))); } [Fact] @@ -172,14 +154,8 @@ public void ZeroSlidingExpirationThrows() var key = "myKey"; var value = new object(); - ExceptionAssert.ThrowsArgumentOutOfRange(() => - { - var result = cache.Set(key, value, new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.Zero)); - }, - nameof(MemoryCacheEntryOptions.SlidingExpiration), - "The sliding expiration value must be positive.", - TimeSpan.Zero); + AssertExtensions.Throws(nameof(MemoryCacheEntryOptions.SlidingExpiration), () => + cache.Set(key, value, new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.Zero))); } [Fact] diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj index 7a98c89e480e..40c5a18fe90d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj @@ -12,19 +12,6 @@ Link="Microsoft.Extensions.Configuration\tests\Common\ConfigurationProviderExtensions.cs" /> - - - - - - - - diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs index cfff1fe2dec8..b9c59d93b4dc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs @@ -5,8 +5,8 @@ using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.Xml; +using System.Tests; using System.Xml; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Configuration.Test; using Xunit; @@ -318,7 +318,6 @@ public void SupportAndIgnoreProcessingInstructions() } [Fact] - [ReplaceCulture] public void ThrowExceptionWhenFindDTD() { var xml = @@ -339,15 +338,19 @@ public void ThrowExceptionWhenFindDTD() "; - var xmlConfigSrc = new XmlConfigurationProvider(new XmlConfigurationSource()); - var isMono = Type.GetType("Mono.Runtime") != null; - var expectedMsg = isMono ? "Document Type Declaration (DTD) is prohibited in this XML. Line 1, position 10." : "For security reasons DTD is prohibited in this XML document. " - + "To enable DTD processing set the DtdProcessing property on XmlReaderSettings " - + "to Parse and pass the settings into XmlReader.Create method."; - var exception = Assert.Throws(() => xmlConfigSrc.Load(TestStreamHelpers.StringToStream(xml))); + using (new ThreadCultureChange("en-GB")) + { + var xmlConfigSrc = new XmlConfigurationProvider(new XmlConfigurationSource()); + var isMono = Type.GetType("Mono.Runtime") != null; + var expectedMsg = isMono ? "Document Type Declaration (DTD) is prohibited in this XML. Line 1, position 10." : "For security reasons DTD is prohibited in this XML document. " + + "To enable DTD processing set the DtdProcessing property on XmlReaderSettings " + + "to Parse and pass the settings into XmlReader.Create method."; + + var exception = Assert.Throws(() => xmlConfigSrc.Load(TestStreamHelpers.StringToStream(xml))); - Assert.Equal(expectedMsg, exception.Message); + Assert.Equal(expectedMsg, exception.Message); + } } [Fact] @@ -433,7 +436,6 @@ public void XmlConfiguration_Does_Not_Throw_On_Optional_Configuration() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)] - [FrameworkSkipCondition(RuntimeFrameworks.Mono)] public void LoadKeyValuePairsFromValidEncryptedXml() { var xml = @" diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj index d741185f4189..9357badc0f94 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj @@ -12,10 +12,6 @@ - - diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj index 5dcd273c8b5f..762664f48f73 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj @@ -6,10 +6,6 @@ - - diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs index cdecbb6bc703..3acb7de6679d 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Specification.Fakes; using Xunit; @@ -343,10 +342,7 @@ public void TryAddEnumerable_ThrowsWhenAddingIndistinguishableImplementationType // Arrange var collection = new ServiceCollection(); - // Act & Assert - ExceptionAssert.ThrowsArgument( - () => collection.TryAddEnumerable(descriptor), - "descriptor", + AssertExtensions.ThrowsContains(() => collection.TryAddEnumerable(descriptor), string.Format(@"Implementation type cannot be '{0}' because it is indistinguishable from other services registered for '{1}'.", implementationType, serviceType)); } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderServiceExtensionsTest.cs index 015350ecad2f..9bed4bfe5ab8 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderServiceExtensionsTest.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.AspNetCore.Testing; using Xunit; namespace Microsoft.Extensions.DependencyInjection @@ -44,7 +43,7 @@ public void GetRequiredService_Throws_WhenNoServiceRegistered() var serviceProvider = CreateTestServiceProvider(0); // Act + Assert - ExceptionAssert.Throws(() => serviceProvider.GetRequiredService(), + AssertExtensions.Throws(() => serviceProvider.GetRequiredService(), $"No service for type '{typeof(IFoo)}' has been registered."); } @@ -55,7 +54,7 @@ public void ISupportRequiredService_GetRequiredService_Throws_WhenNoServiceRegis var serviceProvider = new RequiredServiceSupportingProvider(); // Act + Assert - ExceptionAssert.Throws(() => serviceProvider.GetRequiredService()); + AssertExtensions.Throws(() => serviceProvider.GetRequiredService()); } [Fact] @@ -65,7 +64,7 @@ public void NonGeneric_GetRequiredService_Throws_WhenNoServiceRegistered() var serviceProvider = CreateTestServiceProvider(0); // Act + Assert - ExceptionAssert.Throws(() => serviceProvider.GetRequiredService(typeof(IFoo)), + AssertExtensions.Throws(() => serviceProvider.GetRequiredService(typeof(IFoo)), $"No service for type '{typeof(IFoo)}' has been registered."); } @@ -76,7 +75,7 @@ public void ISupportRequiredService_NonGeneric_GetRequiredService_Throws_WhenNoS var serviceProvider = new RequiredServiceSupportingProvider(); // Act + Assert - ExceptionAssert.Throws(() => serviceProvider.GetRequiredService(typeof(IFoo))); + AssertExtensions.Throws(() => serviceProvider.GetRequiredService(typeof(IFoo))); } [Fact] diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs index 198308d4254d..b2843e399836 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Testing; using Xunit; namespace Microsoft.Extensions.DependencyInjection.ServiceLookup @@ -23,10 +22,7 @@ public void Constructor_WithImplementationType_ThrowsIfServiceTypeIsOpenGenericA }; // Act and Assert - ExceptionAssert.ThrowsArgument( - () => new CallSiteFactory(serviceDescriptors), - "descriptors", - $"Open generic service type '{typeof(IList<>)}' requires registering an open generic implementation type."); + AssertExtensions.Throws("descriptors", () => new CallSiteFactory(serviceDescriptors)); } public static TheoryData Constructor_WithInstance_ThrowsIfServiceTypeIsOpenGenericData => @@ -48,10 +44,7 @@ public void Constructor_WithInstance_ThrowsIfServiceTypeIsOpenGeneric(object ins }; // Act and Assert - var ex = ExceptionAssert.ThrowsArgument( - () => new CallSiteFactory(serviceDescriptors), - "descriptors", - $"Open generic service type '{typeof(IEnumerable<>)}' requires registering an open generic implementation type."); + AssertExtensions.Throws("descriptors", () => new CallSiteFactory(serviceDescriptors)); } [Fact] @@ -64,10 +57,7 @@ public void Constructor_WithFactory_ThrowsIfServiceTypeIsOpenGeneric() }; // Act and Assert - var ex = ExceptionAssert.ThrowsArgument( - () => new CallSiteFactory(serviceDescriptors), - "descriptors", - $"Open generic service type '{typeof(Tuple<>)}' requires registering an open generic implementation type."); + AssertExtensions.Throws("descriptors", () => new CallSiteFactory(serviceDescriptors)); } } } diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj index b59f5900e886..2f22d08400ba 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/Microsoft.Extensions.FileProviders.Physical.Tests.csproj @@ -7,10 +7,8 @@ - - + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/PhysicalFileProviderTests.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/PhysicalFileProviderTests.cs index 819a30a392c8..0d9fb9577845 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/PhysicalFileProviderTests.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/PhysicalFileProviderTests.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.FileProviders.Internal; using Microsoft.Extensions.FileProviders.Physical; using Microsoft.Extensions.Primitives; diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs index b609679863a6..4dd4a4c06571 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs @@ -8,7 +8,6 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; namespace Microsoft.Extensions.Hosting.IntegrationTesting diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj index 2d67db82d52c..ffd54fef7784 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj @@ -8,8 +8,6 @@ - + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs index 50dfdad150e9..c9a4af01e5bc 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs @@ -6,7 +6,6 @@ using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Hosting.IntegrationTesting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Test; diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj index 908e9d0062db..c729cbe73311 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/tests/DI.Common/Common/tests/Microsoft.Extensions.Logging.Testing.Tests.csproj @@ -5,8 +5,6 @@ - Date: Thu, 30 Jul 2020 18:04:37 +0200 Subject: [PATCH 152/755] [wasm] Address TODO in pal_runtimeinformation.c (#40133) The WASM architecture wasn't added there since we already hardcode the architecture to wasm in the managed layer. For consistency we should still define it in the PAL though and address the TODO comment. Also added a test that verifies we indeed get the correct wasm architecture on the Browser platform. --- .../System.Native/Interop.ProcessorArchitecture.cs | 3 ++- .../Unix/System.Native/pal_runtimeinformation.c | 14 ++++++++++---- .../Unix/System.Native/pal_runtimeinformation.h | 3 ++- .../RuntimeInformation/RuntimeInformation.Unix.cs | 2 ++ .../tests/CheckArchitectureTests.cs | 8 ++++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.ProcessorArchitecture.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.ProcessorArchitecture.cs index d18a153ae0f1..81dc2f936895 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.ProcessorArchitecture.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.ProcessorArchitecture.cs @@ -13,7 +13,8 @@ internal enum ProcessorArchitecture x86, x64, ARM, - ARM64 + ARM64, + WASM } } } diff --git a/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.c b/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.c index 0f76fc0b8815..56ad9f2a4240 100644 --- a/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.c +++ b/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.c @@ -41,7 +41,8 @@ int32_t SystemNative_GetUnixVersion(char* version, int* capacity) 0 - x86 1 - x64 2 - ARM - 3 - ARM64 */ + 3 - ARM64 + 4 - WASM */ int32_t SystemNative_GetOSArchitecture() { #if defined(TARGET_ARM) @@ -50,8 +51,10 @@ int32_t SystemNative_GetOSArchitecture() return ARCH_ARM64; #elif defined(TARGET_AMD64) return ARCH_X64; -#elif defined(TARGET_X86) || defined(TARGET_WASM) // TODO: add arch for WASM +#elif defined(TARGET_X86) return ARCH_X86; +#elif defined(TARGET_WASM) + return ARCH_WASM; #else #error Unidentified Architecture #endif @@ -61,7 +64,8 @@ int32_t SystemNative_GetOSArchitecture() 0 - x86 1 - x64 2 - ARM -3 - ARM64 */ +3 - ARM64 +4 - WASM */ int32_t SystemNative_GetProcessArchitecture() { #if defined(TARGET_ARM) @@ -70,8 +74,10 @@ int32_t SystemNative_GetProcessArchitecture() return ARCH_ARM64; #elif defined(TARGET_AMD64) return ARCH_X64; -#elif defined(TARGET_X86) || defined(TARGET_WASM) // TODO: add arch for WASM +#elif defined(TARGET_X86) return ARCH_X86; +#elif defined(TARGET_WASM) + return ARCH_WASM; #else #error Unidentified Architecture #endif diff --git a/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.h b/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.h index f52a01db11c1..8f233ae1e603 100644 --- a/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.h +++ b/src/libraries/Native/Unix/System.Native/pal_runtimeinformation.h @@ -21,5 +21,6 @@ enum ARCH_X86, ARCH_X64, ARCH_ARM, - ARCH_ARM64 + ARCH_ARM64, + ARCH_WASM }; diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs index 01da110b0373..232c7fc8aa55 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs @@ -34,6 +34,8 @@ private static Architecture Map(Interop.Sys.ProcessorArchitecture arch) return Architecture.X64; case Interop.Sys.ProcessorArchitecture.ARM64: return Architecture.Arm64; + case Interop.Sys.ProcessorArchitecture.WASM: + return Architecture.Wasm; case Interop.Sys.ProcessorArchitecture.x86: default: Debug.Assert(arch == Interop.Sys.ProcessorArchitecture.x86, "Unidentified Architecture"); diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs index 4fa46f5bed27..a54b80285783 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs @@ -44,5 +44,13 @@ public void VerifyArchitecture() Assert.Equal(osArch, RuntimeInformation.OSArchitecture); Assert.Equal(processArch, RuntimeInformation.ProcessArchitecture); } + + [Fact] + [PlatformSpecific(TestPlatforms.Browser)] + public void VerifyBrowserArchitecture() + { + Assert.Equal(Architecture.Wasm, RuntimeInformation.OSArchitecture); + Assert.Equal(Architecture.Wasm, RuntimeInformation.ProcessArchitecture); + } } } From 65c9be6388a99739bd72dc2136f4a0a59b00db72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 30 Jul 2020 18:08:50 +0200 Subject: [PATCH 153/755] Sync shared file (#40141) --- .../src/tools/Common/Internal/NativeFormat/NativeFormat.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs b/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs index e92c689d658b..1ebbdac34811 100644 --- a/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs +++ b/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs @@ -84,8 +84,8 @@ enum FixupSignatureKind : uint MethodLdToken = 0x08, AllocateObject = 0x09, DefaultConstructor = 0x0a, - TlsIndex = 0x0b, - TlsOffset = 0x0c, + ThreadStaticIndex = 0x0b, + // unused = 0x0c, Method = 0x0d, IsInst = 0x0e, CastClass = 0x0f, From 1e23a0629617ab18e259872f8fbb11d3f49efc2d Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 30 Jul 2020 10:05:43 -0700 Subject: [PATCH 154/755] Consider that retbuf arg can point to GC heap in fgCreateCallDispatcherAndGetResult() (#39815) Caller return buffer argument can point to GC heap while DispatchTailCalls expects the return value argument to point to the stack. We should use a temporary stack allocated return buffer to hold the value during the dispatcher call and copy the value back to the caller return buffer after that. --- src/coreclr/src/jit/morph.cpp | 63 +++++-- .../General/Vector128/Vector128_r.csproj | 2 - .../General/Vector128/Vector128_ro.csproj | 2 - .../General/Vector128_1/Vector128_1_r.csproj | 2 - .../General/Vector128_1/Vector128_1_ro.csproj | 2 - .../General/Vector256/Vector256_r.csproj | 2 - .../General/Vector256/Vector256_ro.csproj | 2 - .../General/Vector256_1/Vector256_1_r.csproj | 2 - .../General/Vector256_1/Vector256_1_ro.csproj | 2 - .../General/Vector64/Vector64_r.csproj | 2 - .../General/Vector64/Vector64_ro.csproj | 2 - .../General/Vector64_1/Vector64_1_r.csproj | 2 - .../General/Vector64_1/Vector64_1_ro.csproj | 2 - .../JitBlue/Runtime_39581/Runtime_39581.il | 174 ++++++++++++++++++ .../Runtime_39581/Runtime_39581.ilproj | 13 ++ 15 files changed, 239 insertions(+), 35 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.il create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.ilproj diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 28b15c6f6cbe..d5cf8a892395 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -7901,21 +7901,54 @@ GenTree* Compiler::fgCreateCallDispatcherAndGetResult(GenTreeCall* orig // Add return value arg. GenTree* retValArg; - GenTree* retVal = nullptr; - unsigned int newRetLcl = BAD_VAR_NUM; + GenTree* retVal = nullptr; + unsigned int newRetLcl = BAD_VAR_NUM; + GenTree* copyToRetBufNode = nullptr; - // Use existing retbuf if there is one. if (origCall->HasRetBufArg()) { JITDUMP("Transferring retbuf\n"); GenTree* retBufArg = origCall->gtCallArgs->GetNode(); - assert((info.compRetBuffArg != BAD_VAR_NUM) && retBufArg->OperIsLocal() && - (retBufArg->AsLclVarCommon()->GetLclNum() == info.compRetBuffArg)); - retValArg = retBufArg; + assert(info.compRetBuffArg != BAD_VAR_NUM); + assert(retBufArg->OperIsLocal()); + assert(retBufArg->AsLclVarCommon()->GetLclNum() == info.compRetBuffArg); + + if (info.compRetBuffDefStack) + { + // Use existing retbuf. + retValArg = retBufArg; + } + else + { + // Caller return buffer argument retBufArg can point to GC heap while the dispatcher expects + // the return value argument retValArg to point to the stack. + // We use a temporary stack allocated return buffer to hold the value during the dispatcher call + // and copy the value back to the caller return buffer after that. + unsigned int tmpRetBufNum = lvaGrabTemp(true DEBUGARG("substitute local for return buffer")); + + constexpr bool unsafeValueClsCheck = false; + lvaSetStruct(tmpRetBufNum, origCall->gtRetClsHnd, unsafeValueClsCheck); + lvaSetVarAddrExposed(tmpRetBufNum); + + var_types tmpRetBufType = lvaGetDesc(tmpRetBufNum)->TypeGet(); + + retValArg = gtNewOperNode(GT_ADDR, TYP_I_IMPL, gtNewLclvNode(tmpRetBufNum, tmpRetBufType)); + + var_types callerRetBufType = lvaGetDesc(info.compRetBuffArg)->TypeGet(); + + GenTree* dstAddr = gtNewLclvNode(info.compRetBuffArg, callerRetBufType); + GenTree* dst = gtNewObjNode(info.compMethodInfo->args.retTypeClass, dstAddr); + GenTree* src = gtNewLclvNode(tmpRetBufNum, tmpRetBufType); + + constexpr bool isVolatile = false; + constexpr bool isCopyBlock = true; + copyToRetBufNode = gtNewBlkOpNode(dst, src, isVolatile, isCopyBlock); + } + if (origCall->gtType != TYP_VOID) { - retVal = gtClone(retValArg); + retVal = gtClone(retBufArg); } } else if (origCall->gtType != TYP_VOID) @@ -7969,22 +8002,30 @@ GenTree* Compiler::fgCreateCallDispatcherAndGetResult(GenTreeCall* orig GenTree* retAddrSlot = gtNewOperNode(GT_ADDR, TYP_I_IMPL, gtNewLclvNode(lvaRetAddrVar, TYP_I_IMPL)); callDispatcherNode->gtCallArgs = gtPrependNewCallArg(retAddrSlot, callDispatcherNode->gtCallArgs); + GenTree* finalTree = callDispatcherNode; + + if (copyToRetBufNode != nullptr) + { + finalTree = gtNewOperNode(GT_COMMA, TYP_VOID, callDispatcherNode, copyToRetBufNode); + } + if (origCall->gtType == TYP_VOID) { - return callDispatcherNode; + return finalTree; } assert(retVal != nullptr); - GenTree* comma = gtNewOperNode(GT_COMMA, origCall->TypeGet(), callDispatcherNode, retVal); + finalTree = gtNewOperNode(GT_COMMA, origCall->TypeGet(), finalTree, retVal); + // The JIT seems to want to CSE this comma and messes up multi-reg ret // values in the process. Just avoid CSE'ing this tree entirely in that // case. if (origCall->HasMultiRegRetVal()) { - comma->gtFlags |= GTF_DONT_CSE; + finalTree->gtFlags |= GTF_DONT_CSE; } - return comma; + return finalTree; } //------------------------------------------------------------------------ diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj index 794326d41ec5..2e1ffa2dcc1c 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj @@ -2,8 +2,6 @@ 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 0384e6834e01..91f1f64aec29 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj @@ -2,8 +2,6 @@ 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 794326d41ec5..2e1ffa2dcc1c 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,8 +2,6 @@ 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 0384e6834e01..91f1f64aec29 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,8 +2,6 @@ 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 794326d41ec5..2e1ffa2dcc1c 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj @@ -2,8 +2,6 @@ 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 0384e6834e01..91f1f64aec29 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj @@ -2,8 +2,6 @@ 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 6eedfbbafd0f..2e1ffa2dcc1c 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,8 +2,6 @@ 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 ea939ebef621..91f1f64aec29 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,8 +2,6 @@ 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 794326d41ec5..2e1ffa2dcc1c 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj @@ -2,8 +2,6 @@ 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 0384e6834e01..91f1f64aec29 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj @@ -2,8 +2,6 @@ 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 794326d41ec5..2e1ffa2dcc1c 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,8 +2,6 @@ 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 0384e6834e01..91f1f64aec29 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,8 +2,6 @@ Exe true - - true Embedded diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.il b/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.il new file mode 100644 index 000000000000..5288e1508095 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.il @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// The test exposes the issue when: +// +// 1) methods Callee and Caller have the following structure: +// +// S Callee() { produce and return an instance of S } +// +// S Caller() { return Callee(); } +// +// 2) S is a value type with non-GC fields and has such size that it +// must be passed via return buffer; +// +// 3) call to Callee is transformed to tail call via helper: +// +// S result; +// DispatchTailCalls(&IL_STUB_CallTailCallTarget, (IntPtr)&result, _AddressOfReturnAddress()); +// return result; +// +// 4) Caller is invoked via Reflection. +// +// During morph phase the JIT discovers that both Caller and Callee have the return buffer arguments and +// falsely assumes that the value can be directly passed from Caller to Callee. +// Here is a problem: DispatchTailCalls helper expects the RetValue argument (in this case, return buffer argument) +// to always point to the stack. However, during a reflection call the return buffer for S value type can be placed on the GC heap (see condition 2 above). +// As a consequence, when GC is called at DispatchTailCalls the object corresponding to the return value buffer can be moved, +// but the pointers passed to DispatchTailCalls will not be updated that leads to Callee using the non-updated location when writing its return value. +// +// Note: you will find below that Caller uses localloc - this is done in order to prevent a call to Caller to be transformed into fast tail call. +// Note: COMPlus_GCStress=3 or COMPlus_GCStress=C are required in order to reliably expose this issue. + +.assembly extern System.Runtime +{ +} + +.assembly Runtime_39581 +{ +} + +.class private sequential ansi sealed beforefieldinit int32x8 + extends [System.Runtime]System.ValueType +{ + .field public int32 a + .field public int32 b + .field public int32 c + .field public int32 d + .field public int32 e + .field public int32 f + .field public int32 g + .field public int32 h +} + +.class private auto ansi beforefieldinit Runtime_39581.Program + extends [System.Runtime]System.Object +{ + .method private hidebysig static valuetype int32x8 Callee(uint8* arg0) cil managed noinlining + { + .maxstack 2 + .locals init (valuetype int32x8 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj int32x8 + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.0 + IL_000b: stfld int32 int32x8::a + IL_0010: ldloca.s V_0 + IL_0012: ldc.i4.1 + IL_0013: stfld int32 int32x8::b + IL_0018: ldloca.s V_0 + IL_001a: ldc.i4.2 + IL_001b: stfld int32 int32x8::c + IL_0020: ldloca.s V_0 + IL_0022: ldc.i4.3 + IL_0023: stfld int32 int32x8::d + IL_0028: ldloca.s V_0 + IL_002a: ldc.i4.4 + IL_002b: stfld int32 int32x8::e + IL_0030: ldloca.s V_0 + IL_0032: ldc.i4.5 + IL_0033: stfld int32 int32x8::f + IL_0038: ldloca.s V_0 + IL_003a: ldc.i4.6 + IL_003b: stfld int32 int32x8::g + IL_0040: ldloca.s V_0 + IL_0042: ldc.i4.7 + IL_0043: stfld int32 int32x8::h + IL_0048: ldloc.0 + IL_0049: ret + } + + .method public hidebysig static valuetype int32x8 Caller(int32 arg0) cil managed noinlining + { + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.u + IL_0002: localloc + IL_0004: tail. + IL_0006: call valuetype int32x8 Runtime_39581.Program::Callee(uint8*) + IL_000b: ret + } + + .method private hidebysig static int32 Main(string[] args) cil managed + { + .entrypoint + .maxstack 6 + .locals init (valuetype int32x8 V_0) + IL_0000: ldtoken Runtime_39581.Program + IL_0005: call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + IL_000a: ldstr "Caller" + IL_000f: ldc.i4.1 + IL_0010: newarr [System.Runtime]System.Type + IL_0015: dup + IL_0016: ldc.i4.0 + IL_0017: ldtoken [System.Runtime]System.Int32 + IL_001c: call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + IL_0021: stelem.ref + IL_0022: call instance class [System.Runtime]System.Reflection.MethodInfo [System.Runtime]System.Type::GetMethod(string, class [System.Runtime]System.Type[]) + IL_0027: ldnull + IL_0028: ldc.i4.1 + IL_0029: newarr [System.Runtime]System.Object + IL_002e: dup + IL_002f: ldc.i4.0 + IL_0030: ldc.i4.1 + IL_0031: box [System.Runtime]System.Int32 + IL_0036: stelem.ref + IL_0037: callvirt instance object [System.Runtime]System.Reflection.MethodBase::Invoke(object, object[]) + IL_003c: unbox.any int32x8 + IL_0041: stloc.0 + IL_0042: ldloc.0 + IL_0043: ldfld int32 int32x8::a + IL_0048: brtrue.s IL_008c + + IL_004a: ldloc.0 + IL_004b: ldfld int32 int32x8::b + IL_0050: ldc.i4.1 + IL_0051: bne.un.s IL_008c + + IL_0053: ldloc.0 + IL_0054: ldfld int32 int32x8::c + IL_0059: ldc.i4.2 + IL_005a: bne.un.s IL_008c + + IL_005c: ldloc.0 + IL_005d: ldfld int32 int32x8::d + IL_0062: ldc.i4.3 + IL_0063: bne.un.s IL_008c + + IL_0065: ldloc.0 + IL_0066: ldfld int32 int32x8::e + IL_006b: ldc.i4.4 + IL_006c: bne.un.s IL_008c + + IL_006e: ldloc.0 + IL_006f: ldfld int32 int32x8::f + IL_0074: ldc.i4.5 + IL_0075: bne.un.s IL_008c + + IL_0077: ldloc.0 + IL_0078: ldfld int32 int32x8::g + IL_007d: ldc.i4.6 + IL_007e: bne.un.s IL_008c + + IL_0080: ldloc.0 + IL_0081: ldfld int32 int32x8::h + IL_0086: ldc.i4.7 + IL_0087: bne.un.s IL_008c + + IL_0089: ldc.i4.s 100 + IL_008b: ret + + IL_008c: ldc.i4.0 + IL_008d: ret + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.ilproj b/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.ilproj new file mode 100644 index 000000000000..50758ca86d9c --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_39581/Runtime_39581.ilproj @@ -0,0 +1,13 @@ + + + Exe + + + None + True + true + + + + + From e872afcc9184a0c74e15f23cd798cf337d91aa4b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 30 Jul 2020 12:35:09 -0500 Subject: [PATCH 155/755] Fix ILLink.Substitutions.xml Warnings during Blazor build (#40051) * Fix ILLink warning for System.Runtime.Serialization.Formatters LocalAppContextSwitches is getting trimmed from the Browser specific assembly since it is unused. However, we still have an ILLink.Substitutions.xml file referencing it, causing the warning. The fix is to only include the ILLink.Substitutions.xml file for the non-Browser build. * Fix ILLink warning in System.Runtime.InteropServices.JavaScript When building for Browser, the Runtime.InteropServices.JavaScript assembly doesn't use the System.SR type which causes the ILLinker to trim it during the dotnet/runtme build. But since System.SR is used for the AnyOS build we are generating an ILLink.Substitutions.xml file telling the linker to remove the System.SR type. This causes a warning during the Blazor app build because the Type doesn't exist in the assembly, but the XML file references it. The fix is to not create an System.SR Type, nor embed the resources file, for the Browser build. This will need to be undone once a string is used in the Browser build. --- ....Runtime.InteropServices.JavaScript.csproj | 5 +++++ ...ml => ILLink.Substitutions.NonBrowser.xml} | 0 ...em.Runtime.Serialization.Formatters.csproj | 20 +++++++++++-------- 3 files changed, 17 insertions(+), 8 deletions(-) rename src/libraries/System.Runtime.Serialization.Formatters/src/ILLink/{ILLink.Substitutions.xml => ILLink.Substitutions.NonBrowser.xml} (100%) 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 c5455ea87f81..072a1f1766be 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 @@ -8,6 +8,11 @@ SR.SystemRuntimeInteropServicesJavaScript_PlatformNotSupported + + + true + false + diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/ILLink/ILLink.Substitutions.xml b/src/libraries/System.Runtime.Serialization.Formatters/src/ILLink/ILLink.Substitutions.NonBrowser.xml similarity index 100% rename from src/libraries/System.Runtime.Serialization.Formatters/src/ILLink/ILLink.Substitutions.xml rename to src/libraries/System.Runtime.Serialization.Formatters/src/ILLink/ILLink.Substitutions.NonBrowser.xml diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj index 124a497c4637..6d339f895d61 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj @@ -9,8 +9,8 @@ $(MSBuildThisFileDirectory)ILLink\ - - + + @@ -21,10 +21,6 @@ - - - Common\System\LocalAppContextSwitches.Common.cs - @@ -59,8 +55,6 @@ - - @@ -73,6 +67,16 @@ + + + + + Common\System\LocalAppContextSwitches.Common.cs + + + + + From 32ddcd3f7056914c95e600c0f2055b632e323463 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 30 Jul 2020 11:05:17 -0700 Subject: [PATCH 156/755] For arm32, kill REG_PROFILER_RET_SCRATCH for LSRA but not for GC (#40123) Reworking of #37969. Block LSRA from using R2 around the profiler leave callback, but don't kill GC refs in R2, since late codegen will use R2 to temporarily hold return values around the callback. Fixes #37223. Co-authored-by: Carol Eidt --- src/coreclr/src/jit/emit.cpp | 5 +++++ src/coreclr/src/jit/lsraarm.cpp | 2 ++ src/coreclr/src/jit/target.h | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index cc12dabc5492..ab1c281ea5eb 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -7692,7 +7692,12 @@ regMaskTP emitter::emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper) break; case CORINFO_HELP_PROF_FCN_LEAVE: +#if defined(TARGET_ARM) + // profiler scratch remains gc live + result = RBM_PROFILER_LEAVE_TRASH & ~RBM_PROFILER_RET_SCRATCH; +#else result = RBM_PROFILER_LEAVE_TRASH; +#endif break; case CORINFO_HELP_PROF_FCN_TAILCALL: diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index b9b4d0f6d3e6..8402bcdefc0f 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -491,6 +491,8 @@ int LinearScan::BuildNode(GenTree* tree) case GT_RETURN: srcCount = BuildReturn(tree); + killMask = getKillSetForReturn(); + BuildDefsWithKills(tree, 0, RBM_NONE, killMask); break; case GT_RETFILT: diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index 17ecc23c0a16..5eac47184cdd 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -1106,7 +1106,9 @@ typedef unsigned char regNumberSmall; // The registers trashed by profiler enter/leave/tailcall hook // See vm\arm\asmhelpers.asm for more details. #define RBM_PROFILER_ENTER_TRASH RBM_NONE - #define RBM_PROFILER_LEAVE_TRASH RBM_NONE + // While REG_PROFILER_RET_SCRATCH is not trashed by the method, the register allocator must + // consider it killed by the return. + #define RBM_PROFILER_LEAVE_TRASH RBM_PROFILER_RET_SCRATCH #define RBM_PROFILER_TAILCALL_TRASH RBM_NONE // Which register are int and long values returned in ? From fbca8027f0c354b0eaf2f107119b74515941cca9 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Thu, 30 Jul 2020 20:21:31 +0200 Subject: [PATCH 157/755] [browser][tests] Deactivate marshal tests as they are flaky right now. (#40139) * [browser][tests] Deactivate marshal tests as they are flaky right now. * Use active issue instead --- .../System/Runtime/InteropServices/JavaScript/MarshalTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs index 68f16e673f19..b9f4ed73cfb8 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs @@ -7,6 +7,7 @@ namespace System.Runtime.InteropServices.JavaScript.Tests { + [ActiveIssue("https://github.com/dotnet/runtime/issues/40112")] public static class MarshalTests { [Fact] From a87ee38f833d6d9b9d428b99530791abedbcc160 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 30 Jul 2020 11:42:48 -0700 Subject: [PATCH 158/755] Bulk-suppress linker warnings during library builds (#40106) * Enable verbose linker output and bulk-suppress warnings * Suppress ILLinker warnings for now, so ILLinker can enable warnings by default Co-authored-by: Eric Erhardt --- eng/illink.targets | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/eng/illink.targets b/eng/illink.targets index 79eb5d409643..ddd4936cc264 100644 --- a/eng/illink.targets +++ b/eng/illink.targets @@ -216,6 +216,18 @@ $(ILLinkArgs) --disable-opt unusedinterfaces $(ILLinkArgs) --keep-dep-attributes true + + $(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2041 From 65b8cf21a4c1396082498ea41abee85913865497 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 12:04:45 -0700 Subject: [PATCH 159/755] Copy ctor handling for crossgen2 (#40113) - Add IL based test for copy ctor to allow testing in Crossgen2 which doesn't yet support IJW - Add api to determine proper EmbeddedSignatureData index for these - And tests to ensure this remains functional - Marshaller changes to recognize copy constructor cases - Note that there isn't actual marshaller support. Instead the compiler can now able to detect when copy ctors should be used, and falls back to the runtime interop layer --- .../Common/TypeSystem/Common/MethodDesc.cs | 8 +++ .../TypeSystem/Interop/IL/MarshalHelpers.cs | 57 +++++++++++++++-- .../TypeSystem/Interop/IL/MarshalUtils.cs | 2 + .../TypeSystem/Interop/IL/Marshaller.cs | 5 ++ .../Interop/IL/Marshaller.ReadyToRun.cs | 4 ++ .../ILTestAssembly/Signature.il | 5 ++ .../SignatureTests.cs | 10 +++ .../Miscellaneous/CopyCtor/CopyCtorTest.cs | 45 +++++++++++++ .../CopyCtor/CopyCtorTest.csproj | 12 ++++ .../Miscellaneous/CopyCtor/CopyCtorUtil.il | 64 +++++++++++++++++++ .../CopyCtor/CopyCtorUtil.ilproj | 8 +++ 11 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs create mode 100644 src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.csproj create mode 100644 src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il create mode 100644 src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.ilproj diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs index 0545857397ba..1da52dccd3bd 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs @@ -51,6 +51,14 @@ public sealed partial class MethodSignature : TypeSystemEntity // Value of for any custom modifiers on the return type public const string IndexOfCustomModifiersOnReturnType = "0.1.1.1"; + // Value of for any custom modifiers on + // SomeStruct when SomeStruct *, or SomeStruct & is the type of a parameter or return type + // Parameter index 0 represents the return type, and indices 1-n represent the parameters to the signature + public static string GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(int parameterIndex) + { + return $"0.1.1.2.{(parameterIndex + 1).ToStringInvariant()}.1"; + } + public MethodSignature(MethodSignatureFlags flags, int genericParameterCount, TypeDesc returnType, TypeDesc[] parameters, EmbeddedSignatureData[] embeddedSignatureData = null) { _flags = flags; diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index 956e4fc8e274..7b05a9b4ed90 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -166,13 +166,44 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, } } + private static bool HasCopyConstructorCustomModifier(int? parameterIndex, + EmbeddedSignatureData[] customModifierData) + { + if (!parameterIndex.HasValue || customModifierData == null) + return false; + + string customModifierIndex = MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(parameterIndex.Value); + foreach (var customModifier in customModifierData) + { + if (customModifier.kind != EmbeddedSignatureDataKind.RequiredCustomModifier) + continue; + + if (customModifier.index != customModifierIndex) + continue; + + var customModifierType = customModifier.type as DefType; + if (customModifierType == null) + continue; + + if ((customModifierType.Namespace == "System.Runtime.CompilerServices" && customModifierType.Name == "IsCopyConstructed") || + (customModifierType.Namespace == "Microsoft.VisualC" && customModifierType.Name == "NeedsCopyConstructorModifier")) + { + return true; + } + } + + return false; + } + internal static MarshallerKind GetMarshallerKind( - TypeDesc type, - MarshalAsDescriptor marshalAs, - bool isReturn, - bool isAnsi, - MarshallerType marshallerType, - out MarshallerKind elementMarshallerKind) + TypeDesc type, + int? parameterIndex, + EmbeddedSignatureData[] customModifierData, + MarshalAsDescriptor marshalAs, + bool isReturn, + bool isAnsi, + MarshallerType marshallerType, + out MarshallerKind elementMarshallerKind) { elementMarshallerKind = MarshallerKind.Invalid; @@ -183,6 +214,12 @@ internal static MarshallerKind GetMarshallerKind( type = type.GetParameterType(); + if (!type.IsPrimitive && type.IsValueType && marshallerType != MarshallerType.Field + && HasCopyConstructorCustomModifier(parameterIndex, customModifierData)) + { + return MarshallerKind.BlittableValueClassWithCopyCtor; + } + // Compat note: CLR allows ref returning blittable structs for IJW if (isReturn) return MarshallerKind.Invalid; @@ -444,7 +481,15 @@ internal static MarshallerKind GetMarshallerKind( else if (type.IsPointer) { if (nativeType == NativeTypeKind.Default) + { + var pointedAtType = type.GetParameterType(); + if (!pointedAtType.IsPrimitive && !type.IsEnum && marshallerType != MarshallerType.Field + && HasCopyConstructorCustomModifier(parameterIndex, customModifierData)) + { + return MarshallerKind.BlittableValueClassWithCopyCtor; + } return MarshallerKind.BlittableValue; + } else return MarshallerKind.Invalid; } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs index 65f0956943fb..f713f9cb0c29 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs @@ -44,6 +44,8 @@ public static bool IsBlittableType(TypeDesc type) MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind( field.FieldType, + parameterIndex : null, + customModifierData: null, field.GetMarshalAsDescriptor(), isReturn: false, isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass, diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 31c869463025..ecd7b0df4680 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -50,6 +50,7 @@ enum MarshallerKind AsAnyA, AsAnyW, ComInterface, + BlittableValueClassWithCopyCtor, Invalid } public enum MarshalDirection @@ -271,6 +272,8 @@ protected Marshaller() /// type of the parameter to marshal /// The created Marshaller public static Marshaller CreateMarshaller(TypeDesc parameterType, + int? parameterIndex, + EmbeddedSignatureData[] customModifierData, MarshallerType marshallerType, MarshalAsDescriptor marshalAs, MarshalDirection direction, @@ -286,6 +289,8 @@ public static Marshaller CreateMarshaller(TypeDesc parameterType, { MarshallerKind elementMarshallerKind; MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(parameterType, + parameterIndex, + customModifierData, marshalAs, isReturn, flags.CharSet == CharSet.Ansi, diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs index 4ca7a6f95965..04b939334a21 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs @@ -70,6 +70,8 @@ public static Marshaller[] GetMarshallersForMethod(MethodDesc targetMethod) TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type marshallers[i] = CreateMarshaller(parameterType, + parameterIndex, + methodSig.GetEmbeddedSignatureData(), MarshallerType.Argument, parameterMetadata.MarshalAsDescriptor, direction, @@ -121,6 +123,8 @@ public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMet MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind( parameterType, + parameterIndex: i, + customModifierData: methodSig.GetEmbeddedSignatureData(), parameterMetadata.MarshalAsDescriptor, parameterMetadata.Return, isAnsi: true, 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 b895be9b24f4..02f33b81f047 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 @@ -24,6 +24,11 @@ { ret } + + .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) & Method3(int32 modopt(FooModifier)*, int32 modopt(FooModifier)*) cil managed + { + ret + } } .class private auto ansi beforefieldinit Atom 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 e6a21525ee52..60d717291196 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 @@ -69,6 +69,16 @@ public void TestSignatureMatchesModOptAtStartOfSigAndAfterByRef() Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.2.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWithModOptAtStartOfSigAndAfterByRef)); } + [Fact] + public void TestSignatureMatchesModoptOnPointerOrRefModifiedType() + { + MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); + MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method3")).Signature; + Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(0), methodWithModOpt.GetEmbeddedSignatureData()[0].index); + Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1), methodWithModOpt.GetEmbeddedSignatureData()[1].index); + Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2), methodWithModOpt.GetEmbeddedSignatureData()[2].index); + } + [Fact] public void TestSignatureMatches() { diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs new file mode 100644 index 000000000000..764e79006886 --- /dev/null +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using TestLibrary; + +static unsafe class CopyCtor +{ + public static unsafe int StructWithCtorTest(StructWithCtor* ptrStruct, ref StructWithCtor refStruct) + { + if (ptrStruct->_instanceField != 1) + return 1; + if (refStruct._instanceField != 2) + return 2; + + if (StructWithCtor.CopyCtorCallCount != 2) + return 3; + if (StructWithCtor.DtorCallCount != 2) + return 4; + + + return 100; + } + + [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] + public delegate int TestDelegate(StructWithCtor* ptrStruct, ref StructWithCtor refStruct); + + public static unsafe int Main() + { + TestDelegate del = (TestDelegate)StructWithCtorTest; + StructWithCtor s1 = new StructWithCtor(); + StructWithCtor s2 = new StructWithCtor(); + s1._instanceField = 1; + s2._instanceField = 2; + int returnVal = FunctionPointer.Call_FunctionPointer(Marshal.GetFunctionPointerForDelegate(del), &s1, ref s2); + + GC.KeepAlive(del); + + return returnVal; + } +} diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.csproj b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.csproj new file mode 100644 index 000000000000..60abf16802f0 --- /dev/null +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.csproj @@ -0,0 +1,12 @@ + + + Exe + True + + + + + + + + diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il new file mode 100644 index 000000000000..d77a1eec69e5 --- /dev/null +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern mscorlib { } +.assembly extern System.Runtime.CompilerServices.VisualC { } +.assembly CopyCtorUtil { } + +.class public sealed sequential ansi beforefieldinit StructWithCtor + extends [mscorlib]System.ValueType +{ + .field public int32 _instanceField + .field public static int32 CopyCtorCallCount + .field public static int32 DtorCallCount + + .method public specialname static void ''(valuetype StructWithCtor* A_0, + valuetype StructWithCtor* A_1) cil managed + { + ldarg.0 + ldarg.1 + ldfld int32 StructWithCtor::_instanceField + stfld int32 StructWithCtor::_instanceField + + ldsfld int32 StructWithCtor::CopyCtorCallCount + ldc.i4.1 + add + stsfld int32 StructWithCtor::CopyCtorCallCount + ret + } + + .method public specialname static void ''(valuetype StructWithCtor* A_0) cil managed + { + ldsfld int32 StructWithCtor::DtorCallCount + ldc.i4.1 + add + stsfld int32 StructWithCtor::DtorCallCount + ret + } +} + +.class public auto ansi beforefieldinit FunctionPointer + extends [mscorlib]System.Object +{ + .method hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig static int32 Call_FunctionPointer(native int fptr, + valuetype StructWithCtor* arg1, + valuetype StructWithCtor& arg2) cil managed + { + .maxstack 8 + ldarg.1 + ldarg.2 + ldarg.0 + calli unmanaged stdcall int32 (valuetype StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)*, valuetype StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)&) + ret + } +} + + diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.ilproj b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.ilproj new file mode 100644 index 000000000000..7eb71cef69df --- /dev/null +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.ilproj @@ -0,0 +1,8 @@ + + + library + + + + + From 47f9d4b5012a45d687c6544bfe8436d233cd6472 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 12:31:32 -0700 Subject: [PATCH 160/755] Generate deterministic timestamp (#40122) - Port the logic from the Roslyn compiler that handles deterministic timestamp generation - Enable for composite images This allows matching up generated pdb files with the composite image to work correctly in all known cases. --- .../CodeGen/ReadyToRunObjectWriter.cs | 11 +- .../Compiler/CryptographicHashProvider.cs | 252 ++++++++++++++++++ .../ReadyToRun/DebugDirectoryNode.cs | 19 +- .../IBC/IBCProfileParser.cs | 3 +- .../ILCompiler.ReadyToRun.csproj | 1 + .../ObjectWriter/R2RPEBuilder.cs | 10 +- 6 files changed, 285 insertions(+), 11 deletions(-) create mode 100644 src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs index 20d6dac16b8a..68239af41359 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using ILCompiler.DependencyAnalysis.ReadyToRun; @@ -102,8 +103,9 @@ public void EmitPortableExecutable() stopwatch.Start(); PEHeaderBuilder headerBuilder; - int timeDateStamp; + int? timeDateStamp; ISymbolNode r2rHeaderExportSymbol; + Func, BlobContentId> peIdProvider = null; if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null) { @@ -112,8 +114,8 @@ public void EmitPortableExecutable() dllCharacteristics: default(DllCharacteristics), Subsystem.Unknown, _nodeFactory.Target); - // TODO: generate a non-zero timestamp: https://github.com/dotnet/runtime/issues/32507 - timeDateStamp = 0; + peIdProvider = new Func, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content))); + timeDateStamp = null; r2rHeaderExportSymbol = _nodeFactory.Header; } else @@ -135,7 +137,8 @@ public void EmitPortableExecutable() r2rHeaderExportSymbol, Path.GetFileName(_objectFilePath), getRuntimeFunctionsTable, - _customPESectionAlignment); + _customPESectionAlignment, + peIdProvider); NativeDebugDirectoryEntryNode nativeDebugDirectoryEntryNode = null; ISymbolDefinitionNode firstImportThunk = null; diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs new file mode 100644 index 000000000000..dafd0c1ae7bb --- /dev/null +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs @@ -0,0 +1,252 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Metadata; +using System.Security.Cryptography; + +namespace ILCompiler +{ + /// + /// Specifies a hash algorithms used for hashing source files. + /// + public enum SourceHashAlgorithm + { + /// + /// No algorithm specified. + /// + None = 0, + + /// + /// Secure Hash Algorithm 1. + /// + Sha1 = 1, + + /// + /// Secure Hash Algorithm 2 with a hash size of 256 bits. + /// + Sha256 = 2, + } + + internal static class SourceHashAlgorithmUtils + { + public const SourceHashAlgorithm DefaultContentHashAlgorithm = SourceHashAlgorithm.Sha256; + } + + internal abstract class CryptographicHashProvider + { + private ImmutableArray _lazySHA1Hash; + private ImmutableArray _lazySHA256Hash; + private ImmutableArray _lazySHA384Hash; + private ImmutableArray _lazySHA512Hash; + private ImmutableArray _lazyMD5Hash; + + internal abstract ImmutableArray ComputeHash(HashAlgorithm algorithm); + + internal ImmutableArray GetHash(AssemblyHashAlgorithm algorithmId) + { + using (HashAlgorithm? algorithm = TryGetAlgorithm(algorithmId)) + { + // ERR_CryptoHashFailed has already been reported: + if (algorithm == null) + { + return ImmutableArray.Create(); + } + + switch (algorithmId) + { + case AssemblyHashAlgorithm.None: + case AssemblyHashAlgorithm.Sha1: + return GetHash(ref _lazySHA1Hash, algorithm); + + case AssemblyHashAlgorithm.Sha256: + return GetHash(ref _lazySHA256Hash, algorithm); + + case AssemblyHashAlgorithm.Sha384: + return GetHash(ref _lazySHA384Hash, algorithm); + + case AssemblyHashAlgorithm.Sha512: + return GetHash(ref _lazySHA512Hash, algorithm); + + case AssemblyHashAlgorithm.MD5: + return GetHash(ref _lazyMD5Hash, algorithm); + + default: + throw new ArgumentException("algorithmId"); + } + } + } + + internal static int GetHashSize(SourceHashAlgorithm algorithmId) + { + switch (algorithmId) + { + case SourceHashAlgorithm.Sha1: + return 160 / 8; + + case SourceHashAlgorithm.Sha256: + return 256 / 8; + + default: + throw new ArgumentException("algorithmId"); + } + } + + internal static HashAlgorithm? TryGetAlgorithm(SourceHashAlgorithm algorithmId) + { + switch (algorithmId) + { + case SourceHashAlgorithm.Sha1: + return SHA1.Create(); + + case SourceHashAlgorithm.Sha256: + return SHA256.Create(); + + default: + return null; + } + } + + internal static HashAlgorithmName GetAlgorithmName(SourceHashAlgorithm algorithmId) + { + switch (algorithmId) + { + case SourceHashAlgorithm.Sha1: + return HashAlgorithmName.SHA1; + + case SourceHashAlgorithm.Sha256: + return HashAlgorithmName.SHA256; + + default: + throw new ArgumentException("algorithmId"); + } + } + + internal static HashAlgorithm? TryGetAlgorithm(AssemblyHashAlgorithm algorithmId) + { + switch (algorithmId) + { + case AssemblyHashAlgorithm.None: + case AssemblyHashAlgorithm.Sha1: + return SHA1.Create(); + + case AssemblyHashAlgorithm.Sha256: + return SHA256.Create(); + + case AssemblyHashAlgorithm.Sha384: + return SHA384.Create(); + + case AssemblyHashAlgorithm.Sha512: + return SHA512.Create(); + + case AssemblyHashAlgorithm.MD5: + return MD5.Create(); + + default: + return null; + } + } + + internal static bool IsSupportedAlgorithm(AssemblyHashAlgorithm algorithmId) + { + switch (algorithmId) + { + case AssemblyHashAlgorithm.None: + case AssemblyHashAlgorithm.Sha1: + case AssemblyHashAlgorithm.Sha256: + case AssemblyHashAlgorithm.Sha384: + case AssemblyHashAlgorithm.Sha512: + case AssemblyHashAlgorithm.MD5: + return true; + + default: + return false; + } + } + + private ImmutableArray GetHash(ref ImmutableArray lazyHash, HashAlgorithm algorithm) + { + if (lazyHash.IsDefault) + { + ImmutableInterlocked.InterlockedCompareExchange(ref lazyHash, ComputeHash(algorithm), default(ImmutableArray)); + } + + return lazyHash; + } + + internal const int Sha1HashSize = 20; + + internal static ImmutableArray ComputeSha1(Stream stream) + { + if (stream != null) + { + stream.Seek(0, SeekOrigin.Begin); + using (var hashProvider = SHA1.Create()) + { + return ImmutableArray.Create(hashProvider.ComputeHash(stream)); + } + } + + return ImmutableArray.Empty; + } + + internal static ImmutableArray ComputeSha1(ImmutableArray bytes) + { + return ComputeSha1(bytes.ToArray()); + } + + internal static ImmutableArray ComputeSha1(byte[] bytes) + { + using (var hashProvider = SHA1.Create()) + { + return ImmutableArray.Create(hashProvider.ComputeHash(bytes)); + } + } + + internal static ImmutableArray ComputeHash(HashAlgorithmName algorithmName, IEnumerable bytes) + { + using (var incrementalHash = IncrementalHash.CreateHash(algorithmName)) + { + foreach (var blob in bytes) + { + incrementalHash.AppendData(blob.GetBytes()); + } + return ImmutableArray.Create(incrementalHash.GetHashAndReset()); + } + } + + internal static ImmutableArray ComputeHash(HashAlgorithmName algorithmName, IEnumerable> bytes) + { + using (var incrementalHash = IncrementalHash.CreateHash(algorithmName)) + { + foreach (var segment in bytes) + { + incrementalHash.AppendData(segment); + } + return ImmutableArray.Create(incrementalHash.GetHashAndReset()); + } + } + + internal static ImmutableArray ComputeSourceHash(ImmutableArray bytes, SourceHashAlgorithm hashAlgorithm = SourceHashAlgorithmUtils.DefaultContentHashAlgorithm) + { + var algorithmName = GetAlgorithmName(hashAlgorithm); + using (var incrementalHash = IncrementalHash.CreateHash(algorithmName)) + { + incrementalHash.AppendData(bytes.ToArray()); + return ImmutableArray.Create(incrementalHash.GetHashAndReset()); + } + } + + internal static ImmutableArray ComputeSourceHash(IEnumerable bytes, SourceHashAlgorithm hashAlgorithm = SourceHashAlgorithmUtils.DefaultContentHashAlgorithm) + { + return ComputeHash(GetAlgorithmName(hashAlgorithm), bytes); + } + } +} diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs index 08093ecd3671..175025449039 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs @@ -26,10 +26,12 @@ public class DebugDirectoryNode : ObjectNode, ISymbolDefinitionNode private EcmaModule _module; private NativeDebugDirectoryEntryNode _nativeEntry; + private bool _insertDeterministicEntry; public DebugDirectoryNode(EcmaModule sourceModule, string outputFileName) { _module = sourceModule; + _insertDeterministicEntry = sourceModule == null; // Mark module as deterministic if generating composite image string pdbNameRoot = Path.GetFileNameWithoutExtension(outputFileName); if (sourceModule != null) { @@ -50,7 +52,7 @@ public DebugDirectoryNode(EcmaModule sourceModule, string outputFileName) public int Offset => 0; - public int Size => (GetNumDebugDirectoryEntriesInModule() + 1) * ImageDebugDirectorySize; + public int Size => (GetNumDebugDirectoryEntriesInModule() + 1 + (_insertDeterministicEntry ? 1 : 0)) * ImageDebugDirectorySize; public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { @@ -112,8 +114,21 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) builder.EmitReloc(entry, RelocType.IMAGE_REL_FILE_ABSOLUTE); } + // If generating a composite image, emit the deterministic marker + if (_insertDeterministicEntry) + { + builder.EmitUInt(0 /* Characteristics */); + builder.EmitUInt(0); + builder.EmitUShort(0); + builder.EmitUShort(0); + builder.EmitInt((int)DebugDirectoryEntryType.Reproducible); + builder.EmitInt(0); + builder.EmitUInt(0); + builder.EmitUInt(0); + } + // Second, copy existing entries from input module - for(int i = 0; i < numEntries; i++) + for (int i = 0; i < numEntries; i++) { builder.EmitUInt(0 /* Characteristics */); builder.EmitUInt(entries[i].Stamp); diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs index c42ecaa13c1c..718d4e650fa6 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs @@ -113,7 +113,8 @@ public ProfileData ParseIBCDataFromModule(EcmaModule ecmaModule) } else { - _logger.Writer.WriteLine($"Token {0:x} does not refer to a method"); + if (_logger.IsVerbose) + _logger.Writer.WriteLine($"Token {(int)entry.Token:x} does not refer to a method"); } break; diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index 483973871a90..b8d01189009d 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -98,6 +98,7 @@ + diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs index 839b1f21d110..e1731e4c95f8 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs @@ -173,8 +173,9 @@ public R2RPEBuilder( ISymbolNode r2rHeaderExportSymbol, string outputFileSimpleName, Func getRuntimeFunctionsTable, - int? customPESectionAlignment) - : base(peHeaderBuilder, deterministicIdProvider: null) + int? customPESectionAlignment, + Func, BlobContentId> deterministicIdProvider) + : base(peHeaderBuilder, deterministicIdProvider: deterministicIdProvider) { _target = target; _getRuntimeFunctionsTable = getRuntimeFunctionsTable; @@ -288,7 +289,7 @@ public int GetSymbolFilePosition(ISymbolNode symbol) /// /// Output stream for the final R2R PE file /// Timestamp to set in the PE header of the output R2R executable - public void Write(Stream outputStream, int timeDateStamp) + public void Write(Stream outputStream, int? timeDateStamp) { BlobBuilder outputPeFile = new BlobBuilder(); Serialize(outputPeFile); @@ -302,7 +303,8 @@ public void Write(Stream outputStream, int timeDateStamp) ApplyMachineOSOverride(outputStream); - SetPEHeaderTimeStamp(outputStream, timeDateStamp); + if (timeDateStamp.HasValue) + SetPEHeaderTimeStamp(outputStream, timeDateStamp.Value); _written = true; } From 412f022a61a9342ee556d13d4271c487b28a617f Mon Sep 17 00:00:00 2001 From: David Cantu Date: Thu, 30 Jul 2020 13:12:54 -0700 Subject: [PATCH 161/755] Add nullability annotations to XPath*files in Xml/Cache (#40114) * Add nullability annotations to XPath* files in Xml/Cache * Move missplaced assertion on CachedTextNode * Add product fixes suggested on PR feedback --- .../System/Xml/Cache/XPathDocumentBuilder.cs | 104 ++++++++++------- .../Xml/Cache/XPathDocumentNavigator.cs | 43 ++++--- .../src/System/Xml/Cache/XPathNode.cs | 33 +++--- .../src/System/Xml/Cache/XPathNodeHelper.cs | 108 +++++++++--------- .../src/System/Xml/Cache/XPathNodeInfoAtom.cs | 95 +++++++-------- 5 files changed, 210 insertions(+), 173 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentBuilder.cs index ff09876f0d29..34c4fcc87227 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentBuilder.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. +#nullable enable using System; using System.Globalization; using System.IO; @@ -11,6 +12,7 @@ using System.Diagnostics; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace MS.Internal.Xml.Cache { @@ -40,21 +42,21 @@ internal sealed class XPathDocumentBuilder : XmlRawWriter private readonly Stack _stkNmsp; // In-scope namespaces private XPathNodeInfoTable _infoTable; // Atomization table for shared node information private XPathDocument _doc; // Currently building document - private IXmlLineInfo _lineInfo; // Line information provider + private IXmlLineInfo? _lineInfo; // Line information provider private XmlNameTable _nameTable; // Atomization table for all names in the document private bool _atomizeNames; // True if all names should be atomized (false if they are pre-atomized) private XPathNode[] _pageNmsp; // Page of last in-scope namespace node private int _idxNmsp; // Page index of last in-scope namespace node - private XPathNode[] _pageParent; // Page of last parent-type node (Element or Root) + private XPathNode[]? _pageParent; // Page of last parent-type node (Element or Root) private int _idxParent; // Page index of last parent-type node (Element or Root) - private XPathNode[] _pageSibling; // Page of previous sibling node (may be null if no previous sibling) + private XPathNode[]? _pageSibling; // Page of previous sibling node (may be null if no previous sibling) private int _idxSibling; // Page index of previous sibling node private int _lineNumBase; // Line number from which offsets are computed private int _linePosBase; // Line position from which offsets are computed - private XmlQualifiedName _idAttrName; // Cached name of an ID attribute - private Hashtable _elemIdMap; // Map from element name to ID attribute name + private XmlQualifiedName? _idAttrName; // Cached name of an ID attribute + private Hashtable? _elemIdMap; // Map from element name to ID attribute name private XPathNodeRef[] _elemNameIndex; // Elements with the same name are linked together so that they can be searched quickly private const int ElementIndexSize = 64; @@ -62,7 +64,7 @@ internal sealed class XPathDocumentBuilder : XmlRawWriter /// /// Create a new XPathDocumentBuilder which creates nodes in "doc". /// - public XPathDocumentBuilder(XPathDocument doc, IXmlLineInfo lineInfo, string baseUri, XPathDocument.LoadFlags flags) + public XPathDocumentBuilder(XPathDocument doc, IXmlLineInfo? lineInfo, string? baseUri, XPathDocument.LoadFlags flags) { // Allocate the initial node (for non-namespaces) page, and the initial namespace page _nodePageFact.Init(256); @@ -77,7 +79,12 @@ public XPathDocumentBuilder(XPathDocument doc, IXmlLineInfo lineInfo, string bas /// Start construction of a new document. This must be called before any other methods are called. /// It may also be called after Close(), in order to build further documents. /// - public void Initialize(XPathDocument doc, IXmlLineInfo lineInfo, string baseUri, XPathDocument.LoadFlags flags) + [MemberNotNull(nameof(_doc))] + [MemberNotNull(nameof(_elemNameIndex))] + [MemberNotNull(nameof(_infoTable))] + [MemberNotNull(nameof(_nameTable))] + [MemberNotNull(nameof(_pageNmsp))] + public void Initialize(XPathDocument doc, IXmlLineInfo? lineInfo, string? baseUri, XPathDocument.LoadFlags flags) { XPathNode[] page; int idx; @@ -126,14 +133,14 @@ public void Initialize(XPathDocument doc, IXmlLineInfo lineInfo, string baseUri, /// /// XPathDocument ignores the DocType information. /// - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { } /// /// Shortcut for calling WriteStartElement with elemType == null. /// - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { this.WriteStartElement(prefix, localName, ns, string.Empty); } @@ -141,7 +148,7 @@ public override void WriteStartElement(string prefix, string localName, string n /// /// Build an element node and attach it to its parent, if one exists. Make the element the new parent node. /// - public void WriteStartElement(string prefix, string localName, string ns, string baseUri) + public void WriteStartElement(string? prefix, string localName, string? ns, string? baseUri) { int hash; Debug.Assert(prefix != null && localName != null && ns != null && localName.Length != 0 && baseUri != null); @@ -164,7 +171,7 @@ public void WriteStartElement(string prefix, string localName, string ns, string // If elements within this document might have IDs, then cache the name of the ID attribute, if one exists if (_elemIdMap != null) - _idAttrName = (XmlQualifiedName)_elemIdMap[new XmlQualifiedName(localName, prefix)]; + _idAttrName = (XmlQualifiedName?)_elemIdMap[new XmlQualifiedName(localName, prefix)]; } /// @@ -205,7 +212,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri public void WriteEndElement(bool allowShortcutTag) { XPathNodeRef nodeRef; - Debug.Assert(_pageParent[_idxParent].NodeType == XPathNodeType.Element); + Debug.Assert(_pageParent != null && _pageParent[_idxParent].NodeType == XPathNodeType.Element); // If element has no content-typed children except for the one about to be added, then // its value is the same as its only text child's. @@ -277,11 +284,12 @@ public void WriteEndElement(bool allowShortcutTag) /// /// Shortcut for calling WriteStartAttribute with attrfType == null. /// - public override void WriteStartAttribute(string prefix, string localName, string namespaceName) + public override void WriteStartAttribute(string? prefix, string localName, string? namespaceName) { - Debug.Assert(!prefix.Equals("xmlns")); - Debug.Assert(_idxParent == 0 || _pageParent[_idxParent].NodeType == XPathNodeType.Element); - Debug.Assert(_idxSibling == 0 || _pageSibling[_idxSibling].NodeType == XPathNodeType.Attribute); + Debug.Assert(namespaceName != null); + Debug.Assert(prefix != null && !prefix.Equals("xmlns")); + Debug.Assert(_idxParent == 0 || (_pageParent != null && _pageParent[_idxParent].NodeType == XPathNodeType.Element)); + Debug.Assert(_idxSibling == 0 || (_pageSibling != null && _pageSibling[_idxSibling].NodeType == XPathNodeType.Attribute)); if (_atomizeNames) { @@ -298,6 +306,7 @@ public override void WriteStartAttribute(string prefix, string localName, string /// public override void WriteEndAttribute() { + Debug.Assert(_pageSibling != null); Debug.Assert(_pageSibling[_idxSibling].NodeType == XPathNodeType.Attribute); _pageSibling[_idxSibling].SetValue(_textBldr.ReadText()); @@ -309,8 +318,10 @@ public override void WriteEndAttribute() _pageSibling[_idxSibling].Prefix == _idAttrName.Namespace) { // Then add its value to the idValueMap map - Debug.Assert(_idxParent != 0, "ID attribute must have an element parent"); - _doc.AddIdElement(_pageSibling[_idxSibling].Value, _pageParent, _idxParent); + Debug.Assert(_idxParent != 0 && _pageParent != null, "ID attribute must have an element parent"); + string? id = _pageSibling[_idxSibling].Value; + Debug.Assert(id != null); + _doc.AddIdElement(id, _pageParent, _idxParent); } } } @@ -318,7 +329,7 @@ public override void WriteEndAttribute() /// /// Map CData text into regular text. /// - public override void WriteCData(string text) + public override void WriteCData(string? text) { WriteString(text, TextBlockType.Text); } @@ -326,7 +337,7 @@ public override void WriteCData(string text) /// /// Construct comment node. /// - public override void WriteComment(string text) + public override void WriteComment(string? text) { AddSibling(XPathNodeType.Comment, string.Empty, string.Empty, string.Empty, string.Empty); _pageSibling[_idxSibling].SetValue(text); @@ -335,7 +346,7 @@ public override void WriteComment(string text) /// /// Shortcut for calling WriteProcessingInstruction with baseUri = string.Empty. /// - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { this.WriteProcessingInstruction(name, text, string.Empty); } @@ -343,7 +354,7 @@ public override void WriteProcessingInstruction(string name, string text) /// /// Construct pi node. /// - public void WriteProcessingInstruction(string name, string text, string baseUri) + public void WriteProcessingInstruction(string name, string? text, string? baseUri) { if (_atomizeNames) name = _nameTable.Add(name); @@ -355,7 +366,7 @@ public void WriteProcessingInstruction(string name, string text, string baseUri) /// /// Write a whitespace text block. /// - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { WriteString(ws, TextBlockType.Whitespace); } @@ -363,7 +374,7 @@ public override void WriteWhitespace(string ws) /// /// Write an attribute or element text block. /// - public override void WriteString(string text) + public override void WriteString(string? text) { WriteString(text, TextBlockType.Text); } @@ -389,7 +400,7 @@ public override void WriteRaw(char[] buffer, int index, int count) /// /// Write an element text block with the specified text type (whitespace, significant whitespace, or text). /// - public void WriteString(string text, TextBlockType textType) + public void WriteString(string? text, TextBlockType textType) { _textBldr.WriteTextBlock(text, textType); } @@ -424,7 +435,7 @@ public override void WriteSurrogateCharEntity(char lowChar, char highChar) /// public override void Close() { - XPathNode[] page; + XPathNode[]? page; int idx; // If cached text exists, then create a text node at the top-level @@ -470,7 +481,7 @@ internal override void WriteXmlDeclaration(string xmldecl) /// internal override void StartElementContent() { - Debug.Assert(_pageParent[_idxParent].NodeType == XPathNodeType.Element); + Debug.Assert(_pageParent != null && _pageParent[_idxParent].NodeType == XPathNodeType.Element); } /// @@ -479,12 +490,13 @@ internal override void StartElementContent() /// internal override void WriteNamespaceDeclaration(string prefix, string namespaceName) { - XPathNode[] pageTemp, pageOverride, pageNew, pageOrig, pageCopy; + XPathNode[] pageTemp, pageNew, pageCopy; + XPathNode[]? pageOverride, pageOrig; int idxTemp, idxOverride, idxNew, idxOrig, idxCopy; - Debug.Assert(_idxSibling == 0 || _pageSibling[_idxSibling].NodeType == XPathNodeType.Attribute); + Debug.Assert(_idxSibling == 0 || (_pageSibling != null && _pageSibling[_idxSibling].NodeType == XPathNodeType.Attribute)); Debug.Assert(!prefix.Equals("xmlns") && !namespaceName.Equals(XmlReservedNs.NsXmlNs)); Debug.Assert(_idxParent == 0 || _idxNmsp != 0); - Debug.Assert(_idxParent == 0 || _pageParent[_idxParent].NodeType == XPathNodeType.Element); + Debug.Assert(_idxParent == 0 || (_pageParent != null && _pageParent[_idxParent].NodeType == XPathNodeType.Element)); if (_atomizeNames) prefix = _nameTable.Add(prefix); @@ -496,7 +508,7 @@ internal override void WriteNamespaceDeclaration(string prefix, string namespace idxOverride = _idxNmsp; while (idxOverride != 0) { - if ((object)pageOverride[idxOverride].LocalName == (object)prefix) + if ((object)pageOverride![idxOverride].LocalName == (object)prefix) { // Need to clone all namespaces up until the overridden node in order to bypass it break; @@ -517,8 +529,9 @@ internal override void WriteNamespaceDeclaration(string prefix, string namespace while (idxOrig != idxOverride || pageOrig != pageOverride) { + Debug.Assert(pageOrig != null); // Make a copy of the original namespace node - idxTemp = pageOrig[idxOrig].GetParent(out pageTemp); + idxTemp = pageOrig[idxOrig].GetParent(out pageTemp!); idxTemp = NewNamespaceNode(out pageTemp, pageOrig[idxOrig].LocalName, pageOrig[idxOrig].Value, pageTemp, idxTemp); // Attach copy to chain of copied nodes @@ -533,10 +546,10 @@ internal override void WriteNamespaceDeclaration(string prefix, string namespace } // Link farther up in the original chain, just past the last overridden node - idxOverride = pageOverride[idxOverride].GetSibling(out pageOverride); + idxOverride = pageOverride![idxOverride].GetSibling(out pageOverride); if (idxOverride != 0) - pageCopy[idxCopy].SetSibling(_infoTable, pageOverride, idxOverride); + pageCopy[idxCopy].SetSibling(_infoTable, pageOverride!, idxOverride); else Debug.Assert(prefix.Equals("xml"), "xmlns:xml namespace declaration should always be present in the list."); } @@ -553,6 +566,7 @@ internal override void WriteNamespaceDeclaration(string prefix, string namespace if (_idxParent != 0) { + Debug.Assert(_pageParent != null); // If this is the first namespace on the current element, if (!_pageParent[_idxParent].HasNamespaceDecls) { @@ -582,7 +596,7 @@ public void CreateIdTables(IDtdInfo dtdInfo) // Extract the elements which has attribute defined as ID from the element declarations foreach (IDtdAttributeListInfo attrList in dtdInfo.GetAttributeLists()) { - IDtdAttributeInfo idAttribute = attrList.LookupIdAttribute(); + IDtdAttributeInfo? idAttribute = attrList.LookupIdAttribute(); if (idAttribute != null) { if (_elemIdMap == null) @@ -612,7 +626,7 @@ private XPathNodeRef LinkSimilarElements(XPathNode[] pagePrev, int idxPrev, XPat /// /// Helper method that constructs a new Namespace XPathNode. /// - private int NewNamespaceNode(out XPathNode[] page, string prefix, string namespaceUri, XPathNode[] pageElem, int idxElem) + private int NewNamespaceNode(out XPathNode[] page, string prefix, string? namespaceUri, XPathNode[]? pageElem, int idxElem) { XPathNode[] pageNode; int idxNode, lineNumOffset, linePosOffset; @@ -642,7 +656,7 @@ private int NewNamespaceNode(out XPathNode[] page, string prefix, string namespa /// /// Helper method that constructs a new XPathNode. /// - private int NewNode(out XPathNode[] page, XPathNodeType xptyp, string localName, string namespaceUri, string prefix, string baseUri) + private int NewNode(out XPathNode[] page, XPathNodeType xptyp, string localName, string namespaceUri, string prefix, string? baseUri) { XPathNode[] pageNode; int idxNode, lineNumOffset, linePosOffset; @@ -714,7 +728,8 @@ private void ComputeLineInfo(bool isTextNode, out int lineNumOffset, out int lin /// Add a sibling node. If no previous sibling exists, add the node as the first child of the parent. /// If no parent exists, make this node the root of the document. /// - private void AddSibling(XPathNodeType xptyp, string localName, string namespaceUri, string prefix, string baseUri) + [MemberNotNull(nameof(_pageSibling))] + private void AddSibling(XPathNodeType xptyp, string localName, string namespaceUri, string prefix, string? baseUri) { XPathNode[] pageNew; int idxNew; @@ -728,6 +743,7 @@ private void AddSibling(XPathNodeType xptyp, string localName, string namespaceU // this.idxParent is only 0 for the top-most node if (_idxParent != 0) { + Debug.Assert(_pageParent != null); // Set properties on parent _pageParent[_idxParent].SetParentProperties(xptyp); @@ -738,6 +754,7 @@ private void AddSibling(XPathNodeType xptyp, string localName, string namespaceU } else { + Debug.Assert(_pageSibling != null); // There is already a previous sibling _pageSibling[_idxSibling].SetSibling(_infoTable, pageNew, idxNew); } @@ -750,12 +767,13 @@ private void AddSibling(XPathNodeType xptyp, string localName, string namespaceU /// /// Creates a text node from cached text parts. /// + [MemberNotNull(nameof(_pageSibling))] private void CachedTextNode() { TextBlockType textType; string text; Debug.Assert(_textBldr.HasText || (_idxSibling == 0 && _idxParent == 0), "Cannot create empty text node unless it's a top-level text node."); - Debug.Assert(_idxSibling == 0 || !_pageSibling[_idxSibling].IsText, "Cannot create adjacent text nodes."); + Debug.Assert(_idxSibling == 0 || (_pageSibling != null && !_pageSibling[_idxSibling].IsText), "Cannot create adjacent text nodes."); // Create a text node textType = _textBldr.TextType; @@ -833,7 +851,7 @@ public void AllocateSlot(out XPathNode[] page, out int idx) /// private struct TextBlockBuilder { - private IXmlLineInfo _lineInfo; + private IXmlLineInfo? _lineInfo; private TextBlockType _textType; private string _text; private int _lineNum, _linePos; @@ -841,7 +859,7 @@ private struct TextBlockBuilder /// /// Constructor. /// - public void Initialize(IXmlLineInfo lineInfo) + public void Initialize(IXmlLineInfo? lineInfo) { _lineInfo = lineInfo; _textType = TextBlockType.None; @@ -882,12 +900,12 @@ public int LinePosition /// /// Append a text block with the specified type. /// - public void WriteTextBlock(string text, TextBlockType textType) + public void WriteTextBlock(string? text, TextBlockType textType) { Debug.Assert((int)XPathNodeType.Text < (int)XPathNodeType.SignificantWhitespace); Debug.Assert((int)XPathNodeType.SignificantWhitespace < (int)XPathNodeType.Whitespace); - if (text.Length != 0) + if (!string.IsNullOrEmpty(text)) { if (_textType == TextBlockType.None) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs index 3ece1a4ce15f..18a32e7923c6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathDocumentNavigator.cs @@ -63,7 +63,7 @@ public override string Value { get { - string value; + string? value; XPathNode[] page; XPathNode[]? pageEnd; int idx, idxEnd; @@ -94,7 +94,11 @@ public override string Value if (_idxParent != 0) { Debug.Assert(_pageCurrent[_idxCurrent].NodeType == XPathNodeType.Text); - return _pageParent![_idxParent].Value; + + value = _pageParent![_idxParent].Value; + Debug.Assert(value != null); + + return value; } // Must be node with complex content, so concatenate the string values of all text descendants @@ -113,10 +117,12 @@ public override string Value while (XPathNodeHelper.GetTextFollowing(ref page, ref idx, pageEnd, idxEnd)) { Debug.Assert(page[idx].NodeType == XPathNodeType.Element || page[idx].IsText); + value = page[idx].Value; + Debug.Assert(value != null); if (s.Length == 0) { - s = page[idx].Value; + s = value; } else { @@ -125,7 +131,7 @@ public override string Value bldr = new StringBuilder(); bldr.Append(s); } - bldr.Append(page[idx].Value); + bldr.Append(value); } } @@ -193,7 +199,7 @@ public override string BaseURI { get { - XPathNode[] page; + XPathNode[]? page; int idx; if (_idxParent != 0) @@ -210,7 +216,7 @@ public override string BaseURI do { - switch (page[idx].NodeType) + switch (page![idx].NodeType) { case XPathNodeType.Element: case XPathNodeType.Root: @@ -312,7 +318,7 @@ public override bool MoveToAttribute(string? localName, string namespaceURI) /// public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) { - XPathNode[] page; + XPathNode[]? page; int idx; if (namespaceScope == XPathNamespaceScope.Local) @@ -329,11 +335,11 @@ public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) while (idx != 0) { // Don't include the xmlns:xml namespace node if scope is ExcludeXml - if (namespaceScope != XPathNamespaceScope.ExcludeXml || !page[idx].IsXmlNamespaceNode) + if (namespaceScope != XPathNamespaceScope.ExcludeXml || !page![idx].IsXmlNamespaceNode) { _pageParent = _pageCurrent; _idxParent = _idxCurrent; - _pageCurrent = page; + _pageCurrent = page!; _idxCurrent = idx; return true; } @@ -351,7 +357,7 @@ public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) /// public override bool MoveToNextNamespace(XPathNamespaceScope scope) { - XPathNode[] page = _pageCurrent, pageParent; + XPathNode[]? page = _pageCurrent, pageParent; int idx = _idxCurrent, idxParent; // If current node is not a namespace node, return false @@ -367,12 +373,13 @@ public override bool MoveToNextNamespace(XPathNamespaceScope scope) if (idx == 0) return false; + Debug.Assert(page != null); switch (scope) { case XPathNamespaceScope.Local: // Once parent changes, there are no longer any local namespaces idxParent = page[idx].GetParent(out pageParent); - if (idxParent != _idxParent || (object)pageParent != (object?)_pageParent) + if (idxParent != _idxParent || (object?)pageParent != (object?)_pageParent) return false; break; @@ -614,7 +621,7 @@ public override bool MoveToFollowing(string? localName, string namespaceURI, XPa // If this navigator is positioned on a virtual node, then compute following of parent if (_idxParent != 0) { - if (!XPathNodeHelper.GetElementFollowing(ref _pageParent, ref _idxParent, pageEnd, idxEnd, _atomizedLocalName, namespaceURI)) + if (!XPathNodeHelper.GetElementFollowing(ref _pageParent!, ref _idxParent, pageEnd, idxEnd, _atomizedLocalName, namespaceURI)) return false; _pageCurrent = _pageParent; @@ -713,7 +720,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator? end) // If this navigator is positioned on a virtual node, then compute following of parent if (_idxParent != 0) { - if (!XPathNodeHelper.GetContentFollowing(ref _pageParent, ref _idxParent, pageEnd, idxEnd, type)) + if (!XPathNodeHelper.GetContentFollowing(ref _pageParent!, ref _idxParent, pageEnd, idxEnd, type)) return false; _pageCurrent = _pageParent; @@ -812,7 +819,7 @@ public override bool IsDescendant(XPathNavigator? other) XPathDocumentNavigator? that = other as XPathDocumentNavigator; if (that != null) { - XPathNode[] pageThat; + XPathNode[]? pageThat; int idxThat; // If that current node's parent is virtualized, then start with the virtual parent @@ -830,7 +837,7 @@ public override bool IsDescendant(XPathNavigator? other) { if (idxThat == _idxCurrent && pageThat == _pageCurrent) return true; - idxThat = pageThat[idxThat].GetParent(out pageThat); + idxThat = pageThat![idxThat].GetParent(out pageThat); } } return false; @@ -852,7 +859,7 @@ private int GetPrimaryLocation() } // Yes, so primary location should be derived from parent node - return XPathNodeHelper.GetLocation(_pageParent, _idxParent); + return XPathNodeHelper.GetLocation(_pageParent!, _idxParent); } /// @@ -901,7 +908,7 @@ internal override string UniqueId // If the current node is virtualized, code its parent if (_idxParent != 0) { - loc = (_pageParent![0].PageInfo.PageNumber - 1) << 16 | (_idxParent - 1); + loc = (_pageParent![0].PageInfo!.PageNumber - 1) << 16 | (_idxParent - 1); do { buf[idx++] = UniqueIdTbl[loc & 0x1f]; @@ -911,7 +918,7 @@ internal override string UniqueId } // Code the node itself - loc = (_pageCurrent[0].PageInfo.PageNumber - 1) << 16 | (_idxCurrent - 1); + loc = (_pageCurrent[0].PageInfo!.PageNumber - 1) << 16 | (_idxCurrent - 1); do { buf[idx++] = UniqueIdTbl[loc & 0x1f]; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNode.cs index 75ab1647c227..e8c1dd592c72 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNode.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.XPath; @@ -33,7 +34,7 @@ internal struct XPathNode private ushort _idxSimilar; // Page index of next node in document order that has local name with same hashcode private ushort _posOffset; // Line position offset of node (added to LinePositionBase) private uint _props; // Node properties (broken down into bits below) - private string _value; // String value of node + private string? _value; // String value of node private const uint NodeTypeMask = 0xF; private const uint HasAttributeBit = 0x10; @@ -124,7 +125,7 @@ public XPathDocument Document /// public string BaseUri { - get { return _info.BaseUri; } + get { return _info.BaseUri ?? string.Empty; } } /// @@ -159,7 +160,7 @@ public int CollapsedLinePosition /// /// Returns information about the node page. Only the 0th node on each page has this property defined. /// - public XPathNodePageInfo PageInfo + public XPathNodePageInfo? PageInfo { get { return _info.PageInfo; } } @@ -169,13 +170,15 @@ public XPathNodePageInfo PageInfo /// public int GetRoot(out XPathNode[] pageNode) { - return _info.Document.GetRootNode(out pageNode); + int idx = _info.Document.GetRootNode(out pageNode!); + Debug.Assert(pageNode != null); + return idx; } /// /// Returns the parent of this node. If this node has no parent, then 0 is returned. /// - public int GetParent(out XPathNode[] pageNode) + public int GetParent(out XPathNode[]? pageNode) { pageNode = _info.ParentPage; return _idxParent; @@ -184,7 +187,7 @@ public int GetParent(out XPathNode[] pageNode) /// /// Returns the next sibling of this node. If this node has no next sibling, then 0 is returned. /// - public int GetSibling(out XPathNode[] pageNode) + public int GetSibling(out XPathNode[]? pageNode) { pageNode = _info.SiblingPage; return _idxSibling; @@ -194,7 +197,7 @@ public int GetSibling(out XPathNode[] pageNode) /// Returns the next element in document order that has the same local name hashcode as this element. /// If there are no similar elements, then 0 is returned. /// - public int GetSimilarElement(out XPathNode[] pageNode) + public int GetSimilarElement(out XPathNode[]? pageNode) { pageNode = _info.SimilarElementPage; return _idxSimilar; @@ -204,11 +207,11 @@ public int GetSimilarElement(out XPathNode[] pageNode) /// Returns true if this node's name matches the specified localName and namespaceName. Assume /// that localName has been atomized, but namespaceName has not. /// - public bool NameMatch(string localName, string namespaceName) + public bool NameMatch(string? localName, string namespaceName) { - Debug.Assert(localName == null || (object)Document.NameTable.Get(localName) == (object)localName, "localName must be atomized."); + Debug.Assert(localName == null || (object?)Document.NameTable.Get(localName) == (object)localName, "localName must be atomized."); - return (object)_info.LocalName == (object)localName && + return (object)_info.LocalName == (object?)localName && _info.NamespaceUri == namespaceName; } @@ -216,12 +219,12 @@ public bool NameMatch(string localName, string namespaceName) /// Returns true if this is an Element node with a name that matches the specified localName and /// namespaceName. Assume that localName has been atomized, but namespaceName has not. /// - public bool ElementMatch(string localName, string namespaceName) + public bool ElementMatch(string? localName, string namespaceName) { - Debug.Assert(localName == null || (object)Document.NameTable.Get(localName) == (object)localName, "localName must be atomized."); + Debug.Assert(localName == null || (object?)Document.NameTable.Get(localName) == (object)localName, "localName must be atomized."); return NodeType == XPathNodeType.Element && - (object)_info.LocalName == (object)localName && + (object)_info.LocalName == (object?)localName && _info.NamespaceUri == namespaceName; } @@ -333,7 +336,7 @@ public int LocalNameHashCode /// /// Return the precomputed String value of this node (null if no value exists, i.e. document node, element node with complex content, etc). /// - public string Value + public string? Value { get { return _value; } } @@ -385,7 +388,7 @@ public void SetCollapsedLineInfoOffset(int posOffset) /// /// Set this node's value. /// - public void SetValue(string value) + public void SetValue(string? value) { _value = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeHelper.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeHelper.cs index dd477325605f..aaea5e0b5a29 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeHelper.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeHelper.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.XPath; @@ -18,7 +19,7 @@ internal abstract class XPathNodeHelper /// parent is this node). Subsequent nodes may not have the same node as parent, so the caller will /// need to test the parent in order to terminate a search that processes only local namespaces. /// - public static int GetLocalNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[] pageNmsp) + public static int GetLocalNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[]? pageNmsp) { if (pageElem[idxElem].HasNamespaceDecls) { @@ -35,7 +36,7 @@ public static int GetLocalNamespaces(XPathNode[] pageElem, int idxElem, out XPat /// have this element as their parent. Since the xmlns:xml namespace node is always in scope, this /// method will never return 0 if the specified node is an element. /// - public static int GetInScopeNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[] pageNmsp) + public static int GetInScopeNamespaces(XPathNode[] pageElem, int idxElem, out XPathNode[]? pageNmsp) { XPathDocument doc; @@ -47,7 +48,7 @@ public static int GetInScopeNamespaces(XPathNode[] pageElem, int idxElem, out XP // Walk ancestors, looking for an ancestor that has at least one namespace declaration while (!pageElem[idxElem].HasNamespaceDecls) { - idxElem = pageElem[idxElem].GetParent(out pageElem); + idxElem = pageElem[idxElem].GetParent(out pageElem!); if (idxElem == 0) { // There are no namespace nodes declared on ancestors, so return xmlns:xml node @@ -84,12 +85,12 @@ public static bool GetFirstAttribute(ref XPathNode[] pageNode, ref int idxNode) /// public static bool GetNextAttribute(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] page; + XPathNode[]? page; int idx; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); idx = pageNode[idxNode].GetSibling(out page); - if (idx != 0 && page[idx].NodeType == XPathNodeType.Attribute) + if (idx != 0 && page![idx].NodeType == XPathNodeType.Attribute) { pageNode = page; idxNode = idx; @@ -104,7 +105,7 @@ public static bool GetNextAttribute(ref XPathNode[] pageNode, ref int idxNode) /// public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -117,6 +118,7 @@ public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode) { idx = page[idx].GetSibling(out page); Debug.Assert(idx != 0); + Debug.Assert(page != null); } pageNode = page; @@ -132,7 +134,7 @@ public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode) /// public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -141,7 +143,7 @@ public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode) idx = page[idx].GetSibling(out page); if (idx != 0) { - pageNode = page; + pageNode = page!; idxNode = idx; return true; } @@ -155,14 +157,14 @@ public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode) /// public static bool GetParent(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); idx = page[idx].GetParent(out page); if (idx != 0) { - pageNode = page; + pageNode = page!; idxNode = idx; return true; } @@ -177,8 +179,8 @@ public static int GetLocation(XPathNode[] pageNode, int idxNode) { Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); Debug.Assert(idxNode <= ushort.MaxValue); - Debug.Assert(pageNode[0].PageInfo.PageNumber <= short.MaxValue); - return (pageNode[0].PageInfo.PageNumber << 16) | idxNode; + Debug.Assert(pageNode[0].PageInfo!.PageNumber <= short.MaxValue); + return (pageNode[0].PageInfo!.PageNumber << 16) | idxNode; } /// @@ -186,9 +188,9 @@ public static int GetLocation(XPathNode[] pageNode, int idxNode) /// then do not set pageNode or idxNode and return false. Assume that the localName has been atomized with respect /// to this document's name table, but not the namespaceName. /// - public static bool GetElementChild(ref XPathNode[] pageNode, ref int idxNode, string localName, string namespaceName) + public static bool GetElementChild(ref XPathNode[] pageNode, ref int idxNode, string? localName, string namespaceName) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -201,7 +203,7 @@ public static bool GetElementChild(ref XPathNode[] pageNode, ref int idxNode, st // Find element with specified localName and namespaceName do { - if (page[idx].ElementMatch(localName, namespaceName)) + if (page![idx].ElementMatch(localName, namespaceName)) { pageNode = page; idxNode = idx; @@ -220,9 +222,9 @@ public static bool GetElementChild(ref XPathNode[] pageNode, ref int idxNode, st /// return false. Assume that the localName has been atomized with respect to this document's name table, /// but not the namespaceName. /// - public static bool GetElementSibling(ref XPathNode[] pageNode, ref int idxNode, string localName, string namespaceName) + public static bool GetElementSibling(ref XPathNode[] pageNode, ref int idxNode, string? localName, string namespaceName) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -236,7 +238,7 @@ public static bool GetElementSibling(ref XPathNode[] pageNode, ref int idxNode, if (idx == 0) break; - if (page[idx].ElementMatch(localName, namespaceName)) + if (page![idx].ElementMatch(localName, namespaceName)) { pageNode = page; idxNode = idx; @@ -254,7 +256,7 @@ public static bool GetElementSibling(ref XPathNode[] pageNode, ref int idxNode, /// public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; int mask; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -267,7 +269,7 @@ public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode, XP GetChild(ref page, ref idx); do { - if (((1 << (int)page[idx].NodeType) & mask) != 0) + if (((1 << (int)page![idx].NodeType) & mask) != 0) { // Never return attributes, as Attribute is not a content type if (typ == XPathNodeType.Attribute) @@ -292,7 +294,7 @@ public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode, XP /// public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; int mask = XPathNavigator.GetContentKindMask(typ); Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -306,7 +308,7 @@ public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode, if (idx == 0) break; - if (((1 << (int)page[idx].NodeType) & mask) != 0) + if (((1 << (int)page![idx].NodeType) & mask) != 0) { Debug.Assert(typ != XPathNodeType.Attribute && typ != XPathNodeType.Namespace); pageNode = page; @@ -325,7 +327,7 @@ public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode, /// public static bool GetPreviousContentSibling(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] pageParent = pageNode, pagePrec, pageAnc; + XPathNode[]? pageParent, pagePrec, pageAnc; int idxParent = idxNode, idxPrec, idxAnc; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); Debug.Assert(pageNode[idxNode].NodeType != XPathNodeType.Attribute); @@ -336,14 +338,15 @@ public static bool GetPreviousContentSibling(ref XPathNode[] pageNode, ref int i // 3. Get node that immediately precedes the current node in document order // 4. If preceding node is parent, then there is no previous sibling, so return false // 5. Walk ancestors of preceding node, until parent of current node is found - idxParent = pageParent[idxParent].GetParent(out pageParent); + idxParent = pageNode[idxParent].GetParent(out pageParent); if (idxParent != 0) { idxPrec = idxNode - 1; if (idxPrec == 0) { // Need to get previous page - pagePrec = pageNode[0].PageInfo.PreviousPage; + pagePrec = pageNode[0].PageInfo!.PreviousPage; + Debug.Assert(pagePrec != null); idxPrec = pagePrec.Length - 1; } else @@ -385,9 +388,9 @@ public static bool GetPreviousContentSibling(ref XPathNode[] pageNode, ref int i /// then do not set pageNode or idxNode and return false. Assume that the localName has been atomized with respect /// to this document's name table, but not the namespaceName. /// - public static bool GetAttribute(ref XPathNode[] pageNode, ref int idxNode, string localName, string namespaceName) + public static bool GetAttribute(ref XPathNode[] pageNode, ref int idxNode, string? localName, string namespaceName) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)"); @@ -405,7 +408,7 @@ public static bool GetAttribute(ref XPathNode[] pageNode, ref int idxNode, strin } idx = page[idx].GetSibling(out page); } - while (idx != 0 && page[idx].NodeType == XPathNodeType.Attribute); + while (idx != 0 && page![idx].NodeType == XPathNodeType.Attribute); } return false; @@ -419,14 +422,14 @@ public static bool GetAttribute(ref XPathNode[] pageNode, ref int idxNode, strin /// If no such element exists, then do not set pageCurrent or idxCurrent and return false. /// Assume that the localName has been atomized with respect to this document's name table, but not the namespaceName. /// - public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[] pageEnd, int idxEnd, string localName, string namespaceName) + public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[]? pageEnd, int idxEnd, string? localName, string namespaceName) { - XPathNode[] page = pageCurrent; + XPathNode[]? page = pageCurrent; int idx = idxCurrent; Debug.Assert(pageCurrent != null && idxCurrent != 0, "Cannot pass null argument(s)"); // If current node is an element having a matching name, - if (page[idx].NodeType == XPathNodeType.Element && (object)page[idx].LocalName == (object)localName) + if (page[idx].NodeType == XPathNodeType.Element && (object)page[idx].LocalName == (object?)localName) { // Then follow similar element name pointers int idxPageEnd = 0; @@ -434,8 +437,8 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC if (pageEnd != null) { - idxPageEnd = pageEnd[0].PageInfo.PageNumber; - idxPageCurrent = page[0].PageInfo.PageNumber; + idxPageEnd = pageEnd[0].PageInfo!.PageNumber; + idxPageCurrent = page[0].PageInfo!.PageNumber; // If ending node is <= starting node in document order, then scan to end of document if (idxPageCurrent > idxPageEnd || (idxPageCurrent == idxPageEnd && idx >= idxEnd)) @@ -449,10 +452,12 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC if (idx == 0) break; + Debug.Assert(page != null); + // Only scan to ending node if (pageEnd != null) { - idxPageCurrent = page[0].PageInfo.PageNumber; + idxPageCurrent = page[0].PageInfo!.PageNumber; if (idxPageCurrent > idxPageEnd) break; @@ -472,7 +477,7 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC idx++; do { - if ((object)page == (object)pageEnd && idx <= idxEnd) + if ((object)page == (object?)pageEnd && idx <= idxEnd) { // Only scan to termination point while (idx != idxEnd) @@ -486,7 +491,7 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC else { // Scan all nodes in the page - while (idx < page[0].PageInfo.NodeCount) + while (idx < page[0].PageInfo!.NodeCount) { if (page[idx].ElementMatch(localName, namespaceName)) goto FoundNode; @@ -494,7 +499,7 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC } } - page = page[0].PageInfo.NextPage; + page = page[0].PageInfo!.NextPage; idx = 1; } while (page != null); @@ -515,9 +520,9 @@ public static bool GetElementFollowing(ref XPathNode[] pageCurrent, ref int idxC /// 3. Has the specified XPathNodeType (but Attributes and Namespaces never match) /// If no such node exists, then do not set pageCurrent or idxCurrent and return false. /// - public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[] pageEnd, int idxEnd, XPathNodeType typ) + public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[]? pageEnd, int idxEnd, XPathNodeType typ) { - XPathNode[] page = pageCurrent; + XPathNode[]? page = pageCurrent; int idx = idxCurrent; int mask = XPathNavigator.GetContentKindMask(typ); Debug.Assert(pageCurrent != null && idxCurrent != 0, "Cannot pass null argument(s)"); @@ -529,7 +534,7 @@ public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxC idx++; do { - if ((object)page == (object)pageEnd && idx <= idxEnd) + if ((object)page == (object?)pageEnd && idx <= idxEnd) { // Only scan to termination point while (idx != idxEnd) @@ -543,7 +548,7 @@ public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxC else { // Scan all nodes in the page - while (idx < page[0].PageInfo.NodeCount) + while (idx < page[0].PageInfo!.NodeCount) { if (((1 << (int)page[idx].NodeType) & mask) != 0) goto FoundNode; @@ -551,7 +556,7 @@ public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxC } } - page = page[0].PageInfo.NextPage; + page = page[0].PageInfo!.NextPage; idx = 1; } while (page != null); @@ -574,9 +579,9 @@ public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxC /// 2. Non-collapsed text nodes /// If no such node exists, then do not set pageCurrent or idxCurrent and return false. /// - public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[] pageEnd, int idxEnd) + public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[]? pageEnd, int idxEnd) { - XPathNode[] page = pageCurrent; + XPathNode[]? page = pageCurrent; int idx = idxCurrent; Debug.Assert(pageCurrent != null && idxCurrent != 0, "Cannot pass null argument(s)"); Debug.Assert(!page[idx].IsAttrNmsp, "Current node should never be an attribute or namespace--caller should handle this case."); @@ -586,7 +591,7 @@ public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurr idx++; do { - if ((object)page == (object)pageEnd && idx <= idxEnd) + if ((object)page == (object?)pageEnd && idx <= idxEnd) { // Only scan to termination point while (idx != idxEnd) @@ -600,7 +605,7 @@ public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurr else { // Scan all nodes in the page - while (idx < page[0].PageInfo.NodeCount) + while (idx < page[0].PageInfo!.NodeCount) { if (page[idx].IsText || (page[idx].NodeType == XPathNodeType.Element && page[idx].HasCollapsedText)) goto FoundNode; @@ -608,7 +613,7 @@ public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurr } } - page = page[0].PageInfo.NextPage; + page = page[0].PageInfo!.NextPage; idx = 1; } while (page != null); @@ -628,18 +633,18 @@ public static bool GetTextFollowing(ref XPathNode[] pageCurrent, ref int idxCurr /// public static bool GetNonDescendant(ref XPathNode[] pageNode, ref int idxNode) { - XPathNode[] page = pageNode; + XPathNode[]? page = pageNode; int idx = idxNode; // Get page, idx at which to end sequential scan of nodes do { // If the current node has a sibling, - if (page[idx].HasSibling) + if (page![idx].HasSibling) { // Then that is the first non-descendant pageNode = page; - idxNode = page[idx].GetSibling(out pageNode); + idxNode = page[idx].GetSibling(out pageNode!); return true; } @@ -662,7 +667,8 @@ private static void GetChild(ref XPathNode[] pageNode, ref int idxNode) if (++idxNode >= pageNode.Length) { // Child is first node on next page - pageNode = pageNode[0].PageInfo.NextPage; + pageNode = pageNode[0].PageInfo!.NextPage!; + Debug.Assert(pageNode != null); idxNode = 1; } // Else child is next node on this page diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeInfoAtom.cs b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeInfoAtom.cs index 001844076683..4396a832e338 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeInfoAtom.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Cache/XPathNodeInfoAtom.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. +#nullable enable using System; using System.Diagnostics; using System.Text; @@ -17,13 +18,13 @@ internal sealed class XPathNodePageInfo { private readonly int _pageNum; private int _nodeCount; - private readonly XPathNode[] _pagePrev; - private XPathNode[] _pageNext; + private readonly XPathNode[]? _pagePrev; + private XPathNode[]? _pageNext; /// /// Constructor. /// - public XPathNodePageInfo(XPathNode[] pagePrev, int pageNum) + public XPathNodePageInfo(XPathNode[]? pagePrev, int pageNum) { _pagePrev = pagePrev; _pageNum = pageNum; @@ -50,7 +51,7 @@ public int NodeCount /// /// Return the previous node page in the document. /// - public XPathNode[] PreviousPage + public XPathNode[]? PreviousPage { get { return _pagePrev; } } @@ -58,7 +59,7 @@ public XPathNode[] PreviousPage /// /// Return the next node page in the document. /// - public XPathNode[] NextPage + public XPathNode[]? NextPage { get { return _pageNext; } set { _pageNext = value; } @@ -77,20 +78,20 @@ public XPathNode[] NextPage /// internal sealed class XPathNodeInfoAtom : IEquatable { - private string _localName; - private string _namespaceUri; - private string _prefix; - private string _baseUri; - private XPathNode[] _pageParent; - private XPathNode[] _pageSibling; - private XPathNode[] _pageSimilar; - private XPathDocument _doc; + private string _localName = null!; + private string _namespaceUri = null!; + private string _prefix = null!; + private string? _baseUri; + private XPathNode[]? _pageParent; + private XPathNode[]? _pageSibling; + private XPathNode[]? _pageSimilar; + private XPathDocument _doc = null!; private int _lineNumBase; private int _linePosBase; private int _hashCode; private int _localNameHash; - private XPathNodeInfoAtom _next; - private XPathNodePageInfo _pageInfo; + private XPathNodeInfoAtom? _next; + private XPathNodePageInfo? _pageInfo; /// @@ -105,8 +106,8 @@ public XPathNodeInfoAtom(XPathNodePageInfo pageInfo) /// /// Construct a new shared information atom. This method should only be used by the XNodeInfoTable. /// - public XPathNodeInfoAtom(string localName, string namespaceUri, string prefix, string baseUri, - XPathNode[] pageParent, XPathNode[] pageSibling, XPathNode[] pageSimilar, + public XPathNodeInfoAtom(string localName, string namespaceUri, string prefix, string? baseUri, + XPathNode[]? pageParent, XPathNode[]? pageSibling, XPathNode[]? pageSimilar, XPathDocument doc, int lineNumBase, int linePosBase) { Init(localName, namespaceUri, prefix, baseUri, pageParent, pageSibling, pageSimilar, doc, lineNumBase, linePosBase); @@ -115,8 +116,8 @@ public XPathNodeInfoAtom(string localName, string namespaceUri, string prefix, s /// /// Initialize an existing shared information atom. This method should only be used by the XNodeInfoTable. /// - public void Init(string localName, string namespaceUri, string prefix, string baseUri, - XPathNode[] pageParent, XPathNode[] pageSibling, XPathNode[] pageSimilar, + public void Init(string localName, string namespaceUri, string prefix, string? baseUri, + XPathNode[]? pageParent, XPathNode[]? pageSibling, XPathNode[]? pageSimilar, XPathDocument doc, int lineNumBase, int linePosBase) { Debug.Assert(localName != null && namespaceUri != null && prefix != null && doc != null); @@ -143,7 +144,7 @@ public void Init(string localName, string namespaceUri, string prefix, string ba /// /// Returns information about the node page. Only the 0th node on each page has this property defined. /// - public XPathNodePageInfo PageInfo + public XPathNodePageInfo? PageInfo { get { return _pageInfo; } } @@ -175,7 +176,7 @@ public string Prefix /// /// Return the base Uri of nodes that share this information atom. /// - public string BaseUri + public string? BaseUri { get { return _baseUri; } } @@ -183,7 +184,7 @@ public string BaseUri /// /// Return the page containing the next sibling of nodes that share this information atom. /// - public XPathNode[] SiblingPage + public XPathNode[]? SiblingPage { get { return _pageSibling; } } @@ -191,7 +192,7 @@ public XPathNode[] SiblingPage /// /// Return the page containing the next element having a name which has same hashcode as this element. /// - public XPathNode[] SimilarElementPage + public XPathNode[]? SimilarElementPage { get { return _pageSimilar; } } @@ -199,7 +200,7 @@ public XPathNode[] SimilarElementPage /// /// Return the page containing the parent of nodes that share this information atom. /// - public XPathNode[] ParentPage + public XPathNode[]? ParentPage { get { return _pageParent; } } @@ -239,7 +240,7 @@ public int LocalNameHashCode /// /// Link together InfoAtoms that hash to the same hashtable bucket (should only be used by XPathNodeInfoTable) /// - public XPathNodeInfoAtom Next + public XPathNodeInfoAtom? Next { get { return _next; } set { _next = value; } @@ -261,13 +262,13 @@ public override int GetHashCode() unchecked { if (_pageSibling != null) - hashCode += (hashCode << 7) ^ _pageSibling[0].PageInfo.PageNumber; + hashCode += (hashCode << 7) ^ _pageSibling[0].PageInfo!.PageNumber; if (_pageParent != null) - hashCode += (hashCode << 7) ^ _pageParent[0].PageInfo.PageNumber; + hashCode += (hashCode << 7) ^ _pageParent[0].PageInfo!.PageNumber; if (_pageSimilar != null) - hashCode += (hashCode << 7) ^ _pageSimilar[0].PageInfo.PageNumber; + hashCode += (hashCode << 7) ^ _pageSimilar[0].PageInfo!.PageNumber; } // Save hashcode. Don't save 0, so that it won't ever be recomputed. @@ -280,27 +281,27 @@ public override int GetHashCode() /// /// Return true if this InfoAtom has the same values as another InfoAtom. /// - public override bool Equals(object other) + public override bool Equals(object? other) { return Equals(other as XPathNodeInfoAtom); } - public bool Equals(XPathNodeInfoAtom other) + public bool Equals(XPathNodeInfoAtom? other) { Debug.Assert(other != null); - Debug.Assert((object)_doc == (object)other._doc); + Debug.Assert((object?)_doc == (object?)other._doc); Debug.Assert(_pageInfo == null); // Assume that name parts are atomized if (this.GetHashCode() == other.GetHashCode()) { - if ((object)_localName == (object)other._localName && - (object)_pageSibling == (object)other._pageSibling && - (object)_namespaceUri == (object)other._namespaceUri && - (object)_pageParent == (object)other._pageParent && - (object)_pageSimilar == (object)other._pageSimilar && - (object)_prefix == (object)other._prefix && - (object)_baseUri == (object)other._baseUri && + if ((object?)_localName == (object?)other._localName && + (object?)_pageSibling == (object?)other._pageSibling && + (object?)_namespaceUri == (object?)other._namespaceUri && + (object?)_pageParent == (object?)other._pageParent && + (object?)_pageSimilar == (object?)other._pageSimilar && + (object?)_prefix == (object?)other._prefix && + (object?)_baseUri == (object?)other._baseUri && _lineNumBase == other._lineNumBase && _linePosBase == other._linePosBase) { @@ -322,12 +323,14 @@ public override string ToString() bldr.Append(GetHashCode()); bldr.Append(", "); + Debug.Assert(_localName != null); if (_localName.Length != 0) { bldr.Append('{'); bldr.Append(_namespaceUri); bldr.Append('}'); + Debug.Assert(_prefix != null); if (_prefix.Length != 0) { bldr.Append(_prefix); @@ -341,21 +344,21 @@ public override string ToString() if (_pageParent != null) { bldr.Append("parent="); - bldr.Append(_pageParent[0].PageInfo.PageNumber); + bldr.Append(_pageParent[0].PageInfo!.PageNumber); bldr.Append(", "); } if (_pageSibling != null) { bldr.Append("sibling="); - bldr.Append(_pageSibling[0].PageInfo.PageNumber); + bldr.Append(_pageSibling[0].PageInfo!.PageNumber); bldr.Append(", "); } if (_pageSimilar != null) { bldr.Append("similar="); - bldr.Append(_pageSimilar[0].PageInfo.PageNumber); + bldr.Append(_pageSimilar[0].PageInfo!.PageNumber); bldr.Append(", "); } @@ -378,7 +381,7 @@ internal sealed class XPathNodeInfoTable { private XPathNodeInfoAtom[] _hashTable; private int _sizeTable; - private XPathNodeInfoAtom _infoCached; + private XPathNodeInfoAtom? _infoCached; #if DEBUG private const int DefaultTableSize = 2; @@ -398,8 +401,8 @@ public XPathNodeInfoTable() /// /// Create a new XNodeInfoAtom and ensure it is atomized in the table. /// - public XPathNodeInfoAtom Create(string localName, string namespaceUri, string prefix, string baseUri, - XPathNode[] pageParent, XPathNode[] pageSibling, XPathNode[] pageSimilar, + public XPathNodeInfoAtom Create(string localName, string namespaceUri, string prefix, string? baseUri, + XPathNode[]? pageParent, XPathNode[]? pageSibling, XPathNode[]? pageSimilar, XPathDocument doc, int lineNumBase, int linePosBase) { XPathNodeInfoAtom info; @@ -434,7 +437,7 @@ public XPathNodeInfoAtom Create(string localName, string namespaceUri, string pr /// private XPathNodeInfoAtom Atomize(XPathNodeInfoAtom info) { - XPathNodeInfoAtom infoNew, infoNext; + XPathNodeInfoAtom? infoNew, infoNext; // Search for existing XNodeInfoAtom in the table infoNew = _hashTable[info.GetHashCode() & (_hashTable.Length - 1)]; @@ -492,7 +495,7 @@ private void AddInfo(XPathNodeInfoAtom info) public override string ToString() { StringBuilder bldr = new StringBuilder(); - XPathNodeInfoAtom infoAtom; + XPathNodeInfoAtom? infoAtom; for (int i = 0; i < _hashTable.Length; i++) { From 61cbd57ca6dc54ed1e8b6fd45e72c00e8ba030f2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2020 13:55:35 -0700 Subject: [PATCH 162/755] [master] Update dependencies from dotnet/arcade mono/linker Microsoft/vstest dotnet/runtime-assets dotnet/xharness (#40085) * Update dependencies from https://github.com/dotnet/arcade build 20200724.1 Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk , Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat From Version 5.0.0-beta.20364.3 -> To Version 5.0.0-beta.20374.1 * Update dependencies from https://github.com/mono/linker build 20200728.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20374.1 -> To Version 5.0.0-preview.3.20378.1 * Update dependencies from https://github.com/microsoft/vstest build 20200730-02 Microsoft.NET.Test.Sdk From Version 16.8.0-preview-20200720-01 -> To Version 16.8.0-preview-20200730-02 * Update dependencies from https://github.com/dotnet/runtime-assets build 20200727.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.20364.1 -> To Version 5.0.0-beta.20377.1 * Update dependencies from https://github.com/dotnet/xharness build 20200730.1 Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 1.0.0-prerelease.20352.3 -> To Version 1.0.0-prerelease.20380.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 104 +++++++++++++++---------------- eng/Versions.props | 44 ++++++------- eng/common/cross/toolchain.cmake | 41 +++++++----- global.json | 8 +-- 4 files changed, 104 insertions(+), 93 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 19226bc17d50..5458447cdad3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,61 +10,61 @@ - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915 + f6192d1e284a08ac05041d05fa6e60dec74b24f5 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -86,41 +86,41 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - 069d8bd6357e2dbc260a35016ddbefe5dfec4102 + ddb755f58160c0e7fab50964d665be1bf47ff579 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/runtime-assets - 5a041ae14a25fe6e5db62666778a7adb59d5a056 + 4d5781485294568e51a4673719c8ae5ae8955e70 https://github.com/dotnet/llvm-project @@ -182,17 +182,17 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 8224c7254fc4aa5da70bb7d2e0d1c55bca1e19bf + 7c9b806037e88df7eb40a8151808730133676668 - + https://github.com/dotnet/xharness - 5c95b40b725e1aa9d596411c453900385cf6f84c + d5f2dfa6abcab999bd65fb95ac694d4109df405c - + https://github.com/dotnet/xharness - 5c95b40b725e1aa9d596411c453900385cf6f84c + d5f2dfa6abcab999bd65fb95ac694d4109df405c diff --git a/eng/Versions.props b/eng/Versions.props index e005381789a8..35d095e73dc8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,16 +52,16 @@ - 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 - 5.0.0-beta.20364.3 - 5.0.0-beta.20367.6 - 2.5.1-beta.20364.3 - 5.0.0-beta.20374.3 - 5.0.0-beta.20367.6 - 5.0.0-beta.20364.3 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 2.5.1-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 + 5.0.0-beta.20374.1 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 @@ -102,14 +102,14 @@ 4.3.0 5.0.0-alpha.1.19563.3 - 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 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 + 5.0.0-beta.20377.1 2.2.0-prerelease.19564.1 2.0.3 @@ -133,9 +133,9 @@ 4.9.4 4.9.4 - 16.8.0-preview-20200720-01 - 1.0.0-prerelease.20352.3 - 1.0.0-prerelease.20352.3 + 16.8.0-preview-20200730-02 + 1.0.0-prerelease.20380.1 + 1.0.0-prerelease.20380.1 2.4.1 2.4.2 1.3.0 @@ -146,7 +146,7 @@ 3.0.0-preview-20200715.1 - 5.0.0-preview.3.20374.1 + 5.0.0-preview.3.20378.1 5.0.0-preview.8.20378.2 diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 88a758afb19c..b9fe796f0da7 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -127,29 +127,40 @@ endif() # Specify link flags +function(add_toolchain_linker_flag Flag) + set(Config "${ARGV1}") + set(CONFIG_SUFFIX "") + if (NOT Config STREQUAL "") + set(CONFIG_SUFFIX "_${Config}") + endif() + set("CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}" "${CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}} ${Flag}" PARENT_SCOPE) + set("CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}" "${CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}} ${Flag}" PARENT_SCOPE) +endfunction() + + if(TARGET_ARCH_NAME STREQUAL "armel") if(DEFINED TIZEN_TOOLCHAIN) # For Tizen only - add_link_options("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") - add_link_options("-L${CROSS_ROOTFS}/lib") - add_link_options("-L${CROSS_ROOTFS}/usr/lib") - add_link_options("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") endif() elseif(TARGET_ARCH_NAME STREQUAL "arm64") if(DEFINED TIZEN_TOOLCHAIN) # For Tizen only - add_link_options("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") - add_link_options("-L${CROSS_ROOTFS}/lib64") - add_link_options("-L${CROSS_ROOTFS}/usr/lib64") - add_link_options("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") - - add_link_options("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") - add_link_options("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") - add_link_options("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") - add_link_options(-m32) + add_toolchain_linker_flag(-m32) elseif(ILLUMOS) - add_link_options("-L${CROSS_ROOTFS}/lib/amd64") - add_link_options("-L${CROSS_ROOTFS}/usr/amd64/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/amd64/lib") endif() # Specify compile options diff --git a/global.json b/global.json index 1c3df45ddb57..5d4b27ae61c0 100644 --- a/global.json +++ b/global.json @@ -12,10 +12,10 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20372.2", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20364.3", - "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20364.3", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20364.3", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20374.1", + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20374.1", + "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20374.1", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20374.1", "Microsoft.FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", "Microsoft.NET.Sdk.IL": "5.0.0-preview.8.20359.4", "Microsoft.Build.NoTargets": "1.0.53", From fb6cc280611ec76fefd55b2f50c563e0fc6aa45c Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Thu, 30 Jul 2020 23:09:44 +0200 Subject: [PATCH 163/755] Exclude EUid and EGid for Browser build as they are not supported (#39483) --- .../src/System.IO.FileSystem.csproj | 13 +++++++++---- .../src/System/IO/FileStatus.Unix.cs | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj b/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj index 0c36fbf8b216..f7d2d0c5499a 100644 --- a/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj +++ b/src/libraries/System.IO.FileSystem/src/System.IO.FileSystem.csproj @@ -5,6 +5,9 @@ $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable + + $(DefineConstants);TARGET_BROWSER + @@ -177,8 +180,6 @@ Link="Interop\Unix\Interop.Errors.cs" /> - - + + + + diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs index 086c09039f02..e32d3a1c54df 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs @@ -39,7 +39,12 @@ internal static void Initialize( internal bool IsReadOnly(ReadOnlySpan path, bool continueOnError = false) { EnsureStatInitialized(path, continueOnError); +#if TARGET_BROWSER + const Interop.Sys.Permissions readBit = Interop.Sys.Permissions.S_IRUSR; + const Interop.Sys.Permissions writeBit = Interop.Sys.Permissions.S_IWUSR; +#else Interop.Sys.Permissions readBit, writeBit; + if (_fileStatus.Uid == Interop.Sys.GetEUid()) { // User effectively owns the file @@ -58,6 +63,7 @@ internal bool IsReadOnly(ReadOnlySpan path, bool continueOnError = false) readBit = Interop.Sys.Permissions.S_IROTH; writeBit = Interop.Sys.Permissions.S_IWOTH; } +#endif return ((_fileStatus.Mode & (int)readBit) != 0 && // has read permission (_fileStatus.Mode & (int)writeBit) == 0); // but not write permission From fcacfcd44756e2a72e8fe61b6c6ba3ace381da00 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 30 Jul 2020 14:52:15 -0700 Subject: [PATCH 164/755] Verify JsonSerializer support for init-only properties (#40150) --- ...pertyVisibilityTests.NonPublicAccessors.cs | 21 +++++ .../Serialization/PropertyVisibilityTests.cs | 2 +- .../PropertyVisiblityTests.InitOnly.cs | 94 +++++++++++++++++++ .../tests/System.Text.Json.Tests.csproj | 1 + 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Text.Json/tests/Serialization/PropertyVisiblityTests.InitOnly.cs diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs index be76b5e424a0..0dd3657e6f5c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs @@ -298,6 +298,9 @@ private class ClassWithMixedPropertyAccessors_PropertyAttributes [InlineData(typeof(ClassWithPrivateField_WithJsonIncludeProperty))] [InlineData(typeof(ClassWithInternalField_WithJsonIncludeProperty))] [InlineData(typeof(ClassWithProtectedField_WithJsonIncludeProperty))] + [InlineData(typeof(ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty))] + [InlineData(typeof(ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty))] + [InlineData(typeof(ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty))] public static void NonPublicProperty_WithJsonInclude_Invalid(Type type) { InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize("", type)); @@ -350,5 +353,23 @@ private class ClassWithProtectedField_WithJsonIncludeProperty [JsonInclude] protected string MyString = null; } + + private class ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty + { + [JsonInclude] + private string MyString { get; init; } + } + + private class ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty + { + [JsonInclude] + internal string MyString { get; init; } + } + + private class ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty + { + [JsonInclude] + protected string MyString { get; init; } + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 6e377f8340be..062813373ae2 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Collections.Concurrent; -using Xunit; using System.Numerics; +using Xunit; namespace System.Text.Json.Serialization.Tests { diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisiblityTests.InitOnly.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisiblityTests.InitOnly.cs new file mode 100644 index 000000000000..48fe1e34c935 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisiblityTests.InitOnly.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static partial class PropertyVisibilityTests + { + [Theory] + [InlineData(typeof(ClassWithInitOnlyProperty))] + [InlineData(typeof(StructWithInitOnlyProperty))] + public static void InitOnlyProperties_Work(Type type) + { + // Init-only property included by default. + object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type); + Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj)); + + // Init-only properties can be serialized. + Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj)); + } + + [Theory] + [InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter))] + [InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter))] + [InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter))] + public static void NonPublicInitOnlySetter_Without_JsonInclude_Fails(Type type) + { + // Non-public init-only property setter ignored. + object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type); + Assert.Equal(0, (int)type.GetProperty("MyInt").GetValue(obj)); + + // Public getter can be used for serialization. + Assert.Equal(@"{""MyInt"":0}", JsonSerializer.Serialize(obj)); + } + + [Theory] + [InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter_WithAttribute))] + [InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter_WithAttribute))] + [InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute))] + public static void NonPublicInitOnlySetter_With_JsonInclude_Works(Type type) + { + // Non-public init-only property setter included with [JsonInclude]. + object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type); + Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj)); + + // Init-only properties can be serialized. + Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj)); + } + + public class ClassWithInitOnlyProperty + { + public int MyInt { get; init; } + } + + public struct StructWithInitOnlyProperty + { + public int MyInt { get; init; } + } + + public class Class_PropertyWith_PrivateInitOnlySetter + { + public int MyInt { get; private init; } + } + + public class Class_PropertyWith_InternalInitOnlySetter + { + public int MyInt { get; internal init; } + } + + public class Class_PropertyWith_ProtectedInitOnlySetter + { + public int MyInt { get; protected init; } + } + + public class Class_PropertyWith_PrivateInitOnlySetter_WithAttribute + { + [JsonInclude] + public int MyInt { get; private init; } + } + + public class Class_PropertyWith_InternalInitOnlySetter_WithAttribute + { + [JsonInclude] + public int MyInt { get; internal init; } + } + + public class Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute + { + [JsonInclude] + public int MyInt { get; protected init; } + } + } +} 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 808880d9af6a..74459b8f4f6b 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 @@ -99,6 +99,7 @@ + From 621ed57461ed21c4eb8b6fbff3fa81ddf853ff1c Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Thu, 30 Jul 2020 14:52:46 -0700 Subject: [PATCH 165/755] Correcting Mismatch between ref and src (#39741) * minor formatting * ref changes --- .../ref/Microsoft.Extensions.Logging.cs | 32 +++++++++---------- .../ref/Microsoft.Win32.Registry.cs | 1 - .../System.CodeDom/ref/System.CodeDom.cs | 2 +- .../ref/System.ComponentModel.Primitives.cs | 4 +-- .../ref/System.Diagnostics.StackTrace.cs | 4 +-- .../ref/System.Drawing.Common.cs | 13 ++++---- .../ref/System.IO.IsolatedStorage.cs | 5 ++- .../SafeMemoryMappedFileHandle.Windows.cs | 2 ++ .../ref/System.Net.Http.WinHttpHandler.cs | 2 +- .../ref/System.Net.Primitives.cs | 6 ++-- .../ref/System.Numerics.Vectors.cs | 8 ++--- .../ref/System.Resources.Writer.cs | 2 +- .../System.Runtime.CompilerServices.Unsafe.cs | 28 ++++++++-------- ...System.Runtime.CompilerServices.VisualC.cs | 10 +++--- ...time.InteropServices.RuntimeInformation.cs | 12 +++---- .../ref/System.Runtime.InteropServices.cs | 2 +- .../ref/System.Runtime.Loader.cs | 2 +- .../System.Runtime/ref/System.Runtime.cs | 8 ++--- ...System.Security.Cryptography.Primitives.cs | 9 ++++-- .../ref/System.Threading.AccessControl.cs | 24 +++++++------- .../ref/System.Threading.Overlapped.cs | 6 ++-- .../ref/System.Threading.ThreadPool.cs | 2 +- .../System.Threading/ref/System.Threading.cs | 26 +++++++-------- 23 files changed, 106 insertions(+), 104 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.cs b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.cs index d192fa99a484..fafdc5319da6 100644 --- a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.cs +++ b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.cs @@ -14,6 +14,16 @@ public static partial class LoggingServiceCollectionExtensions } namespace Microsoft.Extensions.Logging { + [System.FlagsAttribute] + public enum ActivityTrackingOptions + { + None = 0, + SpanId = 1, + TraceId = 2, + ParentId = 4, + TraceState = 8, + TraceFlags = 16, + } public static partial class FilterLoggingBuilderExtensions { public static Microsoft.Extensions.Logging.ILoggingBuilder AddFilter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Func levelFilter) { throw null; } @@ -39,21 +49,6 @@ public partial interface ILoggingBuilder { Microsoft.Extensions.DependencyInjection.IServiceCollection Services { get; } } - [System.Flags] - public enum ActivityTrackingOptions - { - None = 0x0000, - SpanId = 0x0001, - TraceId = 0x0002, - ParentId = 0x0004, - TraceState = 0x0008, - TraceFlags = 0x0010 - } - public class LoggerFactoryOptions - { - public LoggerFactoryOptions() { } - public ActivityTrackingOptions ActivityTrackingOptions { get {throw null; } set { throw null; } } - } public partial class LoggerFactory : Microsoft.Extensions.Logging.ILoggerFactory, System.IDisposable { public LoggerFactory() { } @@ -67,6 +62,11 @@ public void AddProvider(Microsoft.Extensions.Logging.ILoggerProvider provider) { public Microsoft.Extensions.Logging.ILogger CreateLogger(string categoryName) { throw null; } public void Dispose() { } } + public partial class LoggerFactoryOptions + { + public LoggerFactoryOptions() { } + public Microsoft.Extensions.Logging.ActivityTrackingOptions ActivityTrackingOptions { get { throw null; } set { } } + } public partial class LoggerFilterOptions { public LoggerFilterOptions() { } @@ -87,8 +87,8 @@ public static partial class LoggingBuilderExtensions { public static Microsoft.Extensions.Logging.ILoggingBuilder AddProvider(this Microsoft.Extensions.Logging.ILoggingBuilder builder, Microsoft.Extensions.Logging.ILoggerProvider provider) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder ClearProviders(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder SetMinimumLevel(this Microsoft.Extensions.Logging.ILoggingBuilder builder, Microsoft.Extensions.Logging.LogLevel level) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder Configure(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action action) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder SetMinimumLevel(this Microsoft.Extensions.Logging.ILoggingBuilder builder, Microsoft.Extensions.Logging.LogLevel level) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false, Inherited=false)] public partial class ProviderAliasAttribute : System.Attribute diff --git a/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.cs b/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.cs index f9005e63f445..ea51db47d32e 100644 --- a/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.cs +++ b/src/libraries/Microsoft.Win32.Registry/ref/Microsoft.Win32.Registry.cs @@ -115,7 +115,6 @@ namespace Microsoft.Win32.SafeHandles public sealed partial class SafeRegistryHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid { public SafeRegistryHandle(System.IntPtr preexistingHandle, bool ownsHandle) : base (default(bool)) { } - public override bool IsInvalid { get { throw null; } } protected override bool ReleaseHandle() { throw null; } } } diff --git a/src/libraries/System.CodeDom/ref/System.CodeDom.cs b/src/libraries/System.CodeDom/ref/System.CodeDom.cs index d25a4aaad0cf..fa701a269a54 100644 --- a/src/libraries/System.CodeDom/ref/System.CodeDom.cs +++ b/src/libraries/System.CodeDom/ref/System.CodeDom.cs @@ -993,7 +993,7 @@ protected virtual void GenerateSnippetCompileUnit(System.CodeDom.CodeSnippetComp protected abstract void GenerateSnippetMember(System.CodeDom.CodeSnippetTypeMember e); protected virtual void GenerateSnippetStatement(System.CodeDom.CodeSnippetStatement e) { } protected void GenerateStatement(System.CodeDom.CodeStatement e) { } - protected void GenerateStatements(System.CodeDom.CodeStatementCollection stms) { } + protected void GenerateStatements(System.CodeDom.CodeStatementCollection stmts) { } protected abstract void GenerateThisReferenceExpression(System.CodeDom.CodeThisReferenceExpression e); protected abstract void GenerateThrowExceptionStatement(System.CodeDom.CodeThrowExceptionStatement e); protected abstract void GenerateTryCatchFinallyStatement(System.CodeDom.CodeTryCatchFinallyStatement e); diff --git a/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs b/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs index f7997fb51900..11285fc40906 100644 --- a/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs +++ b/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs @@ -261,7 +261,7 @@ public sealed partial class ParenthesizePropertyNameAttribute : System.Attribute public ParenthesizePropertyNameAttribute() { } public ParenthesizePropertyNameAttribute(bool needParenthesis) { } public bool NeedParenthesis { get { throw null; } } - public override bool Equals(object? o) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } public override bool IsDefaultAttribute() { throw null; } } @@ -291,7 +291,7 @@ public sealed partial class RefreshPropertiesAttribute : System.Attribute public static readonly System.ComponentModel.RefreshPropertiesAttribute Repaint; public RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties refresh) { } public System.ComponentModel.RefreshProperties RefreshProperties { get { throw null; } } - public override bool Equals(object? value) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } public override bool IsDefaultAttribute() { throw null; } } diff --git a/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs b/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs index 3696fe37c421..46fd6d68b0ce 100644 --- a/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs +++ b/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs @@ -10,9 +10,9 @@ public partial class StackFrame { public const int OFFSET_UNKNOWN = -1; public StackFrame() { } - public StackFrame(bool fNeedFileInfo) { } + public StackFrame(bool needFileInfo) { } public StackFrame(int skipFrames) { } - public StackFrame(int skipFrames, bool fNeedFileInfo) { } + public StackFrame(int skipFrames, bool needFileInfo) { } public StackFrame(string? fileName, int lineNumber) { } public StackFrame(string? fileName, int lineNumber, int colNumber) { } public virtual int GetFileColumnNumber() { throw null; } diff --git a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs index 9f54ee11672f..463ccfd5d00e 100644 --- a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs +++ b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs @@ -207,7 +207,6 @@ public sealed partial class BufferedGraphics : System.IDisposable internal BufferedGraphics() { } public System.Drawing.Graphics Graphics { get { throw null; } } public void Dispose() { } - ~BufferedGraphics() { } public void Render() { } public void Render(System.Drawing.Graphics? target) { } public void Render(System.IntPtr targetDC) { } @@ -657,7 +656,7 @@ public void Dispose() { } ~Icon() { } public static System.Drawing.Icon FromHandle(System.IntPtr handle) { throw null; } public void Save(System.IO.Stream outputStream) { } - void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) { } public System.Drawing.Bitmap ToBitmap() { throw null; } public override string ToString() { throw null; } } @@ -731,7 +730,7 @@ public void SaveAdd(System.Drawing.Image image, System.Drawing.Imaging.EncoderPa public void SaveAdd(System.Drawing.Imaging.EncoderParameters? encoderParams) { } public int SelectActiveFrame(System.Drawing.Imaging.FrameDimension dimension, int frameIndex) { throw null; } public void SetPropertyItem(System.Drawing.Imaging.PropertyItem propitem) { } - void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) { } public delegate bool GetThumbnailImageAbort(); } public sealed partial class ImageAnimator @@ -2096,17 +2095,17 @@ public sealed partial class Encoder { public static readonly System.Drawing.Imaging.Encoder ChrominanceTable; public static readonly System.Drawing.Imaging.Encoder ColorDepth; + public static readonly System.Drawing.Imaging.Encoder ColorSpace; public static readonly System.Drawing.Imaging.Encoder Compression; + public static readonly System.Drawing.Imaging.Encoder ImageItems; public static readonly System.Drawing.Imaging.Encoder LuminanceTable; public static readonly System.Drawing.Imaging.Encoder Quality; public static readonly System.Drawing.Imaging.Encoder RenderMethod; + public static readonly System.Drawing.Imaging.Encoder SaveAsCmyk; public static readonly System.Drawing.Imaging.Encoder SaveFlag; public static readonly System.Drawing.Imaging.Encoder ScanMethod; public static readonly System.Drawing.Imaging.Encoder Transformation; public static readonly System.Drawing.Imaging.Encoder Version; - public static readonly System.Drawing.Imaging.Encoder ColorSpace; - public static readonly System.Drawing.Imaging.Encoder ImageItems; - public static readonly System.Drawing.Imaging.Encoder SaveAsCmyk; public Encoder(System.Guid guid) { } public System.Guid Guid { get { throw null; } } } @@ -2718,8 +2717,8 @@ public virtual void OnEndPrint(System.Drawing.Printing.PrintDocument document, S public virtual System.Drawing.Graphics? OnStartPage(System.Drawing.Printing.PrintDocument document, System.Drawing.Printing.PrintPageEventArgs e) { throw null; } public virtual void OnStartPrint(System.Drawing.Printing.PrintDocument document, System.Drawing.Printing.PrintEventArgs e) { } } - [System.ComponentModel.DefaultPropertyAttribute("DocumentName")] [System.ComponentModel.DefaultEventAttribute("PrintPage")] + [System.ComponentModel.DefaultPropertyAttribute("DocumentName")] public partial class PrintDocument : System.ComponentModel.Component { public PrintDocument() { } diff --git a/src/libraries/System.IO.IsolatedStorage/ref/System.IO.IsolatedStorage.cs b/src/libraries/System.IO.IsolatedStorage/ref/System.IO.IsolatedStorage.cs index b8d23578d7b0..776534a95f04 100644 --- a/src/libraries/System.IO.IsolatedStorage/ref/System.IO.IsolatedStorage.cs +++ b/src/libraries/System.IO.IsolatedStorage/ref/System.IO.IsolatedStorage.cs @@ -63,7 +63,6 @@ public void DeleteFile(string file) { } public bool DirectoryExists(string path) { throw null; } public void Dispose() { } public bool FileExists(string path) { throw null; } - ~IsolatedStorageFile() { } public System.DateTimeOffset GetCreationTime(string path) { throw null; } public string[] GetDirectoryNames() { throw null; } public string[] GetDirectoryNames(string searchPattern) { throw null; } @@ -111,8 +110,8 @@ public partial class IsolatedStorageFileStream : System.IO.FileStream public override long Length { get { throw null; } } public override long Position { get { throw null; } set { } } public override Microsoft.Win32.SafeHandles.SafeFileHandle SafeFileHandle { get { throw null; } } - public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int numBytes, System.AsyncCallback? userCallback, object? stateObject) { throw null; } - public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int numBytes, System.AsyncCallback? userCallback, object? stateObject) { throw null; } + public override System.IAsyncResult BeginRead(byte[] array, int offset, int numBytes, System.AsyncCallback? userCallback, object? stateObject) { throw null; } + public override System.IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, System.AsyncCallback? userCallback, object? stateObject) { throw null; } protected override void Dispose(bool disposing) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public override int EndRead(System.IAsyncResult asyncResult) { throw null; } diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Windows.cs b/src/libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Windows.cs index 29a6916bebd9..bd0f7ebb13a3 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Windows.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Windows.cs @@ -14,5 +14,7 @@ protected override bool ReleaseHandle() { return Interop.Kernel32.CloseHandle(handle); } + + public override bool IsInvalid => base.IsInvalid; } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs index 4236046359d6..7339effba4e2 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs @@ -30,11 +30,11 @@ public WinHttpHandler() { } public System.Net.CookieContainer? CookieContainer { get { throw null; } set { } } public System.Net.Http.CookieUsePolicy CookieUsePolicy { get { throw null; } set { } } public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } } + public bool EnableMultipleHttp2Connections { get { throw null; } set { } } public int MaxAutomaticRedirections { get { throw null; } set { } } public int MaxConnectionsPerServer { get { throw null; } set { } } public int MaxResponseDrainSize { get { throw null; } set { } } public int MaxResponseHeadersLength { get { throw null; } set { } } - public bool EnableMultipleHttp2Connections { get { throw null; } set { } } public bool PreAuthenticate { get { throw null; } set { } } public System.Collections.Generic.IDictionary Properties { get { throw null; } } public System.Net.IWebProxy? Proxy { get { throw null; } set { } } diff --git a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs index bce36a86ce62..979baf5e9f1e 100644 --- a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs +++ b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs @@ -253,11 +253,11 @@ public IPAddress(System.ReadOnlySpan address, long scopeid) { } public static short NetworkToHostOrder(short network) { throw null; } public static int NetworkToHostOrder(int network) { throw null; } public static long NetworkToHostOrder(long network) { throw null; } - public static System.Net.IPAddress Parse(System.ReadOnlySpan ipString) { throw null; } + public static System.Net.IPAddress Parse(System.ReadOnlySpan ipSpan) { throw null; } public static System.Net.IPAddress Parse(string ipString) { throw null; } public override string ToString() { throw null; } public bool TryFormat(System.Span destination, out int charsWritten) { throw null; } - public static bool TryParse(System.ReadOnlySpan ipString, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.IPAddress? address) { throw null; } + public static bool TryParse(System.ReadOnlySpan ipSpan, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.IPAddress? address) { throw null; } public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? ipString, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.IPAddress? address) { throw null; } public bool TryWriteBytes(System.Span destination, out int bytesWritten) { throw null; } } @@ -305,7 +305,7 @@ public NetworkCredential(string? userName, string? password, string? domain) { } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public string UserName { get { throw null; } set { } } public System.Net.NetworkCredential GetCredential(string? host, int port, string? authenticationType) { throw null; } - public System.Net.NetworkCredential GetCredential(System.Uri? uri, string? authType) { throw null; } + public System.Net.NetworkCredential GetCredential(System.Uri? uri, string? authenticationType) { throw null; } } public partial class SocketAddress { diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index 9793bb2e37a2..ea873ba3cecd 100644 --- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -208,6 +208,8 @@ public static partial class Vector public static System.Numerics.Vector AsVectorUInt64(System.Numerics.Vector value) where T : struct { throw null; } public static System.Numerics.Vector BitwiseAnd(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } public static System.Numerics.Vector BitwiseOr(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } + public static System.Numerics.Vector Ceiling(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Ceiling(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector condition, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector condition, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector condition, System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } @@ -232,6 +234,8 @@ public static partial class Vector public static bool EqualsAll(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } public static bool EqualsAny(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } public static System.Numerics.Vector Equals(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } + public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -292,10 +296,6 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static void Widen(System.Numerics.Vector source, out System.Numerics.Vector dest1, out System.Numerics.Vector dest2) { throw null; } public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) where T : struct { throw null; } - public static System.Numerics.Vector Ceiling(System.Numerics.Vector value) { throw null; } - public static System.Numerics.Vector Ceiling(System.Numerics.Vector value) { throw null; } - public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } - public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } } public partial struct Vector2 : System.IEquatable, System.IFormattable { diff --git a/src/libraries/System.Resources.Writer/ref/System.Resources.Writer.cs b/src/libraries/System.Resources.Writer/ref/System.Resources.Writer.cs index 9c8653862b1e..f1cb4bcfdc3c 100644 --- a/src/libraries/System.Resources.Writer/ref/System.Resources.Writer.cs +++ b/src/libraries/System.Resources.Writer/ref/System.Resources.Writer.cs @@ -21,7 +21,7 @@ public ResourceWriter(string fileName) { } public System.Func? TypeNameConverter { get { throw null; } set { } } public void AddResource(string name, byte[]? value) { } public void AddResource(string name, System.IO.Stream? value) { } - public void AddResource(string name, System.IO.Stream? value, bool closeAfterWrite) { } + public void AddResource(string name, System.IO.Stream? value, bool closeAfterWrite = false) { } public void AddResource(string name, object? value) { } public void AddResource(string name, string? value) { } public void AddResourceData(string name, string typeName, byte[] serializedData) { } diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs b/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs index 99c28c3a28b0..7c9d4fce9350 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs @@ -9,12 +9,12 @@ namespace System.Runtime.CompilerServices public static partial class Unsafe { public static ref T AddByteOffset(ref T source, System.IntPtr byteOffset) { throw null; } - public static unsafe void* Add(void* source, int elementOffset) { throw null; } + public unsafe static void* Add(void* source, int elementOffset) { throw null; } public static ref T Add(ref T source, int elementOffset) { throw null; } public static ref T Add(ref T source, System.IntPtr elementOffset) { throw null; } public static bool AreSame(ref T left, ref T right) { throw null; } - public static unsafe void* AsPointer(ref T value) { throw null; } - public static unsafe ref T AsRef(void* source) { throw null; } + public unsafe static void* AsPointer(ref T value) { throw null; } + public unsafe static ref T AsRef(void* source) { throw null; } public static ref T AsRef(in T source) { throw null; } #if NETSTANDARD2_1 [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] @@ -24,31 +24,31 @@ public static partial class Unsafe public static ref TTo As(ref TFrom source) { throw null; } public static System.IntPtr ByteOffset(ref T origin, ref T target) { throw null; } public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { } - public static unsafe void CopyBlock(void* destination, void* source, uint byteCount) { } + public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { } public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { } - public static unsafe void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { } - public static unsafe void Copy(void* destination, ref T source) { } - public static unsafe void Copy(ref T destination, void* source) { } + public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { } + public unsafe static void Copy(void* destination, ref T source) { } + public unsafe static void Copy(ref T destination, void* source) { } public static void InitBlock(ref byte startAddress, byte value, uint byteCount) { } - public static unsafe void InitBlock(void* startAddress, byte value, uint byteCount) { } + public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { } public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { } - public static unsafe void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } + public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } public static bool IsAddressGreaterThan(ref T left, ref T right) { throw null; } public static bool IsAddressLessThan(ref T left, ref T right) { throw null; } public static bool IsNullRef(ref T source) { throw null; } public static ref T NullRef() { throw null; } public static T ReadUnaligned(ref byte source) { throw null; } - public static unsafe T ReadUnaligned(void* source) { throw null; } - public static unsafe T Read(void* source) { throw null; } + public unsafe static T ReadUnaligned(void* source) { throw null; } + public unsafe static T Read(void* source) { throw null; } public static void SkipInit(out T value) { throw null; } public static int SizeOf() { throw null; } public static ref T SubtractByteOffset(ref T source, System.IntPtr byteOffset) { throw null; } - public static unsafe void* Subtract(void* source, int elementOffset) { throw null; } + public unsafe static void* Subtract(void* source, int elementOffset) { throw null; } public static ref T Subtract(ref T source, int elementOffset) { throw null; } public static ref T Subtract(ref T source, System.IntPtr elementOffset) { throw null; } public static ref T Unbox(object box) where T : struct { throw null; } public static void WriteUnaligned(ref byte destination, T value) { } - public static unsafe void WriteUnaligned(void* destination, T value) { } - public static unsafe void Write(void* destination, T value) { } + public unsafe static void WriteUnaligned(void* destination, T value) { } + public unsafe static void Write(void* destination, T value) { } } } diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/ref/System.Runtime.CompilerServices.VisualC.cs b/src/libraries/System.Runtime.CompilerServices.VisualC/ref/System.Runtime.CompilerServices.VisualC.cs index f636324e4f4e..5cf0c49999cb 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/ref/System.Runtime.CompilerServices.VisualC.cs +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/ref/System.Runtime.CompilerServices.VisualC.cs @@ -9,6 +9,11 @@ namespace System.Runtime.CompilerServices public static partial class CompilerMarshalOverride { } + [AttributeUsageAttribute(AttributeTargets.Assembly, AllowMultiple=true)] + public sealed class CppInlineNamespaceAttribute : Attribute + { + public CppInlineNamespaceAttribute(string dottedName) {} + } [System.AttributeUsageAttribute(System.AttributeTargets.Struct)] public sealed partial class HasCopySemanticsAttribute : System.Attribute { @@ -49,11 +54,6 @@ public sealed partial class NativeCppClassAttribute : System.Attribute { public NativeCppClassAttribute() { } } - [AttributeUsageAttribute(AttributeTargets.Assembly, AllowMultiple=true)] - public sealed class CppInlineNamespaceAttribute : Attribute - { - public CppInlineNamespaceAttribute(string dottedName) {} - } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Enum | System.AttributeTargets.Interface | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class RequiredAttributeAttribute : System.Attribute { diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs index 46d2dd5159e2..59b347af089b 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs @@ -45,15 +45,15 @@ public static partial class RuntimeInformation public static System.Runtime.InteropServices.Architecture ProcessArchitecture { get { throw null; } } public static string RuntimeIdentifier { get { throw null; } } public static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform osPlatform) { throw null; } - public static bool IsOSPlatformOrLater(string platformName) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; } - public static bool IsOSPlatformEarlierThan(string platformName) { throw null; } public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; } public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; } public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; } public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; } + public static bool IsOSPlatformEarlierThan(string platformName) { throw null; } + public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; } + public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; } + public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; } + public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; } + public static bool IsOSPlatformOrLater(string platformName) { throw null; } } } 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 e4860f7e25eb..792ccaa5377c 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -1031,7 +1031,7 @@ public struct ComInterfaceEntry public struct ComInterfaceDispatch { public System.IntPtr Vtable; - public static unsafe T GetInstance(ComInterfaceDispatch* dispatchPtr) where T : class { throw null; } + public unsafe static T GetInstance(ComInterfaceDispatch* dispatchPtr) where T : class { throw null; } } public System.IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags) { throw null; } protected unsafe abstract ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); diff --git a/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs b/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs index 99d71fc96e42..b73650c6b757 100644 --- a/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs +++ b/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs @@ -9,7 +9,7 @@ namespace System.Reflection.Metadata public static partial class AssemblyExtensions { [System.CLSCompliantAttribute(false)] - public static unsafe bool TryGetRawMetadata(this System.Reflection.Assembly assembly, out byte* blob, out int length) { throw null; } + public unsafe static bool TryGetRawMetadata(this System.Reflection.Assembly assembly, out byte* blob, out int length) { throw null; } } } namespace System.Runtime.Loader diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a4a16a66064e..56cc3ae7b648 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -3638,10 +3638,10 @@ public enum StringComparison } public static partial class StringNormalizationExtensions { - public static bool IsNormalized(this string value) { throw null; } - public static bool IsNormalized(this string value, System.Text.NormalizationForm normalizationForm) { throw null; } - public static string Normalize(this string value) { throw null; } - public static string Normalize(this string value, System.Text.NormalizationForm normalizationForm) { throw null; } + public static bool IsNormalized(this string strInput) { throw null; } + public static bool IsNormalized(this string strInput, System.Text.NormalizationForm normalizationForm) { throw null; } + public static string Normalize(this string strInput) { throw null; } + public static string Normalize(this string strInput, System.Text.NormalizationForm normalizationForm) { throw null; } } [System.FlagsAttribute] public enum StringSplitOptions 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 2add4b9ea90d..0082a61b92b2 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 @@ -9,7 +9,8 @@ namespace System.Security.Cryptography public abstract partial class AsymmetricAlgorithm : System.IDisposable { protected int KeySizeValue; - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] protected System.Security.Cryptography.KeySizes[] LegalKeySizesValue; + [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] + protected System.Security.Cryptography.KeySizes[] LegalKeySizesValue; protected AsymmetricAlgorithm() { } public virtual string? KeyExchangeAlgorithm { get { throw null; } } public virtual int KeySize { get { throw null; } set { } } @@ -220,8 +221,10 @@ public abstract partial class SymmetricAlgorithm : System.IDisposable protected byte[]? IVValue; protected int KeySizeValue; protected byte[]? KeyValue; - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] protected System.Security.Cryptography.KeySizes[] LegalBlockSizesValue; - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] protected System.Security.Cryptography.KeySizes[] LegalKeySizesValue; + [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] + protected System.Security.Cryptography.KeySizes[] LegalBlockSizesValue; + [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] + protected System.Security.Cryptography.KeySizes[] LegalKeySizesValue; protected System.Security.Cryptography.CipherMode ModeValue; protected System.Security.Cryptography.PaddingMode PaddingValue; protected SymmetricAlgorithm() { } diff --git a/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.cs b/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.cs index db92ef1338ef..b42eb330f723 100644 --- a/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.cs +++ b/src/libraries/System.Threading.AccessControl/ref/System.Threading.AccessControl.cs @@ -137,25 +137,25 @@ public void SetAuditRule(System.Security.AccessControl.SemaphoreAuditRule rule) } namespace System.Threading { - public static partial class ThreadingAclExtensions - { - public static System.Security.AccessControl.EventWaitHandleSecurity GetAccessControl(this System.Threading.EventWaitHandle handle) { throw null; } - public static System.Security.AccessControl.MutexSecurity GetAccessControl(this System.Threading.Mutex mutex) { throw null; } - public static System.Security.AccessControl.SemaphoreSecurity GetAccessControl(this System.Threading.Semaphore semaphore) { throw null; } - public static void SetAccessControl(this System.Threading.EventWaitHandle handle, System.Security.AccessControl.EventWaitHandleSecurity eventSecurity) { } - public static void SetAccessControl(this System.Threading.Mutex mutex, System.Security.AccessControl.MutexSecurity mutexSecurity) { } - public static void SetAccessControl(this System.Threading.Semaphore semaphore, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity) { } - } - public static class EventWaitHandleAcl + public static partial class EventWaitHandleAcl { public static System.Threading.EventWaitHandle Create(bool initialState, System.Threading.EventResetMode mode, string? name, out bool createdNew, System.Security.AccessControl.EventWaitHandleSecurity? eventSecurity) { throw null; } } - public static class MutexAcl + public static partial class MutexAcl { public static System.Threading.Mutex Create(bool initiallyOwned, string? name, out bool createdNew, System.Security.AccessControl.MutexSecurity? mutexSecurity) { throw null; } } - public static class SemaphoreAcl + public static partial class SemaphoreAcl { public static System.Threading.Semaphore Create(int initialCount, int maximumCount, string? name, out bool createdNew, System.Security.AccessControl.SemaphoreSecurity? semaphoreSecurity) { throw null; } } + public static partial class ThreadingAclExtensions + { + public static System.Security.AccessControl.EventWaitHandleSecurity GetAccessControl(this System.Threading.EventWaitHandle handle) { throw null; } + public static System.Security.AccessControl.MutexSecurity GetAccessControl(this System.Threading.Mutex mutex) { throw null; } + public static System.Security.AccessControl.SemaphoreSecurity GetAccessControl(this System.Threading.Semaphore semaphore) { throw null; } + public static void SetAccessControl(this System.Threading.EventWaitHandle handle, System.Security.AccessControl.EventWaitHandleSecurity eventSecurity) { } + public static void SetAccessControl(this System.Threading.Mutex mutex, System.Security.AccessControl.MutexSecurity mutexSecurity) { } + public static void SetAccessControl(this System.Threading.Semaphore semaphore, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity) { } + } } diff --git a/src/libraries/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs b/src/libraries/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs index 991a27b0969a..634e1697d461 100644 --- a/src/libraries/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs +++ b/src/libraries/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs @@ -29,14 +29,14 @@ public Overlapped(int offsetLo, int offsetHi, System.IntPtr hEvent, System.IAsyn public int OffsetHigh { get { throw null; } set { } } public int OffsetLow { get { throw null; } set { } } [System.CLSCompliantAttribute(false)] - public static unsafe void Free(System.Threading.NativeOverlapped* nativeOverlappedPtr) { } + public unsafe static void Free(System.Threading.NativeOverlapped* nativeOverlappedPtr) { } [System.CLSCompliantAttribute(false)] [System.ObsoleteAttribute("This method is not safe. Use Pack (iocb, userData) instead. https://go.microsoft.com/fwlink/?linkid=14202")] public unsafe System.Threading.NativeOverlapped* Pack(System.Threading.IOCompletionCallback? iocb) { throw null; } [System.CLSCompliantAttribute(false)] public unsafe System.Threading.NativeOverlapped* Pack(System.Threading.IOCompletionCallback? iocb, object? userData) { throw null; } [System.CLSCompliantAttribute(false)] - public static unsafe System.Threading.Overlapped Unpack(System.Threading.NativeOverlapped* nativeOverlappedPtr) { throw null; } + public unsafe static System.Threading.Overlapped Unpack(System.Threading.NativeOverlapped* nativeOverlappedPtr) { throw null; } [System.CLSCompliantAttribute(false)] [System.ObsoleteAttribute("This method is not safe. Use UnsafePack (iocb, userData) instead. https://go.microsoft.com/fwlink/?linkid=14202")] public unsafe System.Threading.NativeOverlapped* UnsafePack(System.Threading.IOCompletionCallback? iocb) { throw null; } @@ -63,6 +63,6 @@ public void Dispose() { } [System.CLSCompliantAttribute(false)] public unsafe void FreeNativeOverlapped(System.Threading.NativeOverlapped* overlapped) { } [System.CLSCompliantAttribute(false)] - public static unsafe object? GetNativeOverlappedState(System.Threading.NativeOverlapped* overlapped) { throw null; } + public unsafe static object? GetNativeOverlappedState(System.Threading.NativeOverlapped* overlapped) { throw null; } } } diff --git a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs index 75238f619854..b815c818c949 100644 --- a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs +++ b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs @@ -37,7 +37,7 @@ public static partial class ThreadPool public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { throw null; } public static bool SetMinThreads(int workerThreads, int completionPortThreads) { throw null; } [System.CLSCompliantAttribute(false)] - public static unsafe bool UnsafeQueueNativeOverlapped(System.Threading.NativeOverlapped* overlapped) { throw null; } + public unsafe static bool UnsafeQueueNativeOverlapped(System.Threading.NativeOverlapped* overlapped) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Threading.IThreadPoolWorkItem callBack, bool preferLocal) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Threading.WaitCallback callBack, object? state) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Action callBack, TState state, bool preferLocal) { throw null; } diff --git a/src/libraries/System.Threading/ref/System.Threading.cs b/src/libraries/System.Threading/ref/System.Threading.cs index d0f85e23252d..87d1f38e72e8 100644 --- a/src/libraries/System.Threading/ref/System.Threading.cs +++ b/src/libraries/System.Threading/ref/System.Threading.cs @@ -153,61 +153,61 @@ public virtual void Revert(object previousState) { } public static partial class Interlocked { public static int Add(ref int location1, int value) { throw null; } + public static long Add(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static uint Add(ref uint location1, uint value) { throw null; } - public static long Add(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Add(ref ulong location1, ulong value) { throw null; } public static int And(ref int location1, int value) { throw null; } + public static long And(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static uint And(ref uint location1, uint value) { throw null; } - public static long And(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong And(ref ulong location1, ulong value) { throw null; } public static double CompareExchange(ref double location1, double value, double comparand) { throw null; } public static int CompareExchange(ref int location1, int value, int comparand) { throw null; } - [System.CLSCompliantAttribute(false)] - public static uint CompareExchange(ref uint location1, uint value, uint comparand) { throw null; } public static long CompareExchange(ref long location1, long value, long comparand) { throw null; } - [System.CLSCompliantAttribute(false)] - public static ulong CompareExchange(ref ulong location1, ulong value, ulong comparand) { throw null; } public static System.IntPtr CompareExchange(ref System.IntPtr location1, System.IntPtr value, System.IntPtr comparand) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location1")] public static object? CompareExchange(ref object? location1, object? value, object? comparand) { throw null; } public static float CompareExchange(ref float location1, float value, float comparand) { throw null; } + [System.CLSCompliantAttribute(false)] + public static uint CompareExchange(ref uint location1, uint value, uint comparand) { throw null; } + [System.CLSCompliantAttribute(false)] + public static ulong CompareExchange(ref ulong location1, ulong value, ulong comparand) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location1")] public static T CompareExchange(ref T location1, T value, T comparand) where T : class? { throw null; } public static int Decrement(ref int location) { throw null; } + public static long Decrement(ref long location) { throw null; } [System.CLSCompliantAttribute(false)] public static uint Decrement(ref uint location) { throw null; } - public static long Decrement(ref long location) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Decrement(ref ulong location) { throw null; } public static double Exchange(ref double location1, double value) { throw null; } public static int Exchange(ref int location1, int value) { throw null; } - [System.CLSCompliantAttribute(false)] - public static uint Exchange(ref uint location1, uint value) { throw null; } public static long Exchange(ref long location1, long value) { throw null; } - [System.CLSCompliantAttribute(false)] - public static ulong Exchange(ref ulong location1, ulong value) { throw null; } public static System.IntPtr Exchange(ref System.IntPtr location1, System.IntPtr value) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location1")] public static object? Exchange([System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("value")] ref object? location1, object? value) { throw null; } public static float Exchange(ref float location1, float value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static uint Exchange(ref uint location1, uint value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static ulong Exchange(ref ulong location1, ulong value) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location1")] public static T Exchange([System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("value")] ref T location1, T value) where T : class? { throw null; } public static int Increment(ref int location) { throw null; } + public static long Increment(ref long location) { throw null; } [System.CLSCompliantAttribute(false)] public static uint Increment(ref uint location) { throw null; } - public static long Increment(ref long location) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Increment(ref ulong location) { throw null; } public static void MemoryBarrier() { } public static void MemoryBarrierProcessWide() { } public static int Or(ref int location1, int value) { throw null; } + public static long Or(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static uint Or(ref uint location1, uint value) { throw null; } - public static long Or(ref long location1, long value) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Or(ref ulong location1, ulong value) { throw null; } public static long Read(ref long location) { throw null; } From a5e2249753147038bc9f317bb556c32e2bc91f29 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 15:34:25 -0700 Subject: [PATCH 166/755] Do not check static methods for variance safety rules (#40152) - There are no variance restrictions on the method signature of static members This change brings the coreclr runtime into compliance with section 9.7 of Partition II of the ECMA 335 spec. --- src/coreclr/src/vm/methodtablebuilder.cpp | 5 +- .../NoVarianceCheckForStaticMethods.il | 95 +++++++++++++++++++ .../NoVarianceCheckForStaticMethods.ilproj | 10 ++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.il create mode 100644 src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.ilproj diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index aa72eb1f899d..c50c02d1ad8d 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -3026,8 +3026,9 @@ MethodTableBuilder::EnumerateClassMethods() } // Check the appearance of covariant and contravariant in the method signature - // Note that variance is only supported for interfaces - if (bmtGenerics->pVarianceInfo != NULL) + // Note that variance is only supported for interfaces, and these rules are not + // checked for static methods as they cannot be called variantly. + if ((bmtGenerics->pVarianceInfo != NULL) && !IsMdStatic(dwMemberAttrs)) { SigPointer sp(pMemberSignature, cMemberSignature); ULONG callConv; diff --git a/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.il b/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.il new file mode 100644 index 000000000000..fdb11f2401ec --- /dev/null +++ b/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.il @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Metadata version: v4.0.30319 +.assembly extern System.Runtime +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 4:2:2:0 +} +.assembly extern System.Console +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 4:1:2:0 +} +.assembly ConsoleApp5 +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .hash algorithm 0x00008004 + .ver 1:0:0:0 +} +.module ConsoleApp5.dll +// MVID: {580B623A-FB1A-403C-8F9C-8DB0E42D429C} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x047E0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit Program + extends [System.Runtime]System.Object +{ + .method private hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 34 (0x22) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "a" + IL_0006: call !0 class I2`2::M1(!0) + IL_000b: call void [System.Console]System.Console::WriteLine(string) + IL_0010: nop + IL_0011: ldstr "b" + IL_0016: call !1 class I2`2::M2(!1) + IL_001b: call void [System.Console]System.Console::WriteLine(string) + IL_0020: ldc.i4 100 + IL_0021: ret + } // end of method Program::Main + + .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 [System.Runtime]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method Program::.ctor + +} // end of class Program + +.class interface private abstract auto ansi I2`2<+ T1,- T2> +{ + .method public hidebysig static !T1 M1(!T1 x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } // end of method I2`2::M1 + + .method public hidebysig static !T2 M2(!T2 x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } // end of method I2`2::M2 + +} // end of class I2`2 + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** \ No newline at end of file diff --git a/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.ilproj b/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.ilproj new file mode 100644 index 000000000000..6e038d359eb8 --- /dev/null +++ b/src/tests/Loader/classloader/generics/Variance/Interfaces/NoVarianceCheckForStaticMethods.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + From 4e53638a21b2cde04f94a506a3dee51e4bdff9f8 Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 30 Jul 2020 16:20:24 -0700 Subject: [PATCH 167/755] Report POH objects in RootReferences and ObjectReferences (#39992) --- src/coreclr/src/gc/gc.cpp | 23 +-- src/coreclr/tests/issues.targets | 11 +- src/tests/profiler/gc/gc.cs | 90 +++++++----- src/tests/profiler/gc/gcbasic.cs | 83 +++++++++++ src/tests/profiler/gc/gcbasic.csproj | 16 +++ src/tests/profiler/native/CMakeLists.txt | 2 + src/tests/profiler/native/classfactory.cpp | 4 +- .../profiler/native/gcprofiler/gcprofiler.cpp | 136 ++++++++++++++++++ .../profiler/native/gcprofiler/gcprofiler.h | 44 ++++++ 9 files changed, 351 insertions(+), 58 deletions(-) create mode 100644 src/tests/profiler/gc/gcbasic.cs create mode 100644 src/tests/profiler/gc/gcbasic.csproj create mode 100644 src/tests/profiler/native/gcprofiler/gcprofiler.cpp create mode 100644 src/tests/profiler/native/gcprofiler/gcprofiler.h diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index ea08dd1612d2..e20daab80ed2 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -38609,8 +38609,8 @@ void gc_heap::walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOO generation_allocation_start (gen)); uint8_t* end = heap_segment_allocated (seg); - BOOL small_object_segments = TRUE; - int align_const = get_alignment_constant (small_object_segments); + int align_const = get_alignment_constant (TRUE); + BOOL walk_pinned_object_heap = walk_large_object_heap_p; while (1) @@ -38625,20 +38625,25 @@ void gc_heap::walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOO } else { - if (small_object_segments && walk_large_object_heap_p) - + if (walk_large_object_heap_p) { - small_object_segments = FALSE; - align_const = get_alignment_constant (small_object_segments); + walk_large_object_heap_p = FALSE; seg = generation_start_segment (large_object_generation); - x = heap_segment_mem (seg); - end = heap_segment_allocated (seg); - continue; + } + else if (walk_pinned_object_heap) + { + walk_pinned_object_heap = FALSE; + seg = generation_start_segment (pinned_object_generation); } else { break; } + + align_const = get_alignment_constant (FALSE); + x = heap_segment_mem (seg); + end = heap_segment_allocated (seg); + continue; } } diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 3a966079238f..61fad7cdf434 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1625,16 +1625,7 @@ https://github.com/dotnet/runtime/issues/34072 - - needs triage - - - needs triage - - - needs triage - - + needs triage diff --git a/src/tests/profiler/gc/gc.cs b/src/tests/profiler/gc/gc.cs index e0840ef51588..955ee84d49cd 100644 --- a/src/tests/profiler/gc/gc.cs +++ b/src/tests/profiler/gc/gc.cs @@ -6,53 +6,67 @@ namespace Profiler.Tests { - class GCBasicTests //: ProfilerTest + class AllocObject { - static readonly Guid GcBasicEventsProfilerGuid = new Guid("A040B953-EDE7-42D9-9077-AA69BB2BE024"); + public static readonly int ArraySize = 100; + int[] m_array = null; - public static void DoWork() { - int k=0; - while(k<3) { - Console.WriteLine("{0}: Restarting run {1}",Thread.CurrentThread.Name,k); - int[] largeArray = new int[1000000]; - for (int i=0;i<=100;i++){ - int[] saveArray = largeArray; - largeArray = new int[largeArray.Length + 100000]; - saveArray = null; - //Console.WriteLine("{0} at size {1}",Thread.CurrentThread.Name,largeArray.Length.ToString()); - } - k++; - } - } - - public static int RunTest(String[] args) { - long Threads = 1; - - if(args.Length > 2) + public AllocObject(bool poh) + { + if (poh) { - Console.WriteLine("usage: LargeObjectAlloc runtest "); - return 1; + m_array = GC.AllocateArray(ArraySize, true); } - else if(args.Length == 2) + else { - Threads = Int64.Parse(args[1]); + m_array = new int[ArraySize]; } + } + } - Console.WriteLine("LargeObjectAlloc started with {0} threads. Control-C to exit", - Threads.ToString()); + class GCTests + { + static readonly Guid GCProfilerGuid = new Guid("BCD8186F-1EEC-47E9-AFA7-396F879382C3"); + + public static int RunTest(String[] args) + { + int numAllocators = 1024; + int[] root1 = GC.AllocateArray(AllocObject.ArraySize, true); + int[] root2 = GC.AllocateArray(AllocObject.ArraySize, true); + AllocObject[] objs = new AllocObject[numAllocators]; - Thread myThread = null; - for(long i = 0; i < Threads; i++) + Random rand = new Random(); + int numPoh = 0; + int numReg = 0; + for (int i = 0; i < 10000; ++i) { - myThread = new Thread(new ThreadStart(DoWork)); - myThread.Name = i.ToString(); - myThread.Start(); - } + int pos = rand.Next(0, numAllocators); + + bool poh = rand.NextDouble() > 0.5; + objs[pos] = new AllocObject(poh); + + if (poh) + { + ++numPoh; + } + else + { + ++numReg; + } - Console.WriteLine("All threads started"); - myThread.Join(); + if (i % 1000 == 0) + { + GC.Collect(); + Console.WriteLine ($"Did {i} iterations Allocated={GC.GetAllocatedBytesForCurrentThread()}"); + } + + + int[] m_array = new int[100]; + } - Console.WriteLine("Test Passed"); + Console.WriteLine($"{numPoh} POH allocs and {numReg} normal allocs."); + GC.KeepAlive(root1); + GC.KeepAlive(root2); return 100; } @@ -64,8 +78,8 @@ public static int Main(string[] args) } return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, - testName: "GCCallbacksBasic", - profilerClsid: GcBasicEventsProfilerGuid); + testName: "GCTests", + profilerClsid: GCProfilerGuid); } } } diff --git a/src/tests/profiler/gc/gcbasic.cs b/src/tests/profiler/gc/gcbasic.cs new file mode 100644 index 000000000000..61b3f1412e21 --- /dev/null +++ b/src/tests/profiler/gc/gcbasic.cs @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; + +namespace Profiler.Tests +{ + class GCBasicTests + { + static readonly Guid GcBasicEventsProfilerGuid = new Guid("A040B953-EDE7-42D9-9077-AA69BB2BE024"); + + public static void DoWork() + { + // Allocate POH objects + var arr0 = GC.AllocateUninitializedArray(100000, true); + var arr1 = GC.AllocateArray(200000, true); + + int k = 0; + while(k < 3) + { + Console.WriteLine("{0}: Restarting run {1}",Thread.CurrentThread.Name,k); + int[] largeArray = new int[1000000]; + for (int i = 0; i <= 100; i++) + { + int[] saveArray = largeArray; + largeArray = new int[largeArray.Length + 100000]; + saveArray = null; + //Console.WriteLine("{0} at size {1}",Thread.CurrentThread.Name,largeArray.Length.ToString()); + } + + k++; + } + + GC.KeepAlive(arr0); + GC.KeepAlive(arr1); + } + + public static int RunTest(String[] args) + { + long Threads = 1; + + if(args.Length > 2) + { + Console.WriteLine("usage: LargeObjectAlloc runtest "); + return 1; + } + else if(args.Length == 2) + { + Threads = Int64.Parse(args[1]); + } + + Console.WriteLine("LargeObjectAlloc started with {0} threads. Control-C to exit", + Threads.ToString()); + + Thread myThread = null; + for(long i = 0; i < Threads; i++) + { + myThread = new Thread(new ThreadStart(DoWork)); + myThread.Name = i.ToString(); + myThread.Start(); + } + + Console.WriteLine("All threads started"); + myThread.Join(); + + Console.WriteLine("Test Passed"); + return 100; + } + + public static int Main(string[] args) + { + if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) + { + return RunTest(args); + } + + return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, + testName: "GCCallbacksBasic", + profilerClsid: GcBasicEventsProfilerGuid); + } + } +} diff --git a/src/tests/profiler/gc/gcbasic.csproj b/src/tests/profiler/gc/gcbasic.csproj new file mode 100644 index 000000000000..7a525ce745d2 --- /dev/null +++ b/src/tests/profiler/gc/gcbasic.csproj @@ -0,0 +1,16 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + + + + + + + + diff --git a/src/tests/profiler/native/CMakeLists.txt b/src/tests/profiler/native/CMakeLists.txt index a742c928bfc3..b58bb64bbcf9 100644 --- a/src/tests/profiler/native/CMakeLists.txt +++ b/src/tests/profiler/native/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.14.5) project(Profiler) set(GCBASIC_SOURCES gcbasicprofiler/gcbasicprofiler.cpp) +set(GC_SOURCES gcprofiler/gcprofiler.cpp) set(REJIT_SOURCES rejitprofiler/rejitprofiler.cpp rejitprofiler/ilrewriter.cpp rejitprofiler/sigparse.cpp) set(EVENTPIPE_SOURCES eventpipeprofiler/eventpipereadingprofiler.cpp @@ -14,6 +15,7 @@ set(ELT_SOURCES eltprofiler/slowpatheltprofiler.cpp) set(SOURCES ${GCBASIC_SOURCES} + ${GC_SOURCES} ${REJIT_SOURCES} ${EVENTPIPE_SOURCES} ${METADATAGETDISPENSER_SOURCES} diff --git a/src/tests/profiler/native/classfactory.cpp b/src/tests/profiler/native/classfactory.cpp index 301e91dde442..19de05136818 100644 --- a/src/tests/profiler/native/classfactory.cpp +++ b/src/tests/profiler/native/classfactory.cpp @@ -9,6 +9,7 @@ #include "metadatagetdispenser/metadatagetdispenser.h" #include "getappdomainstaticaddress/getappdomainstaticaddress.h" #include "eltprofiler/slowpatheltprofiler.h" +#include "gcprofiler/gcprofiler.h" ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid) { @@ -63,7 +64,8 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI new EventPipeWritingProfiler(), new MetaDataGetDispenser(), new GetAppDomainStaticAddress(), - new SlowPathELTProfiler() + new SlowPathELTProfiler(), + new GCProfiler() // add new profilers here }; diff --git a/src/tests/profiler/native/gcprofiler/gcprofiler.cpp b/src/tests/profiler/native/gcprofiler/gcprofiler.cpp new file mode 100644 index 000000000000..e6d3edccce5a --- /dev/null +++ b/src/tests/profiler/native/gcprofiler/gcprofiler.cpp @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "gcprofiler.h" + +GUID GCProfiler::GetClsid() +{ + // {BCD8186F-1EEC-47E9-AFA7-396F879382C3} + GUID clsid = { 0xBCD8186F, 0x1EEC, 0x47E9, { 0xAF, 0xA7, 0x39, 0x6F, 0x87, 0x93, 0x82, 0xC3 } }; + return clsid; +} + +HRESULT GCProfiler::Initialize(IUnknown* pICorProfilerInfoUnk) +{ + Profiler::Initialize(pICorProfilerInfoUnk); + + HRESULT hr = S_OK; + if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_GC, 0))) + { + _failures++; + printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr); + return hr; + } + + return S_OK; +} + +HRESULT GCProfiler::Shutdown() +{ + Profiler::Shutdown(); + + if (_gcStarts == 0) + { + printf("GCProfiler::Shutdown: FAIL: Expected GarbaseCollectionStarted to be called\n"); + } + else if (_gcFinishes == 0) + { + printf("GCProfiler::Shutdown: FAIL: Expected GarbageCollectionFinished to be called\n"); + } + else if (_pohObjectsSeenRootReferences == 0 || _pohObjectsSeenObjectReferences == 0) + { + printf("GCProfiler::Shutdown: FAIL: no POH objects seen. root references=%d object references=%d\n", + _pohObjectsSeenRootReferences.load(), _pohObjectsSeenObjectReferences.load()); + } + else if(_failures == 0) + { + printf("PROFILER TEST PASSES\n"); + } + else + { + // failures were printed earlier when _failures was incremented + } + fflush(stdout); + + return S_OK; +} + +HRESULT GCProfiler::GarbageCollectionStarted(int cGenerations, BOOL generationCollected[], COR_PRF_GC_REASON reason) +{ + _gcStarts++; + if (_gcStarts - _gcFinishes > 2) + { + _failures++; + printf("GCProfiler::GarbageCollectionStarted: FAIL: Expected GCStart <= GCFinish+2. GCStart=%d, GCFinish=%d\n", (int)_gcStarts, (int)_gcFinishes); + } + + return S_OK; +} + +HRESULT GCProfiler::GarbageCollectionFinished() +{ + _gcFinishes++; + if (_gcStarts < _gcFinishes) + { + _failures++; + printf("GCProfiler::GarbageCollectionFinished: FAIL: Expected GCStart >= GCFinish. Start=%d, Finish=%d\n", (int)_gcStarts, (int)_gcFinishes); + } + + _pohObjectsSeenObjectReferences += NumPOHObjectsSeen(_objectReferencesSeen); + _pohObjectsSeenRootReferences += NumPOHObjectsSeen(_rootReferencesSeen); + + return S_OK; +} + +HRESULT GCProfiler::ObjectReferences(ObjectID objectId, ClassID classId, ULONG cObjectRefs, ObjectID objectRefIds[]) +{ + HRESULT hr = S_OK; + for (ULONG i = 0; i < cObjectRefs; ++i) + { + ObjectID obj = objectRefIds[i]; + if (obj != NULL) + { + _objectReferencesSeen.insert(obj); + } + } + + return S_OK; +} + +HRESULT GCProfiler::RootReferences(ULONG cRootRefs, ObjectID rootRefIds[]) +{ + for (ULONG i = 0; i < cRootRefs; ++i) + { + ObjectID obj = rootRefIds[i]; + if (obj != NULL) + { + _rootReferencesSeen.insert(obj); + } + } + + return S_OK; +} + +int GCProfiler::NumPOHObjectsSeen(std::unordered_set objects) +{ + int count = 0; + for (auto it = objects.begin(); it != objects.end(); ++it) + { + COR_PRF_GC_GENERATION_RANGE gen; + ObjectID obj = *it; + HRESULT hr = pCorProfilerInfo->GetObjectGeneration(obj, &gen); + if (FAILED(hr)) + { + printf("GetObjectGeneration failed hr=0x%x\n", hr); + return hr; + } + + if (gen.generation == COR_PRF_GC_PINNED_OBJECT_HEAP) + { + count++; + } + + } + + return count; +} diff --git a/src/tests/profiler/native/gcprofiler/gcprofiler.h b/src/tests/profiler/native/gcprofiler/gcprofiler.h new file mode 100644 index 000000000000..8e0fbebbc4c2 --- /dev/null +++ b/src/tests/profiler/native/gcprofiler/gcprofiler.h @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +#include "../profiler.h" +#include + + +// TODO: this class is intended to be the heavyweight GC API verification (i.e. COR_PRF_MONITOR_GC) +// vs GCBasicProfiler which verifies COR_PRF_HIGH_BASIC_GC. Right now the only thing it does +// is verify we see POH objects in the RootReferences callback, but it should be fleshed out. +class GCProfiler : public Profiler +{ +public: + GCProfiler() : Profiler(), + _gcStarts(0), + _gcFinishes(0), + _failures(0), + _pohObjectsSeenRootReferences(0), + _pohObjectsSeenObjectReferences(0), + _rootReferencesSeen(), + _objectReferencesSeen() + {} + + virtual GUID GetClsid(); + virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk); + virtual HRESULT STDMETHODCALLTYPE Shutdown(); + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionStarted(int cGenerations, BOOL generationCollected[], COR_PRF_GC_REASON reason); + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionFinished(); + virtual HRESULT STDMETHODCALLTYPE ObjectReferences(ObjectID objectId, ClassID classId, ULONG cObjectRefs, ObjectID objectRefIds[]); + virtual HRESULT STDMETHODCALLTYPE RootReferences(ULONG cRootRefs, ObjectID rootRefIds[]); + +private: + std::atomic _gcStarts; + std::atomic _gcFinishes; + std::atomic _failures; + std::atomic _pohObjectsSeenRootReferences; + std::atomic _pohObjectsSeenObjectReferences; + std::unordered_set _rootReferencesSeen; + std::unordered_set _objectReferencesSeen; + + int NumPOHObjectsSeen(std::unordered_set objects); +}; From 69316ce44430884bb868159f24c88f35726e3f2b Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 30 Jul 2020 19:21:34 -0400 Subject: [PATCH 168/755] [RISCV] Build fixes and simple exception handling (#40142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hello Mono friends, here are some build fixes to make the RISC-V port compile again. Also I added some minimal exception handling stuff to make most of the mini regression test suites passing in the interpreter: ```console $ for i in mono/mini/{basic.exe,basic-float.exe,basic-long.exe,basic-calls.exe,objects.exe,arrays.exe,exceptions.exe,iltests.exe,devirtualization.exe,generics.exe,basic-vectors.exe,ratests.exe}; do \ MONO_PATH=../managed-libs/./mcs/class/lib/net_4_x-linux/ \ qemu-riscv64 ./mono/mini/mono-sgen --config data/config --regression --interp $i; done ``` output here: https://gist.github.com/lewurm/d7e54b47930126e6bae77b9a4eee1d40 While this is cool, keep in mind this only works because `--regression` doesn't pull in any native transitions. For this we essentially need a working JIT and implement some trampolines. Alas I ran out of time for my hackweek project to get it in any useful state, so I didn't include it in this PR. My WIP branch is here: https://github.com/lewurm/mono/commits/riscv-wip I also ran into an annoying qemu bug which I reported here: https://github.com/riscv/riscv-binutils-gdb/issues/223 / https://bugs.launchpad.net/qemu/+bug/1889411 Hopefully this will be fixed before I touch it next time and/or I have real hardware at this point 😄 /cc @alexrp Co-authored-by: lewurm --- src/mono/mono/metadata/object-offsets.h | 3 + src/mono/mono/mini/exceptions-riscv.c | 116 ++++++++++++++++++++--- src/mono/mono/mini/interp/interp.c | 3 - src/mono/mono/mini/mini-riscv.c | 10 ++ src/mono/mono/mini/mini-runtime.c | 2 + src/mono/mono/utils/freebsd-elf_common.h | 1 + 6 files changed, 119 insertions(+), 16 deletions(-) diff --git a/src/mono/mono/metadata/object-offsets.h b/src/mono/mono/metadata/object-offsets.h index 82f901714646..bf2bf0e25272 100644 --- a/src/mono/mono/metadata/object-offsets.h +++ b/src/mono/mono/metadata/object-offsets.h @@ -249,6 +249,9 @@ DECL_OFFSET(MonoLMF, ebp) DECL_OFFSET(MonoLMF, eip) DECL_OFFSET(MonoLMF, gregs) DECL_OFFSET(MonoLMF, fregs) +#elif defined(TARGET_RISCV) +DECL_OFFSET(MonoContext, gregs) +DECL_OFFSET(MonoContext, fregs) #endif // Shared architecture offfsets diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index a5ebedb6af50..5c8983f801b5 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -12,14 +12,15 @@ #ifndef DISABLE_JIT static gpointer -nop_stub (void) +nop_stub (unsigned int pattern) { guint8 *code, *start; start = code = mono_global_codeman_reserve (0x50); - /* nop */ - riscv_addi (code, RISCV_X0, RISCV_X0, 0); + /* hang in debugger */ + riscv_addi (code, RISCV_X0, RISCV_X0, pattern); + riscv_ebreak (code); mono_arch_flush_icache (start, code - start); @@ -29,43 +30,76 @@ nop_stub (void) gpointer mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) { - *info = NULL; - return nop_stub (); + guint8 *start, *code; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + int i, ctx_reg, size; + + size = 512; + code = start = mono_global_codeman_reserve (size); + + riscv_addi (code, RISCV_T0, RISCV_A0, 0); + ctx_reg = RISCV_T0; + + /* Restore fregs */ + for (i = 0; i < RISCV_N_FREGS; ++i) + riscv_flw (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, fregs) + (i * sizeof (double))); + + /* Restore gregs */ + for (i = 0; i < RISCV_N_FREGS; ++i) { + if (i == ctx_reg) + continue; + riscv_ld (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, gregs) + (i * sizeof (double))); + } + + riscv_ld (code, ctx_reg, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, gregs) + (RISCV_ZERO * sizeof (double))); + riscv_jalr (code, RISCV_ZERO, ctx_reg, 0); + /* Not reached */ + riscv_ebreak (code); + + g_assert ((code - start) < size); + mono_arch_flush_icache (start, code - start); + MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); + + if (info) + *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops); + + return start; } gpointer mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) { *info = NULL; - return nop_stub (); + return nop_stub (0x37); } gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { *info = NULL; - return nop_stub (); + return nop_stub (0x77); } gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { *info = NULL; - return nop_stub (); + return nop_stub (0x88); } gpointer mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) { *info = NULL; - return nop_stub (); + return nop_stub (0x99); } gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { *info = NULL; - return nop_stub (); + return nop_stub (0xaa); } #else @@ -125,7 +159,63 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf, host_mgreg_t **save_locations, StackFrameInfo *frame) { - NOT_IMPLEMENTED; + gpointer ip = MONO_CONTEXT_GET_IP (ctx); + + memset (frame, 0, sizeof (StackFrameInfo)); + frame->ji = ji; + + *new_ctx = *ctx; + + if (ji != NULL) { + NOT_IMPLEMENTED; + host_mgreg_t regs [MONO_MAX_IREGS + 12 + 1]; + guint8 *cfa; + guint32 unwind_info_len; + guint8 *unwind_info; + + + if (ji->is_trampoline) + frame->type = FRAME_TYPE_TRAMPOLINE; + else + frame->type = FRAME_TYPE_MANAGED; + + unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len); + + memcpy (regs, &new_ctx->gregs, sizeof (host_mgreg_t) * 32); + + /* f8..f9 & f18..f27 are callee saved */ + for (int i = 0; i < 2; i++) + (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]); + for (int i = 0; i < 10; i++) + (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]); + + gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8*)ji->code_start, + (guint8*)ji->code_start + ji->code_size, + (guint8*)ip, NULL, regs, MONO_MAX_IREGS + 8, + save_locations, MONO_MAX_IREGS, (guint8**)&cfa); + + if (!success) + return FALSE; + + memcpy (&new_ctx->gregs, regs, sizeof (host_mgreg_t) * 32); + for (int i = 0; i < 2; i++) + *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]) = (regs + MONO_MAX_IREGS) [i]; + for (int i = 0; i < 10; i++) + *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]) = (regs + MONO_MAX_IREGS) [i]; + + new_ctx->gregs [RISCV_SP] = (host_mgreg_t)(gsize)cfa; + + if (*lmf) + NOT_IMPLEMENTED; + + /* we substract 1, so that the IP points into the call instruction */ + new_ctx->gregs [RISCV_ZERO]--; + + return TRUE; + } else if (*lmf) { + NOT_IMPLEMENTED; + } + return FALSE; } @@ -177,11 +267,11 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func) void mono_arch_undo_ip_adjustment (MonoContext *context) { - NOT_IMPLEMENTED; + context->gregs[RISCV_ZERO]++; } void mono_arch_do_ip_adjustment (MonoContext *context) { - g_assert_not_reached (); + context->gregs[RISCV_ZERO]--; } diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 68f82f52c5f5..53d20e1997c8 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -2385,7 +2385,6 @@ init_jit_call_info (InterpMethod *rmethod, MonoError *error) static MONO_NEVER_INLINE void do_jit_call (stackval *sp, unsigned char *vt_sp, InterpFrame *frame, InterpMethod *rmethod, MonoError *error) { - MonoMethodSignature *sig; guint8 res_buf [256]; MonoLMFExt ext; JitCallInfo *cinfo; @@ -2402,8 +2401,6 @@ do_jit_call (stackval *sp, unsigned char *vt_sp, InterpFrame *frame, InterpMetho } cinfo = (JitCallInfo*)rmethod->jit_call_info; - sig = cinfo->sig; - /* * Convert the arguments on the interpeter stack to the format expected by the gsharedvt_out wrapper. */ diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 6a92216ea0ca..f12b699a5ef4 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -232,6 +232,16 @@ mono_arch_find_static_call_vtable (host_mgreg_t *regs, guint8 *code) return (MonoVTable *) regs [MONO_ARCH_VTABLE_REG]; } +GSList* +mono_arch_get_cie_program (void) +{ + GSList *l = NULL; + + mono_add_unwind_op_def_cfa (l, (guint8*)NULL, (guint8*)NULL, RISCV_SP, 0); + + return l; +} + host_mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) { diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 33c2a761189f..3dc54a5e2230 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1963,6 +1963,8 @@ enum { ELF_MACHINE = EM_PPC64, #elif HOST_S390X ELF_MACHINE = EM_S390, +#elif HOST_RISCV + ELF_MACHINE = EM_RISCV, #endif JIT_CODE_LOAD = 0 }; diff --git a/src/mono/mono/utils/freebsd-elf_common.h b/src/mono/mono/utils/freebsd-elf_common.h index 7aef2d49667e..658119fdbc51 100644 --- a/src/mono/mono/utils/freebsd-elf_common.h +++ b/src/mono/mono/utils/freebsd-elf_common.h @@ -169,6 +169,7 @@ typedef struct { #define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ #define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ #define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ +#define EM_RISCV 243 /* RISC-V. */ /* Non-standard or deprecated. */ #define EM_486 6 /* Intel i486. */ From a83dc69bd17c080a8a1a6e12f55da7cc53adffde Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 17:13:37 -0700 Subject: [PATCH 169/755] Disable copy ctor test on Mono (#40161) The underlying feature here was designed only for IJW, which isn't supported by mono --- src/coreclr/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 61fad7cdf434..4cb3d04ab9f5 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -964,6 +964,9 @@ + + Handling for Copy constructors isn't present in mono interop + Crashes during LLVM AOT compilation. From 0f36487de9e41e96189e62e5bf4054cb80d9b470 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Thu, 30 Jul 2020 17:19:59 -0700 Subject: [PATCH 170/755] Re-work fix for flow graph update. (#40162) In #39878 I switched fgUpdateChangedFlowGraph to call fgComputeReachability, which both removes unreachable blocks and calls fgComputeDoms. As mentioned in that PR, in addition to removing unreachable blocks fgRemoveUnreachableBlocks updates `BBF_LOOP_HEAD` flags even if no unreachable blocks were found. That resulted in some diffs, both positive and negative, from downstream effects: e.g., in some cases we now recognize more loops, which changes weights, etc. Some of the negative diffs affected benchmarks we are tracking, e.g., in #40094 `System.Text.RegularExpressions.Tests.Perf_Regex_Common` had a 10% regression because of codegen diffs in the large dynamic method created when compiling regular expressions. Because of these regressions, I decided to go with a more surgical fix for the original issue (assert when computing dominators after inlining GC polls). The downstream phases don't really need the dominator info so I changed fgUpdateChangedFlowGraph to not re-compute dominators after GC poll inlining. This reverses all diffs from #39878 and fixes #40094. --- src/coreclr/src/jit/compiler.h | 2 +- src/coreclr/src/jit/flowgraph.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 183e84cf6989..23c3b687984c 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -4968,7 +4968,7 @@ class Compiler // When the flow graph changes, we need to update the block numbers, predecessor lists, reachability sets, and // dominators. - void fgUpdateChangedFlowGraph(); + void fgUpdateChangedFlowGraph(bool computeDoms = true); public: // Compute the predecessors of the blocks in the control flow graph. diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index fb0c8f231385..89ce176fe024 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -1868,7 +1868,7 @@ bool Compiler::fgReachable(BasicBlock* b1, BasicBlock* b2) * it again. */ -void Compiler::fgUpdateChangedFlowGraph() +void Compiler::fgUpdateChangedFlowGraph(bool computeDoms) { // We need to clear this so we don't hit an assert calling fgRenumberBlocks(). fgDomsComputed = false; @@ -1878,7 +1878,11 @@ void Compiler::fgUpdateChangedFlowGraph() fgComputePreds(); fgComputeEnterBlocksSet(); - fgComputeReachability(); + fgComputeReachabilitySets(); + if (computeDoms) + { + fgComputeDoms(); + } } /***************************************************************************** @@ -3725,7 +3729,8 @@ PhaseStatus Compiler::fgInsertGCPolls() { noway_assert(opts.OptimizationEnabled()); fgReorderBlocks(); - fgUpdateChangedFlowGraph(); + constexpr bool computeDoms = false; + fgUpdateChangedFlowGraph(computeDoms); } #ifdef DEBUG if (verbose) From 96d2bf042d65d4043f612f80e34311b7135b02dd Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 21:03:39 -0700 Subject: [PATCH 171/755] Use IsCopyConstructed modreq consistently in test (#40168) - X86 calling convention for copy constructed arguments is special, therefore the delegate must have the IsCopyConstructed modreq as well as the callsite --- .../Miscellaneous/CopyCtor/CopyCtorTest.cs | 5 +-- .../Miscellaneous/CopyCtor/CopyCtorUtil.il | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs index 764e79006886..31f64bb6b4e6 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs @@ -26,12 +26,9 @@ public static unsafe int StructWithCtorTest(StructWithCtor* ptrStruct, ref Struc return 100; } - [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] - public delegate int TestDelegate(StructWithCtor* ptrStruct, ref StructWithCtor refStruct); - public static unsafe int Main() { - TestDelegate del = (TestDelegate)StructWithCtorTest; + TestDelegate del = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), typeof(CopyCtor).GetMethod("StructWithCtorTest")); StructWithCtor s1 = new StructWithCtor(); StructWithCtor s2 = new StructWithCtor(); s1._instanceField = 1; diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il index d77a1eec69e5..495bcf7d34a9 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorUtil.il @@ -5,6 +5,39 @@ .assembly extern System.Runtime.CompilerServices.VisualC { } .assembly CopyCtorUtil { } +.class auto ansi sealed public TestDelegate + extends [mscorlib]System.MulticastDelegate +{ + .custom instance void [mscorlib]System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute::.ctor(valuetype [mscorlib]System.Runtime.InteropServices.CallingConvention) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method TestDelegate::.ctor + + .method public hidebysig newslot virtual + instance int32 Invoke(valuetype [CopyCtorUtil]StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)* ptrStruct, + valuetype [CopyCtorUtil]StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)& refStruct) runtime managed + { + } // end of method TestDelegate::Invoke + + .method public hidebysig newslot virtual + instance class [mscorlib]System.IAsyncResult + BeginInvoke(valuetype [CopyCtorUtil]StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)* ptrStruct, + valuetype [CopyCtorUtil]StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)& refStruct, + class [mscorlib]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method TestDelegate::BeginInvoke + + .method public hidebysig newslot virtual + instance int32 EndInvoke(valuetype [CopyCtorUtil]StructWithCtor modreq([mscorlib]System.Runtime.CompilerServices.IsCopyConstructed)& refStruct, + class [mscorlib]System.IAsyncResult result) runtime managed + { + } // end of method TestDelegate::EndInvoke + +} // end of class TestDelegate + .class public sealed sequential ansi beforefieldinit StructWithCtor extends [mscorlib]System.ValueType { From 8d22d2cd0cd287fc844841f56f32732c34560cf6 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 30 Jul 2020 21:37:23 -0700 Subject: [PATCH 172/755] Correctly handle gc desc for explicit layout type which inherits from another type (#40160) - Fix memory corruption issue when an explicit layout class derived from a class with a gc pointer in it --- src/coreclr/src/vm/methodtablebuilder.cpp | 16 +++++- .../Regressions/13362/Github13362.cs | 56 +++++++++++++++++++ .../Regressions/13362/Github13362.csproj | 11 ++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.cs create mode 100644 src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.csproj diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index c50c02d1ad8d..fc14d39be565 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -8764,8 +8764,10 @@ MethodTableBuilder::HandleGCForExplicitLayout() if (bmtParent->NumParentPointerSeries != 0) { size_t ParentGCSize = CGCDesc::ComputeSize(bmtParent->NumParentPointerSeries); - memcpy( (PVOID) (((BYTE*) pMT) - ParentGCSize), (PVOID) (((BYTE*) GetParentMethodTable()) - ParentGCSize), ParentGCSize - sizeof(UINT) ); - + memcpy( (PVOID) (((BYTE*) pMT) - ParentGCSize), + (PVOID) (((BYTE*) GetParentMethodTable()) - ParentGCSize), + ParentGCSize - sizeof(size_t) // sizeof(size_t) is the NumSeries count + ); } UINT32 dwInstanceSliceOffset = AlignUp(HasParent() ? GetParentMethodTable()->GetNumInstanceFieldBytes() : 0, TARGET_POINTER_SIZE); @@ -8780,6 +8782,16 @@ MethodTableBuilder::HandleGCForExplicitLayout() pSeries->SetSeriesOffset(bmtGCSeries->pSeries[i].offset + OBJECT_SIZE + dwInstanceSliceOffset); pSeries++; } + + // Adjust the inherited series - since the base size has increased by "# new field instance bytes", we need to + // subtract that from all the series (since the series always has BaseSize subtracted for it - see gcdesc.h) + CGCDescSeries *pHighest = CGCDesc::GetCGCDescFromMT(pMT)->GetHighestSeries(); + while (pSeries <= pHighest) + { + CONSISTENCY_CHECK(CheckPointer(GetParentMethodTable())); + pSeries->SetSeriesSize( pSeries->GetSeriesSize() - ((size_t) pMT->GetBaseSize() - (size_t) GetParentMethodTable()->GetBaseSize()) ); + pSeries++; + } } delete [] bmtGCSeries->pSeries; diff --git a/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.cs b/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.cs new file mode 100644 index 000000000000..183c286b3553 --- /dev/null +++ b/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.cs @@ -0,0 +1,56 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace ClrIssueRepro +{ + // If you remove '[StructLayout(LayoutKind.Sequential)]', you get: + // Unhandled exception. System.TypeLoadException: + // Could not load type 'ClrIssueRepro.GenInt' from assembly '...' + // because the format is invalid. + // at ClrIssueRepro.Program.Main(String[] args) + [StructLayout(LayoutKind.Sequential)] + public class GenBase + { + public string _string0 = "string0"; + public string _string1 = "string1"; + } + + [StructLayout(LayoutKind.Explicit)] + public class GenInt : GenBase + { + // Commenting out either one of these fields fixes things!? + [FieldOffset(0)] public string _sstring0 = "string0"; + [FieldOffset(16)] public string _sstring1 = "string1"; + } + + // This works! (it's GenInt with [StructLayout(LayoutKind.Explicit)] and [FieldOffset(..)] removed) + public class GenIntNormal : GenBase + { + public string _sstring0 = "string0"; + public string _sstring1 = "string1"; + } + + class Program + { + static int Main(string[] args) + { + // If you comment this line out, you get + // Unhandled exception. System.TypeLoadException: + // Could not load type 'ClrIssueRepro.GenInt' from assembly '...' + // at ClrIssueRepro.Program.Main(String[] args) + // in Debug and Release builds?! + Type type = typeof(GenInt); + + object instance = new GenInt(); + + // GenIntNormal has the same fields as GenInt, but has + // [StructLayout(LayoutKind.Explicit)] and [FieldOffset(..)] REMOVED + //object instance = new GenIntNormal(); // works fine!! + + string instType = instance.GetType().ToString(); + Console.WriteLine(instType); + return "ClrIssueRepro.GenInt" == instType ? 100 : 0; + } + } +} \ No newline at end of file diff --git a/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.csproj b/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.csproj new file mode 100644 index 000000000000..0a3e92e6e963 --- /dev/null +++ b/src/tests/Loader/classloader/explicitlayout/Regressions/13362/Github13362.csproj @@ -0,0 +1,11 @@ + + + true + Exe + BuildAndRun + 1 + + + + + From 7acaf166f43380ba76616b24a93f1429995ff1d8 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Fri, 31 Jul 2020 11:38:40 +0300 Subject: [PATCH 173/755] [wasm] Re-enable some System.Linq.Expressions tests (#40130) --- src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs | 1 - .../tests/IndexExpression/IndexExpressionTests.cs | 1 - .../tests/Variables/RuntimeVariablesTests.cs | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs b/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs index 67eb00e82e3a..43e504c46dfe 100644 --- a/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs @@ -290,7 +290,6 @@ 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 37b48b827054..438bdf04ea70 100644 --- a/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs @@ -654,7 +654,6 @@ 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 cc514e6c4bc3..9f843394d734 100644 --- a/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs @@ -52,7 +52,6 @@ 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)); @@ -83,7 +82,6 @@ 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)); From 829441924d05b695e235cc21b617bb793de045ec Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 31 Jul 2020 13:36:05 +0200 Subject: [PATCH 174/755] Disable MSB3270 warning when referencing CoreLib (#40158) We intentionally reference CoreLib (platform specific) from our platform neutral (=AnyCPU) assemblies, ie System.Runtime. Disabling the warning that is shown in VS. --- src/libraries/Directory.Build.targets | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index cc196f26392a..83a2e140326c 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -185,6 +185,10 @@ false + + + None + From bc3c718949cc4ee576c40dbd22a99660ac8c75de Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 31 Jul 2020 09:24:48 -0400 Subject: [PATCH 175/755] Fix __asm__ specifications for Clang (#40175) This patch set will enable a clean build of mono for s390x using clang. The register specifications require the use of a prefix ('r' - general registers 'f' - floating point 'a' - access) rather than just a number. This has been fixed in the most recent level of clang. The current compilers (gcc and clang) are also better at optimizing string operations so the compiler option ```-D__USE_STRING_INLINES``` is also no longer required. Co-authored-by: nealef --- src/mono/configure.ac | 2 +- src/mono/mono/mini/mini-s390x.h | 2 +- src/mono/mono/utils/mono-context.h | 4 +- src/mono/mono/utils/mono-hwcap-s390x.c | 2 +- src/mono/mono/utils/mono-tls.c | 8 +- src/mono/mono/utils/valgrind.h | 296 ++++++++++++------------- 6 files changed, 157 insertions(+), 157 deletions(-) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 7a0d36d9ce57..6c114a3765bc 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -4678,7 +4678,7 @@ case "$host" in ACCESS_UNALIGNED="yes" BTLS_SUPPORTED=yes BTLS_PLATFORM=s390x - CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES" + CFLAGS="$CFLAGS -mbackchain" ;; riscv32-*) TARGET=RISCV32 diff --git a/src/mono/mono/mini/mini-s390x.h b/src/mono/mono/mini/mini-s390x.h index 2efcafbd456b..bb358e235ab0 100644 --- a/src/mono/mono/mini/mini-s390x.h +++ b/src/mono/mono/mini/mini-s390x.h @@ -158,7 +158,7 @@ struct SeqPointInfo { #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \ MonoS390StackFrame *sframe; \ - __asm__ volatile("lgr %0,15" : "=r" (sframe)); \ + __asm__ volatile("lgr %0,%%r15" : "=r" (sframe)); \ MONO_CONTEXT_SET_BP ((ctx), sframe->prev); \ MONO_CONTEXT_SET_SP ((ctx), sframe->prev); \ MONO_CONTEXT_SET_IP ((ctx), func); \ diff --git a/src/mono/mono/utils/mono-context.h b/src/mono/mono/utils/mono-context.h index 7647d4eadb7a..2dbf043ba13f 100644 --- a/src/mono/mono/utils/mono-context.h +++ b/src/mono/mono/utils/mono-context.h @@ -918,8 +918,8 @@ typedef struct ucontext MonoContext; "std %%f13,104(%1)\n" \ "std %%f14,112(%1)\n" \ "std %%f15,120(%1)\n" \ - : : "r" (&(ctx).uc_mcontext.gregs[0]), \ - "r" (&(ctx).uc_mcontext.fpregs.fprs[0]) \ + : : "a" (&(ctx).uc_mcontext.gregs[0]), \ + "a" (&(ctx).uc_mcontext.fpregs.fprs[0]) \ : "memory" \ ) diff --git a/src/mono/mono/utils/mono-hwcap-s390x.c b/src/mono/mono/utils/mono-hwcap-s390x.c index 5c24a15e5e1b..fcfaf9cae7a2 100644 --- a/src/mono/mono/utils/mono-hwcap-s390x.c +++ b/src/mono/mono/utils/mono-hwcap-s390x.c @@ -148,7 +148,7 @@ mono_hwcap_arch_init (void) int lFacs = sizeof (facs) / 8; __asm__ __volatile__ ( - "lgfr\t0,%1\n\t" + "lgfr\t%%r0,%1\n\t" ".insn\ts,0xb2b00000,%0\n\t" : "=m" (facs) : "r" (lFacs) diff --git a/src/mono/mono/utils/mono-tls.c b/src/mono/mono/utils/mono-tls.c index 00be95ee3e84..f2b11c852044 100644 --- a/src/mono/mono/utils/mono-tls.c +++ b/src/mono/mono/utils/mono-tls.c @@ -70,11 +70,11 @@ # endif # else # define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; \ - __asm__ ("basr %%r1,0\n\t" \ + __asm__ ("larl %%r1,0f\n\t" \ "j 0f\n\t" \ - ".quad " #var "@NTPOFF\n" \ - "0:\n\t" \ - "lg %0,4(%%r1)\n\t" \ + "0:.quad " #var "@NTPOFF\n" \ + "1:\n\t" \ + "lg %0,0(%%r1)\n\t" \ : "=r" (foo) : : "1"); \ offset = foo; } while (0) # endif diff --git a/src/mono/mono/utils/valgrind.h b/src/mono/mono/utils/valgrind.h index 343d301821e6..0829ac748b7c 100644 --- a/src/mono/mono/utils/valgrind.h +++ b/src/mono/mono/utils/valgrind.h @@ -831,15 +831,15 @@ typedef * (e.g. VEX/priv/guest_s390_decoder.c). */ #define __SPECIAL_INSTRUCTION_PREAMBLE \ - "lr 15,15\n\t" \ - "lr 1,1\n\t" \ - "lr 2,2\n\t" \ - "lr 3,3\n\t" + "lr %%r15,%%r15\n\t" \ + "lr %%r1,%%r1\n\t" \ + "lr %%r2,%%r2\n\t" \ + "lr %%r3,%%r3\n\t" -#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" -#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" -#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" -#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" +#define __CLIENT_REQUEST_CODE "lr %%r2,%%r2\n\t" +#define __GET_NR_CONTEXT_CODE "lr %%r3,%%r3\n\t" +#define __CALL_NO_REDIR_CODE "lr %%r4,%%r4\n\t" +#define __VEX_INJECT_IR_CODE "lr %%r5,%%r5\n\t" #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ _zzq_default, _zzq_request, \ @@ -854,15 +854,15 @@ typedef _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ __asm__ volatile(/* r2 = args */ \ - "lgr 2,%1\n\t" \ + "lgr %%r2,%1\n\t" \ /* r3 = default */ \ - "lgr 3,%2\n\t" \ + "lgr %%r3,%2\n\t" \ __SPECIAL_INSTRUCTION_PREAMBLE \ __CLIENT_REQUEST_CODE \ /* results = r3 */ \ - "lgr %0, 3\n\t" \ + "lgr %0,%%r3\n\t" \ : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "a" (&_zzq_args[0]), "r" (_zzq_default) \ : "cc", "2", "3", "memory" \ ); \ _zzq_result; \ @@ -873,7 +873,7 @@ typedef volatile unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ __GET_NR_CONTEXT_CODE \ - "lgr %0, 3\n\t" \ + "lgr %0,%%r3\n\t" \ : "=a" (__addr) \ : \ : "cc", "3", "memory" \ @@ -4652,17 +4652,17 @@ typedef ,"d"(__builtin_dwarf_cfa()) # define VALGRIND_CFI_PROLOGUE \ ".cfi_remember_state\n\t" \ - "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ - "lgr 7,11\n\t" \ - "lgr 11,%2\n\t" \ + "lgr %%r1,%1\n\t" /* copy the argvec pointer in r1 */ \ + "lgr %%r7,%%r11\n\t" \ + "lgr %%r11,%2\n\t" \ ".cfi_def_cfa r11, 0\n\t" # define VALGRIND_CFI_EPILOGUE \ - "lgr 11, 7\n\t" \ + "lgr %%r11,%%r7\n\t" \ ".cfi_restore_state\n\t" #else # define __FRAME_POINTER # define VALGRIND_CFI_PROLOGUE \ - "lgr 1,%1\n\t" + "lgr %%r1,%1\n\t" # define VALGRIND_CFI_EPILOGUE #endif @@ -4695,11 +4695,11 @@ typedef _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 1, 0(1)\n\t" /* target->r1 */ \ + "aghi %%r15,-160\n\t" \ + "lg %%r1,0(%%r1)\n\t" /* target->r1 */ \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ @@ -4718,12 +4718,12 @@ typedef _argvec[1] = (unsigned long)arg1; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-160\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4742,13 +4742,13 @@ typedef _argvec[2] = (unsigned long)arg2; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-160\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4768,14 +4768,14 @@ typedef _argvec[3] = (unsigned long)arg3; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-160\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4796,15 +4796,15 @@ typedef _argvec[4] = (unsigned long)arg4; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-160\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4826,16 +4826,16 @@ typedef _argvec[5] = (unsigned long)arg5; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-160\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,160\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4859,17 +4859,17 @@ typedef _argvec[6] = (unsigned long)arg6; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-168\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-168\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,168\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,168\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4894,18 +4894,18 @@ typedef _argvec[7] = (unsigned long)arg7; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-176\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-176\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,176\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,176\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4931,19 +4931,19 @@ typedef _argvec[8] = (unsigned long)arg8; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-184\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-184\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "mvc 176(8,%%r15),64(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,184\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,184\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -4970,20 +4970,20 @@ typedef _argvec[9] = (unsigned long)arg9; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-192\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-192\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "mvc 176(8,%%r15),64(%%r1)\n\t" \ + "mvc 184(8,%%r15),72(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,192\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,192\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -5011,21 +5011,21 @@ typedef _argvec[10] = (unsigned long)arg10; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-200\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-200\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "mvc 176(8,%%r15),64(%%r1)\n\t" \ + "mvc 184(8,%%r15),72(%%r1)\n\t" \ + "mvc 192(8,%%r15),80(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,200\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,200\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -5054,22 +5054,22 @@ typedef _argvec[11] = (unsigned long)arg11; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-208\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-208\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "mvc 176(8,%%r15),64(%%r1)\n\t" \ + "mvc 184(8,%%r15),72(%%r1)\n\t" \ + "mvc 192(8,%%r15),80(%%r1)\n\t" \ + "mvc 200(8,%%r15),88(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,208\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,208\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ @@ -5099,23 +5099,23 @@ typedef _argvec[12] = (unsigned long)arg12; \ __asm__ volatile( \ VALGRIND_CFI_PROLOGUE \ - "aghi 15,-216\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "mvc 208(8,15), 96(1)\n\t" \ - "lg 1, 0(1)\n\t" \ + "aghi %%r15,-216\n\t" \ + "lg %%r2,8(%%r1)\n\t" \ + "lg %%r3,16(%%r1)\n\t" \ + "lg %%r4,24(%%r1)\n\t" \ + "lg %%r5,32(%%r1)\n\t" \ + "lg %%r6,40(%%r1)\n\t" \ + "mvc 160(8,%%r15),48(%%r1)\n\t" \ + "mvc 168(8,%%r15),56(%%r1)\n\t" \ + "mvc 176(8,%%r15),64(%%r1)\n\t" \ + "mvc 184(8,%%r15),72(%%r1)\n\t" \ + "mvc 192(8,%%r15),80(%%r1)\n\t" \ + "mvc 200(8,%%r15),88(%%r1)\n\t" \ + "mvc 208(8,%%r15),96(%%r1)\n\t" \ + "lg %%r1,0(%%r1)\n\t" \ VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,216\n\t" \ + "lgr %0,%%r2\n\t" \ + "aghi %%r15,216\n\t" \ VALGRIND_CFI_EPILOGUE \ : /*out*/ "=d" (_res) \ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ From d0d704a2e0b86d37cf62591514325f259acc8435 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Fri, 31 Jul 2020 07:00:17 -0700 Subject: [PATCH 176/755] Bring back Microsoft.Bcl.AsyncInterfaces (#40189) * Bring back Microsoft.Bcl.AsyncInterfaces This is needed in order to build a version of this assembly that uses the latest version of its dependency System.Threading.Tasks.Extensions Without this, we'd reference in inconsistent set of versions for S.T.T.E in libraries that use both AsyncInterfaces and S.T.T.E. * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj * Update src/libraries/System.Text.Json/src/System.Text.Json.csproj * Update src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj * Update src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj * Update src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj * Update src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj * Update src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj * Update src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/tests/Microsoft.Bcl.AsyncInterfaces.Tests.csproj * Update src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj Co-authored-by: Viktor Hofer --- .../Directory.Build.props | 7 + .../Microsoft.Bcl.AsyncInterfaces.sln | 51 ++++ .../pkg/Microsoft.Bcl.AsyncInterfaces.pkgproj | 9 + .../Microsoft.Bcl.AsyncInterfaces.Forwards.cs | 14 + .../ref/Microsoft.Bcl.AsyncInterfaces.cs | 96 +++++++ .../ref/Microsoft.Bcl.AsyncInterfaces.csproj | 14 + .../src/Microsoft.Bcl.AsyncInterfaces.csproj | 39 +++ .../AsyncIteratorMethodBuilder.cs | 61 ++++ .../Sources/ManualResetValueTaskSourceCore.cs | 271 ++++++++++++++++++ ...Microsoft.Bcl.AsyncInterfaces.Tests.csproj | 22 ++ ...soft.Extensions.DependencyInjection.csproj | 2 +- ...soft.Extensions.DependencyInjection.csproj | 2 +- ...oft.Extensions.Hosting.Abstractions.csproj | 2 +- ...oft.Extensions.Hosting.Abstractions.csproj | 2 +- .../src/Microsoft.Extensions.Hosting.csproj | 2 +- ...icrosoft.Extensions.Logging.Console.csproj | 2 +- ...soft.Extensions.Logging.EventSource.csproj | 2 +- .../src/Microsoft.Extensions.Logging.csproj | 2 +- .../ref/System.Text.Json.csproj | 2 +- .../src/System.Text.Json.csproj | 2 +- src/libraries/pkg/baseline/packageIndex.json | 5 +- src/libraries/pkg/descriptions.json | 9 + 22 files changed, 606 insertions(+), 12 deletions(-) create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/Directory.Build.props create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/Microsoft.Bcl.AsyncInterfaces.sln create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/pkg/Microsoft.Bcl.AsyncInterfaces.pkgproj create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.Forwards.cs create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.cs create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/tests/Microsoft.Bcl.AsyncInterfaces.Tests.csproj diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/Directory.Build.props b/src/libraries/Microsoft.Bcl.AsyncInterfaces/Directory.Build.props new file mode 100644 index 000000000000..363643c7a5e0 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/Directory.Build.props @@ -0,0 +1,7 @@ + + + + Open + + + diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/Microsoft.Bcl.AsyncInterfaces.sln b/src/libraries/Microsoft.Bcl.AsyncInterfaces/Microsoft.Bcl.AsyncInterfaces.sln new file mode 100644 index 000000000000..1f6586d8aa79 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/Microsoft.Bcl.AsyncInterfaces.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30120.7 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.AsyncInterfaces", "src\Microsoft.Bcl.AsyncInterfaces.csproj", "{E6C08D1F-5DAC-470E-809D-42DBFAA56DD4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8FA3CF3F-DF33-4DC4-A261-4642AB786838}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{0C330C14-95F7-4AD3-9BD0-8AAB6E3013D8}" + ProjectSection(SolutionItems) = preProject + ref\Microsoft.Bcl.AsyncInterfaces.csproj = ref\Microsoft.Bcl.AsyncInterfaces.csproj + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.AsyncInterfaces.Tests", "tests\Microsoft.Bcl.AsyncInterfaces.Tests.csproj", "{857B2747-4D8E-4A0C-9C38-521F690ED28E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{78938ED3-0E8A-451A-A508-0E724E471B91}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{95680D66-EE1B-4389-A84D-0C49AF570732}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E6C08D1F-5DAC-470E-809D-42DBFAA56DD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6C08D1F-5DAC-470E-809D-42DBFAA56DD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6C08D1F-5DAC-470E-809D-42DBFAA56DD4}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {E6C08D1F-5DAC-470E-809D-42DBFAA56DD4}.Release|Any CPU.Build.0 = Debug|Any CPU + {857B2747-4D8E-4A0C-9C38-521F690ED28E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {857B2747-4D8E-4A0C-9C38-521F690ED28E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {857B2747-4D8E-4A0C-9C38-521F690ED28E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {857B2747-4D8E-4A0C-9C38-521F690ED28E}.Release|Any CPU.Build.0 = Release|Any CPU + {95680D66-EE1B-4389-A84D-0C49AF570732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95680D66-EE1B-4389-A84D-0C49AF570732}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95680D66-EE1B-4389-A84D-0C49AF570732}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95680D66-EE1B-4389-A84D-0C49AF570732}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {E6C08D1F-5DAC-470E-809D-42DBFAA56DD4} = {8FA3CF3F-DF33-4DC4-A261-4642AB786838} + {857B2747-4D8E-4A0C-9C38-521F690ED28E} = {78938ED3-0E8A-451A-A508-0E724E471B91} + {95680D66-EE1B-4389-A84D-0C49AF570732} = {78938ED3-0E8A-451A-A508-0E724E471B91} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {48FA418B-CCC2-4EBD-9CDA-F31C72AC9B05} + EndGlobalSection +EndGlobal diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/pkg/Microsoft.Bcl.AsyncInterfaces.pkgproj b/src/libraries/Microsoft.Bcl.AsyncInterfaces/pkg/Microsoft.Bcl.AsyncInterfaces.pkgproj new file mode 100644 index 000000000000..f0630aaef6ec --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/pkg/Microsoft.Bcl.AsyncInterfaces.pkgproj @@ -0,0 +1,9 @@ + + + + + net461;netcoreapp2.0;uap10.0.16299;$(AllXamarinFrameworks) + + + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.Forwards.cs b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.Forwards.cs new file mode 100644 index 000000000000..1d2d2cc64621 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.Forwards.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.IAsyncDisposable))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IAsyncEnumerable<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IAsyncEnumerator<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.AsyncIteratorMethodBuilder))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.ConfiguredAsyncDisposable))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.EnumeratorCancellationAttribute))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskAsyncEnumerableExtensions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<>))] diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.cs b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.cs new file mode 100644 index 000000000000..13bb163974c9 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.cs @@ -0,0 +1,96 @@ +// 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 +{ + public partial interface IAsyncDisposable + { + System.Threading.Tasks.ValueTask DisposeAsync(); + } +} +namespace System.Collections.Generic +{ + public partial interface IAsyncEnumerable + { + System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + } + public partial interface IAsyncEnumerator : System.IAsyncDisposable + { + T Current { get; } + System.Threading.Tasks.ValueTask MoveNextAsync(); + } +} +namespace System.Runtime.CompilerServices +{ + public partial struct AsyncIteratorMethodBuilder + { + private object _dummy; + private int _dummyPrimitive; + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { } + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { } + public void Complete() { } + public static System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Create() { throw null; } + public void MoveNext(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { } + } + [System.AttributeUsageAttribute(System.AttributeTargets.Method, Inherited=false, AllowMultiple=false)] + public sealed partial class AsyncIteratorStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute + { + public AsyncIteratorStateMachineAttribute(System.Type stateMachineType) : base (default(System.Type)) { } + } + public readonly partial struct ConfiguredAsyncDisposable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable DisposeAsync() { throw null; } + } + public readonly partial struct ConfiguredCancelableAsyncEnumerable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable ConfigureAwait(bool continueOnCapturedContext) { throw null; } + public System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable.Enumerator GetAsyncEnumerator() { throw null; } + public System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable WithCancellation(System.Threading.CancellationToken cancellationToken) { throw null; } + public readonly partial struct Enumerator + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public T Current { get { throw null; } } + public System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable DisposeAsync() { throw null; } + public System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable MoveNextAsync() { throw null; } + } + } + [System.AttributeUsageAttribute(System.AttributeTargets.Parameter, Inherited=false)] + public sealed partial class EnumeratorCancellationAttribute : System.Attribute + { + public EnumeratorCancellationAttribute() { } + } +} +namespace System.Threading.Tasks +{ + public static partial class TaskAsyncEnumerableExtensions + { + public static System.Runtime.CompilerServices.ConfiguredAsyncDisposable ConfigureAwait(this System.IAsyncDisposable source, bool continueOnCapturedContext) { throw null; } + public static System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable ConfigureAwait(this System.Collections.Generic.IAsyncEnumerable source, bool continueOnCapturedContext) { throw null; } + public static System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable WithCancellation(this System.Collections.Generic.IAsyncEnumerable source, System.Threading.CancellationToken cancellationToken) { throw null; } + } +} +namespace System.Threading.Tasks.Sources +{ + public partial struct ManualResetValueTaskSourceCore + { + private TResult _result; + private object _dummy; + private int _dummyPrimitive; + public bool RunContinuationsAsynchronously { readonly get { throw null; } set { } } + public short Version { get { throw null; } } + public TResult GetResult(short token) { throw null; } + public System.Threading.Tasks.Sources.ValueTaskSourceStatus GetStatus(short token) { throw null; } + public void OnCompleted(System.Action continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags) { } + public void Reset() { } + public void SetException(System.Exception error) { } + public void SetResult(TResult result) { } + } +} diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj new file mode 100644 index 000000000000..603d16c0f724 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/ref/Microsoft.Bcl.AsyncInterfaces.csproj @@ -0,0 +1,14 @@ + + + net461;netstandard2.0;netstandard2.1 + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj new file mode 100644 index 000000000000..a87ada3281e7 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/Microsoft.Bcl.AsyncInterfaces.csproj @@ -0,0 +1,39 @@ + + + net461;netstandard2.0;netstandard2.1 + + + true + + + + + + System.Private.CoreLib\System\Collections\Generic\IAsyncEnumerable.cs + + + System.Private.CoreLib\System\Collections\Generic\IAsyncEnumerator.cs + + + System.Private.CoreLib\System\IAsyncDisposable.cs + + + System.Private.CoreLib\System\Runtime\CompilerServices\AsyncIteratorStateMachineAttribute.cs + + + System.Private.CoreLib\System\Runtime\CompilerServices\ConfiguredAsyncDisposable.cs + + + System.Private.CoreLib\System\Runtime\CompilerServices\ConfiguredCancelableAsyncEnumerable.cs + + + System.Private.CoreLib\System\Threading\Tasks\TaskAsyncEnumerableExtensions.cs + + + System.Private.CoreLib\System\Runtime\CompilerServices\EnumeratorCancellationAttribute.cs + + + + + + diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs new file mode 100644 index 000000000000..8943929e80c4 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// NOTE: This is a copy of +// https://github.com/dotnet/coreclr/blame/07b3afc27304800f00975c8fd4836b319aaa8820/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs +// modified to be compilable against .NET Standard 2.0. Key differences: +// - Uses the wrapped AsyncTaskMethodBuilder for Create and MoveNext. +// - Uses a custom object for the debugger identity. +// - Nullable annotations removed. + +using System.Runtime.InteropServices; +using System.Threading; + +namespace System.Runtime.CompilerServices +{ + /// Represents a builder for asynchronous iterators. + [StructLayout(LayoutKind.Auto)] + public struct AsyncIteratorMethodBuilder + { + private AsyncTaskMethodBuilder _methodBuilder; // mutable struct; do not make it readonly + private object _id; + + /// Creates an instance of the struct. + /// The initialized instance. + public static AsyncIteratorMethodBuilder Create() => + new AsyncIteratorMethodBuilder() { _methodBuilder = AsyncTaskMethodBuilder.Create() }; + + /// Invokes on the state machine while guarding the . + /// The type of the state machine. + /// The state machine instance, passed by reference. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void MoveNext(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => + _methodBuilder.Start(ref stateMachine); + + /// Schedules the state machine to proceed to the next action when the specified awaiter completes. + /// The type of the awaiter. + /// The type of the state machine. + /// The awaiter. + /// The state machine. + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine => + _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); + + /// Schedules the state machine to proceed to the next action when the specified awaiter completes. + /// The type of the awaiter. + /// The type of the state machine. + /// The awaiter. + /// The state machine. + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine => + _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); + + /// Marks iteration as being completed, whether successfully or otherwise. + public void Complete() => _methodBuilder.SetResult(); + + /// Gets an object that may be used to uniquely identify this builder to the debugger. + internal object ObjectIdForDebugger => _id ?? Interlocked.CompareExchange(ref _id, new object(), null) ?? _id; + } +} diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs new file mode 100644 index 000000000000..3cb6e817aa61 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs @@ -0,0 +1,271 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// NOTE: This is a copy of +// https://github.com/dotnet/coreclr/blame/07b3afc27304800f00975c8fd4836b319aaa8820/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs, +// modified to be compilable against .NET Standard 2.0. It is missing optimizations present in the .NET Core implementation and should +// only be used when a .NET Standard 2.0 implementation is required. Key differences: +// - ThrowHelper call sites are replaced by normal exception throws. +// - ThreadPool.{Unsafe}QueueUserWorkItem calls that accepted Action/object/bool arguments are replaced by Task.Factory.StartNew usage. +// - ExecutionContext.RunInternal are replaced by ExecutionContext.Run. +// - Nullability annotations are removed. + +using System.Diagnostics; +using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; + +namespace System.Threading.Tasks.Sources +{ + /// Provides the core logic for implementing a manual-reset or . + /// + [StructLayout(LayoutKind.Auto)] + public struct ManualResetValueTaskSourceCore + { + /// + /// The callback to invoke when the operation completes if was called before the operation completed, + /// or if the operation completed before a callback was supplied, + /// or null if a callback hasn't yet been provided and the operation hasn't yet completed. + /// + private Action _continuation; + /// State to pass to . + private object _continuationState; + /// to flow to the callback, or null if no flowing is required. + private ExecutionContext _executionContext; + /// + /// A "captured" or with which to invoke the callback, + /// or null if no special context is required. + /// + private object _capturedContext; + /// Whether the current operation has completed. + private bool _completed; + /// The result with which the operation succeeded, or the default value if it hasn't yet completed or failed. + private TResult _result; + /// The exception with which the operation failed, or null if it hasn't yet completed or completed successfully. + private ExceptionDispatchInfo _error; + /// The current version of this value, used to help prevent misuse. + private short _version; + + /// Gets or sets whether to force continuations to run asynchronously. + /// Continuations may run asynchronously if this is false, but they'll never run synchronously if this is true. + public bool RunContinuationsAsynchronously { get; set; } + + /// Resets to prepare for the next operation. + public void Reset() + { + // Reset/update state for the next use/await of this instance. + _version++; + _completed = false; + _result = default!; + _error = null; + _executionContext = null; + _capturedContext = null; + _continuation = null; + _continuationState = null; + } + + /// Completes with a successful result. + /// The result. + public void SetResult(TResult result) + { + _result = result; + SignalCompletion(); + } + + /// Complets with an error. + /// + public void SetException(Exception error) + { + _error = ExceptionDispatchInfo.Capture(error); + SignalCompletion(); + } + + /// Gets the operation version. + public short Version => _version; + + /// Gets the status of the operation. + /// Opaque value that was provided to the 's constructor. + public ValueTaskSourceStatus GetStatus(short token) + { + ValidateToken(token); + return + _continuation == null || !_completed ? ValueTaskSourceStatus.Pending : + _error == null ? ValueTaskSourceStatus.Succeeded : + _error.SourceException is OperationCanceledException ? ValueTaskSourceStatus.Canceled : + ValueTaskSourceStatus.Faulted; + } + + /// Gets the result of the operation. + /// Opaque value that was provided to the 's constructor. + public TResult GetResult(short token) + { + ValidateToken(token); + if (!_completed) + { + throw new InvalidOperationException(); + } + + _error?.Throw(); + return _result; + } + + /// Schedules the continuation action for this operation. + /// The continuation to invoke when the operation has completed. + /// The state object to pass to when it's invoked. + /// Opaque value that was provided to the 's constructor. + /// The flags describing the behavior of the continuation. + public void OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + { + if (continuation == null) + { + throw new ArgumentNullException(nameof(continuation)); + } + ValidateToken(token); + + if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) + { + _executionContext = ExecutionContext.Capture(); + } + + if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) + { + SynchronizationContext sc = SynchronizationContext.Current; + if (sc != null && sc.GetType() != typeof(SynchronizationContext)) + { + _capturedContext = sc; + } + else + { + TaskScheduler ts = TaskScheduler.Current; + if (ts != TaskScheduler.Default) + { + _capturedContext = ts; + } + } + } + + // We need to set the continuation state before we swap in the delegate, so that + // if there's a race between this and SetResult/Exception and SetResult/Exception + // sees the _continuation as non-null, it'll be able to invoke it with the state + // stored here. However, this also means that if this is used incorrectly (e.g. + // awaited twice concurrently), _continuationState might get erroneously overwritten. + // To minimize the chances of that, we check preemptively whether _continuation + // is already set to something other than the completion sentinel. + + object oldContinuation = _continuation; + if (oldContinuation == null) + { + _continuationState = state; + oldContinuation = Interlocked.CompareExchange(ref _continuation, continuation, null); + } + + if (oldContinuation != null) + { + // Operation already completed, so we need to queue the supplied callback. + if (!ReferenceEquals(oldContinuation, ManualResetValueTaskSourceCoreShared.s_sentinel)) + { + throw new InvalidOperationException(); + } + + switch (_capturedContext) + { + case null: + Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + break; + + case SynchronizationContext sc: + sc.Post(s => + { + var tuple = (Tuple, object>)s; + tuple.Item1(tuple.Item2); + }, Tuple.Create(continuation, state)); + break; + + case TaskScheduler ts: + Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts); + break; + } + } + } + + /// Ensures that the specified token matches the current version. + /// The token supplied by . + private void ValidateToken(short token) + { + if (token != _version) + { + throw new InvalidOperationException(); + } + } + + /// Signals that the operation has completed. Invoked after the result or error has been set. + private void SignalCompletion() + { + if (_completed) + { + throw new InvalidOperationException(); + } + _completed = true; + + if (_continuation != null || Interlocked.CompareExchange(ref _continuation, ManualResetValueTaskSourceCoreShared.s_sentinel, null) != null) + { + if (_executionContext != null) + { + ExecutionContext.Run( + _executionContext, + s => ((ManualResetValueTaskSourceCore)s).InvokeContinuation(), + this); + } + else + { + InvokeContinuation(); + } + } + } + + /// + /// Invokes the continuation with the appropriate captured context / scheduler. + /// This assumes that if is not null we're already + /// running within that . + /// + private void InvokeContinuation() + { + Debug.Assert(_continuation != null); + + switch (_capturedContext) + { + case null: + if (RunContinuationsAsynchronously) + { + Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + } + else + { + _continuation(_continuationState); + } + break; + + case SynchronizationContext sc: + sc.Post(s => + { + var state = (Tuple, object>)s; + state.Item1(state.Item2); + }, Tuple.Create(_continuation, _continuationState)); + break; + + case TaskScheduler ts: + Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts); + break; + } + } + } + + internal static class ManualResetValueTaskSourceCoreShared // separated out of generic to avoid unnecessary duplication + { + internal static readonly Action s_sentinel = CompletionSentinel; + private static void CompletionSentinel(object _) // named method to aid debugging + { + Debug.Fail("The sentinel delegate should never be invoked."); + throw new InvalidOperationException(); + } + } +} diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/tests/Microsoft.Bcl.AsyncInterfaces.Tests.csproj b/src/libraries/Microsoft.Bcl.AsyncInterfaces/tests/Microsoft.Bcl.AsyncInterfaces.Tests.csproj new file mode 100644 index 000000000000..79f4f9b7fc52 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/tests/Microsoft.Bcl.AsyncInterfaces.Tests.csproj @@ -0,0 +1,22 @@ + + + $(NetCoreAppCurrent);net461 + + + + Common\tests\System\Threading\Tasks\Sources\ManualResetValueTaskSource.cs + + + System.Threading.Tasks\tests\System.Runtime.CompilerServices\ConfiguredCancelableAsyncEnumerableTests.cs + + + System.Threading.Tasks\tests\System.Runtime.CompilerServices\ConfiguredAsyncDisposable.cs + + + System.Threading.Tasks.Extensions\tests\ManualResetValueTaskSourceTests.cs + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj index 549b9e74322b..b1b514112a7c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/ref/Microsoft.Extensions.DependencyInjection.csproj @@ -10,6 +10,6 @@ - + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj index 17dc779a7105..65ea136fcf18 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj @@ -45,7 +45,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj index 6b237427cde2..e651cdd660c9 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -14,6 +14,6 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index 1cd83144a389..aa4670aa7d35 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 24879b235bb9..5106330045e6 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 84bcd7c43588..a5286643df9b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj index 0c532335ff2d..e1c994d8b547 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj index 50302ec29144..4029a142486f 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index e22a2d475c2e..affb45ae6be2 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -19,7 +19,7 @@ '$(TargetFramework)' == 'net461'"> - + 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 ca40e1777447..9db4b3972418 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -250,7 +250,7 @@ - + diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index 5ab3eb994be6..cc13c1d2183a 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -24,10 +24,11 @@ "StableVersions": [ "1.0.0" ], - "BaselineVersion": "1.0.0", + "BaselineVersion": "5.0.0", "InboxOn": {}, "AssemblyVersionInPackageVersion": { - "1.0.0.0": "1.0.0" + "1.0.0.0": "1.0.0", + "5.0.0.0": "5.0.0" } }, "Microsoft.Bcl.HashCode": { diff --git a/src/libraries/pkg/descriptions.json b/src/libraries/pkg/descriptions.json index 3b04891e233a..f3111c4f2383 100644 --- a/src/libraries/pkg/descriptions.json +++ b/src/libraries/pkg/descriptions.json @@ -1234,6 +1234,15 @@ "System.Buffers.Text.Utf8Formatter" ] }, + { + "Name": "Microsoft.Bcl.AsyncInterfaces", + "Description": "Provides the IAsyncEnumerable and IAsyncDisposable interfaces and helper types for .NET Standard 2.0. This package is not required starting with .NET Standard 2.1 and .NET Core 3.0.", + "CommonTypes": [ + "System.IAsyncDisposable", + "System.Collections.Generic.IAsyncEnumerable", + "System.Collections.Generic.IAsyncEnumerator" + ] + }, { "Name": "System.Net.Http", "Description": "Provides a programming interface for modern HTTP applications, including HTTP client components that allow applications to consume web services over HTTP and HTTP components that can be used by both clients and servers for parsing HTTP headers.", From 2ac6117818d18d6d1f297a849d36f0f0e64f5d87 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 31 Jul 2020 07:17:17 -0700 Subject: [PATCH 177/755] Rename pInitRegModified ->pInitRegZeroed , fix a condition that decides if initReg should be zero-initialized (#40148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "Renamed pInitRegZeroed to pInitRegModified, initRegZeroed to initRegM… (#36321)" This reverts commit e5516bb2b188e56b47a758c9cbf0a7f1adf90dd0. * Fix the condition that determines if initReg was used during function prolog generation Also update the comments to make the use of initRegZeroed clear. * Reworded some comments related to pInitRegZeroed * Review comments * reword a comment --- src/coreclr/src/jit/codegen.h | 16 +-- src/coreclr/src/jit/codegenarm.cpp | 27 +++-- src/coreclr/src/jit/codegenarm64.cpp | 35 +++---- src/coreclr/src/jit/codegenarmarch.cpp | 10 +- src/coreclr/src/jit/codegencommon.cpp | 137 +++++++++++++------------ src/coreclr/src/jit/codegenxarch.cpp | 50 +++++---- 6 files changed, 136 insertions(+), 139 deletions(-) diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index d6e14d7a308c..e876b155ce35 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -341,12 +341,12 @@ class CodeGen final : public CodeGenInterface void genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowestCalleeSavedOffset, int spDelta); void genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, int lowestCalleeSavedOffset, int spDelta); - void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified); + void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed); #else void genPushCalleeSavedRegisters(); #endif - void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegModified, regMaskTP maskArgRegsLiveIn); + void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn); #if defined(TARGET_ARM) @@ -434,18 +434,18 @@ class CodeGen final : public CodeGenInterface void genZeroInitFltRegs(const regMaskTP& initFltRegs, const regMaskTP& initDblRegs, const regNumber& initReg); - regNumber genGetZeroReg(regNumber initReg, bool* pInitRegModified); + regNumber genGetZeroReg(regNumber initReg, bool* pInitRegZeroed); - void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified); + void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed); - void genReportGenericContextArg(regNumber initReg, bool* pInitRegModified); + void genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed); - void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified); + void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed); void genFinalizeFrame(); #ifdef PROFILING_SUPPORTED - void genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified); + void genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed); void genProfilingLeaveCallback(unsigned helper); #endif // PROFILING_SUPPORTED @@ -511,7 +511,7 @@ class CodeGen final : public CodeGenInterface void genFuncletEpilog(); void genCaptureFuncletPrologEpilogInfo(); - void genSetPSPSym(regNumber initReg, bool* pInitRegModified); + void genSetPSPSym(regNumber initReg, bool* pInitRegZeroed); void genUpdateCurrentFunclet(BasicBlock* block); #if defined(TARGET_ARM) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 0407c710e404..2eaa80862396 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -45,7 +45,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // if caller knows for certain the constant will fit. // // Return Value: -// returns true if the immediate was too large and tmpReg was used and modified. +// returns true if the immediate was small enough to be encoded inside instruction. If not, +// returns false meaning the immediate was too large and tmpReg was used and modified. // bool CodeGen::genInstrWithConstant( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm, insFlags flags, regNumber tmpReg) @@ -100,7 +101,8 @@ bool CodeGen::genInstrWithConstant( // tmpReg - an available temporary register // // Return Value: -// true if `tmpReg` was used. +// returns true if the immediate was small enough to be encoded inside instruction. If not, +// returns false meaning the immediate was too large and tmpReg was used and modified. // bool CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg) { @@ -1650,14 +1652,14 @@ void CodeGen::genCodeForMulLong(GenTreeMultiRegOp* node) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if and only if -// this call sets 'initReg' to a non-zero value. +// initReg - register to use as scratch register +// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is +// not zero after this call. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -1690,7 +1692,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie if (initReg == argReg) { - *pInitRegModified = true; + *pInitRegZeroed = false; } } @@ -1820,17 +1822,14 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper) // Arguments: // frameSize - the size of the stack frame being allocated. // initReg - register to use as a scratch register. -// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if // this call sets 'initReg' to a non-zero value. // maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, - regNumber initReg, - bool* pInitRegModified, - regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -1860,7 +1859,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, } regSet.verifyRegUsed(initReg); - *pInitRegModified = true; + *pInitRegZeroed = false; // The initReg does not contain zero instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, frameSize); compiler->unwindPadding(); @@ -1880,7 +1879,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, if ((genRegMask(initReg) & (RBM_STACK_PROBE_HELPER_ARG | RBM_STACK_PROBE_HELPER_CALL_TARGET | RBM_STACK_PROBE_HELPER_TRASH)) != RBM_NONE) { - *pInitRegModified = true; + *pInitRegZeroed = false; } } diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 2edf42d8580e..a85e2ce06bf9 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -156,7 +156,9 @@ void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool* // Even though INS_add is specified here, the encoder will choose either // an INS_add or an INS_sub and encode the immediate as a positive value // - if (genInstrWithConstant(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, spDelta, tmpReg, true)) + bool wasTempRegisterUsedForImm = + !genInstrWithConstant(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, spDelta, tmpReg, true); + if (wasTempRegisterUsedForImm) { if (pTmpRegIsZero != nullptr) { @@ -4810,14 +4812,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is +// set to non-zero value after this call. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -4845,7 +4847,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE) { - *pInitRegModified = true; + *pInitRegZeroed = false; } } @@ -9592,19 +9594,16 @@ void CodeGen::genArm64EmitterUnitTests() // on Windows as well just to be consistent, even though it should not be necessary. // // Arguments: -// frameSize - the size of the stack frame being allocated. -// initReg - register to use as a scratch register. -// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if -// this call sets 'initReg' to a non-zero value. -// maskArgRegsLiveIn - incoming argument registers that are currently live. +// frameSize - the size of the stack frame being allocated. +// initReg - register to use as a scratch register. +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// this call sets 'initReg' to a non-zero value. Otherwise, it is unchanged. +// maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, - regNumber initReg, - bool* pInitRegModified, - regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -9641,7 +9640,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, -(ssize_t)probeOffset); GetEmitter()->emitIns_R_R_R(INS_ldr, EA_4BYTE, REG_ZR, REG_SPBASE, initReg); regSet.verifyRegUsed(initReg); - *pInitRegModified = true; + *pInitRegZeroed = false; // The initReg does not contain zero lastTouchDelta -= pageSize; } @@ -9701,7 +9700,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, GetEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, rLimit, rOffset); // If equal, we need to probe again GetEmitter()->emitIns_J(INS_bls, NULL, -4); - *pInitRegModified = true; + *pInitRegZeroed = false; // The initReg does not contain zero compiler->unwindPadding(); @@ -9716,7 +9715,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, compiler->unwindPadding(); regSet.verifyRegUsed(initReg); - *pInitRegModified = true; + *pInitRegZeroed = false; // The initReg does not contain zero } } diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index a359156ab2cb..c1dcc7319afc 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -561,14 +561,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla // genSetGSSecurityCookie: Set the "GS" security cookie in the prolog. // // Arguments: -// initReg - register to use as a scratch register -// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if -// this call sets 'initReg' to a non-zero value. +// initReg - register to use as a scratch register +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) +void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -593,7 +593,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0); } - *pInitRegModified = true; + *pInitRegZeroed = false; } //--------------------------------------------------------------------- diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index 8cb0422a41e9..5923e6512f40 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -4821,7 +4821,7 @@ void CodeGen::genCheckUseBlockInit() */ #if defined(TARGET_ARM64) -void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified) +void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed) #else void CodeGen::genPushCalleeSavedRegisters() #endif @@ -5310,8 +5310,7 @@ void CodeGen::genPushCalleeSavedRegisters() JITDUMP(" spAdjustment2=%d\n", spAdjustment2); - genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg, - pInitRegModified); + genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg, pInitRegZeroed); offset += spAdjustment2; // Now subtract off the #outsz (or the rest of the #outsz if it was unaligned, and the above "sub" @@ -5331,13 +5330,13 @@ void CodeGen::genPushCalleeSavedRegisters() // We've already established the frame pointer, so no need to report the stack pointer change to unwind // info. - genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegModified, /* reportUnwindData */ false); + genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegZeroed, /* reportUnwindData */ false); offset += spAdjustment3; } else { genPrologSaveRegPair(REG_FP, REG_LR, compiler->lvaOutgoingArgSpaceSize, -remainingFrameSz, false, initReg, - pInitRegModified); + pInitRegZeroed); offset += remainingFrameSz; offsetSpToSavedFp = compiler->lvaOutgoingArgSpaceSize; @@ -5369,7 +5368,7 @@ void CodeGen::genPushCalleeSavedRegisters() JITDUMP(" remainingFrameSz=%d\n", remainingFrameSz); // We've already established the frame pointer, so no need to report the stack pointer change to unwind info. - genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegModified, /* reportUnwindData */ false); + genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegZeroed, /* reportUnwindData */ false); offset += remainingFrameSz; } else @@ -6098,17 +6097,17 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) #endif // TARGET* -// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegModified if so. +// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegZeroed if so. // Return the register to use. On ARM64, we never touch the initReg, and always just return REG_ZR. -regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegModified) +regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegZeroed) { #ifdef TARGET_ARM64 return REG_ZR; #else // !TARGET_ARM64 - if (*pInitRegModified) + if (*pInitRegZeroed == false) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - *pInitRegModified = false; + *pInitRegZeroed = true; } return initReg; #endif // !TARGET_ARM64 @@ -6118,14 +6117,14 @@ regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegModified) // genZeroInitFrame: Zero any untracked pointer locals and/or initialize memory for locspace // // Arguments: -// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init -// code will end initializing memory (not inclusive). -// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will -// start zero initializing memory. -// initReg - A scratch register (that gets set to zero on some platforms). -// pInitRegModified - Sets a flag that tells the callee whether or not the initReg register got zeroed. -// -void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified) +// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init +// code will end initializing memory (not inclusive). +// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will +// start zero initializing memory. +// initReg - A scratch register (that gets set to zero on some platforms). +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'true' if this method sets initReg register to zero, +// 'false' if initReg was set to a non-zero value, and left unchanged if initReg was not touched. +void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -6200,8 +6199,8 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, #else // !define(TARGET_ARM) - rAddr = initReg; - *pInitRegModified = true; + rAddr = initReg; + *pInitRegZeroed = false; #endif // !defined(TARGET_ARM) @@ -6242,7 +6241,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, // Load immediate into the InitReg register instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, (ssize_t)untrLclLo); GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, rAddr, genFramePointerReg(), initReg); - *pInitRegModified = true; + *pInitRegZeroed = false; } if (useLoop) @@ -6254,7 +6253,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, } #if defined(TARGET_ARM) - rZero1 = genGetZeroReg(initReg, pInitRegModified); + rZero1 = genGetZeroReg(initReg, pInitRegZeroed); instGen_Set_Reg_To_Zero(EA_PTRSIZE, rZero2); target_ssize_t stmImm = (target_ssize_t)(genRegMask(rZero1) | genRegMask(rZero2)); #endif // TARGET_ARM @@ -6343,7 +6342,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, #endif if (blkSize < minSimdSize) { - zeroReg = genGetZeroReg(initReg, pInitRegModified); + zeroReg = genGetZeroReg(initReg, pInitRegZeroed); int i = 0; for (; i + REGSIZE_BYTES <= blkSize; i += REGSIZE_BYTES) @@ -6405,7 +6404,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, assert(alignmentLoBlkSize < XMM_REGSIZE_BYTES); assert((alignedLclLo - alignmentLoBlkSize) == untrLclLo); - zeroReg = genGetZeroReg(initReg, pInitRegModified); + zeroReg = genGetZeroReg(initReg, pInitRegZeroed); int i = 0; for (; i + REGSIZE_BYTES <= alignmentLoBlkSize; i += REGSIZE_BYTES) @@ -6513,7 +6512,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, emit->emitIns_J(INS_jne, nullptr, -5); // initReg will be zero at end of the loop - *pInitRegModified = false; + *pInitRegZeroed = true; } if (untrLclHi != alignedLclHi) @@ -6522,7 +6521,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, assert(alignmentHiBlkSize < XMM_REGSIZE_BYTES); assert((alignedLclHi + alignmentHiBlkSize) == untrLclHi); - zeroReg = genGetZeroReg(initReg, pInitRegModified); + zeroReg = genGetZeroReg(initReg, pInitRegZeroed); int i = 0; for (; i + REGSIZE_BYTES <= alignmentHiBlkSize; i += REGSIZE_BYTES) @@ -6589,13 +6588,13 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, if (layout->IsGCPtr(i)) { GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, - genGetZeroReg(initReg, pInitRegModified), varNum, i * REGSIZE_BYTES); + genGetZeroReg(initReg, pInitRegZeroed), varNum, i * REGSIZE_BYTES); } } } else { - regNumber zeroReg = genGetZeroReg(initReg, pInitRegModified); + regNumber zeroReg = genGetZeroReg(initReg, pInitRegZeroed); // zero out the whole thing rounded up to a single stack slot size unsigned lclSize = roundUp(compiler->lvaLclSize(varNum), (unsigned)sizeof(int)); @@ -6627,7 +6626,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, // printf("initialize untracked spillTmp [EBP-%04X]\n", stkOffs); - inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegModified), TYP_I_IMPL); + inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegZeroed), TYP_I_IMPL); } } @@ -6762,7 +6761,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, * ICodeManager::GetParamTypeArg(). */ -void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegModified) +void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed) { // For OSR the original method has set this up for us. if (compiler->opts.IsOSR()) @@ -6827,8 +6826,8 @@ void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegModifi // We will just use the initReg since it is an available register // and we are probably done using it anyway... - reg = initReg; - *pInitRegModified = true; + reg = initReg; + *pInitRegZeroed = false; // mov reg, [compiler->info.compTypeCtxtArg] GetEmitter()->emitIns_R_AR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, reg, genFramePointerReg(), varDsc->lvStkOffs); @@ -7672,9 +7671,13 @@ void CodeGen::genFnProlog() /* Choose the register to use for zero initialization */ - regNumber initReg = REG_SCRATCH; // Unless we find a better register below - bool initRegModified = true; - regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn; + regNumber initReg = REG_SCRATCH; // Unless we find a better register below + + // Track if initReg holds non-zero value. Start conservative and assume it has non-zero value. + // If initReg is ever set to zero, this variable is set to true and zero initializing initReg + // will be skipped. + bool initRegZeroed = false; + regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn; regMaskTP tempMask; // We should not use the special PINVOKE registers as the initReg @@ -7807,11 +7810,11 @@ void CodeGen::genFnProlog() // been calculated to be one of the callee-saved registers (say, if all the integer argument registers are // in use, and perhaps with other conditions being satisfied). This is ok in other cases, after the callee-saved // registers have been saved. So instead of letting genAllocLclFrame use initReg as a temporary register, - // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegModified output argument. - bool ignoreInitRegModified = true; - genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegModified, + // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegZeroed output argument. + bool ignoreInitRegZeroed = false; + genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegZeroed, intRegState.rsCalleeRegArgMaskLiveIn); - genPushCalleeSavedRegisters(initReg, &initRegModified); + genPushCalleeSavedRegisters(initReg, &initRegZeroed); #else // !TARGET_ARM64 genPushCalleeSavedRegisters(); #endif // !TARGET_ARM64 @@ -7855,7 +7858,7 @@ void CodeGen::genFnProlog() if (maskStackAlloc == RBM_NONE) { - genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegModified, intRegState.rsCalleeRegArgMaskLiveIn); + genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegZeroed, intRegState.rsCalleeRegArgMaskLiveIn); } #endif // !TARGET_ARM64 @@ -7918,11 +7921,11 @@ void CodeGen::genFnProlog() // Zero out the frame as needed // - genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegModified); + genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegZeroed); #if defined(FEATURE_EH_FUNCLETS) - genSetPSPSym(initReg, &initRegModified); + genSetPSPSym(initReg, &initRegZeroed); #else // !FEATURE_EH_FUNCLETS @@ -7935,10 +7938,10 @@ void CodeGen::genFnProlog() // Zero out the slot for nesting level 0 unsigned firstSlotOffs = filterEndOffsetSlotOffs - TARGET_POINTER_SIZE; - if (initRegModified) + if (!initRegZeroed) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - initRegModified = false; + initRegZeroed = true; } GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, initReg, compiler->lvaShadowSPslotsVar, @@ -7947,7 +7950,7 @@ void CodeGen::genFnProlog() #endif // !FEATURE_EH_FUNCLETS - genReportGenericContextArg(initReg, &initRegModified); + genReportGenericContextArg(initReg, &initRegZeroed); #ifdef JIT32_GCENCODER // Initialize the LocalAllocSP slot if there is localloc in the function. @@ -7959,7 +7962,7 @@ void CodeGen::genFnProlog() // Set up the GS security cookie - genSetGSSecurityCookie(initReg, &initRegModified); + genSetGSSecurityCookie(initReg, &initRegZeroed); #ifdef PROFILING_SUPPORTED @@ -7967,7 +7970,7 @@ void CodeGen::genFnProlog() // OSR methods aren't called, so don't have enter hooks. if (!compiler->opts.IsOSR()) { - genProfilingEnterCallback(initReg, &initRegModified); + genProfilingEnterCallback(initReg, &initRegZeroed); } #endif // PROFILING_SUPPORTED @@ -8029,15 +8032,15 @@ void CodeGen::genFnProlog() } else { - xtraReg = REG_SCRATCH; - initRegModified = true; + xtraReg = REG_SCRATCH; + initRegZeroed = false; } genFnPrologCalleeRegArgs(xtraReg, &xtraRegClobbered, regState); if (xtraRegClobbered) { - initRegModified = true; + initRegZeroed = false; } } } @@ -8057,7 +8060,7 @@ void CodeGen::genFnProlog() if (regMask & initRegs) { // Check if we have already zeroed this register - if ((reg == initReg) && !initRegModified) + if ((reg == initReg) && initRegZeroed) { continue; } @@ -8066,7 +8069,7 @@ void CodeGen::genFnProlog() instGen_Set_Reg_To_Zero(EA_PTRSIZE, reg); if (reg == initReg) { - initRegModified = false; + initRegZeroed = true; } } } @@ -8078,17 +8081,17 @@ void CodeGen::genFnProlog() // If initReg is not in initRegs then we will use REG_SCRATCH if ((genRegMask(initReg) & initRegs) == 0) { - initReg = REG_SCRATCH; - initRegModified = true; + initReg = REG_SCRATCH; + initRegZeroed = false; } #ifdef TARGET_ARM // This is needed only for Arm since it can use a zero initialized int register // to initialize vfp registers. - if (initRegModified) + if (!initRegZeroed) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - initRegModified = false; + initRegZeroed = true; } #endif // TARGET_ARM @@ -9095,12 +9098,12 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_R0; } - regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed - bool initRegModified = true; + regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed + bool initRegZeroed = false; if (maskStackAlloc == RBM_NONE) { - genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn); + genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn); } // This is the end of the OS-reported prolog for purposes of unwinding @@ -9397,10 +9400,10 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_ARG_0 | RBM_ARG_2; } - regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed - bool initRegModified = true; + regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed + bool initRegZeroed = false; - genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn); + genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn); // Callee saved float registers are copied to stack in their assigned stack slots // after allocating space for them as part of funclet frame. @@ -9739,7 +9742,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() * correctly reported, the PSPSym could be omitted in some cases.) *********************************** */ -void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified) +void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -9785,8 +9788,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified) // We will just use the initReg since it is an available register // and we are probably done using it anyway... - regNumber regTmp = initReg; - *pInitRegModified = true; + regNumber regTmp = initReg; + *pInitRegZeroed = false; GetEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regTmp, regBase, callerSPOffs); GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0); @@ -9797,8 +9800,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified) // We will just use the initReg since it is an available register // and we are probably done using it anyway... - regNumber regTmp = initReg; - *pInitRegModified = true; + regNumber regTmp = initReg; + *pInitRegZeroed = false; GetEmitter()->emitIns_R_R_Imm(INS_add, EA_PTRSIZE, regTmp, REG_SPBASE, SPtoCallerSPdelta); GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0); diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index c66d25c483c9..88c021ac73d0 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -53,14 +53,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla // genSetGSSecurityCookie: Set the "GS" security cookie in the prolog. // // Arguments: -// initReg - register to use as a scratch register -// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if -// this call sets 'initReg' to a non-zero value. +// initReg - register to use as a scratch register +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) +void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -84,7 +84,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) // initReg = #GlobalSecurityCookieVal64; [frame.GSSecurityCookie] = initReg genSetRegToIcon(initReg, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL); GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0); - *pInitRegModified = true; + *pInitRegZeroed = false; } else #endif @@ -105,7 +105,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, REG_EAX, compiler->lvaGSSecurityCookie, 0); if (initReg == REG_EAX) { - *pInitRegModified = true; + *pInitRegZeroed = false; } } } @@ -1950,19 +1950,16 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode) // genAllocLclFrame: Probe the stack and allocate the local stack frame - subtract from SP. // // Arguments: -// frameSize - the size of the stack frame being allocated. -// initReg - register to use as a scratch register. -// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if -// this call sets 'initReg' to a non-zero value. -// maskArgRegsLiveIn - incoming argument registers that are currently live. +// frameSize - the size of the stack frame being allocated. +// initReg - register to use as a scratch register. +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// this call sets 'initReg' to a non-zero value. +// maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, - regNumber initReg, - bool* pInitRegModified, - regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -2046,7 +2043,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, if (initReg == REG_DEFAULT_HELPER_CALL_TARGET) { - *pInitRegModified = true; + *pInitRegZeroed = false; } static_assert_no_msg((RBM_STACK_PROBE_HELPER_TRASH & RBM_STACK_PROBE_HELPER_ARG) == RBM_NONE); @@ -2056,7 +2053,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, if (initReg == REG_STACK_PROBE_HELPER_ARG) { - *pInitRegModified = true; + *pInitRegZeroed = false; } } @@ -8452,9 +8449,8 @@ void CodeGen::genAmd64EmitterUnitTests() // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegZeroed - OUT parameter. This variable remains unchanged. // // Return Value: // None @@ -8473,7 +8469,7 @@ void CodeGen::genAmd64EmitterUnitTests() // 4. All registers are preserved. // 5. The helper pops the FunctionIDOrClientID argument from the stack. // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -8618,14 +8614,14 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) { assert(compiler->compGeneratingProlog); @@ -8762,7 +8758,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie // If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using. if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0) { - *pInitRegModified = true; + *pInitRegZeroed = false; } #else // !defined(UNIX_AMD64_ABI) @@ -8811,7 +8807,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie // If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using. if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0) { - *pInitRegModified = true; + *pInitRegZeroed = false; } #endif // !defined(UNIX_AMD64_ABI) From 54786218365430bdebd2bfece8d5145d3f33f5d2 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 31 Jul 2020 08:50:06 -0700 Subject: [PATCH 178/755] Delete unused PInvokeInline config value (#40199) Fixes #40192 --- src/coreclr/src/inc/clrconfigvalues.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 48f9ce51fe2a..3cd7db89bb7e 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -692,7 +692,6 @@ RETAIL_CONFIG_STRING_INFO(INTERNAL_EventNameFilter, W("EventNameFilter"), "") /// Interop /// CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_ExposeExceptionsInCOM, W("ExposeExceptionsInCOM"), "") -RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_PInvokeInline, W("PInvokeInline"), "", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_InteropValidatePinnedObjects, W("InteropValidatePinnedObjects"), 0, "After returning from a managed-to-unmanaged interop call, validate GC heap around objects pinned by IL stubs.") RETAIL_CONFIG_DWORD_INFO(EXTERNAL_InteropLogArguments, W("InteropLogArguments"), 0, "Log all pinned arguments passed to an interop call") RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_LogCCWRefCountChange, W("LogCCWRefCountChange"), "Outputs debug information and calls LogCCWRefCountChange_BREAKPOINT when AddRef or Release is called on a CCW.") From 5bd0edfe860e41bdfd690d3743e730594307292e Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Fri, 31 Jul 2020 17:53:30 +0200 Subject: [PATCH 179/755] Move GetCurrentProcessId interop for Browser to managed (#39367) * Move GetCurrentProcessId for Browser to managed It returns constant all the time * Remove redundant indirection * Fix EventSource build break Co-authored-by: Jan Kotas --- .../Unix/System.Native/Interop.GetPid.cs | 2 -- .../Kernel32/Interop.GetCurrentProcessId.cs | 2 -- .../System.Private.CoreLib.Shared.projitems | 6 ++--- .../Diagnostics/Tracing/ActivityTracker.cs | 3 ++- .../System/Diagnostics/Tracing/EventSource.cs | 9 ------- .../Diagnostics/Tracing/StubEnvironment.cs | 27 +++++-------------- .../src/System/Environment.Browser.cs | 4 ++- .../src/System/Environment.Unix.cs | 2 ++ .../src/System/Environment.UnixOrBrowser.cs | 2 -- .../System/Threading/Tasks/TplEventSource.cs | 2 +- 10 files changed, 17 insertions(+), 42 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetPid.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetPid.cs index bbd99dfb5ecb..400dc554a366 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetPid.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetPid.cs @@ -10,6 +10,4 @@ internal static partial class Sys [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetPid")] internal static extern int GetPid(); } - - internal static uint GetCurrentProcessId() => (uint)Sys.GetPid(); } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs index ff50d0d470bc..70009c6f9323 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs @@ -10,6 +10,4 @@ internal static partial class Kernel32 [DllImport(Libraries.Kernel32)] internal static extern uint GetCurrentProcessId(); } - - internal static uint GetCurrentProcessId() => Kernel32.GetCurrentProcessId(); } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index b00e089f872d..61cc83639970 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1715,9 +1715,6 @@ Common\Interop\Unix\System.Native\Interop.GetHostName.cs - - Common\Interop\Unix\System.Native\Interop.GetPid.cs - Common\Interop\Unix\System.Native\Interop.GetPwUid.cs @@ -1826,6 +1823,9 @@ + + Common\Interop\Unix\System.Native\Interop.GetPid.cs + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs index c98e76352fca..cec4e969f2ce 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs @@ -4,6 +4,7 @@ #if ES_BUILD_STANDALONE using System; using System.Diagnostics; +using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; #else using System.Threading.Tasks; #endif @@ -511,7 +512,7 @@ private static unsafe int AddIdToGuid(Guid* outPtr, int whereToAddId, uint id, b uint* sumPtr = (uint*)outPtr; // We set the last DWORD the sum of the first 3 DWORDS in the GUID. This // This last number is a random number (it identifies us as us) the process ID to make it unique per process. - sumPtr[3] = (sumPtr[0] + sumPtr[1] + sumPtr[2] + 0x599D99AD) ^ EventSource.s_currentPid; + sumPtr[3] = (sumPtr[0] + sumPtr[1] + sumPtr[2] + 0x599D99AD) ^ (uint)Environment.ProcessId; return (int)(ptr - ((byte*)outPtr)); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 02b84bcd18ff..ab95ee4c10df 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -2843,14 +2843,6 @@ private void EnsureDescriptorsInitialized() DefineEventPipeEvents(); #endif } - if (s_currentPid == 0) - { -#if ES_BUILD_STANDALONE - // for non-BCL EventSource we must assert SecurityPermission - new SecurityPermission(PermissionState.Unrestricted).Assert(); -#endif - s_currentPid = Interop.GetCurrentProcessId(); - } } // Send out the ETW manifest XML out to ETW @@ -3807,7 +3799,6 @@ private bool SelfDescribingEvents private string[]? m_traits; // Used to implement GetTraits - internal static uint s_currentPid; // current process id, used in synthesizing quasi-GUIDs [ThreadStatic] private static byte m_EventSourceExceptionRecurenceCount; // current recursion count inside ThrowEventSourceException diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs index 9f08d0ca304b..90428c3b942c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs @@ -10,6 +10,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; +using System.Security.Permissions; #endif #if ES_BUILD_AGAINST_DOTNET_V35 using Microsoft.Internal; @@ -22,32 +23,18 @@ namespace Microsoft.Diagnostics.Tracing.Internal namespace System.Diagnostics.Tracing.Internal #endif { +#if ES_BUILD_STANDALONE internal static class Environment { - public static readonly string NewLine = System.Environment.NewLine; - - public static int TickCount => System.Environment.TickCount; - - public static string GetResourceString(string key, params object?[] args) - { - string? fmt = rm.GetString(key); - if (fmt != null) - return string.Format(fmt, args); - - string sargs = string.Join(", ", args); + public static int ProcessId = GetCurrentProcessId(); - return key + " (" + sargs + ")"; - } - - public static string GetRuntimeResourceString(string key, params object?[] args) + private static int GetCurrentProcessId() { - return GetResourceString(key, args); + new SecurityPermission(PermissionState.Unrestricted).Assert(); + return (int)Interop.Kernel32.GetCurrentProcessId(); } - - private static readonly System.Resources.ResourceManager rm = new System.Resources.ResourceManager("Microsoft.Diagnostics.Tracing.Messages", typeof(Environment).Assembly()); } -#if ES_BUILD_STANDALONE internal static class BitOperations { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -365,7 +352,5 @@ internal static partial class Kernel32 [DllImport("kernel32.dll", CharSet = CharSet.Auto)] internal static extern uint GetCurrentProcessId(); } - - internal static uint GetCurrentProcessId() => Kernel32.GetCurrentProcessId(); } #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs index 4f2beaa3b01b..07ad3b8b31c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs @@ -24,5 +24,7 @@ private static OperatingSystem GetOSVersion() { return new OperatingSystem(PlatformID.Other, new Version(1, 0, 0, 0)); } + + private static int GetCurrentProcessId() => 42; } -} \ No newline at end of file +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs index 87306e7b741a..9b5ff6ac417c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs @@ -110,5 +110,7 @@ private static unsafe bool TryGetUserNameFromPasswd(byte* buf, int bufLen, out s // Otherwise, fail. throw new IOException(errorInfo.GetErrorMessage(), errorInfo.RawErrno); } + + private static int GetCurrentProcessId() => Interop.Sys.GetPid(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs index cddf1b929e63..588e1dbf57d1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs @@ -48,8 +48,6 @@ private static string ExpandEnvironmentVariablesCore(string name) private static bool Is64BitOperatingSystemWhen32BitProcess => false; - private static int GetCurrentProcessId() => Interop.Sys.GetPid(); - internal const string NewLineConst = "\n"; public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index 9b89c9ecf19b..ea85eab23cfe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -556,7 +556,7 @@ internal static Guid CreateGuidForTaskID(int taskID) // using the taskGuid, the appdomain ID, and 8 bytes of 'randomization' chosen by // using the last 8 bytes as the provider GUID for this provider. // These were generated by CreateGuid, and are reasonably random (and thus unlikely to collide - uint pid = EventSource.s_currentPid; + int pid = Environment.ProcessId; return new Guid(taskID, (short)DefaultAppDomainID, (short)(DefaultAppDomainID >> 16), (byte)pid, (byte)(pid >> 8), (byte)(pid >> 16), (byte)(pid >> 24), From ef6696aca9feed00139c704c096ae16d9a3e4790 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 31 Jul 2020 12:06:08 -0500 Subject: [PATCH 180/755] Improve runtime error logging (#40176) --- src/mono/wasm/runtime-test.js | 2 ++ src/mono/wasm/runtime/driver.c | 38 +++++++++++++++++---------- src/mono/wasm/runtime/library_mono.js | 3 +-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index a2a66b6f85f6..cc01a77701b4 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -36,6 +36,8 @@ if (typeof console !== "undefined") { console.trace = console.log; if (!console.warn) console.warn = console.log; + if (!console.error) + console.error = console.log; } if (typeof crypto == 'undefined') { diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index e98b1b845933..32de5d807035 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -108,20 +108,30 @@ mono_wasm_invoke_js (MonoString *str, int *is_exception) static void wasm_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { - if (fatal) { - EM_ASM( - var err = new Error(); - console.log ("Stacktrace: \n"); - console.log (err.stack); - ); - - fprintf (stderr, "%s\n", message); - fflush (stderr); - - abort (); - } else { - fprintf (stdout, "L: %s\n", message); - } + EM_ASM({ + var message = $1; + if ($2) + console.trace (message); + + switch ($0) { + case "critical": + case "error": + console.error (message); + break; + case "warning": + console.warn (message); + break; + case "message": + console.log (message); + break; + case "info": + console.info (message); + break; + case "debug": + console.debug (message); + break; + } + },log_level, message, fatal); } #ifdef DRIVER_GEN diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index f47c0f8ec6db..093b9fdf6970 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -780,9 +780,8 @@ var MonoSupportLib = { load_runtime ("unused", args.enable_debugging); } catch (ex) { print ("MONO_WASM: load_runtime () failed: " + ex); - var err = new Error(); print ("MONO_WASM: Stacktrace: \n"); - print (err.stack); + print (ex.stack); var wasm_exit = Module.cwrap ('mono_wasm_exit', null, ['number']); wasm_exit (1); From 6caef3817758aa8600014747f4c4f1c1dac4083b Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 31 Jul 2020 13:18:32 -0500 Subject: [PATCH 181/755] [wasm] Enable stack tests that now work on browser-wasm (#40206) * Enable stack tests that now work on browser-wasm --- .../tests/StackFrameExtensionsTests.cs | 1 - .../System.Diagnostics.StackTrace/tests/StackFrameTests.cs | 1 - .../tests/StackTraceSymbolsTests.cs | 2 +- .../System.Diagnostics.StackTrace/tests/StackTraceTests.cs | 1 - .../tests/TraceEventCacheClassTests.cs | 2 -- .../tests/TraceListenerClassTests.cs | 1 - .../tests/System/Environment.StackTrace.cs | 1 - 7 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameExtensionsTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameExtensionsTests.cs index aaecae6e7fb2..a8572840bfac 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameExtensionsTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameExtensionsTests.cs @@ -6,7 +6,6 @@ namespace System.Diagnostics.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public class StackFrameExtensionsTests { public static IEnumerable StackFrame_TestData() diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs index 445ae86ca6f1..e80c6b950960 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs @@ -8,7 +8,6 @@ namespace System.Diagnostics.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public class StackFrameTests { [Fact] diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs index ba291aeb1d95..8026935ba5a9 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs @@ -7,7 +7,7 @@ namespace System.Diagnostics.SymbolStore.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39650", TestPlatforms.Browser)] public class StackTraceSymbolsTests { [Fact] diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs index 67119f9799cf..894374ba29b4 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs @@ -29,7 +29,6 @@ public static StackTrace MethodWithException() namespace System.Diagnostics.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public class StackTraceTests { [Fact] diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs index 680f8b620a12..6933d0323dae 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs @@ -48,7 +48,6 @@ public void TimestampTest() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public void CallstackTest_NotEmpty() { var cache = new TraceEventCache(); @@ -56,7 +55,6 @@ public void CallstackTest_NotEmpty() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public void CallstackTest_ContainsExpectedFrames() { var cache = new TraceEventCache(); diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs index fbe119351426..08668fdd7321 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs @@ -313,7 +313,6 @@ public void WriteFooterTest(TraceOptions opts, int flagCount) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] [MethodImpl(MethodImplOptions.NoInlining)] public void WriteFooterTest_Callstack() { diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs index 4077019d7010..e3fa2c36d28f 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs @@ -68,7 +68,6 @@ public TestClass() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39223", TestPlatforms.Browser)] public void StackTraceDoesNotStartWithInternalFrame() { string stackTrace = Environment.StackTrace; From ed31ea5ba5872eab0aad5efea5cb45f4618ad388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 31 Jul 2020 20:23:45 +0200 Subject: [PATCH 182/755] Fix nullability warning in ApkBuilder.cs with newer Roslyn (#40155) --- tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index a92a5090c336..92812402ce29 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -257,7 +257,7 @@ private static string GetLatestBuildTools(string androidSdkDir) string? buildTools = Directory.GetDirectories(Path.Combine(androidSdkDir, "build-tools")) .Select(Path.GetFileName) .Where(file => !file!.Contains("-")) - .Select(file => Version.TryParse(Path.GetFileName(file), out Version? version) ? version : default) + .Select(file => { Version.TryParse(Path.GetFileName(file), out Version? version); return version; }) .OrderByDescending(v => v) .FirstOrDefault()?.ToString(); From 5ddc873d9ea6cd4bc6a935fec3057fe89a6932aa Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Fri, 31 Jul 2020 13:16:46 -0700 Subject: [PATCH 183/755] Adding sequential read as the file option in ReadAllBytes (#40213) --- src/libraries/System.IO.FileSystem/src/System/IO/File.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs index 2e5909c15a03..16a82bd337e9 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs @@ -328,7 +328,7 @@ public static void WriteAllText(string path, string? contents, Encoding encoding public static byte[] ReadAllBytes(string path) { // bufferSize == 1 used to avoid unnecessary buffer in FileStream - using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1)) + using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1, FileOptions.SequentialScan)) { long fileLength = fs.Length; if (fileLength > int.MaxValue) From c44154b15126786260f8a6397248dd04c0e015e3 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Fri, 31 Jul 2020 13:31:42 -0700 Subject: [PATCH 184/755] Clarify string source comments (#40210) --- src/libraries/System.Private.CoreLib/src/System/String.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs index 49af25beb49c..54333a3c215d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.cs @@ -611,6 +611,7 @@ public StringRuneEnumerator EnumerateRunes() internal static unsafe int wcslen(char* ptr) { // IndexOf processes memory in aligned chunks, and thus it won't crash even if it accesses memory beyond the null terminator. + // This IndexOf behavior is an implementation detail of the runtime and callers outside System.Private.CoreLib must not depend on it. int length = SpanHelpers.IndexOf(ref *ptr, '\0', int.MaxValue); if (length < 0) { @@ -624,6 +625,7 @@ internal static unsafe int wcslen(char* ptr) internal static unsafe int strlen(byte* ptr) { // IndexOf processes memory in aligned chunks, and thus it won't crash even if it accesses memory beyond the null terminator. + // This IndexOf behavior is an implementation detail of the runtime and callers outside System.Private.CoreLib must not depend on it. int length = SpanHelpers.IndexOf(ref *ptr, (byte)'\0', int.MaxValue); if (length < 0) { From e30648967f5499dea6e7df24c5505826e46412b6 Mon Sep 17 00:00:00 2001 From: John Salem Date: Fri, 31 Jul 2020 15:24:40 -0700 Subject: [PATCH 185/755] Handle success case for overlapped IO in Windows Diagnostics IPC PAL (#39807) Prevents unintialized memory from making its way into the call to WaitForMultipleObjects. That memory could contain a valid handle value and cause WFMO to hang since it isn't waiting on the correct handles. --- .../debug/debug-pal/win/diagnosticsipc.cpp | 32 ++++++++++++++++--- src/coreclr/tests/issues.targets | 3 -- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp index 6c1b55e31118..2b6c38463c1b 100644 --- a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp @@ -119,6 +119,7 @@ bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) _hPipe = INVALID_HANDLE_VALUE; ::CloseHandle(_oOverlap.hEvent); _oOverlap.hEvent = INVALID_HANDLE_VALUE; + memset(&_oOverlap, 0, sizeof(OVERLAPPED)); // clear the overlapped objects state return false; } } @@ -193,11 +194,15 @@ IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) return new IpcStream(hPipe, mode); } -void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback) +void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback callback) { // don't attempt cleanup on shutdown and let the OS handle it if (isShutdown) + { + if (callback != nullptr) + callback("Closing without cleaning underlying handles", 100); return; + } if (_hPipe != INVALID_HANDLE_VALUE) { @@ -205,15 +210,22 @@ void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback) { const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); _ASSERTE(fSuccessDisconnectNamedPipe != 0); + if (fSuccessDisconnectNamedPipe != 0 && callback != nullptr) + callback("Failed to disconnect NamedPipe", ::GetLastError()); } const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe); _ASSERTE(fSuccessCloseHandle != 0); + if (fSuccessCloseHandle != 0 && callback != nullptr) + callback("Failed to close pipe handle", ::GetLastError()); } if (_oOverlap.hEvent != INVALID_HANDLE_VALUE) { - ::CloseHandle(_oOverlap.hEvent); + const BOOL fSuccessCloseEvent = ::CloseHandle(_oOverlap.hEvent); + _ASSERTE(fSuccessCloseEvent != 0); + if (fSuccessCloseEvent != 0 && callback != nullptr) + callback("Failed to close overlap event handle", ::GetLastError()); } } @@ -230,7 +242,7 @@ IpcStream::~IpcStream() Close(); } -void IpcStream::Close(ErrorCallback) +void IpcStream::Close(ErrorCallback callback) { if (_hPipe != INVALID_HANDLE_VALUE) { @@ -240,15 +252,22 @@ void IpcStream::Close(ErrorCallback) { const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); _ASSERTE(fSuccessDisconnectNamedPipe != 0); + if (fSuccessDisconnectNamedPipe != 0 && callback != nullptr) + callback("Failed to disconnect NamedPipe", ::GetLastError()); } const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe); _ASSERTE(fSuccessCloseHandle != 0); + if (fSuccessCloseHandle != 0 && callback != nullptr) + callback("Failed to close pipe handle", ::GetLastError()); } if (_oOverlap.hEvent != INVALID_HANDLE_VALUE) { - ::CloseHandle(_oOverlap.hEvent); + const BOOL fSuccessCloseEvent = ::CloseHandle(_oOverlap.hEvent); + _ASSERTE(fSuccessCloseEvent != 0); + if (fSuccessCloseEvent != 0 && callback != nullptr) + callback("Failed to close overlapped event handle", ::GetLastError()); } } @@ -302,6 +321,11 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_ return -1; } } + else + { + // there's already data to be read + pHandles[i] = rgIpcPollHandles[i].pStream->_oOverlap.hEvent; + } } else { diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 4cb3d04ab9f5..f15a2b532099 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -306,9 +306,6 @@ - - https://github.com/dotnet/runtime/issues/38847 - From d32ba13b0ff61494117b3a124decae116c8c83e1 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 31 Jul 2020 15:33:24 -0700 Subject: [PATCH 186/755] Unregister callback when setting a provider for deferred delete (#40191) --- src/coreclr/src/vm/eventpipeprovider.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/vm/eventpipeprovider.cpp b/src/coreclr/src/vm/eventpipeprovider.cpp index 9bc84079a65e..7aaa31f887b1 100644 --- a/src/coreclr/src/vm/eventpipeprovider.cpp +++ b/src/coreclr/src/vm/eventpipeprovider.cpp @@ -306,6 +306,9 @@ void EventPipeProvider::SetDeleteDeferred() { LIMITED_METHOD_CONTRACT; m_deleteDeferred = true; + // EventSources will be collected once they ungregister themselves, + // so we can't call back in to them. + m_pCallbackFunction = NULL; } void EventPipeProvider::RefreshAllEvents() From 62881e574c89e582c91543bb15e1b443ac1eeeb6 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Fri, 31 Jul 2020 16:35:04 -0700 Subject: [PATCH 187/755] Ensure we can evolve IO.Pipelines package (#40212) --- .../System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj b/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj index 517bc698cc6d..9b454d0d07b4 100644 --- a/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj +++ b/src/libraries/System.IO.Pipelines/pkg/System.IO.Pipelines.pkgproj @@ -11,7 +11,12 @@ - + + + + .NETCoreApp + From 28ffb418cddbb2d7278d24f9eb6b764822043d29 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Sat, 1 Aug 2020 01:39:53 +0200 Subject: [PATCH 188/755] Update area-owners.md (#40200) --- docs/area-owners.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/area-owners.md b/docs/area-owners.md index 17b260a9c9ea..210243387b0c 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -1,6 +1,10 @@ -If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead). +# Pull Requests Tagging -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. +If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead) for [area](#areas) to which the change or issue is closest to. For areas which are large and can be operating system or architecture specific it's better to tag owners of [OS](#operating-systems) or [Architecture](#architectures). + +## Areas + +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`, `@marek-safar`, `@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 | |------------------------------------------------|---------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -121,3 +125,20 @@ Note: Editing this file doesn't update the mapping used by the `@msftbot` issue | 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 @CoffeeFlux | | +## Operating Systems + +| Operating System | Lead | Owners (area experts to tag in PR's and issues) | Description | +|------------------|---------------|-----------------------------------------------------|--------------| +| os-alpine | | | | +| os-android | @steveisok | @akoeplinger | | +| os-freebsd | | | | +| os-mac-os-x | @steveisok | | | +| os-ios | @steveisok | @vargaz | | +| os-tvos | @steveisok | @vargaz | | + +## Architectures + +| Architecture | Lead | Owners (area experts to tag in PR's and issues) | Description | +|-----------------|---------------|-----------------------------------------------------|--------------| +| arch-wasm | @lewing | @lewing @BrzVlad | | + From d40d32bfec9a7f7b4c0bd9a34566ee40219b7d39 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 31 Jul 2020 16:48:38 -0700 Subject: [PATCH 189/755] Disable GCStress for profiler tests (#40171) --- src/tests/profiler/eventpipe/eventpipe.csproj | 2 +- src/tests/profiler/eventpipe/eventpipe_readevents.csproj | 2 ++ src/tests/profiler/gc/gc.csproj | 2 ++ src/tests/profiler/gc/gcbasic.csproj | 2 ++ src/tests/profiler/rejit/rejit.csproj | 2 ++ src/tests/profiler/unittest/getappdomainstaticaddress.csproj | 2 ++ src/tests/profiler/unittest/metadatagetdispenser.csproj | 2 ++ .../tracing/eventpipe/eventsourceerror/eventsourceerror.csproj | 2 +- src/tests/tracing/eventpipe/gcdump/gcdump.csproj | 2 +- 9 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/tests/profiler/eventpipe/eventpipe.csproj b/src/tests/profiler/eventpipe/eventpipe.csproj index cc0888d25678..fc9c21e7144d 100644 --- a/src/tests/profiler/eventpipe/eventpipe.csproj +++ b/src/tests/profiler/eventpipe/eventpipe.csproj @@ -6,7 +6,7 @@ true 0 true - + true diff --git a/src/tests/profiler/eventpipe/eventpipe_readevents.csproj b/src/tests/profiler/eventpipe/eventpipe_readevents.csproj index 7a525ce745d2..fc9c21e7144d 100644 --- a/src/tests/profiler/eventpipe/eventpipe_readevents.csproj +++ b/src/tests/profiler/eventpipe/eventpipe_readevents.csproj @@ -6,6 +6,8 @@ true 0 true + + true diff --git a/src/tests/profiler/gc/gc.csproj b/src/tests/profiler/gc/gc.csproj index 7a525ce745d2..fc9c21e7144d 100644 --- a/src/tests/profiler/gc/gc.csproj +++ b/src/tests/profiler/gc/gc.csproj @@ -6,6 +6,8 @@ true 0 true + + true diff --git a/src/tests/profiler/gc/gcbasic.csproj b/src/tests/profiler/gc/gcbasic.csproj index 7a525ce745d2..fc9c21e7144d 100644 --- a/src/tests/profiler/gc/gcbasic.csproj +++ b/src/tests/profiler/gc/gcbasic.csproj @@ -6,6 +6,8 @@ true 0 true + + true diff --git a/src/tests/profiler/rejit/rejit.csproj b/src/tests/profiler/rejit/rejit.csproj index 7ea4cfaea5be..ac5c4b677e79 100644 --- a/src/tests/profiler/rejit/rejit.csproj +++ b/src/tests/profiler/rejit/rejit.csproj @@ -7,6 +7,8 @@ 0 true True + + true diff --git a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj index 6d133900cd80..c5769302e859 100644 --- a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj +++ b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj @@ -10,6 +10,8 @@ Issue: https://github.com/dotnet/runtime/issues/37117 --> true + + true diff --git a/src/tests/profiler/unittest/metadatagetdispenser.csproj b/src/tests/profiler/unittest/metadatagetdispenser.csproj index 7a525ce745d2..fc9c21e7144d 100644 --- a/src/tests/profiler/unittest/metadatagetdispenser.csproj +++ b/src/tests/profiler/unittest/metadatagetdispenser.csproj @@ -6,6 +6,8 @@ true 0 true + + true diff --git a/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj b/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj index 82a0cd70a890..3d6ed00a9686 100644 --- a/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj +++ b/src/tests/tracing/eventpipe/eventsourceerror/eventsourceerror.csproj @@ -4,7 +4,7 @@ exe BuildAndRun true - + true true 0 diff --git a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj index 676d812f12ea..6d27a4fd2b7e 100644 --- a/src/tests/tracing/eventpipe/gcdump/gcdump.csproj +++ b/src/tests/tracing/eventpipe/gcdump/gcdump.csproj @@ -6,7 +6,7 @@ true true 0 - + true From ab83c882421ac94063730104570f297192519f3f Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Fri, 31 Jul 2020 20:00:08 -0700 Subject: [PATCH 190/755] Avoid lock contention in MemberInfoCache (#40116) --- .../src/System/RuntimeType.CoreCLR.cs | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) 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 a883bad112b3..0dbfbf7f0c61 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 @@ -234,6 +234,48 @@ internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache) internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType) { + // First, see if we've already cached an RuntimeMethodInfo or + // RuntimeConstructorInfo that corresponds to this member. Since another + // thread could be updating the backing store at the same time it's + // possible that the check below will result in a false negative. That's + // ok; we'll handle any concurrency issues in the later call to Insert. + + T?[]? allMembersLocal = m_allMembers; + if (allMembersLocal != null) + { + // if not a Method or a Constructor, fall through + if (cacheType == CacheType.Method) + { + foreach (T? candidate in allMembersLocal) + { + if (candidate is null) + { + break; // end of list; stop iteration and fall through to slower path + } + + if (candidate is RuntimeMethodInfo candidateRMI && candidateRMI.MethodHandle.Value == method.Value) + { + return candidateRMI; // match! + } + } + } + else if (cacheType == CacheType.Constructor) + { + foreach (T? candidate in allMembersLocal) + { + if (candidate is null) + { + break; // end of list; stop iteration and fall through to slower path + } + + if (candidate is RuntimeConstructorInfo candidateRCI && candidateRCI.MethodHandle.Value == method.Value) + { + return candidateRCI; // match! + } + } + } + } + T[] list = null!; MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method); bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; @@ -264,6 +306,29 @@ internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInte internal FieldInfo AddField(RuntimeFieldHandleInternal field) { + // First, see if we've already cached an RtFieldInfo that corresponds + // to this field. Since another thread could be updating the backing + // store at the same time it's possible that the check below will + // result in a false negative. That's ok; we'll handle any concurrency + // issues in the later call to Insert. + + T?[]? allMembersLocal = m_allMembers; + if (allMembersLocal != null) + { + foreach (T? candidate in allMembersLocal) + { + if (candidate is null) + { + break; // end of list; stop iteration and fall through to slower path + } + + if (candidate is RtFieldInfo candidateRtFI && candidateRtFI.GetFieldHandle() == field.Value) + { + return candidateRtFI; // match! + } + } + } + // create the runtime field info FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field); bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; @@ -507,7 +572,7 @@ private void MergeWithGlobalList(T[] list) } Debug.Assert(cachedMembers![freeSlotIndex] == null); - cachedMembers[freeSlotIndex] = newMemberInfo; + Volatile.Write(ref cachedMembers[freeSlotIndex], newMemberInfo); // value may be read outside of lock freeSlotIndex++; } } From b44a8d9b642198f25e0058bbb0e243ef76cfcb4f Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 31 Jul 2020 20:47:39 -0700 Subject: [PATCH 191/755] Contract violation in generating exception is benign, it can be ignored (#40220) --- src/coreclr/src/vm/class.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 7a243ca786b1..d56cb02b68d2 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -1228,10 +1228,12 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); SString strInvalidMethodName; - TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); - SString strParentMethodName; - TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); + { + CONTRACT_VIOLATION(LoadsTypeViolation); + TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); + TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); + } COMPlusThrow( kTypeLoadException, From 06edcffc7bcfab7863b600996b8888b6f1d6e37c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2020 20:48:35 -0700 Subject: [PATCH 192/755] [master] Update dependencies from Microsoft/vstest dotnet/xharness (#40198) * Update dependencies from https://github.com/microsoft/vstest build 20200730-03 Microsoft.NET.Test.Sdk From Version 16.8.0-preview-20200730-02 -> To Version 16.8.0-preview-20200730-03 * Update dependencies from https://github.com/dotnet/xharness build 20200730.2 Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 1.0.0-prerelease.20380.1 -> To Version 1.0.0-prerelease.20380.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 10 +++++----- eng/Versions.props | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5458447cdad3..2fa037a5ef67 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -86,7 +86,7 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest ddb755f58160c0e7fab50964d665be1bf47ff579 @@ -186,13 +186,13 @@ https://github.com/mono/linker 7c9b806037e88df7eb40a8151808730133676668 - + https://github.com/dotnet/xharness - d5f2dfa6abcab999bd65fb95ac694d4109df405c + 277bae290e5be657e4b8f2a5b77ab764e5cf9ccc - + https://github.com/dotnet/xharness - d5f2dfa6abcab999bd65fb95ac694d4109df405c + 277bae290e5be657e4b8f2a5b77ab764e5cf9ccc diff --git a/eng/Versions.props b/eng/Versions.props index 35d095e73dc8..6f76c6d3c6b0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -133,9 +133,9 @@ 4.9.4 4.9.4 - 16.8.0-preview-20200730-02 - 1.0.0-prerelease.20380.1 - 1.0.0-prerelease.20380.1 + 16.8.0-preview-20200730-03 + 1.0.0-prerelease.20380.2 + 1.0.0-prerelease.20380.2 2.4.1 2.4.2 1.3.0 From 1625943a103e9de806842b3d006d48ca16280e3d Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 31 Jul 2020 23:11:22 -0500 Subject: [PATCH 193/755] Remove unused bindings (#40229) --- src/mono/wasm/runtime-test.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index cc01a77701b4..8f4ced5581fc 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -164,7 +164,6 @@ var Module = { onRuntimeInitialized: function () { // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. - var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']); for (var variable in setenv) { MONO.mono_wasm_setenv (variable, setenv [variable]); } @@ -229,16 +228,12 @@ var App = { init: function () { var assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string']) - var find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']) - var find_method = Module.cwrap ('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']) var runtime_invoke = Module.cwrap ('mono_wasm_invoke_method', 'number', ['number', 'number', 'number', 'number']); var string_from_js = Module.cwrap ('mono_wasm_string_from_js', 'number', ['string']); var assembly_get_entry_point = Module.cwrap ('mono_wasm_assembly_get_entry_point', 'number', ['number']); var string_get_utf8 = Module.cwrap ('mono_wasm_string_get_utf8', 'string', ['number']); var string_array_new = Module.cwrap ('mono_wasm_string_array_new', 'number', ['number']); var obj_array_set = Module.cwrap ('mono_wasm_obj_array_set', 'void', ['number', 'number', 'number']); - var exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']); - var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']); var wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); var unbox_int = Module.cwrap ('mono_unbox_int', 'number', ['number']); From 6822ba3308b2ceb3eb8a88c8e02f460e171bc04a Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Sat, 1 Aug 2020 00:42:56 -0700 Subject: [PATCH 194/755] Make dotnet-Microsoft.XmlSerializer.Generator run on latest framework (#40216) --- .../dotnet-Microsoft.XmlSerializer.Generator.runtimeconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/pkg/build/dotnet-Microsoft.XmlSerializer.Generator.runtimeconfig.json b/src/libraries/Microsoft.XmlSerializer.Generator/pkg/build/dotnet-Microsoft.XmlSerializer.Generator.runtimeconfig.json index a8e41025fa98..5978b833d31c 100644 --- a/src/libraries/Microsoft.XmlSerializer.Generator/pkg/build/dotnet-Microsoft.XmlSerializer.Generator.runtimeconfig.json +++ b/src/libraries/Microsoft.XmlSerializer.Generator/pkg/build/dotnet-Microsoft.XmlSerializer.Generator.runtimeconfig.json @@ -5,6 +5,6 @@ "name": "Microsoft.NETCore.App", "version": "2.0.0" }, - "rollForward": "Major" + "rollForward": "LatestMajor" } } \ No newline at end of file From 5de3b209853637b63546460e4a67cc82c4ac75fd Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Sat, 1 Aug 2020 11:55:37 +0200 Subject: [PATCH 195/755] Increase Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ConnectionRemovedAndNewCreated test timeouts (#40209) --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index c8d6078a1381..f86bd58bd75b 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -2131,7 +2131,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ const int MaxConcurrentStreams = 2; using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); using SocketsHttpHandler handler = CreateHandler(); - handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(10); + handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(20); using (HttpClient client = CreateHttpClient(handler)) { server.AllowMultipleConnections = true; @@ -2142,7 +2142,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ Assert.Equal(MaxConcurrentStreams, acceptedStreamIds.Count); List> connection1SendTasks = new List>(); - Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 15).ConfigureAwait(false); + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 30).ConfigureAwait(false); AcquireAllStreamSlots(server, client, connection1SendTasks, MaxConcurrentStreams); int handledRequests1 = (await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)).Count; @@ -2168,7 +2168,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ Assert.True(connection1.IsInvalid); Assert.False(connection0.IsInvalid); - Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 5, expectedWarpUpTasks:2).ConfigureAwait(false); + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 7, expectedWarpUpTasks:2).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); From 58fa9fe4def4cc3c553f5f64ba2df4f33ca3f347 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Sat, 1 Aug 2020 17:59:07 +0300 Subject: [PATCH 196/755] Remove Format wrappers around interpolated strings (#40231) --- .../managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs | 5 +---- .../managed/Microsoft.NET.HostModel/Bundle/FileSpec.cs | 5 +---- .../managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs | 2 +- .../tests/Directory/GetFileSystemEntries_str.cs | 2 +- .../tests/CertTests.cs | 4 ++-- .../Serialization/TestClasses/TestClasses.Constructor.cs | 2 +- .../BuildTools.Publish/CloudTestTasks/ListAzureBlobs.cs | 2 +- 7 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs index 2a37afcecf8e..237a2a550fb1 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs @@ -41,10 +41,7 @@ public void Write(BinaryWriter writer) writer.Write(RelativePath); } - public override string ToString() - { - return string.Format($"{RelativePath} [{Type}] @{Offset} Sz={Size}"); - } + public override string ToString() => $"{RelativePath} [{Type}] @{Offset} Sz={Size}"; } } diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileSpec.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileSpec.cs index ca6d0d872f17..e245b33a0c61 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileSpec.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileSpec.cs @@ -31,10 +31,7 @@ public bool IsValid() !string.IsNullOrWhiteSpace(BundleRelativePath); } - public override string ToString() - { - return string.Format($"SourcePath: {SourcePath}, RelativePath: {BundleRelativePath} {(Excluded ? "[Excluded]" : "")}"); - } + public override string ToString() => $"SourcePath: {SourcePath}, RelativePath: {BundleRelativePath} {(Excluded ? "[Excluded]" : "")}"; } } diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs index d1797b75f5d8..5db826b027c7 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs @@ -63,7 +63,7 @@ public string GetAssemblyName(string hostName) public override string ToString() { string os = IsWindows ? "win" : IsLinux ? "linux" : "osx"; - return string.Format($"OS: {os} FrameworkVersion: {FrameworkVersion}"); + return $"OS: {os} FrameworkVersion: {FrameworkVersion}"; } static OSPlatform HostOS => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? OSPlatform.Linux : diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs index a9fbc242833c..642439142ac0 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs @@ -208,7 +208,7 @@ public void InvalidPath_Core() { foreach (char invalid in Path.GetInvalidFileNameChars()) { - string badPath = string.Format($"{TestDirectory}{Path.DirectorySeparatorChar}te{invalid}st"); + string badPath = $"{TestDirectory}{Path.DirectorySeparatorChar}te{invalid}st"; switch (invalid) { case '/': diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CertTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CertTests.cs index e16a28f9be7a..cdf719833f7f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CertTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CertTests.cs @@ -150,12 +150,12 @@ private void LogVerifyErrors(X509Certificate2 cert, string testName) { foreach (X509ChainStatus chainStatus in chain.ChainStatus) { - _log.WriteLine(string.Format($"X509Certificate2.Verify error: {testName}, {chainStatus.Status}, {chainStatus.StatusInformation}")); + _log.WriteLine($"X509Certificate2.Verify error: {testName}, {chainStatus.Status}, {chainStatus.StatusInformation}"); } } else { - _log.WriteLine(string.Format($"X509Certificate2.Verify expected error; received none: {testName}")); + _log.WriteLine($"X509Certificate2.Verify expected error; received none: {testName}"); } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs index 070aaacb68a7..8dcd74e79dfb 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs @@ -2299,7 +2299,7 @@ public string FormattedDate var startDateString = string.Format("{0:g}", StartDate.Value); var endDateString = string.Format("{0:g}", EndDate.Value); - return string.Format($"From {startDateString} to {endDateString}"); + return $"From {startDateString} to {endDateString}"; } } } diff --git a/tools-local/tasks/installer.tasks/BuildTools.Publish/CloudTestTasks/ListAzureBlobs.cs b/tools-local/tasks/installer.tasks/BuildTools.Publish/CloudTestTasks/ListAzureBlobs.cs index fb68d7bdfea4..2376d5638597 100644 --- a/tools-local/tasks/installer.tasks/BuildTools.Publish/CloudTestTasks/ListAzureBlobs.cs +++ b/tools-local/tasks/installer.tasks/BuildTools.Publish/CloudTestTasks/ListAzureBlobs.cs @@ -100,7 +100,7 @@ public static async Task> ListBlobs(TaskLoggingHelper Log, string A } while (!string.IsNullOrEmpty(nextMarker)) { - urlListBlobs = string.Format($"https://{AccountName}.blob.core.windows.net/{ContainerName}?restype=container&comp=list&marker={nextMarker}"); + urlListBlobs = $"https://{AccountName}.blob.core.windows.net/{ContainerName}?restype=container&comp=list&marker={nextMarker}"; if (!string.IsNullOrWhiteSpace(FilterBlobNames)) { urlListBlobs += $"&prefix={FilterBlobNames}"; From de1f8d847ee3ac635affa5296b163691ef8612f6 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Sat, 1 Aug 2020 12:58:08 -0700 Subject: [PATCH 197/755] Fix for unsafe CSE of Structs (#40164) * Fix for unsafe CSE of Structs - Assign a unique value number when reading a struct field as we don't know the size of the read - Modify the Jit Dump for CSE - No Asm diffs in the Frameworks - Added new test Runtime_38920.cs * Change tabs to spaces --- src/coreclr/src/jit/optcse.cpp | 10 +- src/coreclr/src/jit/valuenum.cpp | 25 ++-- .../JitBlue/Runtime_38920/Runtime_38920.cs | 121 ++++++++++++++++++ .../Runtime_38920/Runtime_38920.csproj | 11 ++ 4 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.csproj diff --git a/src/coreclr/src/jit/optcse.cpp b/src/coreclr/src/jit/optcse.cpp index 5f89a2e96632..06339353826b 100644 --- a/src/coreclr/src/jit/optcse.cpp +++ b/src/coreclr/src/jit/optcse.cpp @@ -2526,8 +2526,9 @@ class CSE_Heuristic #ifdef DEBUG if (m_pCompiler->verbose) { - printf("Moderate CSE Promotion (CSE is live across a call) (%u >= %u)\n", cseRefCnt, - moderateRefCnt); + printf("Moderate CSE Promotion (%s) (%u >= %u)\n", + candidate->LiveAcrossCall() ? "CSE is live across a call" : "not enregisterable", + cseRefCnt, moderateRefCnt); } #endif cse_def_cost = 2; @@ -2558,8 +2559,9 @@ class CSE_Heuristic #ifdef DEBUG if (m_pCompiler->verbose) { - printf("Conservative CSE Promotion (CSE never live at call) (%u < %u)\n", cseRefCnt, - moderateRefCnt); + printf("Conservative CSE Promotion (%s) (%u < %u)\n", + candidate->LiveAcrossCall() ? "CSE is live across a call" : "not enregisterable", + cseRefCnt, moderateRefCnt); } #endif cse_def_cost = 2; diff --git a/src/coreclr/src/jit/valuenum.cpp b/src/coreclr/src/jit/valuenum.cpp index f436216064ae..51e23701a77d 100644 --- a/src/coreclr/src/jit/valuenum.cpp +++ b/src/coreclr/src/jit/valuenum.cpp @@ -4137,14 +4137,23 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree, ValueNum Compiler::fgValueNumberByrefExposedLoad(var_types type, ValueNum pointerVN) { - ValueNum memoryVN = fgCurMemoryVN[ByrefExposed]; - // The memoization for VNFunc applications does not factor in the result type, so - // VNF_ByrefExposedLoad takes the loaded type as an explicit parameter. - ValueNum typeVN = vnStore->VNForIntCon(type); - ValueNum loadVN = - vnStore->VNForFunc(type, VNF_ByrefExposedLoad, typeVN, vnStore->VNNormalValue(pointerVN), memoryVN); - - return loadVN; + if (type == TYP_STRUCT) + { + // We can't assign a value number for a read of a struct as we can't determine + // how many bytes will be read by this load, so return a new unique value number + // + return vnStore->VNForExpr(compCurBB, TYP_STRUCT); + } + else + { + ValueNum memoryVN = fgCurMemoryVN[ByrefExposed]; + // The memoization for VNFunc applications does not factor in the result type, so + // VNF_ByrefExposedLoad takes the loaded type as an explicit parameter. + ValueNum typeVN = vnStore->VNForIntCon(type); + ValueNum loadVN = + vnStore->VNForFunc(type, VNF_ByrefExposedLoad, typeVN, vnStore->VNNormalValue(pointerVN), memoryVN); + return loadVN; + } } var_types ValueNumStore::TypeOfVN(ValueNum vn) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.cs b/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.cs new file mode 100644 index 000000000000..7a91e70711e4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.cs @@ -0,0 +1,121 @@ +// 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.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +class TestStructs +{ + static int exitStatus = 100; + + struct StructA + { + public int a; + } + + // Make both structs with >4 fields to prevent struct promoting and force byref passing. + struct CastFromStruct20 + { + int z; + public StructA structField; + public int b; + public int c; + int q; + } + + struct CastToStruct8 + { + bool a; + bool b; + bool c; + bool d; + public int e; // Overlaps with b in CastFromStruct + } + + struct CastToStruct12 + { + bool a; + bool b; + bool c; + bool d; + public int e; // Overlaps with b in CastFromStruct + public int f; // Overlaps with c in CastFromStruct + } + + + // our src local var has to be an implicit byref, otherwise we won't try to recover struct handle from it. + [MethodImpl(MethodImplOptions.NoInlining)] + static void UnsafeCastFromAPrimitiveStructFieldToStruct(CastFromStruct20 impByRefStruct20, int b, int c) + { + CastToStruct8 to8 = new CastToStruct8(); + CastToStruct12 to12 = new CastToStruct12(); + + // possible incorrect CSE def of impByRefStruct20.structField + // + to8 = Unsafe.As(ref impByRefStruct20.structField); + + for (int i =0; i<10; i++) + { + // possible incorrect CSE use of impByRefStruct20.structField + // + to12 = Unsafe.As(ref impByRefStruct20.structField); + } + + // Check that we modified to8.e correctly + if (to8.e != b) + { + Console.WriteLine("to8.e has the wrong value: " + to8.e + " expected " + b); + exitStatus = -1; + } + + // Check that we modified to12.e correctly + if (to12.e != b) + { + Console.WriteLine("to12.e has the wrong value: " + to12.e + " expected " + b); + exitStatus = -1; + } + + // Check that we modified to12.f correctly + if (to12.f != c) + { + Console.WriteLine("to12.f has the wrong value: " + to12.f + " expected " + c); + exitStatus = -1; + } + } + + public static int Main() + { + int b = 1; + int c = 2; + + CastFromStruct20 s = new CastFromStruct20(); + + s.b = b; + s.c = c; + UnsafeCastFromAPrimitiveStructFieldToStruct(s, b, c); + + s.b = ++b; // 2 + s.c = ++c; // 3 + UnsafeCastFromAPrimitiveStructFieldToStruct(s, b, c); + + b = b * b; + c = c * c; + s.b = b; // 4 + s.c = c; // 9 + UnsafeCastFromAPrimitiveStructFieldToStruct(s, b, c); + + if (exitStatus == 100) + { + Console.WriteLine("Test Passed"); + } + else + { + Console.WriteLine("FAILED"); + } + + return exitStatus; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.csproj new file mode 100644 index 000000000000..e5292cce5876 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_38920/Runtime_38920.csproj @@ -0,0 +1,11 @@ + + + Exe + None + True + True + + + + + From 5f51b774e284565df5e57d2abb0fd91e4c99899b Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Sun, 2 Aug 2020 03:07:16 -0500 Subject: [PATCH 198/755] [browser] Remove ActiveIssue from BinaryPrimitives_StaticWithSpanArgument (#40235) --- src/libraries/System.Memory/tests/Span/Reflection.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Memory/tests/Span/Reflection.cs b/src/libraries/System.Memory/tests/Span/Reflection.cs index 3da4f54013fe..dbdcc7dbdcd3 100644 --- a/src/libraries/System.Memory/tests/Span/Reflection.cs +++ b/src/libraries/System.Memory/tests/Span/Reflection.cs @@ -40,7 +40,6 @@ public static void MemoryExtensions_StaticWithSpanArguments() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39311", TestPlatforms.Browser)] public static void BinaryPrimitives_StaticWithSpanArgument() { Type type = typeof(BinaryPrimitives); From 8abf45309068b73135bd843a2a49fe457e25343e Mon Sep 17 00:00:00 2001 From: Joni Date: Sun, 2 Aug 2020 22:09:35 +0900 Subject: [PATCH 199/755] Fix typo in comment in StringBuilderCache.cs (#40238) --- src/libraries/Common/src/System/Text/StringBuilderCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Text/StringBuilderCache.cs b/src/libraries/Common/src/System/Text/StringBuilderCache.cs index 5e0ca8c6bfb7..b6041ac11e56 100644 --- a/src/libraries/Common/src/System/Text/StringBuilderCache.cs +++ b/src/libraries/Common/src/System/Text/StringBuilderCache.cs @@ -8,7 +8,7 @@ namespace System.Text internal static class StringBuilderCache { // The value 360 was chosen in discussion with performance experts as a compromise between using - // as litle memory per thread as possible and still covering a large part of short-lived + // as little memory per thread as possible and still covering a large part of short-lived // StringBuilder creations on the startup path of VS designers. internal const int MaxBuilderSize = 360; private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity From 1e7aa6f0f0b37244fc82d66e8e89c7232f4c6dc3 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sun, 2 Aug 2020 09:43:05 -0400 Subject: [PATCH 200/755] =?UTF-8?q?[runtime]=20Add=20a=20configure=20worka?= =?UTF-8?q?round=20for=20apple=20silicon=20+=20older=20config=E2=80=A6=20(?= =?UTF-8?q?#40184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ….guess versions. Co-authored-by: vargaz --- src/mono/configure.ac | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 6c114a3765bc..1c8d9ccd4415 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -408,6 +408,13 @@ case "$host" in host_sunos=yes ;; *-*-darwin*) + # Temporary workaround for Apple Silicon + # config.guess returns arm-apple-darwin20.0.0 + if test $ac_cv_host = arm-apple-darwin20.0.0 -o $ac_cv_target = arm-apple-darwin20.0.0; then + echo "You are running on Apple Silicon, but using an old config.guess, invoke configure like this:" + echo "Run configure using ./configure --host=aarch64-apple-darwin20.0.0 --target=aarch64-apple-darwin20.0.0" + exit 1 + fi parallel_mark="Disabled_Currently_Hangs_On_MacOSX" host_darwin=yes target_mach=yes From ca70fc9903e68d36ee16f7d10a9a491251ea8f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Sun, 2 Aug 2020 18:13:00 +0200 Subject: [PATCH 201/755] Reenable ExceptionDispatchInfo.SetCurrentStackTrace test on WASM (#40241) It was fixed by https://github.com/dotnet/runtime/pull/40031. --- .../Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs b/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs index c3242a0197cf..c2bb2bdc48cd 100644 --- a/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs @@ -49,7 +49,6 @@ public static void SetCurrentStackTrace_Invalid_Throws() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39341", TestPlatforms.Browser)] public static void SetCurrentStackTrace_IncludedInExceptionStackTrace() { Exception e; From 4d41f13e03091bb4251448944936de5740a4dcd4 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Sun, 2 Aug 2020 20:45:52 +0300 Subject: [PATCH 202/755] Remove netstandard packaging infra (#40239) --- eng/Subsets.props | 4 - eng/Versions.props | 5 +- src/installer/pkg/projects/descriptions.json | 5 - .../netstandard/Directory.Build.props | 8 -- .../netstandard/netstandardRIDs.props | 6 -- .../netstandard/pkg/Directory.Build.props | 28 ------ .../pkg/NETStandard.Library.Ref.pkgproj | 13 --- .../netstandard/pkg/PackageOverrides.txt | 95 ------------------- .../netstandard/src/netstandard.depproj | 25 ----- .../NETStandardTests.cs | 43 --------- 10 files changed, 1 insertion(+), 231 deletions(-) delete mode 100644 src/installer/pkg/projects/netstandard/Directory.Build.props delete mode 100644 src/installer/pkg/projects/netstandard/netstandardRIDs.props delete mode 100644 src/installer/pkg/projects/netstandard/pkg/Directory.Build.props delete mode 100644 src/installer/pkg/projects/netstandard/pkg/NETStandard.Library.Ref.pkgproj delete mode 100644 src/installer/pkg/projects/netstandard/pkg/PackageOverrides.txt delete mode 100644 src/installer/pkg/projects/netstandard/src/netstandard.depproj delete mode 100644 src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETStandardTests.cs diff --git a/eng/Subsets.props b/eng/Subsets.props index ba103417c838..2c52c183a2ce 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -215,15 +215,11 @@ - - - - diff --git a/eng/Versions.props b/eng/Versions.props index 6f76c6d3c6b0..fd0c5441fa07 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -46,9 +46,6 @@ - - - @@ -176,7 +173,7 @@ Microsoft.NETCore.Runtime.ICU.Transport $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', '$(MicrosoftPrivateIntellisensePackage)', '$(MicrosoftPrivateIntellisenseVersion)', 'IntellisenseFiles', 'net')) diff --git a/src/installer/pkg/projects/descriptions.json b/src/installer/pkg/projects/descriptions.json index b3e4471c47c7..4b4ae7f6d83b 100644 --- a/src/installer/pkg/projects/descriptions.json +++ b/src/installer/pkg/projects/descriptions.json @@ -48,10 +48,5 @@ "Name": "Microsoft.NETCore.App.Ref", "Description": "A set of .NET APIs that are included in the default .NET application model. Contains reference assemblies, documentation, and other design-time assets.", "CommonTypes": [ ] - }, - { - "Name": "NETStandard.Library.Ref", - "Description": "A set of standard .NET APIs that are prescribed to be used and supported together. Contains reference assemblies, documentation, and other design-time assets.", - "CommonTypes": [ ] } ] diff --git a/src/installer/pkg/projects/netstandard/Directory.Build.props b/src/installer/pkg/projects/netstandard/Directory.Build.props deleted file mode 100644 index 1597af77869d..000000000000 --- a/src/installer/pkg/projects/netstandard/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - $(MSBuildThisFileDirectory)netstandardRIDs.props - - - - - diff --git a/src/installer/pkg/projects/netstandard/netstandardRIDs.props b/src/installer/pkg/projects/netstandard/netstandardRIDs.props deleted file mode 100644 index 0b0cbcde167d..000000000000 --- a/src/installer/pkg/projects/netstandard/netstandardRIDs.props +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/installer/pkg/projects/netstandard/pkg/Directory.Build.props b/src/installer/pkg/projects/netstandard/pkg/Directory.Build.props deleted file mode 100644 index 2826aeac134c..000000000000 --- a/src/installer/pkg/projects/netstandard/pkg/Directory.Build.props +++ /dev/null @@ -1,28 +0,0 @@ - - - true - netstandard - Microsoft .NET Standard - - - - - - 2.1 - $(NETStandardPatchVersion) - - .NET Standard 2.1 - .NETStandard - 2.1 - NETStandard.Library - - NetStandard - - - - - - RuntimeIdentifier=$(PackageTargetRuntime) - - - diff --git a/src/installer/pkg/projects/netstandard/pkg/NETStandard.Library.Ref.pkgproj b/src/installer/pkg/projects/netstandard/pkg/NETStandard.Library.Ref.pkgproj deleted file mode 100644 index b9391580563b..000000000000 --- a/src/installer/pkg/projects/netstandard/pkg/NETStandard.Library.Ref.pkgproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/installer/pkg/projects/netstandard/pkg/PackageOverrides.txt b/src/installer/pkg/projects/netstandard/pkg/PackageOverrides.txt deleted file mode 100644 index 8aa32ade39a8..000000000000 --- a/src/installer/pkg/projects/netstandard/pkg/PackageOverrides.txt +++ /dev/null @@ -1,95 +0,0 @@ -Microsoft.Win32.Primitives|4.3.0 -System.AppContext|4.3.0 -System.Collections|4.3.0 -System.Collections.Concurrent|4.3.0 -System.Collections.Immutable|1.4.0 -System.Collections.NonGeneric|4.3.0 -System.Collections.Specialized|4.3.0 -System.ComponentModel|4.3.0 -System.ComponentModel.EventBasedAsync|4.3.0 -System.ComponentModel.Primitives|4.3.0 -System.ComponentModel.TypeConverter|4.3.0 -System.Console|4.3.0 -System.Data.Common|4.3.0 -System.Diagnostics.Contracts|4.3.0 -System.Diagnostics.Debug|4.3.0 -System.Diagnostics.FileVersionInfo|4.3.0 -System.Diagnostics.Process|4.3.0 -System.Diagnostics.StackTrace|4.3.0 -System.Diagnostics.TextWriterTraceListener|4.3.0 -System.Diagnostics.Tools|4.3.0 -System.Diagnostics.TraceSource|4.3.0 -System.Diagnostics.Tracing|4.3.0 -System.Dynamic.Runtime|4.3.0 -System.Globalization|4.3.0 -System.Globalization.Calendars|4.3.0 -System.Globalization.Extensions|4.3.0 -System.IO|4.3.0 -System.IO.Compression|4.3.0 -System.IO.Compression.ZipFile|4.3.0 -System.IO.FileSystem|4.3.0 -System.IO.FileSystem.DriveInfo|4.3.0 -System.IO.FileSystem.Primitives|4.3.0 -System.IO.FileSystem.Watcher|4.3.0 -System.IO.IsolatedStorage|4.3.0 -System.IO.MemoryMappedFiles|4.3.0 -System.IO.Pipes|4.3.0 -System.IO.UnmanagedMemoryStream|4.3.0 -System.Linq|4.3.0 -System.Linq.Expressions|4.3.0 -System.Linq.Queryable|4.3.0 -System.Net.Http|4.3.0 -System.Net.NameResolution|4.3.0 -System.Net.Primitives|4.3.0 -System.Net.Requests|4.3.0 -System.Net.Security|4.3.0 -System.Net.Sockets|4.3.0 -System.Net.WebHeaderCollection|4.3.0 -System.ObjectModel|4.3.0 -System.Private.DataContractSerialization|4.3.0 -System.Reflection|4.3.0 -System.Reflection.Emit|4.3.0 -System.Reflection.Emit.ILGeneration|4.3.0 -System.Reflection.Emit.Lightweight|4.3.0 -System.Reflection.Extensions|4.3.0 -System.Reflection.Primitives|4.3.0 -System.Reflection.TypeExtensions|4.3.0 -System.Resources.ResourceManager|4.3.0 -System.Runtime|4.3.0 -System.Runtime.Extensions|4.3.0 -System.Runtime.Handles|4.3.0 -System.Runtime.InteropServices|4.3.0 -System.Runtime.InteropServices.RuntimeInformation|4.3.0 -System.Runtime.Loader|4.3.0 -System.Runtime.Numerics|4.3.0 -System.Runtime.Serialization.Formatters|4.3.0 -System.Runtime.Serialization.Json|4.3.0 -System.Runtime.Serialization.Primitives|4.3.0 -System.Security.AccessControl|4.4.0 -System.Security.Claims|4.3.0 -System.Security.Cryptography.Algorithms|4.3.0 -System.Security.Cryptography.Csp|4.3.0 -System.Security.Cryptography.Encoding|4.3.0 -System.Security.Cryptography.Primitives|4.3.0 -System.Security.Cryptography.X509Certificates|4.3.0 -System.Security.Cryptography.Xml|4.4.0 -System.Security.Principal|4.3.0 -System.Security.Principal.Windows|4.4.0 -System.Text.Encoding|4.3.0 -System.Text.Encoding.Extensions|4.3.0 -System.Text.RegularExpressions|4.3.0 -System.Threading|4.3.0 -System.Threading.Overlapped|4.3.0 -System.Threading.Tasks|4.3.0 -System.Threading.Tasks.Extensions|4.3.0 -System.Threading.Tasks.Parallel|4.3.0 -System.Threading.Thread|4.3.0 -System.Threading.ThreadPool|4.3.0 -System.Threading.Timer|4.3.0 -System.ValueTuple|4.3.0 -System.Xml.ReaderWriter|4.3.0 -System.Xml.XDocument|4.3.0 -System.Xml.XmlDocument|4.3.0 -System.Xml.XmlSerializer|4.3.0 -System.Xml.XPath|4.3.0 -System.Xml.XPath.XDocument|4.3.0 diff --git a/src/installer/pkg/projects/netstandard/src/netstandard.depproj b/src/installer/pkg/projects/netstandard/src/netstandard.depproj deleted file mode 100644 index ec841c9a3df9..000000000000 --- a/src/installer/pkg/projects/netstandard/src/netstandard.depproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - netstandard2.1 - - - - - - - - - - - - - - diff --git a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETStandardTests.cs b/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETStandardTests.cs deleted file mode 100644 index 0c5c4a29b97e..000000000000 --- a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETStandardTests.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.DotNet.CoreSetup.Test; -using Xunit; - -namespace Microsoft.DotNet.CoreSetup.Packaging.Tests -{ - public class NETStandardTests - { - private readonly RepoDirectoriesProvider dirs = new RepoDirectoriesProvider(); - - [Fact] - public void NETStandardTargetingPackIsValid() - { - using (var tester = NuGetArtifactTester.OpenOrNull( - dirs, - "NETStandard.Library.Ref")) - { - // Allow no targeting pack in case this is a servicing build. - // This condition should be tightened: https://github.com/dotnet/core-setup/issues/8830 - if (tester == null) - { - return; - } - - tester.HasOnlyTheseDataFiles( - "data/FrameworkList.xml", - "data/PackageOverrides.txt"); - - tester.IsTargetingPack(); - - // Most artifacts in the repo use the global Major.Minor, this package doesn't. Test - // this to make sure infra doesn't regress and cause netstandard to lose its special - // 2.1 version. The versioning difference is because netstandard targeting pack - // creation doesn't actually belong in Core-Setup: https://github.com/dotnet/standard/issues/1209 - Assert.Equal( - (2, 1), - (tester.PackageVersion.Major, tester.PackageVersion.Minor)); - } - } - } -} From ce80850a32f2ea1f8285c7682ab44c2bc3732056 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Sun, 2 Aug 2020 13:00:21 -0500 Subject: [PATCH 203/755] Fix ILLink warnings for removed attributes when Debugger.IsSupported is false (#40048) When Debugger.IsSupported feature switch is false, we trim unnecessary attributes in the code - specifically attributes like CompilerGeneratedAttribute and StackTraceHiddenAttribute. However, we still have code accessing these attributes, which causes the ILLinker to warn that it is removing the attributes, but code still uses them. To fix this, remove these attributes from being trimmed when Debugger.IsSupported is false. Instead these attributes will be preserved always so things like "is anonymous type" checks and stack trace tostring will behave correctly. Fix #39707 --- .../src/ILLink/ILLink.LinkAttributes.Shared.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml index d864e9163005..1fc80202571c 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml @@ -29,13 +29,5 @@ - - - - - - - - From a5159b1a8840632ad34cf59c5aaf77040cb6ceda Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Sun, 2 Aug 2020 13:01:19 -0500 Subject: [PATCH 204/755] Annotate DependencyInjection to make it linker friendly (#40227) * Annotate DependencyInjection to make it linker friendly Fix #39745 --- eng/testing/linker/project.csproj.template | 4 + eng/testing/linker/trimmingTests.targets | 12 ++- .../ActivatorUtilities/ActivatorUtilities.cs | 38 +++++---- .../ParameterDefaultValue.cs | 7 +- .../ServiceCollectionDescriptorExtensions.cs | 25 +++--- ...ns.DependencyInjection.Abstractions.csproj | 3 + .../src/ServiceCollectionServiceExtensions.cs | 29 ++++--- .../src/ServiceDescriptor.cs | 29 +++++-- ...soft.Extensions.DependencyInjection.csproj | 6 ++ .../src/ServiceLookup/CallSiteFactory.cs | 11 +-- .../TrimmingTests/ActivatorUtilitiesTests.cs | 38 +++++++++ ...ons.DependencyInjection.TrimmingTests.proj | 14 ++++ .../ServiceCollectionExtensionsTests.cs | 83 +++++++++++++++++++ .../UnconditionalSuppressMessageAttribute.cs | 7 +- 14 files changed, 245 insertions(+), 61 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index ef63096e8019..64a3e93967a3 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -9,6 +9,10 @@ <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) + + {AdditionalProjectReferences} + + diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index 3729bd306bca..6d89002d9e0c 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -57,6 +57,15 @@ <_projectSourceFile>%(TestConsoleApps.ProjectCompileItems) + + <_additionalProjectReferenceTemp Include="$(AdditionalProjectReferences)" /> + <_additionalProjectReference Include="<ProjectReference Include="$(LibrariesProjectRoot)%(_additionalProjectReferenceTemp.Identity)\src\%(_additionalProjectReferenceTemp.Identity).csproj" SkipUseReferenceAssembly="true" />" /> + + + + <_additionalProjectReferencesString>@(_additionalProjectReference, '%0a') + + <_additionalProjectSourceFiles Include="%(TestConsoleApps.AdditionalSourceFiles)" /> @@ -69,7 +78,8 @@ .Replace('{TargetingPackDir}','$(MicrosoftNetCoreAppRefPackDir)') .Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)') .Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)') - .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)'))" + .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)') + .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)'))" Overwrite="true" /> diff --git a/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs b/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs index 7f5b6c3aa0a5..574fd893feba 100644 --- a/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs +++ b/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs @@ -40,7 +40,10 @@ static class ActivatorUtilities /// The type to activate /// Constructor arguments not provided by the . /// An activated object of type instanceType - public static object CreateInstance(IServiceProvider provider, Type instanceType, params object[] parameters) + public static object CreateInstance( + IServiceProvider provider, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, + params object[] parameters) { int bestLength = -1; bool seenPreferred = false; @@ -49,11 +52,9 @@ public static object CreateInstance(IServiceProvider provider, Type instanceType if (!instanceType.GetTypeInfo().IsAbstract) { - foreach (ConstructorInfo? constructor in instanceType - .GetTypeInfo() - .DeclaredConstructors) + foreach (ConstructorInfo? constructor in instanceType.GetConstructors()) { - if (!constructor.IsStatic && constructor.IsPublic) + if (!constructor.IsStatic) { var matcher = new ConstructorMatcher(constructor); bool isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false); @@ -104,7 +105,9 @@ public static object CreateInstance(IServiceProvider provider, Type instanceType /// A factory that will instantiate instanceType using an /// and an argument array containing objects matching the types defined in argumentTypes /// - public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentTypes) + public static ObjectFactory CreateFactory( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, + Type[] argumentTypes) { FindApplicableConstructor(instanceType, argumentTypes, out ConstructorInfo? constructor, out int?[]? parameterMap); @@ -126,19 +129,18 @@ public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentType /// The service provider used to resolve dependencies /// Constructor arguments not provided by the . /// An activated object of type T - public static T CreateInstance(IServiceProvider provider, params object[] parameters) + public static T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider, params object[] parameters) { return (T)CreateInstance(provider, typeof(T), parameters); } - /// /// Retrieve an instance of the given type from the service provider. If one is not found then instantiate it directly. /// /// The type of the service /// The service provider used to resolve dependencies /// The resolved service or created instance - public static T GetServiceOrCreateInstance(IServiceProvider provider) + public static T GetServiceOrCreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider) { return (T)GetServiceOrCreateInstance(provider, typeof(T)); } @@ -149,7 +151,9 @@ public static T GetServiceOrCreateInstance(IServiceProvider provider) /// The service provider /// The type of the service /// The resolved service or created instance - public static object GetServiceOrCreateInstance(IServiceProvider provider, Type type) + public static object GetServiceOrCreateInstance( + IServiceProvider provider, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { return provider.GetService(type) ?? CreateInstance(provider, type); } @@ -214,7 +218,7 @@ private static Expression BuildFactoryExpression( } private static void FindApplicableConstructor( - Type instanceType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, out ConstructorInfo matchingConstructor, out int?[] matchingParameterMap) @@ -235,14 +239,14 @@ private static void FindApplicableConstructor( // Tries to find constructor based on provided argument types private static bool TryFindMatchingConstructor( - Type instanceType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, [NotNullWhen(true)] ref ConstructorInfo? matchingConstructor, [NotNullWhen(true)] ref int?[]? parameterMap) { - foreach (ConstructorInfo? constructor in instanceType.GetTypeInfo().DeclaredConstructors) + foreach (ConstructorInfo? constructor in instanceType.GetConstructors()) { - if (constructor.IsStatic || !constructor.IsPublic) + if (constructor.IsStatic) { continue; } @@ -270,15 +274,15 @@ private static bool TryFindMatchingConstructor( // Tries to find constructor marked with ActivatorUtilitiesConstructorAttribute private static bool TryFindPreferredConstructor( - Type instanceType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, [NotNullWhen(true)] ref ConstructorInfo? matchingConstructor, [NotNullWhen(true)] ref int?[]? parameterMap) { bool seenPreferred = false; - foreach (ConstructorInfo? constructor in instanceType.GetTypeInfo().DeclaredConstructors) + foreach (ConstructorInfo? constructor in instanceType.GetConstructors()) { - if (constructor.IsStatic || !constructor.IsPublic) + if (constructor.IsStatic) { continue; } diff --git a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs index 03f1b26ec0e2..45e8a6aea1d0 100644 --- a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs +++ b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs @@ -4,6 +4,7 @@ #nullable enable using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace Microsoft.Extensions.Internal @@ -41,9 +42,13 @@ public static bool TryGetDefaultValue(ParameterInfo parameter, out object? defau // Workaround for https://github.com/dotnet/corefx/issues/11797 if (defaultValue == null && parameter.ParameterType.IsValueType) { - defaultValue = Activator.CreateInstance(parameter.ParameterType); + defaultValue = CreateValueType(parameter.ParameterType); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "CreateInstance is only called on a ValueType, which will always have a default constructor.")] + object? CreateValueType(Type t) => Activator.CreateInstance(t); + // Handle nullable enums if (defaultValue != null && parameter.ParameterType.IsGenericType && diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs index ad5be9396bf9..b1d8704fe0cb 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Microsoft.Extensions.DependencyInjection.Extensions @@ -124,7 +125,7 @@ public static void TryAdd( /// The type of the service to register. public static void TryAddTransient( this IServiceCollection collection, - Type service) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service) { if (collection == null) { @@ -151,7 +152,7 @@ public static void TryAddTransient( public static void TryAddTransient( this IServiceCollection collection, Type service, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (collection == null) { @@ -210,7 +211,7 @@ public static void TryAddTransient( /// /// The type of the service to add. /// The . - public static void TryAddTransient(this IServiceCollection collection) + public static void TryAddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class { if (collection == null) @@ -229,7 +230,7 @@ public static void TryAddTransient(this IServiceCollection collection) /// The type of the service to add. /// The type of the implementation to use. /// The . - public static void TryAddTransient(this IServiceCollection collection) + public static void TryAddTransient(this IServiceCollection collection) where TService : class where TImplementation : class, TService { @@ -265,7 +266,7 @@ public static void TryAddTransient( /// The type of the service to register. public static void TryAddScoped( this IServiceCollection collection, - Type service) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service) { if (collection == null) { @@ -292,7 +293,7 @@ public static void TryAddScoped( public static void TryAddScoped( this IServiceCollection collection, Type service, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (collection == null) { @@ -351,7 +352,7 @@ public static void TryAddScoped( /// /// The type of the service to add. /// The . - public static void TryAddScoped(this IServiceCollection collection) + public static void TryAddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class { if (collection == null) @@ -370,7 +371,7 @@ public static void TryAddScoped(this IServiceCollection collection) /// The type of the service to add. /// The type of the implementation to use. /// The . - public static void TryAddScoped(this IServiceCollection collection) + public static void TryAddScoped(this IServiceCollection collection) where TService : class where TImplementation : class, TService { @@ -406,7 +407,7 @@ public static void TryAddScoped( /// The type of the service to register. public static void TryAddSingleton( this IServiceCollection collection, - Type service) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service) { if (collection == null) { @@ -433,7 +434,7 @@ public static void TryAddSingleton( public static void TryAddSingleton( this IServiceCollection collection, Type service, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (collection == null) { @@ -492,7 +493,7 @@ public static void TryAddSingleton( /// /// The type of the service to add. /// The . - public static void TryAddSingleton(this IServiceCollection collection) + public static void TryAddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class { if (collection == null) @@ -511,7 +512,7 @@ public static void TryAddSingleton(this IServiceCollection collection) /// The type of the service to add. /// The type of the implementation to use. /// The . - public static void TryAddSingleton(this IServiceCollection collection) + public static void TryAddSingleton(this IServiceCollection collection) where TService : class where TImplementation : class, TService { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index a8e1db4822e5..d1955eaf4e89 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -16,6 +16,9 @@ Link="Common\src\Extensions\ActivatorUtilities\ActivatorUtilitiesConstructorAttribute.cs" /> + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs index 23cf01a1272d..1de2b83d156f 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.DependencyInjection { @@ -23,7 +24,7 @@ public static class ServiceCollectionServiceExtensions public static IServiceCollection AddTransient( this IServiceCollection services, Type serviceType, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (services == null) { @@ -86,7 +87,7 @@ public static IServiceCollection AddTransient( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddTransient(this IServiceCollection services) + public static IServiceCollection AddTransient(this IServiceCollection services) where TService : class where TImplementation : class, TService { @@ -108,7 +109,7 @@ public static IServiceCollection AddTransient(this IS /// public static IServiceCollection AddTransient( this IServiceCollection services, - Type serviceType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType) { if (services == null) { @@ -131,7 +132,7 @@ public static IServiceCollection AddTransient( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddTransient(this IServiceCollection services) + public static IServiceCollection AddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class { if (services == null) @@ -201,8 +202,6 @@ public static IServiceCollection AddTransient( return services.AddTransient(typeof(TService), implementationFactory); } - - /// /// Adds a scoped service of the type specified in with an /// implementation of the type specified in to the @@ -216,7 +215,7 @@ public static IServiceCollection AddTransient( public static IServiceCollection AddScoped( this IServiceCollection services, Type serviceType, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (services == null) { @@ -279,7 +278,7 @@ public static IServiceCollection AddScoped( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddScoped(this IServiceCollection services) + public static IServiceCollection AddScoped(this IServiceCollection services) where TService : class where TImplementation : class, TService { @@ -301,7 +300,7 @@ public static IServiceCollection AddScoped(this IServ /// public static IServiceCollection AddScoped( this IServiceCollection services, - Type serviceType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType) { if (services == null) { @@ -324,7 +323,7 @@ public static IServiceCollection AddScoped( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddScoped(this IServiceCollection services) + public static IServiceCollection AddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class { if (services == null) @@ -408,7 +407,7 @@ public static IServiceCollection AddScoped( public static IServiceCollection AddSingleton( this IServiceCollection services, Type serviceType, - Type implementationType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (services == null) { @@ -471,7 +470,7 @@ public static IServiceCollection AddSingleton( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddSingleton(this IServiceCollection services) + public static IServiceCollection AddSingleton(this IServiceCollection services) where TService : class where TImplementation : class, TService { @@ -493,7 +492,7 @@ public static IServiceCollection AddSingleton(this IS /// public static IServiceCollection AddSingleton( this IServiceCollection services, - Type serviceType) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType) { if (services == null) { @@ -516,7 +515,7 @@ public static IServiceCollection AddSingleton( /// The to add the service to. /// A reference to this instance after the operation has completed. /// - public static IServiceCollection AddSingleton(this IServiceCollection services) + public static IServiceCollection AddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class { if (services == null) @@ -651,7 +650,7 @@ public static IServiceCollection AddSingleton( private static IServiceCollection Add( IServiceCollection collection, Type serviceType, - Type implementationType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime) { var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime); diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs index d5fed233c6b5..57a6d8d33f7d 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.DependencyInjection { @@ -20,7 +21,7 @@ public class ServiceDescriptor /// The of the service. public ServiceDescriptor( Type serviceType, - Type implementationType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime) : this(serviceType, lifetime) { @@ -96,6 +97,7 @@ private ServiceDescriptor(Type serviceType, ServiceLifetime lifetime) public Type ServiceType { get; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] public Type? ImplementationType { get; } public object? ImplementationInstance { get; } @@ -151,7 +153,7 @@ internal Type GetImplementationType() /// The type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Transient() + public static ServiceDescriptor Transient() where TService : class where TImplementation : class, TService { @@ -166,7 +168,9 @@ public static ServiceDescriptor Transient() /// The type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Transient(Type service, Type implementationType) + public static ServiceDescriptor Transient( + Type service, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (service == null) { @@ -254,7 +258,7 @@ public static ServiceDescriptor Transient(Type service, FuncThe type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Scoped() + public static ServiceDescriptor Scoped() where TService : class where TImplementation : class, TService { @@ -269,7 +273,9 @@ public static ServiceDescriptor Scoped() /// The type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Scoped(Type service, Type implementationType) + public static ServiceDescriptor Scoped( + Type service, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { return Describe(service, implementationType, ServiceLifetime.Scoped); } @@ -347,7 +353,7 @@ public static ServiceDescriptor Scoped(Type service, FuncThe type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Singleton() + public static ServiceDescriptor Singleton() where TService : class where TImplementation : class, TService { @@ -362,7 +368,9 @@ public static ServiceDescriptor Singleton() /// The type of the service. /// The type of the implementation. /// A new instance of . - public static ServiceDescriptor Singleton(Type service, Type implementationType) + public static ServiceDescriptor Singleton( + Type service, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType) { if (service == null) { @@ -488,7 +496,7 @@ public static ServiceDescriptor Singleton( return new ServiceDescriptor(serviceType, implementationInstance); } - private static ServiceDescriptor Describe(ServiceLifetime lifetime) + private static ServiceDescriptor Describe(ServiceLifetime lifetime) where TService : class where TImplementation : class, TService { @@ -507,7 +515,10 @@ private static ServiceDescriptor Describe(ServiceLife /// The type of the implementation. /// The lifetime of the service. /// A new instance of . - public static ServiceDescriptor Describe(Type serviceType, Type implementationType, ServiceLifetime lifetime) + public static ServiceDescriptor Describe( + Type serviceType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, + ServiceLifetime lifetime) { return new ServiceDescriptor(serviceType, implementationType, lifetime); } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj index 65ea136fcf18..d7df2f2725f9 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj @@ -25,6 +25,12 @@ Link="Common\src\Extensions\TypeNameHelper\TypeNameHelper.cs" /> + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs index 2bf5ee16fc8e..4aec44848ae0 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using Microsoft.Extensions.Internal; @@ -244,16 +245,16 @@ private ServiceCallSite TryCreateOpenGeneric(ServiceDescriptor descriptor, Type return null; } - private ServiceCallSite CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, + private ServiceCallSite CreateConstructorCallSite( + ResultCache lifetime, + Type serviceType, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, CallSiteChain callSiteChain) { try { callSiteChain.Add(serviceType, implementationType); - ConstructorInfo[] constructors = implementationType.GetTypeInfo() - .DeclaredConstructors - .Where(constructor => constructor.IsPublic) - .ToArray(); + ConstructorInfo[] constructors = implementationType.GetConstructors(); ServiceCallSite[] parameterCallSites = null; diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs new file mode 100644 index 000000000000..eef18d380d1e --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Extensions.DependencyInjection; + +class Program +{ + static int Main(string[] args) + { + ServiceProvider provider = new ServiceCollection().BuildServiceProvider(); + + // ActivatorUtilities.CreateFactory fails due to https://github.com/mono/linker/issues/1398 + //ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty()); + //ServiceA serviceA = factory(provider, null) as ServiceA; + ServiceB serviceB = ActivatorUtilities.CreateInstance(provider, typeof(ServiceB)) as ServiceB; + ServiceC serviceC = ActivatorUtilities.CreateInstance(provider); + ServiceD serviceD = ActivatorUtilities.GetServiceOrCreateInstance(provider, typeof(ServiceD)) as ServiceD; + ServiceE serviceE = ActivatorUtilities.GetServiceOrCreateInstance(provider); + + if (//serviceA is null || + serviceB is null || + serviceC is null || + serviceD is null || + serviceE is null) + { + return -1; + } + + return 100; + } + + private class ServiceA { } + private class ServiceB { } + private class ServiceC { } + private class ServiceD { } + private class ServiceE { } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj new file mode 100644 index 000000000000..e1f5ef6af8cd --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj @@ -0,0 +1,14 @@ + + + + + Microsoft.Extensions.DependencyInjection + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 000000000000..58a1c8b10ab4 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; + +class Program +{ + static int Main(string[] args) + { + IServiceCollection descriptors = new ServiceCollection(); + descriptors.AddTransient(); + descriptors.AddScoped(typeof(ServiceB)); + descriptors.AddSingleton(typeof(IServiceC), typeof(ServiceC)); + + descriptors.AddTransient(); + descriptors.AddTransient(); + descriptors.AddTransient(typeof(IServiceF), typeof(ServiceF)); + + descriptors.AddTransient(); + descriptors.AddTransient(typeof(Logger<>)); + + descriptors.AddTransient(); + descriptors.AddTransient(); + + ServiceProvider provider = descriptors.BuildServiceProvider(); + + if (provider.GetService() is null || + provider.GetService() is null || + provider.GetService() is null || + provider.GetService()?.ServiceE?.ServiceD is null || + provider.GetService>() is null) + { + return -1; + } + + int hServices = 0; + foreach (IServiceH h in provider.GetServices()) + { + hServices++; + if (h == null) + { + return -1; + } + } + + if (hServices != 2) + { + return -1; + } + + return 100; + } + + private class ServiceA { } + private class ServiceB { } + private interface IServiceC { } + private class ServiceC : IServiceC { } + + public interface IServiceD { } + public interface IServiceE { IServiceD ServiceD { get; } } + public interface IServiceF { IServiceE ServiceE { get; } } + public class ServiceD : IServiceD + { + } + public class ServiceE : IServiceE + { + public IServiceD ServiceD { get; } + public ServiceE(IServiceD d) { ServiceD = d; } + } + public class ServiceF : IServiceF + { + public IServiceE ServiceE { get; } + public ServiceF(IServiceE e) { ServiceE = e; } + } + + public class Logger { } + public interface IServiceG { } + public class ServiceG : IServiceG { } + + public interface IServiceH { } + public class ServiceH1 : IServiceH { } + public class ServiceH2 : IServiceH { } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs index eefc9c442925..2d82ed0c0e7f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs @@ -13,7 +13,12 @@ namespace System.Diagnostics.CodeAnalysis /// . So it is always preserved in the compiled assembly. /// [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] - public sealed class UnconditionalSuppressMessageAttribute : Attribute +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class UnconditionalSuppressMessageAttribute : Attribute { /// /// Initializes a new instance of the From 995224db011f77eb095279122244704ccca01d5f Mon Sep 17 00:00:00 2001 From: Edward Kazuya Carlson Date: Sun, 2 Aug 2020 11:04:56 -0700 Subject: [PATCH 205/755] Added variable number for tracking (#39861) --- .../DebugInfo.cs | 20 +++++++++++--- .../DebugInfoTypes.cs | 15 +++++++++++ .../ReadyToRunMethod.cs | 26 ++++++++++++++++++- .../ReadyToRunReader.cs | 16 ++++++------ 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs index 706e98780acb..8a6766d42945 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs @@ -17,15 +17,15 @@ namespace ILCompiler.Reflection.ReadyToRun /// public class DebugInfo { - private readonly ReadyToRunReader _readyToRunReader; + private readonly RuntimeFunction _runtimeFunction; private readonly int _offset; private List _boundsList; private List _variablesList; private Machine _machine; - public DebugInfo(ReadyToRunReader readyToRunReader, int offset) + public DebugInfo(RuntimeFunction runtimeFunction, int offset) { - this._readyToRunReader = readyToRunReader; + this._runtimeFunction = runtimeFunction; this._offset = offset; } @@ -83,6 +83,7 @@ private void EnsureInitialized() { return; } + ReadyToRunReader _readyToRunReader = _runtimeFunction.ReadyToRunReader; int offset = _offset; _boundsList = new List(); _variablesList = new List(); @@ -156,6 +157,19 @@ private void ParseNativeVarInfo(byte[] image, int offset) entry.StartOffset = reader.ReadUInt(); entry.EndOffset = entry.StartOffset + reader.ReadUInt(); entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max); + entry.Variable = new Variable(); + // TODO: This is probably incomplete + // This does not handle any implicit arguments or var args + if (entry.VariableNumber < this._runtimeFunction.Method.Signature.ParameterTypes.Length) + { + entry.Variable.Type = VariableType.Parameter; + entry.Variable.Index = (int)entry.VariableNumber; + } + else + { + entry.Variable.Type = VariableType.Local; + entry.Variable.Index = (int)entry.VariableNumber - this._runtimeFunction.Method.Signature.ParameterTypes.Length; + } var varLoc = new VarLoc(); varLoc.VarLocType = (VarLocType)reader.ReadUInt(); diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs index 73782f2344c3..eef0ab4673cb 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs @@ -17,10 +17,25 @@ public struct NativeVarInfo { public uint StartOffset; public uint EndOffset; + // TODO: Eliminate this public uint VariableNumber; + public Variable Variable { get; internal set; } public VarLoc VariableLocation; } + public enum VariableType + { + Parameter, + Local, + // TODO: Special + } + + public class Variable + { + public VariableType Type { get; internal set; } + public int Index { get; internal set; } + } + [Flags] public enum SourceTypes { diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs index a00419f212c4..266a75bbddc1 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs @@ -144,12 +144,24 @@ public DebugInfo DebugInfo { if (_debugInfo == null) { - _readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out _debugInfo); + int offset; + if (_readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out offset)) + { + this._debugInfo = new DebugInfo(this, offset); + } } return _debugInfo; } } + internal ReadyToRunReader ReadyToRunReader + { + get + { + return _readyToRunReader; + } + } + public RuntimeFunction( ReadyToRunReader readyToRunReader, int id, @@ -218,6 +230,8 @@ public class ReadyToRunMethod public MethodSignature Signature { get; } + public ImmutableArray LocalSignature { get; } + /// /// The type that the method belongs to /// @@ -282,6 +296,7 @@ public IReadOnlyList Fixups /// public ReadyToRunMethod( ReadyToRunReader readyToRunReader, + PEReader peReader, MetadataReader metadataReader, EntityHandle methodHandle, int entryPointId, @@ -309,6 +324,15 @@ public ReadyToRunMethod( case HandleKind.MethodDefinition: { MethodDefinition methodDef = MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); + if (methodDef.RelativeVirtualAddress != 0) + { + MethodBodyBlock mbb = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); + if (!mbb.LocalSignature.IsNil) + { + StandaloneSignature ss = MetadataReader.GetStandaloneSignature(mbb.LocalSignature); + LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); + } + } Name = MetadataReader.GetString(methodDef.Name); Signature = methodDef.DecodeSignature(typeProvider, genericContext); owningTypeHandle = methodDef.GetDeclaringType(); diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index a829b58599e5..3fdb03f6724b 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -80,7 +80,7 @@ public sealed class ReadyToRunReader private List _readyToRunAssemblyHeaders; // DebugInfo - private Dictionary _runtimeFunctionToDebugInfo; + private Dictionary _runtimeFunctionIdToDebugOffset; // ManifestReferences private MetadataReader _manifestReader; @@ -322,12 +322,12 @@ public IReadOnlyDictionary ImportSignatures } - internal Dictionary RuntimeFunctionToDebugInfo + internal Dictionary RuntimeFunctionToDebugInfo { get { EnsureDebugInfo(); - return _runtimeFunctionToDebugInfo; + return _runtimeFunctionIdToDebugOffset; } } @@ -583,11 +583,11 @@ private unsafe void EnsureHeader() private void EnsureDebugInfo() { - if (_runtimeFunctionToDebugInfo != null) + if (_runtimeFunctionIdToDebugOffset != null) { return; } - _runtimeFunctionToDebugInfo = new Dictionary(); + _runtimeFunctionIdToDebugOffset = new Dictionary(); if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.DebugInfo, out ReadyToRunSection debugInfoSection)) { return; @@ -604,8 +604,7 @@ private void EnsureDebugInfo() continue; } - var debugInfo = new DebugInfo(this, offset); - _runtimeFunctionToDebugInfo.Add((int)i, debugInfo); + _runtimeFunctionIdToDebugOffset.Add((int)i, offset); } } @@ -741,7 +740,7 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, Metadat int runtimeFunctionId; int? fixupOffset; GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixupOffset); - ReadyToRunMethod method = new ReadyToRunMethod(this, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset); + ReadyToRunMethod method = new ReadyToRunMethod(this, this.PEReader, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset); if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= isEntryPoint.Length) { @@ -889,6 +888,7 @@ private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixupOffset); ReadyToRunMethod method = new ReadyToRunMethod( this, + this.PEReader, mdReader, methodHandle, runtimeFunctionId, From 3218c128072962fc90d92677c704f8653e1777a0 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, 3 Aug 2020 13:11:52 +0200 Subject: [PATCH 206/755] HTTP agnostic loopback server. (#40144) --- .../System/Net/Http/GenericLoopbackServer.cs | 5 + .../Net/Http/Http2LoopbackConnection.cs | 32 ++- .../System/Net/Http/Http2LoopbackServer.cs | 28 +- .../Net/Http/Http3LoopbackConnection.cs | 8 + .../System/Net/Http/Http3LoopbackServer.cs | 6 +- .../Net/Http/HttpAgnosticLoopbackServer.cs | 263 ++++++++++++++++++ .../HttpClientHandlerTest.Decompression.cs | 3 - .../System/Net/Http/HttpClientHandlerTest.cs | 53 ++-- .../tests/System/Net/Http/LoopbackServer.cs | 109 ++++---- ...ttpClientHandlerTestBase.WinHttpHandler.cs | 6 + .../HttpClientHandlerTest.Http2.cs | 2 +- ...lientHandlerTestBase.SocketsHttpHandler.cs | 6 + .../FunctionalTests/SocketsHttpHandlerTest.cs | 11 +- .../System.Net.Http.Functional.Tests.csproj | 2 + 14 files changed, 423 insertions(+), 111 deletions(-) create mode 100644 src/libraries/Common/tests/System/Net/Http/HttpAgnosticLoopbackServer.cs diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 899b90922de8..da6e915a237f 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -76,6 +76,9 @@ public abstract class GenericLoopbackConnection : IDisposable /// Sends Response body after SendResponse was called with isFinal: false. public abstract Task SendResponseBodyAsync(byte[] content, bool isFinal = true, int requestId = 0); + /// Reads Request, sends Response and closes connection. + public abstract Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = ""); + /// Waits for the client to signal cancellation. public abstract Task WaitForCancellationAsync(bool ignoreIncomingData = true, int requestId = 0); @@ -95,6 +98,8 @@ public class GenericLoopbackOptions SslProtocols.Tls13 | #endif SslProtocols.Tls12; + + public int ListenBacklog { get; set; } = 1; } public struct HttpHeaderData diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 9ee647968482..4701cecd248f 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -18,6 +18,8 @@ namespace System.Net.Test.Common { public class Http2LoopbackConnection : GenericLoopbackConnection { + public const string Http2Prefix = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"; + private Socket _connectionSocket; private Stream _connectionStream; private TaskCompletionSource _ignoredSettingsAckPromise; @@ -58,7 +60,6 @@ public static async Task CreateAsync(Socket socket, Str var protocols = new List(); protocols.Add(SslApplicationProtocol.Http2); - protocols.Add(SslApplicationProtocol.Http11); options.ApplicationProtocols = protocols; options.ServerCertificate = cert; @@ -697,7 +698,11 @@ public async Task SendResponseBodyAsync(int streamId, ReadOnlyMemory respo public override void Dispose() { - ShutdownIgnoringErrorsAsync(_lastStreamId).GetAwaiter().GetResult(); + // Might have been already shutdown manually via WaitForConnectionShutdownAsync which nulls the _connectionStream. + if (_connectionStream != null) + { + ShutdownIgnoringErrorsAsync(_lastStreamId).GetAwaiter().GetResult(); + } } // @@ -783,6 +788,29 @@ public override Task SendResponseBodyAsync(byte[] body, bool isFinal = true, int return SendResponseBodyAsync(streamId, body, isFinal); } + public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") + { + (int streamId, HttpRequestData requestData) = await ReadAndParseRequestHeaderAsync().ConfigureAwait(false); + + // We are about to close the connection, after we send the response. + // So, send a GOAWAY frame now so the client won't inadvertantly try to reuse the connection. + await SendGoAway(streamId).ConfigureAwait(false); + + if (string.IsNullOrEmpty(content)) + { + await SendResponseHeadersAsync(streamId, endStream: true, statusCode, isTrailingHeader: false, headers : headers).ConfigureAwait(false); + } + else + { + await SendResponseHeadersAsync(streamId, endStream: false, statusCode, isTrailingHeader: false, headers : headers).ConfigureAwait(false); + await SendResponseBodyAsync(streamId, Encoding.ASCII.GetBytes(content)).ConfigureAwait(false); + } + + await WaitForConnectionShutdownAsync().ConfigureAwait(false); + + return requestData; + } + public override async Task WaitForCancellationAsync(bool ignoreIncomingData = true, int requestId = 0) { int streamId = requestId == 0 ? _lastStreamId : requestId; diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index e890812cdbcd..53757b9ad567 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -143,27 +143,10 @@ public override void Dispose() public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { - Http2LoopbackConnection connection = await EstablishConnectionAsync().ConfigureAwait(false); - - (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false); - - // We are about to close the connection, after we send the response. - // So, send a GOAWAY frame now so the client won't inadvertantly try to reuse the connection. - await connection.SendGoAway(streamId).ConfigureAwait(false); - - if (string.IsNullOrEmpty(content)) - { - await connection.SendResponseHeadersAsync(streamId, endStream: true, statusCode, isTrailingHeader: false, headers : headers).ConfigureAwait(false); - } - else + using (Http2LoopbackConnection connection = await EstablishConnectionAsync().ConfigureAwait(false)) { - await connection.SendResponseHeadersAsync(streamId, endStream: false, statusCode, isTrailingHeader: false, headers : headers).ConfigureAwait(false); - await connection.SendResponseBodyAsync(streamId, Encoding.ASCII.GetBytes(content)).ConfigureAwait(false); - } - - await connection.WaitForConnectionShutdownAsync().ConfigureAwait(false); - - return requestData; + return await connection.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); + } } public override async Task AcceptConnectionAsync(Func funcAsync) @@ -193,8 +176,6 @@ public static async Task CreateClientAndServerAsync(Func clientFunc, public class Http2Options : GenericLoopbackOptions { - public int ListenBacklog { get; set; } = 1; - public bool ClientCertificateRequired { get; set; } public Http2Options() @@ -233,6 +214,7 @@ private static Http2Options CreateOptions(GenericLoopbackOptions options) http2Options.Address = options.Address; http2Options.UseSsl = options.UseSsl; http2Options.SslProtocols = options.SslProtocols; + http2Options.ListenBacklog = options.ListenBacklog; } return http2Options; } @@ -245,7 +227,7 @@ public override async Task CreateServerAsync(Func HttpVersion20.Value; + public override Version Version => HttpVersion20.Value; } public enum ProtocolErrors diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index cfa912a7f4bf..6a63bb3f39fb 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -168,6 +168,14 @@ private async Task SendResponseHeadersAsync(HttpStatusCode? statusCode = HttpSta await GetOpenRequest(requestId).SendHeadersFrameAsync(headers).ConfigureAwait(false); } + public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") + { + HttpRequestData request = await ReadRequestDataAsync().ConfigureAwait(false); + await SendResponseAsync(statusCode, headers, content).ConfigureAwait(false); + await CloseAsync(Http3LoopbackConnection.H3_NO_ERROR); + return request; + } + public override async Task WaitForCancellationAsync(bool ignoreIncomingData = true, int requestId = 0) { await GetOpenRequest(requestId).WaitForCancellationAsync(ignoreIncomingData).ConfigureAwait(false); diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 49c3c867fff7..6c033a8548c0 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -58,11 +58,7 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { using var con = (Http3LoopbackConnection)await EstablishGenericConnectionAsync().ConfigureAwait(false); - - HttpRequestData request = await con.ReadRequestDataAsync().ConfigureAwait(false); - await con.SendResponseAsync(statusCode, headers, content).ConfigureAwait(false); - await con.CloseAsync(Http3LoopbackConnection.H3_NO_ERROR); - return request; + return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpAgnosticLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/HttpAgnosticLoopbackServer.cs new file mode 100644 index 000000000000..6a6657b3adb0 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Http/HttpAgnosticLoopbackServer.cs @@ -0,0 +1,263 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Xunit; + +namespace System.Net.Test.Common +{ + public class HttpAgnosticLoopbackServer : GenericLoopbackServer, IDisposable + { + private Socket _listenSocket; + private HttpAgnosticOptions _options; + private Uri _uri; + + public override Uri Address => _uri; + + public static HttpAgnosticLoopbackServer CreateServer() + { + return new HttpAgnosticLoopbackServer(new HttpAgnosticOptions()); + } + + public static HttpAgnosticLoopbackServer CreateServer(HttpAgnosticOptions options) + { + return new HttpAgnosticLoopbackServer(options); + } + + private HttpAgnosticLoopbackServer(HttpAgnosticOptions options) + { + _options = options; + _listenSocket = new Socket(_options.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + _listenSocket.Bind(new IPEndPoint(_options.Address, 0)); + _listenSocket.Listen(_options.ListenBacklog); + + var localEndPoint = (IPEndPoint)_listenSocket.LocalEndPoint; + var host = _options.Address.AddressFamily == AddressFamily.InterNetworkV6 ? $"[{localEndPoint.Address}]" : localEndPoint.Address.ToString(); + var scheme = _options.UseSsl ? "https" : "http"; + _uri = new Uri($"{scheme}://{host}:{localEndPoint.Port}/"); + } + + public override void Dispose() + { + if (_listenSocket != null) + { + _listenSocket.Dispose(); + _listenSocket = null; + } + } + public override async Task EstablishGenericConnectionAsync() + { + Socket socket = await _listenSocket.AcceptAsync().ConfigureAwait(false); + Stream stream = new NetworkStream(socket, ownsSocket: true); + + if (_options.UseSsl) + { + var sslStream = new SslStream(stream, false, delegate { return true; }); + + using (X509Certificate2 cert = Configuration.Certificates.GetServerCertificate()) + { + SslServerAuthenticationOptions options = new SslServerAuthenticationOptions(); + + options.EnabledSslProtocols = _options.SslProtocols; + + var protocols = new List(); + protocols.Add(SslApplicationProtocol.Http11); + protocols.Add(SslApplicationProtocol.Http2); + options.ApplicationProtocols = protocols; + + options.ServerCertificate = cert; + + await sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).ConfigureAwait(false); + } + + stream = sslStream; + if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2) + { + // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again. + return await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream); + } + if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http11) + { + // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again. + return await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream); + } + throw new Exception($"Unsupported negotiated protocol {sslStream.NegotiatedApplicationProtocol}"); + } + + var buffer = new byte[24]; + var position = 0; + while (position < buffer.Length) + { + var readBytes = await stream.ReadAsync(buffer, position, buffer.Length - position).ConfigureAwait(false); + if (readBytes == 0) + { + break; + } + position += readBytes; + } + + var memory = new Memory(buffer, 0, position); + stream = new ReturnBufferStream(stream, memory); + + var prefix = Text.Encoding.ASCII.GetString(memory.Span); + if (prefix == Http2LoopbackConnection.Http2Prefix) + { + if (_options.ClearTextVersion == HttpVersion.Version20 || _options.ClearTextVersion == HttpVersion.Unknown) + { + return await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream); + } + } + else + { + if (_options.ClearTextVersion == HttpVersion.Version11 || _options.ClearTextVersion == HttpVersion.Unknown) + { + return await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream); + } + } + + throw new Exception($"HTTP/{_options.ClearTextVersion} server cannot establish connection due to unexpected data: '{prefix}'"); + } + + public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") + { + using (GenericLoopbackConnection connection = await EstablishGenericConnectionAsync().ConfigureAwait(false)) + { + return await connection.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); + } + } + + public override async Task AcceptConnectionAsync(Func funcAsync) + { + using (GenericLoopbackConnection connection = await EstablishGenericConnectionAsync().ConfigureAwait(false)) + { + await funcAsync(connection).ConfigureAwait(false); + } + } + + public static Task CreateClientAndServerAsync(Func clientFunc, Func serverFunc, int timeout = 60_000) + { + return CreateClientAndServerAsync(clientFunc, serverFunc, null, timeout); + } + + public static async Task CreateClientAndServerAsync(Func clientFunc, Func serverFunc, HttpAgnosticOptions httpOptions, int timeout = 60_000) + { + using (var server = HttpAgnosticLoopbackServer.CreateServer(httpOptions ?? new HttpAgnosticOptions())) + { + Task clientTask = clientFunc(server.Address); + Task serverTask = serverFunc(server); + + await new Task[] { clientTask, serverTask }.WhenAllOrAnyFailed(timeout).ConfigureAwait(false); + } + } + } + + public class HttpAgnosticOptions : GenericLoopbackOptions + { + public Version ClearTextVersion { get; set; } + + public HttpAgnosticOptions() + { + ClearTextVersion = HttpVersion.Version11; + } + } + + public sealed class HttpAgnosticLoopbackServerFactory : LoopbackServerFactory + { + public static readonly HttpAgnosticLoopbackServerFactory Singleton = new HttpAgnosticLoopbackServerFactory(); + + public static async Task CreateServerAsync(Func funcAsync, int millisecondsTimeout = 60_000) + { + using (var server = HttpAgnosticLoopbackServer.CreateServer()) + { + await funcAsync(server, server.Address).TimeoutAfter(millisecondsTimeout).ConfigureAwait(false); + } + } + + public override GenericLoopbackServer CreateServer(GenericLoopbackOptions options = null) + { + return HttpAgnosticLoopbackServer.CreateServer(CreateOptions(options)); + } + + public override Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) + { + // This method is always unacceptable to call for an agnostic server. + throw new NotImplementedException("HttpAgnosticLoopbackServerFactory cannot create connection."); + } + + private static HttpAgnosticOptions CreateOptions(GenericLoopbackOptions options) + { + HttpAgnosticOptions httpOptions = new HttpAgnosticOptions(); + if (options != null) + { + httpOptions.Address = options.Address; + httpOptions.UseSsl = options.UseSsl; + httpOptions.SslProtocols = options.SslProtocols; + httpOptions.ListenBacklog = options.ListenBacklog; + } + return httpOptions; + } + + public override async Task CreateServerAsync(Func funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null) + { + using (var server = CreateServer(options)) + { + await funcAsync(server, server.Address).TimeoutAfter(millisecondsTimeout).ConfigureAwait(false); + } + } + + public override Version Version => HttpVersion.Unknown; + } + + internal class ReturnBufferStream : Stream + { + private Stream _stream; + private Memory _buffer; + + public ReturnBufferStream(Stream stream, Memory buffer) + { + _stream = stream; + _buffer = buffer; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_buffer.IsEmpty) + { + return _stream.Read(buffer, offset, count); + } + + var fromBuffer = Math.Min(_buffer.Length, count); + _buffer.Slice(0, fromBuffer).CopyTo(new Memory(buffer, offset, count)); + _buffer = _buffer.Slice(fromBuffer); + offset += fromBuffer; + count -= fromBuffer; + + if (count > 0) + { + return _stream.Read(buffer, offset, count) + fromBuffer; + } + + return fromBuffer; + } + + public override bool CanRead => _stream.CanRead; + public override bool CanSeek => _stream.CanSeek; + public override bool CanWrite => _stream.CanWrite; + public override long Length => _stream.Length; + public override long Position { get => _stream.Position; set => _stream.Position = value; } + public override void Flush() => _stream.Flush(); + public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin); + public override void SetLength(long value) => _stream.SetLength(value); + public override void Write(byte[] buffer, int offset, int count) => _stream.Write(buffer, offset, count); + + } +} diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs index 7ffddeadb45f..4877f7551625 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs @@ -64,9 +64,6 @@ public static IEnumerable DecompressedResponse_MethodSpecified_Decompr } } - private HttpRequestMessage CreateRequest(HttpMethod method, Uri uri, Version version) => - new HttpRequestMessage(method, uri) { Version = version }; - [Theory] [MemberData(nameof(DecompressedResponse_MethodSpecified_DecompressedContentReturned_MemberData))] public async Task DecompressedResponse_MethodSpecified_DecompressedContentReturned( diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index b764d2419e09..371c47f35527 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -230,22 +230,25 @@ public async Task GetAsync_IPv6LinkLocalAddressUri_Success() return; } - using (HttpClient client = CreateHttpClient()) - { - var options = new GenericLoopbackOptions { Address = TestHelper.GetIPv6LinkLocalAddress() }; - if (options.Address == null) - { - throw new SkipTestException("Unable to find valid IPv6 LL address."); - } - await LoopbackServerFactory.CreateServerAsync(async (server, url) => - { - _output.WriteLine(url.ToString()); - await TestHelper.WhenAllCompletedOrAnyFailed( - server.AcceptConnectionSendResponseAndCloseAsync(), - client.GetAsync(url)); - }, options: options); + using HttpClientHandler handler = CreateHttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; + + using HttpClient client = CreateHttpClient(handler); + + var options = new GenericLoopbackOptions { Address = TestHelper.GetIPv6LinkLocalAddress() }; + if (options.Address == null) + { + throw new SkipTestException("Unable to find valid IPv6 LL address."); } + + await LoopbackServerFactory.CreateServerAsync(async (server, url) => + { + _output.WriteLine(url.ToString()); + await TestHelper.WhenAllCompletedOrAnyFailed( + server.AcceptConnectionSendResponseAndCloseAsync(), + client.SendAsync(CreateRequest(HttpMethod.Get, url, UseVersion, true))); + }, options: options); } [Theory] @@ -257,17 +260,19 @@ public async Task GetAsync_IPBasedUri_Success(IPAddress address) return; } - using (HttpClient client = CreateHttpClient()) + using HttpClientHandler handler = CreateHttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; + + using HttpClient client = CreateHttpClient(handler); + + var options = new GenericLoopbackOptions { Address = address }; + await LoopbackServerFactory.CreateServerAsync(async (server, url) => { - var options = new GenericLoopbackOptions { Address = address }; - await LoopbackServerFactory.CreateServerAsync(async (server, url) => - { - _output.WriteLine(url.ToString()); - await TestHelper.WhenAllCompletedOrAnyFailed( - server.AcceptConnectionSendResponseAndCloseAsync(), - client.GetAsync(url)); - }, options: options); - } + _output.WriteLine(url.ToString()); + await TestHelper.WhenAllCompletedOrAnyFailed( + server.AcceptConnectionSendResponseAndCloseAsync(), + client.SendAsync(CreateRequest(HttpMethod.Get, url, UseVersion, true))); + }, options: options); } public static IEnumerable GetAsync_IPBasedUri_Success_MemberData() diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 2d34c3bc8753..2c027ca702cd 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -7,7 +7,9 @@ using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -104,26 +106,8 @@ public async Task EstablishConnectionAsync() catch (SocketException ex) when (ex.SocketErrorCode == SocketError.InvalidArgument && PlatformDetection.IsOSXLike) { } Stream stream = new NetworkStream(s, ownsSocket: false); - if (_options.UseSsl) - { - var sslStream = new SslStream(stream, false, delegate { return true; }); - using (var cert = Configuration.Certificates.GetServerCertificate()) - { - await sslStream.AuthenticateAsServerAsync( - cert, - clientCertificateRequired: true, // allowed but not required - enabledSslProtocols: _options.SslProtocols, - checkCertificateRevocation: false).ConfigureAwait(false); - } - stream = sslStream; - } - if (_options.StreamWrapper != null) - { - stream = _options.StreamWrapper(stream); - } - - return new Connection(s, stream); + return await Connection.CreateAsync(s, stream, _options); } catch (Exception) { @@ -389,7 +373,6 @@ public static string GetConnectionCloseResponse(HttpStatusCode statusCode = Http public class Options : GenericLoopbackOptions { - public int ListenBacklog { get; set; } = 1; public bool WebSocketEndpoint { get; set; } = false; public Func StreamWrapper { get; set; } public string Username { get; set; } @@ -436,6 +419,30 @@ public Connection(Socket socket, Stream stream) public Stream Stream => _stream; public StreamWriter Writer => _writer; + public static async Task CreateAsync(Socket socket, Stream stream, Options httpOptions) + { + if (httpOptions.UseSsl) + { + var sslStream = new SslStream(stream, false, delegate { return true; }); + using (X509Certificate2 cert = Configuration.Certificates.GetServerCertificate()) + { + await sslStream.AuthenticateAsServerAsync( + cert, + clientCertificateRequired: true, // allowed but not required + enabledSslProtocols: httpOptions.SslProtocols, + checkCertificateRevocation: false).ConfigureAwait(false); + } + stream = sslStream; + } + + if (httpOptions.StreamWrapper != null) + { + stream = httpOptions.StreamWrapper(stream); + } + + return new Connection(socket, stream); + } + public async Task ReadAsync(Memory buffer, int offset, int size) { if (_readEnd - _readStart > 0) @@ -885,31 +892,9 @@ public override async Task SendResponseBodyAsync(byte[] body, bool isFinal = tru await SendResponseAsync(Encoding.UTF8.GetString(body)).ConfigureAwait(false); } - public override async Task WaitForCancellationAsync(bool ignoreIncomingData = true, int requestId = 0) + public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { - var buffer = new byte[1024]; - while (true) - { - int bytesRead = await ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); - - if (!ignoreIncomingData) - { - Assert.Equal(0, bytesRead); - } - - if (bytesRead == 0) - { - break; - } - } - } - } - - public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") - { - using (Connection connection = await EstablishConnectionAsync().ConfigureAwait(false)) - { - HttpRequestData requestData = await connection.ReadRequestDataAsync().ConfigureAwait(false); + HttpRequestData requestData = await ReadRequestDataAsync().ConfigureAwait(false); // For historical reasons, we added Date and "Connection: close" (to improve test reliability) bool hasDate = false; @@ -932,9 +917,36 @@ public override async Task HandleRequestAsync(HttpStatusCode st newHeaders.Add(new HttpHeaderData("Date", "{DateTimeOffset.UtcNow:R}")); } - await connection.SendResponseAsync(statusCode, newHeaders, content: content).ConfigureAwait(false); + await SendResponseAsync(statusCode, newHeaders, content: content).ConfigureAwait(false); return requestData; } + + public override async Task WaitForCancellationAsync(bool ignoreIncomingData = true, int requestId = 0) + { + var buffer = new byte[1024]; + while (true) + { + int bytesRead = await ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (!ignoreIncomingData) + { + Assert.Equal(0, bytesRead); + } + + if (bytesRead == 0) + { + break; + } + } + } + } + + public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") + { + using (Connection connection = await EstablishConnectionAsync().ConfigureAwait(false)) + { + return await connection.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); + } } public override Task AcceptConnectionAsync(Func funcAsync) @@ -957,9 +969,9 @@ public override Task CreateServerAsync(Func fu return LoopbackServer.CreateServerAsync((server, uri) => funcAsync(server, uri), options: CreateOptions(options)); } - public override Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) + public override async Task CreateConnectionAsync(Socket socket, Stream stream, GenericLoopbackOptions options = null) { - return Task.FromResult(new LoopbackServer.Connection(socket, stream)); + return await LoopbackServer.Connection.CreateAsync(socket, stream, CreateOptions(options)); } private static LoopbackServer.Options CreateOptions(GenericLoopbackOptions options) @@ -968,6 +980,9 @@ private static LoopbackServer.Options CreateOptions(GenericLoopbackOptions optio if (options != null) { newOptions.Address = options.Address; + newOptions.UseSsl = options.UseSsl; + newOptions.SslProtocols = options.SslProtocols; + newOptions.ListenBacklog = options.ListenBacklog; } return newOptions; } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs index 179cf30e9105..0896bbd7b5b0 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs @@ -25,5 +25,11 @@ protected static WinHttpClientHandler CreateHttpClientHandler(Version useVersion return handler; } + + protected static HttpRequestMessage CreateRequest(HttpMethod method, Uri uri, Version version, bool exactVersion = false) => + new HttpRequestMessage(method, uri) + { + Version = version + }; } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index a0cfd9a88d04..defa4719d64f 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -78,7 +78,7 @@ public async Task Http2_ClientPreface_Sent() string connectionPreface = (await server.AcceptConnectionAsync()).PrefixString; - Assert.Equal("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", connectionPreface); + Assert.Equal(Http2LoopbackConnection.Http2Prefix, connectionPreface); } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs index 90fa26e8fe75..90fddb4008cd 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs @@ -45,5 +45,11 @@ protected static object GetUnderlyingSocketsHttpHandler(HttpClientHandler handle FieldInfo field = typeof(HttpClientHandler).GetField("_underlyingHandler", BindingFlags.Instance | BindingFlags.NonPublic); return field?.GetValue(handler); } + + protected static HttpRequestMessage CreateRequest(HttpMethod method, Uri uri, Version version, bool exactVersion = false) => + new HttpRequestMessage(method, uri) + { + Version = version, + }; } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index f86bd58bd75b..18b603637010 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -117,14 +117,12 @@ public async Task CustomConnectionFactory_AsyncRequest_Success() await using ConnectionListener listener = await listenerFactory.ListenAsync(endPoint: null); await using ConnectionFactory connectionFactory = VirtualNetworkConnectionListenerFactory.GetConnectionFactory(listener); - // TODO: if GenericLoopbackOptions actually worked for HTTP/1 LoopbackServer we could just use that and pass in to CreateConnectionAsync. - // Making that work causes other tests to fail, so for now... - bool useHttps = UseVersion.Major >= 2 && new GenericLoopbackOptions().UseSsl; + var options = new GenericLoopbackOptions(); Task serverTask = Task.Run(async () => { await using Connection serverConnection = await listener.AcceptAsync(); - using GenericLoopbackConnection loopbackConnection = await LoopbackServerFactory.CreateConnectionAsync(socket: null, serverConnection.Stream); + using GenericLoopbackConnection loopbackConnection = await LoopbackServerFactory.CreateConnectionAsync(socket: null, serverConnection.Stream, options); await loopbackConnection.InitializeConnectionAsync(); @@ -137,13 +135,14 @@ public async Task CustomConnectionFactory_AsyncRequest_Success() Task clientTask = Task.Run(async () => { using HttpClientHandler handler = CreateHttpClientHandler(); - + handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; + var socketsHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); socketsHandler.ConnectionFactory = connectionFactory; using HttpClient client = CreateHttpClient(handler); - string response = await client.GetStringAsync($"{(useHttps ? "https" : "http")}://{Guid.NewGuid():N}.com/foo"); + string response = await client.GetStringAsync($"{(options.UseSsl ? "https" : "http")}://{Guid.NewGuid():N}.com/foo"); Assert.Equal("foo", response); }); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index bdf9887ad6c9..2c97dd43097e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -120,6 +120,8 @@ Link="Common\System\Net\TestWebProxies.cs" /> + Date: Mon, 3 Aug 2020 14:52:12 +0300 Subject: [PATCH 207/755] [wasm] Re-enable some Microsoft.Extensions.Logging.Tests tests on browser-wasm. (#40255) --- .../tests/ConsoleLoggerExtensionsTests.cs | 13 ------------- .../tests/Common/LoggerFactoryTest.cs | 1 - 2 files changed, 14 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs index 09388a106b5b..a5f02fe897c5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs @@ -76,7 +76,6 @@ public void AddConsoleFormatter_NullConfigure_Throws() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [MemberData(nameof(FormatterNames))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_ConsoleLoggerOptionsFromConfigFile_IsReadFromLoggingConfiguration(string formatterName) { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -96,7 +95,6 @@ public void AddConsole_ConsoleLoggerOptionsFromConfigFile_IsReadFromLoggingConfi } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsoleFormatter_CustomFormatter_IsReadFromLoggingConfiguration() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -156,7 +154,6 @@ private class CustomOptions : ConsoleFormatterOptions } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -187,7 +184,6 @@ public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() } [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[] { @@ -218,7 +214,6 @@ public void AddSimpleConsole_OutsideConfig_TakesProperty() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddSystemdConsole_ChangeProperties_IsReadFromLoggingConfiguration() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -245,7 +240,6 @@ public void AddSystemdConsole_ChangeProperties_IsReadFromLoggingConfiguration() } [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[] { @@ -276,7 +270,6 @@ public void AddSystemdConsole_OutsideConfig_TakesProperty() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddJsonConsole_ChangeProperties_IsReadFromLoggingConfiguration() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -305,7 +298,6 @@ public void AddJsonConsole_ChangeProperties_IsReadFromLoggingConfiguration() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddJsonConsole_OutsideConfig_TakesProperty() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -340,7 +332,6 @@ public void AddJsonConsole_OutsideConfig_TakesProperty() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_NullFormatterNameUsingSystemdFormat_AnyDeprecatedPropertiesOverwriteFormatterOptions() { var configs = new[] { @@ -366,7 +357,6 @@ public void AddConsole_NullFormatterNameUsingSystemdFormat_AnyDeprecatedProperti } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_NullFormatterName_UsingSystemdFormat_IgnoreFormatterOptionsAndUseDeprecatedInstead() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -399,7 +389,6 @@ public void AddConsole_NullFormatterName_UsingSystemdFormat_IgnoreFormatterOptio } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_NullFormatterName_UsingDefaultFormat_IgnoreFormatterOptionsAndUseDeprecatedInstead() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -442,7 +431,6 @@ public void AddConsole_NullFormatterName_UsingDefaultFormat_IgnoreFormatterOptio [InlineData("missingFormatter")] [InlineData("simple")] [InlineData("Simple")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_FormatterNameIsSet_UsingDefaultFormat_IgnoreDeprecatedAndUseFormatterOptionsInstead(string formatterName) { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { @@ -486,7 +474,6 @@ public void AddConsole_FormatterNameIsSet_UsingDefaultFormat_IgnoreDeprecatedAnd [InlineData("missingFormatter")] [InlineData("systemd")] [InlineData("Systemd")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddConsole_FormatterNameIsSet_UsingSystemdFormat_IgnoreDeprecatedAndUseFormatterOptionsInstead(string formatterName) { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs index 8e81ba231909..c124f36eaa24 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs @@ -198,7 +198,6 @@ public void TestActivityIds(ActivityTrackingOptions options) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void TestInvalidActivityTrackingOptions() { Assert.Throws(() => From 215db60d405f6a963121b54035a35163681ff5b7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 12:00:09 +0000 Subject: [PATCH 208/755] Update dependencies from https://github.com/dotnet/xharness build 20200802.1 (#40256) [master] Update dependencies from dotnet/xharness - Updates: - Microsoft.DotNet.XHarness.CLI: from 1.0.0-prerelease.20380.2 to 1.0.0-prerelease.20402.1 - Microsoft.DotNet.XHarness.TestRunners.Xunit: from 1.0.0-prerelease.20380.2 to 1.0.0-prerelease.20402.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2fa037a5ef67..6e2321c81bbc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -186,13 +186,13 @@ https://github.com/mono/linker 7c9b806037e88df7eb40a8151808730133676668 - + https://github.com/dotnet/xharness - 277bae290e5be657e4b8f2a5b77ab764e5cf9ccc + 2cb87a26217ee107e7d764770c44d986b4333c10 - + https://github.com/dotnet/xharness - 277bae290e5be657e4b8f2a5b77ab764e5cf9ccc + 2cb87a26217ee107e7d764770c44d986b4333c10 diff --git a/eng/Versions.props b/eng/Versions.props index fd0c5441fa07..626488d72481 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -131,8 +131,8 @@ 4.9.4 16.8.0-preview-20200730-03 - 1.0.0-prerelease.20380.2 - 1.0.0-prerelease.20380.2 + 1.0.0-prerelease.20402.1 + 1.0.0-prerelease.20402.1 2.4.1 2.4.2 1.3.0 From f3b82558eb5711ff65a0f21aab556599bf5a4cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 3 Aug 2020 16:05:00 +0200 Subject: [PATCH 209/755] Fix ICU_CFLAGS in mono configure.ac (#40263) We need to set these defines so we don't use obsolete ICU functions and cause warnings, just like we do in the CMakeLists.txt version.. --- src/mono/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 1c8d9ccd4415..8a9996eb7cf4 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -6884,7 +6884,7 @@ if test x$with_core = xonly; then if test x$have_shim_globalization = xyes || test x$cross_compiling = xyes; then ICU_SHIM_PATH=../../../libraries/Native/Unix/System.Globalization.Native if test x$target_wasm = xyes && test x$with_static_icu = xyes; then - ICU_CFLAGS="-DTARGET_UNIX -DU_DISABLE_RENAMING" + ICU_CFLAGS="-DTARGET_UNIX -DU_DISABLE_RENAMING -DHAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS -DHAVE_SET_MAX_VARIABLE" have_sys_icu=yes elif test x$target_osx = xyes; then ORIG_CPPFLAGS=$CPPFLAGS From f1911f345dfd2429c453ce5578b8721c9bcf97d7 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Mon, 3 Aug 2020 17:24:09 +0100 Subject: [PATCH 210/755] Fix nullable annotations for ImmutableArray cast methods (#40084) * Fix nullable annotations for ImmutableArray cast methods, Fixes #39799 * address feedback --- .../ref/System.Collections.Immutable.cs | 6 +++--- .../Collections/Immutable/ImmutableArray_1.Minimal.cs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index bd650bdc3235..c8daf5a07fd9 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -122,9 +122,9 @@ public partial struct ImmutableArray : System.Collections.Generic.ICollection public System.ReadOnlyMemory AsMemory() { throw null; } public System.ReadOnlySpan AsSpan() { throw null; } #endif - public System.Collections.Immutable.ImmutableArray As() where TOther : class { throw null; } - public System.Collections.Immutable.ImmutableArray CastArray() where TOther : class { throw null; } - public static System.Collections.Immutable.ImmutableArray CastUp(System.Collections.Immutable.ImmutableArray items) where TDerived : class, T { throw null; } + public System.Collections.Immutable.ImmutableArray As() where TOther : class? { throw null; } + public System.Collections.Immutable.ImmutableArray CastArray() where TOther : class? { throw null; } + public static System.Collections.Immutable.ImmutableArray CastUp(System.Collections.Immutable.ImmutableArray items) where TDerived : class?, T { throw null; } public System.Collections.Immutable.ImmutableArray Clear() { throw null; } public bool Contains(T item) { throw null; } public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length) { } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs index 93da9008ff8b..6210a0a9a1f8 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs @@ -334,7 +334,7 @@ public bool Equals(ImmutableArray other) /// or method. /// public static ImmutableArray CastUp(ImmutableArray items) - where TDerived : class, T + where TDerived : class?, T { return new ImmutableArray(items.array); } @@ -344,7 +344,7 @@ public static ImmutableArray CastUp(ImmutableArray items) /// array to an array of type . /// /// Thrown if the cast is illegal. - public ImmutableArray CastArray() where TOther : class + public ImmutableArray CastArray() where TOther : class? { return new ImmutableArray((TOther[])(object)array!); } @@ -364,9 +364,9 @@ public ImmutableArray CastArray() where TOther : class /// element types to their derived types. However, downcasting is only successful /// when it reverses a prior upcasting operation. /// - public ImmutableArray As() where TOther : class + public ImmutableArray As() where TOther : class? { - return new ImmutableArray((this.array as TOther[])!); + return new ImmutableArray((this.array as TOther[])); } /// From a1c19db3ff60d42b690db5b3d2ba866c99d41ffd Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Mon, 3 Aug 2020 18:28:48 +0200 Subject: [PATCH 211/755] IsSupported reports SocketsHttpHandler availability on different platforms (#40271) Fixes #39489 --- src/libraries/System.Net.Http/ref/System.Net.Http.cs | 1 + .../System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs | 2 ++ .../System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 8f72cd9665e7..f259892c5bc9 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -328,6 +328,7 @@ protected override void Dispose(bool disposing) { } public sealed partial class SocketsHttpHandler : System.Net.Http.HttpMessageHandler { public SocketsHttpHandler() { } + public static bool IsSupported { get { throw null; } } public bool AllowAutoRedirect { get { throw null; } set { } } public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } } public System.Net.Connections.ConnectionFactory? ConnectionFactory { get { throw null; } set { } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs index 8c462eea5f0c..2a1d63d35b15 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs @@ -12,6 +12,8 @@ namespace System.Net.Http { public sealed class SocketsHttpHandler : HttpMessageHandler { + public static bool IsSupported => false; + public bool UseCookies { get => throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 8eb5a9290750..db2cfedf2b1a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -35,6 +35,8 @@ private void CheckDisposedOrStarted() } } + public static bool IsSupported => true; + public bool UseCookies { get => _settings._useCookies; From dc764266f76f190cceb530dc15b7152ffdbc2b46 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 3 Aug 2020 10:26:34 -0700 Subject: [PATCH 212/755] fix ReceiveMessageFromPacketInfo in DualMode ReceiveMessageFromAsync (#39249) * add test * fix dual mode on windows * fix linux * Update src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs --- .../Sockets/SocketAsyncEventArgs.Windows.cs | 8 +-- .../System/Net/Sockets/SocketPal.Windows.cs | 7 ++- .../FunctionalTests/DualModeSocketTest.cs | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index 0c4b0fce6a86..6368666ec6bf 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -486,13 +486,13 @@ internal unsafe SocketError DoOperationReceiveMessageFrom(Socket socket, SafeSoc bool ipv4 = (_currentSocket!.AddressFamily == AddressFamily.InterNetwork || (ipAddress != null && ipAddress.IsIPv4MappedToIPv6)); // DualMode bool ipv6 = _currentSocket.AddressFamily == AddressFamily.InterNetworkV6; - if (ipv4 && (_controlBufferPinned == null || _controlBufferPinned.Length != sizeof(Interop.Winsock.ControlData))) + if (ipv6 && (_controlBufferPinned == null || _controlBufferPinned.Length != sizeof(Interop.Winsock.ControlDataIPv6))) { - _controlBufferPinned = GC.AllocateUninitializedArray(sizeof(Interop.Winsock.ControlData), pinned: true); + _controlBufferPinned = GC.AllocateUninitializedArray(sizeof(Interop.Winsock.ControlDataIPv6), pinned: true); } - else if (ipv6 && (_controlBufferPinned == null || _controlBufferPinned.Length != sizeof(Interop.Winsock.ControlDataIPv6))) + else if (ipv4 && (_controlBufferPinned == null || _controlBufferPinned.Length != sizeof(Interop.Winsock.ControlData))) { - _controlBufferPinned = GC.AllocateUninitializedArray(sizeof(Interop.Winsock.ControlDataIPv6), pinned: true); + _controlBufferPinned = GC.AllocateUninitializedArray(sizeof(Interop.Winsock.ControlData), pinned: true); } // If single buffer we need a single element WSABuffer. diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs index d68f47cf3777..1d7947523b12 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs @@ -436,6 +436,12 @@ public static unsafe IPPacketInformation GetIPPacketInformation(Interop.Winsock. public static unsafe IPPacketInformation GetIPPacketInformation(Interop.Winsock.ControlDataIPv6* controlBuffer) { + if (controlBuffer->length == (UIntPtr)sizeof(Interop.Winsock.ControlData)) + { + // IPv4 client connectiong to dual mode socket. + return GetIPPacketInformation((Interop.Winsock.ControlData*)controlBuffer); + } + IPAddress address = controlBuffer->length != UIntPtr.Zero ? new IPAddress(new ReadOnlySpan(controlBuffer->address, Interop.Winsock.IPv6AddressLength)) : IPAddress.IPv6None; @@ -451,7 +457,6 @@ public static unsafe SocketError ReceiveMessageFrom(Socket socket, SafeSocketHan bytesTransferred = 0; receiveAddress = socketAddress; ipPacketInformation = default(IPPacketInformation); - fixed (byte* ptrBuffer = buffer) fixed (byte* ptrSocketAddress = socketAddress.Buffer) { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs index fa81b0194b59..38ea1a28c108 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs @@ -1947,6 +1947,60 @@ public void ReceiveMessageFromV4BoundToAnyV6_Success() ReceiveMessageFrom_Helper(IPAddress.IPv6Any, IPAddress.Loopback); } + [Theory] + [InlineData(true)] + [InlineData(false)] + [PlatformSpecific(~TestPlatforms.OSX)] // ReceiveMessageFrom not supported on OSX + public void ReceiveMessageFromAsync_SocketAsyncEventArgs_Success(bool ipv4) + { + const int DataLength = 10; + AddressFamily family = ipv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; + IPAddress loopback = ipv4 ? IPAddress.Loopback : IPAddress.Loopback.MapToIPv6(); + IPAddress clientAddress = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; + + var completed = new ManualResetEventSlim(false); + using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) + using (var receiver = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp)) + { + receiver.DualMode = true; + receiver.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true); + receiver.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true); + int receiverPort = receiver.BindToAnonymousPort(IPAddress.IPv6Any); + + if (!ipv4) + { + sender.DualMode = true; + } + + int senderPort = sender.BindToAnonymousPort(loopback); + var expectedEP = new IPEndPoint(IPAddress.Loopback.MapToIPv6(), senderPort); + + var args = new SocketAsyncEventArgs() { RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Any, 0) }; + args.Completed += (s, e) => { Console.WriteLine("Got 1 packet {0} {1}", e.RemoteEndPoint, e.ReceiveMessageFromPacketInfo.Address); completed.Set(); }; + args.SetBuffer(new byte[DataLength], 0, DataLength); + + var ep = new IPEndPoint(loopback, receiverPort); + for (int iters = 0; iters < 5; iters++) + { + for (int i = 0; i < TestSettings.UDPRedundancy; i++) + { + sender.SendTo(new byte[DataLength], ep); + } + + if (!receiver.ReceiveMessageFromAsync(args)) + { + completed.Set(); + } + Assert.True(completed.Wait(TestSettings.PassingTestTimeout), "Timeout while waiting for connection"); + completed.Reset(); + + Assert.Equal(DataLength, args.BytesTransferred); + Assert.Equal(expectedEP, args.RemoteEndPoint); + Assert.True(args.ReceiveMessageFromPacketInfo.Address.Equals(IPAddress.Loopback) || args.ReceiveMessageFromPacketInfo.Address.Equals(IPAddress.Loopback.MapToIPv6())); + } + } + } + private void ReceiveMessageFrom_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false) { using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp)) From df7f985f44712efd46b8b3bc5e4d83fe3d83ed4b Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 3 Aug 2020 10:54:37 -0700 Subject: [PATCH 213/755] Allow increased log level filtering for event source logger (#40165) --- .../src/LoggingEventSource.cs | 64 +++++++---- .../tests/EventSourceLoggerTest.cs | 107 ++++++++++++++++++ 2 files changed, 146 insertions(+), 25 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs index d62ff6e7fe96..a8bb22212705 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs @@ -31,7 +31,9 @@ namespace Microsoft.Extensions.Logging.EventSource /// /// SPEC = // empty spec, same as * /// | NAME // Just a name the level is the default level - /// | NAME : LEVEL // specifies level for a particular logger (can have a * suffix). + /// | NAME : LEVEL // specifies level for a particular logger (can have a * suffix). + /// + /// When "UseAppFilters" is specified in the FilterSpecs, it avoids disabling all categories which happens by default otherwise. /// /// Where Name is the name of a ILoggger (case matters), Name can have a * which acts as a wildcard /// AS A SUFFIX. Thus Net* will match any loggers that start with the 'Net'. @@ -111,6 +113,7 @@ public static class Keywords // having assignment in ctor would overwrite the value private LoggerFilterRule[] _filterSpec = Array.Empty(); private CancellationTokenSource _cancellationTokenSource; + private const string UseAppFilters = "UseAppFilters"; private LoggingEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat) { @@ -336,39 +339,50 @@ private static LoggerFilterRule[] ParseFilterSpec(string filterSpec, LogLevel de return new[] { new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, null, defaultLevel, null) }; } - var rules = new List(); + if (filterSpec == null) + { + // All event source loggers are disabled by default + return new[] { new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, null, LogLevel.None, null) }; + } - // All event source loggers are disabled by default - rules.Add(new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, null, LogLevel.None, null)); + var rules = new List(); + int ruleStringsStartIndex = 0; + string[] ruleStrings = filterSpec.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + if (ruleStrings.Length > 0 && ruleStrings[0].Equals(UseAppFilters, StringComparison.OrdinalIgnoreCase)) + { + // Avoid adding default rule to disable event source loggers + ruleStringsStartIndex = 1; + } + else + { + rules.Add(new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, null, LogLevel.None, null)); + } - if (filterSpec != null) + for (int i = ruleStringsStartIndex; i < ruleStrings.Length; i++) { - string[] ruleStrings = filterSpec.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string rule in ruleStrings) + string rule = ruleStrings[i]; + LogLevel level = defaultLevel; + string[] parts = rule.Split(new[] { ':' }, 2); + string loggerName = parts[0]; + if (loggerName.Length == 0) { - LogLevel level = defaultLevel; - string[] parts = rule.Split(new[] { ':' }, 2); - string loggerName = parts[0]; - if (loggerName.Length == 0) - { - continue; - } + continue; + } - if (loggerName[loggerName.Length - 1] == '*') - { - loggerName = loggerName.Substring(0, loggerName.Length - 1); - } + if (loggerName[loggerName.Length - 1] == '*') + { + loggerName = loggerName.Substring(0, loggerName.Length - 1); + } - if (parts.Length == 2) + if (parts.Length == 2) + { + if (!TryParseLevel(defaultLevel, parts[1], out level)) { - if (!TryParseLevel(defaultLevel, parts[1], out level)) - { - continue; - } + continue; } - - rules.Add(new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, loggerName, level, null)); } + + rules.Add(new LoggerFilterRule(typeof(EventSourceLoggerProvider).FullName, loggerName, level, null)); } return rules.ToArray(); diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs index f015f06a05c0..6c4543c05d4f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs @@ -53,6 +53,113 @@ public void IsEnabledReturnsCorrectValue() } } + [Fact] + public void FilterSpecs_UseAppFilters_IncreaseLoggingLevelForOneCategory_GuaranteesAllRulesRemainAvailable() + { + using (var testListener = new TestEventListener()) + { + var loggerFactory = LoggerFactory.Create(builder => + builder + .AddEventSourceLogger() + .AddFilter("Logger1*", LogLevel.Warning) + .AddFilter("Logger2*", LogLevel.Error) + .AddFilter("Logger3*", LogLevel.Critical) + .AddFilter("Logger4*", LogLevel.Error) + ); + + var listenerSettings = new TestEventListener.ListenerSettings(); + listenerSettings.FilterSpec = "UseAppFilters;Logger3:1"; + testListener.EnableEvents(listenerSettings); + + var logger = loggerFactory.CreateLogger("Logger1"); + var logger2 = loggerFactory.CreateLogger("Logger2"); + var logger3 = loggerFactory.CreateLogger("Logger3"); + var logger4 = loggerFactory.CreateLogger("Logger4"); + + Assert.False(logger.IsEnabled(LogLevel.None)); + Assert.True(logger.IsEnabled(LogLevel.Critical)); + Assert.True(logger.IsEnabled(LogLevel.Error)); + Assert.True(logger.IsEnabled(LogLevel.Warning)); + Assert.False(logger.IsEnabled(LogLevel.Information)); + Assert.False(logger.IsEnabled(LogLevel.Debug)); + Assert.False(logger.IsEnabled(LogLevel.Trace)); + + Assert.False(logger2.IsEnabled(LogLevel.None)); + Assert.True(logger2.IsEnabled(LogLevel.Critical)); + Assert.True(logger2.IsEnabled(LogLevel.Error)); + Assert.False(logger2.IsEnabled(LogLevel.Warning)); + Assert.False(logger2.IsEnabled(LogLevel.Information)); + Assert.False(logger2.IsEnabled(LogLevel.Debug)); + Assert.False(logger2.IsEnabled(LogLevel.Trace)); + + Assert.False(logger3.IsEnabled(LogLevel.None)); + Assert.True(logger3.IsEnabled(LogLevel.Critical)); + Assert.True(logger3.IsEnabled(LogLevel.Error)); + Assert.True(logger3.IsEnabled(LogLevel.Warning)); + Assert.True(logger3.IsEnabled(LogLevel.Information)); + Assert.True(logger3.IsEnabled(LogLevel.Debug)); + Assert.False(logger3.IsEnabled(LogLevel.Trace)); + + Assert.False(logger4.IsEnabled(LogLevel.None)); + Assert.True(logger4.IsEnabled(LogLevel.Critical)); + Assert.True(logger4.IsEnabled(LogLevel.Error)); + Assert.False(logger4.IsEnabled(LogLevel.Warning)); + Assert.False(logger4.IsEnabled(LogLevel.Information)); + Assert.False(logger4.IsEnabled(LogLevel.Debug)); + Assert.False(logger4.IsEnabled(LogLevel.Trace)); + } + } + + [Theory] + [InlineData("")] + [InlineData("UseAppFilters_StartsThisWay:Debug;")] + public void FilterSpecs_IncreaseLoggingLevelForOneCategory_DisablesExistingRulesByDefault(string prefix) + { + using (var testListener = new TestEventListener()) + { + var loggerFactory = LoggerFactory.Create(builder => + builder + .AddEventSourceLogger() + .AddFilter("Logger1*", LogLevel.Warning) + .AddFilter("Logger2*", LogLevel.Error) + .AddFilter("Logger3*", LogLevel.Critical) + .AddFilter("Logger4*", LogLevel.Error) + ); + + var listenerSettings = new TestEventListener.ListenerSettings(); + listenerSettings.FilterSpec = prefix + "Logger3:1"; + testListener.EnableEvents(listenerSettings); + + var logger = loggerFactory.CreateLogger("Logger1"); + var logger2 = loggerFactory.CreateLogger("Logger2"); + var logger3 = loggerFactory.CreateLogger("Logger3"); + var logger4 = loggerFactory.CreateLogger("Logger4"); + + foreach (LogLevel level in Enum.GetValues(typeof(LogLevel))) + { + Assert.False(logger.IsEnabled(LogLevel.None)); + Assert.False(logger2.IsEnabled(LogLevel.None)); + } + + Assert.False(logger3.IsEnabled(LogLevel.None)); + Assert.True(logger3.IsEnabled(LogLevel.Critical)); + Assert.True(logger3.IsEnabled(LogLevel.Error)); + Assert.True(logger3.IsEnabled(LogLevel.Warning)); + Assert.True(logger3.IsEnabled(LogLevel.Information)); + Assert.True(logger3.IsEnabled(LogLevel.Debug)); + Assert.False(logger3.IsEnabled(LogLevel.Trace)); + + // Note: default disabling rule does not take precedence on filter rules that specify both a provider and a category + Assert.False(logger4.IsEnabled(LogLevel.None)); + Assert.True(logger4.IsEnabled(LogLevel.Critical)); + Assert.True(logger4.IsEnabled(LogLevel.Error)); + Assert.False(logger4.IsEnabled(LogLevel.Warning)); + Assert.False(logger4.IsEnabled(LogLevel.Information)); + Assert.False(logger4.IsEnabled(LogLevel.Debug)); + Assert.False(logger4.IsEnabled(LogLevel.Trace)); + } + } + [Fact] public void Logs_AsExpected_WithDefaults() { From bb712235cc32806012d1fed5842da409dfea91ac Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Mon, 3 Aug 2020 12:46:34 -0700 Subject: [PATCH 214/755] Generating the verison and other macros on the fly (#39670) * generating the header on the fly * add feedback from other pr * simplify includePath * address feedbacl * simplify the includePath code --- .../System.Runtime.CompilerServices.Unsafe.il | 4 +- ...tem.Runtime.CompilerServices.Unsafe.ilproj | 58 ++++++++++++++++++- .../src/include/net5.0/coreassembly.h | 9 --- .../src/include/netcoreapp2.0/coreassembly.h | 9 --- .../src/include/netfx/coreassembly.h | 9 --- .../src/include/netstandard1.0/coreassembly.h | 8 --- .../src/include/netstandard2.0/coreassembly.h | 20 ------- 7 files changed, 57 insertions(+), 60 deletions(-) delete mode 100644 src/libraries/System.Runtime.CompilerServices.Unsafe/src/include/net5.0/coreassembly.h delete mode 100644 src/libraries/System.Runtime.CompilerServices.Unsafe/src/include/netcoreapp2.0/coreassembly.h delete mode 100644 src/libraries/System.Runtime.CompilerServices.Unsafe/src/include/netfx/coreassembly.h delete mode 100644 src/libraries/System.Runtime.CompilerServices.Unsafe/src/include/netstandard1.0/coreassembly.h delete mode 100644 src/libraries/System.Runtime.CompilerServices.Unsafe/src/include/netstandard2.0/coreassembly.h diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index 51e4105a138f..fe3df674c114 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#include "coreassembly.h" +#include "version.h" .assembly System.Runtime.CompilerServices.Unsafe { @@ -40,7 +40,7 @@ 01 00 00 00 00 ) // false .hash algorithm 0x00008004 - .ver 5:0:0:0 + .ver ASSEMBLY_VERSION } .module System.Runtime.CompilerServices.Unsafe.dll // MVID: {1E97D84A-565B-49C5-B60A-F31A1A4ACE13} diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj index e019c46d2697..de3e21defc6c 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj @@ -5,13 +5,19 @@ OPT + $(CoreCompileDependsOn);GenerateVersionFile $(MSBuildThisFileDirectory)System.Runtime.CompilerServices.Unsafe.xml {04BA3E3C-6979-4792-B19E-C797AD607F42} - include\$(TargetFramework) - include\netfx - $(IlasmFlags) -INCLUDE=$(IncludePath) -DEBUG=$(DebugOptimization) + #define netcoreapp + $(IlasmFlags) -DEBUG=$(DebugOptimization) $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.0;netstandard1.0;net45 true + System.Runtime + netstandard + + + mscorlib + #define net45 @@ -21,6 +27,52 @@ + + + $([MSBuild]::NormalizeDirectory('$(IntermediateOutputPath)', 'version')) + $(IlasmFlags) -INCLUDE=$(IncludePath) + $([MSBuild]::NormalizePath('$(IncludePath)', 'version.h')) + <_AssemblyVersion>$(AssemblyVersion.Replace('.', ':')) + <_coreAssemblyName Condition="'%(ReferencePath.FileName)' == '$(CoreAssembly)'">%(ReferencePath.FusionName) + <_assemblyNamePattern>[0-9]+)\.(?[0-9]+)\.(?[0-9]+)\.(?[0-9]+), .*PublicKeyToken=(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})]]> + <_coreAssemblyVersion>$([System.Text.RegularExpressions.Regex]::Replace( + $(_coreAssemblyName), + $(_assemblyNamePattern), + '${v1}:${v2}:${v3}:${v4}')) + <_coreAssemblyPublicKeyToken>$([System.Text.RegularExpressions.Regex]::Replace( + $(_coreAssemblyName), + $(_assemblyNamePattern), + '${p1} ${p2} ${p3} ${p4} ${p5} ${p6} ${p7} ${p8}').ToUpperInvariant()) + <_VersionFileContents> + + + + + + + + + + + Date: Mon, 3 Aug 2020 13:03:23 -0700 Subject: [PATCH 215/755] Type verification in tests (#40186) - Enable type layout verification in crossgen2 test passes Product bugs found/fixed - Fix type blittability issue found during enabling this test. - HFA encoding was not correct for Arm64, and did not have R2R defined constants - Fix type layout verification infrastructure issues - Do not generate type layout checks or verification if the offset is 24 bits or larger - Only load approx enclosing type when verifying, instead of enclosing type (this avoids asserts) --- src/coreclr/src/inc/readytorun.h | 9 +++ .../Internal/Runtime/ReadyToRunConstants.cs | 11 ++++ .../ReadyToRun/FieldFixupSignature.cs | 5 +- .../ReadyToRun/TypeFixupSignature.cs | 14 ++--- .../ReadyToRunSymbolNodeFactory.cs | 8 +-- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 15 +++-- src/coreclr/src/vm/fieldmarshaler.cpp | 2 +- src/coreclr/src/vm/jitinterface.cpp | 11 ++-- src/coreclr/src/zap/zapreadytorun.cpp | 10 ++++ .../tests/src/CLRTest.CrossGen.targets | 2 + src/tests/readytorun/crossgen2/Program.cs | 56 +++++++++++++++++++ 11 files changed, 119 insertions(+), 24 deletions(-) diff --git a/src/coreclr/src/inc/readytorun.h b/src/coreclr/src/inc/readytorun.h index b883f4b558e9..e1719a2843eb 100644 --- a/src/coreclr/src/inc/readytorun.h +++ b/src/coreclr/src/inc/readytorun.h @@ -395,4 +395,13 @@ enum ReadyToRunRuntimeConstants : DWORD READYTORUN_ReversePInvokeTransitionFrameSizeInPointerUnits = 2 }; +enum ReadyToRunHFAElemType : DWORD +{ + READYTORUN_HFA_ELEMTYPE_None = 0, + READYTORUN_HFA_ELEMTYPE_Float32 = 1, + READYTORUN_HFA_ELEMTYPE_Float64 = 2, + READYTORUN_HFA_ELEMTYPE_Vector64 = 3, + READYTORUN_HFA_ELEMTYPE_Vector128 = 4, +}; + #endif // __READYTORUN_H__ diff --git a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index ce6de5de37ca..6d92e7b5d122 100644 --- a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -314,6 +314,17 @@ public enum ReadyToRunHelper TypeHandleToRuntimeTypeHandle, } + // Enum used for HFA type recognition. + // Supported across architectures, so that it can be used in altjits and cross-compilation. + public enum ReadyToRunHFAElemType + { + None = 0, + Float32 = 1, + Float64 = 2, + Vector64 = 3, + Vector128 = 4, + } + public static class ReadyToRunRuntimeConstants { public const int READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11; diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs index ebeb537f5f15..eb5431f29e52 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; using Internal.JitInterface; using Internal.Text; @@ -13,17 +14,19 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun { public class FieldFixupSignature : Signature { + public const int MaxCheckableOffset = 0x1FFFFFFF; private readonly ReadyToRunFixupKind _fixupKind; private readonly FieldDesc _fieldDesc; - public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldDesc fieldDesc) + public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldDesc fieldDesc, NodeFactory factory) { _fixupKind = fixupKind; _fieldDesc = fieldDesc; // Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature ((CompilerTypeSystemContext)fieldDesc.Context).EnsureLoadableType(fieldDesc.OwningType); + Debug.Assert(factory.SignatureContext.GetTargetModule(_fieldDesc) != null); } public override int ClassCode => 271828182; diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs index 0bc86c7794cb..ea21b730330b 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs @@ -81,16 +81,16 @@ private static void EncodeTypeLayout(ObjectDataSignatureBuilder dataBuilder, Typ if (defType.IsHomogeneousAggregate) { - CorElementType elementType = (defType.ValueTypeShapeCharacteristics & ValueTypeShapeCharacteristics.AggregateMask) switch + ReadyToRunHFAElemType hfaElementType = (defType.ValueTypeShapeCharacteristics & ValueTypeShapeCharacteristics.AggregateMask) switch { - ValueTypeShapeCharacteristics.Float32Aggregate => CorElementType.ELEMENT_TYPE_R4, - ValueTypeShapeCharacteristics.Float64Aggregate => CorElementType.ELEMENT_TYPE_R8, - ValueTypeShapeCharacteristics.Vector64Aggregate => CorElementType.ELEMENT_TYPE_R8, + ValueTypeShapeCharacteristics.Float32Aggregate => ReadyToRunHFAElemType.Float32, + ValueTypeShapeCharacteristics.Float64Aggregate => ReadyToRunHFAElemType.Float64, + ValueTypeShapeCharacteristics.Vector64Aggregate => ReadyToRunHFAElemType.Vector64, // See MethodTable::GetHFAType - ValueTypeShapeCharacteristics.Vector128Aggregate => CorElementType.ELEMENT_TYPE_VALUETYPE, - _ => CorElementType.Invalid + ValueTypeShapeCharacteristics.Vector128Aggregate => ReadyToRunHFAElemType.Vector128, + _ => throw new NotSupportedException() }; - dataBuilder.EmitUInt((uint)elementType); + dataBuilder.EmitUInt((uint)hfaElementType); } if (alignment != pointerSize) diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs index 7ae68230d8a6..1178d4372c33 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs @@ -70,7 +70,7 @@ private void CreateNodeCaches() _codegenNodeFactory, _codegenNodeFactory.HelperImports, ReadyToRunHelper.DelayLoad_Helper, - new FieldFixupSignature(ReadyToRunFixupKind.FieldAddress, key) + new FieldFixupSignature(ReadyToRunFixupKind.FieldAddress, key, _codegenNodeFactory) ); }); @@ -78,7 +78,7 @@ private void CreateNodeCaches() { return new PrecodeHelperImport( _codegenNodeFactory, - new FieldFixupSignature(ReadyToRunFixupKind.FieldOffset, key) + new FieldFixupSignature(ReadyToRunFixupKind.FieldOffset, key, _codegenNodeFactory) ); }); @@ -94,7 +94,7 @@ private void CreateNodeCaches() { return new PrecodeHelperImport( _codegenNodeFactory, - new FieldFixupSignature(_verifyTypeAndFieldLayout ? ReadyToRunFixupKind.Verify_FieldOffset : ReadyToRunFixupKind.Check_FieldOffset, key) + new FieldFixupSignature(_verifyTypeAndFieldLayout ? ReadyToRunFixupKind.Verify_FieldOffset : ReadyToRunFixupKind.Check_FieldOffset, key, _codegenNodeFactory) ); }); @@ -356,7 +356,7 @@ private ISymbolNode CreateFieldHandleHelper(FieldDesc field) { return new PrecodeHelperImport( _codegenNodeFactory, - new FieldFixupSignature(ReadyToRunFixupKind.FieldHandle, field)); + new FieldFixupSignature(ReadyToRunFixupKind.FieldHandle, field, _codegenNodeFactory)); } private ISymbolNode CreateCctorTrigger(TypeDesc type) diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 2c2085635f34..57c4b738d690 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1012,7 +1012,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET CorInfoHelpFunc.CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE); } - if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) + if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); @@ -1066,7 +1066,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET else if (helperId != ReadyToRunHelperId.Invalid) { - if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) + if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); @@ -1922,7 +1922,7 @@ private bool NeedsTypeLayoutCheck(TypeDesc type) if (!type.IsValueType) return false; - return !_compilation.IsLayoutFixedInCurrentVersionBubble(type) || _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout; + return !_compilation.IsLayoutFixedInCurrentVersionBubble(type) || (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !((MetadataType)type).IsNonVersionable()); } private bool HasLayoutMetadata(TypeDesc type) @@ -1963,6 +1963,9 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (pMT.IsValueType) { // ENCODE_CHECK_FIELD_OFFSET + if (pResult->offset > FieldFixupSignature.MaxCheckableOffset) + throw new RequiresRuntimeJitException(callerMethod.ToString() + " -> " + field.ToString()); + _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); // No-op other than generating the check field offset fixup } @@ -1978,7 +1981,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, } else if (pMT.IsValueType) { - if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) + if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); @@ -1987,7 +1990,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, } else if (_compilation.IsInheritanceChainLayoutFixedInCurrentVersionBubble(pMT.BaseType)) { - if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) + if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); @@ -2009,7 +2012,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { PreventRecursiveFieldInlinesOutsideVersionBubble(field, callerMethod); - if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) + if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); diff --git a/src/coreclr/src/vm/fieldmarshaler.cpp b/src/coreclr/src/vm/fieldmarshaler.cpp index 4b1b7abc39ca..47a0f2693f14 100644 --- a/src/coreclr/src/vm/fieldmarshaler.cpp +++ b/src/coreclr/src/vm/fieldmarshaler.cpp @@ -277,7 +277,7 @@ bool IsFieldBlittable( } else { - isBlittable = !valueTypeHandle.GetMethodTable()->HasInstantiation() && valueTypeHandle.GetMethodTable()->IsBlittable(); + isBlittable = valueTypeHandle.GetMethodTable()->IsBlittable(); } break; default: diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 9e3c9180ef0b..9dc409db9ad5 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -13840,7 +13840,8 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, DWORD baseOffset = CorSigUncompressData(pBlob); DWORD fieldOffset = CorSigUncompressData(pBlob); FieldDesc* pField = ZapSig::DecodeField(currentModule, pInfoModule, pBlob); - pField->GetEnclosingMethodTable()->CheckRestore(); + MethodTable *pEnclosingMT = pField->GetApproxEnclosingMethodTable(); + pEnclosingMT->CheckRestore(); DWORD actualFieldOffset = pField->GetOffset(); if (!pField->IsStatic() && !pField->IsFieldOfValueType()) { @@ -13849,10 +13850,10 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, DWORD actualBaseOffset = 0; if (!pField->IsStatic() && - pField->GetEnclosingMethodTable()->GetParentMethodTable() != NULL && - !pField->GetEnclosingMethodTable()->IsValueType()) + pEnclosingMT->GetParentMethodTable() != NULL && + !pEnclosingMT->IsValueType()) { - actualBaseOffset = ReadyToRunInfo::GetFieldBaseOffset(pField->GetEnclosingMethodTable()); + actualBaseOffset = ReadyToRunInfo::GetFieldBaseOffset(pEnclosingMT); } if ((fieldOffset != actualFieldOffset) || (baseOffset != actualBaseOffset)) @@ -13863,7 +13864,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, SString fatalErrorString; fatalErrorString.Printf(W("Verify_FieldOffset '%s.%s' %d!=%d || %d!=%d"), - GetFullyQualifiedNameForClassW(pField->GetEnclosingMethodTable()), + GetFullyQualifiedNameForClassW(pEnclosingMT), ssFieldName.GetUnicode(), fieldOffset, actualFieldOffset, diff --git a/src/coreclr/src/zap/zapreadytorun.cpp b/src/coreclr/src/zap/zapreadytorun.cpp index e36d4aee6eaf..d5bb25ab1b6a 100644 --- a/src/coreclr/src/zap/zapreadytorun.cpp +++ b/src/coreclr/src/zap/zapreadytorun.cpp @@ -851,3 +851,13 @@ static_assert_no_msg((int)READYTORUN_FIXUP_Verify_TypeLayout == (int)EN // static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_LOOKUP_TABLE_ENTRY) == sizeof(CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY)); static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_CLAUSE) == sizeof(CORCOMPILE_EXCEPTION_CLAUSE)); + +// +// ReadyToRunHFAElemType +// +static_assert_no_msg((int)READYTORUN_HFA_ELEMTYPE_None == (int)CORINFO_HFA_ELEM_NONE); +static_assert_no_msg((int)READYTORUN_HFA_ELEMTYPE_Float32 == (int)CORINFO_HFA_ELEM_FLOAT); +static_assert_no_msg((int)READYTORUN_HFA_ELEMTYPE_Float64 == (int)CORINFO_HFA_ELEM_DOUBLE); +static_assert_no_msg((int)READYTORUN_HFA_ELEMTYPE_Vector64 == (int)CORINFO_HFA_ELEM_VECTOR64); +static_assert_no_msg((int)READYTORUN_HFA_ELEMTYPE_Vector128 == (int)CORINFO_HFA_ELEM_VECTOR128); + diff --git a/src/coreclr/tests/src/CLRTest.CrossGen.targets b/src/coreclr/tests/src/CLRTest.CrossGen.targets index 3460ed5f6f7a..3fd4b4a530c9 100644 --- a/src/coreclr/tests/src/CLRTest.CrossGen.targets +++ b/src/coreclr/tests/src/CLRTest.CrossGen.targets @@ -111,6 +111,7 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then echo -r:$CORE_ROOT/System.*.dll>>$__ResponseFile echo -r:$CORE_ROOT/Microsoft.*.dll>>$__ResponseFile echo -r:$CORE_ROOT/mscorlib.dll>>$__ResponseFile + echo --verify-type-and-field-layout>>$__ResponseFile echo --targetarch:$(TargetArchitecture)>>$__ResponseFile echo -O>>$__ResponseFile @@ -249,6 +250,7 @@ if defined RunCrossGen2 ( echo !__InputFile!>>!__ResponseFile! echo -o:!__OutputFile!>>!__ResponseFile! echo --targetarch:$(TargetArchitecture)>>!__ResponseFile! + echo --verify-type-and-field-layout>>!__ResponseFile! echo -O>>!__ResponseFile! echo -r:!CORE_ROOT!\System.*.dll>>!__ResponseFile! echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__ResponseFile! diff --git a/src/tests/readytorun/crossgen2/Program.cs b/src/tests/readytorun/crossgen2/Program.cs index e2da74337546..16ab7df575a9 100644 --- a/src/tests/readytorun/crossgen2/Program.cs +++ b/src/tests/readytorun/crossgen2/Program.cs @@ -1765,6 +1765,61 @@ private static bool ArrayLdtokenTests() return true; } + [StructLayout(LayoutKind.Explicit)] + struct ExplicitLayoutStruct16 + { + [FieldOffset(0)] + public int x; + [FieldOffset(4)] + public int y; + [FieldOffset(8)] + public int z; + [FieldOffset(12)] + public int w; + public override string ToString() { return $"{x}{y}{z}{w}"; } + } + struct BlittableStruct + { + public ExplicitLayoutStruct16 _explict; + public override string ToString() { return $"{_explict}"; } + } + + struct StructWithGenericBlittableStruct + { + public BlittableStruct _blittableGeneric; + public int _int; + public override string ToString() { return $"{_blittableGeneric}{_int}"; } + } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + private static bool TestWithStructureNonBlittableFieldDueToGenerics_StringCompare(ref StructWithGenericBlittableStruct input) + { + StructWithGenericBlittableStruct s = new StructWithGenericBlittableStruct(); + s._blittableGeneric._explict.x = 1; + s._blittableGeneric._explict.y = 2; + s._blittableGeneric._explict.z = 3; + s._blittableGeneric._explict.w = 4; + s._int = 5; + + Console.WriteLine(input); + Console.WriteLine(s); + + return s.Equals(input) && input.ToString() == "12345"; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool TestWithStructureNonBlittableFieldDueToGenerics() + { + StructWithGenericBlittableStruct s = new StructWithGenericBlittableStruct(); + s._blittableGeneric._explict.x = 1; + s._blittableGeneric._explict.y = 2; + s._blittableGeneric._explict.z = 3; + s._blittableGeneric._explict.w = 4; + s._int = 5; + + return TestWithStructureNonBlittableFieldDueToGenerics_StringCompare(ref s); + } + public static int Main(string[] args) { _passedTests = new List(); @@ -1832,6 +1887,7 @@ public static int Main(string[] args) RunTest("GenericLdtokenTest", GenericLdtokenTest()); RunTest("ArrayLdtokenTests", ArrayLdtokenTests()); RunTest("TestGenericMDArrayBehavior", TestGenericMDArrayBehavior()); + RunTest("TestWithStructureNonBlittableFieldDueToGenerics", TestWithStructureNonBlittableFieldDueToGenerics()); File.Delete(TextFileName); From fa5a4435966c8899d20959df224cabdee8e6e178 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 3 Aug 2020 15:08:04 -0500 Subject: [PATCH 216/755] Fix the trimming tests to link non-app assemblies correctly. (#40246) The PrepareForILLink target will pass any ManagedAssemblyToLink that isn't marked as IsTrimmable=true to a TrimmerRootAssembly. This will cause the assembly to be passed to the linker with `-a`, which means the asesmbly won't be fully trimmed. So any assembly outside of the runtimepack will be passed with -a (for example Microsoft.Extensions.*). Fix this by moving to BeforeTargets=PrepareForILLink and marking the single application assembly as a root. --- eng/testing/linker/SupportFiles/Directory.Build.targets | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eng/testing/linker/SupportFiles/Directory.Build.targets b/eng/testing/linker/SupportFiles/Directory.Build.targets index 49422a33b9be..a9dfda8012d9 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.targets +++ b/eng/testing/linker/SupportFiles/Directory.Build.targets @@ -20,11 +20,14 @@ + BeforeTargets="PrepareForILLink"> link + + + From 436fd91c3f820126e9eee8147c9873dff53ea2c9 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 3 Aug 2020 13:08:46 -0700 Subject: [PATCH 217/755] fix regression in ChannelBinding/NTLM auth (#40222) * fix regression in ChannelBinding/NTLM auth * fix index --- .../Windows/SspiCli/SecuritySafeHandles.cs | 92 ++++++++++++++----- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs index bef2693adb88..40ef8b2c8811 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs @@ -453,28 +453,50 @@ internal static unsafe int InitializeSecurityContext( if (inSecBuffers.Count > 2) { inUnmanagedBuffer[2].BufferType = inSecBuffers._item2.Type; - inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length; - inUnmanagedBuffer[2].pvBuffer = inSecBuffers._item2.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken2; + if (inSecBuffers._item2.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item2.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[2].pvBuffer = (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[2].cbBuffer = ((ChannelBinding)inSecBuffers._item2.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length; + inUnmanagedBuffer[2].pvBuffer = (IntPtr)pinnedToken2; + } + } if (inSecBuffers.Count > 1) { inUnmanagedBuffer[1].BufferType = inSecBuffers._item1.Type; - inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length; - inUnmanagedBuffer[1].pvBuffer = inSecBuffers._item1.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken1; + if (inSecBuffers._item1.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item1.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[1].pvBuffer = (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[1].cbBuffer = ((ChannelBinding)inSecBuffers._item1.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length; + inUnmanagedBuffer[1].pvBuffer = (IntPtr)pinnedToken1; + } } if (inSecBuffers.Count > 0) { inUnmanagedBuffer[0].BufferType = inSecBuffers._item0.Type; - inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length; - inUnmanagedBuffer[0].pvBuffer = inSecBuffers._item0.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken0; + if (inSecBuffers._item0.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item0.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[0].pvBuffer = (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[0].cbBuffer = ((ChannelBinding)inSecBuffers._item0.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length; + inUnmanagedBuffer[0].pvBuffer = (IntPtr)pinnedToken0; + } } fixed (byte* pinnedOutBytes = outSecBuffer.token) @@ -685,28 +707,50 @@ internal static unsafe int AcceptSecurityContext( if (inSecBuffers.Count > 2) { inUnmanagedBuffer[2].BufferType = inSecBuffers._item2.Type; - inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length; - inUnmanagedBuffer[2].pvBuffer = inSecBuffers._item2.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken2; + if (inSecBuffers._item2.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item2.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[2].pvBuffer = (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[2].cbBuffer = ((ChannelBinding)inSecBuffers._item2.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length; + inUnmanagedBuffer[2].pvBuffer = (IntPtr)pinnedToken2; + } + } if (inSecBuffers.Count > 1) { inUnmanagedBuffer[1].BufferType = inSecBuffers._item1.Type; - inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length; - inUnmanagedBuffer[1].pvBuffer = inSecBuffers._item1.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken1; + if (inSecBuffers._item1.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item1.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[1].pvBuffer = (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[1].cbBuffer = ((ChannelBinding)inSecBuffers._item1.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length; + inUnmanagedBuffer[1].pvBuffer = (IntPtr)pinnedToken1; + } } if (inSecBuffers.Count > 0) { inUnmanagedBuffer[0].BufferType = inSecBuffers._item0.Type; - inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length; - inUnmanagedBuffer[0].pvBuffer = inSecBuffers._item0.UnmanagedToken != null ? - (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle() : - (IntPtr)pinnedToken0; + if (inSecBuffers._item0.UnmanagedToken != null) + { + Debug.Assert(inSecBuffers._item0.Type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); + inUnmanagedBuffer[0].pvBuffer = (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[0].cbBuffer = ((ChannelBinding)inSecBuffers._item0.UnmanagedToken).Size; + } + else + { + inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length; + inUnmanagedBuffer[0].pvBuffer = (IntPtr)pinnedToken0; + } } fixed (byte* pinnedOutBytes = outSecBuffer.token) From a4f15bff674160b592e66865247cc73419835805 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Mon, 3 Aug 2020 14:03:42 -0700 Subject: [PATCH 218/755] Add ActivityContext parsing APIs (#40183) * Add ActivityContext parsing APIs * Address the feedback --- ...em.Diagnostics.DiagnosticSourceActivity.cs | 2 ++ .../src/Resources/Strings.resx | 3 ++ .../src/System/Diagnostics/Activity.cs | 17 ++++++---- .../src/System/Diagnostics/ActivityContext.cs | 34 +++++++++++++++++++ .../src/System/Diagnostics/ActivitySource.cs | 2 +- .../tests/ActivitySourceTests.cs | 26 ++++++++++++++ 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs index f0b93c82b407..8e0f944e09cf 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs @@ -210,6 +210,8 @@ public readonly struct ActivityEvent public System.Diagnostics.ActivityTraceFlags TraceFlags { get { throw null; } } public string? TraceState { get { throw null; } } public bool IsRemote { get { throw null; } } + public static bool TryParse(string traceParent, string? traceState, out System.Diagnostics.ActivityContext context) { throw null; } + public static System.Diagnostics.ActivityContext Parse(string traceParent, string? traceState) { throw null; } public static bool operator ==(System.Diagnostics.ActivityContext left, System.Diagnostics.ActivityContext right) { throw null; } public static bool operator !=(System.Diagnostics.ActivityContext left, System.Diagnostics.ActivityContext right) { throw null; } public bool Equals(System.Diagnostics.ActivityContext value) { throw null; } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.DiagnosticSource/src/Resources/Strings.resx index 52df21c79f1e..76242301beb3 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/Resources/Strings.resx @@ -156,4 +156,7 @@ "The collection already contains item with same key '{0}''" + + "Invalid trace parent." + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index d842a0c7dabe..b5cd641c3eea 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -839,24 +839,29 @@ private static bool IsW3CId(string id) #if ALLOW_PARTIALLY_TRUSTED_CALLERS [System.Security.SecuritySafeCriticalAttribute] #endif - internal static bool TryConvertIdToContext(string id, out ActivityContext context) + internal static bool TryConvertIdToContext(string traceParent, string? traceState, out ActivityContext context) { context = default; - if (!IsW3CId(id)) + if (!IsW3CId(traceParent)) { return false; } - ReadOnlySpan traceIdSpan = id.AsSpan(3, 32); - ReadOnlySpan spanIdSpan = id.AsSpan(36, 16); + ReadOnlySpan traceIdSpan = traceParent.AsSpan(3, 32); + ReadOnlySpan spanIdSpan = traceParent.AsSpan(36, 16); if (!ActivityTraceId.IsLowerCaseHexAndNotAllZeros(traceIdSpan) || !ActivityTraceId.IsLowerCaseHexAndNotAllZeros(spanIdSpan) || - !HexConverter.IsHexLowerChar(id[53]) || !HexConverter.IsHexLowerChar(id[54])) + !HexConverter.IsHexLowerChar(traceParent[53]) || !HexConverter.IsHexLowerChar(traceParent[54])) { return false; } - context = new ActivityContext(new ActivityTraceId(traceIdSpan.ToString()), new ActivitySpanId(spanIdSpan.ToString()), (ActivityTraceFlags) ActivityTraceId.HexByteFromChars(id[53], id[54])); + context = new ActivityContext( + new ActivityTraceId(traceIdSpan.ToString()), + new ActivitySpanId(spanIdSpan.ToString()), + (ActivityTraceFlags) ActivityTraceId.HexByteFromChars(traceParent[53], traceParent[54]), + traceState); + return true; } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs index 454eba3ab0c6..d94640ad23fa 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs @@ -59,6 +59,40 @@ public ActivityContext(ActivityTraceId traceId, ActivitySpanId spanId, ActivityT /// public bool IsRemote { get; } + /// + /// Parse W3C trace context headers to ActivityContext object. + /// + /// W3C trace parent header. + /// W3C trace state. + /// The ActivityContext object created from the parsing operation. + public static bool TryParse(string traceParent, string? traceState, out ActivityContext context) + { + if (traceParent == null) + { + throw new ArgumentNullException(nameof(traceParent)); + } + + return Activity.TryConvertIdToContext(traceParent, traceState, out context); + } + + /// + /// Parse W3C trace context headers to ActivityContext object. + /// + /// W3C trace parent header. + /// Trace state. + /// + /// The ActivityContext object created from the parsing operation. + /// + public static ActivityContext Parse(string traceParent, string? traceState) + { + if (!TryParse(traceParent, traceState, out ActivityContext context)) + { + throw new ArgumentException(SR.InvalidTraceParent); + } + + return context; + } + public bool Equals(ActivityContext value) => SpanId.Equals(value.SpanId) && TraceId.Equals(value.TraceId) && TraceFlags == value.TraceFlags && TraceState == value.TraceState; public override bool Equals(object? obj) => (obj is ActivityContext context) ? Equals(context) : false; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs index a89068f6c11b..ac110fd590e5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs @@ -145,7 +145,7 @@ public bool HasListeners() { if (!canUseContext.HasValue) { - canUseContext = Activity.TryConvertIdToContext(parentId, out ActivityContext ctx); + canUseContext = Activity.TryConvertIdToContext(parentId, traceState: null, out ActivityContext ctx); if (canUseContext.Value) { dataWithContext = new ActivityCreationOptions(data.Source, data.Name, ctx, data.Kind, data.Tags, data.Links); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs index 5b22f1638161..99bafcd319d5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs @@ -382,6 +382,32 @@ public void TestDefaultParentContext() }).Dispose(); } + [Fact] + public void TestActivityContextParsing() + { + const string w3cId = "00-99d43cb30a4cdb4fbeee3a19c29201b0-e82825765f051b47-01"; + Assert.True(ActivityContext.TryParse(w3cId, "k=v", out ActivityContext context)); + Assert.Equal("99d43cb30a4cdb4fbeee3a19c29201b0", context.TraceId.ToHexString()); + Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); + Assert.Equal("k=v", context.TraceState); + + context = ActivityContext.Parse(w3cId, "k=v"); + Assert.Equal("99d43cb30a4cdb4fbeee3a19c29201b0", context.TraceId.ToHexString()); + Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); + Assert.Equal("k=v", context.TraceState); + + context = ActivityContext.Parse(w3cId, null); + Assert.Null(context.TraceState); + + Assert.Throws(() => ActivityContext.TryParse(null, "k=v", out context)); + Assert.Throws(() => ActivityContext.Parse(null, null)); + Assert.Throws(() => ActivityContext.Parse("BadW3C", null)); + + const string invalidW3CContext = "00-Z9d43cb30a4cdb4fbeee3a19c29201b0-e82825765f051b47-01"; + Assert.False(ActivityContext.TryParse(invalidW3CContext, null, out context)); + } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void TestCreatingActivityUsingDifferentParentIds() From a5d291720e6504a60548f071f3a84194db8a7249 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Mon, 3 Aug 2020 14:26:55 -0700 Subject: [PATCH 219/755] Improve default ciphersuites on Linux The ciphersuites are now server-order preferenced, which matches Windows and macOS. The ciphersuite list is: * Anything provided via the CipherSuitePolicy, otherwise * Anything provided via config (OPENSSL_CONF or default) * An opinionated default The opinionated default currently contains one TLS 1.0/1.1 ciphersuite for each of an RSA or ECDSA server certificate, due to complexities in the current tests with not expecting "there are no valid ciphersuites enabled" errors with asking for those lower protocol versions explicitly. With TLS 1.0/1.1 still enabled by default the server config does not get an "A" from SslLabs out of the box; followup work will increase test robustness and remove that fallback. --- .../apibridge.c | 10 ++ .../apibridge.h | 1 + .../opensslshim.h | 6 + .../pal_ssl.c | 103 +++++++++++++++++- 4 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c index 066d872d8068..b5bab626c700 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c @@ -478,6 +478,16 @@ int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* return 1; } +int32_t local_SSL_CTX_config(SSL_CTX* ctx, const char* name) +{ + (void)ctx; + (void)name; + + // 1.0.x didn't load config in the same manner as 1.1.x, + // so the appropriate answer is "section not found". + return 0; +} + int32_t local_SSL_is_init_finished(const SSL* ssl) { return SSL_state(ssl) == SSL_ST_OK; diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h index f2146a08ed74..52e74314d076 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h @@ -26,6 +26,7 @@ int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q); int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d); int32_t local_SSL_is_init_finished(const SSL* ssl); +int32_t local_SSL_CTX_config(SSL_CTX* ctx, const char* name); unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options); void local_SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level); int local_SSL_session_reused(SSL* ssl); diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index 98c4672c5cc0..d59533208f4e 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -148,6 +148,7 @@ int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp); int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q); int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d); int32_t SSL_is_init_finished(SSL* ssl); +int SSL_CTX_config(SSL_CTX* ctx, const char* name); #undef SSL_CTX_set_options unsigned long SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options); void SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level); @@ -456,6 +457,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi REQUIRED_FUNCTION(SSL_ctrl) \ REQUIRED_FUNCTION(SSL_set_quiet_shutdown) \ REQUIRED_FUNCTION(SSL_CTX_check_private_key) \ + FALLBACK_FUNCTION(SSL_CTX_config) \ REQUIRED_FUNCTION(SSL_CTX_ctrl) \ REQUIRED_FUNCTION(SSL_CTX_free) \ FALLBACK_FUNCTION(SSL_is_init_finished) \ @@ -474,6 +476,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi REQUIRED_FUNCTION(SSL_CTX_use_PrivateKey) \ REQUIRED_FUNCTION(SSL_do_handshake) \ REQUIRED_FUNCTION(SSL_free) \ + REQUIRED_FUNCTION(SSL_get_ciphers) \ REQUIRED_FUNCTION(SSL_get_client_CA_list) \ REQUIRED_FUNCTION(SSL_get_current_cipher) \ REQUIRED_FUNCTION(SSL_get_error) \ @@ -855,6 +858,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_ctrl SSL_ctrl_ptr #define SSL_set_quiet_shutdown SSL_set_quiet_shutdown_ptr #define SSL_CTX_check_private_key SSL_CTX_check_private_key_ptr +#define SSL_CTX_config SSL_CTX_config_ptr #define SSL_CTX_ctrl SSL_CTX_ctrl_ptr #define SSL_CTX_free SSL_CTX_free_ptr #define SSL_CTX_new SSL_CTX_new_ptr @@ -872,6 +876,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_CTX_use_PrivateKey SSL_CTX_use_PrivateKey_ptr #define SSL_do_handshake SSL_do_handshake_ptr #define SSL_free SSL_free_ptr +#define SSL_get_ciphers SSL_get_ciphers_ptr #define SSL_get_client_CA_list SSL_get_client_CA_list_ptr #define SSL_get_current_cipher SSL_get_current_cipher_ptr #define SSL_get_error SSL_get_error_ptr @@ -986,6 +991,7 @@ FOR_ALL_OPENSSL_FUNCTIONS // type-safe OPENSSL_sk_num #define sk_ASN1_OBJECT_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(ASN1_OBJECT)*)0)) #define sk_GENERAL_NAME_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(GENERAL_NAME)*)0)) +#define sk_SSL_CIPHER_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(SSL_CIPHER)*)0)) #define sk_X509_NAME_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509_NAME)*)0)) #define sk_X509_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509)*)0)) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c index 89aca2c3a041..5167987a1c4e 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c @@ -15,6 +15,19 @@ c_static_assert(PAL_SSL_ERROR_WANT_WRITE == SSL_ERROR_WANT_WRITE); c_static_assert(PAL_SSL_ERROR_SYSCALL == SSL_ERROR_SYSCALL); c_static_assert(PAL_SSL_ERROR_ZERO_RETURN == SSL_ERROR_ZERO_RETURN); +#define DOTNET_DEFAULT_CIPHERSTRING \ + "ECDHE-ECDSA-AES256-GCM-SHA384:" \ + "ECDHE-ECDSA-AES128-GCM-SHA256:" \ + "ECDHE-RSA-AES256-GCM-SHA384:" \ + "ECDHE-RSA-AES128-GCM-SHA256:" \ + "ECDHE-ECDSA-AES256-SHA384:" \ + "ECDHE-ECDSA-AES128-SHA256:" \ + "ECDHE-RSA-AES256-SHA384:" \ + "ECDHE-RSA-AES128-SHA256:" \ + /* Temporary TLS 1.0/1.1 compat after this line */\ + "ECDHE-ECDSA-AES256-SHA:" \ + "ECDHE-RSA-AES256-SHA:" \ + int32_t CryptoNative_EnsureOpenSslInitialized(void); #ifdef NEED_OPENSSL_1_0 @@ -25,6 +38,79 @@ static void EnsureLibSsl10Initialized() } #endif +static int32_t g_config_specified_ciphersuites = 0; + +static void DetectCiphersuiteConfiguration() +{ + // This routine will always produce g_config_specified_ciphersuites = 0 on OpenSSL 1.0.x, + // so if we're building direct for 1.0.x (the only time NEED_OPENSSL_1_1 is undefined) then + // just omit all the code here. + // + // The method uses OpenSSL 1.0.x API, except for the fallback function SSL_CTX_config, to + // make the portable version easier. +#ifdef NEED_OPENSSL_1_1 + + // Check to see if there's a registered default CipherString. If not, we will use our own. + SSL_CTX* ctx = SSL_CTX_new(TLS_method()); + assert(ctx != NULL); + + // SSL_get_ciphers returns a shared pointer, no need to save/free it. + // It gets invalidated every time we touch the configuration, so we can't ask just once, either. + SSL* ssl = SSL_new(ctx); + assert(ssl != NULL); + int defaultCount = sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)); + SSL_free(ssl); + + int rv = SSL_CTX_set_cipher_list(ctx, "ALL"); + assert(rv); + + ssl = SSL_new(ctx); + assert(ssl != NULL); + int allCount = sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)); + SSL_free(ssl); + + // It isn't expected that the default list and the "ALL" list have the same cardinality, + // but if that does happen (custom build, config, et cetera) then use the "RSA" list + // instead of the "ALL" list. Since the RSA list doesn't include legacy ciphersuites + // appropriate for ECDSA server certificates, it should be different than the ALL list. + if (allCount == defaultCount) + { + rv = SSL_CTX_set_cipher_list(ctx, "RSA"); + assert(rv); + ssl = SSL_new(ctx); + assert(ssl != NULL); + allCount = sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)); + SSL_free(ssl); + // If the implicit default, "ALL", and "RSA" all have the same cardinality, just fail. + assert(allCount != defaultCount); + } + + if (!SSL_CTX_config(ctx, "system_default")) + { + // There's no system_default configuration, so no default CipherString. + ERR_clear_error(); + } + else + { + ssl = SSL_new(ctx); + assert(ssl != NULL); + int after = sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)); + SSL_free(ssl); + + g_config_specified_ciphersuites = (allCount != after); + } + + SSL_CTX_free(ctx); + +#elif !defined(FEATURE_DISTRO_AGNOSTIC_SSL) && defined(SSL_SYSTEM_DEFAULT_CIPHER_LIST) + + // The Fedora, RHEL, and CentOS builds replace the normal defaults (with a configuration model). + // Consider their non-portable builds to always have specified ciphersuites in config. + g_config_specified_ciphersuites = 1; + +#endif +} + void CryptoNative_EnsureLibSslInitialized() { CryptoNative_EnsureOpenSslInitialized(); @@ -40,6 +126,8 @@ void CryptoNative_EnsureLibSslInitialized() #elif OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM EnsureLibSsl10Initialized(); #endif + + DetectCiphersuiteConfiguration(); } const SSL_METHOD* CryptoNative_SslV2_3Method() @@ -57,7 +145,20 @@ SSL_CTX* CryptoNative_SslCtxCreate(SSL_METHOD* method) { // As of OpenSSL 1.1.0, compression is disabled by default. In case an older build // is used, ensure it's disabled. - SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); + // + // The other .NET platforms are server-preference, and the common consensus seems + // to be to use server preference (as of June 2020), so just always assert that. + SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE); + + // If openssl.cnf doesn't have an opinion for CipherString, then use this value instead + if (!g_config_specified_ciphersuites) + { + if (!SSL_CTX_set_cipher_list(ctx, DOTNET_DEFAULT_CIPHERSTRING)) + { + SSL_CTX_free(ctx); + return NULL; + } + } } return ctx; From 985f8ef146f6c19a7190acaa9c48e3334cb54616 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Mon, 3 Aug 2020 14:59:27 -0700 Subject: [PATCH 220/755] Don't remove dead indirections that may throw. (#40226) Liveness incorrectly removed indirection rhs's of dead assignments. This change fixes that. Fixes #39823. --- src/coreclr/src/jit/liveness.cpp | 16 +--- src/coreclr/src/jit/lower.cpp | 85 +++++++++++-------- src/coreclr/src/jit/lower.h | 3 + .../JitBlue/GitHub_39823/GitHub_39823.cs | 39 +++++++++ .../JitBlue/GitHub_39823/GitHub_39823.csproj | 14 +++ 5 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.cs create mode 100644 src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.csproj diff --git a/src/coreclr/src/jit/liveness.cpp b/src/coreclr/src/jit/liveness.cpp index 504a6c0fc37f..75cf6e42dda7 100644 --- a/src/coreclr/src/jit/liveness.cpp +++ b/src/coreclr/src/jit/liveness.cpp @@ -1980,11 +1980,10 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR GenTree* data = store->OperIs(GT_STOREIND) ? store->AsStoreInd()->Data() : store->AsBlk()->Data(); data->SetUnusedValue(); + if (data->isIndir()) { - // This is a block assignment. An indirection of the rhs is not considered - // to happen until the assignment so mark it as non-faulting. - data->gtFlags |= GTF_IND_NONFAULTING; + Lowering::TransformUnusedIndirection(data->AsIndir(), this, block); } blockRange.Remove(store); @@ -2322,17 +2321,6 @@ bool Compiler::fgRemoveDeadStore(GenTree** pTree, } #endif // DEBUG // Extract the side effects - if (rhsNode->TypeGet() == TYP_STRUCT) - { - // This is a block assignment. An indirection of the rhs is not considered to - // happen until the assignment, so we will extract the side effects from only - // the address. - if (rhsNode->OperIsIndir()) - { - assert(rhsNode->OperGet() != GT_NULLCHECK); - rhsNode = rhsNode->AsIndir()->Addr(); - } - } gtExtractSideEffList(rhsNode, &sideEffList); } diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index cc9e2891e9a4..150bfd2d38d6 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -6450,41 +6450,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind) if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue()) { - // A nullcheck is essentially the same as an indirection with no use. - // The difference lies in whether a target register must be allocated. - // On XARCH we can generate a compare with no target register as long as the addresss - // is not contained. - // On ARM64 we can generate a load to REG_ZR in all cases. - // However, on ARM we must always generate a load to a register. - // In the case where we require a target register, it is better to use GT_IND, since - // GT_NULLCHECK is a non-value node and would therefore require an internal register - // to use as the target. That is non-optimal because it will be modeled as conflicting - // with the source register(s). - // So, to summarize: - // - On ARM64, always use GT_NULLCHECK for a dead indirection. - // - On ARM, always use GT_IND. - // - On XARCH, use GT_IND if we have a contained address, and GT_NULLCHECK otherwise. - // In all cases, change the type to TYP_INT. - // - ind->gtType = TYP_INT; -#ifdef TARGET_ARM64 - bool useNullCheck = true; -#elif TARGET_ARM - bool useNullCheck = false; -#else // TARGET_XARCH - bool useNullCheck = !ind->Addr()->isContained(); -#endif // !TARGET_XARCH - - if (useNullCheck && ind->OperIs(GT_IND)) - { - ind->ChangeOper(GT_NULLCHECK); - ind->ClearUnusedValue(); - } - else if (!useNullCheck && ind->OperIs(GT_NULLCHECK)) - { - ind->ChangeOper(GT_IND); - ind->SetUnusedValue(); - } + TransformUnusedIndirection(ind, comp, m_block); } } else @@ -6496,6 +6462,55 @@ void Lowering::LowerIndir(GenTreeIndir* ind) } } +//------------------------------------------------------------------------ +// TransformUnusedIndirection: change the opcode and the type of the unused indirection. +// +// Arguments: +// ind - Indirection to transform. +// comp - Compiler instance. +// block - Basic block of the indirection. +// +void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, BasicBlock* block) +{ + // A nullcheck is essentially the same as an indirection with no use. + // The difference lies in whether a target register must be allocated. + // On XARCH we can generate a compare with no target register as long as the addresss + // is not contained. + // On ARM64 we can generate a load to REG_ZR in all cases. + // However, on ARM we must always generate a load to a register. + // In the case where we require a target register, it is better to use GT_IND, since + // GT_NULLCHECK is a non-value node and would therefore require an internal register + // to use as the target. That is non-optimal because it will be modeled as conflicting + // with the source register(s). + // So, to summarize: + // - On ARM64, always use GT_NULLCHECK for a dead indirection. + // - On ARM, always use GT_IND. + // - On XARCH, use GT_IND if we have a contained address, and GT_NULLCHECK otherwise. + // In all cases, change the type to TYP_INT. + // + assert(ind->OperIs(GT_NULLCHECK, GT_IND)); + + ind->gtType = TYP_INT; +#ifdef TARGET_ARM64 + bool useNullCheck = true; +#elif TARGET_ARM + bool useNullCheck = false; +#else // TARGET_XARCH + bool useNullCheck = !ind->Addr()->isContained(); +#endif // !TARGET_XARCH + + if (useNullCheck && ind->OperIs(GT_IND)) + { + comp->gtChangeOperToNullCheck(ind, block); + ind->ClearUnusedValue(); + } + else if (!useNullCheck && ind->OperIs(GT_NULLCHECK)) + { + ind->ChangeOper(GT_IND); + ind->SetUnusedValue(); + } +} + //------------------------------------------------------------------------ // LowerBlockStoreCommon: a common logic to lower STORE_OBJ/BLK/DYN_BLK. // diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 0c620aebeb0f..135446c7e84d 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -8,6 +8,7 @@ XX Lower XX XX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ #ifndef _LOWER_H_ @@ -532,6 +533,8 @@ class Lowering final : public Phase bool IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, GenTree* node, bool* supportsRegOptional); #endif // FEATURE_HW_INTRINSICS + static void TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, BasicBlock* block); + private: static bool NodesAreEquivalentLeaves(GenTree* candidate, GenTree* storeInd); diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.cs b/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.cs new file mode 100644 index 000000000000..501641e9b3cf --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Diagnostics; + +class Runtime_39823 +{ + struct IntsWrapped + { + public int i1; + public int i2; + public int i3; + public int i4; + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int TestUnusedObjCopy(IntsWrapped* ps) + { + IntsWrapped s = *ps; + return 100; + } + + + public static unsafe int Main() + { + try + { + TestUnusedObjCopy((IntsWrapped*)0); + Debug.Assert(false, "unreachable"); + } + catch + { + return 100; + } + return -1; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.csproj new file mode 100644 index 000000000000..51c683dceab5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/GitHub_39823/GitHub_39823.csproj @@ -0,0 +1,14 @@ + + + Exe + 1 + + + Full + True + True + + + + + From d10f6f11debe5308d21f9e9802ba155b6624e2fd Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Mon, 3 Aug 2020 15:30:09 -0700 Subject: [PATCH 221/755] Don't rely on the built-in interface marshaller during COM activation. (#40228) * Don't rely on the built-in marshaller during activation. Relying on the built-in marshaller leverages the Class interface approach which doesn't work for some interface types (e.g. interfaces inheriting from IDispatch). This approach is wrong regardless of why given that COM dictates the returned value must be properly cast the specific interface vtable. --- .../Runtime/InteropServices/ComActivator.cs | 46 ++-- src/tests/Interop/COM/Activator/Program.cs | 28 +- .../COM/NativeClients/Dispatch/Client.cpp | 258 +++++++++++------- 3 files changed, 196 insertions(+), 136 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs index 45f4d4839fb8..c41d4dd96616 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs @@ -25,7 +25,7 @@ public interface IClassFactory void CreateInstance( [MarshalAs(UnmanagedType.Interface)] object? pUnkOuter, ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] out object? ppvObject); + out IntPtr ppvObject); void LockServer([MarshalAs(UnmanagedType.Bool)] bool fLock); } @@ -51,7 +51,7 @@ internal interface IClassFactory2 : IClassFactory new void CreateInstance( [MarshalAs(UnmanagedType.Interface)] object? pUnkOuter, ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] out object? ppvObject); + out IntPtr ppvObject); new void LockServer([MarshalAs(UnmanagedType.Bool)] bool fLock); @@ -66,7 +66,7 @@ void CreateInstanceLic( [MarshalAs(UnmanagedType.Interface)] object? pUnkReserved, ref Guid riid, [MarshalAs(UnmanagedType.BStr)] string bstrKey, - [MarshalAs(UnmanagedType.Interface)] out object ppvObject); + out IntPtr ppvObject); } [StructLayout(LayoutKind.Sequential)] @@ -493,28 +493,32 @@ public static Type GetValidatedInterfaceType(Type classType, ref Guid riid, obje #endif } - public static void ValidateObjectIsMarshallableAsInterface(object obj, Type interfaceType) + public static IntPtr GetObjectAsInterface(object obj, Type interfaceType) { #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION - // If the requested "interface type" is type object then return - // because type object is always marshallable. + // If the requested "interface type" is type object then return as IUnknown if (interfaceType == typeof(object)) { - return; + return Marshal.GetIUnknownForObject(obj); } Debug.Assert(interfaceType.IsInterface); - // The intent of this call is to validate the interface can be + // The intent of this call is to get AND validate the interface can be // marshalled to native code. An exception will be thrown if the // type is unable to be marshalled to native code. // Scenarios where this is relevant: // - Interfaces that use Generics // - Interfaces that define implementation - IntPtr ptr = Marshal.GetComInterfaceForObject(obj, interfaceType, CustomQueryInterfaceMode.Ignore); + IntPtr interfaceMaybe = Marshal.GetComInterfaceForObject(obj, interfaceType, CustomQueryInterfaceMode.Ignore); - // Decrement the above 'Marshal.GetComInterfaceForObject()' - Marshal.Release(ptr); + if (interfaceMaybe == IntPtr.Zero) + { + // E_NOINTERFACE + throw new InvalidCastException(); + } + + return interfaceMaybe; #else throw new PlatformNotSupportedException(); #endif @@ -544,18 +548,18 @@ public static object CreateAggregatedObject(object pUnkOuter, object comObject) public void CreateInstance( [MarshalAs(UnmanagedType.Interface)] object? pUnkOuter, ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] out object? ppvObject) + out IntPtr ppvObject) { #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION Type interfaceType = BasicClassFactory.GetValidatedInterfaceType(_classType, ref riid, pUnkOuter); - ppvObject = Activator.CreateInstance(_classType)!; + object obj = Activator.CreateInstance(_classType)!; if (pUnkOuter != null) { - ppvObject = BasicClassFactory.CreateAggregatedObject(pUnkOuter, ppvObject); + obj = BasicClassFactory.CreateAggregatedObject(pUnkOuter, obj); } - BasicClassFactory.ValidateObjectIsMarshallableAsInterface(ppvObject, interfaceType); + ppvObject = BasicClassFactory.GetObjectAsInterface(obj, interfaceType); #else throw new PlatformNotSupportedException(); #endif @@ -593,7 +597,7 @@ public LicenseClassFactory(Guid clsid, Type classType) public void CreateInstance( [MarshalAs(UnmanagedType.Interface)] object? pUnkOuter, ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] out object? ppvObject) + out IntPtr ppvObject) { #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION CreateInstanceInner(pUnkOuter, ref riid, key: null, isDesignTime: true, out ppvObject); @@ -640,7 +644,7 @@ public void CreateInstanceLic( [MarshalAs(UnmanagedType.Interface)] object? pUnkReserved, ref Guid riid, [MarshalAs(UnmanagedType.BStr)] string bstrKey, - [MarshalAs(UnmanagedType.Interface)] out object ppvObject) + out IntPtr ppvObject) { #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION Debug.Assert(pUnkReserved == null); @@ -655,18 +659,18 @@ private void CreateInstanceInner( ref Guid riid, string? key, bool isDesignTime, - out object ppvObject) + out IntPtr ppvObject) { #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION Type interfaceType = BasicClassFactory.GetValidatedInterfaceType(_classType, ref riid, pUnkOuter); - ppvObject = _licenseProxy.AllocateAndValidateLicense(_classType, key, isDesignTime); + object obj = _licenseProxy.AllocateAndValidateLicense(_classType, key, isDesignTime); if (pUnkOuter != null) { - ppvObject = BasicClassFactory.CreateAggregatedObject(pUnkOuter, ppvObject); + obj = BasicClassFactory.CreateAggregatedObject(pUnkOuter, obj); } - BasicClassFactory.ValidateObjectIsMarshallableAsInterface(ppvObject, interfaceType); + ppvObject = BasicClassFactory.GetObjectAsInterface(obj, interfaceType); #else throw new PlatformNotSupportedException(); #endif diff --git a/src/tests/Interop/COM/Activator/Program.cs b/src/tests/Interop/COM/Activator/Program.cs index ac7fe8d005e6..fd525aaf2e90 100644 --- a/src/tests/Interop/COM/Activator/Program.cs +++ b/src/tests/Interop/COM/Activator/Program.cs @@ -105,9 +105,11 @@ static void ValidateAssemblyIsolation() var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt); - object svr; - factory.CreateInstance(null, ref iid, out svr); - typeCFromAssemblyA = (Type)((IGetTypeFromC)svr).GetTypeFromC(); + IntPtr svrRaw; + factory.CreateInstance(null, ref iid, out svrRaw); + var svr = (IGetTypeFromC)Marshal.GetObjectForIUnknown(svrRaw); + Marshal.Release(svrRaw); + typeCFromAssemblyA = (Type)svr.GetTypeFromC(); } using (HostPolicyMock.Mock_corehost_resolve_component_dependencies( @@ -127,9 +129,11 @@ static void ValidateAssemblyIsolation() var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt); - object svr; - factory.CreateInstance(null, ref iid, out svr); - typeCFromAssemblyB = (Type)((IGetTypeFromC)svr).GetTypeFromC(); + IntPtr svrRaw; + factory.CreateInstance(null, ref iid, out svrRaw); + var svr = (IGetTypeFromC)Marshal.GetObjectForIUnknown(svrRaw); + Marshal.Release(svrRaw); + typeCFromAssemblyB = (Type)svr.GetTypeFromC(); } Assert.AreNotEqual(typeCFromAssemblyA, typeCFromAssemblyB, "Types should be from different AssemblyLoadContexts"); @@ -178,8 +182,10 @@ static void ValidateUserDefinedRegistrationCallbacks() var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt); - object svr; - factory.CreateInstance(null, ref iid, out svr); + IntPtr svrRaw; + factory.CreateInstance(null, ref iid, out svrRaw); + var svr = Marshal.GetObjectForIUnknown(svrRaw); + Marshal.Release(svrRaw); var inst = (IValidateRegistrationCallbacks)svr; Assert.IsFalse(inst.DidRegister()); @@ -215,8 +221,10 @@ static void ValidateUserDefinedRegistrationCallbacks() var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt); - object svr; - factory.CreateInstance(null, ref iid, out svr); + IntPtr svrRaw; + factory.CreateInstance(null, ref iid, out svrRaw); + var svr = Marshal.GetObjectForIUnknown(svrRaw); + Marshal.Release(svrRaw); var inst = (IValidateRegistrationCallbacks)svr; cxt.InterfaceId = Guid.Empty; diff --git a/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp b/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp index 36b4806dc61f..0aa509cb31c0 100644 --- a/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp +++ b/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp @@ -88,59 +88,81 @@ void Validate_Numeric_In_ReturnByRef() ULONGLONG ul1 = 4168; ULONGLONG ul2; - DISPPARAMS params; - params.cArgs = 14; - params.rgvarg = new VARIANTARG[params.cArgs]; - params.cNamedArgs = 0; - params.rgdispidNamedArgs = nullptr; + { + DISPPARAMS params; + params.cArgs = 14; + params.rgvarg = new VARIANTARG[params.cArgs]; + params.cNamedArgs = 0; + params.rgdispidNamedArgs = nullptr; - V_VT(¶ms.rgvarg[13]) = VT_UI1; - V_UI1(¶ms.rgvarg[13]) = b1; - V_VT(¶ms.rgvarg[12]) = VT_BYREF | VT_UI1; - V_UI1REF(¶ms.rgvarg[12]) = &b2; - V_VT(¶ms.rgvarg[11]) = VT_I2; - V_I2(¶ms.rgvarg[11]) = s1; - V_VT(¶ms.rgvarg[10]) = VT_BYREF | VT_I2; - V_I2REF(¶ms.rgvarg[10]) = &s2; - V_VT(¶ms.rgvarg[9]) = VT_UI2; - V_UI2(¶ms.rgvarg[9]) = us1; - V_VT(¶ms.rgvarg[8]) = VT_BYREF | VT_UI2; - V_UI2REF(¶ms.rgvarg[8]) = &us2; - V_VT(¶ms.rgvarg[7]) = VT_I4; - V_I4(¶ms.rgvarg[7]) = i1; - V_VT(¶ms.rgvarg[6]) = VT_BYREF | VT_I4; - V_I4REF(¶ms.rgvarg[6]) = &i2; - V_VT(¶ms.rgvarg[5]) = VT_UI4; - V_UI4(¶ms.rgvarg[5]) = ui1; - V_VT(¶ms.rgvarg[4]) = VT_BYREF | VT_UI4; - V_UI4REF(¶ms.rgvarg[4]) = &ui2; - V_VT(¶ms.rgvarg[3]) = VT_I8; - V_I8(¶ms.rgvarg[3]) = l1; - V_VT(¶ms.rgvarg[2]) = VT_BYREF | VT_I8; - V_I8REF(¶ms.rgvarg[2]) = &l2; - V_VT(¶ms.rgvarg[1]) = VT_UI8; - V_UI8(¶ms.rgvarg[1]) = ul1; - V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_UI8; - V_UI8REF(¶ms.rgvarg[0]) = &ul2; - - THROW_IF_FAILED(dispatchTesting->Invoke( - methodId, - IID_NULL, - lcid, - DISPATCH_METHOD, - ¶ms, - nullptr, - nullptr, - nullptr - )); + V_VT(¶ms.rgvarg[13]) = VT_UI1; + V_UI1(¶ms.rgvarg[13]) = b1; + V_VT(¶ms.rgvarg[12]) = VT_BYREF | VT_UI1; + V_UI1REF(¶ms.rgvarg[12]) = &b2; + V_VT(¶ms.rgvarg[11]) = VT_I2; + V_I2(¶ms.rgvarg[11]) = s1; + V_VT(¶ms.rgvarg[10]) = VT_BYREF | VT_I2; + V_I2REF(¶ms.rgvarg[10]) = &s2; + V_VT(¶ms.rgvarg[9]) = VT_UI2; + V_UI2(¶ms.rgvarg[9]) = us1; + V_VT(¶ms.rgvarg[8]) = VT_BYREF | VT_UI2; + V_UI2REF(¶ms.rgvarg[8]) = &us2; + V_VT(¶ms.rgvarg[7]) = VT_I4; + V_I4(¶ms.rgvarg[7]) = i1; + V_VT(¶ms.rgvarg[6]) = VT_BYREF | VT_I4; + V_I4REF(¶ms.rgvarg[6]) = &i2; + V_VT(¶ms.rgvarg[5]) = VT_UI4; + V_UI4(¶ms.rgvarg[5]) = ui1; + V_VT(¶ms.rgvarg[4]) = VT_BYREF | VT_UI4; + V_UI4REF(¶ms.rgvarg[4]) = &ui2; + V_VT(¶ms.rgvarg[3]) = VT_I8; + V_I8(¶ms.rgvarg[3]) = l1; + V_VT(¶ms.rgvarg[2]) = VT_BYREF | VT_I8; + V_I8REF(¶ms.rgvarg[2]) = &l2; + V_VT(¶ms.rgvarg[1]) = VT_UI8; + V_UI8(¶ms.rgvarg[1]) = ul1; + V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_UI8; + V_UI8REF(¶ms.rgvarg[0]) = &ul2; + + THROW_IF_FAILED(dispatchTesting->Invoke( + methodId, + IID_NULL, + lcid, + DISPATCH_METHOD, + ¶ms, + nullptr, + nullptr, + nullptr + )); + + THROW_FAIL_IF_FALSE(b2 == b1 * 2); + THROW_FAIL_IF_FALSE(s2 == s1 * 2); + THROW_FAIL_IF_FALSE(us2 == us1 * 2); + THROW_FAIL_IF_FALSE(i2 == i1 * 2); + THROW_FAIL_IF_FALSE(ui2 == ui1 * 2); + THROW_FAIL_IF_FALSE(l2 == l1 * 2); + THROW_FAIL_IF_FALSE(ul2 == ul1 * 2); + } - THROW_FAIL_IF_FALSE(b2 == b1 * 2); - THROW_FAIL_IF_FALSE(s2 == s1 * 2); - THROW_FAIL_IF_FALSE(us2 == us1 * 2); - THROW_FAIL_IF_FALSE(i2 == i1 * 2); - THROW_FAIL_IF_FALSE(ui2 == ui1 * 2); - THROW_FAIL_IF_FALSE(l2 == l1 * 2); - THROW_FAIL_IF_FALSE(ul2 == ul1 * 2); + { + b2 = 0; + s2 = 0; + us2 = 0; + i2 = 0; + ui2 = 0; + l2 = 0; + ul2 = 0; + + THROW_IF_FAILED(dispatchTesting->DoubleNumeric_ReturnByRef(b1, &b2, s1, &s2, us1, &us2, i1, (INT*)&i2, ui1, (UINT*)&ui2, l1, &l2, ul1, &ul2)); + + THROW_FAIL_IF_FALSE(b2 == b1 * 2); + THROW_FAIL_IF_FALSE(s2 == s1 * 2); + THROW_FAIL_IF_FALSE(us2 == us1 * 2); + THROW_FAIL_IF_FALSE(i2 == i1 * 2); + THROW_FAIL_IF_FALSE(ui2 == ui1 * 2); + THROW_FAIL_IF_FALSE(l2 == l1 * 2); + THROW_FAIL_IF_FALSE(ul2 == ul1 * 2); + } } namespace @@ -183,37 +205,50 @@ void Validate_Float_In_ReturnAndUpdateByRef() lcid, &methodId)); - float a = 12.34f; - float b = 1.234f; - float expected = b + a; - - DISPPARAMS params; - params.cArgs = 2; - params.rgvarg = new VARIANTARG[params.cArgs]; - params.cNamedArgs = 0; - params.rgdispidNamedArgs = nullptr; + const float a = 12.34f; + const float b_orig = 1.234f; + const float expected = b_orig + a; - VARIANT result; - - V_VT(¶ms.rgvarg[1]) = VT_R4; - V_R4(¶ms.rgvarg[1]) = a; - V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_R4; - V_R4REF(¶ms.rgvarg[0]) = &b; + float b = b_orig; + { + DISPPARAMS params; + params.cArgs = 2; + params.rgvarg = new VARIANTARG[params.cArgs]; + params.cNamedArgs = 0; + params.rgdispidNamedArgs = nullptr; + + VARIANT result; + + V_VT(¶ms.rgvarg[1]) = VT_R4; + V_R4(¶ms.rgvarg[1]) = a; + V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_R4; + V_R4REF(¶ms.rgvarg[0]) = &b; + + + THROW_IF_FAILED(dispatchTesting->Invoke( + methodId, + IID_NULL, + lcid, + DISPATCH_METHOD, + ¶ms, + &result, + nullptr, + nullptr + )); + + THROW_FAIL_IF_FALSE(EqualByBound(expected, V_R4(&result))); + THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + } - THROW_IF_FAILED(dispatchTesting->Invoke( - methodId, - IID_NULL, - lcid, - DISPATCH_METHOD, - ¶ms, - &result, - nullptr, - nullptr - )); + { + b = b_orig; + float result; + THROW_IF_FAILED(dispatchTesting->Add_Float_ReturnAndUpdateByRef(a, &b, &result)); - THROW_FAIL_IF_FALSE(EqualByBound(expected, V_R4(&result))); - THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, result)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + } } void Validate_Double_In_ReturnAndUpdateByRef() @@ -237,37 +272,50 @@ void Validate_Double_In_ReturnAndUpdateByRef() lcid, &methodId)); - double a = 1856.5634; - double b = 587867.757; - double expected = a + b; - - DISPPARAMS params; - params.cArgs = 2; - params.rgvarg = new VARIANTARG[params.cArgs]; - params.cNamedArgs = 0; - params.rgdispidNamedArgs = nullptr; - - VARIANT result; + const double a = 1856.5634; + const double b_orig = 587867.757; + const double expected = a + b_orig; - V_VT(¶ms.rgvarg[1]) = VT_R8; - V_R8(¶ms.rgvarg[1]) = a; - V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_R8; - V_R8REF(¶ms.rgvarg[0]) = &b; + double b = b_orig; + { + DISPPARAMS params; + params.cArgs = 2; + params.rgvarg = new VARIANTARG[params.cArgs]; + params.cNamedArgs = 0; + params.rgdispidNamedArgs = nullptr; + + VARIANT result; + + V_VT(¶ms.rgvarg[1]) = VT_R8; + V_R8(¶ms.rgvarg[1]) = a; + V_VT(¶ms.rgvarg[0]) = VT_BYREF | VT_R8; + V_R8REF(¶ms.rgvarg[0]) = &b; + + + THROW_IF_FAILED(dispatchTesting->Invoke( + methodId, + IID_NULL, + lcid, + DISPATCH_METHOD, + ¶ms, + &result, + nullptr, + nullptr + )); + + THROW_FAIL_IF_FALSE(EqualByBound(expected, V_R8(&result))); + THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + } - THROW_IF_FAILED(dispatchTesting->Invoke( - methodId, - IID_NULL, - lcid, - DISPATCH_METHOD, - ¶ms, - &result, - nullptr, - nullptr - )); + { + b = b_orig; + double result; + THROW_IF_FAILED(dispatchTesting->Add_Double_ReturnAndUpdateByRef(a, &b, &result)); - THROW_FAIL_IF_FALSE(EqualByBound(expected, V_R8(&result))); - THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, result)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, b)); + } } void Validate_LCID_Marshaled() From ba97db39fcab6f5740415d9f912436d1b52e65d2 Mon Sep 17 00:00:00 2001 From: SUN Guoyun <40024232+sunny868@users.noreply.github.com> Date: Tue, 4 Aug 2020 07:11:05 +0800 Subject: [PATCH 222/755] Use Environment.SystemPageSize to set desireBufferSize (#40247) PAGE_SIZE is not all 4096 for all architecture, so we can get it by Environment.SystemPageSize Co-authored-by: Sunguoyun --- .../tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs index 4dd10185ecd8..f7ef3d6afa8f 100644 --- a/src/libraries/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs @@ -85,7 +85,7 @@ public static void Linux_BufferSizeRoundtrips() // On Linux, setting the buffer size of the server will also set the buffer size of the // client, regardless of the direction of the flow - int desiredBufferSize = 4096; + int desiredBufferSize = Environment.SystemPageSize; using (var server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None, desiredBufferSize)) { Assert.Equal(desiredBufferSize, server.OutBufferSize); From a297222753da9ae62dfe3304e4924ff74693c77d Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Mon, 3 Aug 2020 16:54:10 -0700 Subject: [PATCH 223/755] Fix attribute differences in between refs and implementations (#40185) * Fix attribute differences in between refs and implementations * Update APICompat version and address feedback * Fix builds * PR Feedback, include attributes for all tfms in S.T.Json ref --- eng/Version.Details.xml | 4 +- eng/Versions.props | 2 +- .../System/Reflection/Emit/AssemblyBuilder.cs | 2 +- .../System/Reflection/Emit/ModuleBuilder.cs | 4 +- .../InteropServices/Marshal.CoreCLR.cs | 32 ++++++++++++++++ ...nsions.DependencyInjection.Abstractions.cs | 4 +- ...ns.DependencyInjection.Abstractions.csproj | 2 + .../ref/System.Net.Sockets.cs | 1 + .../ref/System.ObjectModel.cs | 37 ++++++++++--------- .../ref/System.Reflection.Emit.cs | 4 +- .../ref/System.Runtime.InteropServices.cs | 1 + .../ref/System.Runtime.Loader.cs | 4 ++ .../System.Runtime/ref/System.Runtime.cs | 7 ++-- ...tem.ServiceModel.Syndication.netcoreapp.cs | 10 ++--- .../System.Text.Json/ref/System.Text.Json.cs | 5 --- .../ref/System.Text.Json.csproj | 4 ++ src/libraries/shims/ApiCompat.proj | 1 + .../ApiCompatBaseline.PreviousNetCoreApp.txt | 18 ++++----- 18 files changed, 91 insertions(+), 51 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6e2321c81bbc..62948380391f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -18,9 +18,9 @@ https://github.com/dotnet/arcade f6192d1e284a08ac05041d05fa6e60dec74b24f5 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + 39c3b73c4b2b79981405e865e5a4fa096662f13a https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 626488d72481..dac2f73712b3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -49,7 +49,7 @@ - 5.0.0-beta.20374.1 + 5.0.0-beta.20381.6 5.0.0-beta.20374.1 5.0.0-beta.20374.1 5.0.0-beta.20374.1 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 60d6791a0572..7313b405bf0e 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 @@ -497,7 +497,7 @@ public override FileStream[] GetFiles(bool getResourceModules) public override Module? GetModule(string name) => InternalAssembly.GetModule(name); - [RequiresUnreferencedCode("Types might be removed")] + [RequiresUnreferencedCode("Assembly references might be removed")] public override AssemblyName[] GetReferencedAssemblies() { return InternalAssembly.GetReferencedAssemblies(); 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 c1ed6b887a02..aec1ca393d4c 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 @@ -742,13 +742,13 @@ public override FieldInfo[] GetFields(BindingFlags bindingFlags) return InternalModule.GetField(name, bindingAttr); } - [RequiresUnreferencedCode("Fields might be removed")] + [RequiresUnreferencedCode("Methods might be removed")] public override MethodInfo[] GetMethods(BindingFlags bindingFlags) { return InternalModule.GetMethods(bindingFlags); } - [RequiresUnreferencedCode("Fields might be removed")] + [RequiresUnreferencedCode("Methods 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/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 33d43881adb3..33efcbf9a335 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 @@ -5,6 +5,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices.ComTypes; +using System.Runtime.Versioning; using System.StubHelpers; namespace System.Runtime.InteropServices @@ -306,6 +307,7 @@ public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb) /// /// Given a managed object that wraps an ITypeInfo, return its name. /// + [MinimumOSPlatform("windows7.0")] public static string GetTypeInfoName(ITypeInfo typeInfo) { if (typeInfo is null) @@ -319,12 +321,14 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) // This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it // on Marshal for more consistent API surface. + [MinimumOSPlatform("windows7.0")] public static Type? GetTypeFromCLSID(Guid clsid) => RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError: false); /// /// Return the IUnknown* for an Object if the current context is the one /// where the RCW was first seen. Will return null otherwise. /// + [MinimumOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetIUnknownForObject(object o) { if (o is null) @@ -348,6 +352,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the IDispatch* for an Object. /// + [MinimumOSPlatform("windows7.0")] public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) { if (o is null) @@ -365,6 +370,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Return the IUnknown* representing the interface for the Object. /// Object o should support Type T /// + [MinimumOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T) { if (o is null) @@ -380,6 +386,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) return GetComInterfaceForObjectNative(o, T, false, true); } + [MinimumOSPlatform("windows7.0")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) => GetComInterfaceForObject(o!, typeof(TInterface)); /// @@ -387,6 +394,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Object o should support Type T, it refer the value of mode to /// invoke customized QueryInterface or not. /// + [MinimumOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode) { if (o is null) @@ -409,6 +417,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the managed object representing the IUnknown* /// + [MinimumOSPlatform("windows7.0")] public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { if (pUnk == IntPtr.Zero) @@ -422,6 +431,7 @@ public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) [MethodImpl(MethodImplOptions.InternalCall)] private static extern object GetObjectForIUnknownNative(IntPtr /* IUnknown* */ pUnk); + [MinimumOSPlatform("windows7.0")] public static object GetUniqueObjectForIUnknown(IntPtr unknown) { if (unknown == IntPtr.Zero) @@ -445,12 +455,15 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown) /// Return an Object for IUnknown, using the Type T. /// Type T should be either a COM imported Type or a sub-type of COM imported Type /// + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t); + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o); + [MinimumOSPlatform("windows7.0")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull { return CreateAggregatedObject(pOuter, (object)o); @@ -549,6 +562,7 @@ public static string PtrToStringBSTR(IntPtr ptr) /// Release the COM component and if the reference hits 0 zombie this object. /// Further usage of this Object might throw an exception /// + [MinimumOSPlatform("windows7.0")] public static int ReleaseComObject(object o) { if (o is null) @@ -571,6 +585,7 @@ public static int ReleaseComObject(object o) /// Release the COM component and zombie this object. /// Further usage of this Object might throw an exception /// + [MinimumOSPlatform("windows7.0")] public static int FinalReleaseComObject(object o) { if (o is null) @@ -589,6 +604,7 @@ public static int FinalReleaseComObject(object o) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void InternalFinalReleaseComObject(object o); + [MinimumOSPlatform("windows7.0")] public static object? GetComObjectData(object obj, object key) { if (obj is null) @@ -614,6 +630,7 @@ public static int FinalReleaseComObject(object o) /// false if the data could not be added because there already was data for the /// specified key. /// + [MinimumOSPlatform("windows7.0")] public static bool SetComObjectData(object obj, object key, object? data) { if (obj is null) @@ -637,6 +654,7 @@ public static bool SetComObjectData(object obj, object key, object? data) /// This method takes the given COM object and wraps it in an object /// of the specified type. The type must be derived from __ComObject. /// + [MinimumOSPlatform("windows7.0")] [return: NotNullIfNotNull("o")] public static object? CreateWrapperOfType(object? o, Type t) { @@ -687,6 +705,7 @@ public static bool SetComObjectData(object obj, object key, object? data) return Wrapper; } + [MinimumOSPlatform("windows7.0")] public static TWrapper CreateWrapperOfType([AllowNull] T o) { return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!; @@ -701,6 +720,7 @@ public static TWrapper CreateWrapperOfType([AllowNull] T o) [MethodImpl(MethodImplOptions.InternalCall)] public static extern bool IsTypeVisibleFromCom(Type t); + [MinimumOSPlatform("windows7.0")] public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) { if (pUnk == IntPtr.Zero) @@ -713,6 +733,7 @@ public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr pp } } + [MinimumOSPlatform("windows7.0")] public static unsafe int AddRef(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -721,6 +742,7 @@ public static unsafe int AddRef(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 1 /* IUnknown.AddRef slot */)))(pUnk); } + [MinimumOSPlatform("windows7.0")] public static unsafe int Release(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -729,26 +751,32 @@ public static unsafe int Release(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 2 /* IUnknown.Release slot */)))(pUnk); } + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant); + [MinimumOSPlatform("windows7.0")] public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) { GetNativeVariantForObject((object?)obj, pDstNativeVariant); } + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant); + [MinimumOSPlatform("windows7.0")] [return: MaybeNull] public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { return (T)GetObjectForNativeVariant(pSrcNativeVariant)!; } + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars); + [MinimumOSPlatform("windows7.0")] public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars); @@ -763,15 +791,18 @@ public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int c /// Returns the first valid COM slot that GetMethodInfoForSlot will work on /// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. /// + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetStartComSlot(Type t); /// /// Returns the last valid COM slot that GetMethodInfoForSlot will work on. /// + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetEndComSlot(Type t); + [MinimumOSPlatform("windows7.0")] public static object BindToMoniker(string monikerName) { CreateBindCtx(0, out IBindCtx bindctx); @@ -791,6 +822,7 @@ public static object BindToMoniker(string monikerName) [DllImport(Interop.Libraries.Ole32, PreserveSig = false)] private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult); + [MinimumOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak); #endif // FEATURE_COMINTEROP diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs index fa3699e2218f..5f9137309bb5 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs @@ -14,6 +14,7 @@ public static partial class ActivatorUtilities public static object GetServiceOrCreateInstance(System.IServiceProvider provider, System.Type type) { throw null; } public static T GetServiceOrCreateInstance(System.IServiceProvider provider) { throw null; } } + [System.AttributeUsageAttribute(System.AttributeTargets.All)] public partial class ActivatorUtilitiesConstructorAttribute : System.Attribute { public ActivatorUtilitiesConstructorAttribute() { } @@ -69,9 +70,10 @@ public partial class ServiceDescriptor { public ServiceDescriptor(System.Type serviceType, System.Func factory, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { } public ServiceDescriptor(System.Type serviceType, object instance) { } - public ServiceDescriptor(System.Type serviceType, System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { } + public ServiceDescriptor(System.Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { } public System.Func? ImplementationFactory { get { throw null; } } public object? ImplementationInstance { get { throw null; } } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public System.Type? ImplementationType { get { throw null; } } public Microsoft.Extensions.DependencyInjection.ServiceLifetime Lifetime { get { throw null; } } public System.Type ServiceType { get { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index 36abc792ab94..6b74303de9ee 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -5,5 +5,7 @@ + + diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index 0917f00c68e0..39e114d0d2a9 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -254,6 +254,7 @@ public partial class Socket : System.IDisposable { public Socket(System.Net.Sockets.SafeSocketHandle handle) { } public Socket(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } + [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] public Socket(System.Net.Sockets.SocketInformation socketInformation) { } public Socket(System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } public System.Net.Sockets.AddressFamily AddressFamily { get { throw null; } } diff --git a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs index e29b22bb1505..150918a79900 100644 --- a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs +++ b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs @@ -50,12 +50,12 @@ public ReadOnlyDictionary(System.Collections.Generic.IDictionary d protected System.Collections.Generic.IDictionary Dictionary { get { throw null; } } public TValue this[TKey key] { get { throw null; } } public System.Collections.ObjectModel.ReadOnlyDictionary.KeyCollection Keys { get { throw null; } } - bool System.Collections.Generic.ICollection>.IsReadOnly { get { throw null; } } - TValue System.Collections.Generic.IDictionary.this[TKey key] { get { throw null; } set { } } - System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get { throw null; } } - System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get { throw null; } } - System.Collections.Generic.IEnumerable System.Collections.Generic.IReadOnlyDictionary.Keys { get { throw null; } } - System.Collections.Generic.IEnumerable System.Collections.Generic.IReadOnlyDictionary.Values { get { throw null; } } + bool System.Collections.Generic.ICollection>.IsReadOnly { get { throw null; } } + TValue System.Collections.Generic.IDictionary.this[TKey key] { get { throw null; } set { } } + System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get { throw null; } } + System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get { throw null; } } + System.Collections.Generic.IEnumerable System.Collections.Generic.IReadOnlyDictionary.Keys { get { throw null; } } + System.Collections.Generic.IEnumerable System.Collections.Generic.IReadOnlyDictionary.Values { get { throw null; } } bool System.Collections.ICollection.IsSynchronized { get { throw null; } } object System.Collections.ICollection.SyncRoot { get { throw null; } } bool System.Collections.IDictionary.IsFixedSize { get { throw null; } } @@ -66,13 +66,13 @@ public ReadOnlyDictionary(System.Collections.Generic.IDictionary d public System.Collections.ObjectModel.ReadOnlyDictionary.ValueCollection Values { get { throw null; } } public bool ContainsKey(TKey key) { throw null; } public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } - void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) { } - void System.Collections.Generic.ICollection>.Clear() { } - bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) { throw null; } - void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { } - bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) { throw null; } - void System.Collections.Generic.IDictionary.Add(TKey key, TValue value) { } - bool System.Collections.Generic.IDictionary.Remove(TKey key) { throw null; } + void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) { } + void System.Collections.Generic.ICollection>.Clear() { } + bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) { throw null; } + void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { } + bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) { throw null; } + void System.Collections.Generic.IDictionary.Add(TKey key, TValue value) { } + bool System.Collections.Generic.IDictionary.Remove(TKey key) { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } void System.Collections.IDictionary.Add(object key, object? value) { } void System.Collections.IDictionary.Clear() { } @@ -198,9 +198,9 @@ public sealed partial class TypeConverterAttribute : System.Attribute { public static readonly System.ComponentModel.TypeConverterAttribute Default; public TypeConverterAttribute() { } - public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName) { } - public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { } - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] + public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName) { } + public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public string ConverterTypeName { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } @@ -208,8 +208,9 @@ public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccess [System.AttributeUsageAttribute(System.AttributeTargets.Class, Inherited=true)] public sealed partial class TypeDescriptionProviderAttribute : System.Attribute { - public TypeDescriptionProviderAttribute(string typeName) { } - public TypeDescriptionProviderAttribute(System.Type type) { } + public TypeDescriptionProviderAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] string typeName) { } + public TypeDescriptionProviderAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type type) { } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public string TypeName { get { throw null; } } } } 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 f5b245a5cee0..a84677c50ffe 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -42,7 +42,7 @@ 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")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Assembly references 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; } @@ -365,7 +365,7 @@ public void CreateGlobalFunctions() { } [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")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Methods 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")] 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 792ccaa5377c..a7cc4f4bffd8 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -493,6 +493,7 @@ public static void Copy(float[] source, int startIndex, System.IntPtr destinatio [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o) { throw null; } + [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, T o) where T : notnull { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] diff --git a/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs b/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs index b73650c6b757..a942f9030c0d 100644 --- a/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs +++ b/src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs @@ -41,9 +41,13 @@ public event System.Action? Unloading public static System.Runtime.Loader.AssemblyLoadContext? GetLoadContext(System.Reflection.Assembly assembly) { throw null; } protected virtual System.Reflection.Assembly? Load(System.Reflection.AssemblyName assemblyName) { throw null; } public System.Reflection.Assembly LoadFromAssemblyName(System.Reflection.AssemblyName assemblyName) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public System.Reflection.Assembly LoadFromAssemblyPath(string assemblyPath) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public System.Reflection.Assembly LoadFromNativeImagePath(string nativeImagePath, string? assemblyPath) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public System.Reflection.Assembly LoadFromStream(System.IO.Stream assembly) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public System.Reflection.Assembly LoadFromStream(System.IO.Stream assembly, System.IO.Stream? assemblySymbols) { throw null; } protected virtual System.IntPtr LoadUnmanagedDll(string unmanagedDllName) { throw null; } protected System.IntPtr LoadUnmanagedDllFromPath(string unmanagedDllPath) { throw null; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 56cc3ae7b648..c19f4f56f631 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8835,6 +8835,7 @@ public ResourceManager(System.Type resourceSource) { } public virtual string BaseName { get { throw null; } } protected System.Resources.UltimateResourceFallbackLocation FallbackLocation { get { throw null; } set { } } public virtual bool IgnoreCase { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors)] public virtual System.Type ResourceSetType { get { throw null; } } public static System.Resources.ResourceManager CreateFileBasedResourceManager(string baseName, string resourceDir, System.Type? usingResourceSet) { throw null; } protected static System.Globalization.CultureInfo GetNeutralResourcesLanguage(System.Reflection.Assembly a) { throw null; } @@ -9971,12 +9972,12 @@ public FrameworkName(string identifier, System.Version version, string? profile) public static bool operator !=(System.Runtime.Versioning.FrameworkName? left, System.Runtime.Versioning.FrameworkName? right) { throw null; } public override string ToString() { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] public sealed class MinimumOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public MinimumOSPlatformAttribute(string platformName) : base(platformName) { } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] public sealed class ObsoletedInOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public ObsoletedInOSPlatformAttribute(string platformName) : base(platformName) { } @@ -9989,7 +9990,7 @@ public abstract class OSPlatformAttribute : System.Attribute private protected OSPlatformAttribute(string platformName) { } public string PlatformName { get; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] public sealed class RemovedInOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public RemovedInOSPlatformAttribute(string platformName) : base(platformName) { } diff --git a/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.netcoreapp.cs b/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.netcoreapp.cs index 216b88d505b0..866e28444fe1 100644 --- a/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.netcoreapp.cs +++ b/src/libraries/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.netcoreapp.cs @@ -34,16 +34,16 @@ public partial struct XmlDateTimeData private object _dummy; private int _dummyPrimitive; public XmlDateTimeData(string dateTimeString, System.Xml.XmlQualifiedName elementQualifiedName) { throw null; } - public string DateTimeString { get { throw null; } } - public System.Xml.XmlQualifiedName ElementQualifiedName { get { throw null; } } + public readonly string DateTimeString { get { throw null; } } + public readonly System.Xml.XmlQualifiedName ElementQualifiedName { get { throw null; } } } public partial struct XmlUriData { private object _dummy; private int _dummyPrimitive; public XmlUriData(string uriString, System.UriKind uriKind, System.Xml.XmlQualifiedName elementQualifiedName) { throw null; } - public System.Xml.XmlQualifiedName ElementQualifiedName { get { throw null; } } - public System.UriKind UriKind { get { throw null; } } - public string UriString { get { throw null; } } + public readonly System.Xml.XmlQualifiedName ElementQualifiedName { get { throw null; } } + public readonly System.UriKind UriKind { get { throw null; } } + public readonly string UriString { get { throw null; } } } } 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 514e3bd8b53f..533f4f4a7513 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -518,14 +518,9 @@ internal JsonConverter() { } public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute { protected JsonConverterAttribute() { } -#if NETCOREAPP && !NETCOREAPP3_0 public JsonConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type converterType) { } [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public System.Type? ConverterType { get { throw null; } } -#else - public JsonConverterAttribute(System.Type converterType) { } - public System.Type? ConverterType { get { throw null; } } -#endif public virtual System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert) { throw null; } } public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index affb45ae6be2..d041bece0a67 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -6,6 +6,10 @@ + + + + diff --git a/src/libraries/shims/ApiCompat.proj b/src/libraries/shims/ApiCompat.proj index da102c545083..bfb6304de49b 100644 --- a/src/libraries/shims/ApiCompat.proj +++ b/src/libraries/shims/ApiCompat.proj @@ -2,6 +2,7 @@ $(BuildTargetFramework) + $(NetCoreAppCurrent) false netcoreapp3.1 diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index 99ad677cb9b7..078e32277bdf 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -20,7 +20,7 @@ CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.Diagnostics.ProcessStartInfo.Environment' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' on 'System.Diagnostics.ProcessStartInfo.Verb' changed from '[DefaultValueAttribute(null)]' in the contract to '[DefaultValueAttribute("")]' in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.Diagnostics.ProcessStartInfo.WindowStyle' in the contract but not the implementation. -Compat issues due to removal of System.Runtime.InteropServices.WindowsRuntime +Compat issues due to removal of System.Runtime.InteropServices.WindowsRuntime: TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.DefaultInterfaceAttribute' does not exist in the implementation but it does exist in the contract. TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken' does not exist in the implementation but it does exist in the contract. TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable' does not exist in the implementation but it does exist in the contract. @@ -30,13 +30,9 @@ TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArr TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute' does not exist in the implementation but it does exist in the contract. TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal' does not exist in the implementation but it does exist in the contract. TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArrayAttribute' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.DefaultInterfaceAttribute' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.IActivationFactory' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.InterfaceImplementedInVersionAttribute' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArrayAttribute' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal' does not exist in the implementation but it does exist in the contract. -TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArrayAttribute' does not exist in the implementation but it does exist in the contract. -Total Issues: 36 +Compat issues with assembly System.Text.Json: +CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonConverterAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Struct, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Struct, AllowMultiple=false)]' in the implementation. +CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonExtensionDataAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. +CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonIgnoreAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. +CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonPropertyNameAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. +Total Issues: 40 From 035737c6e5fd8d664974e8598693aaa3abbc5811 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 4 Aug 2020 04:10:23 +0200 Subject: [PATCH 224/755] Fix Windows coreclr.dll size regression (#40282) * Fix Windows coreclr.dll size regression A recent change has replaced usage of SELECTANY by constexpr to significantly reduce size of coreclr binaries on Unix. But it has resulted in about 180kB regression in coreclr.dll size on Windows. This change gets rid of the constexpr at places that can be reasonably moved to having declaration in header and definition in a .cpp file. I've also found a couple of things that are not used anymore, so I have deleted them. The only thing where I've moved back to using SELECTANY on Windows is the DbgIPCEventTypeNames in dbgipcevents.h. That table and the related GetEventType / GetEventName methods are used in both mscordbi and coreclr and sharing a .cpp source with the data between those two libraries was ugly and problematic. * Fix x86 build * Fix clang format * Reflect PR feedback defined(_MSC_VER) --- src/coreclr/src/debug/inc/dbgipcevents.h | 7 +- .../src/dlls/mscorpe/ceefilegenwriter.cpp | 160 ++++++++++++++++- src/coreclr/src/dlls/mscorpe/stubs.h | 168 ------------------ src/coreclr/src/gcinfo/CMakeLists.txt | 1 + src/coreclr/src/gcinfo/simplerhash.cpp | 41 +++++ src/coreclr/src/inc/delayloadhelpers.h | 112 ------------ src/coreclr/src/inc/simplerhash.inl | 31 +--- src/coreclr/src/inc/utilcode.h | 13 +- src/coreclr/src/jit/CMakeLists.txt | 1 + src/coreclr/src/jit/_typeinfo.h | 6 +- src/coreclr/src/jit/compiler.hpp | 5 + src/coreclr/src/jit/jithashtable.cpp | 53 ++++++ src/coreclr/src/jit/jithashtable.h | 33 +--- src/coreclr/src/jit/target.h | 39 ++-- src/coreclr/src/jit/targetamd64.cpp | 14 ++ src/coreclr/src/jit/targetarm.cpp | 8 + src/coreclr/src/jit/targetarm64.cpp | 8 + src/coreclr/src/jit/targetx86.cpp | 5 + src/coreclr/src/utilcode/CMakeLists.txt | 1 - src/coreclr/src/utilcode/delayloadhelpers.cpp | 113 ------------ src/coreclr/src/vm/stdinterfaces.cpp | 2 +- 21 files changed, 333 insertions(+), 488 deletions(-) delete mode 100644 src/coreclr/src/dlls/mscorpe/stubs.h create mode 100644 src/coreclr/src/gcinfo/simplerhash.cpp delete mode 100644 src/coreclr/src/inc/delayloadhelpers.h create mode 100644 src/coreclr/src/jit/jithashtable.cpp delete mode 100644 src/coreclr/src/utilcode/delayloadhelpers.cpp diff --git a/src/coreclr/src/debug/inc/dbgipcevents.h b/src/coreclr/src/debug/inc/dbgipcevents.h index 3bff8ccaa188..34d8130bc5e4 100644 --- a/src/coreclr/src/debug/inc/dbgipcevents.h +++ b/src/coreclr/src/debug/inc/dbgipcevents.h @@ -984,7 +984,12 @@ struct MSLAYOUT IPCEventTypeNameMapping const char * eventName; }; -constexpr IPCEventTypeNameMapping DbgIPCEventTypeNames[] = +#ifdef _MSC_VER +extern const __declspec(selectany) +#else +constexpr +#endif +IPCEventTypeNameMapping DbgIPCEventTypeNames[] = { #define IPC_EVENT_TYPE0(type, val) { type, #type }, #define IPC_EVENT_TYPE1(type, val) { type, #type }, diff --git a/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp b/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp index 77afa5a83024..0fb18b0629b2 100644 --- a/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp +++ b/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp @@ -12,10 +12,168 @@ #include #include "corerror.h" -#include "stubs.h" #include #include +// The following block contains a template for the default entry point stubs of a COM+ +// IL only program. One can emit these stubs (with some fix-ups) and make +// the code supplied the entry point value for the image. The fix-ups will +// in turn cause mscoree.dll to be loaded and the correct entry point to be +// called. +// +// Note: Although these stubs contain x86 specific code, they are used +// for all platforms + + +//***************************************************************************** +// This stub is designed for a x86 Windows application. It will call the +// _CorExeMain function in mscoree.dll. This entry point will in turn load +// and run the IL program. +// +// jump _CorExeMain(); +// +// The code jumps to the imported function _CorExeMain using the iat. +// The address in the template is address of the iat entry which is +// fixed up by the loader when the image is paged in. +//***************************************************************************** + +const BYTE ExeMainX86Template[] = +{ + // Jump through IAT to _CorExeMain + 0xFF, 0x25, // jmp [iat:_CorDllMain entry] + 0x00, 0x00, 0x00, 0x00, // address to replace + +}; + +#define ExeMainX86TemplateSize sizeof(ExeMainX86Template) +#define CorExeMainX86IATOffset 2 + +//***************************************************************************** +// This stub is designed for a x86 Windows application. It will call the +// _CorDllMain function in mscoree.dll with with the base entry point for +// the loaded DLL. This entry point will in turn load and run the IL program. +// +// jump _CorDllMain +// +// The code jumps to the imported function _CorExeMain using the iat. +// The address in the template is address of the iat entry which is +// fixed up by the loader when the image is paged in. +//***************************************************************************** + +const BYTE DllMainX86Template[] = +{ + // Jump through IAT to CorDllMain + 0xFF, 0x25, // jmp [iat:_CorDllMain entry] + 0x00, 0x00, 0x00, 0x00, // address to replace +}; + +#define DllMainX86TemplateSize sizeof(DllMainX86Template) +#define CorDllMainX86IATOffset 2 + +//***************************************************************************** +// This stub is designed for a AMD64 Windows application. It will call the +// _CorExeMain function in mscoree.dll. This entry point will in turn load +// and run the IL program. +// +// mov rax, _CorExeMain(); +// jmp [rax] +// +// The code jumps to the imported function _CorExeMain using the iat. +// The address in the template is address of the iat entry which is +// fixed up by the loader when the image is paged in. +//***************************************************************************** + +const BYTE ExeMainAMD64Template[] = +{ + // Jump through IAT to _CorExeMain + 0x48, 0xA1, // rex.w rex.b mov rax,[following address] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorExeMain entry + 0xFF, 0xE0 // jmp [rax] +}; + +#define ExeMainAMD64TemplateSize sizeof(ExeMainAMD64Template) +#define CorExeMainAMD64IATOffset 2 + +//***************************************************************************** +// This stub is designed for a AMD64 Windows application. It will call the +// _CorDllMain function in mscoree.dll with with the base entry point for +// the loaded DLL. This entry point will in turn load and run the IL program. +// +// mov rax, _CorDllMain(); +// jmp [rax] +// +// The code jumps to the imported function _CorDllMain using the iat. +// The address in the template is address of the iat entry which is +// fixed up by the loader when the image is paged in. +//***************************************************************************** + +const BYTE DllMainAMD64Template[] = +{ + // Jump through IAT to CorDllMain + 0x48, 0xA1, // rex.w rex.b mov rax,[following address] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorDllMain entry + 0xFF, 0xE0 // jmp [rax] +}; + +#define DllMainAMD64TemplateSize sizeof(DllMainAMD64Template) +#define CorDllMainAMD64IATOffset 2 + +//***************************************************************************** +// This stub is designed for an ia64 Windows application. It will call the +// _CorExeMain function in mscoree.dll. This entry point will in turn load +// and run the IL program. +// +// jump _CorExeMain(); +// +// The code jumps to the imported function _CorExeMain using the iat. +// We set the value of gp to point at the iat table entry for _CorExeMain +//***************************************************************************** + +const BYTE ExeMainIA64Template[] = +{ + // ld8 r9 = [gp] ;; + // ld8 r10 = [r9],8 + // nop.i ;; + // ld8 gp = [r9] + // mov b6 = r10 + // br.cond.sptk.few b6 + // + 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, + 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, + 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00 +}; + +#define ExeMainIA64TemplateSize sizeof(ExeMainIA64Template) + +//***************************************************************************** +// This stub is designed for an ia64 Windows application. It will call the +// _CorDllMain function in mscoree.dll with with the base entry point for +// the loaded DLL. This entry point will in turn load and run the IL program. +// +// jump _CorDllMain +// +// The code jumps to the imported function _CorExeMain using the iat. +// We set the value of gp to point at the iat table entry for _CorExeMain +//***************************************************************************** + +const BYTE DllMainIA64Template[] = +{ + // ld8 r9 = [gp] ;; + // ld8 r10 = [r9],8 + // nop.i ;; + // ld8 gp = [r9] + // mov b6 = r10 + // br.cond.sptk.few b6 + // + 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, + 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, + 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00 +}; + +#define DllMainIA64TemplateSize sizeof(DllMainIA64Template) + #ifdef EMIT_FIXUPS // Emitted PEFIXUP structure looks like this diff --git a/src/coreclr/src/dlls/mscorpe/stubs.h b/src/coreclr/src/dlls/mscorpe/stubs.h deleted file mode 100644 index f0e7ce380df3..000000000000 --- a/src/coreclr/src/dlls/mscorpe/stubs.h +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// Stubs.h -// -// This file contains a template for the default entry point stubs of a COM+ -// IL only program. One can emit these stubs (with some fix-ups) and make -// the code supplied the entry point value for the image. The fix-ups will -// in turn cause mscoree.dll to be loaded and the correct entry point to be -// called. -// -// Note: Although these stubs contain x86 specific code, they are used -// for all platforms -// -//***************************************************************************** -#ifndef __STUBS_H__ -#define __STUBS_H__ - -//***************************************************************************** -// This stub is designed for a x86 Windows application. It will call the -// _CorExeMain function in mscoree.dll. This entry point will in turn load -// and run the IL program. -// -// jump _CorExeMain(); -// -// The code jumps to the imported function _CorExeMain using the iat. -// The address in the template is address of the iat entry which is -// fixed up by the loader when the image is paged in. -//***************************************************************************** - -constexpr BYTE ExeMainX86Template[] = -{ - // Jump through IAT to _CorExeMain - 0xFF, 0x25, // jmp [iat:_CorDllMain entry] - 0x00, 0x00, 0x00, 0x00, // address to replace - -}; - -#define ExeMainX86TemplateSize sizeof(ExeMainX86Template) -#define CorExeMainX86IATOffset 2 - -//***************************************************************************** -// This stub is designed for a x86 Windows application. It will call the -// _CorDllMain function in mscoree.dll with with the base entry point for -// the loaded DLL. This entry point will in turn load and run the IL program. -// -// jump _CorDllMain -// -// The code jumps to the imported function _CorExeMain using the iat. -// The address in the template is address of the iat entry which is -// fixed up by the loader when the image is paged in. -//***************************************************************************** - -constexpr BYTE DllMainX86Template[] = -{ - // Jump through IAT to CorDllMain - 0xFF, 0x25, // jmp [iat:_CorDllMain entry] - 0x00, 0x00, 0x00, 0x00, // address to replace -}; - -#define DllMainX86TemplateSize sizeof(DllMainX86Template) -#define CorDllMainX86IATOffset 2 - -//***************************************************************************** -// This stub is designed for a AMD64 Windows application. It will call the -// _CorExeMain function in mscoree.dll. This entry point will in turn load -// and run the IL program. -// -// mov rax, _CorExeMain(); -// jmp [rax] -// -// The code jumps to the imported function _CorExeMain using the iat. -// The address in the template is address of the iat entry which is -// fixed up by the loader when the image is paged in. -//***************************************************************************** - -constexpr BYTE ExeMainAMD64Template[] = -{ - // Jump through IAT to _CorExeMain - 0x48, 0xA1, // rex.w rex.b mov rax,[following address] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorExeMain entry - 0xFF, 0xE0 // jmp [rax] -}; - -#define ExeMainAMD64TemplateSize sizeof(ExeMainAMD64Template) -#define CorExeMainAMD64IATOffset 2 - -//***************************************************************************** -// This stub is designed for a AMD64 Windows application. It will call the -// _CorDllMain function in mscoree.dll with with the base entry point for -// the loaded DLL. This entry point will in turn load and run the IL program. -// -// mov rax, _CorDllMain(); -// jmp [rax] -// -// The code jumps to the imported function _CorDllMain using the iat. -// The address in the template is address of the iat entry which is -// fixed up by the loader when the image is paged in. -//***************************************************************************** - -constexpr BYTE DllMainAMD64Template[] = -{ - // Jump through IAT to CorDllMain - 0x48, 0xA1, // rex.w rex.b mov rax,[following address] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorDllMain entry - 0xFF, 0xE0 // jmp [rax] -}; - -#define DllMainAMD64TemplateSize sizeof(DllMainAMD64Template) -#define CorDllMainAMD64IATOffset 2 - -//***************************************************************************** -// This stub is designed for an ia64 Windows application. It will call the -// _CorExeMain function in mscoree.dll. This entry point will in turn load -// and run the IL program. -// -// jump _CorExeMain(); -// -// The code jumps to the imported function _CorExeMain using the iat. -// We set the value of gp to point at the iat table entry for _CorExeMain -//***************************************************************************** - -constexpr BYTE ExeMainIA64Template[] = -{ - // ld8 r9 = [gp] ;; - // ld8 r10 = [r9],8 - // nop.i ;; - // ld8 gp = [r9] - // mov b6 = r10 - // br.cond.sptk.few b6 - // - 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, - 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, - 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00 -}; - -#define ExeMainIA64TemplateSize sizeof(ExeMainIA64Template) - -//***************************************************************************** -// This stub is designed for an ia64 Windows application. It will call the -// _CorDllMain function in mscoree.dll with with the base entry point for -// the loaded DLL. This entry point will in turn load and run the IL program. -// -// jump _CorDllMain -// -// The code jumps to the imported function _CorExeMain using the iat. -// We set the value of gp to point at the iat table entry for _CorExeMain -//***************************************************************************** - -constexpr BYTE DllMainIA64Template[] = -{ - // ld8 r9 = [gp] ;; - // ld8 r10 = [r9],8 - // nop.i ;; - // ld8 gp = [r9] - // mov b6 = r10 - // br.cond.sptk.few b6 - // - 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, - 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, - 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00 -}; - -#define DllMainIA64TemplateSize sizeof(DllMainIA64Template) - -#endif // __STUBS_H__ diff --git a/src/coreclr/src/gcinfo/CMakeLists.txt b/src/coreclr/src/gcinfo/CMakeLists.txt index 3862de8633d0..98801f1f7bc3 100644 --- a/src/coreclr/src/gcinfo/CMakeLists.txt +++ b/src/coreclr/src/gcinfo/CMakeLists.txt @@ -3,6 +3,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set( GCINFO_SOURCES arraylist.cpp gcinfoencoder.cpp + simplerhash.cpp ) diff --git a/src/coreclr/src/gcinfo/simplerhash.cpp b/src/coreclr/src/gcinfo/simplerhash.cpp new file mode 100644 index 000000000000..1233b91538c2 --- /dev/null +++ b/src/coreclr/src/gcinfo/simplerhash.cpp @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "simplerhash.h" + +// Table of primes and their magic-number-divide constant. +// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1" +// These were selected by looking for primes, each roughly twice as big as the next, having +// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). +// + +const PrimeInfo primeInfo[] = +{ + PrimeInfo(9, 0x38e38e39, 1), + PrimeInfo(23, 0xb21642c9, 4), + PrimeInfo(59, 0x22b63cbf, 3), + PrimeInfo(131, 0xfa232cf3, 7), + PrimeInfo(239, 0x891ac73b, 7), + PrimeInfo(433, 0x975a751, 4), + PrimeInfo(761, 0x561e46a5, 8), + PrimeInfo(1399, 0xbb612aa3, 10), + PrimeInfo(2473, 0x6a009f01, 10), + PrimeInfo(4327, 0xf2555049, 12), + PrimeInfo(7499, 0x45ea155f, 11), + PrimeInfo(12973, 0x1434f6d3, 10), + PrimeInfo(22433, 0x2ebe18db, 12), + PrimeInfo(46559, 0xb42bebd5, 15), + PrimeInfo(96581, 0xadb61b1b, 16), + PrimeInfo(200341, 0x29df2461, 15), + PrimeInfo(415517, 0xa181c46d, 18), + PrimeInfo(861719, 0x4de0bde5, 18), + PrimeInfo(1787021, 0x9636c46f, 20), + PrimeInfo(3705617, 0x4870adc1, 20), + PrimeInfo(7684087, 0x8bbc5b83, 22), + PrimeInfo(15933877, 0x86c65361, 23), + PrimeInfo(33040633, 0x40fec79b, 23), + PrimeInfo(68513161, 0x7d605cd1, 25), + PrimeInfo(142069021, 0xf1da390b, 27), + PrimeInfo(294594427, 0x74a2507d, 27), + PrimeInfo(733045421, 0x5dbec447, 28), +}; diff --git a/src/coreclr/src/inc/delayloadhelpers.h b/src/coreclr/src/inc/delayloadhelpers.h deleted file mode 100644 index 160a9da30680..000000000000 --- a/src/coreclr/src/inc/delayloadhelpers.h +++ /dev/null @@ -1,112 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// Contains convenience functionality for lazily loading modules -// and getting entrypoints within them. -// - -#ifndef DelayLoadHelpers_h -#define DelayLoadHelpers_h - -#include "volatile.h" - -namespace DelayLoad -{ - //================================================================================================================= - // Contains information needed to load and cache a module. Use through - // the DELAY_LOADED_MODULE macro defined below. - struct Module - { - LPCWSTR const m_wzDllName; - HMODULE m_hMod; - HRESULT m_hr; - Volatile m_fInitialized; - - // Returns a non-ref-counted HMODULE; will load the module if necessary. - // Do not FreeLibrary the returned value. - HRESULT GetValue(HMODULE *pHMODULE); - }; -} - -//===================================================================================================================== -// Use at global scope to declare a delay loaded module represented as a -// DelayLoad::Module instance. The module may then be accessed as -// 'DelayLoad::Modules::DLL_NAME'. -// -// Parameters: -// DLL_NAME - the simple name (without extension) of the DLL. -// -// Example: -// DELAY_LOADED_MODULE(Kernel32); -// void Foo() { -// HMODULE hModKernel32 = nullptr; -// IfFailThrow(DelayLoad::Modules::Kernel32.GetValue(&hModKernel32)); -// // Use hModKernel32 as needed. Do not FreeLibrary the value! -// } - -#define DELAY_LOADED_MODULE(DLL_NAME) \ - namespace DelayLoad { \ - namespace Modules { \ - constexpr Module DLL_NAME = { L#DLL_NAME W(".dll"), nullptr, S_OK, false }; \ - } \ - } - -namespace DelayLoad -{ - //================================================================================================================= - // Contains information needed to load a function pointer from a DLL. Builds - // on the DelayLoad::Module functionality, and should be used through - // the DELAY_LOADED_FUNCTION macro defined below. - struct Function - { - Module * const m_pModule; - LPCSTR const m_szFunctionName; - PVOID m_pvFunction; - HRESULT m_hr; - Volatile m_fInitialized; - - // On success, ppvFunc is set to point to the entrypoint corresponding to - // m_szFunctionName as exported from m_pModule. - HRESULT GetValue(LPVOID * ppvFunc); - - // Convenience function that does the necessary casting for you. - template inline - HRESULT GetValue(FnT ** ppFunc) - { - return GetValue(reinterpret_cast(ppFunc)); - } - }; -} - -//===================================================================================================================== -// Use at global scope to declare a delay loaded function and its associated module, -// represented as DelayLoad::Function and DelayLoad::Module instances, respectively. -// The function may then be accessed as 'DelayLoad::DLL_NAME::FUNC_NAME', and the -// module may be access as described in DELAY_LOADED_MODULE's comment. -// -// Parameters: -// DLL_NAME - unquoted simple name (without extension) of the DLL containing -// the function. -// FUNC_NAME - unquoted entrypoint name exported from the DLL. -// -// Example: -// DELAY_LOADED_FUNCTION(MyDll, MyFunction); -// HRESULT Foo(...) { -// typedef HRESULT MyFunction_t(); -// MyFunction_t * pFunc = nullptr; -// IfFailRet(DelayLoad::WinTypes::RoResolveNamespace.GetValue(&pFunc)); -// return (*pFunc)(...); -// } - -#define DELAY_LOADED_FUNCTION(DLL_NAME, FUNC_NAME) \ - DELAY_LOADED_MODULE(DLL_NAME) \ - namespace DelayLoad { \ - namespace DLL_NAME { \ - constexpr Function FUNC_NAME = { &Modules::##DLL_NAME, #FUNC_NAME, nullptr, S_OK, false }; \ - } \ - } - -#endif // DelayLoadHelpers_h - diff --git a/src/coreclr/src/inc/simplerhash.inl b/src/coreclr/src/inc/simplerhash.inl index 309778e91791..6694ab61212b 100644 --- a/src/coreclr/src/inc/simplerhash.inl +++ b/src/coreclr/src/inc/simplerhash.inl @@ -303,36 +303,7 @@ void SimplerHashTable::Reallocate(unsigned newTable // 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). // -constexpr PrimeInfo primeInfo[] = -{ - PrimeInfo(9, 0x38e38e39, 1), - PrimeInfo(23, 0xb21642c9, 4), - PrimeInfo(59, 0x22b63cbf, 3), - PrimeInfo(131, 0xfa232cf3, 7), - PrimeInfo(239, 0x891ac73b, 7), - PrimeInfo(433, 0x975a751, 4), - PrimeInfo(761, 0x561e46a5, 8), - PrimeInfo(1399, 0xbb612aa3, 10), - PrimeInfo(2473, 0x6a009f01, 10), - PrimeInfo(4327, 0xf2555049, 12), - PrimeInfo(7499, 0x45ea155f, 11), - PrimeInfo(12973, 0x1434f6d3, 10), - PrimeInfo(22433, 0x2ebe18db, 12), - PrimeInfo(46559, 0xb42bebd5, 15), - PrimeInfo(96581, 0xadb61b1b, 16), - PrimeInfo(200341, 0x29df2461, 15), - PrimeInfo(415517, 0xa181c46d, 18), - PrimeInfo(861719, 0x4de0bde5, 18), - PrimeInfo(1787021, 0x9636c46f, 20), - PrimeInfo(3705617, 0x4870adc1, 20), - PrimeInfo(7684087, 0x8bbc5b83, 22), - PrimeInfo(15933877, 0x86c65361, 23), - PrimeInfo(33040633, 0x40fec79b, 23), - PrimeInfo(68513161, 0x7d605cd1, 25), - PrimeInfo(142069021, 0xf1da390b, 27), - PrimeInfo(294594427, 0x74a2507d, 27), - PrimeInfo(733045421, 0x5dbec447, 28), -}; +extern const PrimeInfo primeInfo[27]; template PrimeInfo SimplerHashTable::NextPrime(unsigned number) diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index bc3fb9377e29..4ed456df94c7 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -4073,13 +4073,14 @@ HRESULT GetImageRuntimeVersionString(PVOID pMetaData, LPCSTR* pString); // The registry keys and values that contain the information regarding // the default registered unmanaged debugger. //***************************************************************************** -constexpr WCHAR kDebugApplicationsPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); -constexpr WCHAR kDebugApplicationsKey[] = W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); -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"); +#define kDebugApplicationsPoliciesKey W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications") +#define kDebugApplicationsKey W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications") + +#define kUnmanagedDebuggerKey W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") +#define kUnmanagedDebuggerValue W("Debugger") +#define kUnmanagedDebuggerAutoValue W("Auto") +#define 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/CMakeLists.txt b/src/coreclr/src/jit/CMakeLists.txt index 15aa4d59b63c..3f695823be4f 100644 --- a/src/coreclr/src/jit/CMakeLists.txt +++ b/src/coreclr/src/jit/CMakeLists.txt @@ -54,6 +54,7 @@ set( JIT_SOURCES instr.cpp jitconfig.cpp jiteh.cpp + jithashtable.cpp jittelemetry.cpp lclmorph.cpp lclvars.cpp diff --git a/src/coreclr/src/jit/_typeinfo.h b/src/coreclr/src/jit/_typeinfo.h index 4bc90e50dbe6..26173db3fae4 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 -constexpr char* g_ti_type_names_map[] = { +const char* g_ti_type_names_map[] = { #define DEF_TI(ti, nm) nm, #include "titypes.h" #undef DEF_TI @@ -57,7 +57,7 @@ constexpr char* g_ti_type_names_map[] = { namespace { #endif // _MSC_VER -constexpr ti_types g_jit_types_map[] = { +const 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 -constexpr ti_types g_ti_types_map[CORINFO_TYPE_COUNT] = { +const 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/compiler.hpp b/src/coreclr/src/jit/compiler.hpp index c12bacd94d7a..ca3ed3c6fc66 100644 --- a/src/coreclr/src/jit/compiler.hpp +++ b/src/coreclr/src/jit/compiler.hpp @@ -3169,6 +3169,7 @@ inline regMaskTP genIntAllRegArgMask(unsigned numRegs) inline regMaskTP genFltAllRegArgMask(unsigned numRegs) { +#ifndef TARGET_X86 assert(numRegs <= MAX_FLOAT_REG_ARG); regMaskTP result = RBM_NONE; @@ -3177,6 +3178,10 @@ inline regMaskTP genFltAllRegArgMask(unsigned numRegs) result |= fltArgMasks[i]; } return result; +#else + assert(!"no x86 float arg regs\n"); + return RBM_NONE; +#endif } /* diff --git a/src/coreclr/src/jit/jithashtable.cpp b/src/coreclr/src/jit/jithashtable.cpp new file mode 100644 index 000000000000..cf9f22639efe --- /dev/null +++ b/src/coreclr/src/jit/jithashtable.cpp @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "jitpch.h" + +#if defined(_MSC_VER) +#pragma hdrstop +#endif // defined(_MSC_VER) + +// Table of primes and their magic-number-divide constant. +// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1" +// These were selected by looking for primes, each roughly twice as big as the next, having +// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). + +#include "jithashtable.h" + +// Table of primes and their magic-number-divide constant. +// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1" +// These were selected by looking for primes, each roughly twice as big as the next, having +// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). + +// clang-format off +const JitPrimeInfo jitPrimeInfo[] +{ + JitPrimeInfo(9, 0x38e38e39, 1), + JitPrimeInfo(23, 0xb21642c9, 4), + JitPrimeInfo(59, 0x22b63cbf, 3), + JitPrimeInfo(131, 0xfa232cf3, 7), + JitPrimeInfo(239, 0x891ac73b, 7), + JitPrimeInfo(433, 0x975a751, 4), + JitPrimeInfo(761, 0x561e46a5, 8), + JitPrimeInfo(1399, 0xbb612aa3, 10), + JitPrimeInfo(2473, 0x6a009f01, 10), + JitPrimeInfo(4327, 0xf2555049, 12), + JitPrimeInfo(7499, 0x45ea155f, 11), + JitPrimeInfo(12973, 0x1434f6d3, 10), + JitPrimeInfo(22433, 0x2ebe18db, 12), + JitPrimeInfo(46559, 0xb42bebd5, 15), + JitPrimeInfo(96581, 0xadb61b1b, 16), + JitPrimeInfo(200341, 0x29df2461, 15), + JitPrimeInfo(415517, 0xa181c46d, 18), + JitPrimeInfo(861719, 0x4de0bde5, 18), + JitPrimeInfo(1787021, 0x9636c46f, 20), + JitPrimeInfo(3705617, 0x4870adc1, 20), + JitPrimeInfo(7684087, 0x8bbc5b83, 22), + JitPrimeInfo(15933877, 0x86c65361, 23), + JitPrimeInfo(33040633, 0x40fec79b, 23), + JitPrimeInfo(68513161, 0x7d605cd1, 25), + JitPrimeInfo(142069021, 0xf1da390b, 27), + JitPrimeInfo(294594427, 0x74a2507d, 27), + JitPrimeInfo(733045421, 0x5dbec447, 28), +}; +// clang-format on diff --git a/src/coreclr/src/jit/jithashtable.h b/src/coreclr/src/jit/jithashtable.h index cb2cc1e60d20..131f804a1127 100644 --- a/src/coreclr/src/jit/jithashtable.h +++ b/src/coreclr/src/jit/jithashtable.h @@ -91,38 +91,7 @@ class JitPrimeInfo // These were selected by looking for primes, each roughly twice as big as the next, having // 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). -// clang-format off -constexpr JitPrimeInfo jitPrimeInfo[] -{ - JitPrimeInfo(9, 0x38e38e39, 1), - JitPrimeInfo(23, 0xb21642c9, 4), - JitPrimeInfo(59, 0x22b63cbf, 3), - JitPrimeInfo(131, 0xfa232cf3, 7), - JitPrimeInfo(239, 0x891ac73b, 7), - JitPrimeInfo(433, 0x975a751, 4), - JitPrimeInfo(761, 0x561e46a5, 8), - JitPrimeInfo(1399, 0xbb612aa3, 10), - JitPrimeInfo(2473, 0x6a009f01, 10), - JitPrimeInfo(4327, 0xf2555049, 12), - JitPrimeInfo(7499, 0x45ea155f, 11), - JitPrimeInfo(12973, 0x1434f6d3, 10), - JitPrimeInfo(22433, 0x2ebe18db, 12), - JitPrimeInfo(46559, 0xb42bebd5, 15), - JitPrimeInfo(96581, 0xadb61b1b, 16), - JitPrimeInfo(200341, 0x29df2461, 15), - JitPrimeInfo(415517, 0xa181c46d, 18), - JitPrimeInfo(861719, 0x4de0bde5, 18), - JitPrimeInfo(1787021, 0x9636c46f, 20), - JitPrimeInfo(3705617, 0x4870adc1, 20), - JitPrimeInfo(7684087, 0x8bbc5b83, 22), - JitPrimeInfo(15933877, 0x86c65361, 23), - JitPrimeInfo(33040633, 0x40fec79b, 23), - JitPrimeInfo(68513161, 0x7d605cd1, 25), - JitPrimeInfo(142069021, 0xf1da390b, 27), - JitPrimeInfo(294594427, 0x74a2507d, 27), - JitPrimeInfo(733045421, 0x5dbec447, 28), -}; -// clang-format on +extern const JitPrimeInfo jitPrimeInfo[27]; // Hash table class definition diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index 5eac47184cdd..5b1f6cff48bc 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -436,6 +436,7 @@ typedef unsigned char regNumberSmall; #define FIRST_ARG_STACK_OFFS (2*REGSIZE_BYTES) // Caller's saved EBP and return address #define MAX_REG_ARG 2 + #define MAX_FLOAT_REG_ARG 0 #define REG_ARG_FIRST REG_ECX #define REG_ARG_LAST REG_EDX @@ -444,10 +445,8 @@ typedef unsigned char regNumberSmall; #define REG_ARG_0 REG_ECX #define REG_ARG_1 REG_EDX - 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}; + extern const regNumber intArgRegs [MAX_REG_ARG]; + extern const regMaskTP intArgMasks[MAX_REG_ARG]; #define RBM_ARG_0 RBM_ECX #define RBM_ARG_1 RBM_EDX @@ -782,10 +781,10 @@ typedef unsigned char regNumberSmall; #define REG_ARG_4 REG_R8 #define REG_ARG_5 REG_R9 - 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 }; + extern const regNumber intArgRegs [MAX_REG_ARG]; + extern const regMaskTP intArgMasks[MAX_REG_ARG]; + extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG]; + extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG]; #define RBM_ARG_0 RBM_RDI #define RBM_ARG_1 RBM_RSI @@ -805,10 +804,10 @@ typedef unsigned char regNumberSmall; #define REG_ARG_2 REG_R8 #define REG_ARG_3 REG_R9 - 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 }; + extern const regNumber intArgRegs [MAX_REG_ARG]; + extern const regMaskTP intArgMasks[MAX_REG_ARG]; + extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG]; + extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG]; #define RBM_ARG_0 RBM_ECX #define RBM_ARG_1 RBM_EDX @@ -1155,8 +1154,8 @@ typedef unsigned char regNumberSmall; #define REG_ARG_2 REG_R2 #define REG_ARG_3 REG_R3 - constexpr regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3}; - constexpr regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3}; + extern const regNumber intArgRegs [MAX_REG_ARG]; + extern const regMaskTP intArgMasks[MAX_REG_ARG]; #define RBM_ARG_0 RBM_R0 #define RBM_ARG_1 RBM_R1 @@ -1167,8 +1166,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 - 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 }; + extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG]; + extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG]; #define LBL_DIST_SMALL_MAX_NEG (0) #define LBL_DIST_SMALL_MAX_POS (+1020) @@ -1489,8 +1488,8 @@ typedef unsigned char regNumberSmall; #define REG_ARG_6 REG_R6 #define REG_ARG_7 REG_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}; + extern const regNumber intArgRegs [MAX_REG_ARG]; + extern const regMaskTP intArgMasks[MAX_REG_ARG]; #define RBM_ARG_0 RBM_R0 #define RBM_ARG_1 RBM_R1 @@ -1522,8 +1521,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) - 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 }; + extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG]; + extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG]; #define LBL_DIST_SMALL_MAX_NEG (-1048576) #define LBL_DIST_SMALL_MAX_POS (+1048575) diff --git a/src/coreclr/src/jit/targetamd64.cpp b/src/coreclr/src/jit/targetamd64.cpp index 143e6e464180..372c4dffc27b 100644 --- a/src/coreclr/src/jit/targetamd64.cpp +++ b/src/coreclr/src/jit/targetamd64.cpp @@ -15,4 +15,18 @@ const char* Target::g_tgtCPUName = "x64"; const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L; +// clang-format off +#ifdef UNIX_AMD64_ABI +const regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 }; +const regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 }; +const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 }; +const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 }; +#else // !UNIX_AMD64_ABI +const regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 }; +const regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 }; +const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 }; +const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 }; +#endif // !UNIX_AMD64_ABI +// clang-format on + #endif // TARGET_AMD64 diff --git a/src/coreclr/src/jit/targetarm.cpp b/src/coreclr/src/jit/targetarm.cpp index ca974a76af39..da125cbb436a 100644 --- a/src/coreclr/src/jit/targetarm.cpp +++ b/src/coreclr/src/jit/targetarm.cpp @@ -15,4 +15,12 @@ const char* Target::g_tgtCPUName = "arm"; const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L; +// clang-format off +const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3}; +const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3}; + +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 }; +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 }; +// clang-format on + #endif // TARGET_ARM diff --git a/src/coreclr/src/jit/targetarm64.cpp b/src/coreclr/src/jit/targetarm64.cpp index 7b035f145b01..8f5481a83e02 100644 --- a/src/coreclr/src/jit/targetarm64.cpp +++ b/src/coreclr/src/jit/targetarm64.cpp @@ -15,4 +15,12 @@ const char* Target::g_tgtCPUName = "arm64"; const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L; +// clang-format off +const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7}; +const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3, RBM_R4, RBM_R5, RBM_R6, RBM_R7}; + +const regNumber fltArgRegs [] = {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7 }; +const regMaskTP fltArgMasks[] = {RBM_V0, RBM_V1, RBM_V2, RBM_V3, RBM_V4, RBM_V5, RBM_V6, RBM_V7 }; +// clang-format on + #endif // TARGET_ARM64 diff --git a/src/coreclr/src/jit/targetx86.cpp b/src/coreclr/src/jit/targetx86.cpp index 391a934e5b9e..fab7286782a2 100644 --- a/src/coreclr/src/jit/targetx86.cpp +++ b/src/coreclr/src/jit/targetx86.cpp @@ -15,4 +15,9 @@ const char* Target::g_tgtCPUName = "x86"; const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_L2R; +// clang-format off +const regNumber intArgRegs [] = {REG_ECX, REG_EDX}; +const regMaskTP intArgMasks[] = {RBM_ECX, RBM_EDX}; +// clang-format on + #endif // TARGET_X86 diff --git a/src/coreclr/src/utilcode/CMakeLists.txt b/src/coreclr/src/utilcode/CMakeLists.txt index 4c1ce806b651..30fcba8c0627 100644 --- a/src/coreclr/src/utilcode/CMakeLists.txt +++ b/src/coreclr/src/utilcode/CMakeLists.txt @@ -26,7 +26,6 @@ set(UTILCODE_COMMON_SOURCES arraylist.cpp bitvector.cpp comex.cpp - delayloadhelpers.cpp guidfromname.cpp memorypool.cpp iallocator.cpp diff --git a/src/coreclr/src/utilcode/delayloadhelpers.cpp b/src/coreclr/src/utilcode/delayloadhelpers.cpp deleted file mode 100644 index 90936ccbcfc0..000000000000 --- a/src/coreclr/src/utilcode/delayloadhelpers.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// Contains convenience functionality for lazily loading modules -// and getting entrypoints within them. -// - -#include "stdafx.h" - -#include "crtwrap.h" -#include "winwrap.h" -#include "utilcode.h" -#include "clrhost.h" -#include "holder.h" -#include "delayloadhelpers.h" - -namespace DelayLoad -{ - //================================================================================================================= - // Used to synchronize initialization. Is not used when initialization has already taken place. - - static CRITSEC_COOKIE g_pLock = nullptr; - - //================================================================================================================= - // Creates and initializes g_pLock when first used. - - static HRESULT InitializeLock() - { - STATIC_CONTRACT_LIMITED_METHOD; - HRESULT hr = S_OK; - - CRITSEC_COOKIE pLock = ClrCreateCriticalSection(CrstLeafLock, CRST_REENTRANCY); - IfNullRet(pLock); - if (InterlockedCompareExchangeT(&g_pLock, pLock, nullptr) != nullptr) - { - ClrDeleteCriticalSection(pLock); - } - - return S_OK; - } - - //================================================================================================================= - HRESULT Module::GetValue(HMODULE *pHMODULE) - { - STATIC_CONTRACT_LIMITED_METHOD; - HRESULT hr = S_OK; - - if (pHMODULE == nullptr) - { - return E_INVALIDARG; - } - - if (!m_fInitialized) - { - IfFailRet(InitializeLock()); - - HModuleHolder hMod = ::LoadLibraryW(m_wzDllName); - hr = (hMod == nullptr) ? HRESULT_FROM_GetLastError() : S_OK; - _ASSERTE(FAILED(hr) == (hMod == nullptr)); - - { // Lock scope - CRITSEC_Holder lock(g_pLock); - if (!m_fInitialized) - { - m_hr = hr; - m_hMod = hMod.Extract(); - m_fInitialized = true; - } - } - } - - _ASSERTE(m_fInitialized); - *pHMODULE = m_hMod; - return m_hr; - } - - //================================================================================================================= - HRESULT Function::GetValue(LPVOID * ppvFunc) - { - STATIC_CONTRACT_LIMITED_METHOD; - HRESULT hr = S_OK; - - if (ppvFunc == nullptr) - { - return E_INVALIDARG; - } - - if (!m_fInitialized) - { - HMODULE hMod = nullptr; - IfFailRet(m_pModule->GetValue(&hMod)); - - LPVOID pvFunc = reinterpret_cast(::GetProcAddress(hMod, m_szFunctionName)); - hr = (pvFunc == nullptr) ? HRESULT_FROM_GetLastError() : S_OK; - - { // Lock scope - CRITSEC_Holder lock(g_pLock); - if (!m_fInitialized) - { - m_hr = hr; - m_pvFunction = pvFunc; - m_fInitialized = true; - } - } - } - - _ASSERTE(m_fInitialized); - *ppvFunc = m_pvFunction; - return m_hr; - } -} diff --git a/src/coreclr/src/vm/stdinterfaces.cpp b/src/coreclr/src/vm/stdinterfaces.cpp index c573f3041f13..1913546164ce 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 constexpr GUID IID_IAgileObject = { 0x94ea2b94, 0xe9cc, 0x49e0, { 0xc0, 0xff, 0xee, 0x64, 0xca, 0x8f, 0x5b, 0x90 } }; +EXTERN_C const 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 cb5b205838cc8eab7cc017a83fd667cacb6b04ce Mon Sep 17 00:00:00 2001 From: Fan Yang <52458914+fanyang-mono@users.noreply.github.com> Date: Mon, 3 Aug 2020 22:11:55 -0400 Subject: [PATCH 225/755] Check if a method is dynamic when transforming internal calls (#40266) --- src/mono/mono/mini/interp/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 13c910817b70..1fd13dd4bec3 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1904,7 +1904,7 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas static MonoMethod* interp_transform_internal_calls (MonoMethod *method, MonoMethod *target_method, MonoMethodSignature *csignature, gboolean is_virtual) { - if (method->wrapper_type == MONO_WRAPPER_NONE && target_method != NULL) { + if (((method->wrapper_type == MONO_WRAPPER_NONE) || (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)) && target_method != NULL) { if (target_method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE); if (!is_virtual && target_method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) From 6991ccd1e8cdfb640a74be7db54e81f456406d1f Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Tue, 4 Aug 2020 00:17:46 -0400 Subject: [PATCH 226/755] Change new thread's affinity after thread starts, from the same thread, as a workaround for Snap (#40205) - Snap's default strict confinement doesn't allow setting the affinity of a different thread, and currently doesn't allow `sched_setaffinity(, ...)`, which pthread implementation calls - Switched to use sched_setaffinity(0, ...) where appropriate Fix for https://github.com/dotnet/runtime/issues/1634 in master --- src/coreclr/src/gc/unix/config.gc.h.in | 3 +- src/coreclr/src/gc/unix/configure.cmake | 3 +- src/coreclr/src/gc/unix/gcenv.unix.cpp | 19 ++++- src/coreclr/src/pal/src/config.h.in | 2 +- src/coreclr/src/pal/src/configure.cmake | 2 +- src/coreclr/src/pal/src/thread/thread.cpp | 96 ++++++++++++++--------- 6 files changed, 79 insertions(+), 46 deletions(-) diff --git a/src/coreclr/src/gc/unix/config.gc.h.in b/src/coreclr/src/gc/unix/config.gc.h.in index 954176f74a34..42b6429be80e 100644 --- a/src/coreclr/src/gc/unix/config.gc.h.in +++ b/src/coreclr/src/gc/unix/config.gc.h.in @@ -18,7 +18,8 @@ #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK #cmakedefine01 HAVE_MACH_ABSOLUTE_TIME #cmakedefine01 HAVE_SCHED_GETAFFINITY -#cmakedefine01 HAVE_PTHREAD_GETAFFINITY_NP +#cmakedefine01 HAVE_SCHED_SETAFFINITY +#cmakedefine01 HAVE_PTHREAD_SETAFFINITY_NP #cmakedefine01 HAVE_PTHREAD_NP_H #cmakedefine01 HAVE_CPUSET_T #cmakedefine01 HAVE__SC_AVPHYS_PAGES diff --git a/src/coreclr/src/gc/unix/configure.cmake b/src/coreclr/src/gc/unix/configure.cmake index cc7fb90265d8..6d190a8c4673 100644 --- a/src/coreclr/src/gc/unix/configure.cmake +++ b/src/coreclr/src/gc/unix/configure.cmake @@ -86,6 +86,7 @@ check_cxx_source_runs(" check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY) +check_library_exists(c sched_setaffinity "" HAVE_SCHED_SETAFFINITY) check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) if (HAVE_LIBPTHREAD) @@ -94,7 +95,7 @@ elseif (HAVE_PTHREAD_IN_LIBC) set(PTHREAD_LIBRARY c) endif() -check_library_exists(${PTHREAD_LIBRARY} pthread_getaffinity_np "" HAVE_PTHREAD_GETAFFINITY_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_setaffinity_np "" HAVE_PTHREAD_SETAFFINITY_NP) check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES) check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES) diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index e7a122498699..76a9efaf36e5 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -985,19 +985,32 @@ size_t GCToOSInterface::GetCacheSizePerLogicalCpu(bool trueSize) // true if setting the affinity was successful, false otherwise. bool GCToOSInterface::SetThreadAffinity(uint16_t procNo) { -#if HAVE_PTHREAD_GETAFFINITY_NP +#if HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP cpu_set_t cpuSet; CPU_ZERO(&cpuSet); CPU_SET((int)procNo, &cpuSet); + // Snap's default strict confinement does not allow sched_setaffinity(, ...) without manually connecting the + // process-control plug. sched_setaffinity(, ...) is also currently not allowed, only + // sched_setaffinity(0, ...). pthread_setaffinity_np(pthread_self(), ...) seems to call + // sched_setaffinity(, ...) in at least one implementation, and does not work. To work around those + // issues, use sched_setaffinity(0, ...) if available and only otherwise fall back to pthread_setaffinity_np(). See the + // following for more information: + // - https://github.com/dotnet/runtime/pull/38795 + // - https://github.com/dotnet/runtime/issues/1634 + // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13 +#if HAVE_SCHED_SETAFFINITY + int st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet); +#else int st = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet); +#endif return (st == 0); -#else // HAVE_PTHREAD_GETAFFINITY_NP +#else // !(HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP) // There is no API to manage thread affinity, so let's ignore the request return false; -#endif // HAVE_PTHREAD_GETAFFINITY_NP +#endif // HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP } // Boosts the calling thread's thread priority to a level higher than the default diff --git a/src/coreclr/src/pal/src/config.h.in b/src/coreclr/src/pal/src/config.h.in index 8e7e69288bc9..39a05ee0ff22 100644 --- a/src/coreclr/src/pal/src/config.h.in +++ b/src/coreclr/src/pal/src/config.h.in @@ -36,7 +36,6 @@ #cmakedefine01 HAVE_PTHREAD_GETCPUCLOCKID #cmakedefine01 HAVE_PTHREAD_SIGQUEUE #cmakedefine01 HAVE_PTHREAD_GETAFFINITY_NP -#cmakedefine01 HAVE_PTHREAD_ATTR_SETAFFINITY_NP #cmakedefine01 HAVE_CPUSET_T #cmakedefine01 HAVE_SIGRETURN #cmakedefine01 HAVE__THREAD_SYS_SIGRETURN @@ -66,6 +65,7 @@ #cmakedefine01 HAVE_TTRACE #cmakedefine01 HAVE_PIPE2 #cmakedefine01 HAVE_SCHED_GETAFFINITY +#cmakedefine01 HAVE_SCHED_SETAFFINITY #cmakedefine HAVE_UNW_GET_SAVE_LOC #cmakedefine HAVE_UNW_GET_ACCESSORS #cmakedefine01 HAVE_XSWDEV diff --git a/src/coreclr/src/pal/src/configure.cmake b/src/coreclr/src/pal/src/configure.cmake index b67637b584ba..5fb606a2983d 100644 --- a/src/coreclr/src/pal/src/configure.cmake +++ b/src/coreclr/src/pal/src/configure.cmake @@ -81,6 +81,7 @@ check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H) check_function_exists(kqueue HAVE_KQUEUE) check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY) +check_library_exists(c sched_setaffinity "" HAVE_SCHED_SETAFFINITY) check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) check_library_exists(c pthread_create "" HAVE_PTHREAD_IN_LIBC) @@ -100,7 +101,6 @@ check_library_exists(${PTHREAD_LIBRARY} pthread_getattr_np "" HAVE_PTHREAD_GETAT check_library_exists(${PTHREAD_LIBRARY} pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID) check_library_exists(${PTHREAD_LIBRARY} pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE) check_library_exists(${PTHREAD_LIBRARY} pthread_getaffinity_np "" HAVE_PTHREAD_GETAFFINITY_NP) -check_library_exists(${PTHREAD_LIBRARY} pthread_attr_setaffinity_np "" HAVE_PTHREAD_ATTR_SETAFFINITY_NP) check_function_exists(sigreturn HAVE_SIGRETURN) check_function_exists(_thread_sys_sigreturn HAVE__THREAD_SYS_SIGRETURN) diff --git a/src/coreclr/src/pal/src/thread/thread.cpp b/src/coreclr/src/pal/src/thread/thread.cpp index 6efe93492bc3..89d805c35404 100644 --- a/src/coreclr/src/pal/src/thread/thread.cpp +++ b/src/coreclr/src/pal/src/thread/thread.cpp @@ -740,41 +740,6 @@ CorUnix::InternalCreateThread( storedErrno = errno; #endif // PTHREAD_CREATE_MODIFIES_ERRNO -#if HAVE_PTHREAD_ATTR_SETAFFINITY_NP && HAVE_SCHED_GETAFFINITY - { - // Threads inherit their parent's affinity mask on Linux. This is not desired, so we reset - // the current thread's affinity mask to the mask of the current process. - cpu_set_t cpuSet; - CPU_ZERO(&cpuSet); - - int st = sched_getaffinity(gPID, sizeof(cpu_set_t), &cpuSet); - if (st != 0) - { - ASSERT("sched_getaffinity failed!\n"); - // the sched_getaffinity should never fail for getting affinity of the current process - palError = ERROR_INTERNAL_ERROR; - goto EXIT; - } - - st = pthread_attr_setaffinity_np(&pthreadAttr, sizeof(cpu_set_t), &cpuSet); - if (st != 0) - { - if (st == ENOMEM) - { - palError = ERROR_NOT_ENOUGH_MEMORY; - } - else - { - ASSERT("pthread_attr_setaffinity_np failed!\n"); - // The pthread_attr_setaffinity_np should never fail except of OOM when - // passed the mask extracted using sched_getaffinity. - palError = ERROR_INTERNAL_ERROR; - } - goto EXIT; - } - } -#endif // HAVE_PTHREAD_GETAFFINITY_NP && HAVE_SCHED_GETAFFINITY - iError = pthread_create(&pthread, &pthreadAttr, CPalThread::ThreadEntry, pNewThread); #if PTHREAD_CREATE_MODIFIES_ERRNO @@ -1754,6 +1719,10 @@ CPalThread::ThreadEntry( PTHREAD_START_ROUTINE pfnStartRoutine; LPVOID pvPar; DWORD retValue; +#if HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY + cpu_set_t cpuSet; + int st; +#endif pThread = reinterpret_cast(pvParam); @@ -1763,6 +1732,42 @@ CPalThread::ThreadEntry( goto fail; } +#if HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY + // Threads inherit their parent's affinity mask on Linux. This is not desired, so we reset + // the current thread's affinity mask to the mask of the current process. + // + // Typically, we would use pthread_attr_setaffinity_np() and have pthread_create() create the thread with the specified + // affinity. At least one implementation of pthread_create() following a pthread_attr_setaffinity_np() calls + // sched_setaffinity(, ...), which is not allowed under Snap's default strict confinement without manually + // connecting the process-control plug. To work around that, have the thread set the affinity after it starts. + // sched_setaffinity(, ...) is also currently not allowed, only sched_setaffinity(0, ...). + // pthread_setaffinity_np(pthread_self(), ...) seems to call sched_setaffinity(, ...) in at least one + // implementation, and does not work. Use sched_setaffinity(0, ...) instead. See the following for more information: + // - https://github.com/dotnet/runtime/pull/38795 + // - https://github.com/dotnet/runtime/issues/1634 + // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13 + + CPU_ZERO(&cpuSet); + + st = sched_getaffinity(gPID, sizeof(cpu_set_t), &cpuSet); + if (st != 0) + { + ASSERT("sched_getaffinity failed!\n"); + // The sched_getaffinity should never fail for getting affinity of the current process + palError = ERROR_INTERNAL_ERROR; + goto fail; + } + + st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet); + if (st != 0) + { + ASSERT("sched_setaffinity failed!\n"); + // The sched_setaffinity should never fail when passed the mask extracted using sched_getaffinity + palError = ERROR_INTERNAL_ERROR; + goto fail; + } +#endif // HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY + #if !HAVE_MACH_EXCEPTIONS if (!pThread->EnsureSignalAlternateStack()) { @@ -2946,18 +2951,31 @@ BOOL PALAPI PAL_SetCurrentThreadAffinity(WORD procNo) { -#if HAVE_PTHREAD_GETAFFINITY_NP +#if HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP cpu_set_t cpuSet; CPU_ZERO(&cpuSet); - CPU_SET(procNo, &cpuSet); + + // Snap's default strict confinement does not allow sched_setaffinity(, ...) without manually connecting the + // process-control plug. sched_setaffinity(, ...) is also currently not allowed, only + // sched_setaffinity(0, ...). pthread_setaffinity_np(pthread_self(), ...) seems to call + // sched_setaffinity(, ...) in at least one implementation, and does not work. To work around those + // issues, use sched_setaffinity(0, ...) if available and only otherwise fall back to pthread_setaffinity_np(). See the + // following for more information: + // - https://github.com/dotnet/runtime/pull/38795 + // - https://github.com/dotnet/runtime/issues/1634 + // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13 +#if HAVE_SCHED_SETAFFINITY + int st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet); +#else int st = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet); +#endif return st == 0; -#else // HAVE_PTHREAD_GETAFFINITY_NP +#else // !(HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP) // There is no API to manage thread affinity, so let's ignore the request return FALSE; -#endif // HAVE_PTHREAD_GETAFFINITY_NP +#endif // HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP } /*++ From 8953bab5c03c717296dfb57107330b0aff87e16e Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Mon, 3 Aug 2020 21:44:37 -0700 Subject: [PATCH 227/755] improve exception message when HTTP2 connection establishment fails (#40251) Co-authored-by: Geoffrey Kizer --- .../src/Resources/Strings.resx | 3 + .../SocketsHttpHandler/Http2Connection.cs | 59 ++++++++++++------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/libraries/System.Net.Http/src/Resources/Strings.resx b/src/libraries/System.Net.Http/src/Resources/Strings.resx index 8848ecf67948..0ac22a4bf44c 100644 --- a/src/libraries/System.Net.Http/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http/src/Resources/Strings.resx @@ -435,6 +435,9 @@ The HTTP/2 server reset the stream. HTTP/2 error code '{0}' (0x{1}). + + An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake. + This method is not implemented by this class. 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 c9ad97f65dbc..bb59149fb6e9 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 @@ -191,7 +191,17 @@ private async ValueTask ReadFrameAsync(bool initialFrame = false) { int bytesRead = await _stream.ReadAsync(_incomingBuffer.AvailableMemory).ConfigureAwait(false); _incomingBuffer.Commit(bytesRead); - if (bytesRead == 0) ThrowPrematureEOF(FrameHeader.Size); + if (bytesRead == 0) + { + if (_incomingBuffer.ActiveLength == 0) + { + ThrowMissingFrame(); + } + else + { + ThrowPrematureEOF(FrameHeader.Size); + } + } } while (_incomingBuffer.ActiveLength < FrameHeader.Size); } @@ -229,33 +239,44 @@ private async ValueTask ReadFrameAsync(bool initialFrame = false) void ThrowPrematureEOF(int requiredBytes) => throw new IOException(SR.Format(SR.net_http_invalid_response_premature_eof_bytecount, requiredBytes - _incomingBuffer.ActiveLength)); + + void ThrowMissingFrame() => + throw new IOException(SR.net_http_invalid_response_missing_frame); + } private async Task ProcessIncomingFramesAsync() { try { - // Read the initial settings frame. - FrameHeader frameHeader = await ReadFrameAsync(initialFrame: true).ConfigureAwait(false); - if (frameHeader.Type != FrameType.Settings || frameHeader.AckFlag) + FrameHeader frameHeader; + try { - ThrowProtocolError(); - } - if (NetEventSource.Log.IsEnabled()) Trace($"Frame 0: {frameHeader}."); + // Read the initial settings frame. + frameHeader = await ReadFrameAsync(initialFrame: true).ConfigureAwait(false); + if (frameHeader.Type != FrameType.Settings || frameHeader.AckFlag) + { + ThrowProtocolError(); + } - // Process the initial SETTINGS frame. This will send an ACK. - ProcessSettingsFrame(frameHeader); + if (NetEventSource.Log.IsEnabled()) Trace($"Frame 0: {frameHeader}."); + + // Process the initial SETTINGS frame. This will send an ACK. + ProcessSettingsFrame(frameHeader); + } + catch (IOException e) + { + throw new IOException(SR.net_http_http2_connection_not_established, e); + } // Keep processing frames as they arrive. for (long frameNum = 1; ; frameNum++) { - // We could just call ReadFrameAsync here, but we add this code before it for two reasons: - // 1. To provide a better error message when we're unable to read another frame. We otherwise - // generally output an error message that's relatively obscure. - // 2. To avoid another state machine allocation in the relatively common case where we - // currently don't have enough data buffered and issuing a read for the frame header - // completes asynchronously, but that read ends up also reading enough data to fulfill - // the entire frame's needs (not just the header). + // We could just call ReadFrameAsync here, but we add this code + // to avoid another state machine allocation in the relatively common case where we + // currently don't have enough data buffered and issuing a read for the frame header + // completes asynchronously, but that read ends up also reading enough data to fulfill + // the entire frame's needs (not just the header). if (_incomingBuffer.ActiveLength < FrameHeader.Size) { _incomingBuffer.EnsureAvailableSpace(FrameHeader.Size - _incomingBuffer.ActiveLength); @@ -266,10 +287,8 @@ private async Task ProcessIncomingFramesAsync() _incomingBuffer.Commit(bytesRead); if (bytesRead == 0) { - string message = _incomingBuffer.ActiveLength == 0 ? - SR.net_http_invalid_response_missing_frame : - SR.Format(SR.net_http_invalid_response_premature_eof_bytecount, FrameHeader.Size - _incomingBuffer.ActiveLength); - throw new IOException(message); + // ReadFrameAsync below will detect that the frame is incomplete and throw the appropriate error. + break; } } while (_incomingBuffer.ActiveLength < FrameHeader.Size); From 4c0ebbdd344304e36773c01eb61b9a486b198a3c Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Tue, 4 Aug 2020 11:01:22 +0300 Subject: [PATCH 228/755] [wasm] Modify System.Net.Request to throw PNSE on Browser WASM (#40274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [wasm] Modify System.Net.Request to throw PNSE on Browser WASM * [wasm] Re-enable System.ComponentModel.EventBasedAsync.Tests.BackgroundWorkerTests.TestFinalization test * Make the CS0809 build warning depend on if PNSE assembly is going to be generated * Update src/libraries/System.Net.Requests/src/System.Net.Requests.csproj Co-authored-by: Alexander Köplinger * Remove redundant condition Co-authored-by: Alexander Köplinger --- .../tests/BackgroundWorkerTests.cs | 1 - .../System.Net.Requests/src/Resources/Strings.resx | 3 +++ .../System.Net.Requests/src/System.Net.Requests.csproj | 8 ++++++-- src/libraries/System.Net.Requests/tests/AssemblyInfo.cs | 2 +- .../tests/System.Net.Requests.Tests.csproj | 1 + 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/tests/BackgroundWorkerTests.cs b/src/libraries/System.ComponentModel.EventBasedAsync/tests/BackgroundWorkerTests.cs index 8ba0dcb842cd..7bdfb4d6a34d 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/tests/BackgroundWorkerTests.cs +++ b/src/libraries/System.ComponentModel.EventBasedAsync/tests/BackgroundWorkerTests.cs @@ -327,7 +327,6 @@ public void DisposeTwiceShouldNotThrow() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38283", TestPlatforms.Browser)] public void TestFinalization() { // BackgroundWorker has a finalizer that exists purely for backwards compatibility diff --git a/src/libraries/System.Net.Requests/src/Resources/Strings.resx b/src/libraries/System.Net.Requests/src/Resources/Strings.resx index cb28aec1a43a..5240ec2908ee 100644 --- a/src/libraries/System.Net.Requests/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Requests/src/Resources/Strings.resx @@ -267,4 +267,7 @@ The specified value is not a valid Host header string. + + System.Net.Requests is not supported on this platform. + diff --git a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj index 96471eef5eb5..b21e3f413267 100644 --- a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj +++ b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj @@ -4,7 +4,11 @@ $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser enable - + + SR.SystemNetRequests_PlatformNotSupported + $(NoWarn);CS0809 + + @@ -77,7 +81,7 @@ Link="Common\System\Net\ContextAwareResult.Windows.cs" /> - + diff --git a/src/libraries/System.Net.Requests/tests/AssemblyInfo.cs b/src/libraries/System.Net.Requests/tests/AssemblyInfo.cs index 527dabb9c3cd..67d13a0af274 100644 --- a/src/libraries/System.Net.Requests/tests/AssemblyInfo.cs +++ b/src/libraries/System.Net.Requests/tests/AssemblyInfo.cs @@ -4,4 +4,4 @@ using Xunit; [assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/34690", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] -[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/38283", TestPlatforms.Browser)] +[assembly: SkipOnMono("System.Net.Requests is not supported on Browser.", TestPlatforms.Browser)] diff --git a/src/libraries/System.Net.Requests/tests/System.Net.Requests.Tests.csproj b/src/libraries/System.Net.Requests/tests/System.Net.Requests.Tests.csproj index e0c47d0262bd..ecb8a780af90 100644 --- a/src/libraries/System.Net.Requests/tests/System.Net.Requests.Tests.csproj +++ b/src/libraries/System.Net.Requests/tests/System.Net.Requests.Tests.csproj @@ -4,6 +4,7 @@ true $(NetCoreAppCurrent) $(DefineConstants);NETSTANDARD + true From 41de6d4994467fffdbf3bf0e5a3a1ff1f56144ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 4 Aug 2020 11:39:15 +0200 Subject: [PATCH 229/755] WASM: Pump timer queue in xharness when running unit tests (#40278) * WASM: Pump timer queue in xharness when running unit tests We only pumped the threadpool but we didn't pump the timer queue inside the xharness runner, so in the case of Task.Delay() it'll schedule a callback on the timer queue and that will never happen which leads to the infinite loop waiting for the test to finish. To fix that we call an internal method to pump the timer queue like we do for the threadpool. Requires an xharness bump to include https://github.com/dotnet/xharness/pull/290 Fixes https://github.com/dotnet/runtime/issues/38931 * Don't nullref if no timers were started --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 8 +++---- eng/Versions.props | 4 ++-- .../tests/AsyncValueTaskMethodBuilderTests.cs | 3 --- .../tests/ManualResetValueTaskSourceTests.cs | 4 ---- .../tests/ValueTaskTests.cs | 13 ----------- .../Threading/TimerQueue.Browser.Mono.cs | 22 ++++++++++++------- 7 files changed, 21 insertions(+), 35 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 519943094947..d6009aca5b52 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.20352.2", + "version": "1.0.0-prerelease.20403.2", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 62948380391f..ef6271c1e2eb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -186,13 +186,13 @@ https://github.com/mono/linker 7c9b806037e88df7eb40a8151808730133676668 - + https://github.com/dotnet/xharness - 2cb87a26217ee107e7d764770c44d986b4333c10 + abc6d581ce00214ef763fb8510d1ba0aa54e7717 - + https://github.com/dotnet/xharness - 2cb87a26217ee107e7d764770c44d986b4333c10 + abc6d581ce00214ef763fb8510d1ba0aa54e7717 diff --git a/eng/Versions.props b/eng/Versions.props index dac2f73712b3..6a05c5233477 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -131,8 +131,8 @@ 4.9.4 16.8.0-preview-20200730-03 - 1.0.0-prerelease.20402.1 - 1.0.0-prerelease.20402.1 + 1.0.0-prerelease.20403.2 + 1.0.0-prerelease.20403.2 2.4.1 2.4.2 1.3.0 diff --git a/src/libraries/System.Threading.Tasks.Extensions/tests/AsyncValueTaskMethodBuilderTests.cs b/src/libraries/System.Threading.Tasks.Extensions/tests/AsyncValueTaskMethodBuilderTests.cs index eb1def0b9cd2..d929d30d22d6 100644 --- a/src/libraries/System.Threading.Tasks.Extensions/tests/AsyncValueTaskMethodBuilderTests.cs +++ b/src/libraries/System.Threading.Tasks.Extensions/tests/AsyncValueTaskMethodBuilderTests.cs @@ -399,7 +399,6 @@ async ValueTask ValueTaskReturningAsyncMethod(int result) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public static async Task AwaitTasksAndValueTasks_InTaskAndValueTaskMethods() { for (int i = 0; i < 2; i++) @@ -522,7 +521,6 @@ async ValueTask ValueTaskInt32ReturningMethod() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_ConcurrentBuilders_WorkCorrectly() { await Task.WhenAll(Enumerable.Range(0, Environment.ProcessorCount).Select(async _ => @@ -540,7 +538,6 @@ static async ValueTask ValueTaskAsync() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_ConcurrentBuilders_WorkCorrectly() { await Task.WhenAll(Enumerable.Range(0, Environment.ProcessorCount).Select(async _ => diff --git a/src/libraries/System.Threading.Tasks.Extensions/tests/ManualResetValueTaskSourceTests.cs b/src/libraries/System.Threading.Tasks.Extensions/tests/ManualResetValueTaskSourceTests.cs index 4f3e9366b5ff..b43ca1f952db 100644 --- a/src/libraries/System.Threading.Tasks.Extensions/tests/ManualResetValueTaskSourceTests.cs +++ b/src/libraries/System.Threading.Tasks.Extensions/tests/ManualResetValueTaskSourceTests.cs @@ -11,7 +11,6 @@ namespace System.Threading.Tasks.Sources.Tests public class ManualResetValueTaskSourceTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task ReuseInstanceWithResets_Success() { var mrvts = new ManualResetValueTaskSource(); @@ -84,7 +83,6 @@ public async Task SetResult_BeforeOnCompleted_ResultAvailableSynchronously() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task SetResult_AfterOnCompleted_ResultAvailableAsynchronously() { var mrvts = new ManualResetValueTaskSource(); @@ -133,7 +131,6 @@ public async Task SetException_BeforeOnCompleted_ResultAvailableSynchronously() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task SetException_AfterOnCompleted_ResultAvailableAsynchronously() { var mrvts = new ManualResetValueTaskSource(); @@ -415,7 +412,6 @@ protected override void QueueTask(Task task) [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task AsyncEnumerable_Success(bool awaitForeach, bool asyncIterator) { IAsyncEnumerable enumerable = asyncIterator ? diff --git a/src/libraries/System.Threading.Tasks.Extensions/tests/ValueTaskTests.cs b/src/libraries/System.Threading.Tasks.Extensions/tests/ValueTaskTests.cs index 41325575f978..9d4d485b2c61 100644 --- a/src/libraries/System.Threading.Tasks.Extensions/tests/ValueTaskTests.cs +++ b/src/libraries/System.Threading.Tasks.Extensions/tests/ValueTaskTests.cs @@ -371,7 +371,6 @@ public void Generic_CreateFromValueTaskSource_AsTaskNotIdempotent() // validates [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_CreateFromValueTaskSource_Success(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0) : ManualResetValueTaskSourceFactory.Delay(1, 0), 0); @@ -386,7 +385,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Success(bool sync) [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_CreateFromValueTaskSource_Success(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(42) : ManualResetValueTaskSourceFactory.Delay(1, 42), 0); @@ -401,7 +399,6 @@ public async Task Generic_CreateFromValueTaskSource_Success(bool sync) [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_CreateFromValueTaskSource_Faulted(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new FormatException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new FormatException()), 0); @@ -420,7 +417,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Faulted(bool sync) [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_CreateFromValueTaskSource_Faulted(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new FormatException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new FormatException()), 0); @@ -439,7 +435,6 @@ public async Task Generic_CreateFromValueTaskSource_Faulted(bool sync) [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_CreateFromValueTaskSource_Canceled(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new OperationCanceledException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new OperationCanceledException()), 0); @@ -458,7 +453,6 @@ public async Task NonGeneric_CreateFromValueTaskSource_Canceled(bool sync) [Theory] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_CreateFromValueTaskSource_Canceled(bool sync) { var vt = new ValueTask(sync ? ManualResetValueTaskSourceFactory.Completed(0, new OperationCanceledException()) : ManualResetValueTaskSourceFactory.Delay(1, 0, new OperationCanceledException()), 0); @@ -578,7 +572,6 @@ ValueTask Create() => [InlineData(null)] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_CreateFromTask_Await_Normal(bool? continueOnCapturedContext) { var t = new ValueTask(Task.Delay(1)); @@ -593,7 +586,6 @@ public async Task NonGeneric_CreateFromTask_Await_Normal(bool? continueOnCapture [InlineData(null)] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_CreateFromTask_Await_Normal(bool? continueOnCapturedContext) { var t = new ValueTask(Task.Delay(1).ContinueWith(_ => 42)); @@ -608,7 +600,6 @@ public async Task Generic_CreateFromTask_Await_Normal(bool? continueOnCapturedCo [InlineData(null)] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task CreateFromValueTaskSource_Await_Normal(bool? continueOnCapturedContext) { var mre = new ManualResetValueTaskSource(); @@ -625,7 +616,6 @@ public async Task CreateFromValueTaskSource_Await_Normal(bool? continueOnCapture [InlineData(null)] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_CreateFromValueTaskSource_Await_Normal(bool? continueOnCapturedContext) { var mre = new ManualResetValueTaskSource(); @@ -815,7 +805,6 @@ await Task.Run(async () => [InlineData(CtorMode.Result, true)] [InlineData(CtorMode.Task, true)] [InlineData(CtorMode.ValueTaskSource, true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_Awaiter_ContinuesOnCapturedContext(CtorMode mode, bool sync) { await Task.Run(async () => @@ -854,7 +843,6 @@ await Task.Run(async () => [InlineData(CtorMode.Result, false, true)] [InlineData(CtorMode.Task, false, true)] [InlineData(CtorMode.ValueTaskSource, false, true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task NonGeneric_ConfiguredAwaiter_ContinuesOnCapturedContext(CtorMode mode, bool continueOnCapturedContext, bool sync) { await Task.Run(async () => @@ -893,7 +881,6 @@ await Task.Run(async () => [InlineData(CtorMode.Result, false, true)] [InlineData(CtorMode.Task, false, true)] [InlineData(CtorMode.ValueTaskSource, false, true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/38931", TestPlatforms.Browser)] public async Task Generic_ConfiguredAwaiter_ContinuesOnCapturedContext(CtorMode mode, bool continueOnCapturedContext, bool sync) { await Task.Run(async () => diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs index 776935b3de7e..475f0c8af1ed 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs @@ -33,7 +33,12 @@ private TimerQueue(int id) // Called by mini-wasm.c:mono_set_timeout_exec private static void TimeoutCallback() { - Run(); + int shortestWaitDurationMs = PumpTimerQueue(); + + if (shortestWaitDurationMs != int.MaxValue) + { + SetTimeout((int)shortestWaitDurationMs, 0); + } } private bool SetTimer(uint actualDuration) @@ -53,14 +58,18 @@ private bool SetTimer(uint actualDuration) return true; } - private static void Run() + private static int PumpTimerQueue() // NOTE: this method is called via reflection by test code { - int shortestWaitDurationMs; + if (s_scheduledTimersToFire == null) + { + return int.MaxValue; + } + List timersToFire = s_scheduledTimersToFire!; List timers; timers = s_scheduledTimers!; long currentTimeMs = TickCount64; - shortestWaitDurationMs = int.MaxValue; + int shortestWaitDurationMs = int.MaxValue; for (int i = timers.Count - 1; i >= 0; --i) { TimerQueue timer = timers[i]; @@ -94,10 +103,7 @@ private static void Run() timersToFire.Clear(); } - if (shortestWaitDurationMs != int.MaxValue) - { - SetTimeout((int)shortestWaitDurationMs, 0); - } + return shortestWaitDurationMs; } } } From 0bd3ae0b247ccd20b1516b04d56d7c23b53bd408 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Tue, 4 Aug 2020 05:44:58 -0400 Subject: [PATCH 230/755] [Wasm] Enable System.Data.Common tests (#39463) Disable the tests that require SQL Server. Co-authored-by: Steve Pfister Co-authored-by: Maxim Lipnin --- .../Data/Common/DbProviderFactoriesTests.cs | 1 + .../Data/Common/DbProviderFactoryTest.cs | 1 + .../tests/System/Data/DataRowTest2.cs | 2 +- .../System/Data/DataSetInferXmlSchemaTest.cs | 14 ++-- .../System/Data/DataSetReadXmlSchemaTest.cs | 40 +++++------ .../tests/System/Data/DataSetReadXmlTest.cs | 12 ++-- .../tests/System/Data/DataSetTest.cs | 14 ++-- .../tests/System/Data/DataSetTest2.cs | 42 +++++------ .../System/Data/DataSetTypedDataSetTest.cs | 2 +- .../System/Data/DataTableExtensionsTest.cs | 1 + .../System/Data/DataTableReadXmlSchemaTest.cs | 16 ++--- .../tests/System/Data/DataTableTest.cs | 8 +-- .../tests/System/Data/DataTableTest4.cs | 4 +- .../tests/System/Data/FacadeTest.cs | 1 + .../Data/SqlTypes/SqlStringSortingTest.cs | 2 +- .../System/Data/SqlTypes/SqlStringTest.cs | 69 ++++++++++--------- src/libraries/tests.proj | 3 - 17 files changed, 118 insertions(+), 114 deletions(-) diff --git a/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoriesTests.cs b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoriesTests.cs index 8862a85e5c37..2537fb30e95d 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoriesTests.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoriesTests.cs @@ -15,6 +15,7 @@ public sealed class TestProviderFactory : DbProviderFactory private TestProviderFactory() { } } + [PlatformSpecific(~TestPlatforms.Browser)] public class DbProviderFactoriesTests { [Fact] diff --git a/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.cs b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.cs index 9393016bc51f..b810686ab4f7 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.cs @@ -6,6 +6,7 @@ namespace System.Data.Tests.Common { + [PlatformSpecific(~TestPlatforms.Browser)] public class DbProviderFactoryTest { [Fact] diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataRowTest2.cs b/src/libraries/System.Data.Common/tests/System/Data/DataRowTest2.cs index 7369c8588669..bfb22d111550 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataRowTest2.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataRowTest2.cs @@ -1894,7 +1894,7 @@ public void IsNull_ByIndex() Assert.True(dr.IsNull(1)); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void IsNull_ByName() { DataTable dt = new DataTable(); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetInferXmlSchemaTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetInferXmlSchemaTest.cs index b953a5d3616c..5bf2ef00533a 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetInferXmlSchemaTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetInferXmlSchemaTest.cs @@ -246,7 +246,7 @@ public void SimpleElementTable() DataSetAssertion.AssertDataColumn("col3", dt.Columns[2], "col3", true, false, 0, 1, "col3", MappingType.Element, typeof(string), DBNull.Value, string.Empty, -1, string.Empty, 2, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void SimpleDataSet() { DataSet ds = GetDataSet(_xml8, null); @@ -337,7 +337,7 @@ public void SignificantWhitespaceIgnored2() DataSetAssertion.AssertDataSet("pure_whitespace", ds, "root", 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TwoElementTable() { // FIXME: Also test ReadXml (, XmlReadMode.InferSchema) and @@ -356,7 +356,7 @@ public void TwoElementTable() DataSetAssertion.AssertDataColumn("col2_2", dt.Columns[1], "col2_2", true, false, 0, 1, "col2_2", MappingType.Element, typeof(string), DBNull.Value, string.Empty, -1, string.Empty, 1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ConflictSimpleComplexColumns() { DataSet ds = GetDataSet(_xml18, null); @@ -377,7 +377,7 @@ public void ConflictSimpleComplexColumns() DataSetAssertion.AssertForeignKeyConstraint("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string[] { "table_Id" }, new string[] { "table_Id" }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ConflictColumnTable() { DataSet ds = GetDataSet(_xml19, null); @@ -398,7 +398,7 @@ public void ConflictColumnTable() DataSetAssertion.AssertForeignKeyConstraint("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string[] { "table_Id" }, new string[] { "table_Id" }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ConflictColumnTableAttribute() { // Conflicts between a column and a table, additionally an attribute. @@ -421,7 +421,7 @@ public void ConflictColumnTableAttribute() DataSetAssertion.AssertForeignKeyConstraint("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string[] { "table_Id" }, new string[] { "table_Id" }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ConflictAttributeDataTable() { Assert.Throws(() => @@ -433,7 +433,7 @@ public void ConflictAttributeDataTable() }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ConflictExistingPrimaryKey() { Assert.Throws(() => diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlSchemaTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlSchemaTest.cs index 4c1bfa8ca081..de1c0685bb05 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlSchemaTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlSchemaTest.cs @@ -52,7 +52,7 @@ private DataSet CreateTestSet() return ds; } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void SingleElementTreatmentDifference() { // This is one of the most complicated case. When the content @@ -149,7 +149,7 @@ public void SingleElementTreatmentDifference() DataSetAssertion.AssertDataTable("complex", ds.Tables[0], "Root", 1, 0, 0, 0, 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void SuspiciousDataSetElement() { string schema = @" @@ -174,7 +174,7 @@ public void SuspiciousDataSetElement() DataSetAssertion.AssertDataTable("table", ds.Tables[0], "elem", 2, 0, 0, 0, 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void UnusedComplexTypesIgnored() { string xs = @" @@ -213,7 +213,7 @@ public void SimpleTypeComponentsIgnored() DataSetAssertion.AssertDataSet("ds", ds, "NewDataSet", 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void IsDataSetAndTypeIgnored() { string xsbase = @" @@ -243,7 +243,7 @@ public void IsDataSetAndTypeIgnored() DataSetAssertion.AssertDataSet("ds", ds, "NewDataSet", 1, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void NestedReferenceNotAllowed() { string xs = @" @@ -272,7 +272,7 @@ public void NestedReferenceNotAllowed() }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void IsDataSetOnLocalElementIgnored() { string xsbase = @" @@ -294,7 +294,7 @@ public void IsDataSetOnLocalElementIgnored() DataSetAssertion.AssertDataSet("ds", ds, "NewDataSet", 1, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void LocaleOnRootWithoutIsDataSet() { using (new ThreadCultureChange("fi-FI")) @@ -323,7 +323,7 @@ public void LocaleOnRootWithoutIsDataSet() } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ElementHasIdentityConstraint() { string constraints = @" @@ -381,7 +381,7 @@ public void ElementHasIdentityConstraint() Assert.Equal(0, ds.Relations.Count); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void PrefixedTargetNS() { string xs = @" @@ -477,7 +477,7 @@ private void ReadTest1Check(DataSet ds) new string[] { "Column1_3" }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] // 001-004 public void TestSampleFileNoTables() { @@ -510,7 +510,7 @@ public void TestSampleFileNoTables() DataSetAssertion.AssertDataSet("004", ds, "NewDataSet", 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileSimpleTables() { var ds = new DataSet(); @@ -547,7 +547,7 @@ public void TestSampleFileSimpleTables() DataSetAssertion.AssertDataColumn("att2", dt.Columns["att2"], "att2", true, false, 0, 1, "att2", MappingType.Attribute, typeof(int), 2, string.Empty, -1, string.Empty, /*1*/-1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileComplexTables() { // Nested simple type element @@ -608,7 +608,7 @@ public void TestSampleFileComplexTables() DataSetAssertion.AssertDataColumn("id", dt.Columns[1], "uno_Id", true, false, 0, 1, "uno_Id", MappingType.Hidden, typeof(int), DBNull.Value, string.Empty, -1, string.Empty, 1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileComplexTables3() { var ds = new DataSet(); @@ -639,7 +639,7 @@ public void TestSampleFileComplexTables3() DataSetAssertion.AssertDataColumn("simple", dt.Columns[1], "e_text", false, false, 0, 1, "e_text", MappingType.SimpleContent, typeof(decimal), DBNull.Value, string.Empty, -1, string.Empty, 1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileXPath() { var ds = new DataSet(); @@ -681,7 +681,7 @@ public void TestSampleFileXPath() ")); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestAnnotatedRelation1() { var ds = new DataSet(); @@ -732,7 +732,7 @@ public void TestAnnotatedRelation1() DataSetAssertion.AssertDataRelation("rel", ds.Relations[0], "rel", false, new string[] { "pk" }, new string[] { "fk" }, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestAnnotatedRelation2() { var ds = new DataSet(); @@ -783,7 +783,7 @@ public void TestAnnotatedRelation2() DataSetAssertion.AssertDataRelation("rel", ds.Relations[0], "rel", true, new string[] { "pk" }, new string[] { "fk" }, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void RepeatableSimpleElement() { var ds = new DataSet(); @@ -811,7 +811,7 @@ public void RepeatableSimpleElement() DataSetAssertion.AssertDataRelation("rel", ds.Relations[0], "Foo_Bar", true, new string[] { "Foo_Id" }, new string[] { "Foo_Id" }, true, true); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestMoreThanOneRepeatableColumns() { var ds = new DataSet(); @@ -861,7 +861,7 @@ public void AutoIncrementStep() Assert.True(ds.GetXmlSchema().IndexOf("AutoIncrementStep") > 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadConstraints() { var ds = new DataSet(); @@ -904,7 +904,7 @@ public void ReadConstraints() Assert.Equal("fk1", ds.Tables[1].Constraints[0].ConstraintName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadAnnotatedRelations_MultipleColumns() { var ds = new DataSet(); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlTest.cs index 0bf6fd549143..fa45aa582875 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetReadXmlTest.cs @@ -65,7 +65,7 @@ public class DataSetReadXmlTest "; private const string schema2 = schema1 + xml8; - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadSimpleAuto() { DataSet ds; @@ -285,7 +285,7 @@ public void ReadSimpleIgnoreSchema() "NewDataSet", 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadSimpleInferSchema() { DataSet ds; @@ -606,7 +606,7 @@ public void SequentialRead2() DataSetAssertion.AssertDataTable("#3", ds.Tables[0], "root", 1, 2, 0, 0, 0, 0); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadComplexElementDocument() { var ds = new DataSet(); @@ -639,7 +639,7 @@ public void IgnoreSchemaShouldFillData() Assert.Equal(0, dt.Rows.Count); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void NameConflictDSAndTable() { string xml = @" @@ -657,7 +657,7 @@ public void NameConflictDSAndTable() Assert.NotNull(ds.Tables["PriceListDetails"]); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ColumnOrder() { string xml = "" + @@ -690,7 +690,7 @@ public void ColumnOrder() Assert.Equal(3, ds.Tables[0].Columns[3].Ordinal); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void XmlSpace() { string xml = "" + diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs index bd35d061c0dd..4c2e8b38b4e5 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs @@ -367,7 +367,7 @@ public void OwnWriteXmlSchema() Assert.Equal("", TextString); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadWriteXml() { var ds = new DataSet(); @@ -424,7 +424,7 @@ public void ReadWriteXml() Assert.Equal("", TextString); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadWriteXmlDiffGram() { var ds = new DataSet(); @@ -507,7 +507,7 @@ public void ReadWriteXmlDiffGram() Assert.Equal("", TextString); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void WriteXmlSchema() { using (new ThreadCultureChange("fi-FI")) @@ -989,7 +989,7 @@ public void WriteNestedTableXml() Assert.Equal(sw.ToString().Replace("\r\n", "\n"), xml.Replace("\r\n", "\n")); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void WriteXmlToStream() { string xml = "sample textsample text 2"; @@ -1028,7 +1028,7 @@ public void WtiteXmlEncodedXml() Assert.Equal(sw.ToString().Replace("\r\n", "\n"), xml.Replace("\r\n", "\n")); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadWriteXml2() { string xml = ""; @@ -1046,7 +1046,7 @@ public void ReadWriteXml2() Assert.Equal(xml, sw.ToString()); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadWriteXml3() { string input = @" @@ -1559,7 +1559,7 @@ public void WriteXmlModeSchema() Assert.Equal(result.Replace("\r\n", "\n"), xml.Replace("\r\n", "\n")); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void WriteXmlModeSchema1() { // Keeping the brackets as the test otherwise starts to fail. diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest2.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest2.cs index aec8467dbc60..d5943b3da388 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest2.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest2.cs @@ -540,7 +540,7 @@ public void HasErrors() #region test namespaces - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_BasicXml() { StringBuilder sb = new StringBuilder(); @@ -572,7 +572,7 @@ public void InferXmlSchema_BasicXml() Assert.Equal("Discontinued", ds.Tables[1].Columns[2].ColumnName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_WithoutIgnoreNameSpaces() { StringBuilder sb = new StringBuilder(); @@ -597,7 +597,7 @@ public void InferXmlSchema_WithoutIgnoreNameSpaces() Assert.Equal(8, ds.Tables.Count); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_IgnoreNameSpace() { StringBuilder sb = new StringBuilder(); @@ -637,7 +637,7 @@ public void InferXmlSchema_IgnoreNameSpace() Assert.Equal("Discontinued", ds.Tables[2].Columns["Discontinued"].ColumnName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_IgnoreNameSpaces() //Ignoring 2 namespaces { StringBuilder sb = new StringBuilder(); @@ -667,7 +667,7 @@ public void InferXmlSchema_IgnoreNameSpaces() //Ignoring 2 namespaces #endregion #region inferringTables - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringTables1() { //According to the msdn documantaion : @@ -691,7 +691,7 @@ public void InferXmlSchema_inferringTables1() Assert.Equal("Element1_Text", ds.Tables[0].Columns["Element1_Text"].ColumnName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringTables2() { //According to the msdn documantaion : @@ -741,7 +741,7 @@ public void InferXmlSchema_inferringTables3() Assert.Equal("Element2", ds.Tables[0].Columns["Element2"].ColumnName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringTables4() { //According to the msdn documantaion : @@ -766,7 +766,7 @@ public void InferXmlSchema_inferringTables4() Assert.Equal("attr2", ds.Tables[0].Columns["attr2"].ColumnName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringTables5() { //According to the msdn documantaion : @@ -791,7 +791,7 @@ public void InferXmlSchema_inferringTables5() #endregion #region inferringColumns - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringColumns1() { //ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconinferringcolumns.htm @@ -815,7 +815,7 @@ public void InferXmlSchema_inferringColumns1() Assert.Equal(typeof(string), ds.Tables[0].Columns["attr2"].DataType); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringColumns2() { //ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconinferringcolumns.htm @@ -850,7 +850,7 @@ public void InferXmlSchema_inferringColumns2() #region Inferring Relationships - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_inferringRelationships1() { //ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconinferringrelationships.htm @@ -914,7 +914,7 @@ public void InferXmlSchema_inferringRelationships1() #region Inferring Element Text - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_elementText1() { //ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconinferringelementtext.htm @@ -942,7 +942,7 @@ public void InferXmlSchema_elementText1() Assert.Equal(typeof(string), ds.Tables["Element1"].Columns["Element1_Text"].DataType); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void InferXmlSchema_elementText2() { //ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconinferringelementtext.htm @@ -988,7 +988,7 @@ public void Locale() Assert.Equal(culInfo, ds.Locale); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void DataSetSpecificCulture() { using (new ThreadCultureChange("cs-CZ")) @@ -2235,7 +2235,7 @@ public void ReadXml_Strm2() // Tables[2] ParentRelations[0] name Assert.Equal("Stock_Price", ds.Tables[2].ParentRelations[0].RelationName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXml_Strm3() { DataSet ds = new DataSet("TestDataSet"); @@ -2264,7 +2264,7 @@ public void ReadXml_Strm3() Assert.Equal(MappingType.Hidden, ds.Tables["Price"].Columns["Stock_Id"].ColumnMapping); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXml_Strm4() { _ds = new DataSet("Stocks"); @@ -2365,7 +2365,7 @@ private void privateTestCase(string name, string toTable, string toTestSelect, s Assert.Equal(_ds.Tables[toTable].Select(toTestSelect)[0]["Stock_Id"], _ds.Tables[toCompareTable].Select(toCompareSelect)[0]["Stock_Id"]); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXml_Strm5() { string xmlData; @@ -2589,7 +2589,7 @@ private string dataSetDescription(DataSet ds) return desc; } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXml_Strm6() { // TC1 @@ -2608,7 +2608,7 @@ public void ReadXml_Strm6() Assert.Equal(3, ds.Tables["c"].Rows.Count); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXmlSchema_2() { var ds = new DataSet(); @@ -3070,7 +3070,7 @@ private void CheckNode(string description, string xPath, int expectedNodesCout, Assert.Equal(expectedNodesCout, actualNodeCount); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void WriteXml_Stream() { { @@ -3515,7 +3515,7 @@ private void AssertDataTableValues(DataTable dt) Assert.Equal("data8", dt.Rows[0]["&ID"]); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void Bug537229_BinFormatSerializer_Test() { DataSet ds = new DataSet(); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetTypedDataSetTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetTypedDataSetTest.cs index cc5d61cdac4a..856b779e8c11 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetTypedDataSetTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetTypedDataSetTest.cs @@ -40,7 +40,7 @@ public class DataSetTypedDataSetTest { private string _eventStatus = string.Empty; - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TypedDataSet() { int i = 0; diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableExtensionsTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableExtensionsTest.cs index e3f53fe429ab..8608ba7bd645 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableExtensionsTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableExtensionsTest.cs @@ -5,6 +5,7 @@ namespace System.Data.Tests { + [PlatformSpecific(~TestPlatforms.Browser)] public class DataTableExtensionsTest { private DataTable _dt; diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableReadXmlSchemaTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableReadXmlSchemaTest.cs index 59191f5226fe..17bb95df00d1 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableReadXmlSchemaTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableReadXmlSchemaTest.cs @@ -53,7 +53,7 @@ private DataSet CreateTestSet() return ds; } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void SuspiciousDataSetElement() { string schema = @" @@ -108,7 +108,7 @@ public void UnusedComplexTypesIgnored() }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void IsDataSetAndTypeIgnored() { string xsbase = @" @@ -140,7 +140,7 @@ public void IsDataSetAndTypeIgnored() }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void NestedReferenceNotAllowed() { string xs = @" @@ -194,7 +194,7 @@ public void LocaleOnRootWithoutIsDataSet() DataSetAssertion.AssertDataColumn("col2", dt.Columns[1], "Child", false, false, 0, 1, "Child", MappingType.Element, typeof(string), DBNull.Value, string.Empty, -1, string.Empty, 1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void PrefixedTargetNS() { string xs = @" @@ -308,7 +308,7 @@ public void TestSampleFileSimpleTables() DataSetAssertion.AssertDataColumn("att2", dt.Columns["att2"], "att2", true, false, 0, 1, "att2", MappingType.Attribute, typeof(int), 2, string.Empty, -1, string.Empty, /*1*/-1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileComplexTables3() { var ds = new DataSet(); @@ -338,7 +338,7 @@ public void TestSampleFileComplexTables3() DataSetAssertion.AssertDataColumn("simple", dt.Columns[1], "e_text", false, false, 0, 1, "e_text", MappingType.SimpleContent, typeof(decimal), DBNull.Value, string.Empty, -1, string.Empty, 1, string.Empty, false, false); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void TestSampleFileXPath() { var ds = new DataSet(); @@ -428,7 +428,7 @@ public void ReadConstraints() Assert.Equal("Constraint1", ds.Tables[0].Constraints[0].ConstraintName); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void XsdSchemaSerializationIgnoresLocale() { var serializer = new BinaryFormatter(); @@ -475,7 +475,7 @@ public void XsdSchemaSerializationIgnoresLocale() Assert.DoesNotContain("()2", rawSchemaXML); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework does not have the fix for this bug")] public void XsdSchemaDeserializationIgnoresLocale() { diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs index 2202651e330e..df8276d0aac4 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs @@ -375,7 +375,7 @@ public void SelectOperators() } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void DataColumnTypeSerialization() { DataTable dt = new DataTable("MyTable"); @@ -1767,7 +1767,7 @@ public void TestWriteXmlSchema3() Assert.Equal("", textString); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void Serialize() { // Create an array with multiple elements refering to @@ -2887,7 +2887,7 @@ public void ReadXmlSchema() Assert.True(column3.Unique); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void ReadXmlSchema_2() { DataTable dt = new DataTable(); @@ -3111,7 +3111,7 @@ public void ReadXmlSchema_ByXmlReader() Assert.Equal(0, dt2.Rows.Count); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void WriteXmlSchema() { using (new ThreadCultureChange("en-GB")) diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest4.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest4.cs index 4fa0a6308fa7..da6cabc4ecd1 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest4.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest4.cs @@ -870,7 +870,7 @@ public void XmlTest7() Assert.Equal(3, row["ParentID"]); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void XmlTest8() { MakeParentTable1(); @@ -910,7 +910,7 @@ public void XmlTest8() Assert.Equal("3", row["DepartmentID"]); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void XmlTest9() { MakeParentTable1(); diff --git a/src/libraries/System.Data.Common/tests/System/Data/FacadeTest.cs b/src/libraries/System.Data.Common/tests/System/Data/FacadeTest.cs index 49540efe7a7e..f8eba45d7f5c 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/FacadeTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/FacadeTest.cs @@ -10,6 +10,7 @@ public class FacadeTest [Theory] [InlineData("Microsoft.SqlServer.Server.SqlMetaData")] // Type from System.Data.SqlClient [InlineData("System.Data.SqlTypes.SqlBytes")] // Type from System.Data.Common + [PlatformSpecific(~TestPlatforms.Browser)] public void TestSystemData(string typeName) { // Verify that the type can be loaded via .NET Framework compat facade diff --git a/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringSortingTest.cs b/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringSortingTest.cs index 1f6fb8536ea4..0cae8f7a4040 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringSortingTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringSortingTest.cs @@ -37,7 +37,7 @@ public static class SqlStringSortingTest private static readonly UnicodeEncoding s_unicodeEncoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true); - [ConditionalTheory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] [InlineData("ja-JP", 0x0411)] // Japanese - Japan [InlineData("ar-SA", 0x0401)] // Arabic - Saudi Arabia [InlineData("de-DE", 0x0407)] // German - Germany diff --git a/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringTest.cs b/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringTest.cs index d123a60bf4e0..86a4b1683c4c 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlStringTest.cs @@ -62,7 +62,7 @@ public void Constructor_Value_Success() ValidateProperties(value, CultureInfo.CurrentCulture, new SqlString(value)); } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] [InlineData(1033, "en-US")] [InlineData(1036, "fr-FR")] public void Constructor_ValueLcid_Success(int lcid, string name) @@ -97,35 +97,38 @@ public void Create() SqlString testString = new SqlString("Test"); Assert.Equal("Test", testString.Value); - // SqlString (String, int) - testString = new SqlString("Test", 2057); - Assert.Equal(2057, testString.LCID); - - // SqlString (int, SqlCompareOptions, byte[]) - testString = new SqlString(2057, - SqlCompareOptions.BinarySort | SqlCompareOptions.IgnoreCase, - new byte[2] { 123, 221 }); - Assert.Equal(2057, testString.CompareInfo.LCID); - - // SqlString(string, int, SqlCompareOptions) - testString = new SqlString("Test", 2057, SqlCompareOptions.IgnoreNonSpace); - Assert.False(testString.IsNull); - - // SqlString (int, SqlCompareOptions, byte[], bool) - testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[4] { 100, 100, 200, 45 }, true); - Assert.Equal((byte)63, testString.GetNonUnicodeBytes()[0]); - testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[2] { 113, 100 }, false); - Assert.Equal("qd", testString.Value); - - // SqlString (int, SqlCompareOptions, byte[], int, int) - testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[2] { 113, 100 }, 0, 2); - Assert.False(testString.IsNull); - - // SqlString (int, SqlCompareOptions, byte[], int, int, bool) - testString = new SqlString(2057, SqlCompareOptions.IgnoreCase, new byte[3] { 100, 111, 50 }, 1, 2, false); - Assert.Equal("o2", testString.Value); - testString = new SqlString(2057, SqlCompareOptions.IgnoreCase, new byte[3] { 123, 111, 222 }, 1, 2, true); - Assert.False(testString.IsNull); + if (PlatformDetection.IsNotInvariantGlobalization) + { + // SqlString (String, int) + testString = new SqlString("Test", 2057); + Assert.Equal(2057, testString.LCID); + + // SqlString (int, SqlCompareOptions, byte[]) + testString = new SqlString(2057, + SqlCompareOptions.BinarySort | SqlCompareOptions.IgnoreCase, + new byte[2] { 123, 221 }); + Assert.Equal(2057, testString.CompareInfo.LCID); + + // SqlString(string, int, SqlCompareOptions) + testString = new SqlString("Test", 2057, SqlCompareOptions.IgnoreNonSpace); + Assert.False(testString.IsNull); + + // SqlString (int, SqlCompareOptions, byte[], bool) + testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[4] { 100, 100, 200, 45 }, true); + Assert.Equal((byte)63, testString.GetNonUnicodeBytes()[0]); + testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[2] { 113, 100 }, false); + Assert.Equal("qd", testString.Value); + + // SqlString (int, SqlCompareOptions, byte[], int, int) + testString = new SqlString(2057, SqlCompareOptions.BinarySort, new byte[2] { 113, 100 }, 0, 2); + Assert.False(testString.IsNull); + + // SqlString (int, SqlCompareOptions, byte[], int, int, bool) + testString = new SqlString(2057, SqlCompareOptions.IgnoreCase, new byte[3] { 100, 111, 50 }, 1, 2, false); + Assert.Equal("o2", testString.Value); + testString = new SqlString(2057, SqlCompareOptions.IgnoreCase, new byte[3] { 123, 111, 222 }, 1, 2, true); + Assert.False(testString.IsNull); + } } [Fact] @@ -170,7 +173,7 @@ public void PublicFields() } // Test properties - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void Properties() { using (new ThreadCultureChange("en-AU")) @@ -207,7 +210,7 @@ public void CompareToArgumentException() AssertExtensions.Throws(null, () => _test1.CompareTo(test)); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void CompareToSqlTypeException() { SqlString t1 = new SqlString("test", 2057, SqlCompareOptions.IgnoreCase); @@ -215,7 +218,7 @@ public void CompareToSqlTypeException() Assert.Throws(() => t1.CompareTo(t2)); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] public void CompareTo() { Assert.True(_test1.CompareTo(_test3) < 0); diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 3a61b3e16c98..75ce0856c06d 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -21,9 +21,6 @@ - - - From 55140820accf2563fdaf1f36c5063f6bb79f7256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Tue, 4 Aug 2020 12:51:04 +0200 Subject: [PATCH 231/755] Increased timeouts, fixed indentation. (#40273) --- .../tests/HttpWebRequestTest.cs | 112 +++++++++--------- 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs b/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs index c09a28538162..32903adbbe87 100644 --- a/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs @@ -109,7 +109,7 @@ public static IEnumerable MixedWebRequestParameters() yield return new object[] {new HttpWebRequestParameters { AllowAutoRedirect = true, AutomaticDecompression = DecompressionMethods.GZip, MaximumAutomaticRedirections = 2, MaximumResponseHeadersLength = 100, PreAuthenticate = true, SslProtocols = SecurityProtocolType.Tls12, Timeout = 100000}, true}; yield return new object[] {new HttpWebRequestParameters { AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.GZip, - MaximumAutomaticRedirections = 2, MaximumResponseHeadersLength = 100, PreAuthenticate = true, SslProtocols = SecurityProtocolType.Tls12, Timeout = 10000, + MaximumAutomaticRedirections = 2, MaximumResponseHeadersLength = 100, PreAuthenticate = true, SslProtocols = SecurityProtocolType.Tls12, Timeout = 100000, NewServerCertificateValidationCallback = true }, false}; yield return new object[] {new HttpWebRequestParameters { AllowAutoRedirect = true, AutomaticDecompression = DecompressionMethods.GZip, MaximumAutomaticRedirections = 2, MaximumResponseHeadersLength = 100, PreAuthenticate = true, SslProtocols = SecurityProtocolType.Tls12, Timeout = 100000, @@ -1688,62 +1688,60 @@ public void GetResponseAsync_ParametersAreNotCachable_CreateNewClient(HttpWebReq public void GetResponseAsync_ParametersAreCachableButDifferent_CreateNewClient() { RemoteExecutor.Invoke(async (async) => - { - using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) - { - listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); - listener.Listen(1); - var ep = (IPEndPoint)listener.LocalEndPoint; - var uri = new Uri($"http://{ep.Address}:{ep.Port}/"); - - var referenceParameters = new HttpWebRequestParameters - { - AllowAutoRedirect = true, - AutomaticDecompression = DecompressionMethods.GZip, - MaximumAutomaticRedirections = 2, - MaximumResponseHeadersLength = 100, - PreAuthenticate = true, - SslProtocols = SecurityProtocolType.Tls12, - Timeout = 100000 - }; - HttpWebRequest firstRequest = WebRequest.CreateHttp(uri); - referenceParameters.Configure(firstRequest); - firstRequest.Method = HttpMethod.Get.Method; - - string responseContent = "Test response."; - - Task firstResponseTask = bool.Parse(async) ? firstRequest.GetResponseAsync() : Task.Run(() => firstRequest.GetResponse()); - using (Socket server = await listener.AcceptAsync()) - using (var serverStream = new NetworkStream(server, ownsSocket: false)) - using (var serverReader = new StreamReader(serverStream)) - { - await ReplyToClient(responseContent, server, serverReader); - await VerifyResponse(responseContent, firstResponseTask); - - foreach (object[] caseRow in CachableWebRequestParameters()) - { - var currentParameters = (HttpWebRequestParameters)caseRow[0]; - bool connectionReused = (bool)caseRow[1]; - Task secondAccept = listener.AcceptAsync(); - - HttpWebRequest currentRequest = WebRequest.CreateHttp(uri); - currentParameters.Configure(currentRequest); - - Task currentResponseTask = bool.Parse(async) ? currentRequest.GetResponseAsync() : Task.Run(() => currentRequest.GetResponse()); - if (connectionReused) - { - await ReplyToClient(responseContent, server, serverReader); - Assert.False(secondAccept.IsCompleted); - await VerifyResponse(responseContent, currentResponseTask); - } - else - { - await VerifyNewConnection(responseContent, secondAccept, currentResponseTask); - } - } - } - } - }, (this is HttpWebRequestTest_Async).ToString()).Dispose(); + { + using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + listener.Listen(1); + var ep = (IPEndPoint)listener.LocalEndPoint; + var uri = new Uri($"http://{ep.Address}:{ep.Port}/"); + var referenceParameters = new HttpWebRequestParameters + { + AllowAutoRedirect = true, + AutomaticDecompression = DecompressionMethods.GZip, + MaximumAutomaticRedirections = 2, + MaximumResponseHeadersLength = 100, + PreAuthenticate = true, + SslProtocols = SecurityProtocolType.Tls12, + Timeout = 100000 + }; + HttpWebRequest firstRequest = WebRequest.CreateHttp(uri); + referenceParameters.Configure(firstRequest); + firstRequest.Method = HttpMethod.Get.Method; + + string responseContent = "Test response."; + Task firstResponseTask = bool.Parse(async) ? firstRequest.GetResponseAsync() : Task.Run(() => firstRequest.GetResponse()); + using (Socket server = await listener.AcceptAsync()) + using (var serverStream = new NetworkStream(server, ownsSocket: false)) + using (var serverReader = new StreamReader(serverStream)) + { + await ReplyToClient(responseContent, server, serverReader); + await VerifyResponse(responseContent, firstResponseTask); + + foreach (object[] caseRow in CachableWebRequestParameters()) + { + var currentParameters = (HttpWebRequestParameters)caseRow[0]; + bool connectionReused = (bool)caseRow[1]; + Task secondAccept = listener.AcceptAsync(); + + HttpWebRequest currentRequest = WebRequest.CreateHttp(uri); + currentParameters.Configure(currentRequest); + + Task currentResponseTask = bool.Parse(async) ? currentRequest.GetResponseAsync() : Task.Run(() => currentRequest.GetResponse()); + if (connectionReused) + { + await ReplyToClient(responseContent, server, serverReader); + Assert.False(secondAccept.IsCompleted); + await VerifyResponse(responseContent, currentResponseTask); + } + else + { + await VerifyNewConnection(responseContent, secondAccept, currentResponseTask); + } + } + } + } + }, (this is HttpWebRequestTest_Async).ToString()).Dispose(); } [Fact] From 4c18fb2cea5a7e0123fee52e61139836be3362b4 Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Tue, 4 Aug 2020 04:08:56 -0700 Subject: [PATCH 232/755] Reduce binary size by moving data definitions out of headers. (#40254) --- src/coreclr/src/debug/inc/dbgipcevents.h | 22 +++------------------- src/coreclr/src/debug/shared/utils.cpp | 14 ++++++++++++++ src/coreclr/src/inc/cor.h | 2 +- src/coreclr/src/utilcode/sigbuilder.cpp | 2 ++ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/coreclr/src/debug/inc/dbgipcevents.h b/src/coreclr/src/debug/inc/dbgipcevents.h index 34d8130bc5e4..6fd2cf197c65 100644 --- a/src/coreclr/src/debug/inc/dbgipcevents.h +++ b/src/coreclr/src/debug/inc/dbgipcevents.h @@ -984,25 +984,9 @@ struct MSLAYOUT IPCEventTypeNameMapping const char * eventName; }; -#ifdef _MSC_VER -extern const __declspec(selectany) -#else -constexpr -#endif -IPCEventTypeNameMapping DbgIPCEventTypeNames[] = -{ - #define IPC_EVENT_TYPE0(type, val) { type, #type }, - #define IPC_EVENT_TYPE1(type, val) { type, #type }, - #define IPC_EVENT_TYPE2(type, val) { type, #type }, - #include "dbgipceventtypes.h" - #undef IPC_EVENT_TYPE2 - #undef IPC_EVENT_TYPE1 - #undef IPC_EVENT_TYPE0 - { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" } -}; - -const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]); +extern const IPCEventTypeNameMapping DbgIPCEventTypeNames[]; +extern const size_t nameCount; struct MSLAYOUT IPCENames // We use a class/struct so that the function can remain in a shared header file { @@ -1033,7 +1017,7 @@ struct MSLAYOUT IPCENames // We use a class/struct so that the function can rema #undef IPC_EVENT_TYPE0 }; - unsigned int i, lim; + size_t i, lim; if (eventType < DB_IPCE_DEBUGGER_FIRST) { diff --git a/src/coreclr/src/debug/shared/utils.cpp b/src/coreclr/src/debug/shared/utils.cpp index 5363e30ee8a8..b9c7d72db3f7 100644 --- a/src/coreclr/src/debug/shared/utils.cpp +++ b/src/coreclr/src/debug/shared/utils.cpp @@ -200,3 +200,17 @@ void ExportILToNativeMap(ULONG32 cMap, // [in] Min size of mapExt, m #endif // _DEBUG } } + +const IPCEventTypeNameMapping DbgIPCEventTypeNames[] = +{ + #define IPC_EVENT_TYPE0(type, val) { type, #type }, + #define IPC_EVENT_TYPE1(type, val) { type, #type }, + #define IPC_EVENT_TYPE2(type, val) { type, #type }, + #include "dbgipceventtypes.h" + #undef IPC_EVENT_TYPE2 + #undef IPC_EVENT_TYPE1 + #undef IPC_EVENT_TYPE0 + { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" } +}; + +const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]); diff --git a/src/coreclr/src/inc/cor.h b/src/coreclr/src/inc/cor.h index 8d2b63294602..035ba44e7f87 100644 --- a/src/coreclr/src/inc/cor.h +++ b/src/coreclr/src/inc/cor.h @@ -2093,7 +2093,7 @@ inline ULONG CorSigUncompressData( // return number of bytes of that compre } -constexpr mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType}; +extern const mdToken g_tkCorEncodeToken[]; // uncompress a token inline mdToken CorSigUncompressToken( // return the token. diff --git a/src/coreclr/src/utilcode/sigbuilder.cpp b/src/coreclr/src/utilcode/sigbuilder.cpp index 111164149e7e..4a8f8fe6c183 100644 --- a/src/coreclr/src/utilcode/sigbuilder.cpp +++ b/src/coreclr/src/utilcode/sigbuilder.cpp @@ -6,6 +6,8 @@ #include "sigbuilder.h" #include "ex.h" +const mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType}; + void SigBuilder::AppendByte(BYTE b) { STANDARD_VM_CONTRACT; From 9cac0afdb40272d21a12f0d0cf52bbe460d59e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 4 Aug 2020 15:40:00 +0200 Subject: [PATCH 233/755] Bump timeout in global-build.yml for debug runtime builds (#40309) A good build of the `runtime-live-build` pipeline takes between 45-55mins for the debug runtime configurations already so we sometimes run into the 60mins default Azure DevOps timeout if we happen to catch a slow machine. Bumping the timeout to 120mins like we do in other pipelines to fix this. --- eng/pipelines/global-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 9721eb4b9f47..2d7e301f1a5e 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -48,6 +48,7 @@ jobs: testGroup: innerloop nameSuffix: Runtime_Debug buildArgs: -c release -runtimeConfiguration debug + timeoutInMinutes: 120 # # Build with Debug config and Release runtimeConfiguration From a2df15627fb7384f7c643cc8ba2ad2a55968e288 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 4 Aug 2020 06:42:19 -0700 Subject: [PATCH 234/755] Cleanup EventSource (#40204) * Move StubEnvironment.cs to Microsoft.Diagnostics.Tracing.EventSource.Redist * Delete ES_BUILD_PCL and ES_BUILD_AGAINST_DOTNET_V35 --- ...gnostics.Tracing.EventSource.Redist.csproj | 2 +- .../Diagnostics/Tracing/StubEnvironment.cs | 71 ++++ .../System.Private.CoreLib.Shared.projitems | 1 - .../Diagnostics/Tracing/ActivityTracker.cs | 26 -- .../Diagnostics/Tracing/EventDescriptor.cs | 3 - .../Diagnostics/Tracing/EventProvider.cs | 20 +- .../System/Diagnostics/Tracing/EventSource.cs | 72 ++-- .../Tracing/EventSourceException.cs | 7 - .../Diagnostics/Tracing/StubEnvironment.cs | 356 ------------------ .../Tracing/TraceLogging/DataCollector.cs | 3 - .../Tracing/TraceLogging/FieldMetadata.cs | 3 - .../Tracing/TraceLogging/PropertyValue.cs | 2 +- .../Tracing/TraceLogging/Statics.cs | 117 +----- .../TraceLogging/TraceLoggingEventSource.cs | 12 +- .../TraceLoggingMetadataCollector.cs | 3 - .../Tracing/TraceLogging/TypeAnalysis.cs | 5 +- 16 files changed, 117 insertions(+), 586 deletions(-) create mode 100644 src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs diff --git a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj index 4da74c9647f8..8c2783236fc6 100644 --- a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj +++ b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj @@ -10,6 +10,7 @@ true + @@ -36,7 +37,6 @@ - diff --git a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs new file mode 100644 index 000000000000..7d437be5f43d --- /dev/null +++ b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; + +namespace Microsoft.Diagnostics.Tracing +{ + internal static class Environment + { + public static readonly int ProcessId = GetCurrentProcessId(); + + private static int GetCurrentProcessId() + { + new SecurityPermission(PermissionState.Unrestricted).Assert(); + return (int)Interop.Kernel32.GetCurrentProcessId(); + } + } + + internal static class BitOperations + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateLeft(uint value, int offset) + => (value << offset) | (value >> (32 - offset)); + + public static int PopCount(uint value) + { + const uint c1 = 0x_55555555u; + const uint c2 = 0x_33333333u; + const uint c3 = 0x_0F0F0F0Fu; + const uint c4 = 0x_01010101u; + + value = value - ((value >> 1) & c1); + value = (value & c2) + ((value >> 2) & c2); + value = (((value + (value >> 4)) & c3) * c4) >> 24; + + return (int)value; + } + + public static int TrailingZeroCount(uint value) + { + if (value == 0) + return 32; + + int count = 0; + while ((value & 1) == 0) + { + value >>= 1; + count++; + } + return count; + } + } +} + +internal static partial class Interop +{ + [SuppressUnmanagedCodeSecurityAttribute] + internal static partial class Kernel32 + { + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + internal static extern int GetCurrentThreadId(); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + internal static extern uint GetCurrentProcessId(); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 61cc83639970..7add08bf9d38 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1170,7 +1170,6 @@ - diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs index cec4e969f2ce..e3f6632f59fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs @@ -4,7 +4,6 @@ #if ES_BUILD_STANDALONE using System; using System.Diagnostics; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; #else using System.Threading.Tasks; #endif @@ -228,10 +227,8 @@ public void Enable() } catch (NotImplementedException) { -#if (!ES_BUILD_PCL) // send message to debugger without delay System.Diagnostics.Debugger.Log(0, null, "Activity Enabled() called but AsyncLocals Not Supported (pre V4.6). Ignoring Enable"); -#endif } } } @@ -637,27 +634,4 @@ public class Keywords public void SetActivityId(Guid Id) { WriteEvent(3, Id); } } #endif - -#if ES_BUILD_AGAINST_DOTNET_V35 || ES_BUILD_PCL || NO_ASYNC_LOCAL - // In these cases we don't have any Async local support. Do nothing. - internal sealed class AsyncLocalValueChangedArgs - { - public T PreviousValue { get { return default(T); } } - public T CurrentValue { get { return default(T); } } - - } - - internal sealed class AsyncLocal - { - public AsyncLocal(Action> valueChangedHandler) { - throw new NotImplementedException("AsyncLocal only available on V4.6 and above"); - } - public T Value - { - get { return default(T); } - set { } - } - } -#endif - } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs index d687d41b42e7..5bdde239895a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -#endif using System.Runtime.InteropServices; #if ES_BUILD_STANDALONE diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs index 919927f4ebaa..6ed62d08290a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs @@ -1,22 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE -using Microsoft.Win32; using System; using System.Diagnostics; -using System.Security.Permissions; -using BitOperations = Microsoft.Diagnostics.Tracing.Internal.BitOperations; -#endif using System.Collections.Generic; using System.Globalization; using System.Numerics; using System.Runtime.InteropServices; -#if (CORECLR || MONO) && TARGET_WINDOWS -using Internal.Win32; + +#if ES_BUILD_STANDALONE +using Microsoft.Win32; +using System.Security.Permissions; #endif -#if ES_BUILD_AGAINST_DOTNET_V35 -using Microsoft.Internal; // for Tuple (can't define alias for open generic types so we "use" the whole namespace) + +#if !ES_BUILD_STANDALONE && TARGET_WINDOWS +using Internal.Win32; #endif #if ES_BUILD_STANDALONE @@ -521,7 +519,7 @@ private unsafe void GetSessionInfo(SessionInfoCallback action, ref List @@ -3029,15 +3009,15 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt Type? ret = eventSourceType; // return false for "object" and interfaces - if (ret.BaseType() == null) + if (ret.BaseType == null) return null; // now go up the inheritance chain until hitting a concrete type ("object" at worse) do { - ret = ret.BaseType(); + ret = ret.BaseType; } - while (ret != null && ret.IsAbstract()); + while (ret != null && ret.IsAbstract); if (ret != null) { @@ -3074,7 +3054,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt Exception? exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error byte[]? res = null; - if (eventSourceType.IsAbstract() && (flags & EventManifestOptions.Strict) == 0) + if (eventSourceType.IsAbstract && (flags & EventManifestOptions.Strict) == 0) return null; try @@ -3094,7 +3074,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt ResourceManager? resources = null; EventSourceAttribute? eventSourceAttrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); if (eventSourceAttrib != null && eventSourceAttrib.LocalizationResources != null) - resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly()); + resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly); manifest = new ManifestBuilder(GetName(eventSourceType, flags), GetGuid(eventSourceType), eventSourceDllName, resources, flags); @@ -3107,13 +3087,13 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt // eventSourceType must be sealed and must derive from this EventSource if ((flags & EventManifestOptions.Strict) != 0) { - bool typeMatch = GetEventSourceBaseType(eventSourceType, (flags & EventManifestOptions.AllowEventSourceOverride) != 0, eventSourceType.Assembly().ReflectionOnly()) != null; + bool typeMatch = GetEventSourceBaseType(eventSourceType, (flags & EventManifestOptions.AllowEventSourceOverride) != 0, eventSourceType.Assembly.ReflectionOnly) != null; if (!typeMatch) { manifest.ManifestError(SR.EventSource_TypeMustDeriveFromEventSource); } - if (!eventSourceType.IsAbstract() && !eventSourceType.IsSealed()) + if (!eventSourceType.IsAbstract && !eventSourceType.IsSealed) { manifest.ManifestError(SR.EventSource_TypeMustBeSealedOrAbstract); } @@ -3129,7 +3109,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt Type? nestedType = eventSourceType.GetNestedType(providerEnumKind); if (nestedType != null) { - if (eventSourceType.IsAbstract()) + if (eventSourceType.IsAbstract) { manifest.ManifestError(SR.Format(SR.EventSource_AbstractMustNotDeclareKTOC, nestedType.Name)); } @@ -3170,7 +3150,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt continue; } - if (eventSourceType.IsAbstract()) + if (eventSourceType.IsAbstract) { if (eventAttribute != null) { @@ -3321,7 +3301,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt } // if this is an abstract event source we've already performed all the validation we can - if (!eventSourceType.IsAbstract() && (source == null || !source.SelfDescribingEvents)) + if (!eventSourceType.IsAbstract && (source == null || !source.SelfDescribingEvents)) { bNeedsManifest = (flags & EventManifestOptions.OnlyIfNeededForRegistration) == 0 #if FEATURE_MANAGED_ETW_CHANNELS @@ -3355,7 +3335,7 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt foreach (string error in manifest.Errors) { if (!firstError) - msg += Environment.NewLine; + msg += System.Environment.NewLine; firstError = false; msg += error; } @@ -3389,7 +3369,7 @@ private static bool RemoveFirstArgIfRelatedActivityId(ref ParameterInfo[] args) // to the manifest. private static void AddProviderEnumKind(ManifestBuilder manifest, FieldInfo staticField, string providerEnumKind) { - bool reflectionOnly = staticField.Module.Assembly.ReflectionOnly(); + bool reflectionOnly = staticField.Module.Assembly.ReflectionOnly; Type staticFieldType = staticField.FieldType; if (!reflectionOnly && (staticFieldType == typeof(EventOpcode)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventOpcode))) { @@ -3586,7 +3566,6 @@ private static void DebugCheckEvent(ref Dictionary? eventsByName /// The literal value or -1 if the value could not be determined. private static int GetHelperCallFirstArg(MethodInfo method) { -#if (!ES_BUILD_PCL) // Currently searches for the following pattern // // ... // CAN ONLY BE THE INSTRUCTIONS BELOW @@ -3703,7 +3682,6 @@ private static int GetHelperCallFirstArg(MethodInfo method) } idx++; } -#endif return -1; } @@ -3715,10 +3693,8 @@ internal void ReportOutOfBandMessage(string msg) { try { -#if (!ES_BUILD_PCL) // send message to debugger without delay - System.Diagnostics.Debugger.Log(0, null, string.Format("EventSource Error: {0}{1}", msg, Environment.NewLine)); -#endif + System.Diagnostics.Debugger.Log(0, null, string.Format("EventSource Error: {0}{1}", msg, System.Environment.NewLine)); // Send it to all listeners. if (m_outOfBandMessageCount < 16 - 1) // Note this is only if size byte @@ -5423,7 +5399,7 @@ public void AddEventParameter(Type type, string name) templates.Append(" length=\"").Append(name).Append("Size\""); } // ETW does not support 64-bit value maps, so we don't specify these as ETW maps - if (type.IsEnum() && Enum.GetUnderlyingType(type) != typeof(ulong) && Enum.GetUnderlyingType(type) != typeof(long)) + if (type.IsEnum && Enum.GetUnderlyingType(type) != typeof(ulong) && Enum.GetUnderlyingType(type) != typeof(long)) { templates.Append(" map=\"").Append(type.Name).Append('"'); mapsTab ??= new Dictionary(); @@ -5915,14 +5891,14 @@ private string GetKeywords(ulong keywords, string eventName) private string GetTypeName(Type type) { - if (type.IsEnum()) + if (type.IsEnum) { FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); string typeName = GetTypeName(fields[0].FieldType); return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned. } - switch (type.GetTypeCode()) + switch (Type.GetTypeCode(type)) { case TypeCode.Boolean: return "win:Boolean"; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSourceException.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSourceException.cs index 67f70c747e2c..638bb05b9eb9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSourceException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSourceException.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -#endif using System.Runtime.Serialization; #if ES_BUILD_STANDALONE @@ -16,9 +13,7 @@ namespace System.Diagnostics.Tracing /// /// Exception that is thrown when an error occurs during EventSource operation. /// -#if !ES_BUILD_PCL [Serializable] -#endif public class EventSourceException : Exception { /// @@ -38,12 +33,10 @@ public EventSourceException(string? message) : base(message) { } /// public EventSourceException(string? message, Exception? innerException) : base(message, innerException) { } -#if !ES_BUILD_PCL /// /// Initializes a new instance of the EventSourceException class with serialized data. /// protected EventSourceException(SerializationInfo info, StreamingContext context) : base(info, context) { } -#endif internal EventSourceException(Exception? innerException) : base(SR.EventSource_ListenerWriteFailure, innerException) { } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs deleted file mode 100644 index 90428c3b942c..000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs +++ /dev/null @@ -1,356 +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; -#if ES_BUILD_PCL -using System.Collections.Generic; -#endif -using System.Reflection; -#if ES_BUILD_STANDALONE -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Permissions; -#endif -#if ES_BUILD_AGAINST_DOTNET_V35 -using Microsoft.Internal; -#endif -using Microsoft.Reflection; - -#if ES_BUILD_STANDALONE -namespace Microsoft.Diagnostics.Tracing.Internal -#else -namespace System.Diagnostics.Tracing.Internal -#endif -{ -#if ES_BUILD_STANDALONE - internal static class Environment - { - public static int ProcessId = GetCurrentProcessId(); - - private static int GetCurrentProcessId() - { - new SecurityPermission(PermissionState.Unrestricted).Assert(); - return (int)Interop.Kernel32.GetCurrentProcessId(); - } - } - - internal static class BitOperations - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeft(uint value, int offset) - => (value << offset) | (value >> (32 - offset)); - - public static int PopCount(uint value) - { - const uint c1 = 0x_55555555u; - const uint c2 = 0x_33333333u; - const uint c3 = 0x_0F0F0F0Fu; - const uint c4 = 0x_01010101u; - - value = value - ((value >> 1) & c1); - value = (value & c2) + ((value >> 2) & c2); - value = (((value + (value >> 4)) & c3) * c4) >> 24; - - return (int)value; - } - - public static int TrailingZeroCount(uint value) - { - if (value == 0) - return 32; - - int count = 0; - while ((value & 1) == 0) - { - value >>= 1; - count++; - } - return count; - } - } -#endif -} - -#if ES_BUILD_AGAINST_DOTNET_V35 - -namespace Microsoft.Internal -{ - using System.Text; - - internal static class Tuple - { - public static Tuple Create(T1 item1) - { - return new Tuple(item1); - } - - public static Tuple Create(T1 item1, T2 item2) - { - return new Tuple(item1, item2); - } - } - - [Serializable] - internal class Tuple - { - private readonly T1 m_Item1; - - public T1 Item1 { get { return m_Item1; } } - - public Tuple(T1 item1) - { - m_Item1 = item1; - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.Append('('); - sb.Append(m_Item1); - sb.Append(')'); - return sb.ToString(); - } - - int Size - { - get - { - return 1; - } - } - } - - [Serializable] - public class Tuple - { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - - public T1 Item1 { get { return m_Item1; } } - public T2 Item2 { get { return m_Item2; } } - - public Tuple(T1 item1, T2 item2) - { - m_Item1 = item1; - m_Item2 = item2; - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.Append('('); - sb.Append(m_Item1); - sb.Append(", "); - sb.Append(m_Item2); - sb.Append(')'); - return sb.ToString(); - } - - int Size - { - get - { - return 2; - } - } - } -} - -#endif - -namespace Microsoft.Reflection -{ -#if ES_BUILD_PCL - [Flags] - public enum BindingFlags - { - DeclaredOnly = 0x02, // Only look at the members declared on the Type - Instance = 0x04, // Include Instance members in search - Static = 0x08, // Include Static members in search - Public = 0x10, // Include Public members in search - NonPublic = 0x20, // Include Non-Public members in search - } - - public enum TypeCode { - Empty = 0, // Null reference - Object = 1, // Instance that isn't a value - DBNull = 2, // Database null value - Boolean = 3, // Boolean - Char = 4, // Unicode character - SByte = 5, // Signed 8-bit integer - Byte = 6, // Unsigned 8-bit integer - Int16 = 7, // Signed 16-bit integer - UInt16 = 8, // Unsigned 16-bit integer - Int32 = 9, // Signed 32-bit integer - UInt32 = 10, // Unsigned 32-bit integer - Int64 = 11, // Signed 64-bit integer - UInt64 = 12, // Unsigned 64-bit integer - Single = 13, // IEEE 32-bit float - Double = 14, // IEEE 64-bit double - Decimal = 15, // Decimal - DateTime = 16, // DateTime - String = 18, // Unicode character string - } -#endif - internal static class ReflectionExtensions - { -#if (!ES_BUILD_PCL) - - // - // Type extension methods - // - public static bool IsEnum(this Type type) { return type.IsEnum; } - public static bool IsAbstract(this Type type) { return type.IsAbstract; } - public static bool IsSealed(this Type type) { return type.IsSealed; } - public static bool IsValueType(this Type type) { return type.IsValueType; } - public static bool IsGenericType(this Type type) { return type.IsGenericType; } - public static Type? BaseType(this Type type) { return type.BaseType; } - public static Assembly Assembly(this Type type) { return type.Assembly; } - public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); } - - public static bool ReflectionOnly(this Assembly assm) { return assm.ReflectionOnly; } - -#else - - // - // Type extension methods - // - public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; } - public static bool IsAbstract(this Type type) { return type.GetTypeInfo().IsAbstract; } - public static bool IsSealed(this Type type) { return type.GetTypeInfo().IsSealed; } - public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; } - public static bool IsGenericType(this Type type) { return type.IsConstructedGenericType; } - public static Type? BaseType(this Type type) { return type.GetTypeInfo().BaseType; } - public static Assembly Assembly(this Type type) { return type.GetTypeInfo().Assembly; } - public static IEnumerable GetProperties(this Type type) - { - return type.GetRuntimeProperties(); - } - public static MethodInfo? GetGetMethod(this PropertyInfo propInfo) { return propInfo.GetMethod; } - public static Type[] GetGenericArguments(this Type type) { return type.GenericTypeArguments; } - - public static MethodInfo[] GetMethods(this Type type, BindingFlags flags) - { - // Minimal implementation to cover only the cases we need - System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0); - System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Static|BindingFlags.Public|BindingFlags.NonPublic)) == 0); - Func visFilter; - Func instFilter; - switch (flags & (BindingFlags.Public | BindingFlags.NonPublic)) - { - case 0: visFilter = mi => false; break; - case BindingFlags.Public: visFilter = mi => mi.IsPublic; break; - case BindingFlags.NonPublic: visFilter = mi => !mi.IsPublic; break; - default: visFilter = mi => true; break; - } - switch (flags & (BindingFlags.Instance | BindingFlags.Static)) - { - case 0: instFilter = mi => false; break; - case BindingFlags.Instance: instFilter = mi => !mi.IsStatic; break; - case BindingFlags.Static: instFilter = mi => mi.IsStatic; break; - default: instFilter = mi => true; break; - } - List methodInfos = new List(); - foreach (var declaredMethod in type.GetTypeInfo().DeclaredMethods) - { - if (visFilter(declaredMethod) && instFilter(declaredMethod)) - methodInfos.Add(declaredMethod); - } - return methodInfos.ToArray(); - } - public static FieldInfo[] GetFields(this Type type, BindingFlags flags) - { - // Minimal implementation to cover only the cases we need - System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0); - System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) == 0); - Func visFilter; - Func instFilter; - switch (flags & (BindingFlags.Public | BindingFlags.NonPublic)) - { - case 0: visFilter = fi => false; break; - case BindingFlags.Public: visFilter = fi => fi.IsPublic; break; - case BindingFlags.NonPublic: visFilter = fi => !fi.IsPublic; break; - default: visFilter = fi => true; break; - } - switch (flags & (BindingFlags.Instance | BindingFlags.Static)) - { - case 0: instFilter = fi => false; break; - case BindingFlags.Instance: instFilter = fi => !fi.IsStatic; break; - case BindingFlags.Static: instFilter = fi => fi.IsStatic; break; - default: instFilter = fi => true; break; - } - List fieldInfos = new List(); - foreach (var declaredField in type.GetTypeInfo().DeclaredFields) - { - if (visFilter(declaredField) && instFilter(declaredField)) - fieldInfos.Add(declaredField); - } - return fieldInfos.ToArray(); - } - public static Type? GetNestedType(this Type type, string nestedTypeName) - { - TypeInfo? ti = null; - foreach (var nt in type.GetTypeInfo().DeclaredNestedTypes) - { - if (nt.Name == nestedTypeName) - { - ti = nt; - break; - } - } - return ti == null ? null : ti.AsType(); - } - public static TypeCode GetTypeCode(this Type type) - { - if (type == typeof(bool)) return TypeCode.Boolean; - else if (type == typeof(byte)) return TypeCode.Byte; - else if (type == typeof(char)) return TypeCode.Char; - else if (type == typeof(ushort)) return TypeCode.UInt16; - else if (type == typeof(uint)) return TypeCode.UInt32; - else if (type == typeof(ulong)) return TypeCode.UInt64; - else if (type == typeof(sbyte)) return TypeCode.SByte; - else if (type == typeof(short)) return TypeCode.Int16; - else if (type == typeof(int)) return TypeCode.Int32; - else if (type == typeof(long)) return TypeCode.Int64; - else if (type == typeof(string)) return TypeCode.String; - else if (type == typeof(float)) return TypeCode.Single; - else if (type == typeof(double)) return TypeCode.Double; - else if (type == typeof(DateTime)) return TypeCode.DateTime; - else if (type == (typeof(decimal))) return TypeCode.Decimal; - else return TypeCode.Object; - } - - // - // FieldInfo extension methods - // - public static object? GetRawConstantValue(this FieldInfo fi) - { return fi.GetValue(null); } - - // - // Assembly extension methods - // - public static bool ReflectionOnly(this Assembly assm) - { - // In PCL we can't load in reflection-only context - return false; - } - -#endif - } -} - -#if ES_BUILD_STANDALONE -internal static partial class Interop -{ - [SuppressUnmanagedCodeSecurityAttribute] - internal static partial class Kernel32 - { - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] - internal static extern int GetCurrentThreadId(); - - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] - internal static extern uint GetCurrentProcessId(); - } -} -#endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs index da5a4e1807bf..19bf2e01fdc0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs @@ -1,11 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; using System.Diagnostics; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -#endif using System.Runtime.InteropServices; #if ES_BUILD_STANDALONE diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs index 47fc5b3fb32a..cd5db860c31a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs @@ -1,14 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; using System.Diagnostics; -#endif using System.Text; #if ES_BUILD_STANDALONE -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; namespace Microsoft.Diagnostics.Tracing #else namespace System.Diagnostics.Tracing diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs index 35e9c2da5102..31ce1d6d85a9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs @@ -217,7 +217,7 @@ public override Func GetPropertyGetter(PropertyInf { Type type = property.PropertyType; - if (!Statics.IsValueType(type)) + if (!type.IsValueType) { var getter = (Func)GetGetMethod(property, type); return container => new PropertyValue(getter((TContainer)container.ReferenceValue!)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs index dd3920ba73d0..b7ad6be87d6b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs @@ -1,15 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -#endif using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; -using Microsoft.Reflection; #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing @@ -321,87 +317,22 @@ public static TraceLoggingDataType FormatPtr( #region Reflection helpers - /* - All TraceLogging use of reflection APIs should go through wrappers here. - This helps with portability, and it also makes it easier to audit what - kinds of reflection operations are being done. - */ - - public static object? CreateInstance(Type type, params object?[]? parameters) - { - return Activator.CreateInstance(type, parameters); - } - - public static bool IsValueType(Type type) - { - bool result = type.IsValueType(); - return result; - } - - public static bool IsEnum(Type type) - { - bool result = type.IsEnum(); - return result; - } - - public static IEnumerable GetProperties(Type type) - { - IEnumerable result = type.GetProperties(); - return result; - } - - public static MethodInfo? GetGetMethod(PropertyInfo propInfo) - { - MethodInfo? result = propInfo.GetGetMethod(); - return result; - } - - public static MethodInfo? GetDeclaredStaticMethod(Type declaringType, string name) - { - MethodInfo? result; -#if (ES_BUILD_PCL) - result = declaringType.GetTypeInfo().GetDeclaredMethod(name); -#else - result = declaringType.GetMethod( - name, - BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic); -#endif - return result; - } - public static bool HasCustomAttribute( PropertyInfo propInfo, Type attributeType) { - bool result; -#if (ES_BUILD_PCL) - result = propInfo.IsDefined(attributeType); -#else - object[] attributes = propInfo.GetCustomAttributes( - attributeType, - false); - result = attributes.Length != 0; -#endif - return result; + return propInfo.IsDefined(attributeType, false); } public static AttributeType? GetCustomAttribute(PropertyInfo propInfo) where AttributeType : Attribute { AttributeType? result = null; -#if (ES_BUILD_PCL) - foreach (var attrib in propInfo.GetCustomAttributes(false)) - { - result = attrib; - break; - } -#else object[] attributes = propInfo.GetCustomAttributes(typeof(AttributeType), false); if (attributes.Length != 0) { result = (AttributeType)attributes[0]; } -#endif return result; } @@ -409,52 +340,28 @@ public static bool HasCustomAttribute( where AttributeType : Attribute { AttributeType? result = null; -#if (ES_BUILD_PCL) - foreach (var attrib in type.GetTypeInfo().GetCustomAttributes(false)) - { - result = attrib; - break; - } -#else object[] attributes = type.GetCustomAttributes(typeof(AttributeType), false); if (attributes.Length != 0) { result = (AttributeType)attributes[0]; } -#endif return result; } - public static Type[] GetGenericArguments(Type type) - { - return type.GetGenericArguments(); - } - public static Type? FindEnumerableElementType(Type type) { Type? elementType = null; if (IsGenericMatch(type, typeof(IEnumerable<>))) { - elementType = GetGenericArguments(type)[0]; + elementType = type.GetGenericArguments()[0]; } else { -#if (ES_BUILD_PCL) - IEnumerable ifaceTypes = type.GetTypeInfo().ImplementedInterfaces; -#else Type[] ifaceTypes = type.FindInterfaces(IsGenericMatch, typeof(IEnumerable<>)); -#endif foreach (Type ifaceType in ifaceTypes) { -#if (ES_BUILD_PCL) - if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>))) - { - continue; - } -#endif - if (elementType != null) { // ambiguous match. report no match at all. @@ -462,7 +369,7 @@ public static Type[] GetGenericArguments(Type type) break; } - elementType = GetGenericArguments(ifaceType)[0]; + elementType = ifaceType.GetGenericArguments()[0]; } } @@ -471,21 +378,7 @@ public static Type[] GetGenericArguments(Type type) public static bool IsGenericMatch(Type type, object? openType) { - return type.IsGenericType() && type.GetGenericTypeDefinition() == (Type?)openType; - } - - public static Delegate CreateDelegate(Type delegateType, MethodInfo methodInfo) - { - Delegate result; -#if (ES_BUILD_PCL) - result = methodInfo.CreateDelegate( - delegateType); -#else - result = Delegate.CreateDelegate( - delegateType, - methodInfo); -#endif - return result; + return type.IsGenericType && type.GetGenericTypeDefinition() == (Type?)openType; } public static TraceLoggingTypeInfo CreateDefaultTypeInfo( @@ -579,7 +472,7 @@ public static TraceLoggingTypeInfo CreateDefaultTypeInfo( } else { - if (Statics.IsEnum(dataType)) + if (dataType.IsEnum) dataType = Enum.GetUnderlyingType(dataType); if (dataType == typeof(string)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index cabafa707239..c6127beeb4cd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -13,14 +13,10 @@ // #define FEATURE_ADVANCED_MANAGED_ETW_CHANNELS #endif -#if ES_BUILD_STANDALONE using System; -using System.Diagnostics; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor; -#endif using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; @@ -440,7 +436,7 @@ private unsafe void WriteMultiMergeInner( descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); -#if (!ES_BUILD_PCL && !NETCOREAPP) +#if ES_BUILD_STANDALONE System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -624,7 +620,7 @@ private unsafe void WriteImpl( descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #endif // FEATURE_MANAGED_ETW -#if (!ES_BUILD_PCL && !NETCOREAPP) +#if ES_BUILD_STANDALONE System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif EventOpcode opcode = (EventOpcode)descriptor.Opcode; @@ -731,7 +727,7 @@ private unsafe void WriteToAllListeners(string? eventName, ref EventDescriptor e DispatchToAllListeners(-1, eventCallbackArgs); } -#if (!ES_BUILD_PCL && !NETCOREAPP) +#if ES_BUILD_STANDALONE [System.Runtime.ConstrainedExecution.ReliabilityContract( System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, System.Runtime.ConstrainedExecution.Cer.Success)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs index d50140fef4cc..e0f2943cbce7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if ES_BUILD_STANDALONE using System; -using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; -#endif using System.Collections.Generic; #if ES_BUILD_STANDALONE diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs index df3a61ff2fbf..0324f31563bb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs @@ -30,10 +30,9 @@ public TypeAnalysis( EventDataAttribute? eventAttrib, List recursionCheck) { - IEnumerable propertyInfos = Statics.GetProperties(dataType); var propertyList = new List(); - foreach (PropertyInfo propertyInfo in propertyInfos) + foreach (PropertyInfo propertyInfo in dataType.GetProperties()) { if (Statics.HasCustomAttribute(propertyInfo, typeof(EventIgnoreAttribute))) { @@ -46,7 +45,7 @@ public TypeAnalysis( continue; } - MethodInfo? getterInfo = Statics.GetGetMethod(propertyInfo); + MethodInfo? getterInfo = propertyInfo.GetGetMethod(); if (getterInfo == null) { continue; From c0707135c4969be520efae02c9593d481c57cc8f Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Tue, 4 Aug 2020 16:12:11 +0200 Subject: [PATCH 235/755] Xml docs for SocketsHttpHandler's IsSupported and EnableMultipleHttp2Connections (#40308) Fixes #39489 --- .../Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index db2cfedf2b1a..73c1c3493af0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -35,6 +35,9 @@ private void CheckDisposedOrStarted() } } + /// + /// Gets a value that indicates whether the handler is supported on the current platform. + /// public static bool IsSupported => true; public bool UseCookies @@ -277,6 +280,10 @@ public TimeSpan Expect100ContinueTimeout } } + /// + /// Gets or sets a value that indicates whether additional HTTP/2 connections can be established to the same server + /// when the maximum of concurrent streams is reached on all existing connections. + /// public bool EnableMultipleHttp2Connections { get => _settings._enableMultipleHttp2Connections; From c469ac9f3a9687bc118d899047a166e327e2a33e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 4 Aug 2020 10:31:40 -0400 Subject: [PATCH 236/755] Fix hang in HTTP/2 handling of canceling credit waits (#40243) * Re-combine CreditWaiter and CancelableCreditWaiter The split was to optimize the case when there's no cancellation token, but based on the evolution of the codebase, that doesn't really happen, and it makes the common cancellation case a bit more expensive (and convoluted). * Fix hang in HTTP/2 handling of canceling credit The CreditWaiter took a lock to protect its ManualResetValueTaskSourceCore state. The lock was also shared with its parent. This could result in a situation where the parent was holding the lock and called into the CreditWaiter to dispose of it and in turn dispose of the registration with the CancellationToken. That registration could have represented an in-flight cancellation callback, which would also try to take the lock in order to complete the MRVTSC. And since CancellationTokenRegistration.Dispose blocks waiting for an in-flight cancellation callback to complete, this could deadlock, with a thread holding the lock while waiting for another thread that tries to take the lock to make forward progress. This fixes it simply by avoiding the lock entirely and instead using a simple compare-exchange to protect the right to complete the MRVTSC. * Address PR feedback --- .../Http/SocketsHttpHandler/CreditManager.cs | 4 +- .../Http/SocketsHttpHandler/CreditWaiter.cs | 125 +++++++++--------- .../Http/SocketsHttpHandler/Http2Stream.cs | 9 +- .../StressTests/HttpStress/StressServer.cs | 3 +- 4 files changed, 68 insertions(+), 73 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs index f6d37aef6238..1174a8599697 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs @@ -60,9 +60,7 @@ public ValueTask RequestCreditAsync(int amount, CancellationToken cancellat if (NetEventSource.Log.IsEnabled()) _owner.Trace($"{_name}. requested={amount}, no credit available."); // Otherwise, create a new waiter. - CreditWaiter waiter = cancellationToken.CanBeCanceled ? - new CancelableCreditWaiter(SyncObject, cancellationToken) : - new CreditWaiter(); + var waiter = new CreditWaiter(cancellationToken); waiter.Amount = amount; // Add the waiter at the tail of the queue. 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 31ca2470b1f1..43a8d86d71a7 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 @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -10,21 +9,65 @@ namespace System.Net.Http { /// Represents a waiter for credit. - internal class CreditWaiter : IValueTaskSource + internal sealed class CreditWaiter : IValueTaskSource { + // State for the implementation of the CreditWaiter. Note that neither _cancellationToken nor + // _registration are zero'd out upon completion, because they're used for synchronization + // between successful completion and cancellation. This means an instance may end up + // referencing the underlying CancellationTokenSource even after the await operation has completed. + + /// Cancellation token for the current wait operation. + private CancellationToken _cancellationToken; + /// Cancellation registration for the current wait operation. + private CancellationTokenRegistration _registration; + /// implementation. + private ManualResetValueTaskSourceCore _source; + + // State carried with the waiter for the consumer to use; these aren't used at all in the implementation. + + /// Amount of credit desired by this waiter. public int Amount; + /// Next waiter in a list of waiters. public CreditWaiter? Next; - protected ManualResetValueTaskSourceCore _source; - public CreditWaiter() => _source.RunContinuationsAsynchronously = true; + /// Initializes a waiter for a credit wait operation. + /// The cancellation token for this wait operation. + public CreditWaiter(CancellationToken cancellationToken) + { + _source.RunContinuationsAsynchronously = true; + RegisterCancellation(cancellationToken); + } - public ValueTask AsValueTask() => new ValueTask(this, _source.Version); + /// Re-initializes a waiter for a credit wait operation. + /// The cancellation token for this wait operation. + public void ResetForAwait(CancellationToken cancellationToken) + { + _source.Reset(); + RegisterCancellation(cancellationToken); + } - public bool IsPending => _source.GetStatus(_source.Version) == ValueTaskSourceStatus.Pending; + /// Registers with the cancellation token to transition the source to a canceled state. + /// The cancellation token with which to register. + private void RegisterCancellation(CancellationToken cancellationToken) + { + _cancellationToken = cancellationToken; + _registration = cancellationToken.UnsafeRegister(static s => + { + // The callback will only fire if cancellation owns the right to complete the instance. + var thisRef = (CreditWaiter)s!; + thisRef._source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(thisRef._cancellationToken))); + }, this); + } + /// Wraps the instance as a to make it awaitable. + public ValueTask AsValueTask() => new ValueTask(this, _source.Version); + + /// Completes the instance with the specified result. + /// The result value. + /// true if the instance was successfully completed; false if it was or is being canceled. public bool TrySetResult(int result) { - if (IsPending) + if (UnregisterAndOwnCompletion()) { _source.SetResult(result); return true; @@ -33,17 +76,25 @@ public bool TrySetResult(int result) return false; } - public virtual void CleanUp() { } - + /// Disposes the instance, failing any outstanding wait. public void Dispose() { - CleanUp(); - if (IsPending) + if (UnregisterAndOwnCompletion()) { _source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(CreditManager), SR.net_http_disposed_while_in_use))); } } + /// Unregisters the cancellation callback. + /// true if the non-cancellation caller has the right to complete the instance; false if the instance was or is being completed by cancellation. + private bool UnregisterAndOwnCompletion() => + // Unregister the cancellation callback. If Unregister returns true, then the cancellation callback was successfully removed, + // meaning it hasn't run and won't ever run. If it returns false, a) cancellation already occurred or is occurring and thus + // the callback couldn't be removed, b) cancellation occurred prior to the UnsafeRegister call such that _registration was + // set to a default value (or hasn't been set yet), or c) a default CancellationToken was used. (a) and (b) are effectively + // the same, and (c) can be checked via CanBeCanceled. + _registration.Unregister() || !_cancellationToken.CanBeCanceled; + int IValueTaskSource.GetResult(short token) => _source.GetResult(token); ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => @@ -51,56 +102,4 @@ ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => void IValueTaskSource.OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _source.OnCompleted(continuation, state, token, flags); } - - /// Represents a cancelable waiter for credit. - internal sealed class CancelableCreditWaiter : CreditWaiter - { - private readonly object _syncObj; - private CancellationTokenRegistration _registration; - - public CancelableCreditWaiter(object syncObj, CancellationToken cancellationToken) - { - _syncObj = syncObj; - RegisterCancellation(cancellationToken); - } - - public void ResetForAwait(CancellationToken cancellationToken) - { - Debug.Assert(Monitor.IsEntered(_syncObj)); - Debug.Assert(!IsPending); - Debug.Assert(Next is null); - Debug.Assert(_registration == default); - - _source.Reset(); - RegisterCancellation(cancellationToken); - } - - public override void CleanUp() - { - Monitor.IsEntered(_syncObj); - _registration.Dispose(); - _registration = default; - } - - private void RegisterCancellation(CancellationToken cancellationToken) - { - _registration = cancellationToken.UnsafeRegister(static s => - { - CancelableCreditWaiter thisRef = (CancelableCreditWaiter)s!; - lock (thisRef._syncObj) - { - if (thisRef.IsPending) - { - thisRef._registration = default; // benign race with setting in the ctor - thisRef._source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(thisRef._registration.Token))); - - // We don't remove it from the list as we lack a prev pointer that would enable us to do so correctly, - // and it's not worth adding a prev pointer for the rare case of cancellation. We instead just - // check when completing a waiter whether it's already been canceled. As such, we also do not - // dispose it here. - } - } - }, this); - } - } } 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 254fec2cd30e..0635de4df9b9 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 @@ -36,7 +36,7 @@ private sealed class Http2Stream : IValueTaskSource, IHttpHeadersHandler, IHttpT private ArrayBuffer _responseBuffer; // mutable struct, do not make this readonly private int _pendingWindowUpdate; - private CancelableCreditWaiter? _creditWaiter; + private CreditWaiter? _creditWaiter; private int _availableCredit; private StreamCompletionState _requestCompletionState; @@ -426,7 +426,7 @@ public void OnWindowUpdate(int amount) lock (SyncObject) { _availableCredit = checked(_availableCredit + amount); - if (_availableCredit > 0 && _creditWaiter != null && _creditWaiter.IsPending) + if (_availableCredit > 0 && _creditWaiter != null) { int granted = Math.Min(_availableCredit, _creditWaiter.Amount); if (_creditWaiter.TrySetResult(granted)) @@ -1100,11 +1100,10 @@ private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationT { if (_creditWaiter is null) { - _creditWaiter = new CancelableCreditWaiter(SyncObject, _requestBodyCancellationSource.Token); + _creditWaiter = new CreditWaiter(_requestBodyCancellationSource.Token); } else { - Debug.Assert(!_creditWaiter.IsPending); _creditWaiter.ResetForAwait(_requestBodyCancellationSource.Token); } _creditWaiter.Amount = buffer.Length; @@ -1113,9 +1112,9 @@ private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationT if (sendSize == -1) { + // Logically this is part of the else block above, but we can't await while holding the lock. Debug.Assert(_creditWaiter != null); sendSize = await _creditWaiter.AsValueTask().ConfigureAwait(false); - _creditWaiter.CleanUp(); } ReadOnlyMemory current; diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs index 91bee1c33866..6bf834b8ef97 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs @@ -198,8 +198,7 @@ private static void MapRoutes(IEndpointRouteBuilder endpoints) }); endpoints.MapGet("/variables", async context => { - string queryString = context.Request.QueryString.Value; - NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(queryString); + NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(context.Request.QueryString.Value!); StringBuilder sb = new StringBuilder(); for (int i = 0; i < nameValueCollection.Count; i++) From 21ea59f90044f4f662117fc43022f07eafb485cd Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 4 Aug 2020 16:57:14 +0200 Subject: [PATCH 237/755] [browser][io] Workaround for issue MoveDirectory (#40310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [browser][io] Workaround for issue MoveDirectory - Issue workaround while waiting for emscripten fix. https://github.com/dotnet/runtime/issues/40305 - The following code checks for the existence of the source and destination directories which replaces the same code in the emscripten code. emscripten tracking issue: https://github.com/emscripten-core/emscripten/issues/11804 * Update src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs Co-authored-by: Alexander Köplinger Co-authored-by: Alexander Köplinger --- .../src/System/IO/FileSystem.Unix.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs index cb39fcb7e030..df790a51b8d9 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs @@ -381,6 +381,19 @@ public static void MoveDirectory(string sourceFullPath, string destFullPath) throw new IOException(SR.Format(SR.IO_AlreadyExists_Name, destFullPath)); } +#if TARGET_BROWSER + // renaming a file doesn't return correct error code on emscripten if one of the parent paths does not exist, + // manually workaround it for now (https://github.com/dotnet/runtime/issues/40305) + if (!Directory.Exists(Path.GetDirectoryName(sourceFullPath))) + { + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath)); + } + if (!Directory.Exists(Path.GetDirectoryName(destFullPath))) + { + throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destFullPath)); + } +#endif + if (Interop.Sys.Rename(sourceFullPath, destFullPath) < 0) { Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); From e2d3fd4cffe10afb4b509e7e45774f83a2c36b93 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 4 Aug 2020 11:50:39 -0500 Subject: [PATCH 238/755] Normalize array magic numbers and remove switch (#40279) --- src/mono/wasm/runtime/binding_support.js | 25 +++--------------------- src/mono/wasm/runtime/corebindings.c | 5 +++-- src/mono/wasm/runtime/driver.c | 5 +++-- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index bdef5f6ac5dc..d3dd31e8c723 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -226,7 +226,7 @@ var BindingSupportLib = { return enumValue; - + case 10: // arrays case 11: case 12: case 13: @@ -361,26 +361,7 @@ var BindingSupportLib = { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays if (!!(js_obj.buffer instanceof ArrayBuffer && js_obj.BYTES_PER_ELEMENT)) { - var arrayType = 0; - if (js_obj instanceof Int8Array) - arrayType = 11; - if (js_obj instanceof Uint8Array) - arrayType = 12; - if (js_obj instanceof Uint8ClampedArray) - arrayType = 12; - if (js_obj instanceof Int16Array) - arrayType = 13; - if (js_obj instanceof Uint16Array) - arrayType = 14; - if (js_obj instanceof Int32Array) - arrayType = 15; - if (js_obj instanceof Uint32Array) - arrayType = 16; - if (js_obj instanceof Float32Array) - arrayType = 17; - if (js_obj instanceof Float64Array) - arrayType = 18; - + var arrayType = js_obj[Symbol.for("wasm type")]; var heapBytes = this.js_typedarray_to_heap(js_obj); var bufferArray = this.mono_typed_array_new(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType); Module._free(heapBytes.byteOffset); @@ -516,7 +497,7 @@ var BindingSupportLib = { this.typedarray_copy_from(newTypedArray, pinned_array, begin, end, bytes_per_element); return newTypedArray; - }, + }, js_to_mono_enum: function (method, parmIdx, js_obj) { this.bindings_lazy_init (); diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index ce7c73851aa2..a0263c2a8ba9 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -98,8 +98,9 @@ void core_initialize_internals () // Float32Array | float | float // Float64Array | double | double // typed array marshalling -#define MARSHAL_ARRAY_BYTE 11 -#define MARSHAL_ARRAY_UBYTE 12 +#define MARSHAL_ARRAY_BYTE 10 +#define MARSHAL_ARRAY_UBYTE 11 +#define MARSHAL_ARRAY_UBYTE_C 12 // alias of MARSHAL_ARRAY_UBYTE #define MARSHAL_ARRAY_SHORT 13 #define MARSHAL_ARRAY_USHORT 14 #define MARSHAL_ARRAY_INT 15 diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 32de5d807035..2cadc3bfffed 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -568,8 +568,9 @@ MonoClass* mono_get_uri_class(MonoException** exc) #define MARSHAL_TYPE_SAFEHANDLE 23 // typed array marshalling -#define MARSHAL_ARRAY_BYTE 11 -#define MARSHAL_ARRAY_UBYTE 12 +#define MARSHAL_ARRAY_BYTE 10 +#define MARSHAL_ARRAY_UBYTE 11 +#define MARSHAL_ARRAY_UBYTE_C 12 #define MARSHAL_ARRAY_SHORT 13 #define MARSHAL_ARRAY_USHORT 14 #define MARSHAL_ARRAY_INT 15 From a512ac4b7991ebda693069a5dd718384f05f378b Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 4 Aug 2020 13:06:36 -0400 Subject: [PATCH 239/755] [runtime] Handle null byref returns in runtime invokes. (#40071) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [runtime] Handle null byref returns in runtime invokes. Fixes https://github.com/dotnet/runtime/issues/39380. * Reenable fixed test Co-authored-by: Alexander Köplinger --- .../tests/System/Reflection/InvokeRefReturn.cs | 1 - src/mono/mono/metadata/object.c | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.cs b/src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.cs index ee28dd51c2e3..885e17992c17 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.cs @@ -59,7 +59,6 @@ public static unsafe void TestRefReturnOfPointer() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39380", TestPlatforms.Browser)] public static unsafe void TestNullRefReturnOfPointer() { TestClassIntPointer tc = new TestClassIntPointer(null); diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 71e7377e7982..5f0baa667721 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -5737,8 +5737,13 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params, mono_error_assert_ok (error); MONO_STATIC_POINTER_INIT_END (MonoMethod, box_method) - g_assert (res->vtable->klass == mono_defaults.int_class); - box_args [0] = ((MonoIntPtr*)res)->m_value; + if (res) { + g_assert (res->vtable->klass == mono_defaults.int_class); + box_args [0] = ((MonoIntPtr*)res)->m_value; + } else { + g_assert (sig->ret->byref); + box_args [0] = NULL; + } if (sig->ret->byref) { // byref is already unboxed by the invoke code MonoType *tmpret = mono_metadata_type_dup (NULL, sig->ret); From e00452af834afcbb3bce3d904e2c8ca6f36d0916 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 4 Aug 2020 12:09:27 -0500 Subject: [PATCH 240/755] Fix logger output. (#40291) --- src/mono/wasm/runtime/driver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 2cadc3bfffed..fec72602ed36 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -109,11 +109,11 @@ static void wasm_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { EM_ASM({ - var message = $1; + var message = Module.UTF8ToString ($3) + ": " + Module.UTF8ToString ($1); if ($2) console.trace (message); - switch ($0) { + switch (Module.UTF8ToString ($0)) { case "critical": case "error": console.error (message); @@ -130,8 +130,11 @@ wasm_logger (const char *log_domain, const char *log_level, const char *message, case "debug": console.debug (message); break; + default: + console.log (message); + break; } - },log_level, message, fatal); + }, log_level, message, fatal, log_domain); } #ifdef DRIVER_GEN From 664d9f8661bee9a504e600f2ceae1b09181c8038 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 4 Aug 2020 10:28:04 -0700 Subject: [PATCH 241/755] cleanup schannel pal (#39755) * cleanup schannel pal * fix netfx --- .../Windows/Crypt32/Interop.CERT_INFO.cs | 5 ++- .../Crypt32/Interop.certificates_types.cs | 10 ------ .../Interop/Windows/SspiCli/ISSPIInterface.cs | 2 +- .../Interop/Windows/SspiCli/Interop.SSPI.cs | 17 +++------- .../Interop/Windows/SspiCli/SSPIAuthType.cs | 4 +-- .../Windows/SspiCli/SSPISecureChannelType.cs | 4 +-- .../Interop/Windows/SspiCli/SSPIWrapper.cs | 4 +-- .../Windows/SspiCli/SecuritySafeHandles.cs | 24 +++----------- .../src/System.Net.Http.WinHttpHandler.csproj | 14 ++++++++ .../tests/UnitTests/FakeInterop.cs | 29 ++++++++++++++++ .../tests/UnitTests/FakeX509Certificates.cs | 19 +++++++++++ ....Net.Http.WinHttpHandler.Unit.Tests.csproj | 4 --- .../src/System.Net.Http.csproj | 30 +++++++++-------- .../System.Net.Http.Unit.Tests.csproj | 4 --- .../src/System.Net.HttpListener.csproj | 22 +++++++++---- .../src/System.Net.Mail.csproj | 22 +++++++++---- .../Unit/System.Net.Mail.Unit.Tests.csproj | 20 ++++++++--- .../src/System.Net.Security.csproj | 16 +++++++-- .../Net/Security/SslStreamPal.Windows.cs | 33 +++++++++---------- 19 files changed, 173 insertions(+), 110 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_INFO.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_INFO.cs index 26efa43871aa..21f010177ac1 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_INFO.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_INFO.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; internal static partial class Interop { @@ -16,8 +15,8 @@ internal struct CERT_INFO internal DATA_BLOB SerialNumber; internal CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; internal DATA_BLOB Issuer; - internal FILETIME NotBefore; - internal FILETIME NotAfter; + internal System.Runtime.InteropServices.ComTypes.FILETIME NotBefore; + internal System.Runtime.InteropServices.ComTypes.FILETIME NotAfter; internal DATA_BLOB Subject; internal CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; internal CRYPT_BIT_BLOB IssuerUniqueId; diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs index 3a5d9d31baf8..2fa029d9d8f3 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs @@ -86,16 +86,6 @@ internal static partial class CertChainPolicyErrors internal const uint CERT_E_ROLE = 0x800B0103; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct CERT_CONTEXT - { - internal uint dwCertEncodingType; - internal IntPtr pbCertEncoded; - internal uint cbCertEncoded; - internal IntPtr pCertInfo; - internal IntPtr hCertStore; - } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal unsafe struct SSL_EXTRA_CERT_CHAIN_POLICY_PARA { diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/ISSPIInterface.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/ISSPIInterface.cs index 62daefd267e7..7260037a70fd 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/ISSPIInterface.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/ISSPIInterface.cs @@ -13,7 +13,7 @@ internal interface ISSPIInterface SecurityPackageInfoClass[]? SecurityPackages { get; set; } int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer pkgArray); int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential); - int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential); + unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCHANNEL_CRED* authdata, out SafeFreeCredentials outCredential); unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential); int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential); int AcceptSecurityContext(SafeFreeCredentials? credential, ref SafeDeleteSslContext? context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags); diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/Interop.SSPI.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/Interop.SSPI.cs index 9556c5054533..93998b37ee70 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/Interop.SSPI.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/Interop.SSPI.cs @@ -172,21 +172,14 @@ internal unsafe struct SecPkgContext_IssuerListInfoEx } [StructLayout(LayoutKind.Sequential)] - internal struct SCHANNEL_CRED + internal unsafe struct SCHANNEL_CRED { public const int CurrentVersion = 0x4; public int dwVersion; public int cCreds; - // ptr to an array of pointers - // There is a hack done with this field. AcquireCredentialsHandle requires an array of - // certificate handles; we only ever use one. In order to avoid pinning a one element array, - // we copy this value onto the stack, create a pointer on the stack to the copied value, - // and replace this field with the pointer, during the call to AcquireCredentialsHandle. - // Then we fix it up afterwards. Fine as long as all the SSPI credentials are not - // supposed to be threadsafe. - public IntPtr paCred; + public Crypt32.CERT_CONTEXT** paCred; public IntPtr hRootStore; // == always null, OTHERWISE NOT RELIABLE public int cMappers; @@ -223,9 +216,7 @@ internal unsafe struct SCH_CREDENTIALS public int dwCredformat; public int cCreds; - // This is pointer to arry of CERT_CONTEXT* - // We do not use it directly in .NET. Instead, we wrap returned OS pointer in safe handle. - public void* paCred; + public Crypt32.CERT_CONTEXT** paCred; public IntPtr hRootStore; // == always null, OTHERWISE NOT RELIABLE public int cMappers; @@ -423,7 +414,7 @@ internal static extern unsafe int AcquireCredentialsHandleW( [In] string moduleName, [In] int usage, [In] void* logonID, - [In] ref SCHANNEL_CRED authData, + [In] SCHANNEL_CRED* authData, [In] void* keyCallback, [In] void* keyArgument, ref CredHandle handlePtr, diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIAuthType.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIAuthType.cs index 7d359791a0fe..415ef9d9f7a2 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIAuthType.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIAuthType.cs @@ -40,9 +40,9 @@ public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.Credentia return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential) + public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCHANNEL_CRED* authdata, out SafeFreeCredentials outCredential) { - return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); + return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, authdata, out outCredential); } public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential) diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPISecureChannelType.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPISecureChannelType.cs index e30e53d27262..fb1d93d356d6 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPISecureChannelType.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPISecureChannelType.cs @@ -40,9 +40,9 @@ public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.Credentia return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential) + public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCHANNEL_CRED* authdata, out SafeFreeCredentials outCredential) { - return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); + return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, authdata, out outCredential); } public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential) diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs index eaf912697a91..57ce62329432 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs @@ -108,12 +108,12 @@ public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secMod return credentialsHandle; } - public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SCHANNEL_CRED scc) + public static unsafe SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SCHANNEL_CRED* scc) { int errorCode = secModule.AcquireCredentialsHandle( package, intent, - ref scc, + scc, out SafeFreeCredentials outCredential); if (errorCode != 0) diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs index 40ef8b2c8811..19d5a6a4836c 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs @@ -257,40 +257,24 @@ public static unsafe int AcquireCredentialsHandle( public static unsafe int AcquireCredentialsHandle( string package, Interop.SspiCli.CredentialUse intent, - ref Interop.SspiCli.SCHANNEL_CRED authdata, + Interop.SspiCli.SCHANNEL_CRED* authdata, out SafeFreeCredentials outCredential) { int errorCode = -1; long timeStamp; - // If there is a certificate, wrap it into an array. - // Not threadsafe. - IntPtr copiedPtr = authdata.paCred; - try - { - IntPtr certArrayPtr = new IntPtr(&copiedPtr); - if (copiedPtr != IntPtr.Zero) - { - authdata.paCred = certArrayPtr; - } - - outCredential = new SafeFreeCredential_SECURITY(); + outCredential = new SafeFreeCredential_SECURITY(); - errorCode = Interop.SspiCli.AcquireCredentialsHandleW( + errorCode = Interop.SspiCli.AcquireCredentialsHandleW( null, package, (int)intent, null, - ref authdata, + authdata, null, null, ref outCredential._handle, out timeStamp); - } - finally - { - authdata.paCred = copiedPtr; - } if (NetEventSource.Log.IsEnabled()) NetEventSource.Verbose(null, $"{nameof(Interop.SspiCli.AcquireCredentialsHandleW)} returns 0x{errorCode:x}, handle = {outCredential}"); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index e29dc793e5e5..71f4b005c6b4 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -15,6 +15,20 @@ + + + + + + + - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + - - - + + + + + + + + - - + + + + + + + + + + + + + + + - Date: Tue, 4 Aug 2020 11:04:05 -0700 Subject: [PATCH 242/755] Minimum CMake downgrade for Linux (#39044) Co-authored-by: Santiago Fernandez Madero Co-authored-by: Jan Vorlicek --- eng/native/build-commons.sh | 9 +-- eng/native/configurecompiler.cmake | 78 +++++++++++-------- eng/native/configureplatform.cmake | 22 +----- eng/native/functions.cmake | 28 ++++++- eng/native/gen-buildsys.sh | 8 +- src/coreclr/CMakeLists.txt | 2 +- src/coreclr/pgosupport.cmake | 17 +++- .../ToolBox/SOS/DacTableGen/CMakeLists.txt | 1 + src/coreclr/src/binder/CMakeLists.txt | 6 +- .../src/classlibnative/bcltype/CMakeLists.txt | 6 +- .../src/classlibnative/float/CMakeLists.txt | 7 +- .../src/debug/debug-pal/CMakeLists.txt | 4 +- src/coreclr/src/debug/ee/wks/CMakeLists.txt | 14 ++-- .../src/debug/ildbsymlib/CMakeLists.txt | 5 +- .../src/dlls/mscoree/coreclr/CMakeLists.txt | 18 +++-- src/coreclr/src/dlls/mscorrc/CMakeLists.txt | 4 +- src/coreclr/src/gcinfo/CMakeLists.txt | 5 +- src/coreclr/src/inc/CMakeLists.txt | 5 +- src/coreclr/src/interop/CMakeLists.txt | 5 +- src/coreclr/src/jit/static/CMakeLists.txt | 9 ++- src/coreclr/src/md/ceefilegen/CMakeLists.txt | 7 +- src/coreclr/src/md/compiler/CMakeLists.txt | 8 +- src/coreclr/src/md/enc/CMakeLists.txt | 8 +- src/coreclr/src/md/hotdata/CMakeLists.txt | 6 +- src/coreclr/src/md/runtime/CMakeLists.txt | 8 +- src/coreclr/src/pal/src/CMakeLists.txt | 4 +- .../dummyprovider/CMakeLists.txt | 4 +- .../lttngprovider/CMakeLists.txt | 4 +- .../palsuite/eventprovider/CMakeLists.txt | 4 +- src/coreclr/src/unwinder/CMakeLists.txt | 6 +- src/coreclr/src/utilcode/CMakeLists.txt | 12 +-- src/coreclr/src/vm/CMakeLists.txt | 2 +- src/coreclr/src/vm/eventing/CMakeLists.txt | 5 +- .../vm/eventing/EtwProvider/CMakeLists.txt | 4 +- .../src/vm/eventing/eventpipe/CMakeLists.txt | 16 ++-- src/coreclr/src/vm/wks/CMakeLists.txt | 27 ++++--- src/installer/corehost/CMakeLists.txt | 2 +- .../cli/apphost/static/CMakeLists.txt | 4 +- src/installer/corehost/cli/exe.cmake | 1 - .../cli/fxr/standalone/CMakeLists.txt | 3 +- .../cli/test/mockhostfxr/CMakeLists.txt | 1 - src/libraries/Native/Unix/CMakeLists.txt | 16 ++-- .../CMakeLists.txt | 7 +- src/tests/CMakeLists.txt | 2 +- 44 files changed, 249 insertions(+), 165 deletions(-) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index b976f5fdc6cf..e5bec2b3b8ce 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -48,11 +48,6 @@ check_prereqs() { echo "Checking prerequisites..." - if ! cmake --help 2>&1 | grep -q \\-B; then - echo "Please install cmake v3.14.5 or newer from https://www.cmake.org/download/." - exit 1 - fi - if [[ "$__HostOS" == "OSX" ]]; then # Check presence of pkg-config on the path command -v pkg-config 2>/dev/null || { echo >&2 "Please install pkg-config before running this script, see https://github.com/dotnet/runtime/blob/master/docs/workflow/requirements/macos-requirements.md"; exit 1; } @@ -177,8 +172,8 @@ EOF cmake_command="emcmake $cmake_command" fi - echo "Executing $cmake_command --build \"$intermediatesDir\" --target install -j $__NumProc" - $cmake_command --build "$intermediatesDir" --target install -j "$__NumProc" + echo "Executing $cmake_command --build \"$intermediatesDir\" --target install -- -j $__NumProc" + $cmake_command --build "$intermediatesDir" --target install -- -j "$__NumProc" fi local exit_code="$?" diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 51a58fc06f61..02611fa19272 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -8,8 +8,6 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) -cmake_policy(SET CMP0083 NEW) - include(CheckCXXCompilerFlag) # "configureoptimization.cmake" must be included after CLR_CMAKE_HOST_UNIX has been set. @@ -38,11 +36,18 @@ set(CMAKE_CXX_FLAGS_CHECKED "") set(CMAKE_EXE_LINKER_FLAGS_CHECKED "") set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "") +set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "") +set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "") +set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "") + add_compile_definitions("$<$,$>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Checked;BUILDENV_CHECKED=1>") add_compile_definitions("$<$,$>:NDEBUG;URTBLDENV_FRIENDLY=Retail>") if (MSVC) - add_link_options(/GUARD:CF) + add_linker_flag(/GUARD:CF) # Linker flags # @@ -55,48 +60,51 @@ if (MSVC) endif () #Do not create Side-by-Side Assembly Manifest - add_link_options($<$,SHARED_LIBRARY>:/MANIFEST:NO>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO") # can handle addresses larger than 2 gigabytes - add_link_options($<$,SHARED_LIBRARY>:/LARGEADDRESSAWARE>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE") #Compatible with Data Execution Prevention - add_link_options($<$,SHARED_LIBRARY>:/NXCOMPAT>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NXCOMPAT") #Use address space layout randomization - add_link_options($<$,SHARED_LIBRARY>:/DYNAMICBASE>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DYNAMICBASE") #shrink pdb size - add_link_options($<$,SHARED_LIBRARY>:/PDBCOMPRESS>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /PDBCOMPRESS") - add_link_options($<$,SHARED_LIBRARY>:/DEBUG>) - add_link_options($<$,SHARED_LIBRARY>:/IGNORE:4197,4013,4254,4070,4221>) - add_link_options($<$,SHARED_LIBRARY>:/SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}>) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4197,4013,4254,4070,4221") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}") set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221") - add_link_options($<$,EXECUTABLE>:/DEBUG>) - add_link_options($<$,EXECUTABLE>:/PDBCOMPRESS>) - add_link_options($<$,EXECUTABLE>:/STACK:1572864>) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /PDBCOMPRESS") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1572864") # Debug build specific flags - add_link_options($<$,$>,$,SHARED_LIBRARY>>:/NOVCFEATURE>) + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NOVCFEATURE") + set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "${CMAKE_SHARED_LINKER_FLAGS_CHECKED} /NOVCFEATURE") # Checked build specific flags - add_link_options($<$:/INCREMENTAL:NO>) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification" - add_link_options($<$:/OPT:REF>) - add_link_options($<$:/OPT:NOICF>) + add_linker_flag(/INCREMENTAL:NO CHECKED) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification" + add_linker_flag(/OPT:REF CHECKED) + add_linker_flag(/OPT:NOICF CHECKED) # Release build specific flags - add_link_options($<$:/LTCG>) - add_link_options($<$:/OPT:REF>) - add_link_options($<$:/OPT:ICF>) + add_linker_flag(/LTCG RELEASE) + add_linker_flag(/OPT:REF RELEASE) + add_linker_flag(/OPT:ICF RELEASE) + add_linker_flag(/INCREMENTAL:NO RELEASE) set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG") # ReleaseWithDebugInfo build specific flags - add_link_options($<$:/LTCG>) - add_link_options($<$:/OPT:REF>) - add_link_options($<$:/OPT:ICF>) + add_linker_flag(/LTCG RELWITHDEBINFO) + add_linker_flag(/OPT:REF RELWITHDEBINFO) + add_linker_flag(/OPT:ICF RELWITHDEBINFO) set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") # Force uCRT to be dynamically linked for Release build - add_link_options("$<$:/NODEFAULTLIB:libucrt.lib;/DEFAULTLIB:ucrt.lib>") + add_linker_flag(/NODEFAULTLIB:libucrt.lib RELEASE) + add_linker_flag(/DEFAULTLIB:ucrt.lib RELEASE) elseif (CLR_CMAKE_HOST_UNIX) # Set the values to display when interactively configuring CMAKE_BUILD_TYPE @@ -155,11 +163,10 @@ elseif (CLR_CMAKE_HOST_UNIX) # -fdata-sections -ffunction-sections: each function has own section instead of one per .o file (needed for --gc-sections) # -O1: optimization level used instead of -O0 to avoid compile error "invalid operand for inline asm constraint" - add_compile_definitions("$<$,$>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>") - add_link_options($<$,$>,$,EXECUTABLE>>:${CLR_SANITIZE_LINK_OPTIONS}>) - + add_compile_options("$<$,$>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>") + add_linker_flag("${CLR_SANITIZE_LINK_OPTIONS}" DEBUG CHECKED) # -Wl and --gc-sections: drop unused sections\functions (similar to Windows /Gy function-level-linking) - add_link_options("$<$,$>,$,SHARED_LIBRARY>>:${CLR_SANITIZE_LINK_OPTIONS};-Wl,--gc-sections>") + add_linker_flag("-Wl,--gc-sections" DEBUG CHECKED) endif () endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED) endif(MSVC) @@ -171,15 +178,18 @@ endif(MSVC) # ./build-native.sh cmakeargs "-DCLR_ADDITIONAL_COMPILER_OPTIONS=<...>" cmakeargs "-DCLR_ADDITIONAL_LINKER_FLAGS=<...>" # if(CLR_CMAKE_HOST_UNIX) - add_link_options(${CLR_ADDITIONAL_LINKER_FLAGS}) + foreach(ADDTL_LINKER_FLAG ${CLR_ADDITIONAL_LINKER_FLAGS}) + add_linker_flag(${ADDTL_LINKER_FLAG}) + endforeach() endif(CLR_CMAKE_HOST_UNIX) if(CLR_CMAKE_HOST_LINUX) add_compile_options($<$:-Wa,--noexecstack>) - add_link_options(-Wl,--build-id=sha1 -Wl,-z,relro,-z,now) + add_linker_flag(-Wl,--build-id=sha1) + add_linker_flag(-Wl,-z,relro,-z,now) elseif(CLR_CMAKE_HOST_FREEBSD) add_compile_options($<$:-Wa,--noexecstack>) - add_link_options(LINKER:--build-id=sha1) + add_linker_flag("-Wl,--build-id=sha1") elseif(CLR_CMAKE_HOST_SUNOS) add_compile_options($<$:-Wa,--noexecstack>) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector") @@ -359,7 +369,7 @@ if (CLR_CMAKE_HOST_UNIX) if(CLR_CMAKE_HOST_OSX) set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.12) add_compile_options(${MACOS_VERSION_MIN_FLAGS}) - add_link_options(${MACOS_VERSION_MIN_FLAGS}) + add_linker_flag(${MACOS_VERSION_MIN_FLAGS}) endif(CLR_CMAKE_HOST_OSX) endif(CLR_CMAKE_HOST_UNIX) @@ -510,7 +520,7 @@ if(CLR_CMAKE_ENABLE_CODE_COVERAGE) add_compile_options(-fprofile-arcs) add_compile_options(-ftest-coverage) - add_link_options(--coverage) + add_linker_flag(--coverage) else() message(FATAL_ERROR "Code coverage builds not supported on current platform") endif(CLR_CMAKE_HOST_UNIX) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index c65274141dd4..dbfadfda5991 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -1,4 +1,3 @@ -include(CheckPIESupported) include(${CMAKE_CURRENT_LIST_DIR}/functions.cmake) # If set, indicates that this is not an officially supported release @@ -382,24 +381,11 @@ else() endif() if(NOT CLR_CMAKE_TARGET_BROWSER) - # Skip check_pie_supported call on Android as ld from llvm toolchain with NDK API level 21 - # complains about missing linker flag `-no-pie` (while level 28's ld does support this flag, - # but since we know that PIE is supported, we can safely skip this redundant check). - # # The default linker on Solaris also does not support PIE. - if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS) - # All code we build should be compiled as position independent - get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) - if("CXX" IN_LIST languages) - set(CLR_PIE_LANGUAGE CXX) - else() - set(CLR_PIE_LANGUAGE C) - endif() - check_pie_supported(OUTPUT_VARIABLE PIE_SUPPORT_OUTPUT LANGUAGES ${CLR_PIE_LANGUAGE}) - if(NOT MSVC AND NOT CMAKE_${CLR_PIE_LANGUAGE}_LINK_PIE_SUPPORTED) - message(WARNING "PIE is not supported at link time: ${PIE_SUPPORT_OUTPUT}.\n" - "PIE link options will not be passed to linker.") - endif() + if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS AND NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_HOST_TVOS AND NOT CLR_CMAKE_HOST_IOS AND NOT MSVC) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") + add_compile_options($<$,EXECUTABLE>:-fPIE>) + add_compile_options($<$,SHARED_LIBRARY>:-fPIC>) endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake index 8b73581ed142..1509a17fa59b 100644 --- a/eng/native/functions.cmake +++ b/eng/native/functions.cmake @@ -148,7 +148,7 @@ function(preprocess_compile_asm) set(options "") set(oneValueArgs TARGET OUTPUT_OBJECTS) set(multiValueArgs ASM_FILES) - cmake_parse_arguments(PARSE_ARGV 0 COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}") + cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) get_include_directories_asm(ASM_INCLUDE_DIRECTORIES) @@ -241,7 +241,7 @@ function(target_precompile_header) set(options "") set(oneValueArgs TARGET HEADER) set(multiValueArgs ADDITIONAL_INCLUDE_DIRECTORIES) - cmake_parse_arguments(PARSE_ARGV 0 PRECOMPILE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}") + cmake_parse_arguments(PRECOMPILE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) if ("${PRECOMPILE_HEADERS_TARGET}" STREQUAL "") message(SEND_ERROR "No target supplied to target_precompile_header.") @@ -360,7 +360,7 @@ endfunction() function(install_clr) set(oneValueArgs ADDITIONAL_DESTINATION) set(multiValueArgs TARGETS) - cmake_parse_arguments(PARSE_ARGV 0 INSTALL_CLR "${options}" "${oneValueArgs}" "${multiValueArgs}") + cmake_parse_arguments(INSTALL_CLR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) if ("${INSTALL_CLR_TARGETS}" STREQUAL "") message(FATAL_ERROR "At least one target must be passed to install_clr(TARGETS )") @@ -416,6 +416,15 @@ function(disable_pax_mprotect targetName) endif() endfunction() +if (CMAKE_VERSION VERSION_LESS "3.12") + # Polyfill add_compile_definitions when it is unavailable + function(add_compile_definitions) + get_directory_property(DIR_COMPILE_DEFINITIONS COMPILE_DEFINITIONS) + list(APPEND DIR_COMPILE_DEFINITIONS ${ARGV}) + set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "${DIR_COMPILE_DEFINITIONS}") + endfunction() +endif() + function(_add_executable) if(NOT WIN32) add_executable(${ARGV} ${VERSION_FILE_PATH}) @@ -479,3 +488,16 @@ function(generate_module_index Target ModuleIndexFile) DEPENDS ${ModuleIndexFile} ) endfunction(generate_module_index) + +# add_linker_flag(Flag [Config1 Config2 ...]) +function(add_linker_flag Flag) + if (ARGN STREQUAL "") + set("CMAKE_EXE_LINKER_FLAGS" "${CMAKE_EXE_LINKER_FLAGS} ${Flag}" PARENT_SCOPE) + set("CMAKE_SHARED_LINKER_FLAGS" "${CMAKE_SHARED_LINKER_FLAGS} ${Flag}" PARENT_SCOPE) + else() + foreach(Config ${ARGN}) + set("CMAKE_EXE_LINKER_FLAGS_${Config}" "${CMAKE_EXE_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE) + set("CMAKE_SHARED_LINKER_FLAGS_${Config}" "${CMAKE_SHARED_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE) + endforeach() + endif() +endfunction() diff --git a/eng/native/gen-buildsys.sh b/eng/native/gen-buildsys.sh index f27bb33e3577..1b4c2e02c597 100755 --- a/eng/native/gen-buildsys.sh +++ b/eng/native/gen-buildsys.sh @@ -91,6 +91,9 @@ if [[ "$build_arch" == "wasm" ]]; then cmake_command="emcmake $cmake_command" fi +# We have to be able to build with CMake 3.6.2, so we can't use the -S or -B options +pushd "$3" + # Include CMAKE_USER_MAKE_RULES_OVERRIDE as uninitialized since it will hold its value in the CMake cache otherwise can cause issues when branch switching $cmake_command \ -G "$generator" \ @@ -98,5 +101,6 @@ $cmake_command \ "-DCMAKE_INSTALL_PREFIX=$__CMakeBinDir" \ $cmake_extra_defines \ $__UnprocessedCMakeArgs \ - -S "$1" \ - -B "$3" + "$1" + +popd diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index 0d60cf16fc10..b94eb54a6715 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14.5) +cmake_minimum_required(VERSION 3.6.2) cmake_policy(SET CMP0042 NEW) diff --git a/src/coreclr/pgosupport.cmake b/src/coreclr/pgosupport.cmake index 4b1198090171..04bde2bc20bc 100644 --- a/src/coreclr/pgosupport.cmake +++ b/src/coreclr/pgosupport.cmake @@ -1,5 +1,18 @@ -include(CheckIPOSupported) -check_ipo_supported(RESULT HAVE_LTO) +include(CheckCXXSourceCompiles) +include(CheckCXXCompilerFlag) + +# VC++ guarantees support for LTCG (LTO's equivalent) +if(NOT WIN32) + # Function required to give CMAKE_REQUIRED_* local scope + function(check_have_lto) + set(CMAKE_REQUIRED_FLAGS -flto) + set(CMAKE_REQUIRED_LIBRARIES -flto -fuse-ld=gold) + check_cxx_source_compiles("int main() { return 0; }" HAVE_LTO) + endfunction(check_have_lto) + check_have_lto() + + check_cxx_compiler_flag(-faligned-new COMPILER_SUPPORTS_F_ALIGNED_NEW) +endif(NOT WIN32) # Adds Profile Guided Optimization (PGO) flags to the current target function(add_pgo TargetName) diff --git a/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt b/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt index e3fc3ed9e3a5..98cc178b8a30 100644 --- a/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt +++ b/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.8) # Quick note: The CMake C# support is using the CSC bundled with the MSBuild that the native build runs on, not the one supplied by the local .NET SDK. project(DacTableGen LANGUAGES CSharp) diff --git a/src/coreclr/src/binder/CMakeLists.txt b/src/coreclr/src/binder/CMakeLists.txt index 9c242ed1518d..208f1214dd0d 100644 --- a/src/coreclr/src/binder/CMakeLists.txt +++ b/src/coreclr/src/binder/CMakeLists.txt @@ -82,11 +82,13 @@ endif(CLR_CMAKE_TARGET_WIN32) convert_to_absolute_path(BINDER_SOURCES ${BINDER_SOURCES}) convert_to_absolute_path(BINDER_CROSSGEN_SOURCES ${BINDER_CROSSGEN_SOURCES}) -add_library_clr(v3binder +add_library_clr(v3binder_obj OBJECT ${BINDER_SOURCES} ) -add_dependencies(v3binder eventing_headers) +add_dependencies(v3binder_obj eventing_headers) +add_library(v3binder INTERFACE) +target_sources(v3binder INTERFACE $) add_library_clr(v3binder_crossgen STATIC diff --git a/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt b/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt index c3122ec12ec3..fdcf344c16ac 100644 --- a/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt +++ b/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt @@ -10,9 +10,11 @@ set(BCLTYPE_SOURCES variant.cpp ) -add_library_clr(bcltype +add_library_clr(bcltype_obj OBJECT ${BCLTYPE_SOURCES} ) -add_dependencies(bcltype eventing_headers) +add_dependencies(bcltype_obj eventing_headers) +add_library(bcltype INTERFACE) +target_sources(bcltype INTERFACE $) diff --git a/src/coreclr/src/classlibnative/float/CMakeLists.txt b/src/coreclr/src/classlibnative/float/CMakeLists.txt index 2345ad0b9135..b2c47ea39b65 100644 --- a/src/coreclr/src/classlibnative/float/CMakeLists.txt +++ b/src/coreclr/src/classlibnative/float/CMakeLists.txt @@ -7,9 +7,12 @@ set(FLOAT_SOURCES floatsingle.cpp ) -add_library_clr(comfloat_wks +add_library_clr(comfloat_wks_obj OBJECT ${FLOAT_SOURCES} ) -add_dependencies(comfloat_wks eventing_headers) +add_dependencies(comfloat_wks_obj eventing_headers) + +add_library(comfloat_wks INTERFACE) +target_sources(comfloat_wks INTERFACE $) \ No newline at end of file diff --git a/src/coreclr/src/debug/debug-pal/CMakeLists.txt b/src/coreclr/src/debug/debug-pal/CMakeLists.txt index 12a0005c0532..213fa59e784c 100644 --- a/src/coreclr/src/debug/debug-pal/CMakeLists.txt +++ b/src/coreclr/src/debug/debug-pal/CMakeLists.txt @@ -34,4 +34,6 @@ if(CLR_CMAKE_HOST_UNIX) endif(CLR_CMAKE_HOST_UNIX) -_add_library(debug-pal OBJECT ${TWO_WAY_PIPE_SOURCES}) +_add_library(debug-pal_obj OBJECT ${TWO_WAY_PIPE_SOURCES}) +add_library(debug-pal INTERFACE) +target_sources(debug-pal INTERFACE $) diff --git a/src/coreclr/src/debug/ee/wks/CMakeLists.txt b/src/coreclr/src/debug/ee/wks/CMakeLists.txt index a6891ebb052c..3dd5e3612dfc 100644 --- a/src/coreclr/src/debug/ee/wks/CMakeLists.txt +++ b/src/coreclr/src/debug/ee/wks/CMakeLists.txt @@ -9,9 +9,9 @@ if (CLR_CMAKE_TARGET_WIN32) if(CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) - preprocess_compile_asm(TARGET cordbee_wks ASM_FILES ${ASM_FILE} OUTPUT_OBJECTS ASM_OBJECTS) + preprocess_compile_asm(TARGET cordbee_wks_obj ASM_FILES ${ASM_FILE} OUTPUT_OBJECTS ASM_OBJECTS) - add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE} ${ASM_OBJECTS}) + add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE} ${ASM_OBJECTS}) else () @@ -23,19 +23,21 @@ if (CLR_CMAKE_TARGET_WIN32) set_source_files_properties(${ASM_FILE} PROPERTIES COMPILE_OPTIONS "${ASM_OPTIONS}") - add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE}) + add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE}) endif() else () if(CLR_CMAKE_HOST_ARCH_AMD64 OR CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64 OR CLR_CMAKE_HOST_ARCH_I386) - add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S) + add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S) else() message(FATAL_ERROR "Unknown platform") endif() endif (CLR_CMAKE_TARGET_WIN32) -target_precompile_header(TARGET cordbee_wks HEADER stdafx.h) -add_dependencies(cordbee_wks eventing_headers) +target_precompile_header(TARGET cordbee_wks_obj HEADER stdafx.h) +add_dependencies(cordbee_wks_obj eventing_headers) +add_library(cordbee_wks INTERFACE) +target_sources(cordbee_wks INTERFACE $) diff --git a/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt b/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt index b5b249228d26..362da1f64830 100644 --- a/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt +++ b/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt @@ -10,5 +10,6 @@ set( ILDBSYMLIB_SOURCES symwrite.cpp ) -add_library_clr(ildbsymlib OBJECT ${ILDBSYMLIB_SOURCES}) - +add_library_clr(ildbsymlib_obj OBJECT ${ILDBSYMLIB_SOURCES}) +add_library(ildbsymlib INTERFACE) +target_sources(ildbsymlib INTERFACE $) diff --git a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt index f01133ce40ff..2a25b2119b36 100644 --- a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt @@ -10,17 +10,17 @@ if (CLR_CMAKE_HOST_WIN32) list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def) - add_link_options(/ENTRY:CoreDllMain) + add_linker_flag("/ENTRY:CoreDllMain") # Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the # invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page). - add_link_options(/INCREMENTAL:NO) + add_linker_flag("/INCREMENTAL:NO") # Delay load libraries required for WinRT as that is not supported on all platforms - add_link_options("/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll") + add_linker_flag("/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll") # Delay load version.dll so that we can specify how to search when loading it as it is not part of Windows' known DLLs - add_link_options("/DELAYLOAD:version.dll") + add_linker_flag("/DELAYLOAD:version.dll") # No library groups for Win32 set(START_LIBRARY_GROUP) @@ -33,7 +33,7 @@ else(CLR_CMAKE_HOST_WIN32) if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS) # This option is necessary to ensure that the overloaded delete operator defined inside # of the utilcode will be used instead of the standard library delete operator. - add_link_options("LINKER:-Bsymbolic") + add_linker_flag("-Wl,-Bsymbolic") # The following linked options can be inserted into the linker libraries list to # ensure proper resolving of circular references between a subset of the libraries. @@ -109,7 +109,7 @@ set(CORECLR_LIBRARIES ildbsymlib utilcode v3binder - System.Globalization.Native-Static + System.Globalization.Native-static interop ) @@ -168,8 +168,10 @@ if(FEATURE_MERGE_JIT_AND_ENGINE) set(CLRJIT_STATIC clrjit_static) endif(FEATURE_MERGE_JIT_AND_ENGINE) -target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks cee_wks_core) -target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable cee_wks_core) +target_sources(coreclr PUBLIC $) +target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks) +target_sources(coreclr_static PUBLIC $) +target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable) # Create the runtime module index header file containing the coreclr build id # for xplat and the timestamp/size on Windows. diff --git a/src/coreclr/src/dlls/mscorrc/CMakeLists.txt b/src/coreclr/src/dlls/mscorrc/CMakeLists.txt index ed5ee8876508..e114ec19cea6 100644 --- a/src/coreclr/src/dlls/mscorrc/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscorrc/CMakeLists.txt @@ -19,7 +19,9 @@ if(CLR_CMAKE_HOST_WIN32) else() build_resources(${CMAKE_CURRENT_SOURCE_DIR}/include.rc mscorrc TARGET_CPP_FILE) - add_library_clr(mscorrc OBJECT + add_library_clr(mscorrc_obj OBJECT ${TARGET_CPP_FILE} ) + add_library(mscorrc INTERFACE) + target_sources(mscorrc INTERFACE $) endif(CLR_CMAKE_HOST_WIN32) diff --git a/src/coreclr/src/gcinfo/CMakeLists.txt b/src/coreclr/src/gcinfo/CMakeLists.txt index 98801f1f7bc3..f40ff3deb83a 100644 --- a/src/coreclr/src/gcinfo/CMakeLists.txt +++ b/src/coreclr/src/gcinfo/CMakeLists.txt @@ -17,11 +17,14 @@ endif(CLR_CMAKE_TARGET_ARCH_I386) convert_to_absolute_path(GCINFO_SOURCES ${GCINFO_SOURCES}) -add_library_clr(gcinfo +add_library_clr(gcinfo_obj OBJECT ${GCINFO_SOURCES} ) +add_library(gcinfo INTERFACE) +target_sources(gcinfo INTERFACE $) + add_library_clr(gcinfo_crossgen STATIC ${GCINFO_SOURCES} diff --git a/src/coreclr/src/inc/CMakeLists.txt b/src/coreclr/src/inc/CMakeLists.txt index 817622012516..4f75d3a882d4 100644 --- a/src/coreclr/src/inc/CMakeLists.txt +++ b/src/coreclr/src/inc/CMakeLists.txt @@ -58,7 +58,9 @@ if(FEATURE_JIT_PITCHING) endif(FEATURE_JIT_PITCHING) # Compile *_i.cpp to lib -_add_library(corguids OBJECT ${CORGUIDS_SOURCES}) +_add_library(corguids_obj OBJECT ${CORGUIDS_SOURCES}) +add_library(corguids INTERFACE) +target_sources(corguids INTERFACE $) # Binplace the inc files for packaging later. @@ -75,4 +77,3 @@ _install (FILES cfi.h gcinfoencoder.h gcinfotypes.h DESTINATION inc) -_install (TARGETS corguids DESTINATION lib) diff --git a/src/coreclr/src/interop/CMakeLists.txt b/src/coreclr/src/interop/CMakeLists.txt index b8a0e769318d..1642f55a04da 100644 --- a/src/coreclr/src/interop/CMakeLists.txt +++ b/src/coreclr/src/interop/CMakeLists.txt @@ -30,7 +30,10 @@ endif(WIN32) convert_to_absolute_path(INTEROP_SOURCES ${INTEROP_SOURCES}) -add_library_clr(interop +add_library_clr(interop_obj OBJECT ${INTEROP_SOURCES} ) + +add_library(interop INTERFACE) +target_sources(interop INTERFACE $) \ No newline at end of file diff --git a/src/coreclr/src/jit/static/CMakeLists.txt b/src/coreclr/src/jit/static/CMakeLists.txt index b4e62c041cd4..01bdbf5a731f 100644 --- a/src/coreclr/src/jit/static/CMakeLists.txt +++ b/src/coreclr/src/jit/static/CMakeLists.txt @@ -2,14 +2,17 @@ project(ClrJit) set_source_files_properties(${JIT_EXPORTS_FILE} PROPERTIES GENERATED TRUE) -add_library_clr(clrjit_static +add_library_clr(clrjit_obj OBJECT ${JIT_CORE_SOURCES} ${JIT_ARCH_SOURCES} ) if(CLR_CMAKE_HOST_UNIX) - add_dependencies(clrjit_static coreclrpal gcinfo) + add_dependencies(clrjit_obj coreclrpal gcinfo) endif(CLR_CMAKE_HOST_UNIX) -target_precompile_header(TARGET clrjit_static HEADER jitpch.h ADDITIONAL_INCLUDE_DIRECTORIES ${JIT_SOURCE_DIR}) +target_precompile_header(TARGET clrjit_obj HEADER jitpch.h ADDITIONAL_INCLUDE_DIRECTORIES ${JIT_SOURCE_DIR}) + +add_library(clrjit_static INTERFACE) +target_sources(clrjit_static INTERFACE $) diff --git a/src/coreclr/src/md/ceefilegen/CMakeLists.txt b/src/coreclr/src/md/ceefilegen/CMakeLists.txt index 39864c71817f..fd0f8424d97f 100644 --- a/src/coreclr/src/md/ceefilegen/CMakeLists.txt +++ b/src/coreclr/src/md/ceefilegen/CMakeLists.txt @@ -25,8 +25,11 @@ if (CLR_CMAKE_TARGET_WIN32) list(APPEND CEEFILEGEN_SOURCES ${CEEFILEGEN_HEADERS}) endif (CLR_CMAKE_TARGET_WIN32) -add_library_clr(ceefgen +add_library_clr(ceefgen_obj OBJECT ${CEEFILEGEN_SOURCES} ) -target_precompile_header(TARGET ceefgen HEADER stdafx.h) +target_precompile_header(TARGET ceefgen_obj HEADER stdafx.h) + +add_library(ceefgen INTERFACE) +target_sources(ceefgen INTERFACE $) diff --git a/src/coreclr/src/md/compiler/CMakeLists.txt b/src/coreclr/src/md/compiler/CMakeLists.txt index 495fa4d70ca2..f32c80407c6a 100644 --- a/src/coreclr/src/md/compiler/CMakeLists.txt +++ b/src/coreclr/src/md/compiler/CMakeLists.txt @@ -68,9 +68,11 @@ add_library_clr(mdcompiler_dac ${MDCOMPILER_SOURCES}) set_target_properties(mdcompiler_dac PROPERTIES DAC_COMPONENT TRUE) target_precompile_header(TARGET mdcompiler_dac HEADER stdafx.h) -add_library_clr(mdcompiler_wks OBJECT ${MDCOMPILER_WKS_SOURCES}) -target_compile_definitions(mdcompiler_wks PRIVATE FEATURE_METADATA_EMIT_ALL) -target_precompile_header(TARGET mdcompiler_wks HEADER stdafx.h) +add_library_clr(mdcompiler_wks_obj OBJECT ${MDCOMPILER_WKS_SOURCES}) +target_compile_definitions(mdcompiler_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL) +target_precompile_header(TARGET mdcompiler_wks_obj HEADER stdafx.h) +add_library(mdcompiler_wks INTERFACE) +target_sources(mdcompiler_wks INTERFACE $) add_library_clr(mdcompiler-dbi ${MDCOMPILER_SOURCES}) set_target_properties(mdcompiler-dbi PROPERTIES DBI_COMPONENT TRUE) diff --git a/src/coreclr/src/md/enc/CMakeLists.txt b/src/coreclr/src/md/enc/CMakeLists.txt index 14ed0a267fae..e30c51b1e37c 100644 --- a/src/coreclr/src/md/enc/CMakeLists.txt +++ b/src/coreclr/src/md/enc/CMakeLists.txt @@ -52,9 +52,11 @@ add_library_clr(mdruntimerw_dac ${MDRUNTIMERW_SOURCES}) set_target_properties(mdruntimerw_dac PROPERTIES DAC_COMPONENT TRUE) target_precompile_header(TARGET mdruntimerw_dac HEADER stdafx.h) -add_library_clr(mdruntimerw_wks OBJECT ${MDRUNTIMERW_SOURCES}) -target_compile_definitions(mdruntimerw_wks PRIVATE FEATURE_METADATA_EMIT_ALL) -target_precompile_header(TARGET mdruntimerw_wks HEADER stdafx.h) +add_library_clr(mdruntimerw_wks_obj OBJECT ${MDRUNTIMERW_SOURCES}) +target_compile_definitions(mdruntimerw_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL) +target_precompile_header(TARGET mdruntimerw_wks_obj HEADER stdafx.h) +add_library(mdruntimerw_wks INTERFACE) +target_sources(mdruntimerw_wks INTERFACE $) add_library_clr(mdruntimerw-dbi ${MDRUNTIMERW_SOURCES}) set_target_properties(mdruntimerw-dbi PROPERTIES DBI_COMPONENT TRUE) diff --git a/src/coreclr/src/md/hotdata/CMakeLists.txt b/src/coreclr/src/md/hotdata/CMakeLists.txt index 03430e292c75..46381cf7dddd 100644 --- a/src/coreclr/src/md/hotdata/CMakeLists.txt +++ b/src/coreclr/src/md/hotdata/CMakeLists.txt @@ -33,8 +33,10 @@ add_library_clr(mdhotdata_dac ${MDHOTDATA_SOURCES}) set_target_properties(mdhotdata_dac PROPERTIES DAC_COMPONENT TRUE) target_precompile_header(TARGET mdhotdata_dac HEADER external.h) -add_library_clr(mdhotdata_full OBJECT ${MDHOTDATA_SOURCES}) -target_precompile_header(TARGET mdhotdata_full HEADER external.h) +add_library_clr(mdhotdata_full_obj OBJECT ${MDHOTDATA_SOURCES}) +target_precompile_header(TARGET mdhotdata_full_obj HEADER external.h) +add_library(mdhotdata_full INTERFACE) +target_sources(mdhotdata_full INTERFACE $) add_library_clr(mdhotdata_crossgen ${MDHOTDATA_SOURCES}) set_target_properties(mdhotdata_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE) diff --git a/src/coreclr/src/md/runtime/CMakeLists.txt b/src/coreclr/src/md/runtime/CMakeLists.txt index 5753e655abf9..06e9e8300019 100644 --- a/src/coreclr/src/md/runtime/CMakeLists.txt +++ b/src/coreclr/src/md/runtime/CMakeLists.txt @@ -49,9 +49,11 @@ add_library_clr(mdruntime_dac ${MDRUNTIME_SOURCES}) set_target_properties(mdruntime_dac PROPERTIES DAC_COMPONENT TRUE) target_precompile_header(TARGET mdruntime_dac HEADER stdafx.h) -add_library_clr(mdruntime_wks OBJECT ${MDRUNTIME_SOURCES}) -target_compile_definitions(mdruntime_wks PRIVATE FEATURE_METADATA_EMIT_ALL) -target_precompile_header(TARGET mdruntime_wks HEADER stdafx.h) +add_library_clr(mdruntime_wks_obj OBJECT ${MDRUNTIME_SOURCES}) +target_compile_definitions(mdruntime_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL) +target_precompile_header(TARGET mdruntime_wks_obj HEADER stdafx.h) +add_library(mdruntime_wks INTERFACE) +target_sources(mdruntime_wks INTERFACE $) add_library_clr(mdruntime-dbi ${MDRUNTIME_SOURCES}) set_target_properties(mdruntime-dbi PROPERTIES DBI_COMPONENT TRUE) diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt index 094f14cabf82..712dabf46a3e 100644 --- a/src/coreclr/src/pal/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/CMakeLists.txt @@ -267,10 +267,12 @@ endif(CLR_CMAKE_TARGET_OSX) # > warning for library: libtracepointprovider.a the table of contents is empty (no object file members in the library define global symbols) # if(CLR_CMAKE_TARGET_LINUX) - add_library(tracepointprovider + add_library(tracepointprovider_obj OBJECT misc/tracepointprovider.cpp ) + add_library(tracepointprovider INTERFACE) + target_sources(tracepointprovider INTERFACE $) endif(CLR_CMAKE_TARGET_LINUX) if(CLR_CMAKE_TARGET_OSX) diff --git a/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt b/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt index 39b9826d1ab5..8e6968cf783d 100644 --- a/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt +++ b/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt @@ -1,8 +1,8 @@ -include(FindPython) +include(FindPythonInterp) set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genDummyProvider.py) -set(GENERATE_COMMAND ${Python_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) execute_process( COMMAND ${GENERATE_COMMAND} --dry-run diff --git a/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt b/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt index 234dea19b753..d55dab3557f3 100644 --- a/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt +++ b/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt @@ -1,7 +1,7 @@ -include(FindPython) +include(FindPythonInterp) set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genLttngProvider.py) -set(GENERATE_COMMAND ${Python_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) execute_process( COMMAND ${GENERATE_COMMAND} --dry-run diff --git a/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt b/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt index 000ee2d2fb0d..845fae656be4 100644 --- a/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt +++ b/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt @@ -5,10 +5,10 @@ set(SOURCES set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man) set(TEST_GENERATOR ${CLR_DIR}/src/scripts/genEventingTests.py) -include(FindPython) +include(FindPythonInterp) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clralltestevents.cpp - COMMAND ${Python_EXECUTABLE} ${TEST_GENERATOR} --testdir "${CMAKE_CURRENT_BINARY_DIR}" --man "${EVENT_MANIFEST}" + COMMAND ${PYTHON_EXECUTABLE} ${TEST_GENERATOR} --testdir "${CMAKE_CURRENT_BINARY_DIR}" --man "${EVENT_MANIFEST}" DEPENDS ${EVENT_MANIFEST} ${TEST_GENERATOR} COMMENT "Updating clralltestevents.cpp" ) diff --git a/src/coreclr/src/unwinder/CMakeLists.txt b/src/coreclr/src/unwinder/CMakeLists.txt index 98cdb0c0b7a8..e9af2458140d 100644 --- a/src/coreclr/src/unwinder/CMakeLists.txt +++ b/src/coreclr/src/unwinder/CMakeLists.txt @@ -20,8 +20,10 @@ list(APPEND UNWINDER_SOURCES convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES}) if(CLR_CMAKE_HOST_UNIX) - add_library_clr(unwinder_wks OBJECT ${UNWINDER_SOURCES}) - add_dependencies(unwinder_wks eventing_headers) + add_library_clr(unwinder_wks_obj OBJECT ${UNWINDER_SOURCES}) + add_dependencies(unwinder_wks_obj eventing_headers) + add_library(unwinder_wks INTERFACE) + target_sources(unwinder_wks INTERFACE $) endif(CLR_CMAKE_HOST_UNIX) add_library_clr(unwinder_dac ${UNWINDER_SOURCES}) diff --git a/src/coreclr/src/utilcode/CMakeLists.txt b/src/coreclr/src/utilcode/CMakeLists.txt index 30fcba8c0627..9eeac28ae4fb 100644 --- a/src/coreclr/src/utilcode/CMakeLists.txt +++ b/src/coreclr/src/utilcode/CMakeLists.txt @@ -96,7 +96,9 @@ convert_to_absolute_path(UTILCODE_CROSSGEN_SOURCES ${UTILCODE_CROSSGEN_SOURCES}) convert_to_absolute_path(UTILCODE_STATICNOHOST_SOURCES ${UTILCODE_STATICNOHOST_SOURCES}) add_library_clr(utilcode_dac STATIC ${UTILCODE_DAC_SOURCES}) -add_library_clr(utilcode OBJECT ${UTILCODE_SOURCES}) +add_library_clr(utilcode_obj OBJECT ${UTILCODE_SOURCES}) +add_library(utilcode INTERFACE) +target_sources(utilcode INTERFACE $) add_library_clr(utilcodestaticnohost STATIC ${UTILCODE_STATICNOHOST_SOURCES}) add_library_clr(utilcode_crossgen STATIC ${UTILCODE_CROSSGEN_SOURCES}) @@ -104,9 +106,9 @@ if(CLR_CMAKE_HOST_UNIX) target_link_libraries(utilcodestaticnohost nativeresourcestring) target_link_libraries(utilcode_crossgen nativeresourcestring) target_link_libraries(utilcode_dac nativeresourcestring) - target_link_libraries(utilcode nativeresourcestring) + target_link_libraries(utilcode INTERFACE nativeresourcestring) add_dependencies(utilcode_dac coreclrpal) - add_dependencies(utilcode coreclrpal) + add_dependencies(utilcode_obj coreclrpal) endif(CLR_CMAKE_HOST_UNIX) @@ -119,10 +121,10 @@ set_target_properties(utilcode_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE) target_compile_definitions(utilcode_dac PRIVATE SELF_NO_HOST) target_compile_definitions(utilcodestaticnohost PRIVATE SELF_NO_HOST) add_dependencies(utilcode_dac ${UTILCODE_DEPENDENCIES}) -add_dependencies(utilcode ${UTILCODE_DEPENDENCIES}) +add_dependencies(utilcode_obj ${UTILCODE_DEPENDENCIES}) add_dependencies(utilcode_crossgen ${UTILCODE_DEPENDENCIES}) add_dependencies(utilcodestaticnohost ${UTILCODE_DEPENDENCIES}) target_precompile_header(TARGET utilcode_dac HEADER stdafx.h) -target_precompile_header(TARGET utilcode HEADER stdafx.h) +target_precompile_header(TARGET utilcode_obj HEADER stdafx.h) target_precompile_header(TARGET utilcode_crossgen HEADER stdafx.h) target_precompile_header(TARGET utilcodestaticnohost HEADER stdafx.h) diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index 23b2e91f6b1b..83ebd3c3576e 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -923,7 +923,7 @@ list(APPEND VM_HEADERS_DAC if (CLR_CMAKE_TARGET_WIN32) list(APPEND VM_SOURCES_WKS ${VM_HEADERS_WKS}) - list(APPEND VM_SOURCES_WKS_ARCH_ASM ${VM_HEADERS_WKS_ARCH_ASM}) + list(APPEND VM_SOURCES_WKS ${VM_HEADERS_WKS_ARCH_ASM}) list(APPEND VM_SOURCES_DAC ${VM_HEADERS_DAC}) endif(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/src/vm/eventing/CMakeLists.txt b/src/coreclr/src/vm/eventing/CMakeLists.txt index 98dd158df545..e2bf024fc59f 100644 --- a/src/coreclr/src/vm/eventing/CMakeLists.txt +++ b/src/coreclr/src/vm/eventing/CMakeLists.txt @@ -8,12 +8,13 @@ else() set(NEED_XPLAT_HEADER ON) endif() -include(FindPython) +include(FindPythonInterp) set (EventingHeaders ${GENERATED_INCLUDE_DIR}/etmdummy.h ${GENERATED_INCLUDE_DIR}/clretwallmain.h ${GENERATED_INCLUDE_DIR}/clreventpipewriteevents.h + ${GENERATED_INCLUDE_DIR}/clrproviders.h ) if (NEED_XPLAT_HEADER) @@ -24,7 +25,7 @@ endif() set(GENEVENTING_SCRIPT ${CLR_DIR}/src/scripts/genEventing.py) add_custom_target(eventing_headers - ${Python_EXECUTABLE} ${GENEVENTING_SCRIPT} --man ${EVENT_MANIFEST} --inc ${GENERATED_INCLUDE_DIR} --dummy ${GENERATED_INCLUDE_DIR}/etmdummy.h ${NONEXTERN_ARG} ${NOXPLATHEADER_ARG} + ${PYTHON_EXECUTABLE} ${GENEVENTING_SCRIPT} --man ${EVENT_MANIFEST} --inc ${GENERATED_INCLUDE_DIR} --dummy ${GENERATED_INCLUDE_DIR}/etmdummy.h ${NONEXTERN_ARG} ${NOXPLATHEADER_ARG} DEPENDS ${EVENT_MANIFEST} ${GENEVENTING_SCRIPT} VERBATIM ) diff --git a/src/coreclr/src/vm/eventing/EtwProvider/CMakeLists.txt b/src/coreclr/src/vm/eventing/EtwProvider/CMakeLists.txt index 34a067e1ec54..4c7df2fbb3cf 100644 --- a/src/coreclr/src/vm/eventing/EtwProvider/CMakeLists.txt +++ b/src/coreclr/src/vm/eventing/EtwProvider/CMakeLists.txt @@ -1,4 +1,4 @@ -include(FindPython) +include(FindPythonInterp) set(ETW_PROVIDER_SCRIPT ${CLR_DIR}/src/scripts/genEtwProvider.py) @@ -14,5 +14,5 @@ set (ETW_PROVIDER_OUTPUTS set_source_files_properties(${ETW_PROVIDER_OUTPUTS} PROPERTIES GENERATED TRUE) add_custom_target(eventprovider - ${Python_EXECUTABLE} ${ETW_PROVIDER_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${GENERATED_INCLUDE_DIR} + ${PYTHON_EXECUTABLE} ${ETW_PROVIDER_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${GENERATED_INCLUDE_DIR} DEPENDS ${EVENT_MANIFEST} ${EVENT_EXCLUSIONS} ${ETW_PROVIDER_SCRIPT}) diff --git a/src/coreclr/src/vm/eventing/eventpipe/CMakeLists.txt b/src/coreclr/src/vm/eventing/eventpipe/CMakeLists.txt index 4e816676b8a7..00d79737e54c 100644 --- a/src/coreclr/src/vm/eventing/eventpipe/CMakeLists.txt +++ b/src/coreclr/src/vm/eventing/eventpipe/CMakeLists.txt @@ -1,9 +1,9 @@ -include(FindPython) +include(FindPythonInterp) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genEventPipe.py) -set(GENERATE_COMMAND ${Python_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${CMAKE_CURRENT_BINARY_DIR} ${NONEXTERN_ARG}) +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${CMAKE_CURRENT_BINARY_DIR} ${NONEXTERN_ARG}) execute_process( COMMAND ${GENERATE_COMMAND} --dry-run @@ -28,10 +28,8 @@ add_custom_command(OUTPUT ${EVENTPIPE_SOURCES} COMMAND ${GENERATE_COMMAND} DEPENDS ${GENERATE_SCRIPT} ${EVENT_MANIFEST} ${EVENT_EXCLUSIONS}) -add_library_clr(eventpipe OBJECT ${EVENTPIPE_SOURCES}) -set_target_properties(eventpipe PROPERTIES LINKER_LANGUAGE CXX) -add_dependencies(eventpipe eventing_headers) - -if (NOT CLR_CMAKE_TARGET_WIN32) - _install(TARGETS eventpipe DESTINATION lib) -endif() +add_library_clr(eventpipe_obj OBJECT ${EVENTPIPE_SOURCES}) +set_target_properties(eventpipe_obj PROPERTIES LINKER_LANGUAGE CXX) +add_dependencies(eventpipe_obj eventing_headers) +add_library(eventpipe INTERFACE) +target_sources(eventpipe INTERFACE $) diff --git a/src/coreclr/src/vm/wks/CMakeLists.txt b/src/coreclr/src/vm/wks/CMakeLists.txt index 8141137330e6..7c3dd84bd3d0 100644 --- a/src/coreclr/src/vm/wks/CMakeLists.txt +++ b/src/coreclr/src/vm/wks/CMakeLists.txt @@ -8,8 +8,12 @@ if (CLR_CMAKE_TARGET_WIN32) endif (CLR_CMAKE_TARGET_WIN32) add_library_clr(cee_wks_core OBJECT ${VM_SOURCES_WKS} ${VM_SOURCES_WKS_ARCH_ASM}) +add_library_clr(cee_wks_obj OBJECT ${VM_SOURCES_WKS_SPECIAL}) +add_library_clr(cee_wks_mergeable_obj OBJECT ${VM_SOURCES_WKS_SPECIAL}) target_precompile_header(TARGET cee_wks_core HEADER common.h) +target_precompile_header(TARGET cee_wks_obj HEADER common.h) +target_precompile_header(TARGET cee_wks_mergeable_obj HEADER common.h) if (MSVC) # corelib.cpp does not compile with precompiled header file @@ -17,6 +21,8 @@ if (MSVC) endif() add_dependencies(cee_wks_core eventing_headers) +add_dependencies(cee_wks_obj eventing_headers) +add_dependencies(cee_wks_mergeable_obj eventing_headers) if (CLR_CMAKE_TARGET_WIN32) @@ -49,20 +55,23 @@ if (CLR_CMAKE_TARGET_WIN32) ) add_dependencies(cee_wks_core asmconstants_inc) + add_dependencies(cee_wks_obj asmconstants_inc) + add_dependencies(cee_wks_mergeable_obj asmconstants_inc) endif(NOT CLR_CMAKE_HOST_ARCH_ARM AND NOT CLR_CMAKE_HOST_ARCH_ARM64) endif (CLR_CMAKE_TARGET_WIN32) -add_library_clr(cee_wks OBJECT ${VM_SOURCES_WKS_SPECIAL} $ ${VM_WKS_ARCH_ASM_OBJECTS}) -add_library_clr(cee_wks_mergeable OBJECT ${VM_SOURCES_WKS_SPECIAL} $ ${VM_WKS_ARCH_ASM_OBJECTS}) - add_custom_target(preprocessd_asm DEPENDS ${VM_WKS_ARCH_ASM_OBJECTS}) -add_dependencies(cee_wks preprocessd_asm) -add_dependencies(cee_wks_mergeable preprocessd_asm) +add_dependencies(cee_wks_core preprocessd_asm) +add_dependencies(cee_wks_obj preprocessd_asm) +add_dependencies(cee_wks_mergeable_obj preprocessd_asm) + -target_precompile_header(TARGET cee_wks HEADER common.h) -target_precompile_header(TARGET cee_wks_mergeable HEADER common.h) +target_compile_definitions(cee_wks_mergeable_obj PUBLIC FEATURE_MERGE_JIT_AND_ENGINE) +target_compile_definitions(cee_wks_mergeable_obj PUBLIC CORECLR_EMBEDDED) -target_compile_definitions(cee_wks_mergeable PUBLIC FEATURE_MERGE_JIT_AND_ENGINE) -target_compile_definitions(cee_wks_mergeable PUBLIC CORECLR_EMBEDDED) +add_library(cee_wks INTERFACE) +target_sources(cee_wks INTERFACE $ ${VM_WKS_ARCH_ASM_OBJECTS}) +add_library(cee_wks_mergeable INTERFACE) +target_sources(cee_wks_mergeable INTERFACE $ $ ${VM_WKS_ARCH_ASM_OBJECTS}) diff --git a/src/installer/corehost/CMakeLists.txt b/src/installer/corehost/CMakeLists.txt index 651a63be0cac..46d1c5e89814 100644 --- a/src/installer/corehost/CMakeLists.txt +++ b/src/installer/corehost/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14.5) +cmake_minimum_required(VERSION 3.6.2) project(corehost) diff --git a/src/installer/corehost/cli/apphost/static/CMakeLists.txt b/src/installer/corehost/cli/apphost/static/CMakeLists.txt index 6d8d3f431aef..85ea6ffe642d 100644 --- a/src/installer/corehost/cli/apphost/static/CMakeLists.txt +++ b/src/installer/corehost/cli/apphost/static/CMakeLists.txt @@ -30,6 +30,8 @@ set(HEADERS ../../../hostfxr_resolver.h ) +list(APPEND SOURCES $ $) + if(CLR_CMAKE_TARGET_WIN32) list(APPEND SOURCES ../apphost.windows.cpp) @@ -199,8 +201,6 @@ endif(NOT CLR_CMAKE_TARGET_LINUX) set_property(TARGET singlefilehost PROPERTY ENABLE_EXPORTS 1) target_link_libraries(singlefilehost - libhostfxr_static - libhostpolicy_static libhostcommon ${CORECLR_LIBRARIES} diff --git a/src/installer/corehost/cli/exe.cmake b/src/installer/corehost/cli/exe.cmake index fed0bdd455b2..6431edfbc4f9 100644 --- a/src/installer/corehost/cli/exe.cmake +++ b/src/installer/corehost/cli/exe.cmake @@ -4,7 +4,6 @@ project (${DOTNET_PROJECT_NAME}) cmake_policy(SET CMP0011 NEW) -cmake_policy(SET CMP0083 NEW) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) include(${CMAKE_CURRENT_LIST_DIR}/hostmisc/hostmisc.cmake) diff --git a/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt b/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt index d6c147f8f588..c6b07eba340c 100644 --- a/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt +++ b/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories(../../fxr) # CMake does not recommend using globbing since it messes with the freshness checks set(SOURCES ./hostpolicy_resolver.cpp + $ ) set(HEADERS @@ -48,4 +49,4 @@ if(CLR_CMAKE_HOST_UNIX) endif(CLR_CMAKE_HOST_UNIX) install_with_stripped_symbols(hostfxr TARGETS corehost) -target_link_libraries(hostfxr libhostcommon libhostfxr_static) +target_link_libraries(hostfxr libhostcommon) diff --git a/src/installer/corehost/cli/test/mockhostfxr/CMakeLists.txt b/src/installer/corehost/cli/test/mockhostfxr/CMakeLists.txt index 94099c49c1d6..8b5a55fe9b17 100644 --- a/src/installer/corehost/cli/test/mockhostfxr/CMakeLists.txt +++ b/src/installer/corehost/cli/test/mockhostfxr/CMakeLists.txt @@ -1,7 +1,6 @@ # Licensed to the .NET Foundation under one or more agreements. # The .NET Foundation licenses this file to you under the MIT license. -cmake_minimum_required (VERSION 3.14.5) project(mockhostfxr_2_2) set(DOTNET_PROJECT_NAME "mockhostfxr_2_2") diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 6c1c4ea45861..3168c7e55c83 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -1,14 +1,14 @@ -cmake_minimum_required(VERSION 3.14.5) +cmake_minimum_required(VERSION 3.6.2) +if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + # CMake 3.14.5 contains bug fixes for iOS + cmake_minimum_required(VERSION 3.14.5) + endif() cmake_policy(SET CMP0042 NEW) project(CoreFX C) include(${CLR_ENG_NATIVE_DIR}/configuretools.cmake) -if(NOT CLR_CMAKE_TARGET_BROWSER) - cmake_policy(SET CMP0083 NEW) -endif(NOT CLR_CMAKE_TARGET_BROWSER) - set(CMAKE_MACOSX_RPATH ON) set(CMAKE_INSTALL_PREFIX $ENV{__CMakeBinDir}) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -161,7 +161,8 @@ if(CLR_CMAKE_TARGET_UNIX) if(NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) if(CLR_CMAKE_TARGET_OSX) add_definitions(-DTARGET_OSX) - add_link_options(-Wl,-bind_at_load) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-bind_at_load") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-bind_at_load" ) else() add_compile_options($<$:-Wa,--noexecstack>) if(CLR_CMAKE_TARGET_SUNOS) @@ -169,7 +170,8 @@ if(CLR_CMAKE_TARGET_UNIX) else() # -z,now is required for full relro. # see https://www.redhat.com/en/blog/hardening-elf-binaries-using-relocation-read-only-relro - add_link_options(-Wl,--build-id=sha1 -Wl,-z,relro,-z,now) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=sha1 -Wl,-z,relro,-z,now") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1 -Wl,-z,relro,-z,now" ) endif() endif() endif() diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt index 37e2574b481c..b08f49e88622 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt @@ -75,14 +75,15 @@ if (GEN_SHARED_LIB) install_with_stripped_symbols (System.Globalization.Native PROGRAMS .) endif() -add_library(System.Globalization.Native-Static +add_library(System.Globalization.Native_obj OBJECT ${NATIVEGLOBALIZATION_SOURCES} ) -set_target_properties(System.Globalization.Native-Static PROPERTIES OUTPUT_NAME System.Globalization.Native CLEAN_DIRECT_OUTPUT 1) +set_target_properties(System.Globalization.Native_obj PROPERTIES OUTPUT_NAME System.Globalization.Native CLEAN_DIRECT_OUTPUT 1) -install (TARGETS System.Globalization.Native-Static DESTINATION .) +add_library(System.Globalization.Native-static INTERFACE) +target_sources(System.Globalization.Native-static INTERFACE $) if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) if (GEN_SHARED_LIB) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 0523d165acba..77fcc16a01f9 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14.5) +cmake_minimum_required(VERSION 3.6.2) cmake_policy(SET CMP0042 NEW) project(Tests) From d7506e7d04b5dadf40e48896a8c1585ed10cd354 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 4 Aug 2020 11:43:24 -0700 Subject: [PATCH 243/755] Add step to run linker on entire runtime pack during libraries build (#40172) * Add step to run linker on entire runtime pack during libraries build * Address feedback * Only run for NetCoreAppCurrent * Include appropriate S.P.CoreLib * Address review feedback * Add common property group for shared linker args; remove unneeded changes from PR * Rename illink-sharedframeworks.targets to illink-sharedframework.targets * Address review feedback --- eng/illink.targets | 51 +++++++------ src/libraries/Directory.Build.props | 1 + src/libraries/illink-sharedframework.targets | 76 ++++++++++++++++++++ src/libraries/src.proj | 3 + 4 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 src/libraries/illink-sharedframework.targets diff --git a/eng/illink.targets b/eng/illink.targets index ddd4936cc264..682871ebc72b 100644 --- a/eng/illink.targets +++ b/eng/illink.targets @@ -184,22 +184,37 @@ + + + + + $(ILLinkArgs) -t + + + $(ILLinkArgs) --strip-link-attributes false --ignore-link-attributes true + + $(ILLinkArgs) --skip-unresolved true + + $(ILLinkArgs) --disable-opt unusedinterfaces + + + - + - $(ILLinkArgs)-r $(TargetName) + $(ILLinkArgs) -r $(TargetName) $(ILLinkArgs) -c skip $(ILLinkArgs) -u skip $(ILLinkArgs) -p link $(TargetName) - - $(ILLinkArgs) -t $(ILLinkArgs) -b true $(ILLinkArgs) --strip-descriptors false @@ -207,27 +222,21 @@ $(ILLinkArgs) -x "$(ILLinkTrimXmlLibraryBuild)" $(ILLinkArgs) --strip-substitutions false - - - $(ILLinkArgs) --strip-link-attributes false --ignore-link-attributes true - - $(ILLinkArgs) --skip-unresolved true - - $(ILLinkArgs) --disable-opt unusedinterfaces $(ILLinkArgs) --keep-dep-attributes true - $(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2041 + $(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2050 diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 57898d4ff67e..98097c8ab318 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -328,4 +328,5 @@ false true + diff --git a/src/libraries/illink-sharedframework.targets b/src/libraries/illink-sharedframework.targets new file mode 100644 index 000000000000..9ccc5a2ec850 --- /dev/null +++ b/src/libraries/illink-sharedframework.targets @@ -0,0 +1,76 @@ + + + + + + $([MSBuild]::NormalizePath('$(ArtifactsBinDir)', 'ILLinkTrimAssembly', '$(BuildSettings)', 'trimmed-runtimepack')) + + + + + $(ILLinkArgs) -c link + + $(ILLinkArgs) -b true + + $(ILLinkArgs) --nowarn IL2006;IL2009;IL2025;IL2026;IL2035;IL2050 + + + + + + + + + <_AssemblyPaths>$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir);$(SystemPrivateCoreLibPath) + + + + + <_DependencyDirectories Include="$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir.TrimEnd('\'))" /> + + + + $(ILLinkArgs) -d @(_DependencyDirectories->'"%(Identity)"', ' -d ') + + + + <_AssembliesToLink Include="System.Private.CoreLib" /> + + <_LibrariesToLink Include="$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)*.dll" /> + <_AssembliesToLink Include="@(_LibrariesToLink->'%(FileName)')" /> + + + + $(ILLinkArgs) -r @(_AssembliesToLink->'%(Identity)', ' -r ') + + + + + <_DotNetHostDirectory>$(RepoRoot).dotnet + <_DotNetHostFileName>dotnet + <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe + + + + + + + diff --git a/src/libraries/src.proj b/src/libraries/src.proj index c534a380309d..ce82c68ea701 100644 --- a/src/libraries/src.proj +++ b/src/libraries/src.proj @@ -49,6 +49,9 @@ Properties="$(TraversalGlobalProperties)" /> + + From 73f9666ede4a23ccc19c541f98498ab31d1560a2 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 4 Aug 2020 12:17:16 -0700 Subject: [PATCH 244/755] Add more runtime GC counters (#38851) * Add more GC counters * Cleanup * Change size of last GC stats arrays from total_generation_count to max_generation * add asserts and fix error * fix typo * Fix Windows build * Remove pause time / time between GC counters as discussed in design PR * revert changes to GC for unused counters * more unnecessary changes * build fix * last bit of undoing changes * CR feedback --- .../src/System/Diagnostics/Tracing/RuntimeEventSource.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index d5f1c745ff1c..eecca7780c4c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -26,6 +26,7 @@ internal sealed class RuntimeEventSource : EventSource private IncrementingPollingCounter? _completedItemsCounter; private IncrementingPollingCounter? _allocRateCounter; private PollingCounter? _timerCounter; + private PollingCounter? _fragmentationCounter; #if !MONO private IncrementingPollingCounter? _exceptionCounter; @@ -70,6 +71,10 @@ protected override void OnEventCommand(EventCommandEventArgs command) _completedItemsCounter ??= new IncrementingPollingCounter("threadpool-completed-items-count", this, () => ThreadPool.CompletedWorkItemCount) { DisplayName = "ThreadPool Completed Work Item Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _allocRateCounter ??= new IncrementingPollingCounter("alloc-rate", this, () => GC.GetTotalAllocatedBytes()) { DisplayName = "Allocation Rate", DisplayUnits = "B", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _timerCounter ??= new PollingCounter("active-timer-count", this, () => Timer.ActiveCount) { DisplayName = "Number of Active Timers" }; + _fragmentationCounter ??= new PollingCounter("gc-fragmentation", this, () => { + var gcInfo = GC.GetGCMemoryInfo(); + return gcInfo.FragmentedBytes * 100d / gcInfo.HeapSizeBytes; + }) { DisplayName = "GC Fragmentation", DisplayUnits = "%" }; #if !MONO _exceptionCounter ??= new IncrementingPollingCounter("exception-count", this, () => Exception.GetExceptionCount()) { DisplayName = "Exception Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _gcTimeCounter ??= new PollingCounter("time-in-gc", this, () => GC.GetLastGCPercentTimeInGC()) { DisplayName = "% Time in GC since last GC", DisplayUnits = "%" }; From 26ae38683115c2c5c67e4ca86510d8ecd1469177 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Tue, 4 Aug 2020 15:44:28 -0400 Subject: [PATCH 245/755] fix typo: fuitful -> fruitful (#40333) --- docs/design/coreclr/botr/xplat-minidump-generation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/coreclr/botr/xplat-minidump-generation.md b/docs/design/coreclr/botr/xplat-minidump-generation.md index 9ac1d2040906..16b506dbb313 100644 --- a/docs/design/coreclr/botr/xplat-minidump-generation.md +++ b/docs/design/coreclr/botr/xplat-minidump-generation.md @@ -12,7 +12,7 @@ Our solution at this time is to intercept any unhandled exception in the PAL lay We looked at the existing technologies like Breakpad and its derivatives (e.g.: an internal MS version called _msbreakpad_ from the SQL team....). Breakpad generates Windows minidumps but they are not compatible with existing tools like Windbg, etc. Msbreakpad even more so. There is a minidump to Linux core conversion utility but it seems like a wasted extra step. _Breakpad_ does allow the minidump to be generated in-process inside the signal handlers. It restricts the APIs to what was allowed in a "async" signal handler (like SIGSEGV) and has a small subset of the C++ runtime that was also similarly constrained. We also need to add the set of memory regions for the "managed" state which requires loading and using the _DAC_'s (*) enumerate memory interfaces. Loading modules is not allowed in an async signal handler but forking/execve is allowed so launching an utility that loads the _DAC_, enumerates the list of memory regions and writes the dump is the only reasonable option. It would also allow uploading the dump to a server too. -\* The _DAC_ is a special build of parts of the coreclr runtime that allows inspection of the runtime's managed state (stacks, variables, GC state heaps) out of context. One of the many interfaces it provides is [ICLRDataEnumMemoryRegions](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/debug/daccess/dacimpl.h) which enumerates all the managed state a minidump would require to enable a fuitful debugging experience. +\* The _DAC_ is a special build of parts of the coreclr runtime that allows inspection of the runtime's managed state (stacks, variables, GC state heaps) out of context. One of the many interfaces it provides is [ICLRDataEnumMemoryRegions](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/debug/daccess/dacimpl.h) which enumerates all the managed state a minidump would require to enable a fruitful debugging experience. _Breakpad_ could have still been used out of context in the generation utility but there seemed no value to their Windows-like minidump format when it would have to be converted to the native Linux core format away because in most scenarios using the platform tools like _lldb_ is necessary. It also adds a coreclr build dependency on Google's _Breakpad_ or SQL's _msbreakpad_ source repo. The only advantage is that the breakpad minidumps may be a little smaller because minidumps memory regions are byte granule and Linux core memory regions need to be page granule. From 1e961bab56f33b7b5179b9a70ca0724428d1b8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 4 Aug 2020 21:48:16 +0200 Subject: [PATCH 246/755] Fix warning in debugger-agent.c (#40325) ``` CC libmono_dbg_la-debugger-agent.lo /Users/runner/work/1/s/src/mono/mono/mini/debugger-agent.c:1088:9: warning: unused variable 'argv' [-Wunused-variable] char *argv [ ] = { ``` --- src/mono/mono/mini/debugger-agent.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index 82108808fc21..5b6d729a3390 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -1085,18 +1085,18 @@ finish_agent_init (gboolean on_startup) // FIXME: Generated address // FIXME: Races with transport_connect () - char *argv [ ] = { - agent_config.launch, - agent_config.transport, - agent_config.address, - NULL - }; #ifdef G_OS_WIN32 // Nothing. FIXME? g_spawn_async_with_pipes is easy enough to provide for Windows if needed. #elif !HAVE_G_SPAWN g_printerr ("g_spawn_async_with_pipes not supported on this platform\n"); exit (1); #else + char *argv [ ] = { + agent_config.launch, + agent_config.transport, + agent_config.address, + NULL + }; int res = g_spawn_async_with_pipes (NULL, argv, NULL, (GSpawnFlags)0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!res) { g_printerr ("Failed to execute '%s'.\n", agent_config.launch); From c91269cb959a78309d0fa3040ae6028cce97f86e Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 4 Aug 2020 12:59:46 -0700 Subject: [PATCH 247/755] Make macOS targets in global build job template default to 120 minutes timeout (#40330) --- eng/pipelines/common/global-build-job.yml | 8 +++++++- eng/pipelines/global-build.yml | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index dcbba9fb3654..3f22f762be8c 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -25,11 +25,17 @@ jobs: dependsOn: checkout pool: ${{ parameters.pool }} container: ${{ parameters.container }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} condition: and(succeeded(), ${{ parameters.condition }}) workspace: clean: all + # macOS hosted pool machines are slower so we need to give a greater timeout for global-build + # which builds multiple subsets. + ${{ if and(contains(parameters.pool.vmImage, 'macOS'), eq(parameters.timeoutInMinutes, '')) }}: + timeoutInMinutes: 120 + ${{ if or(not(contains(parameters.pool.vmImage, 'macOS')), ne(parameters.timeoutInMinutes, '')) }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + variables: - name: _osParameter value: -os ${{ parameters.osGroup }} diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 2d7e301f1a5e..9721eb4b9f47 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -48,7 +48,6 @@ jobs: testGroup: innerloop nameSuffix: Runtime_Debug buildArgs: -c release -runtimeConfiguration debug - timeoutInMinutes: 120 # # Build with Debug config and Release runtimeConfiguration From b552749906402ec7994150bc9dd8970440dbb9c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 4 Aug 2020 22:25:58 +0200 Subject: [PATCH 248/755] Mono: Ensure tasklets are removed in netcore build (#40324) Tasklets were an old mono-specific extension for continuations that is no longer relevant. --- src/mono/mono/metadata/object-offsets.h | 2 ++ src/mono/mono/mini/exceptions-amd64.c | 8 ++++---- src/mono/mono/mini/exceptions-x86.c | 2 +- src/mono/mono/mini/mini-runtime.c | 2 ++ src/mono/mono/mini/tasklets.c | 5 ++++- src/mono/mono/mini/tasklets.h | 3 +++ 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/object-offsets.h b/src/mono/mono/metadata/object-offsets.h index bf2bf0e25272..f11bbf58e82b 100644 --- a/src/mono/mono/metadata/object-offsets.h +++ b/src/mono/mono/metadata/object-offsets.h @@ -167,11 +167,13 @@ DECL_OFFSET(MonoJitTlsData, stack_restore_ctx) DECL_OFFSET(MonoGSharedVtMethodRuntimeInfo, locals_size) DECL_OFFSET(MonoGSharedVtMethodRuntimeInfo, entries) //XXX more to fix here +#if !defined(ENABLE_NETCORE) DECL_OFFSET(MonoContinuation, stack_used_size) DECL_OFFSET(MonoContinuation, saved_stack) DECL_OFFSET(MonoContinuation, return_sp) DECL_OFFSET(MonoContinuation, lmf) DECL_OFFSET(MonoContinuation, return_ip) +#endif DECL_OFFSET(MonoDelegateTrampInfo, method) DECL_OFFSET(MonoDelegateTrampInfo, invoke_impl) diff --git a/src/mono/mono/mini/exceptions-amd64.c b/src/mono/mono/mini/exceptions-amd64.c index f795a06b1eca..8be488d1309e 100644 --- a/src/mono/mono/mini/exceptions-amd64.c +++ b/src/mono/mono/mini/exceptions-amd64.c @@ -1905,7 +1905,7 @@ void mono_arch_code_chunk_destroy (void *chunk) } #endif /* MONO_ARCH_HAVE_UNWIND_TABLE */ -#if MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) +#if MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) && !defined(ENABLE_NETCORE) MonoContinuationRestore mono_tasklets_arch_restore (void) { @@ -1956,7 +1956,7 @@ mono_tasklets_arch_restore (void) saved = start; return (MonoContinuationRestore)saved; } -#endif /* MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) */ +#endif /* MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) && !defined(ENABLE_NETCORE) */ /* * mono_arch_setup_resume_sighandler_ctx: @@ -1975,14 +1975,14 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func) MONO_CONTEXT_SET_IP (ctx, func); } -#if !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT) +#if (!MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT)) && !defined(ENABLE_NETCORE) MonoContinuationRestore mono_tasklets_arch_restore (void) { g_assert_not_reached (); return NULL; } -#endif /* !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT) */ +#endif /* (!MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT)) && !defined(ENABLE_NETCORE) */ void mono_arch_undo_ip_adjustment (MonoContext *ctx) diff --git a/src/mono/mono/mini/exceptions-x86.c b/src/mono/mono/mini/exceptions-x86.c index a0f79a71426c..ef9927577e6a 100644 --- a/src/mono/mono/mini/exceptions-x86.c +++ b/src/mono/mono/mini/exceptions-x86.c @@ -1175,7 +1175,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s #endif } -#if MONO_SUPPORT_TASKLETS +#if MONO_SUPPORT_TASKLETS && !defined(ENABLE_NETCORE) MonoContinuationRestore mono_tasklets_arch_restore (void) { diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 3dc54a5e2230..caf65d40e88a 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4596,7 +4596,9 @@ mini_init (const char *filename, const char *runtime_version) mono_simd_intrinsics_init (); #endif +#ifndef ENABLE_NETCORE mono_tasklets_init (); +#endif register_trampolines (domain); diff --git a/src/mono/mono/mini/tasklets.c b/src/mono/mono/mini/tasklets.c index 361b3f02353f..402a3a981c23 100644 --- a/src/mono/mono/mini/tasklets.c +++ b/src/mono/mono/mini/tasklets.c @@ -12,6 +12,7 @@ #include "mono/metadata/loader-internals.h" #include "mono/utils/mono-tls-inline.h" +#if !defined(ENABLE_NETCORE) #if defined(MONO_SUPPORT_TASKLETS) #include "mono/metadata/loader-internals.h" @@ -213,5 +214,7 @@ mono_tasklets_init(void) mono_add_internal_call_internal ("Mono.Tasklets.Continuation::restore", continuation_restore); } -#endif +#endif /* MONO_SUPPORT_TASKLETS */ + +#endif /* ENABLE_NETCORE */ diff --git a/src/mono/mono/mini/tasklets.h b/src/mono/mono/mini/tasklets.h index fc6f0b8178a9..dd8750f3f2f2 100644 --- a/src/mono/mono/mini/tasklets.h +++ b/src/mono/mono/mini/tasklets.h @@ -7,6 +7,7 @@ #include "mini.h" +#if !defined(ENABLE_NETCORE) typedef struct { MonoLMF *lmf; gpointer top_sp; @@ -31,5 +32,7 @@ void mono_tasklets_cleanup (void); MonoContinuationRestore mono_tasklets_arch_restore (void); +#endif /* ENABLE_NETCORE */ + #endif /* __MONO_TASKLETS_H__ */ From 6d98f6dcc6e924a265f591f2e4d69f2e84d04807 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Tue, 4 Aug 2020 18:02:35 -0400 Subject: [PATCH 249/755] Don't suspend for debugger while holding the slot backpatching lock (#40060) - Mostly reverted the previous workaround for the issue (commit fc06054a774e28a5a47bbe862adcf03251abb43c) - Added a forbid-suspend-for-debugger region in preemptive GC mode - Added a crst holder type that acquires a lock and enters the forbid region - Where the slot backpatching lock would be taken where cooperative GC mode may be entered inside that lock, the new crst holder is used - When a suspend for debugger is requested, a thread in preemptive GC mode that is in the forbid region is considered not yet suspended and is synched later similarly to threads in cooperative GC mode Fixes https://github.com/dotnet/runtime/issues/37278 --- src/coreclr/src/debug/ee/debugger.cpp | 9 -- src/coreclr/src/vm/callcounting.cpp | 6 +- src/coreclr/src/vm/codeversion.cpp | 3 +- src/coreclr/src/vm/crst.cpp | 85 +++++++++++++++++++ src/coreclr/src/vm/crst.h | 26 ++++-- src/coreclr/src/vm/fptrstubs.cpp | 4 +- src/coreclr/src/vm/method.cpp | 4 +- .../src/vm/methoddescbackpatchinfo.cpp | 27 ------ src/coreclr/src/vm/methoddescbackpatchinfo.h | 67 +++++++-------- src/coreclr/src/vm/prestub.cpp | 3 +- src/coreclr/src/vm/rejit.cpp | 2 +- src/coreclr/src/vm/threads.cpp | 1 + src/coreclr/src/vm/threads.h | 15 ++++ src/coreclr/src/vm/threads.inl | 18 ++++ src/coreclr/src/vm/threadsuspend.cpp | 60 +++++++++---- src/coreclr/src/vm/tieredcompilation.cpp | 10 +-- src/coreclr/src/vm/virtualcallstub.cpp | 6 +- 17 files changed, 231 insertions(+), 115 deletions(-) diff --git a/src/coreclr/src/debug/ee/debugger.cpp b/src/coreclr/src/debug/ee/debugger.cpp index 56ecf032b71d..5ead858581ac 100644 --- a/src/coreclr/src/debug/ee/debugger.cpp +++ b/src/coreclr/src/debug/ee/debugger.cpp @@ -15242,15 +15242,6 @@ HRESULT Debugger::FuncEvalSetup(DebuggerIPCE_FuncEvalInfo *pEvalInfo, return CORDBG_E_FUNC_EVAL_BAD_START_POINT; } - if (MethodDescBackpatchInfoTracker::IsLockOwnedByAnyThread()) - { - // A thread may have suspended for the debugger while holding the slot backpatching lock while trying to enter - // cooperative GC mode. If the FuncEval calls a method that is eligible for slot backpatching (virtual or interface - // methods that are eligible for tiering), the FuncEval may deadlock on trying to acquire the same lock. Fail the - // FuncEval to avoid the issue. - return CORDBG_E_FUNC_EVAL_BAD_START_POINT; - } - // Create a DebuggerEval to hold info about this eval while its in progress. Constructor copies the thread's // CONTEXT. DebuggerEval *pDE = new (interopsafe, nothrow) DebuggerEval(filterContext, pEvalInfo, fInException); diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp index 45edd54b8d35..8c3678bfd853 100644 --- a/src/coreclr/src/vm/callcounting.cpp +++ b/src/coreclr/src/vm/callcounting.cpp @@ -824,8 +824,7 @@ void CallCountingManager::CompleteCallCounting() { CodeVersionManager *codeVersionManager = appDomain->GetCodeVersionManager(); - MethodDescBackpatchInfoTracker::PollForDebuggerSuspension(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder; // Backpatching entry point slots requires cooperative GC mode, see // MethodDescBackpatchInfoTracker::Backpatch_Locked(). The code version manager's table lock is an unsafe lock that @@ -956,8 +955,7 @@ void CallCountingManager::StopAndDeleteAllCallCountingStubs() TieredCompilationManager *tieredCompilationManager = GetAppDomain()->GetTieredCompilationManager(); bool scheduleTieringBackgroundWork = false; { - MethodDescBackpatchInfoTracker::PollForDebuggerSuspension(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder; ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER); struct AutoRestartEE diff --git a/src/coreclr/src/vm/codeversion.cpp b/src/coreclr/src/vm/codeversion.cpp index 5ae3940a1681..78f2ede9d5f9 100644 --- a/src/coreclr/src/vm/codeversion.cpp +++ b/src/coreclr/src/vm/codeversion.cpp @@ -1759,7 +1759,8 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary( do { bool mayHaveEntryPointSlotsToBackpatch = doPublish && pMethodDesc->MayHaveEntryPointSlotsToBackpatch(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder(mayHaveEntryPointSlotsToBackpatch); + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder( + mayHaveEntryPointSlotsToBackpatch); // Try a faster check to see if we can avoid checking the currently active code version // - For the default code version, if a profiler is attached it may be notified of JIT events and may request rejit diff --git a/src/coreclr/src/vm/crst.cpp b/src/coreclr/src/vm/crst.cpp index 22f7a1ff9759..cbfb665285b4 100644 --- a/src/coreclr/src/vm/crst.cpp +++ b/src/coreclr/src/vm/crst.cpp @@ -772,6 +772,91 @@ BOOL CrstBase::IsSafeToTake() #endif // _DEBUG +CrstBase::CrstAndForbidSuspendForDebuggerHolder::CrstAndForbidSuspendForDebuggerHolder(CrstBase *pCrst) + : m_pCrst(pCrst), m_pThreadForExitingForbidRegion(nullptr) +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + if (pCrst == nullptr) + { + return; + } + + // Reentrant locks are currently not supported + _ASSERTE((pCrst->m_dwFlags & CRST_REENTRANCY) == 0); + + Thread *pThread = GetThread(); + _ASSERTE(pThread != nullptr); + if (pThread->IsInForbidSuspendForDebuggerRegion()) + { + AcquireLock(pCrst); + return; + } + + while (true) + { + // Enter the forbid region and make that state change visible to other threads (memory barrier) before checking for the + // TS_DebugSuspendPending state. The other interacting thread in SysStartSuspendForDebug(), sets TS_DebugSuspendPending + // and makes that state change visible to other threads (memory barrier) before checking for whether this thread is in + // the forbid region. This ensures that in race conditions where both threads update the respective state and make the + // state change visible to other threads, at least one of those threads will see the state change made by the other + // thread. If this thread sees the state change (TS_DebugSuspendPending), it will avoid entering the forbid region by + // exiting the lock and pulsing the GC mode to try suspending for the debugger. If SysStartSuspendForDebug() sees the + // state change (that this thread is in the forbid region), then it will flag this thread appropriately to sync for + // suspend, and the debugger will later identify this thread as synced after this thread leaves the forbid region. + // + // The forbid region could be entered after acquiring the lock, but an additional memory barrier would be necessary. It + // is entered before the lock just to make use of the implicit memory barrier from acquiring the lock. It is anyway a + // prerequisite for entering a lock along with entering a forbid-suspend-for-debugger region, that the lock is not held + // for too long such that the thread can suspend for the debugger in reasonable time. + pThread->EnterForbidSuspendForDebuggerRegion(); + AcquireLock(pCrst); // implicit full memory barrier on all supported platforms + + // This can be an opportunistic check (instead of a volatile load), because if the GC mode change below does not suspend + // for the debugger (which is also possible with a volatile load), it will just loop around and try again if necessary + if (!pThread->HasThreadStateOpportunistic(Thread::TS_DebugSuspendPending)) + { + m_pThreadForExitingForbidRegion = pThread; + return; + } + + // Cannot enter the forbid region when a suspend for the debugger is pending because there are likely to be subsequent + // changes to the GC mode inside the lock, and this thread needs to suspend for the debugger in reasonable time. Exit + // the lock and pulse the GC mode to suspend for the debugger. + ReleaseLock(pCrst); + pThread->ExitForbidSuspendForDebuggerRegion(); + GCX_COOP(); + } +} + +CrstBase::CrstAndForbidSuspendForDebuggerHolder::~CrstAndForbidSuspendForDebuggerHolder() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + if (m_pCrst == nullptr) + { + return; + } + + ReleaseLock(m_pCrst); + if (m_pThreadForExitingForbidRegion != nullptr) + { + m_pThreadForExitingForbidRegion->ExitForbidSuspendForDebuggerRegion(); + } +} + #endif // !DACCESS_COMPILE #ifdef TEST_DATA_CONSISTENCY diff --git a/src/coreclr/src/vm/crst.h b/src/coreclr/src/vm/crst.h index 8bdcaae4f919..ed1e393002a9 100644 --- a/src/coreclr/src/vm/crst.h +++ b/src/coreclr/src/vm/crst.h @@ -362,13 +362,14 @@ friend class Crst; { m_dwFlags = 0; } + // ------------------------------- Holders ------------------------------ - public: - // - // CrstHolder is optimized for the common use that takes the lock in constructor - // and releases it in destructor. Users that require all Holder features - // can use CrstHolderWithState. - // +public: + // + // CrstHolder is optimized for the common use that takes the lock in constructor + // and releases it in destructor. Users that require all Holder features + // can use CrstHolderWithState. + // class CrstHolder { CrstBase * m_pCrst; @@ -397,11 +398,22 @@ friend class Crst; // Generally, it's better to use a regular CrstHolder, and then use the Release() / Acquire() methods on it. // This just exists to convert legacy OS Critical Section patterns over to holders. typedef DacHolder UnsafeCrstInverseHolder; + + class CrstAndForbidSuspendForDebuggerHolder + { + private: + CrstBase *m_pCrst; + Thread *m_pThreadForExitingForbidRegion; + + public: + CrstAndForbidSuspendForDebuggerHolder(CrstBase *pCrst); + ~CrstAndForbidSuspendForDebuggerHolder(); + }; }; typedef CrstBase::CrstHolder CrstHolder; typedef CrstBase::CrstHolderWithState CrstHolderWithState; - +typedef CrstBase::CrstAndForbidSuspendForDebuggerHolder CrstAndForbidSuspendForDebuggerHolder; // The CRST. class Crst : public CrstBase diff --git a/src/coreclr/src/vm/fptrstubs.cpp b/src/coreclr/src/vm/fptrstubs.cpp index f76b7951027a..cd3dd33d4d86 100644 --- a/src/coreclr/src/vm/fptrstubs.cpp +++ b/src/coreclr/src/vm/fptrstubs.cpp @@ -151,10 +151,12 @@ PCODE FuncPtrStubs::GetFuncPtrStub(MethodDesc * pMD, PrecodeType type) if (setTargetAfterAddingToHashTable) { + GCX_PREEMP(); + _ASSERTE(pMD->IsVersionableWithVtableSlotBackpatch()); PCODE temporaryEntryPoint = pMD->GetTemporaryEntryPoint(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCPreemp slotBackpatchLockHolder; // Set the funcptr stub's entry point to the current entry point inside the lock and after the funcptr stub is exposed, // to synchronize with backpatching in MethodDesc::BackpatchEntryPointSlots() diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index e378fad4affe..3fa602804b54 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -4903,8 +4903,10 @@ void MethodDesc::RecordAndBackpatchEntryPointSlot( { WRAPPER_NO_CONTRACT; + GCX_PREEMP(); + LoaderAllocator *mdLoaderAllocator = GetLoaderAllocator(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder; RecordAndBackpatchEntryPointSlot_Locked( mdLoaderAllocator, diff --git a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp index f6ea27e1fd9f..efe1d04cf6f8 100644 --- a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp +++ b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp @@ -65,7 +65,6 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr // MethodDescBackpatchInfoTracker CrstStatic MethodDescBackpatchInfoTracker::s_lock; -bool MethodDescBackpatchInfoTracker::s_isLocked = false; #ifndef DACCESS_COMPILE @@ -123,30 +122,4 @@ bool MethodDescBackpatchInfoTracker::IsLockOwnedByCurrentThread() } #endif // _DEBUG -#ifndef DACCESS_COMPILE -void MethodDescBackpatchInfoTracker::PollForDebuggerSuspension() -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - _ASSERTE(!IsLockOwnedByCurrentThread()); - - // If suspension is pending for the debugger, pulse the GC mode to suspend the thread here. Following this call, typically - // the lock is acquired and the GC mode is changed, and suspending there would cause FuncEvals to fail (see - // Debugger::FuncEvalSetup() at the reference to IsLockOwnedByAnyThread()). Since this thread is in preemptive mode, the - // debugger may think it's already suspended and it would be unfortunate to suspend the thread with the lock held. - Thread *thread = GetThread(); - _ASSERTE(thread != nullptr); - if (thread->HasThreadState(Thread::TS_DebugSuspendPending)) - { - GCX_COOP(); - } -} -#endif - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/src/vm/methoddescbackpatchinfo.h b/src/coreclr/src/vm/methoddescbackpatchinfo.h index a4d7a8c64fd6..2fc5e6c8e8f1 100644 --- a/src/coreclr/src/vm/methoddescbackpatchinfo.h +++ b/src/coreclr/src/vm/methoddescbackpatchinfo.h @@ -65,7 +65,6 @@ class MethodDescBackpatchInfoTracker { private: static CrstStatic s_lock; - static bool s_isLocked; class BackpatchInfoTrackerHashTraits : public NoRemoveDefaultCrossLoaderAllocatorHashTraits { @@ -97,63 +96,55 @@ class MethodDescBackpatchInfoTracker static bool IsLockOwnedByCurrentThread(); #endif -#ifndef DACCESS_COMPILE public: - static bool IsLockOwnedByAnyThread() + // To be used when the thread will remain in preemptive GC mode while holding the lock + class ConditionalLockHolderForGCPreemp : private CrstHolderWithState { - LIMITED_METHOD_CONTRACT; - return VolatileLoadWithoutBarrier(&s_isLocked); - } - - static void PollForDebuggerSuspension(); -#endif - -public: - class ConditionalLockHolder : private CrstHolderWithState - { - private: - bool m_isLocked; - public: - ConditionalLockHolder(bool acquireLock = true) + ConditionalLockHolderForGCPreemp(bool acquireLock = true) : CrstHolderWithState( #ifndef DACCESS_COMPILE acquireLock ? &s_lock : nullptr #else nullptr #endif - ), - m_isLocked(false) + ) { - WRAPPER_NO_CONTRACT; - - #ifndef DACCESS_COMPILE - if (acquireLock) + CONTRACTL { - _ASSERTE(IsLockOwnedByCurrentThread()); - _ASSERTE(!s_isLocked); - m_isLocked = true; - s_isLocked = true; + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } - #endif + CONTRACTL_END; } - ~ConditionalLockHolder() - { - WRAPPER_NO_CONTRACT; + DISABLE_COPY(ConditionalLockHolderForGCPreemp); + }; - #ifndef DACCESS_COMPILE - if (m_isLocked) +#ifndef DACCESS_COMPILE +public: + // To be used when the thread may enter cooperative GC mode while holding the lock. The thread enters a + // forbid-suspend-for-debugger region along with acquiring the lock, such that it would not suspend for the debugger while + // holding the lock, as that may otherwise cause a FuncEval to deadlock when trying to acquire the lock. + class ConditionalLockHolderForGCCoop : private CrstAndForbidSuspendForDebuggerHolder + { + public: + ConditionalLockHolderForGCCoop(bool acquireLock = true) + : CrstAndForbidSuspendForDebuggerHolder(acquireLock ? &s_lock : nullptr) + { + CONTRACTL { - _ASSERTE(IsLockOwnedByCurrentThread()); - _ASSERTE(s_isLocked); - s_isLocked = false; + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } - #endif + CONTRACTL_END; } - DISABLE_COPY(ConditionalLockHolder); + DISABLE_COPY(ConditionalLockHolderForGCCoop); }; +#endif public: MethodDescBackpatchInfoTracker() diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index e6ff77ab239b..d44c3cc062f8 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -95,7 +95,8 @@ PCODE MethodDesc::DoBackpatch(MethodTable * pMT, MethodTable *pDispatchingMT, BO // Only take the lock if the method is versionable with vtable slot backpatch, for recording slots and synchronizing with // backpatching slots - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder(isVersionableWithVtableSlotBackpatch); + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder( + isVersionableWithVtableSlotBackpatch); // Get the method entry point inside the lock above to synchronize with backpatching in // MethodDesc::BackpatchEntryPointSlots() diff --git a/src/coreclr/src/vm/rejit.cpp b/src/coreclr/src/vm/rejit.cpp index d9077a370ff6..ff180ceba33a 100644 --- a/src/coreclr/src/vm/rejit.cpp +++ b/src/coreclr/src/vm/rejit.cpp @@ -643,7 +643,7 @@ HRESULT ReJitManager::UpdateActiveILVersions( SHash::Iterator endIter = mgrToCodeActivationBatch.End(); { - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder; for (SHash::Iterator iter = beginIter; iter != endIter; iter++) { diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index ab09248fadc0..9dae20e9d487 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1606,6 +1606,7 @@ Thread::Thread() m_DeserializationTracker = NULL; m_currentPrepareCodeConfig = nullptr; + m_isInForbidSuspendForDebuggerRegion = false; #ifdef _DEBUG memset(dangerousObjRefs, 0, sizeof(dangerousObjRefs)); diff --git a/src/coreclr/src/vm/threads.h b/src/coreclr/src/vm/threads.h index a56bd5e4757c..03aea2ea03ce 100644 --- a/src/coreclr/src/vm/threads.h +++ b/src/coreclr/src/vm/threads.h @@ -4750,6 +4750,21 @@ class Thread private: PrepareCodeConfig *m_currentPrepareCodeConfig; + +#ifndef DACCESS_COMPILE +public: + bool IsInForbidSuspendForDebuggerRegion() const + { + LIMITED_METHOD_CONTRACT; + return m_isInForbidSuspendForDebuggerRegion; + } + + void EnterForbidSuspendForDebuggerRegion(); + void ExitForbidSuspendForDebuggerRegion(); +#endif + +private: + bool m_isInForbidSuspendForDebuggerRegion; }; // End of class Thread diff --git a/src/coreclr/src/vm/threads.inl b/src/coreclr/src/vm/threads.inl index 68fa53b0ab62..5dc6ef8d00e1 100644 --- a/src/coreclr/src/vm/threads.inl +++ b/src/coreclr/src/vm/threads.inl @@ -195,6 +195,24 @@ inline Thread::CurrentPrepareCodeConfigHolder::~CurrentPrepareCodeConfigHolder() config->SetNextInSameThread(nullptr); } +inline void Thread::EnterForbidSuspendForDebuggerRegion() +{ + WRAPPER_NO_CONTRACT; + _ASSERTE(this == GetThread()); + + _ASSERTE(!m_isInForbidSuspendForDebuggerRegion); + m_isInForbidSuspendForDebuggerRegion = true; +} + +inline void Thread::ExitForbidSuspendForDebuggerRegion() +{ + WRAPPER_NO_CONTRACT; + _ASSERTE(this == GetThread()); + + _ASSERTE(m_isInForbidSuspendForDebuggerRegion); + m_isInForbidSuspendForDebuggerRegion = false; +} + #ifdef HOST_WINDOWS inline size_t Thread::GetOffsetOfThreadStatic(void* pThreadStatic) { diff --git a/src/coreclr/src/vm/threadsuspend.cpp b/src/coreclr/src/vm/threadsuspend.cpp index 7d632cb27b1a..a9db60e8755e 100644 --- a/src/coreclr/src/vm/threadsuspend.cpp +++ b/src/coreclr/src/vm/threadsuspend.cpp @@ -2262,6 +2262,8 @@ void Thread::RareDisablePreemptiveGC() // waiting for GC _ASSERTE ((m_StateNC & Thread::TSNC_OwnsSpinLock) == 0); + _ASSERTE(!MethodDescBackpatchInfoTracker::IsLockOwnedByCurrentThread() || IsInForbidSuspendForDebuggerRegion()); + if (!GCHeapUtilities::IsGCHeapInitialized()) { goto Exit; @@ -2561,6 +2563,8 @@ void Thread::RareEnablePreemptiveGC() // holding a spin lock in coop mode and transit to preemp mode will cause deadlock on GC _ASSERTE ((m_StateNC & Thread::TSNC_OwnsSpinLock) == 0); + _ASSERTE(!MethodDescBackpatchInfoTracker::IsLockOwnedByCurrentThread() || IsInForbidSuspendForDebuggerRegion()); + FastInterlockOr (&m_fPreemptiveGCDisabled, 0); #if defined(STRESS_HEAP) && defined(_DEBUG) @@ -2582,7 +2586,7 @@ void Thread::RareEnablePreemptiveGC() // for GC, the fact that we are leaving the EE means that it no longer needs to // suspend us. But if we are doing a non-GC suspend, we need to block now. // Give the debugger precedence over user suspensions: - while (m_State & TS_DebugSuspendPending) + while ((m_State & TS_DebugSuspendPending) && !IsInForbidSuspendForDebuggerRegion()) { #ifdef DEBUGGING_SUPPORTED @@ -4609,7 +4613,11 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) // and the moment we enable TrapReturningThreads in MarkForSuspension. However, // nothing bad happens if the thread has transitioned to preemptive before marking // the thread for suspension; the thread will later be identified as Synced in - // SysSweepThreadsForDebug + // SysSweepThreadsForDebug. + // + // If the thread transitions to preemptive mode and into a forbid-suspend-for-debugger + // region, SysSweepThreadsForDebug would similarly identify the thread as synced + // after it leaves the forbid region. #else // DISABLE_THREADSUSPEND // Resume the thread and let it run to a safe point thread->ResumeThread(); @@ -4625,23 +4633,32 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) // they attempt to re-enter they will trip. thread->MarkForSuspension(TS_DebugSuspendPending); + if ( #ifdef DISABLE_THREADSUSPEND - // There'a a race above between the moment we first check m_fPreemptiveGCDisabled - // and the moment we enable TrapReturningThreads in MarkForSuspension. To account - // for that we check whether the thread moved into cooperative mode, and if it had - // we mark it as a DebugWillSync thread, that will be handled later in - // SysSweepThreadsForDebug - if (thread->m_fPreemptiveGCDisabled) + // There'a a race above between the moment we first check m_fPreemptiveGCDisabled + // and the moment we enable TrapReturningThreads in MarkForSuspension. To account + // for that we check whether the thread moved into cooperative mode, and if it had + // we mark it as a DebugWillSync thread, that will be handled later in + // SysSweepThreadsForDebug. + thread->m_fPreemptiveGCDisabled || +#endif // DISABLE_THREADSUSPEND + // The thread may have been suspended in a forbid-suspend-for-debugger region, or + // before the state change to set TS_DebugSuspendPending is made visible to other + // threads, the thread may have transitioned into a forbid region. In either case, + // flag the thread as TS_DebugWillSync and let SysSweepThreadsForDebug later + // identify the thread as synced after the thread leaves the forbid region. + thread->IsInForbidSuspendForDebuggerRegion()) { // Remember that this thread will be running to a safe point FastInterlockIncrement(&m_DebugWillSyncCount); thread->SetThreadState(TS_DebugWillSync); } -#else // DISABLE_THREADSUSPEND + +#ifndef DISABLE_THREADSUSPEND if (str == STR_Success) { thread->ResumeThread(); } -#endif // DISABLE_THREADSUSPEND +#endif // !DISABLE_THREADSUSPEND LOG((LF_CORDB, LL_INFO1000, "[0x%x] SUSPEND: gc enabled.\n", thread->GetThreadId())); @@ -4720,9 +4737,10 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync) // this thread will happen after any earlier writes on a different // thread. FastInterlockOr(&thread->m_fPreemptiveGCDisabled, 0); - if (!thread->m_fPreemptiveGCDisabled) + if (!thread->m_fPreemptiveGCDisabled && !thread->IsInForbidSuspendForDebuggerRegion()) { - // If the thread toggled to preemptive mode, then it's synced. + // If the thread toggled to preemptive mode and is not in a + // forbid-suspend-for-debugger region, then it's synced. goto Label_MarkThreadAsSynced; } else @@ -4756,7 +4774,7 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync) else if (str == STR_SwitchedOut) { // The thread was switched b/c of fiber-mode stuff. - if (!thread->m_fPreemptiveGCDisabled) + if (!thread->m_fPreemptiveGCDisabled && !thread->IsInForbidSuspendForDebuggerRegion()) { goto Label_MarkThreadAsSynced; } @@ -4771,15 +4789,27 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync) } else if (!thread->m_fPreemptiveGCDisabled) { - // If the thread toggled to preemptive mode, then it's synced. + // If the thread toggled to preemptive mode and is not in a + // forbid-suspend-for-debugger region, then it's synced. // We can safely resume the thread here b/c it's in PreemptiveMode and the // EE will trap anybody trying to re-enter cooperative. So letting it run free // won't hurt the runtime. + // + // If the thread is in a forbid-suspend-for-debugger region, the thread needs to + // be resumed to give it a chance to leave the forbid region. The EE will also + // trap the thread if it tries to re-enter a forbid region. _ASSERTE(str == STR_Success); thread->ResumeThread(); - goto Label_MarkThreadAsSynced; + if (!thread->IsInForbidSuspendForDebuggerRegion()) + { + goto Label_MarkThreadAsSynced; + } + else + { + continue; + } } #if defined(FEATURE_HIJACK) && !defined(TARGET_UNIX) // If the thread is in jitted code, HandledJitCase will try to hijack it; and the hijack diff --git a/src/coreclr/src/vm/tieredcompilation.cpp b/src/coreclr/src/vm/tieredcompilation.cpp index 01c663c8ba68..05fc6735ff74 100644 --- a/src/coreclr/src/vm/tieredcompilation.cpp +++ b/src/coreclr/src/vm/tieredcompilation.cpp @@ -448,8 +448,7 @@ void TieredCompilationManager::DeactivateTieringDelay() COUNT_T methodCount = methodsPendingCounting->GetCount(); CodeVersionManager *codeVersionManager = GetAppDomain()->GetCodeVersionManager(); - MethodDescBackpatchInfoTracker::PollForDebuggerSuspension(); - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder; + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder; // Backpatching entry point slots requires cooperative GC mode, see // MethodDescBackpatchInfoTracker::Backpatch_Locked(). The code version manager's table lock is an unsafe lock that @@ -825,11 +824,8 @@ void TieredCompilationManager::ActivateCodeVersion(NativeCodeVersion nativeCodeV HRESULT hr = S_OK; { bool mayHaveEntryPointSlotsToBackpatch = pMethod->MayHaveEntryPointSlotsToBackpatch(); - if (mayHaveEntryPointSlotsToBackpatch) - { - MethodDescBackpatchInfoTracker::PollForDebuggerSuspension(); - } - MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder(mayHaveEntryPointSlotsToBackpatch); + MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder( + mayHaveEntryPointSlotsToBackpatch); // Backpatching entry point slots requires cooperative GC mode, see // MethodDescBackpatchInfoTracker::Backpatch_Locked(). The code version manager's table lock is an unsafe lock that diff --git a/src/coreclr/src/vm/virtualcallstub.cpp b/src/coreclr/src/vm/virtualcallstub.cpp index 828b56093b8c..1f05aef25888 100644 --- a/src/coreclr/src/vm/virtualcallstub.cpp +++ b/src/coreclr/src/vm/virtualcallstub.cpp @@ -2765,7 +2765,7 @@ DispatchHolder *VirtualCallStubManager::GenerateDispatchStub(PCODE ad TADDR slot = holder->stub()->implTargetSlot(&slotType); pMD->RecordAndBackpatchEntryPointSlot(m_loaderAllocator, slot, slotType); - // RecordAndBackpatchEntryPointSlot() takes a lock that would exit and reenter cooperative GC mode + // RecordAndBackpatchEntryPointSlot() may exit and reenter cooperative GC mode *pMayHaveReenteredCooperativeGCMode = true; } #endif @@ -2827,7 +2827,7 @@ DispatchHolder *VirtualCallStubManager::GenerateDispatchStubLong(PCODE TADDR slot = holder->stub()->implTargetSlot(&slotType); pMD->RecordAndBackpatchEntryPointSlot(m_loaderAllocator, slot, slotType); - // RecordAndBackpatchEntryPointSlot() takes a lock that would exit and reenter cooperative GC mode + // RecordAndBackpatchEntryPointSlot() may exit and reenter cooperative GC mode *pMayHaveReenteredCooperativeGCMode = true; } #endif @@ -3020,7 +3020,7 @@ ResolveCacheElem *VirtualCallStubManager::GenerateResolveCacheElem(void *addrOfC (TADDR)&e->target, EntryPointSlots::SlotType_Normal); - // RecordAndBackpatchEntryPointSlot() takes a lock that would exit and reenter cooperative GC mode + // RecordAndBackpatchEntryPointSlot() may exit and reenter cooperative GC mode *pMayHaveReenteredCooperativeGCMode = true; } #endif From 7d3b804b6078a647835bfaf697369109855093b5 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 4 Aug 2020 18:18:21 -0400 Subject: [PATCH 250/755] [wasm] Make mono_wasm_get_obj_type () GC safe by doing all object access before calling into the runtime. (#40312) Part of the fix for https://github.com/dotnet/runtime/issues/40132. --- src/mono/wasm/runtime/driver.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index fec72602ed36..0400c39f8e15 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -587,6 +587,11 @@ mono_wasm_get_obj_type (MonoObject *obj) if (!obj) return 0; + /* Process obj before calling into the runtime, class_from_name () can invoke managed code */ + MonoClass *klass = mono_object_get_class (obj); + MonoType *type = mono_class_get_type (klass); + obj = NULL; + if (!datetime_class) datetime_class = mono_class_from_name (mono_get_corlib(), "System", "DateTime"); if (!datetimeoffset_class) @@ -598,9 +603,6 @@ mono_wasm_get_obj_type (MonoObject *obj) if (!safehandle_class) safehandle_class = mono_class_from_name (mono_get_corlib(), "System.Runtime.InteropServices", "SafeHandle"); - MonoClass *klass = mono_object_get_class (obj); - MonoType *type = mono_class_get_type (klass); - switch (mono_type_get_type (type)) { // case MONO_TYPE_CHAR: prob should be done not as a number? case MONO_TYPE_BOOLEAN: From 646cfa33683482eb6acacb69b6a4ea6a9af6ce0f Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 4 Aug 2020 17:25:03 -0700 Subject: [PATCH 251/755] Add LoggerColorBehavior (#40221) --- .../Microsoft.Extensions.Logging.Console.cs | 10 ++++- .../src/ConsoleLoggerOptions.cs | 2 +- .../src/ConsoleLoggerProvider.cs | 2 +- .../src/LoggerColorBehavior.cs | 27 ++++++++++++ .../src/SimpleConsoleFormatter.cs | 4 +- .../src/SimpleConsoleFormatterOptions.cs | 4 +- .../tests/ConsoleFormatterTests.cs | 2 +- .../tests/ConsoleLoggerExtensionsTests.cs | 8 ++-- .../tests/ConsoleLoggerTest.cs | 6 ++- .../tests/SimpleConsoleFormatterTests.cs | 41 +++++++++++++------ 10 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/LoggerColorBehavior.cs 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 c7ed2ea8cd4f..0ffa7866b579 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 @@ -50,7 +50,7 @@ public enum ConsoleLoggerFormat public partial class ConsoleLoggerOptions { public ConsoleLoggerOptions() { } - [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use SimpleConsoleFormatterOptions.DisableColors instead.", false)] + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use SimpleConsoleFormatterOptions.ColorBehavior instead.", false)] public bool DisableColors { get { throw null; } set { } } [System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Please use ConsoleLoggerOptions.FormatterName instead.", false)] public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } @@ -77,10 +77,16 @@ public partial class JsonConsoleFormatterOptions : Microsoft.Extensions.Logging. public JsonConsoleFormatterOptions() { } public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } } + public enum LoggerColorBehavior + { + Default = 0, + Enabled = 1, + Disabled = 2, + } public partial class SimpleConsoleFormatterOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { public SimpleConsoleFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } + public Microsoft.Extensions.Logging.Console.LoggerColorBehavior ColorBehavior { get { throw null; } set { } } public bool SingleLine { get { throw null; } set { } } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index cda6f89e52c1..5951124db396 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -13,7 +13,7 @@ public class ConsoleLoggerOptions /// /// Disables colors when . /// - [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use SimpleConsoleFormatterOptions.DisableColors instead.", false)] + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use SimpleConsoleFormatterOptions.ColorBehavior instead.", false)] public bool DisableColors { get; set; } #pragma warning disable CS0618 diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 4c5c596a4467..d5a22520a1e2 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -153,7 +153,7 @@ private void UpdateFormatterOptions(ConsoleFormatter formatter, ConsoleLoggerOpt { defaultFormatter.FormatterOptions = new SimpleConsoleFormatterOptions() { - DisableColors = deprecatedFromOptions.DisableColors, + ColorBehavior = deprecatedFromOptions.DisableColors ? LoggerColorBehavior.Disabled : LoggerColorBehavior.Enabled, IncludeScopes = deprecatedFromOptions.IncludeScopes, TimestampFormat = deprecatedFromOptions.TimestampFormat, UseUtcTimestamp = deprecatedFromOptions.UseUtcTimestamp, diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/LoggerColorBehavior.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/LoggerColorBehavior.cs new file mode 100644 index 000000000000..c38ec1969b43 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/LoggerColorBehavior.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Console +{ + /// + /// Determines when to use color when logging messages. + /// + public enum LoggerColorBehavior + { + /// + /// Use the default color behavior, enabling color except when the console output is redirected. + /// + /// + /// Enables color except when the console output is redirected. + /// + Default, + /// + /// Enable color for logging + /// + Enabled, + /// + /// Disable color for logging + /// + Disabled, + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs index f5b0571bc537..bc702ca0438a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatter.cs @@ -147,7 +147,9 @@ private static string GetLogLevelString(LogLevel logLevel) private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) { - if (FormatterOptions.DisableColors) + bool disableColors = (FormatterOptions.ColorBehavior == LoggerColorBehavior.Disabled) || + (FormatterOptions.ColorBehavior == LoggerColorBehavior.Default && System.Console.IsOutputRedirected); + if (disableColors) { return new ConsoleColors(null, null); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatterOptions.cs index 9ee51c149389..44aab1edc5ff 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/SimpleConsoleFormatterOptions.cs @@ -11,9 +11,9 @@ public class SimpleConsoleFormatterOptions : ConsoleFormatterOptions public SimpleConsoleFormatterOptions() { } /// - /// Disables colors when . + /// Determines when to use color when logging messages. /// - public bool DisableColors { get; set; } + public LoggerColorBehavior ColorBehavior { get; set; } /// /// When , the entire message gets logged in a single line. diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs index 580a745a12d8..78e17092a5f0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs @@ -126,7 +126,7 @@ public void Log_LogsCorrectTimestamp(string formatterName, LogLevel level) // Arrange var t = SetUp( new ConsoleLoggerOptions { FormatterName = formatterName }, - new SimpleConsoleFormatterOptions { TimestampFormat = "yyyy-MM-ddTHH:mm:sszz ", UseUtcTimestamp = false }, + new SimpleConsoleFormatterOptions { TimestampFormat = "yyyy-MM-ddTHH:mm:sszz ", UseUtcTimestamp = false, ColorBehavior = LoggerColorBehavior.Enabled }, new ConsoleFormatterOptions { TimestampFormat = "yyyy-MM-ddTHH:mm:sszz ", UseUtcTimestamp = false }, new JsonConsoleFormatterOptions { TimestampFormat = "yyyy-MM-ddTHH:mm:sszz ", diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs index a5f02fe897c5..739978be7d06 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs @@ -157,7 +157,7 @@ private class CustomOptions : ConsoleFormatterOptions public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() { var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { - new KeyValuePair("Console:FormatterOptions:DisableColors", "true"), + new KeyValuePair("Console:FormatterOptions:ColorBehavior", "Disabled"), new KeyValuePair("Console:FormatterOptions:SingleLine", "true"), new KeyValuePair("Console:FormatterOptions:TimestampFormat", "HH:mm "), new KeyValuePair("Console:FormatterOptions:UseUtcTimestamp", "true"), @@ -176,7 +176,7 @@ public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() var logger = (ConsoleLogger)consoleLoggerProvider.CreateLogger("Category"); Assert.Equal(ConsoleFormatterNames.Simple, logger.Options.FormatterName); var formatter = Assert.IsType(logger.Formatter); - Assert.True(formatter.FormatterOptions.DisableColors); + Assert.Equal(LoggerColorBehavior.Disabled, formatter.FormatterOptions.ColorBehavior); Assert.True(formatter.FormatterOptions.SingleLine); Assert.Equal("HH:mm ", formatter.FormatterOptions.TimestampFormat); Assert.True(formatter.FormatterOptions.UseUtcTimestamp); @@ -424,7 +424,7 @@ public void AddConsole_NullFormatterName_UsingDefaultFormat_IgnoreFormatterOptio Assert.Equal("HH:mm:ss ", formatter.FormatterOptions.TimestampFormat); // ignore FormatterOptions, using deprecated one Assert.False(formatter.FormatterOptions.UseUtcTimestamp); // not set anywhere, defaulted to false Assert.False(formatter.FormatterOptions.IncludeScopes); // setup using lambda wins over config - Assert.True(formatter.FormatterOptions.DisableColors); // setup using lambda + Assert.Equal(LoggerColorBehavior.Disabled, formatter.FormatterOptions.ColorBehavior); // setup using lambda } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -467,7 +467,7 @@ public void AddConsole_FormatterNameIsSet_UsingDefaultFormat_IgnoreDeprecatedAnd Assert.Equal("HH:mm ", formatter.FormatterOptions.TimestampFormat); // ignore deprecated, using FormatterOptions instead Assert.False(formatter.FormatterOptions.UseUtcTimestamp); // not set anywhere, defaulted to false Assert.True(formatter.FormatterOptions.IncludeScopes); // ignore deprecated set in lambda use FormatterOptions instead - Assert.False(formatter.FormatterOptions.DisableColors); // ignore deprecated set in lambda, defaulted to false + Assert.Equal(LoggerColorBehavior.Default, formatter.FormatterOptions.ColorBehavior); // ignore deprecated set in lambda, defaulted to false } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs index 9f6a99f5d7d9..ebe9985a245d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs @@ -86,7 +86,8 @@ private static void VerifyDeprecatedPropertiesUsedOnNullFormatterName(ConsoleLog Assert.Equal(formatter.FormatterOptions.IncludeScopes, logger.Options.IncludeScopes); Assert.Equal(formatter.FormatterOptions.UseUtcTimestamp, logger.Options.UseUtcTimestamp); Assert.Equal(formatter.FormatterOptions.TimestampFormat, logger.Options.TimestampFormat); - Assert.Equal(formatter.FormatterOptions.DisableColors, logger.Options.DisableColors); + Assert.Equal(formatter.FormatterOptions.ColorBehavior, + logger.Options.DisableColors ? LoggerColorBehavior.Disabled : LoggerColorBehavior.Enabled); } else { @@ -102,7 +103,8 @@ private static void UpdateFormatterOptions(ConsoleFormatter formatter, ConsoleLo // kept for deprecated apis: if (formatter is SimpleConsoleFormatter defaultFormatter) { - defaultFormatter.FormatterOptions.DisableColors = deprecatedFromOptions.DisableColors; + defaultFormatter.FormatterOptions.ColorBehavior = deprecatedFromOptions.DisableColors ? + LoggerColorBehavior.Disabled : LoggerColorBehavior.Enabled; defaultFormatter.FormatterOptions.IncludeScopes = deprecatedFromOptions.IncludeScopes; defaultFormatter.FormatterOptions.TimestampFormat = deprecatedFromOptions.TimestampFormat; defaultFormatter.FormatterOptions.UseUtcTimestamp = deprecatedFromOptions.UseUtcTimestamp; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs index 9a54c78f3696..3bb1fa491ece 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs @@ -9,13 +9,16 @@ namespace Microsoft.Extensions.Logging.Console.Test { public class SimpleConsoleFormatterTests : ConsoleFormatterTests { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public void Log_WritingScopes_LogsWithCorrectColors() + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(LoggerColorBehavior.Default)] + [InlineData(LoggerColorBehavior.Enabled)] + [InlineData(LoggerColorBehavior.Disabled)] + public void Log_WritingScopes_LogsWithCorrectColorsWhenColorEnabled(LoggerColorBehavior colorBehavior) { // Arrange var t = SetUp( new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Simple }, - new SimpleConsoleFormatterOptions { IncludeScopes = true } + new SimpleConsoleFormatterOptions { IncludeScopes = true, ColorBehavior = colorBehavior } ); var logger = t.Logger; var sink = t.Sink; @@ -29,13 +32,25 @@ public void Log_WritingScopes_LogsWithCorrectColors() } // Assert - Assert.Equal(2, sink.Writes.Count); - var write = sink.Writes[0]; - Assert.Equal(ConsoleColor.Black, write.BackgroundColor); - Assert.Equal(ConsoleColor.DarkGreen, write.ForegroundColor); - write = sink.Writes[1]; - Assert.Equal(TestConsole.DefaultBackgroundColor, write.BackgroundColor); - Assert.Equal(TestConsole.DefaultForegroundColor, write.ForegroundColor); + switch (colorBehavior) + { + case LoggerColorBehavior.Enabled: + Assert.Equal(2, sink.Writes.Count); + var write = sink.Writes[0]; + Assert.Equal(ConsoleColor.Black, write.BackgroundColor); + Assert.Equal(ConsoleColor.DarkGreen, write.ForegroundColor); + write = sink.Writes[1]; + Assert.Equal(TestConsole.DefaultBackgroundColor, write.BackgroundColor); + Assert.Equal(TestConsole.DefaultForegroundColor, write.ForegroundColor); + break; + case LoggerColorBehavior.Default: + case LoggerColorBehavior.Disabled: + Assert.Equal(1, sink.Writes.Count); + write = sink.Writes[0]; + Assert.Equal(TestConsole.DefaultBackgroundColor, write.BackgroundColor); + Assert.Equal(TestConsole.DefaultForegroundColor, write.ForegroundColor); + break; + } } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -44,7 +59,7 @@ public void Log_NoLogScope_DoesNotWriteAnyScopeContentToOutput() // Arrange var t = SetUp( new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Simple }, - new SimpleConsoleFormatterOptions { IncludeScopes = true } + new SimpleConsoleFormatterOptions { IncludeScopes = true, ColorBehavior = LoggerColorBehavior.Enabled } ); var logger = t.Logger; var sink = t.Sink; @@ -68,7 +83,7 @@ public void Log_SingleLine_LogsWhenMessageIsNotProvided() // Arrange var t = SetUp( new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Simple }, - new SimpleConsoleFormatterOptions { SingleLine = true } + new SimpleConsoleFormatterOptions { SingleLine = true, ColorBehavior = LoggerColorBehavior.Enabled } ); var logger = (ILogger)t.Logger; var sink = t.Sink; @@ -99,7 +114,7 @@ public void Log_SingleLine_LogsWhenBothMessageAndExceptionProvided() // Arrange var t = SetUp( new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Simple }, - new SimpleConsoleFormatterOptions { SingleLine = true } + new SimpleConsoleFormatterOptions { SingleLine = true, ColorBehavior = LoggerColorBehavior.Enabled } ); var logger = (ILogger)t.Logger; var sink = t.Sink; From 5ad9b0e2333b9031dd26a5930f0bec1870cc1367 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Wed, 5 Aug 2020 04:00:13 +0200 Subject: [PATCH 252/755] Add Browser specific PersistedFiles implementation (#39350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Browser specific PersistedFiles implementation Simplified the implementation removes dependency on several native calls which all return only default values. Co-authored-by: Alexander Köplinger --- .../System.Private.CoreLib.Shared.projitems | 23 ++++++++++--------- .../src/System/IO/PersistedFiles.Browser.cs | 10 ++++++++ .../tests/System/EnvironmentTests.cs | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/IO/PersistedFiles.Browser.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 7add08bf9d38..1715d433f8d0 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -47,7 +47,6 @@ - @@ -1708,15 +1707,9 @@ Common\Interop\Unix\System.Native\Interop.GetCwd.cs - - Common\Interop\Unix\System.Native\Interop.GetEUid.cs - Common\Interop\Unix\System.Native\Interop.GetHostName.cs - - Common\Interop\Unix\System.Native\Interop.GetPwUid.cs - Common\Interop\Unix\System.Native\Interop.GetRandomBytes.cs @@ -1794,7 +1787,6 @@ - @@ -1802,14 +1794,11 @@ - - - @@ -1822,14 +1811,26 @@ + + Common\Interop\Unix\System.Native\Interop.GetEUid.cs + + + Common\Interop\Unix\System.Native\Interop.GetPwUid.cs + Common\Interop\Unix\System.Native\Interop.GetPid.cs + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/PersistedFiles.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/IO/PersistedFiles.Browser.cs new file mode 100644 index 000000000000..06b606ac29d3 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/IO/PersistedFiles.Browser.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.IO +{ + internal static partial class PersistedFiles + { + internal static string? GetHomeDirectory() => Environment.GetEnvironmentVariable("HOME"); + } +} diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index ff8eb26cd243..136e7a928175 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -317,7 +317,7 @@ public void FailFast_ExceptionStackTrace_InnerException() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Tests OS-specific environment + [PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Browser)] // Tests OS-specific environment public void GetFolderPath_Unix_PersonalIsHomeAndUserProfile() { Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.Personal)); From a1339cc3e41cee79bfbeafde9a7462523f70cef4 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 4 Aug 2020 21:13:21 -0500 Subject: [PATCH 253/755] Annotate Extensions.Options to make it linker friendly (#40294) * Annotate Extensions.Options to make it linker friendly Fix #40236 --- .../Microsoft.Extensions.Options.sln | 14 ++-- .../ref/Microsoft.Extensions.Options.cs | 28 +++---- .../ref/Microsoft.Extensions.Options.csproj | 2 + .../src/IOptions.cs | 5 +- .../src/IOptionsFactory.cs | 5 +- .../src/IOptionsMonitor.cs | 3 +- .../src/IOptionsMonitorCache.cs | 4 +- .../src/IOptionsSnapshot.cs | 6 +- .../src/Microsoft.Extensions.Options.csproj | 5 ++ .../src/Options.cs | 8 +- .../src/OptionsCache.cs | 5 +- .../src/OptionsFactory.cs | 5 +- .../src/OptionsManager.cs | 7 +- .../src/OptionsMonitor.cs | 6 +- .../src/OptionsMonitorExtensions.cs | 7 +- .../src/OptionsServiceCollectionExtensions.cs | 11 ++- .../src/OptionsWrapper.cs | 6 +- .../ComplexOptions.cs | 0 .../FakeChangeToken.cs | 0 .../FakeOptions.cs | 0 .../FakeOptionsFactory.cs | 0 .../Microsoft.Extensions.Options.Tests.csproj | 0 .../OptionsBuilderTest.cs | 0 .../OptionsFactoryTests.cs | 0 .../OptionsMonitorTest.cs | 0 .../OptionsSnapshotTest.cs | 0 .../OptionsTest.cs | 0 .../OptionsValidationTests.cs | 0 .../tests/TrimmingTests/ConfigureTests.cs | 78 +++++++++++++++++++ ...soft.Extensions.Options.TrimmingTests.proj | 16 ++++ 30 files changed, 183 insertions(+), 38 deletions(-) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/ComplexOptions.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/FakeChangeToken.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/FakeOptions.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/FakeOptionsFactory.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/Microsoft.Extensions.Options.Tests.csproj (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsBuilderTest.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsFactoryTests.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsMonitorTest.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsSnapshotTest.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsTest.cs (100%) rename src/libraries/Microsoft.Extensions.Options/tests/{ => Microsoft.Extensions.Options.Tests}/OptionsValidationTests.cs (100%) create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj diff --git a/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.sln b/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.sln index b67b0a590f1f..569f822cf139 100644 --- a/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.sln +++ b/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.sln @@ -13,9 +13,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Option EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "src\Microsoft.Extensions.Options.csproj", "{0ACF563C-7E53-469A-A61D-B93916DED810}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.Tests", "tests\Microsoft.Extensions.Options.Tests.csproj", "{77771F73-3122-49BD-85D8-6D880B9902F3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{A5C2304B-0A92-427A-BD01-C7927EFA8B78}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{A5C2304B-0A92-427A-BD01-C7927EFA8B78}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.Tests", "tests\Microsoft.Extensions.Options.Tests\Microsoft.Extensions.Options.Tests.csproj", "{0905577D-D2A0-4EF1-848B-8A99F12BE3D0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -31,14 +31,14 @@ Global {0ACF563C-7E53-469A-A61D-B93916DED810}.Debug|Any CPU.Build.0 = Debug|Any CPU {0ACF563C-7E53-469A-A61D-B93916DED810}.Release|Any CPU.ActiveCfg = Release|Any CPU {0ACF563C-7E53-469A-A61D-B93916DED810}.Release|Any CPU.Build.0 = Release|Any CPU - {77771F73-3122-49BD-85D8-6D880B9902F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77771F73-3122-49BD-85D8-6D880B9902F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77771F73-3122-49BD-85D8-6D880B9902F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77771F73-3122-49BD-85D8-6D880B9902F3}.Release|Any CPU.Build.0 = Release|Any CPU {A5C2304B-0A92-427A-BD01-C7927EFA8B78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A5C2304B-0A92-427A-BD01-C7927EFA8B78}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5C2304B-0A92-427A-BD01-C7927EFA8B78}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5C2304B-0A92-427A-BD01-C7927EFA8B78}.Release|Any CPU.Build.0 = Release|Any CPU + {0905577D-D2A0-4EF1-848B-8A99F12BE3D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0905577D-D2A0-4EF1-848B-8A99F12BE3D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0905577D-D2A0-4EF1-848B-8A99F12BE3D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0905577D-D2A0-4EF1-848B-8A99F12BE3D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -46,8 +46,8 @@ Global GlobalSection(NestedProjects) = preSolution {9F96CC5A-969C-47FA-81DB-7093598A226F} = {5827CC1E-1A61-4799-96B4-AB1052346A52} {0ACF563C-7E53-469A-A61D-B93916DED810} = {9205B11D-A45B-4F2C-BF37-8C5F26FCBDB7} - {77771F73-3122-49BD-85D8-6D880B9902F3} = {CAB34510-96B9-422E-904F-C03476004E13} {A5C2304B-0A92-427A-BD01-C7927EFA8B78} = {CAB34510-96B9-422E-904F-C03476004E13} + {0905577D-D2A0-4EF1-848B-8A99F12BE3D0} = {CAB34510-96B9-422E-904F-C03476004E13} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5DE09ECD-4E45-4B08-B44A-327EF5203D1B} diff --git a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.cs b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.cs index 32f254eff792..d0b8af0aec10 100644 --- a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.cs +++ b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.cs @@ -13,8 +13,8 @@ public static partial class OptionsServiceCollectionExtensions public static Microsoft.Extensions.Options.OptionsBuilder AddOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TOptions : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureAll(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureOptions) where TOptions : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, object configureInstance) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type configureType) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TConfigureOptions : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors)] System.Type configureType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TConfigureOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TConfigureOptions : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureOptions) where TOptions : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureOptions) where TOptions : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection PostConfigureAll(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureOptions) where TOptions : class { throw null; } @@ -106,28 +106,28 @@ public partial interface IOptionsChangeTokenSource string Name { get; } Microsoft.Extensions.Primitives.IChangeToken GetChangeToken(); } - public partial interface IOptionsFactory where TOptions : class + public partial interface IOptionsFactory<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> where TOptions : class { TOptions Create(string name); } - public partial interface IOptionsMonitorCache where TOptions : class + public partial interface IOptionsMonitorCache<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> where TOptions : class { void Clear(); TOptions GetOrAdd(string name, System.Func createOptions); bool TryAdd(string name, TOptions options); bool TryRemove(string name); } - public partial interface IOptionsMonitor + public partial interface IOptionsMonitor<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions> { TOptions CurrentValue { get; } TOptions Get(string name); System.IDisposable OnChange(System.Action listener); } - public partial interface IOptionsSnapshot : Microsoft.Extensions.Options.IOptions where TOptions : class + public partial interface IOptionsSnapshot<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions> : Microsoft.Extensions.Options.IOptions where TOptions : class { TOptions Get(string name); } - public partial interface IOptions where TOptions : class + public partial interface IOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions> where TOptions : class { TOptions Value { get; } } @@ -142,7 +142,7 @@ public partial interface IValidateOptions where TOptions : class public static partial class Options { public static readonly string DefaultName; - public static Microsoft.Extensions.Options.IOptions Create(TOptions options) where TOptions : class { throw null; } + public static Microsoft.Extensions.Options.IOptions Create<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions>(TOptions options) where TOptions : class { throw null; } } public partial class OptionsBuilder where TOptions : class { @@ -174,7 +174,7 @@ public OptionsBuilder(Microsoft.Extensions.DependencyInjection.IServiceCollectio public virtual Microsoft.Extensions.Options.OptionsBuilder Validate(System.Func validation) { throw null; } public virtual Microsoft.Extensions.Options.OptionsBuilder Validate(System.Func validation, string failureMessage) { throw null; } } - public partial class OptionsCache : Microsoft.Extensions.Options.IOptionsMonitorCache where TOptions : class + public partial class OptionsCache<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptionsMonitorCache where TOptions : class { public OptionsCache() { } public void Clear() { } @@ -182,14 +182,14 @@ public void Clear() { } public virtual bool TryAdd(string name, TOptions options) { throw null; } public virtual bool TryRemove(string name) { throw null; } } - public partial class OptionsFactory : Microsoft.Extensions.Options.IOptionsFactory where TOptions : class + public partial class OptionsFactory<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptionsFactory where TOptions : class { public OptionsFactory(System.Collections.Generic.IEnumerable> setups, System.Collections.Generic.IEnumerable> postConfigures) { } public OptionsFactory(System.Collections.Generic.IEnumerable> setups, System.Collections.Generic.IEnumerable> postConfigures, System.Collections.Generic.IEnumerable> validations) { } public TOptions Create(string name) { throw null; } protected virtual TOptions CreateInstance(string name) { throw null; } } - public partial class OptionsManager : Microsoft.Extensions.Options.IOptions, Microsoft.Extensions.Options.IOptionsSnapshot where TOptions : class + public partial class OptionsManager<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptions, Microsoft.Extensions.Options.IOptionsSnapshot where TOptions : class { public OptionsManager(Microsoft.Extensions.Options.IOptionsFactory factory) { } public TOptions Value { get { throw null; } } @@ -197,9 +197,9 @@ public OptionsManager(Microsoft.Extensions.Options.IOptionsFactory fac } public static partial class OptionsMonitorExtensions { - public static System.IDisposable OnChange(this Microsoft.Extensions.Options.IOptionsMonitor monitor, System.Action listener) { throw null; } + public static System.IDisposable OnChange<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions>(this Microsoft.Extensions.Options.IOptionsMonitor monitor, System.Action listener) { throw null; } } - public partial class OptionsMonitor : Microsoft.Extensions.Options.IOptionsMonitor, System.IDisposable where TOptions : class + public partial class OptionsMonitor<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptionsMonitor, System.IDisposable where TOptions : class { public OptionsMonitor(Microsoft.Extensions.Options.IOptionsFactory factory, System.Collections.Generic.IEnumerable> sources, Microsoft.Extensions.Options.IOptionsMonitorCache cache) { } public TOptions CurrentValue { get { throw null; } } @@ -215,7 +215,7 @@ public OptionsValidationException(string optionsName, System.Type optionsType, S public string OptionsName { get { throw null; } } public System.Type OptionsType { get { throw null; } } } - public partial class OptionsWrapper : Microsoft.Extensions.Options.IOptions where TOptions : class + public partial class OptionsWrapper<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptions where TOptions : class { public OptionsWrapper(TOptions options) { } public TOptions Value { get { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj index a71d9b27e599..c441c3ec38a1 100644 --- a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj @@ -4,6 +4,8 @@ + + diff --git a/src/libraries/Microsoft.Extensions.Options/src/IOptions.cs b/src/libraries/Microsoft.Extensions.Options/src/IOptions.cs index de08efd501d2..0ceca9fb0c94 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/IOptions.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/IOptions.cs @@ -1,13 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; + namespace Microsoft.Extensions.Options { /// /// Used to retrieve configured instances. /// /// The type of options being requested. - public interface IOptions where TOptions : class + public interface IOptions<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] out TOptions> + where TOptions : class { /// /// The default configured instance diff --git a/src/libraries/Microsoft.Extensions.Options/src/IOptionsFactory.cs b/src/libraries/Microsoft.Extensions.Options/src/IOptionsFactory.cs index e8d8a17a8476..82077f13cef7 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/IOptionsFactory.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/IOptionsFactory.cs @@ -1,13 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; + namespace Microsoft.Extensions.Options { /// /// Used to create instances. /// /// The type of options being requested. - public interface IOptionsFactory where TOptions : class + public interface IOptionsFactory<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> + where TOptions : class { /// /// Returns a configured instance with the given name. diff --git a/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs b/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs index 9f01a495de94..10c51cba1aac 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -9,7 +10,7 @@ namespace Microsoft.Extensions.Options /// Used for notifications when instances change. /// /// The options type. - public interface IOptionsMonitor + public interface IOptionsMonitor<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] out TOptions> { /// /// Returns the current instance with the . diff --git a/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitorCache.cs b/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitorCache.cs index 0706192059d4..f06062d3eae0 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitorCache.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitorCache.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -9,7 +10,8 @@ namespace Microsoft.Extensions.Options /// Used by to cache instances. /// /// The type of options being requested. - public interface IOptionsMonitorCache where TOptions : class + public interface IOptionsMonitorCache<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> + where TOptions : class { /// /// Gets a named options instance, or adds a new instance created with . diff --git a/src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs b/src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs index 603be4b7c857..d29a381f0cb5 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs @@ -1,13 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; + namespace Microsoft.Extensions.Options { /// /// Used to access the value of for the lifetime of a request. /// /// Options type. - public interface IOptionsSnapshot : IOptions where TOptions : class + public interface IOptionsSnapshot<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] out TOptions> : + IOptions + where TOptions : class { /// /// Returns a configured instance with the given name. diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index d9840099d4ed..4da5f5e410f2 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -7,6 +7,11 @@ false + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options/src/Options.cs b/src/libraries/Microsoft.Extensions.Options/src/Options.cs index bd9ca34ef643..7c6ea6bc34f6 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Options.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/Options.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 Microsoft.Extensions.Options { /// @@ -8,6 +10,9 @@ namespace Microsoft.Extensions.Options /// public static class Options { + // By default, we're going to keep public, parameterless constructor on any Options class. + internal const DynamicallyAccessedMemberTypes DynamicallyAccessedMembers = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor; + /// /// The default name used for options instances: "". /// @@ -19,7 +24,8 @@ public static class Options /// Options type. /// Options object. /// Wrapped options object. - public static IOptions Create(TOptions options) where TOptions : class + public static IOptions Create<[DynamicallyAccessedMembers(DynamicallyAccessedMembers)] TOptions>(TOptions options) + where TOptions : class { return new OptionsWrapper(options); } diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs index 8bf2b3388b2f..b4094fe54de2 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -10,7 +11,9 @@ namespace Microsoft.Extensions.Options /// Used to cache instances. /// /// The type of options being requested. - public class OptionsCache : IOptionsMonitorCache where TOptions : class + public class OptionsCache<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> : + IOptionsMonitorCache + where TOptions : class { private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>(StringComparer.Ordinal); diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs index c20cd9ee3a37..dec163c398d3 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -10,7 +11,9 @@ namespace Microsoft.Extensions.Options /// Implementation of . /// /// The type of options being requested. - public class OptionsFactory : IOptionsFactory where TOptions : class + public class OptionsFactory<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> : + IOptionsFactory + where TOptions : class { private readonly IEnumerable> _setups; private readonly IEnumerable> _postConfigures; diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs index 20182ab52109..71b5a134f351 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs @@ -1,13 +1,18 @@ // 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 Microsoft.Extensions.Options { /// /// Implementation of and . /// /// Options type. - public class OptionsManager : IOptions, IOptionsSnapshot where TOptions : class + public class OptionsManager<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> : + IOptions, + IOptionsSnapshot + where TOptions : class { private readonly IOptionsFactory _factory; private readonly OptionsCache _cache = new OptionsCache(); // Note: this is a private cache diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs index 6fe92a3c40f8..7c43e2864cdf 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Primitives; namespace Microsoft.Extensions.Options @@ -11,7 +12,10 @@ namespace Microsoft.Extensions.Options /// Implementation of . /// /// Options type. - public class OptionsMonitor : IOptionsMonitor, IDisposable where TOptions : class + public class OptionsMonitor<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> : + IOptionsMonitor, + IDisposable + where TOptions : class { private readonly IOptionsMonitorCache _cache; private readonly IOptionsFactory _factory; diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitorExtensions.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitorExtensions.cs index aecb3ec75800..518a5744f85b 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitorExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitorExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -16,7 +17,9 @@ public static class OptionsMonitorExtensions /// The IOptionsMonitor. /// The action to be invoked when has changed. /// An which should be disposed to stop listening for changes. - public static IDisposable OnChange(this IOptionsMonitor monitor, Action listener) - => monitor.OnChange((o, _) => listener(o)); + public static IDisposable OnChange<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions>( + this IOptionsMonitor monitor, + Action listener) + => monitor.OnChange((o, _) => listener(o)); } } diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs index 2a1aec0395ab..10341d4e217d 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -140,8 +141,10 @@ public static IServiceCollection PostConfigureAll(this IServiceCollect /// The type that will configure options. /// The to add the services to. /// The so that additional calls can be chained. - public static IServiceCollection ConfigureOptions(this IServiceCollection services) where TConfigureOptions : class - => services.ConfigureOptions(typeof(TConfigureOptions)); + public static IServiceCollection ConfigureOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TConfigureOptions>( + this IServiceCollection services) + where TConfigureOptions : class + => services.ConfigureOptions(typeof(TConfigureOptions)); private static bool IsAction(Type type) => (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Action<>)); @@ -174,7 +177,9 @@ private static IEnumerable FindConfigurationServices(Type type) /// The to add the services to. /// The type that will configure options. /// The so that additional calls can be chained. - public static IServiceCollection ConfigureOptions(this IServiceCollection services, Type configureType) + public static IServiceCollection ConfigureOptions( + this IServiceCollection services, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type configureType) { services.AddOptions(); IEnumerable serviceTypes = FindConfigurationServices(configureType); diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsWrapper.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsWrapper.cs index ca47d5e78219..cdc295802aac 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsWrapper.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsWrapper.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Options { @@ -9,7 +9,9 @@ namespace Microsoft.Extensions.Options /// wrapper that returns the options instance. /// /// Options type. - public class OptionsWrapper : IOptions where TOptions : class + public class OptionsWrapper<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> : + IOptions + where TOptions : class { /// /// Intializes the wrapper with the options instance to return. diff --git a/src/libraries/Microsoft.Extensions.Options/tests/ComplexOptions.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/ComplexOptions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/ComplexOptions.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/ComplexOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/FakeChangeToken.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeChangeToken.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/FakeChangeToken.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeChangeToken.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/FakeOptions.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeOptions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/FakeOptions.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/FakeOptionsFactory.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeOptionsFactory.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/FakeOptionsFactory.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/FakeOptionsFactory.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/Microsoft.Extensions.Options.Tests.csproj similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests.csproj rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/Microsoft.Extensions.Options.Tests.csproj diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsBuilderTest.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsBuilderTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsBuilderTest.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsBuilderTest.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsFactoryTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsFactoryTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsFactoryTests.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsFactoryTests.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsMonitorTest.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsMonitorTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsMonitorTest.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsMonitorTest.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsSnapshotTest.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsSnapshotTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsSnapshotTest.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsSnapshotTest.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsTest.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsTest.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/OptionsValidationTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsValidationTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Options/tests/OptionsValidationTests.cs rename to src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsValidationTests.cs diff --git a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs new file mode 100644 index 000000000000..870b27bbe9e1 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; + +class Program +{ + static int Main(string[] args) + { + ServiceCollection services = new ServiceCollection(); + services.Configure(o => + { + o.OptionValue = 99; + }); + services.ConfigureOptions(); + services.AddOptions() + .Configure>((b, a) => + { + b.OptionString = a.Value.OptionValue.ToString(); + }); + + ServiceProvider provider = services.BuildServiceProvider(); + + OptionsA optionsA = provider.GetService>().Value; + OptionsB optionsB = provider.GetService>().CurrentValue; + OptionsC optionsC = provider.GetService>().Value; + OptionsD optionsD = provider.GetService>().Create(string.Empty); + + if (optionsA.OptionValue != 99 || + optionsA.PostConfigureOption != 101 || + optionsB.OptionString != "99" || + optionsC is null || + optionsD is null) + { + return -1; + } + + return 100; + } + + private class OptionsA + { + public int OptionValue { get; set; } + public int PostConfigureOption { get; set; } + } + + private class OptionsAPostConfigure : IPostConfigureOptions + { + public void PostConfigure(string name, OptionsA options) + { + if (name.Length != 0) + { + throw new ArgumentException("name must be empty", nameof(name)); + } + + options.PostConfigureOption = 101; + } + } + + private class OptionsB + { + public string OptionString { get; set; } + } + + // Note: OptionsC is never configured + private class OptionsC + { + public string OptionString { get; set; } + } + + // Note: OptionsD is never configured + private class OptionsD + { + public string OptionString { get; set; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj new file mode 100644 index 000000000000..669ac862ad7b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj @@ -0,0 +1,16 @@ + + + + + + Microsoft.Extensions.Options; + Microsoft.Extensions.DependencyInjection + + + + + + + + + From 29257871a189d90bfbbe8c04e4cdc22086ecb5ab Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 4 Aug 2020 22:58:54 -0500 Subject: [PATCH 254/755] Add runtime feature checks for 5.0 browser (#40347) --- .../Runtime/CompilerServices/RuntimeFeatureTests.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs b/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs index b724ea170a3d..1c2bc0a6efea 100644 --- a/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs +++ b/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs @@ -36,6 +36,14 @@ public static void DynamicCode_Jit() Assert.True(RuntimeFeature.IsDynamicCodeSupported); Assert.True(RuntimeFeature.IsDynamicCodeCompiled); } + + [Fact] + [PlatformSpecific(TestPlatforms.Browser)] + public static void DynamicCode_Browser() + { + Assert.True(RuntimeFeature.IsDynamicCodeSupported); + Assert.False(RuntimeFeature.IsDynamicCodeCompiled); + } public static IEnumerable GetStaticFeatureNames() { From 02db286a282fae25186282236164f52c0aa6c340 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Tue, 4 Aug 2020 21:02:17 -0700 Subject: [PATCH 255/755] Remove potential NULLCHECK creation after LIR on arm32. (#40349) * Use `TransformUnusedIndirection` in LIR liveness. * Use `TYP_INT` as `TransformUnusedIndirection` does. * fix grammar. --- src/coreclr/src/jit/compiler.cpp | 7 ++++++- src/coreclr/src/jit/liveness.cpp | 4 ++-- src/coreclr/src/jit/lower.cpp | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index 4e1140efe426..b836a2efa2f2 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -9293,11 +9293,16 @@ bool Compiler::lvaIsOSRLocal(unsigned varNum) // tree - the node to change; // basicBlock - basic block of the node. // +// Notes: +// the function should not be called after lowering for platforms that do not support +// emitting NULLCHECK nodes, like arm32. Use `Lowering::TransformUnusedIndirection` +// that handles it and calls this function when appropriate. +// void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block) { assert(tree->OperIs(GT_FIELD, GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK)); tree->ChangeOper(GT_NULLCHECK); - tree->ChangeType(TYP_BYTE); + tree->ChangeType(TYP_INT); block->bbFlags |= BBF_HAS_NULLCHECK; optMethodFlags |= OMF_HAS_NULLCHECK; } diff --git a/src/coreclr/src/jit/liveness.cpp b/src/coreclr/src/jit/liveness.cpp index 75cf6e42dda7..5c3c86010fda 100644 --- a/src/coreclr/src/jit/liveness.cpp +++ b/src/coreclr/src/jit/liveness.cpp @@ -2127,8 +2127,8 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR if (!removed && node->IsUnusedValue()) { // IR doesn't expect dummy uses of `GT_OBJ/BLK/DYN_BLK`. - JITDUMP("Replace an unused OBJ/BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); - gtChangeOperToNullCheck(node, block); + JITDUMP("Transform an unused OBJ/BLK node [%06d]\n", dspTreeID(node)); + Lowering::TransformUnusedIndirection(node->AsIndir(), this, block); } } break; diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 150bfd2d38d6..61e15a339b4a 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -6488,7 +6488,7 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas // - On XARCH, use GT_IND if we have a contained address, and GT_NULLCHECK otherwise. // In all cases, change the type to TYP_INT. // - assert(ind->OperIs(GT_NULLCHECK, GT_IND)); + assert(ind->OperIs(GT_NULLCHECK, GT_IND, GT_BLK, GT_OBJ)); ind->gtType = TYP_INT; #ifdef TARGET_ARM64 @@ -6499,12 +6499,12 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas bool useNullCheck = !ind->Addr()->isContained(); #endif // !TARGET_XARCH - if (useNullCheck && ind->OperIs(GT_IND)) + if (useNullCheck && !ind->OperIs(GT_NULLCHECK)) { comp->gtChangeOperToNullCheck(ind, block); ind->ClearUnusedValue(); } - else if (!useNullCheck && ind->OperIs(GT_NULLCHECK)) + else if (!useNullCheck && !ind->OperIs(GT_IND)) { ind->ChangeOper(GT_IND); ind->SetUnusedValue(); From 92e9e885d933ecc7370136701ad22be850c39ed0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 5 Aug 2020 01:01:13 -0400 Subject: [PATCH 256/755] Clean up more byte packing/unpacking. (#40334) --- .../Security/Cryptography/DSACng.ImportExport.cs | 10 +++------- .../src/Internal/Cryptography/Helpers.cs | 10 ---------- .../Security/Cryptography/PKCS1MaskGenerationMethod.cs | 3 ++- .../Cryptography/RSACryptoServiceProvider.Windows.cs | 3 ++- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs index 57e626126613..61ec4f336c60 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs @@ -3,6 +3,7 @@ #nullable enable using Internal.Cryptography; +using System.Buffers.Binary; using System.Diagnostics; using static Interop.BCrypt; @@ -359,7 +360,7 @@ public override DSAParameters ExportParameters(bool includePrivateParameters) offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey // Read out a (V1) BCRYPT_DSA_KEY_BLOB structure. - dsaParams.Counter = FromBigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); + dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); @@ -393,7 +394,7 @@ public override DSAParameters ExportParameters(bool includePrivateParameters) offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4] // Read out a BCRYPT_DSA_KEY_BLOB_V2 structure. - dsaParams.Counter = FromBigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); + dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); @@ -422,11 +423,6 @@ public override DSAParameters ExportParameters(bool includePrivateParameters) } } - private static int FromBigEndian(byte[] b) - { - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; - } - /// /// This function checks the magic value in the key blob header /// diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs index 8854940afbeb..dc900c0ac0a7 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs @@ -58,15 +58,5 @@ public static byte[] FixupKeyParity(this byte[] key) } return oddParityKey; } - - internal static void ConvertIntToByteArray(uint value, byte[] dest) - { - Debug.Assert(dest != null); - Debug.Assert(dest.Length == 4); - dest[0] = (byte)((value & 0xFF000000) >> 24); - dest[1] = (byte)((value & 0xFF0000) >> 16); - dest[2] = (byte)((value & 0xFF00) >> 8); - dest[3] = (byte)(value & 0xFF); - } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/PKCS1MaskGenerationMethod.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/PKCS1MaskGenerationMethod.cs index 6688025b1f08..4e24f7eae2cf 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/PKCS1MaskGenerationMethod.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/PKCS1MaskGenerationMethod.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.Binary; using System.Diagnostics; using Internal.Cryptography; @@ -38,7 +39,7 @@ public override byte[] GenerateMask(byte[] rgbSeed, int cbReturn) for (int ib = 0; ib < rgbT.Length;) { // Increment counter -- up to 2^32 * sizeof(Hash) - Helpers.ConvertIntToByteArray(counter++, rgbCounter); + BinaryPrimitives.WriteUInt32BigEndian(rgbCounter, counter++); hasher.TransformBlock(rgbSeed, 0, rgbSeed.Length, rgbSeed, 0); hasher.TransformFinalBlock(rgbCounter, 0, 4); Debug.Assert(hasher.Hash != null); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs index 7a22b937cd52..e0a8cce1751b 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.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.Binary; using System.Diagnostics; using System.IO; using System.Runtime.Versioning; @@ -195,7 +196,7 @@ public override int KeySize get { byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_KEYLEN); - _keySize = (keySize[0] | (keySize[1] << 8) | (keySize[2] << 16) | (keySize[3] << 24)); + _keySize = BinaryPrimitives.ReadInt32LittleEndian(keySize); return _keySize; } } From b497143c168c8df00f070e95a4c6fee4092d2ea6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2020 05:08:27 +0000 Subject: [PATCH 257/755] [master] Update dependencies from dotnet/icu dotnet/llvm-project mono/linker (#40268) [master] Update dependencies from dotnet/icu dotnet/llvm-project mono/linker - Updates: - Microsoft.NET.ILLink.Tasks: from 5.0.0-preview.3.20378.1 to 5.0.0-preview.3.20403.5 - Updates: - Microsoft.NETCore.Runtime.ICU.Transport: from 5.0.0-preview.8.20378.2 to 5.0.0-preview.8.20403.1 - Updates: - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20365.1 to 9.0.1-alpha.1.20403.1 - Fix linker tests by fixing some warnings, and suppressing reflection warnings during the linker tests. - Merge remote-tracking branch 'upstream/master' into UpdateLinker - Suppress IL2008;IL2009 on non-Windows linker tests. - Suppress more linker warnings on non-Windows. - Suppress more linker warnings --- eng/Version.Details.xml | 40 ++++++++++---------- eng/Versions.props | 20 +++++----- eng/testing/linker/project.csproj.template | 8 +++- src/coreclr/src/vm/corelib.h | 4 +- src/coreclr/src/vm/dispatchinfo.cpp | 4 +- src/libraries/illink-sharedframework.targets | 12 +++++- 6 files changed, 51 insertions(+), 37 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ef6271c1e2eb..ea4afb6ae2ad 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 - 7ba1659d3c954a86115ddd0e0e8445a8c7c0dee8 + f58ab86d7e07a66ea189859f298843ccf41a0914 @@ -122,37 +122,37 @@ https://github.com/dotnet/runtime-assets 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf - + https://github.com/dotnet/llvm-project - 4e6a09468cb4e4e1be38ac25fcf866ca8136638b + 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf https://github.com/dotnet/runtime @@ -182,9 +182,9 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 7c9b806037e88df7eb40a8151808730133676668 + 8f32ed57a05eeb0bae3790c4db75b316c3da76c7 https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 6a05c5233477..45e754414804 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,18 +143,18 @@ 3.0.0-preview-20200715.1 - 5.0.0-preview.3.20378.1 + 5.0.0-preview.3.20403.5 - 5.0.0-preview.8.20378.2 + 5.0.0-preview.8.20403.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 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20403.1 diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index 64a3e93967a3..2f1f26c2fd87 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -6,7 +6,11 @@ {RuntimeIdentifier} {RuntimePackDir} {TargetingPackDir} - <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) + + IL2006;IL2026 + + $(LinkerNoWarn);IL2008;IL2009;IL2037 + <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) --nowarn $(LinkerNoWarn) @@ -32,4 +36,4 @@ GeneratePathProperty="true" /> - \ No newline at end of file + diff --git a/src/coreclr/src/vm/corelib.h b/src/coreclr/src/vm/corelib.h index f6ad66da1a07..e7b66f25d5f9 100644 --- a/src/coreclr/src/vm/corelib.h +++ b/src/coreclr/src/vm/corelib.h @@ -390,8 +390,6 @@ DEFINE_METHOD(STUBFIELDINFO, CTOR, .ctor, #endif DEFINE_CLASS(FIELD, Reflection, RuntimeFieldInfo) -DEFINE_METHOD(FIELD, SET_VALUE, SetValue, IM_Obj_Obj_BindingFlags_Binder_CultureInfo_RetVoid) -DEFINE_METHOD(FIELD, GET_VALUE, GetValue, IM_Obj_RetObj) DEFINE_CLASS(FIELD_HANDLE, System, RuntimeFieldHandle) DEFINE_FIELD(FIELD_HANDLE, M_FIELD, m_ptr) @@ -399,6 +397,8 @@ DEFINE_FIELD(FIELD_HANDLE, M_FIELD, m_ptr) DEFINE_CLASS(I_RT_FIELD_INFO, System, IRuntimeFieldInfo) DEFINE_CLASS(FIELD_INFO, Reflection, FieldInfo) +DEFINE_METHOD(FIELD_INFO, SET_VALUE, SetValue, IM_Obj_Obj_BindingFlags_Binder_CultureInfo_RetVoid) +DEFINE_METHOD(FIELD_INFO, GET_VALUE, GetValue, IM_Obj_RetObj) DEFINE_CLASS(GUID, System, Guid) diff --git a/src/coreclr/src/vm/dispatchinfo.cpp b/src/coreclr/src/vm/dispatchinfo.cpp index b44062c796d4..817f74eac761 100644 --- a/src/coreclr/src/vm/dispatchinfo.cpp +++ b/src/coreclr/src/vm/dispatchinfo.cpp @@ -1602,7 +1602,7 @@ void DispatchInfo::InvokeMemberWorker(DispatchMemberInfo* pDispMemberInfo, COMPlusThrowHR(DISP_E_BADPARAMCOUNT); // Retrieve the method descriptor that will be called on. - MethodDesc *pMD = GetFieldInfoMD(METHOD__FIELD__GET_VALUE, pObjs->MemberInfo->GetTypeHandle()); + MethodDesc *pMD = GetFieldInfoMD(METHOD__FIELD_INFO__GET_VALUE, pObjs->MemberInfo->GetTypeHandle()); MethodDescCallSite getValue(pMD, &pObjs->MemberInfo); // Prepare the arguments that will be passed to Invoke. @@ -1624,7 +1624,7 @@ void DispatchInfo::InvokeMemberWorker(DispatchMemberInfo* pDispMemberInfo, COMPlusThrowHR(DISP_E_NONAMEDARGS); // Retrieve the method descriptor that will be called on. - MethodDesc *pMD = GetFieldInfoMD(METHOD__FIELD__SET_VALUE, pObjs->MemberInfo->GetTypeHandle()); + MethodDesc *pMD = GetFieldInfoMD(METHOD__FIELD_INFO__SET_VALUE, pObjs->MemberInfo->GetTypeHandle()); MethodDescCallSite setValue(pMD, &pObjs->MemberInfo); // Prepare the arguments that will be passed to Invoke. diff --git a/src/libraries/illink-sharedframework.targets b/src/libraries/illink-sharedframework.targets index 9ccc5a2ec850..32d2f00cd1cc 100644 --- a/src/libraries/illink-sharedframework.targets +++ b/src/libraries/illink-sharedframework.targets @@ -23,7 +23,17 @@ IL2050: P/invoke method A declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. --> - $(ILLinkArgs) --nowarn IL2006;IL2009;IL2025;IL2026;IL2035;IL2050 + IL2006;IL2009;IL2025;IL2026;IL2035;IL2050 + + $(LinkerNoWarn);IL2008;IL2037 + $(LinkerNoWarn);IL2012 + $(ILLinkArgs) --nowarn $(LinkerNoWarn) From 5fd9958c08da7cb65b1a138f65242e4dc67b710f Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 5 Aug 2020 09:40:55 +0200 Subject: [PATCH 258/755] Fix corerun binplacing in testhost (#40341) Fixes https://github.com/dotnet/runtime/issues/40215 --- src/libraries/restore/runtime/runtime.depproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj index b433ff319213..792cb8f840a2 100644 --- a/src/libraries/restore/runtime/runtime.depproj +++ b/src/libraries/restore/runtime/runtime.depproj @@ -60,10 +60,10 @@ AfterTargets="AfterResolveReferences;FilterNugetPackages" Condition="'$(RuntimeFlavor)' != 'Mono'"> - + From a62b82be59beda4aeb5a7c54d729fa6b55d59288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 5 Aug 2020 12:59:48 +0200 Subject: [PATCH 259/755] Do not trim generic interfaces implemented by arrays (#40260) Logic within the CoreCLR VM depends on the order of methods on these interfaces to find methods on SZArrayHelper. SZArrayHelper is already rooted from MscorlibBinder, but the interface methods are referenced only implicitly through their slots and need a dedicated entry. --- .../src/System.Private.CoreLib/ILLinkTrim.xml | 7 +++++++ .../TrimmingTests/ActivatorUtilitiesTests.cs | 7 +++---- .../tests/TrimmingTests/InterfacesOnArrays.cs | 17 +++++++++++++++++ .../System.Runtime.TrimmingTests.proj | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs diff --git a/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml b/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml index 11a67fdac313..8031688ca0b9 100644 --- a/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml +++ b/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml @@ -17,5 +17,12 @@ + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs index eef18d380d1e..2a3e22724e26 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs @@ -10,15 +10,14 @@ static int Main(string[] args) { ServiceProvider provider = new ServiceCollection().BuildServiceProvider(); - // ActivatorUtilities.CreateFactory fails due to https://github.com/mono/linker/issues/1398 - //ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty()); - //ServiceA serviceA = factory(provider, null) as ServiceA; + ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty()); + ServiceA serviceA = factory(provider, null) as ServiceA; ServiceB serviceB = ActivatorUtilities.CreateInstance(provider, typeof(ServiceB)) as ServiceB; ServiceC serviceC = ActivatorUtilities.CreateInstance(provider); ServiceD serviceD = ActivatorUtilities.GetServiceOrCreateInstance(provider, typeof(ServiceD)) as ServiceD; ServiceE serviceE = ActivatorUtilities.GetServiceOrCreateInstance(provider); - if (//serviceA is null || + if (serviceA is null || serviceB is null || serviceC is null || serviceD is null || diff --git a/src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs b/src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs new file mode 100644 index 000000000000..f8c76da93998 --- /dev/null +++ b/src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; + +class Program +{ + class Mine { } + + static int Main() + { + Mine[] s = new Mine[1] { new Mine() }; + Mine[] d = new Mine[1]; + ((ICollection)s).CopyTo(d, 0); + return s[0] == d[0] ? 100 : -1; + } +} diff --git a/src/libraries/System.Runtime/tests/TrimmingTests/System.Runtime.TrimmingTests.proj b/src/libraries/System.Runtime/tests/TrimmingTests/System.Runtime.TrimmingTests.proj index ce96e07448a3..ce80b61eec67 100644 --- a/src/libraries/System.Runtime/tests/TrimmingTests/System.Runtime.TrimmingTests.proj +++ b/src/libraries/System.Runtime/tests/TrimmingTests/System.Runtime.TrimmingTests.proj @@ -9,6 +9,7 @@ + + - + <_Parameter1>$(MinimiumSupportedWindowsPlatform) 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 33efcbf9a335..b0c4eaaa6f29 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 @@ -307,7 +307,7 @@ public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb) /// /// Given a managed object that wraps an ITypeInfo, return its name. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static string GetTypeInfoName(ITypeInfo typeInfo) { if (typeInfo is null) @@ -321,14 +321,14 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) // This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it // on Marshal for more consistent API surface. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Type? GetTypeFromCLSID(Guid clsid) => RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError: false); /// /// Return the IUnknown* for an Object if the current context is the one /// where the RCW was first seen. Will return null otherwise. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetIUnknownForObject(object o) { if (o is null) @@ -352,7 +352,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the IDispatch* for an Object. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) { if (o is null) @@ -370,7 +370,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Return the IUnknown* representing the interface for the Object. /// Object o should support Type T /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T) { if (o is null) @@ -386,7 +386,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) return GetComInterfaceForObjectNative(o, T, false, true); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) => GetComInterfaceForObject(o!, typeof(TInterface)); /// @@ -394,7 +394,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Object o should support Type T, it refer the value of mode to /// invoke customized QueryInterface or not. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode) { if (o is null) @@ -417,7 +417,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the managed object representing the IUnknown* /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { if (pUnk == IntPtr.Zero) @@ -431,7 +431,7 @@ public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) [MethodImpl(MethodImplOptions.InternalCall)] private static extern object GetObjectForIUnknownNative(IntPtr /* IUnknown* */ pUnk); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object GetUniqueObjectForIUnknown(IntPtr unknown) { if (unknown == IntPtr.Zero) @@ -455,15 +455,15 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown) /// Return an Object for IUnknown, using the Type T. /// Type T should be either a COM imported Type or a sub-type of COM imported Type /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull { return CreateAggregatedObject(pOuter, (object)o); @@ -562,7 +562,7 @@ public static string PtrToStringBSTR(IntPtr ptr) /// Release the COM component and if the reference hits 0 zombie this object. /// Further usage of this Object might throw an exception /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int ReleaseComObject(object o) { if (o is null) @@ -585,7 +585,7 @@ public static int ReleaseComObject(object o) /// Release the COM component and zombie this object. /// Further usage of this Object might throw an exception /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int FinalReleaseComObject(object o) { if (o is null) @@ -604,7 +604,7 @@ public static int FinalReleaseComObject(object o) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void InternalFinalReleaseComObject(object o); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object? GetComObjectData(object obj, object key) { if (obj is null) @@ -630,7 +630,7 @@ public static int FinalReleaseComObject(object o) /// false if the data could not be added because there already was data for the /// specified key. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool SetComObjectData(object obj, object key, object? data) { if (obj is null) @@ -654,7 +654,7 @@ public static bool SetComObjectData(object obj, object key, object? data) /// This method takes the given COM object and wraps it in an object /// of the specified type. The type must be derived from __ComObject. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [return: NotNullIfNotNull("o")] public static object? CreateWrapperOfType(object? o, Type t) { @@ -705,7 +705,7 @@ public static bool SetComObjectData(object obj, object key, object? data) return Wrapper; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static TWrapper CreateWrapperOfType([AllowNull] T o) { return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!; @@ -720,7 +720,7 @@ public static TWrapper CreateWrapperOfType([AllowNull] T o) [MethodImpl(MethodImplOptions.InternalCall)] public static extern bool IsTypeVisibleFromCom(Type t); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) { if (pUnk == IntPtr.Zero) @@ -733,7 +733,7 @@ public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr pp } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static unsafe int AddRef(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -742,7 +742,7 @@ public static unsafe int AddRef(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 1 /* IUnknown.AddRef slot */)))(pUnk); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static unsafe int Release(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -751,32 +751,32 @@ public static unsafe int Release(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 2 /* IUnknown.Release slot */)))(pUnk); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) { GetNativeVariantForObject((object?)obj, pDstNativeVariant); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [return: MaybeNull] public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { return (T)GetObjectForNativeVariant(pSrcNativeVariant)!; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars); @@ -791,18 +791,18 @@ public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int c /// Returns the first valid COM slot that GetMethodInfoForSlot will work on /// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetStartComSlot(Type t); /// /// Returns the last valid COM slot that GetMethodInfoForSlot will work on. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetEndComSlot(Type t); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object BindToMoniker(string monikerName) { CreateBindCtx(0, out IBindCtx bindctx); @@ -822,7 +822,7 @@ public static object BindToMoniker(string monikerName) [DllImport(Interop.Libraries.Ole32, PreserveSig = false)] private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak); #endif // FEATURE_COMINTEROP diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index df967acbbdfb..1d53ffa8e46b 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -607,7 +607,7 @@ public DictionarySectionHandler() { } protected virtual string ValueAttributeName { get { throw null; } } public virtual object Create(object parent, object context, System.Xml.XmlNode section) { throw null; } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public sealed partial class DpapiProtectedConfigurationProvider : System.Configuration.ProtectedConfigurationProvider { public DpapiProtectedConfigurationProvider() { } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs index b6ada8acbfef..3a395e05b17c 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs @@ -9,7 +9,7 @@ namespace System.Configuration { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public sealed class DpapiProtectedConfigurationProvider : ProtectedConfigurationProvider { private bool _useMachineProtection = true; diff --git a/src/libraries/System.Console/ref/System.Console.cs b/src/libraries/System.Console/ref/System.Console.cs index 20b7d335e046..94cabc7a6827 100644 --- a/src/libraries/System.Console/ref/System.Console.cs +++ b/src/libraries/System.Console/ref/System.Console.cs @@ -9,14 +9,14 @@ namespace System public static partial class Console { public static System.ConsoleColor BackgroundColor { get { throw null; } set { } } - public static int BufferHeight { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public static int BufferWidth { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + public static int BufferHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int BufferWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static bool CapsLock { get { throw null; } } public static int CursorLeft { get { throw null; } set { } } - public static int CursorSize { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public static int CursorSize { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public static int CursorTop { get { throw null; } set { } } - public static bool CursorVisible { [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] get { throw null; } set { } } + public static bool CursorVisible { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] get { throw null; } set { } } public static System.IO.TextWriter Error { get { throw null; } } public static System.ConsoleColor ForegroundColor { get { throw null; } set { } } public static System.IO.TextReader In { get { throw null; } } @@ -27,25 +27,25 @@ public static partial class Console public static bool KeyAvailable { get { throw null; } } public static int LargestWindowHeight { get { throw null; } } public static int LargestWindowWidth { get { throw null; } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static bool NumberLock { get { throw null; } } public static System.IO.TextWriter Out { get { throw null; } } public static System.Text.Encoding OutputEncoding { get { throw null; } set { } } - public static string Title { [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] get { throw null; } set { } } + public static string Title { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] get { throw null; } set { } } public static bool TreatControlCAsInput { get { throw null; } set { } } - public static int WindowHeight { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public static int WindowLeft { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public static int WindowTop { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public static int WindowWidth { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public static int WindowHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int WindowLeft { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int WindowTop { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int WindowWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public static event System.ConsoleCancelEventHandler? CancelKeyPress { add { } remove { } } public static void Beep() { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void Beep(int frequency, int duration) { } public static void Clear() { } public static (int Left, int Top) GetCursorPosition() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, System.ConsoleColor sourceForeColor, System.ConsoleColor sourceBackColor) { } public static System.IO.Stream OpenStandardError() { throw null; } public static System.IO.Stream OpenStandardError(int bufferSize) { throw null; } @@ -58,15 +58,15 @@ public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth public static System.ConsoleKeyInfo ReadKey(bool intercept) { throw null; } public static string? ReadLine() { throw null; } public static void ResetColor() { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void SetBufferSize(int width, int height) { } public static void SetCursorPosition(int left, int top) { } public static void SetError(System.IO.TextWriter newError) { } public static void SetIn(System.IO.TextReader newIn) { } public static void SetOut(System.IO.TextWriter newOut) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void SetWindowPosition(int left, int top) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void SetWindowSize(int width, int height) { } public static void Write(bool value) { } public static void Write(char value) { } diff --git a/src/libraries/System.Console/src/System/Console.cs b/src/libraries/System.Console/src/System/Console.cs index ed25ffe8599f..d20ec813d7a4 100644 --- a/src/libraries/System.Console/src/System/Console.cs +++ b/src/libraries/System.Console/src/System/Console.cs @@ -277,17 +277,17 @@ static StrongBox EnsureInitialized() public static int CursorSize { get { return ConsolePal.CursorSize; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.CursorSize = value; } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool NumberLock { get { return ConsolePal.NumberLock; } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool CapsLock { get { return ConsolePal.CapsLock; } @@ -315,18 +315,18 @@ public static void ResetColor() public static int BufferWidth { get { return ConsolePal.BufferWidth; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.BufferWidth = value; } } public static int BufferHeight { get { return ConsolePal.BufferHeight; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.BufferHeight = value; } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void SetBufferSize(int width, int height) { ConsolePal.SetBufferSize(width, height); @@ -335,38 +335,38 @@ public static void SetBufferSize(int width, int height) public static int WindowLeft { get { return ConsolePal.WindowLeft; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.WindowLeft = value; } } public static int WindowTop { get { return ConsolePal.WindowTop; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.WindowTop = value; } } public static int WindowWidth { get { return ConsolePal.WindowWidth; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.WindowWidth = value; } } public static int WindowHeight { get { return ConsolePal.WindowHeight; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ConsolePal.WindowHeight = value; } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void SetWindowPosition(int left, int top) { ConsolePal.SetWindowPosition(left, top); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void SetWindowSize(int width, int height) { ConsolePal.SetWindowSize(width, height); @@ -384,7 +384,7 @@ public static int LargestWindowHeight public static bool CursorVisible { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] get { return ConsolePal.CursorVisible; } set { ConsolePal.CursorVisible = value; } } @@ -413,7 +413,7 @@ public static (int Left, int Top) GetCursorPosition() public static string Title { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] get { return ConsolePal.Title; } set { @@ -426,19 +426,19 @@ public static void Beep() ConsolePal.Beep(); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void Beep(int frequency, int duration) { ConsolePal.Beep(frequency, duration); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop) { ConsolePal.MoveBufferArea(sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop, ' ', ConsoleColor.Black, BackgroundColor); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) { ConsolePal.MoveBufferArea(sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop, sourceChar, sourceForeColor, sourceBackColor); diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index 60808eea784a..de9b9df74c83 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -41,8 +41,8 @@ public Process() { } public System.Diagnostics.ProcessModule? MainModule { get { throw null; } } public System.IntPtr MainWindowHandle { get { throw null; } } public string MainWindowTitle { get { throw null; } } - public System.IntPtr MaxWorkingSet { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public System.IntPtr MinWorkingSet { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public System.IntPtr MaxWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.IntPtr MinWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public System.Diagnostics.ProcessModuleCollection Modules { get { throw null; } } [System.ObsoleteAttribute("This property has been deprecated. Please use System.Diagnostics.Process.NonpagedSystemMemorySize64 instead. https://go.microsoft.com/fwlink/?linkid=14202")] public int NonpagedSystemMemorySize { get { throw null; } } @@ -116,10 +116,10 @@ public void Refresh() { } public static System.Diagnostics.Process Start(string fileName) { throw null; } public static System.Diagnostics.Process Start(string fileName, string arguments) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.Diagnostics.Process Start(string fileName, string userName, System.Security.SecureString password, string domain) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.Diagnostics.Process Start(string fileName, string arguments, string userName, System.Security.SecureString password, string domain) { throw null; } public override string ToString() { throw null; } public void WaitForExit() { } @@ -165,19 +165,19 @@ public ProcessStartInfo(string fileName, string arguments) { } public System.Collections.ObjectModel.Collection ArgumentList { get { throw null; } } public string Arguments { get { throw null; } set { } } public bool CreateNoWindow { get { throw null; } set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public string Domain { get { throw null; } set { } } public System.Collections.Generic.IDictionary Environment { get { throw null; } } public System.Collections.Specialized.StringDictionary EnvironmentVariables { get { throw null; } } public bool ErrorDialog { get { throw null; } set { } } public System.IntPtr ErrorDialogParentHandle { get { throw null; } set { } } public string FileName { get { throw null; } set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public bool LoadUserProfile { get { throw null; } set { } } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public System.Security.SecureString? Password { get { throw null; } set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public string? PasswordInClearText { get { throw null; } set { } } public bool RedirectStandardError { get { throw null; } set { } } public bool RedirectStandardInput { get { throw null; } set { } } @@ -202,9 +202,9 @@ internal ProcessThread() { } public int Id { get { throw null; } } public int IdealProcessor { set { } } public bool PriorityBoostEnabled { get { throw null; } set { } } - public System.Diagnostics.ThreadPriorityLevel PriorityLevel { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public System.Diagnostics.ThreadPriorityLevel PriorityLevel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public System.TimeSpan PrivilegedProcessorTime { get { throw null; } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public System.IntPtr ProcessorAffinity { set { } } public System.IntPtr StartAddress { get { throw null; } } public System.DateTime StartTime { get { throw null; } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs index 845c054930dd..2fa005cbdd4e 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs @@ -42,14 +42,14 @@ public static void LeaveDebugMode() } [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Process Start(string fileName, string userName, SecureString password, string domain) { throw new PlatformNotSupportedException(SR.ProcessStartWithPasswordAndDomainNotSupported); } [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain) { throw new PlatformNotSupportedException(SR.ProcessStartWithPasswordAndDomainNotSupported); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs index f56571300cea..abd11001b032 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs @@ -47,7 +47,7 @@ public static Process[] GetProcessesByName(string? processName, string machineNa } [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Process? Start(string fileName, string userName, SecureString password, string domain) { ProcessStartInfo startInfo = new ProcessStartInfo(fileName); @@ -59,7 +59,7 @@ public static Process[] GetProcessesByName(string? processName, string machineNa } [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Process? Start(string fileName, string arguments, string userName, SecureString password, string domain) { ProcessStartInfo startInfo = new ProcessStartInfo(fileName, arguments); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index 17b665eb5dd0..aac6c7b1f964 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -265,7 +265,7 @@ public IntPtr MaxWorkingSet EnsureWorkingSetLimits(); return _maxWorkingSet; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { SetWorkingSetLimits(null, value); @@ -285,7 +285,7 @@ public IntPtr MinWorkingSet EnsureWorkingSetLimits(); return _minWorkingSet; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { SetWorkingSetLimits(value, null); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs index 1af5bb923dc9..9cbbd4009502 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs @@ -14,21 +14,21 @@ public sealed partial class ProcessStartInfo { private const bool CaseSensitiveEnvironmentVariables = true; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public string PasswordInClearText { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(PasswordInClearText))); } set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(PasswordInClearText))); } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public string Domain { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Domain))); } set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Domain))); } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public bool LoadUserProfile { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(LoadUserProfile))); } @@ -40,7 +40,7 @@ public bool LoadUserProfile public string[] Verbs => Array.Empty(); [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public SecureString Password { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Password))); } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs index 5545b0590f4c..ba3ab4eee48e 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs @@ -12,21 +12,21 @@ public sealed partial class ProcessStartInfo private const bool CaseSensitiveEnvironmentVariables = false; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public string? PasswordInClearText { get; set; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public string Domain { get => _domain ?? string.Empty; set => _domain = value; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public bool LoadUserProfile { get; set; } [CLSCompliant(false)] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public SecureString? Password { get; set; } } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs index ac65c2dffb87..d1b8cdb978da 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs @@ -41,7 +41,7 @@ private bool PriorityBoostEnabledCore /// two, etc. For example, the value 1 means run on processor one, 2 means run on /// processor two, 3 means run on processor one or two. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public IntPtr ProcessorAffinity { set { throw new PlatformNotSupportedException(); } // No ability to change the affinity of a thread in an arbitrary process diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs index 450a1d77edf3..db18cd7f4b2d 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs @@ -100,7 +100,7 @@ private ThreadPriorityLevel PriorityLevelCore /// two, etc. For example, the value 1 means run on processor one, 2 means run on /// processor two, 3 means run on processor one or two. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public IntPtr ProcessorAffinity { set diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs index b4ad10f029c5..b0a10b5e9a6b 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs @@ -95,7 +95,7 @@ public ThreadPriorityLevel PriorityLevel } return _priorityLevel.Value; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { PriorityLevelCore = value; diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs b/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs index cc5e3b773569..b7d16e5d740d 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs +++ b/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs @@ -18,7 +18,7 @@ public DriveInfo(string driveName) { } public long TotalFreeSpace { get { throw null; } } public long TotalSize { get { throw null; } } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] - public string VolumeLabel { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public string VolumeLabel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public static System.IO.DriveInfo[] GetDrives() { throw null; } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public override string ToString() { throw null; } diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs index 89ac3ae7ad5f..bbfbd8bb4ac2 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs @@ -42,7 +42,7 @@ public string VolumeLabel { return Name; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { throw new PlatformNotSupportedException(); 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 e1834a4b2d80..ef89cd3763f2 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 @@ -139,7 +139,7 @@ public unsafe string VolumeLabel return new string(volumeName); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { uint oldMode; diff --git a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs index 953c048a7943..09e8f6d76393 100644 --- a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs +++ b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs @@ -121,10 +121,10 @@ public static void Copy(string sourceFileName, string destFileName, bool overwri public static System.IO.FileStream Create(string path, int bufferSize) { throw null; } public static System.IO.FileStream Create(string path, int bufferSize, System.IO.FileOptions options) { throw null; } public static System.IO.StreamWriter CreateText(string path) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void Decrypt(string path) { } public static void Delete(string path) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void Encrypt(string path) { } public static bool Exists(string? path) { throw null; } public static System.IO.FileAttributes GetAttributes(string path) { throw null; } diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs index 16a82bd337e9..366e55a7b399 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs @@ -646,13 +646,13 @@ public static void Move(string sourceFileName, string destFileName, bool overwri FileSystem.MoveFile(fullSourceFileName, fullDestFileName, overwrite); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void Encrypt(string path) { FileSystem.Encrypt(path ?? throw new ArgumentNullException(nameof(path))); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void Decrypt(string path) { FileSystem.Decrypt(path ?? throw new ArgumentNullException(nameof(path))); diff --git a/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs b/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs index 4748d3acb85b..22135ab9cdab 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs @@ -33,11 +33,11 @@ internal MemoryMappedFile() { } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity) { throw null; } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.MemoryMappedFiles.MemoryMappedFileOptions options, System.IO.HandleInheritability inheritability) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.MemoryMappedFiles.MemoryMappedFileOptions options, System.IO.HandleInheritability inheritability) { throw null; } public System.IO.MemoryMappedFiles.MemoryMappedViewAccessor CreateViewAccessor() { throw null; } public System.IO.MemoryMappedFiles.MemoryMappedViewAccessor CreateViewAccessor(long offset, long size) { throw null; } @@ -47,11 +47,11 @@ internal MemoryMappedFile() { } public System.IO.MemoryMappedFiles.MemoryMappedViewStream CreateViewStream(long offset, long size, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } public void Dispose() { } protected virtual void Dispose(bool disposing) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName, System.IO.MemoryMappedFiles.MemoryMappedFileRights desiredAccessRights) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName, System.IO.MemoryMappedFiles.MemoryMappedFileRights desiredAccessRights, System.IO.HandleInheritability inheritability) { throw null; } } public enum MemoryMappedFileAccess diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs b/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs index aed549229ae1..fbd2fbc257c4 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs @@ -44,19 +44,19 @@ private MemoryMappedFile(SafeMemoryMappedFileHandle handle, FileStream fileStrea // the first override of this method. Note: having ReadWrite access to the object does not mean that we // have ReadWrite access to the pages mapping the file. The OS will check against the access on the pages // when a view is created. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile OpenExisting(string mapName) { return OpenExisting(mapName, MemoryMappedFileRights.ReadWrite, HandleInheritability.None); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile OpenExisting(string mapName, MemoryMappedFileRights desiredAccessRights) { return OpenExisting(mapName, desiredAccessRights, HandleInheritability.None); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile OpenExisting(string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability) { @@ -295,21 +295,21 @@ public static MemoryMappedFile CreateNew(string? mapName, long capacity, MemoryM // memory mapped file if one exists with the same name. The capacity, options, and // memoryMappedFileSecurity arguments will be ignored in the case of the later. // This is ideal for P2P style IPC. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity) { return CreateOrOpen(mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity, MemoryMappedFileAccess access) { return CreateOrOpen(mapName, capacity, access, MemoryMappedFileOptions.None, HandleInheritability.None); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability) diff --git a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs index 8ef9f9f5b064..54b3486328a8 100644 --- a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs +++ b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs @@ -48,7 +48,7 @@ public sealed partial class NamedPipeClientStream : System.IO.Pipes.PipeStream public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options, System.Security.Principal.TokenImpersonationLevel impersonationLevel) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options, System.Security.Principal.TokenImpersonationLevel impersonationLevel, System.IO.HandleInheritability inheritability) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public int NumberOfServerInstances { get { throw null; } } protected internal override void CheckPipePropertyOperations() { } public void Connect() { } @@ -129,7 +129,7 @@ protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle? hand public override int ReadByte() { throw null; } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } public override void SetLength(long value) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public void WaitForPipeDrain() { } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } @@ -141,7 +141,7 @@ public override void WriteByte(byte value) { } public enum PipeTransmissionMode { Byte = 0, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] Message = 1, } } diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs index dfb09b40cfed..89d8bb70179f 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs @@ -67,7 +67,7 @@ private bool TryConnect(int timeout, CancellationToken cancellationToken) return true; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public int NumberOfServerInstances { get diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs index 730f1eab530e..a7f489497717 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs @@ -108,7 +108,7 @@ private bool TryConnect(int timeout, CancellationToken cancellationToken) return true; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public unsafe int NumberOfServerInstances { get diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs index 502829f49daa..b84999c721e3 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs @@ -220,7 +220,7 @@ private IOException GetIOExceptionForSocketException(SocketException e) } // Blocks until the other end of the pipe has read in all written buffer. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void WaitForPipeDrain() { CheckWriteOperations(); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs index 030f769a762b..1060da2ea372 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs @@ -179,7 +179,7 @@ private Task WriteAsyncCore(ReadOnlyMemory buffer, CancellationToken cance } // Blocks until the other end of the pipe has read in all written buffer. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void WaitForPipeDrain() { CheckWriteOperations(); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs index fbfd0ccf85ec..8ed232d3b458 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs @@ -8,7 +8,7 @@ namespace System.IO.Pipes public enum PipeTransmissionMode { Byte = 0, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] Message = 1, } } diff --git a/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs b/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs index 3e867fd5a07b..c93cc4941d5b 100644 --- a/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs +++ b/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs @@ -139,11 +139,11 @@ public partial class HttpListenerTimeoutManager { internal HttpListenerTimeoutManager() { } public System.TimeSpan DrainEntityBody { get { throw null; } set { } } - public System.TimeSpan EntityBody { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public System.TimeSpan HeaderWait { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public System.TimeSpan EntityBody { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.TimeSpan HeaderWait { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public System.TimeSpan IdleConnection { get { throw null; } set { } } - public long MinSendBytesPerSecond { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } - public System.TimeSpan RequestQueue { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public long MinSendBytesPerSecond { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.TimeSpan RequestQueue { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } } } namespace System.Net.WebSockets diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs index fbb9d1718db8..8734f93b145f 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs @@ -39,7 +39,7 @@ public TimeSpan IdleConnection public TimeSpan EntityBody { get => TimeSpan.Zero; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ValidateTimeout(value); @@ -50,7 +50,7 @@ public TimeSpan EntityBody public TimeSpan HeaderWait { get => TimeSpan.Zero; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ValidateTimeout(value); @@ -61,7 +61,7 @@ public TimeSpan HeaderWait public long MinSendBytesPerSecond { get => 0; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { if (value < 0 || value > uint.MaxValue) @@ -75,7 +75,7 @@ public long MinSendBytesPerSecond public TimeSpan RequestQueue { get => TimeSpan.Zero; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { ValidateTimeout(value); diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs index 3de078196d9e..13da1e11e963 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs @@ -83,7 +83,7 @@ public TimeSpan EntityBody { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody, value); @@ -121,7 +121,7 @@ public TimeSpan RequestQueue { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue, value); @@ -157,7 +157,7 @@ public TimeSpan HeaderWait { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait, value); @@ -177,7 +177,7 @@ public long MinSendBytesPerSecond // return _minSendBytesPerSecond; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { // diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index 5d924c0d5cab..c0d7c4e2dd19 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -8,70 +8,70 @@ namespace System.Net.Sockets { public enum IOControlCode : long { - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] EnableCircularQueuing = (long)671088642, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] Flush = (long)671088644, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AddressListChange = (long)671088663, DataToRead = (long)1074030207, OobDataRead = (long)1074033415, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] GetBroadcastAddress = (long)1207959557, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AddressListQuery = (long)1207959574, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] QueryTargetPnpHandle = (long)1207959576, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AsyncIO = (long)2147772029, NonBlockingIO = (long)2147772030, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AssociateHandle = (long)2281701377, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] MultipointLoopback = (long)2281701385, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] MulticastScope = (long)2281701386, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] SetQos = (long)2281701387, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] SetGroupQos = (long)2281701388, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] RoutingInterfaceChange = (long)2281701397, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] NamespaceChange = (long)2281701401, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] ReceiveAll = (long)2550136833, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] ReceiveAllMulticast = (long)2550136834, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] ReceiveAllIgmpMulticast = (long)2550136835, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] KeepAliveValues = (long)2550136836, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AbsorbRouterAlert = (long)2550136837, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] UnicastInterface = (long)2550136838, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] LimitBroadcasts = (long)2550136839, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] BindToInterface = (long)2550136840, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] MulticastInterface = (long)2550136841, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AddMulticastGroupOnInterface = (long)2550136842, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] DeleteMulticastGroupFromInterface = (long)2550136843, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] GetExtensionFunctionPointer = (long)3355443206, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] GetQos = (long)3355443207, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] GetGroupQos = (long)3355443208, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] TranslateHandle = (long)3355443213, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] RoutingInterfaceQuery = (long)3355443220, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] AddressListSort = (long)3355443225, } public partial struct IPPacketInformation @@ -254,7 +254,7 @@ public partial class Socket : System.IDisposable { public Socket(System.Net.Sockets.SafeSocketHandle handle) { } public Socket(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public Socket(System.Net.Sockets.SocketInformation socketInformation) { } public Socket(System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } public System.Net.Sockets.AddressFamily AddressFamily { get { throw null; } } @@ -326,7 +326,7 @@ public void Disconnect(bool reuseSocket) { } public bool DisconnectAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; } public void Dispose() { } protected virtual void Dispose(bool disposing) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public System.Net.Sockets.SocketInformation DuplicateAndClose(int targetProcessId) { throw null; } public System.Net.Sockets.Socket EndAccept(out byte[] buffer, System.IAsyncResult asyncResult) { throw null; } public System.Net.Sockets.Socket EndAccept(out byte[] buffer, out int bytesTransferred, System.IAsyncResult asyncResult) { throw null; } @@ -391,7 +391,7 @@ public void SendFile(string? fileName, byte[]? preBuffer, byte[]? postBuffer, Sy public int SendTo(byte[] buffer, System.Net.EndPoint remoteEP) { throw null; } public int SendTo(byte[] buffer, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEP) { throw null; } public bool SendToAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public void SetIPProtectionLevel(System.Net.Sockets.IPProtectionLevel level) { } public void SetRawSocketOption(int optionLevel, int optionName, System.ReadOnlySpan optionValue) { } public void SetSocketOption(System.Net.Sockets.SocketOptionLevel optionLevel, System.Net.Sockets.SocketOptionName optionName, bool optionValue) { } @@ -626,7 +626,7 @@ public TcpListener(System.Net.IPEndPoint localEP) { } public System.Threading.Tasks.Task AcceptSocketAsync() { throw null; } public System.Net.Sockets.TcpClient AcceptTcpClient() { throw null; } public System.Threading.Tasks.Task AcceptTcpClientAsync() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public void AllowNatTraversal(bool allowed) { } public System.IAsyncResult BeginAcceptSocket(System.AsyncCallback? callback, object? state) { throw null; } public System.IAsyncResult BeginAcceptTcpClient(System.AsyncCallback? callback, object? state) { throw null; } @@ -644,11 +644,11 @@ public enum TransmitFileOptions UseDefaultWorkerThread = 0, Disconnect = 1, ReuseSocket = 2, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] WriteBehind = 4, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] UseSystemThread = 16, - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] UseKernelApc = 32, } public partial class UdpClient : System.IDisposable @@ -667,7 +667,7 @@ public UdpClient(string hostname, int port) { } public bool ExclusiveAddressUse { get { throw null; } set { } } public bool MulticastLoopback { get { throw null; } set { } } public short Ttl { get { throw null; } set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public void AllowNatTraversal(bool allowed) { } public System.IAsyncResult BeginReceive(System.AsyncCallback? requestCallback, object? state) { throw null; } public System.IAsyncResult BeginSend(byte[] datagram, int bytes, System.AsyncCallback? requestCallback, object? state) { throw null; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs index fc1d69159bab..a2e4c9efd0ec 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs @@ -7,70 +7,70 @@ namespace System.Net.Sockets { public enum IOControlCode : long { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AsyncIO = 0x8004667D, NonBlockingIO = 0x8004667E, // fionbio DataToRead = 0x4004667F, // fionread OobDataRead = 0x40047307, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AssociateHandle = 0x88000001, // SIO_ASSOCIATE_HANDLE - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] EnableCircularQueuing = 0x28000002, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] Flush = 0x28000004, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] GetBroadcastAddress = 0x48000005, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] GetExtensionFunctionPointer = 0xC8000006, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] GetQos = 0xC8000007, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] GetGroupQos = 0xC8000008, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] MultipointLoopback = 0x88000009, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] MulticastScope = 0x8800000A, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] SetQos = 0x8800000B, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] SetGroupQos = 0x8800000C, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] TranslateHandle = 0xC800000D, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] RoutingInterfaceQuery = 0xC8000014, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] RoutingInterfaceChange = 0x88000015, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AddressListQuery = 0x48000016, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AddressListChange = 0x28000017, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] QueryTargetPnpHandle = 0x48000018, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] NamespaceChange = 0x88000019, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AddressListSort = 0xC8000019, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] ReceiveAll = 0x98000001, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] ReceiveAllMulticast = 0x98000002, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] ReceiveAllIgmpMulticast = 0x98000003, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] KeepAliveValues = 0x98000004, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AbsorbRouterAlert = 0x98000005, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] UnicastInterface = 0x98000006, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] LimitBroadcasts = 0x98000007, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] BindToInterface = 0x98000008, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] MulticastInterface = 0x98000009, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] AddMulticastGroupOnInterface = 0x9800000A, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] DeleteMulticastGroupFromInterface = 0x9800000B } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs index 989e400c756f..e5905b7b70bf 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs @@ -10,7 +10,7 @@ namespace System.Net.Sockets { public partial class Socket { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public Socket(SocketInformation socketInformation) { // This constructor works in conjunction with DuplicateAndClose, which is not supported on Unix. @@ -18,7 +18,7 @@ public Socket(SocketInformation socketInformation) throw new PlatformNotSupportedException(SR.net_sockets_duplicateandclose_notsupported); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public SocketInformation DuplicateAndClose(int targetProcessId) { // DuplicateAndClose is not supported on Unix, since passing file descriptors between processes diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs index ccb589ed3e34..f4b87f2e4ff5 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs @@ -17,7 +17,7 @@ public partial class Socket internal void ReplaceHandleIfNecessaryAfterFailedConnect() { /* nop on Windows */ } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public Socket(SocketInformation socketInformation) { InitializeSockets(); @@ -106,7 +106,7 @@ private unsafe void LoadSocketTypeFromHandle( blocking = true; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public SocketInformation DuplicateAndClose(int targetProcessId) { ThrowIfDisposed(); diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 30a1e61f5546..ac327f86f709 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -1989,7 +1989,7 @@ public int GetRawSocketOption(int optionLevel, int optionName, Span option return realOptionLength; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void SetIPProtectionLevel(IPProtectionLevel level) { if (level == IPProtectionLevel.Unspecified) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs index df906c11b4d0..b32a6d105031 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs @@ -112,7 +112,7 @@ public bool ExclusiveAddressUse } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void AllowNatTraversal(bool allowed) { if (_active) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs index cc1d42c633f0..418e7a6ab070 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs @@ -11,11 +11,11 @@ public enum TransmitFileOptions UseDefaultWorkerThread = 0x00, Disconnect = 0x01, ReuseSocket = 0x02, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] WriteBehind = 0x04, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] UseSystemThread = 0x10, - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] UseKernelApc = 0x20, }; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs index e5b9074bb4cf..4b19c4bf0063 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs @@ -193,7 +193,7 @@ public bool ExclusiveAddressUse } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void AllowNatTraversal(bool allowed) { _clientSocket.SetIPProtectionLevel(allowed ? IPProtectionLevel.Unrestricted : IPProtectionLevel.EdgeRestricted); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs index 5be89fc00623..c0d28b17cbf7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs @@ -22,7 +22,7 @@ public DispatchWrapper(object? obj) } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public object? WrappedObject { get; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs index 2e7c3b36b4e6..2a64a19a6a42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs @@ -15,7 +15,7 @@ public static int GetHRForException(Exception? e) return e?.HResult ?? 0; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int AddRef(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -23,13 +23,13 @@ public static int AddRef(IntPtr pUnk) public static bool AreComObjectsAvailableForCleanup() => false; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object BindToMoniker(string monikerName) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -39,55 +39,55 @@ public static void CleanupUnusedObjectsInCurrentContext() { } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object? CreateWrapperOfType(object? o, Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static TWrapper CreateWrapperOfType([AllowNull] T o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void ChangeWrapperHandleStrength(object otp, bool fIsWeak) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int FinalReleaseComObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetComInterfaceForObject(object o, Type T) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object? GetComObjectData(object obj, object key) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -103,92 +103,92 @@ public static IntPtr GetHINSTANCE(Module m) return (IntPtr)(-1); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetIDispatchForObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static IntPtr GetIUnknownForObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object GetTypedObjectForIUnknown(IntPtr pUnk, Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object GetObjectForIUnknown(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] [return: MaybeNull] public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object?[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int GetStartComSlot(Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int GetEndComSlot(Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Type? GetTypeFromCLSID(Guid clsid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static string GetTypeInfoName(ITypeInfo typeInfo) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static object GetUniqueObjectForIUnknown(IntPtr unknown) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -213,25 +213,25 @@ public static bool IsTypeVisibleFromCom(Type t) return false; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int Release(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static int ReleaseComObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool SetComObjectData(object obj, object key, object? data) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs index c230113c9b0f..0f99e4475a43 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs @@ -45,7 +45,7 @@ public TargetPlatformAttribute(string platformName) : base(platformName) /// applied to indicate support on multiple operating systems. /// /// - /// Callers can apply a + /// Callers can apply a /// or use guards to prevent calls to APIs on unsupported operating systems. /// /// A given platform should only be specified once. @@ -66,9 +66,9 @@ public TargetPlatformAttribute(string platformName) : base(platformName) #else internal #endif - sealed class MinimumOSPlatformAttribute : OSPlatformAttribute + sealed class SupportedOSPlatformAttribute : OSPlatformAttribute { - public MinimumOSPlatformAttribute(string platformName) : base(platformName) + public SupportedOSPlatformAttribute (string platformName) : base(platformName) { } } @@ -133,9 +133,9 @@ public ObsoletedInOSPlatformAttribute(string platformName, string message) : bas #else internal #endif - sealed class RemovedInOSPlatformAttribute : OSPlatformAttribute + sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute { - public RemovedInOSPlatformAttribute(string platformName) : base(platformName) + public UnsupportedOSPlatformAttribute(string platformName) : base(platformName) { } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs index 6d95be79f6ce..608838a786b4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs @@ -28,7 +28,7 @@ public EventWaitHandle(bool initialState, EventResetMode mode, string? name, out CreateEventCore(initialState, mode, name, out createdNew); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static EventWaitHandle OpenExisting(string name) { switch (OpenExistingWorker(name, out EventWaitHandle? result)) @@ -45,7 +45,7 @@ public static EventWaitHandle OpenExisting(string name) } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool TryOpenExisting(string name, [NotNullWhen(true)] out EventWaitHandle? result) => OpenExistingWorker(name, out result!) == OpenExistingResult.Success; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs index 40555cc8dfda..4836f7014865 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs @@ -33,7 +33,7 @@ public Semaphore(int initialCount, int maximumCount, string? name, out bool crea CreateSemaphoreCore(initialCount, maximumCount, name, out createdNew); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static Semaphore OpenExisting(string name) { switch (OpenExistingWorker(name, out Semaphore? result)) @@ -50,7 +50,7 @@ public static Semaphore OpenExisting(string name) } } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public static bool TryOpenExisting(string name, [NotNullWhen(true)] out Semaphore? result) => OpenExistingWorker(name, out result!) == OpenExistingResult.Success; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index f468e6cab13a..cb41f1b7dc41 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -227,7 +227,7 @@ public ApartmentState ApartmentState set => TrySetApartmentState(value); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public void SetApartmentState(ApartmentState state) { if (!TrySetApartmentState(state)) 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 a7cc4f4bffd8..5adee94bd662 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -317,7 +317,7 @@ public DefaultParameterValueAttribute(object? value) { } public sealed partial class DispatchWrapper { public DispatchWrapper(object? obj) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public object? WrappedObject { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Property, Inherited=false)] @@ -463,15 +463,15 @@ public static partial class Marshal { public static readonly int SystemDefaultCharSize; public static readonly int SystemMaxDBCSCharSize; - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int AddRef(System.IntPtr pUnk) { throw null; } public static System.IntPtr AllocCoTaskMem(int cb) { throw null; } public static System.IntPtr AllocHGlobal(int cb) { throw null; } public static System.IntPtr AllocHGlobal(System.IntPtr cb) { throw null; } public static bool AreComObjectsAvailableForCleanup() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static object BindToMoniker(string monikerName) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static void ChangeWrapperHandleStrength(object otp, bool fIsWeak) { } public static void CleanupUnusedObjectsInCurrentContext() { } public static void Copy(byte[] source, int startIndex, System.IntPtr destination, int length) { } @@ -490,41 +490,41 @@ public static void Copy(System.IntPtr source, System.IntPtr[] destination, int s public static void Copy(System.IntPtr source, float[] destination, int startIndex, int length) { } public static void Copy(System.IntPtr[] source, int startIndex, System.IntPtr destination, int length) { } public static void Copy(float[] source, int startIndex, System.IntPtr destination, int length) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, T o) where T : notnull { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("o")] public static object? CreateWrapperOfType(object? o, System.Type t) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static TWrapper CreateWrapperOfType([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T o) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void DestroyStructure(System.IntPtr ptr, System.Type structuretype) { } public static void DestroyStructure(System.IntPtr ptr) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int FinalReleaseComObject(object o) { throw null; } public static void FreeBSTR(System.IntPtr ptr) { } public static void FreeCoTaskMem(System.IntPtr ptr) { } public static void FreeHGlobal(System.IntPtr hglobal) { } public static System.Guid GenerateGuidForType(System.Type type) { throw null; } public static string? GenerateProgIdForType(System.Type type) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr GetComInterfaceForObject(object o, System.Type T) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr GetComInterfaceForObject(object o, System.Type T, System.Runtime.InteropServices.CustomQueryInterfaceMode mode) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IntPtr GetComInterfaceForObject([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T o) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static object? GetComObjectData(object obj, object key) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.Delegate GetDelegateForFunctionPointer(System.IntPtr ptr, System.Type t) { throw null; } public static TDelegate GetDelegateForFunctionPointer(System.IntPtr ptr) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int GetEndComSlot(System.Type t) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("GetExceptionCode() may be unavailable in future releases.")] @@ -538,41 +538,41 @@ public static void FreeHGlobal(System.IntPtr hglobal) { } public static System.IntPtr GetHINSTANCE(System.Reflection.Module m) { throw null; } public static int GetHRForException(System.Exception? e) { throw null; } public static int GetHRForLastWin32Error() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IntPtr GetIDispatchForObject(object o) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.IntPtr GetIUnknownForObject(object o) { throw null; } public static int GetLastWin32Error() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void GetNativeVariantForObject(object? obj, System.IntPtr pDstNativeVariant) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void GetNativeVariantForObject([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T obj, System.IntPtr pDstNativeVariant) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static object GetObjectForIUnknown(System.IntPtr pUnk) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object? GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static T GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object?[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static T[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int GetStartComSlot(System.Type t) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.Type GetTypeFromCLSID(System.Guid clsid) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static object GetUniqueObjectForIUnknown(System.IntPtr unknown) { throw null; } public static bool IsComObject(object o) { throw null; } public static bool IsTypeVisibleFromCom(System.Type t) { throw null; } @@ -597,7 +597,7 @@ public static void PtrToStructure(System.IntPtr ptr, object structure) { } [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static T PtrToStructure(System.IntPtr ptr) { throw null; } public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T structure) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { throw null; } public static byte ReadByte(System.IntPtr ptr) { throw null; } public static byte ReadByte(System.IntPtr ptr, int ofs) { throw null; } @@ -626,16 +626,16 @@ public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.Code public static System.IntPtr ReadIntPtr(object ptr, int ofs) { throw null; } public static System.IntPtr ReAllocCoTaskMem(System.IntPtr pv, int cb) { throw null; } public static System.IntPtr ReAllocHGlobal(System.IntPtr pv, System.IntPtr cb) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int Release(System.IntPtr pUnk) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static int ReleaseComObject(object o) { throw null; } public static System.IntPtr SecureStringToBSTR(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToCoTaskMemAnsi(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToCoTaskMemUnicode(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToGlobalAllocAnsi(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToGlobalAllocUnicode(System.Security.SecureString s) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static bool SetComObjectData(object obj, object key, object? data) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static int SizeOf(object structure) { throw null; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index c19f4f56f631..da360cbad7cd 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -9973,9 +9973,9 @@ public FrameworkName(string identifier, System.Version version, string? profile) public override string ToString() { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] - public sealed class MinimumOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute + public sealed class SupportedOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { - public MinimumOSPlatformAttribute(string platformName) : base(platformName) { } + public SupportedOSPlatformAttribute(string platformName) : base(platformName) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] public sealed class ObsoletedInOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute @@ -9991,9 +9991,9 @@ private protected OSPlatformAttribute(string platformName) { } public string PlatformName { get; } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] - public sealed class RemovedInOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute + public sealed class UnsupportedOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { - public RemovedInOSPlatformAttribute(string platformName) : base(platformName) { } + public UnsupportedOSPlatformAttribute(string platformName) : base(platformName) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property, Inherited=false)] [System.Diagnostics.ConditionalAttribute("RESOURCE_ANNOTATION_WORK")] diff --git a/src/libraries/System.Runtime/tests/System/Runtime/Versioning/OSPlatformAttributeTests.cs b/src/libraries/System.Runtime/tests/System/Runtime/Versioning/OSPlatformAttributeTests.cs index 3b9db8ce3bb8..af507a5b4a34 100644 --- a/src/libraries/System.Runtime/tests/System/Runtime/Versioning/OSPlatformAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Runtime/Versioning/OSPlatformAttributeTests.cs @@ -37,9 +37,9 @@ public void TestObsoletedInOSPlatformAttribute(string platformName, string messa [InlineData("Windows8.0")] [InlineData("Android4.1")] [InlineData("")] - public void TestRemovedInOSPlatformAttribute(string platformName) + public void TestUnsupportedOSPlatformAttribute(string platformName) { - var tpa = new RemovedInOSPlatformAttribute(platformName); + var tpa = new UnsupportedOSPlatformAttribute(platformName); Assert.Equal(platformName, tpa.PlatformName); } @@ -48,9 +48,9 @@ public void TestRemovedInOSPlatformAttribute(string platformName) [InlineData("Windows10.0")] [InlineData("OSX")] [InlineData("")] - public void TestMinimumOSPlatformAttribute(string platformName) + public void TestSupportedOSPlatformAttribute(string platformName) { - var tpa = new MinimumOSPlatformAttribute(platformName); + var tpa = new SupportedOSPlatformAttribute(platformName); Assert.Equal(platformName, tpa.PlatformName); } diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs index f4bbc111fbe3..ef1b0d7eb2b3 100644 --- a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs +++ b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs @@ -27,7 +27,7 @@ protected override void Dispose(bool disposing) { } public override void GenerateIV() { } public override void GenerateKey() { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public sealed partial class CspKeyContainerInfo { public CspKeyContainerInfo(System.Security.Cryptography.CspParameters parameters) { } @@ -87,11 +87,11 @@ public sealed partial class DSACryptoServiceProvider : System.Security.Cryptogra { public DSACryptoServiceProvider() { } public DSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public DSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public DSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } public override string? KeyExchangeAlgorithm { get { throw null; } } public override int KeySize { get { throw null; } } @@ -152,7 +152,7 @@ public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashNa public string HashName { get { throw null; } set { } } public int IterationCount { get { throw null; } set { } } public byte[]? Salt { get { throw null; } set { } } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw null; } protected override void Dispose(bool disposing) { } [System.ObsoleteAttribute("Rfc2898DeriveBytes replaces PasswordDeriveBytes for deriving key material from a password and is preferred in new applications.")] @@ -164,7 +164,7 @@ public sealed partial class RC2CryptoServiceProvider : System.Security.Cryptogra { public RC2CryptoServiceProvider() { } public override int EffectiveKeySize { get { throw null; } set { } } - public bool UseSalt { get { throw null; } [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] set { } } + public bool UseSalt { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } public override void GenerateIV() { } @@ -188,11 +188,11 @@ public sealed partial class RSACryptoServiceProvider : System.Security.Cryptogra { public RSACryptoServiceProvider() { } public RSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public RSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public RSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } public override string? KeyExchangeAlgorithm { get { throw null; } } public override int KeySize { get { throw null; } } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs index 843352987a4c..4ae3494de720 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs @@ -5,7 +5,7 @@ namespace System.Security.Cryptography { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public sealed class CspKeyContainerInfo { public CspKeyContainerInfo(CspParameters parameters) { throw GetPlatformNotSupported(); } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs index 25021e88630d..c707007cb931 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs @@ -7,7 +7,7 @@ namespace System.Security.Cryptography { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public sealed class CspKeyContainerInfo { private readonly CspParameters _parameters; diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs index 74811cb089ee..0c324e1f5916 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs @@ -38,13 +38,13 @@ public DSACryptoServiceProvider(int dwKeySize) : base() KeySize = dwKeySize; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public DSACryptoServiceProvider(CspParameters parameters) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); @@ -56,7 +56,7 @@ public DSACryptoServiceProvider(CspParameters parameters) public override bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten) => _impl.TryCreateSignature(hash, destination, out bytesWritten); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public CspKeyContainerInfo CspKeyContainerInfo { get { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspKeyContainerInfo))); } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs index 686728e6a522..ef5d6f544a28 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs @@ -50,7 +50,7 @@ public DSACryptoServiceProvider(int dwKeySize) /// for the cryptographic service provider (CSP). /// /// The parameters for the CSP. - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public DSACryptoServiceProvider(CspParameters? parameters) : this(0, parameters) { @@ -63,7 +63,7 @@ public DSACryptoServiceProvider(CspParameters? parameters) /// The size of the key for the cryptographic algorithm in bits. /// The parameters for the CSP. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is required by the FIPS 186-2 DSA spec.")] - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public DSACryptoServiceProvider(int dwKeySize, CspParameters? parameters) { if (dwKeySize < 0) @@ -185,7 +185,7 @@ private SafeKeyHandle SafeKeyHandle /// /// Gets a CspKeyContainerInfo object that describes additional information about a cryptographic key pair. /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public CspKeyContainerInfo CspKeyContainerInfo { get diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs index 2627057a7bb5..777b1d6e7ccb 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs @@ -7,7 +7,7 @@ namespace System.Security.Cryptography { public partial class PasswordDeriveBytes : DeriveBytes { - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CryptDeriveKey))); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs index 58c546e62b27..41d8e23454cf 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs @@ -12,7 +12,7 @@ public partial class PasswordDeriveBytes : DeriveBytes { private SafeProvHandle? _safeProvHandle; - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { if (keySize < 0) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs index 3cab2033995b..559bd9647904 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs @@ -104,7 +104,7 @@ public override PaddingMode Padding public bool UseSalt { get { return false; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { // Don't allow a true value diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs index a7c1c42084e3..1118b136bfc1 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs @@ -44,7 +44,7 @@ public bool UseSalt { return _use40bitSalt; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] set { _use40bitSalt = value; diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs index d36a068c80b3..d44478f7177f 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs @@ -27,15 +27,15 @@ public RSACryptoServiceProvider(int dwKeySize) _impl = RSA.Create(dwKeySize); } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public RSACryptoServiceProvider(int dwKeySize, CspParameters parameters) => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public RSACryptoServiceProvider(CspParameters parameters) => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public CspKeyContainerInfo CspKeyContainerInfo => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspKeyContainerInfo))); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs index e0a8cce1751b..f3a6586ee434 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs @@ -40,13 +40,13 @@ public RSACryptoServiceProvider(int dwKeySize) { } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public RSACryptoServiceProvider(int dwKeySize, CspParameters? parameters) : this(dwKeySize, parameters, false) { } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public RSACryptoServiceProvider(CspParameters? parameters) : this(0, parameters, true) { @@ -174,7 +174,7 @@ private SafeKeyHandle SafeKeyHandle /// /// CspKeyContainerInfo property /// - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public CspKeyContainerInfo CspKeyContainerInfo { get diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs index 07b51c0d456c..a0256d2581af 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs @@ -332,7 +332,7 @@ public partial class X509Chain : System.IDisposable { public X509Chain() { } public X509Chain(bool useMachineContext) { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public X509Chain(System.IntPtr chainContext) { } public System.IntPtr ChainContext { get { throw null; } } public System.Security.Cryptography.X509Certificates.X509ChainElementCollection ChainElements { get { throw null; } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs index 51d4001e2d51..348ed9249aaa 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs @@ -24,7 +24,7 @@ public X509Chain(bool useMachineContext) _useMachineContext = useMachineContext; } - [MinimumOSPlatform("windows7.0")] + [SupportedOSPlatform("windows7.0")] public X509Chain(IntPtr chainContext) { _pal = ChainPal.FromHandle(chainContext); diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs index 83df550d43dd..294f9592e819 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs @@ -80,7 +80,7 @@ public static void MemoryBarrier() { } public static void ResetAbort() { } [System.ObsoleteAttribute("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. https://go.microsoft.com/fwlink/?linkid=14202", false)] public void Resume() { } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public void SetApartmentState(System.Threading.ApartmentState state) { } [System.ObsoleteAttribute("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public void SetCompressedStack(System.Threading.CompressedStack stack) { } diff --git a/src/libraries/System.Threading/ref/System.Threading.cs b/src/libraries/System.Threading/ref/System.Threading.cs index 87d1f38e72e8..ac1c98dd4d57 100644 --- a/src/libraries/System.Threading/ref/System.Threading.cs +++ b/src/libraries/System.Threading/ref/System.Threading.cs @@ -115,11 +115,11 @@ public partial class EventWaitHandle : System.Threading.WaitHandle public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode) { } public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string? name) { } public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string? name, out bool createdNew) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.Threading.EventWaitHandle OpenExisting(string name) { throw null; } public bool Reset() { throw null; } public bool Set() { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static bool TryOpenExisting(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Threading.EventWaitHandle? result) { throw null; } } public sealed partial class ExecutionContext : System.IDisposable, System.Runtime.Serialization.ISerializable @@ -350,11 +350,11 @@ public sealed partial class Semaphore : System.Threading.WaitHandle public Semaphore(int initialCount, int maximumCount) { } public Semaphore(int initialCount, int maximumCount, string? name) { } public Semaphore(int initialCount, int maximumCount, string? name, out bool createdNew) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static System.Threading.Semaphore OpenExisting(string name) { throw null; } public int Release() { throw null; } public int Release(int releaseCount) { throw null; } - [System.Runtime.Versioning.MinimumOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] public static bool TryOpenExisting(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Threading.Semaphore? result) { throw null; } } public partial class SemaphoreFullException : System.SystemException From dd05d4757795224e7ffd996c030a7080001a03a8 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 5 Aug 2020 09:10:15 -0700 Subject: [PATCH 262/755] When invoking class constructor ensure class is initialized (#40293) When invoking the class constructor method via reflection invoke, ensure that the class constructor is run via the standard run class constructor pathway instead of running it explicitly. Do the same for module constructors. --- .../src/System/Reflection/INVOCATION_FLAGS.cs | 3 +- .../Reflection/RuntimeConstructorInfo.cs | 23 +++++++++++- .../tests/ConstructorInfoTests.cs | 35 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs index e7d9b97ac5c6..b6a55518914a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs @@ -14,7 +14,8 @@ internal enum INVOCATION_FLAGS : uint INVOCATION_FLAGS_INITIALIZED = 0x00000001, // it's used for both method and field to signify that no access is allowed INVOCATION_FLAGS_NO_INVOKE = 0x00000002, - /* unused 0x00000004 */ + // Set for static ctors, to ensure that the static ctor is run as a static ctor before it is explicitly executed via reflection + INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR = 0x00000004, // Set for static ctors and ctors on abstract types, which // can be invoked only if the "this" object is provided (even if it's null). INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008, diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs index 9d0086ca4425..e06251e6ad85 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Runtime.CompilerServices; using System.Text; using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; @@ -47,7 +48,12 @@ internal INVOCATION_FLAGS InvocationFlags // We don't need other flags if this method cannot be invoked invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE; } - else if (IsStatic || declaringType != null && declaringType.IsAbstract) + else if (IsStatic) + { + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR | + INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE; + } + else if (declaringType != null && declaringType.IsAbstract) { invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE; } @@ -280,6 +286,21 @@ internal void ThrowNoInvokeException() // check basic method consistency. This call will throw if there are problems in the target/method relationship CheckConsistency(obj); + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR) != 0) + { + // Run the class constructor through the class constructor mechanism instead of the Invoke path. + // This avoids allowing mutation of readonly static fields, and initializes the type correctly. + + var declaringType = DeclaringType; + + if (declaringType != null) + RuntimeHelpers.RunClassConstructor(declaringType.TypeHandle); + else + RuntimeHelpers.RunModuleConstructor(Module.ModuleHandle); + + return null; + } + Signature sig = Signature; // get the signature diff --git a/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs b/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs index 38a5e4607185..a10424528107 100644 --- a/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs +++ b/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs @@ -68,6 +68,27 @@ public void Invoke_StaticConstructor_NullObject_NullParameters() Assert.Null(obj); } + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40351", TestRuntimes.Mono)] + public void Invoke_StaticConstructorMultipleTimes() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection)); + Assert.Equal(1, constructors.Length); + // The first time the static cctor is called, it should run the cctor twice + // Once to initialize run the cctor as a cctor + // The second to run it as a method which is invoked. + Assert.Equal(0, ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection.VisibleStatics.s_cctorCallCount); + object obj = constructors[0].Invoke(null, new object[] { }); + Assert.Null(obj); + Assert.Equal(1, ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection.VisibleStatics.s_cctorCallCount); + + // Subsequent invocations of the static cctor should not run the cctor at all, as it has already executed + // and running multiple times opens up the possibility of modifying read only static data + obj = constructors[0].Invoke(null, new object[] { }); + Assert.Null(obj); + Assert.Equal(1, ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection.VisibleStatics.s_cctorCallCount); + } + [Fact] [ActiveIssue("https://github.com/mono/mono/issues/15024", TestRuntimes.Mono)] public void Invoke_StaticConstructor_ThrowsMemberAccessException() @@ -236,6 +257,20 @@ public static class ClassWithStaticConstructor static ClassWithStaticConstructor() { } } + // Use this class only from the Invoke_StaticConstructorMultipleTimes method + public static class ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection + { + public static class VisibleStatics + { + public static int s_cctorCallCount; + } + + static ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection() + { + VisibleStatics.s_cctorCallCount++; + } + } + public struct StructWith1Constructor { public int x; From d306c6f31d85648c479012b20a9786d453a79ea1 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 5 Aug 2020 18:24:03 +0200 Subject: [PATCH 263/755] Mark existing Windows-specific APIs without a version number, fixes #40095 (#40375) --- eng/Configurations.props | 1 - eng/versioning.targets | 2 +- .../InteropServices/Marshal.CoreCLR.cs | 62 +++++++-------- ...stem.Configuration.ConfigurationManager.cs | 2 +- .../DpapiProtectedConfigurationProvider.cs | 2 +- .../System.Console/ref/System.Console.cs | 34 ++++---- .../System.Console/src/System/Console.cs | 34 ++++---- .../ref/System.Diagnostics.Process.cs | 20 ++--- .../src/System/Diagnostics/Process.Unix.cs | 4 +- .../src/System/Diagnostics/Process.Windows.cs | 4 +- .../src/System/Diagnostics/Process.cs | 4 +- .../Diagnostics/ProcessStartInfo.Unix.cs | 8 +- .../Diagnostics/ProcessStartInfo.Windows.cs | 8 +- .../System/Diagnostics/ProcessThread.Unix.cs | 2 +- .../Diagnostics/ProcessThread.Windows.cs | 2 +- .../src/System/Diagnostics/ProcessThread.cs | 2 +- .../ref/System.IO.FileSystem.DriveInfo.cs | 2 +- .../src/System/IO/DriveInfo.UnixOrBrowser.cs | 2 +- .../src/System/IO/DriveInfo.Windows.cs | 2 +- .../ref/System.IO.FileSystem.cs | 4 +- .../src/System/IO/File.cs | 4 +- .../ref/System.IO.MemoryMappedFiles.cs | 12 +-- .../IO/MemoryMappedFiles/MemoryMappedFile.cs | 12 +-- .../System.IO.Pipes/ref/System.IO.Pipes.cs | 6 +- .../IO/Pipes/NamedPipeClientStream.Unix.cs | 2 +- .../IO/Pipes/NamedPipeClientStream.Windows.cs | 2 +- .../src/System/IO/Pipes/PipeStream.Unix.cs | 2 +- .../src/System/IO/Pipes/PipeStream.Windows.cs | 2 +- .../System/IO/Pipes/PipeTransmissionMode.cs | 2 +- .../ref/System.Net.HttpListener.cs | 8 +- .../HttpListenerTimeoutManager.Managed.cs | 8 +- .../HttpListenerTimeoutManager.Windows.cs | 8 +- .../ref/System.Net.Sockets.cs | 78 +++++++++---------- .../src/System/Net/Sockets/IOControlCode.cs | 62 +++++++-------- .../src/System/Net/Sockets/Socket.Unix.cs | 4 +- .../src/System/Net/Sockets/Socket.Windows.cs | 4 +- .../src/System/Net/Sockets/Socket.cs | 2 +- .../src/System/Net/Sockets/TCPListener.cs | 2 +- .../System/Net/Sockets/TransmitFileOptions.cs | 6 +- .../src/System/Net/Sockets/UDPClient.cs | 2 +- .../InteropServices/DispatchWrapper.cs | 2 +- .../Runtime/InteropServices/Marshal.NoCom.cs | 62 +++++++-------- .../src/System/Threading/EventWaitHandle.cs | 4 +- .../src/System/Threading/Semaphore.cs | 4 +- .../src/System/Threading/Thread.cs | 2 +- .../ref/System.Runtime.InteropServices.cs | 64 +++++++-------- .../ref/System.Security.Cryptography.Csp.cs | 18 ++--- .../Cryptography/CspKeyContainerInfo.Unix.cs | 2 +- .../CspKeyContainerInfo.Windows.cs | 2 +- .../DSACryptoServiceProvider.Unix.cs | 6 +- .../DSACryptoServiceProvider.Windows.cs | 6 +- .../Cryptography/PasswordDeriveBytes.Unix.cs | 2 +- .../PasswordDeriveBytes.Windows.cs | 2 +- .../RC2CryptoServiceProvider.Unix.cs | 2 +- .../RC2CryptoServiceProvider.Windows.cs | 2 +- .../RSACryptoServiceProvider.Unix.cs | 6 +- .../RSACryptoServiceProvider.Windows.cs | 6 +- ....Security.Cryptography.X509Certificates.cs | 2 +- .../X509Certificates/X509Chain.cs | 2 +- .../ref/System.Threading.Thread.cs | 2 +- .../System.Threading/ref/System.Threading.cs | 8 +- 61 files changed, 317 insertions(+), 318 deletions(-) diff --git a/eng/Configurations.props b/eng/Configurations.props index 59424f7cc30a..3d123f81972a 100644 --- a/eng/Configurations.props +++ b/eng/Configurations.props @@ -29,7 +29,6 @@ $(NetCoreAppCurrent) Microsoft.NETCore.App .NET $(NetCoreAppCurrentVersion) - WINDOWS7.0 diff --git a/eng/versioning.targets b/eng/versioning.targets index 9b3078d94156..f0cbf0e22899 100644 --- a/eng/versioning.targets +++ b/eng/versioning.targets @@ -25,7 +25,7 @@ - <_Parameter1>$(MinimiumSupportedWindowsPlatform) + <_Parameter1>windows 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 b0c4eaaa6f29..994244c034db 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 @@ -307,7 +307,7 @@ public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb) /// /// Given a managed object that wraps an ITypeInfo, return its name. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static string GetTypeInfoName(ITypeInfo typeInfo) { if (typeInfo is null) @@ -321,14 +321,14 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) // This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it // on Marshal for more consistent API surface. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Type? GetTypeFromCLSID(Guid clsid) => RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError: false); /// /// Return the IUnknown* for an Object if the current context is the one /// where the RCW was first seen. Will return null otherwise. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr /* IUnknown* */ GetIUnknownForObject(object o) { if (o is null) @@ -352,7 +352,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the IDispatch* for an Object. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) { if (o is null) @@ -370,7 +370,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Return the IUnknown* representing the interface for the Object. /// Object o should support Type T /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T) { if (o is null) @@ -386,7 +386,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) return GetComInterfaceForObjectNative(o, T, false, true); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) => GetComInterfaceForObject(o!, typeof(TInterface)); /// @@ -394,7 +394,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// Object o should support Type T, it refer the value of mode to /// invoke customized QueryInterface or not. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode) { if (o is null) @@ -417,7 +417,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo) /// /// Return the managed object representing the IUnknown* /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { if (pUnk == IntPtr.Zero) @@ -431,7 +431,7 @@ public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) [MethodImpl(MethodImplOptions.InternalCall)] private static extern object GetObjectForIUnknownNative(IntPtr /* IUnknown* */ pUnk); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object GetUniqueObjectForIUnknown(IntPtr unknown) { if (unknown == IntPtr.Zero) @@ -455,15 +455,15 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown) /// Return an Object for IUnknown, using the Type T. /// Type T should be either a COM imported Type or a sub-type of COM imported Type /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull { return CreateAggregatedObject(pOuter, (object)o); @@ -562,7 +562,7 @@ public static string PtrToStringBSTR(IntPtr ptr) /// Release the COM component and if the reference hits 0 zombie this object. /// Further usage of this Object might throw an exception /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int ReleaseComObject(object o) { if (o is null) @@ -585,7 +585,7 @@ public static int ReleaseComObject(object o) /// Release the COM component and zombie this object. /// Further usage of this Object might throw an exception /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int FinalReleaseComObject(object o) { if (o is null) @@ -604,7 +604,7 @@ public static int FinalReleaseComObject(object o) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void InternalFinalReleaseComObject(object o); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object? GetComObjectData(object obj, object key) { if (obj is null) @@ -630,7 +630,7 @@ public static int FinalReleaseComObject(object o) /// false if the data could not be added because there already was data for the /// specified key. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool SetComObjectData(object obj, object key, object? data) { if (obj is null) @@ -654,7 +654,7 @@ public static bool SetComObjectData(object obj, object key, object? data) /// This method takes the given COM object and wraps it in an object /// of the specified type. The type must be derived from __ComObject. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [return: NotNullIfNotNull("o")] public static object? CreateWrapperOfType(object? o, Type t) { @@ -705,7 +705,7 @@ public static bool SetComObjectData(object obj, object key, object? data) return Wrapper; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static TWrapper CreateWrapperOfType([AllowNull] T o) { return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!; @@ -720,7 +720,7 @@ public static TWrapper CreateWrapperOfType([AllowNull] T o) [MethodImpl(MethodImplOptions.InternalCall)] public static extern bool IsTypeVisibleFromCom(Type t); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) { if (pUnk == IntPtr.Zero) @@ -733,7 +733,7 @@ public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr pp } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static unsafe int AddRef(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -742,7 +742,7 @@ public static unsafe int AddRef(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 1 /* IUnknown.AddRef slot */)))(pUnk); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static unsafe int Release(IntPtr pUnk) { if (pUnk == IntPtr.Zero) @@ -751,32 +751,32 @@ public static unsafe int Release(IntPtr pUnk) return ((delegate * stdcall )(*(*(void***)pUnk + 2 /* IUnknown.Release slot */)))(pUnk); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) { GetNativeVariantForObject((object?)obj, pDstNativeVariant); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [return: MaybeNull] public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { return (T)GetObjectForNativeVariant(pSrcNativeVariant)!; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars); @@ -791,18 +791,18 @@ public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int c /// Returns the first valid COM slot that GetMethodInfoForSlot will work on /// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetStartComSlot(Type t); /// /// Returns the last valid COM slot that GetMethodInfoForSlot will work on. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetEndComSlot(Type t); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object BindToMoniker(string monikerName) { CreateBindCtx(0, out IBindCtx bindctx); @@ -822,7 +822,7 @@ public static object BindToMoniker(string monikerName) [DllImport(Interop.Libraries.Ole32, PreserveSig = false)] private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak); #endif // FEATURE_COMINTEROP diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index 1d53ffa8e46b..29527d20cd52 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -607,7 +607,7 @@ public DictionarySectionHandler() { } protected virtual string ValueAttributeName { get { throw null; } } public virtual object Create(object parent, object context, System.Xml.XmlNode section) { throw null; } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public sealed partial class DpapiProtectedConfigurationProvider : System.Configuration.ProtectedConfigurationProvider { public DpapiProtectedConfigurationProvider() { } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs index 3a395e05b17c..db546c801031 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/DpapiProtectedConfigurationProvider.cs @@ -9,7 +9,7 @@ namespace System.Configuration { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public sealed class DpapiProtectedConfigurationProvider : ProtectedConfigurationProvider { private bool _useMachineProtection = true; diff --git a/src/libraries/System.Console/ref/System.Console.cs b/src/libraries/System.Console/ref/System.Console.cs index 94cabc7a6827..6c17987a1b49 100644 --- a/src/libraries/System.Console/ref/System.Console.cs +++ b/src/libraries/System.Console/ref/System.Console.cs @@ -9,14 +9,14 @@ namespace System public static partial class Console { public static System.ConsoleColor BackgroundColor { get { throw null; } set { } } - public static int BufferHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public static int BufferWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + public static int BufferHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public static int BufferWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static bool CapsLock { get { throw null; } } public static int CursorLeft { get { throw null; } set { } } - public static int CursorSize { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int CursorSize { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static int CursorTop { get { throw null; } set { } } - public static bool CursorVisible { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] get { throw null; } set { } } + public static bool CursorVisible { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] get { throw null; } set { } } public static System.IO.TextWriter Error { get { throw null; } } public static System.ConsoleColor ForegroundColor { get { throw null; } set { } } public static System.IO.TextReader In { get { throw null; } } @@ -27,25 +27,25 @@ public static partial class Console public static bool KeyAvailable { get { throw null; } } public static int LargestWindowHeight { get { throw null; } } public static int LargestWindowWidth { get { throw null; } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static bool NumberLock { get { throw null; } } public static System.IO.TextWriter Out { get { throw null; } } public static System.Text.Encoding OutputEncoding { get { throw null; } set { } } - public static string Title { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] get { throw null; } set { } } + public static string Title { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] get { throw null; } set { } } public static bool TreatControlCAsInput { get { throw null; } set { } } - public static int WindowHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public static int WindowLeft { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public static int WindowTop { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public static int WindowWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public static int WindowHeight { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public static int WindowLeft { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public static int WindowTop { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public static int WindowWidth { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static event System.ConsoleCancelEventHandler? CancelKeyPress { add { } remove { } } public static void Beep() { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void Beep(int frequency, int duration) { } public static void Clear() { } public static (int Left, int Top) GetCursorPosition() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, System.ConsoleColor sourceForeColor, System.ConsoleColor sourceBackColor) { } public static System.IO.Stream OpenStandardError() { throw null; } public static System.IO.Stream OpenStandardError(int bufferSize) { throw null; } @@ -58,15 +58,15 @@ public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth public static System.ConsoleKeyInfo ReadKey(bool intercept) { throw null; } public static string? ReadLine() { throw null; } public static void ResetColor() { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void SetBufferSize(int width, int height) { } public static void SetCursorPosition(int left, int top) { } public static void SetError(System.IO.TextWriter newError) { } public static void SetIn(System.IO.TextReader newIn) { } public static void SetOut(System.IO.TextWriter newOut) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void SetWindowPosition(int left, int top) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void SetWindowSize(int width, int height) { } public static void Write(bool value) { } public static void Write(char value) { } diff --git a/src/libraries/System.Console/src/System/Console.cs b/src/libraries/System.Console/src/System/Console.cs index d20ec813d7a4..ec589857c161 100644 --- a/src/libraries/System.Console/src/System/Console.cs +++ b/src/libraries/System.Console/src/System/Console.cs @@ -277,17 +277,17 @@ static StrongBox EnsureInitialized() public static int CursorSize { get { return ConsolePal.CursorSize; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.CursorSize = value; } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool NumberLock { get { return ConsolePal.NumberLock; } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool CapsLock { get { return ConsolePal.CapsLock; } @@ -315,18 +315,18 @@ public static void ResetColor() public static int BufferWidth { get { return ConsolePal.BufferWidth; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.BufferWidth = value; } } public static int BufferHeight { get { return ConsolePal.BufferHeight; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.BufferHeight = value; } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void SetBufferSize(int width, int height) { ConsolePal.SetBufferSize(width, height); @@ -335,38 +335,38 @@ public static void SetBufferSize(int width, int height) public static int WindowLeft { get { return ConsolePal.WindowLeft; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.WindowLeft = value; } } public static int WindowTop { get { return ConsolePal.WindowTop; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.WindowTop = value; } } public static int WindowWidth { get { return ConsolePal.WindowWidth; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.WindowWidth = value; } } public static int WindowHeight { get { return ConsolePal.WindowHeight; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ConsolePal.WindowHeight = value; } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void SetWindowPosition(int left, int top) { ConsolePal.SetWindowPosition(left, top); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void SetWindowSize(int width, int height) { ConsolePal.SetWindowSize(width, height); @@ -384,7 +384,7 @@ public static int LargestWindowHeight public static bool CursorVisible { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] get { return ConsolePal.CursorVisible; } set { ConsolePal.CursorVisible = value; } } @@ -413,7 +413,7 @@ public static (int Left, int Top) GetCursorPosition() public static string Title { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] get { return ConsolePal.Title; } set { @@ -426,19 +426,19 @@ public static void Beep() ConsolePal.Beep(); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void Beep(int frequency, int duration) { ConsolePal.Beep(frequency, duration); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop) { ConsolePal.MoveBufferArea(sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop, ' ', ConsoleColor.Black, BackgroundColor); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) { ConsolePal.MoveBufferArea(sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop, sourceChar, sourceForeColor, sourceBackColor); diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index de9b9df74c83..57c2a5cfc612 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -41,8 +41,8 @@ public Process() { } public System.Diagnostics.ProcessModule? MainModule { get { throw null; } } public System.IntPtr MainWindowHandle { get { throw null; } } public string MainWindowTitle { get { throw null; } } - public System.IntPtr MaxWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public System.IntPtr MinWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.IntPtr MaxWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public System.IntPtr MinWorkingSet { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public System.Diagnostics.ProcessModuleCollection Modules { get { throw null; } } [System.ObsoleteAttribute("This property has been deprecated. Please use System.Diagnostics.Process.NonpagedSystemMemorySize64 instead. https://go.microsoft.com/fwlink/?linkid=14202")] public int NonpagedSystemMemorySize { get { throw null; } } @@ -116,10 +116,10 @@ public void Refresh() { } public static System.Diagnostics.Process Start(string fileName) { throw null; } public static System.Diagnostics.Process Start(string fileName, string arguments) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Diagnostics.Process Start(string fileName, string userName, System.Security.SecureString password, string domain) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Diagnostics.Process Start(string fileName, string arguments, string userName, System.Security.SecureString password, string domain) { throw null; } public override string ToString() { throw null; } public void WaitForExit() { } @@ -165,19 +165,19 @@ public ProcessStartInfo(string fileName, string arguments) { } public System.Collections.ObjectModel.Collection ArgumentList { get { throw null; } } public string Arguments { get { throw null; } set { } } public bool CreateNoWindow { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public string Domain { get { throw null; } set { } } public System.Collections.Generic.IDictionary Environment { get { throw null; } } public System.Collections.Specialized.StringDictionary EnvironmentVariables { get { throw null; } } public bool ErrorDialog { get { throw null; } set { } } public System.IntPtr ErrorDialogParentHandle { get { throw null; } set { } } public string FileName { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public bool LoadUserProfile { get { throw null; } set { } } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public System.Security.SecureString? Password { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public string? PasswordInClearText { get { throw null; } set { } } public bool RedirectStandardError { get { throw null; } set { } } public bool RedirectStandardInput { get { throw null; } set { } } @@ -202,9 +202,9 @@ internal ProcessThread() { } public int Id { get { throw null; } } public int IdealProcessor { set { } } public bool PriorityBoostEnabled { get { throw null; } set { } } - public System.Diagnostics.ThreadPriorityLevel PriorityLevel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.Diagnostics.ThreadPriorityLevel PriorityLevel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public System.TimeSpan PrivilegedProcessorTime { get { throw null; } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public System.IntPtr ProcessorAffinity { set { } } public System.IntPtr StartAddress { get { throw null; } } public System.DateTime StartTime { get { throw null; } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs index 2fa005cbdd4e..fee92705d931 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs @@ -42,14 +42,14 @@ public static void LeaveDebugMode() } [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Process Start(string fileName, string userName, SecureString password, string domain) { throw new PlatformNotSupportedException(SR.ProcessStartWithPasswordAndDomainNotSupported); } [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain) { throw new PlatformNotSupportedException(SR.ProcessStartWithPasswordAndDomainNotSupported); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs index abd11001b032..af02b8a2b614 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs @@ -47,7 +47,7 @@ public static Process[] GetProcessesByName(string? processName, string machineNa } [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Process? Start(string fileName, string userName, SecureString password, string domain) { ProcessStartInfo startInfo = new ProcessStartInfo(fileName); @@ -59,7 +59,7 @@ public static Process[] GetProcessesByName(string? processName, string machineNa } [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Process? Start(string fileName, string arguments, string userName, SecureString password, string domain) { ProcessStartInfo startInfo = new ProcessStartInfo(fileName, arguments); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index aac6c7b1f964..6d33ac04877c 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -265,7 +265,7 @@ public IntPtr MaxWorkingSet EnsureWorkingSetLimits(); return _maxWorkingSet; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { SetWorkingSetLimits(null, value); @@ -285,7 +285,7 @@ public IntPtr MinWorkingSet EnsureWorkingSetLimits(); return _minWorkingSet; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { SetWorkingSetLimits(value, null); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs index 9cbbd4009502..4c674caef0b1 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs @@ -14,21 +14,21 @@ public sealed partial class ProcessStartInfo { private const bool CaseSensitiveEnvironmentVariables = true; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public string PasswordInClearText { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(PasswordInClearText))); } set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(PasswordInClearText))); } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public string Domain { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Domain))); } set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Domain))); } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public bool LoadUserProfile { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(LoadUserProfile))); } @@ -40,7 +40,7 @@ public bool LoadUserProfile public string[] Verbs => Array.Empty(); [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public SecureString Password { get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Password))); } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs index ba3ab4eee48e..f786a0055eb8 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs @@ -12,21 +12,21 @@ public sealed partial class ProcessStartInfo private const bool CaseSensitiveEnvironmentVariables = false; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public string? PasswordInClearText { get; set; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public string Domain { get => _domain ?? string.Empty; set => _domain = value; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public bool LoadUserProfile { get; set; } [CLSCompliant(false)] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public SecureString? Password { get; set; } } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs index d1b8cdb978da..ccee750841cd 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Unix.cs @@ -41,7 +41,7 @@ private bool PriorityBoostEnabledCore /// two, etc. For example, the value 1 means run on processor one, 2 means run on /// processor two, 3 means run on processor one or two. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public IntPtr ProcessorAffinity { set { throw new PlatformNotSupportedException(); } // No ability to change the affinity of a thread in an arbitrary process diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs index db18cd7f4b2d..f46fd604e5e2 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.Windows.cs @@ -100,7 +100,7 @@ private ThreadPriorityLevel PriorityLevelCore /// two, etc. For example, the value 1 means run on processor one, 2 means run on /// processor two, 3 means run on processor one or two. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public IntPtr ProcessorAffinity { set diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs index b0a10b5e9a6b..f5ec77c8e564 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs @@ -95,7 +95,7 @@ public ThreadPriorityLevel PriorityLevel } return _priorityLevel.Value; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { PriorityLevelCore = value; diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs b/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs index b7d16e5d740d..19e8f51412b3 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs +++ b/src/libraries/System.IO.FileSystem.DriveInfo/ref/System.IO.FileSystem.DriveInfo.cs @@ -18,7 +18,7 @@ public DriveInfo(string driveName) { } public long TotalFreeSpace { get { throw null; } } public long TotalSize { get { throw null; } } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] - public string VolumeLabel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public string VolumeLabel { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static System.IO.DriveInfo[] GetDrives() { throw null; } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public override string ToString() { throw null; } diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs index bbfbd8bb4ac2..51892986a5df 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs @@ -42,7 +42,7 @@ public string VolumeLabel { return Name; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { throw new PlatformNotSupportedException(); 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 ef89cd3763f2..d361611377ed 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 @@ -139,7 +139,7 @@ public unsafe string VolumeLabel return new string(volumeName); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { uint oldMode; diff --git a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs index 09e8f6d76393..e6fbef2727e0 100644 --- a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs +++ b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs @@ -121,10 +121,10 @@ public static void Copy(string sourceFileName, string destFileName, bool overwri public static System.IO.FileStream Create(string path, int bufferSize) { throw null; } public static System.IO.FileStream Create(string path, int bufferSize, System.IO.FileOptions options) { throw null; } public static System.IO.StreamWriter CreateText(string path) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void Decrypt(string path) { } public static void Delete(string path) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void Encrypt(string path) { } public static bool Exists(string? path) { throw null; } public static System.IO.FileAttributes GetAttributes(string path) { throw null; } diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs index 366e55a7b399..1b089a91ffc8 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/File.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/File.cs @@ -646,13 +646,13 @@ public static void Move(string sourceFileName, string destFileName, bool overwri FileSystem.MoveFile(fullSourceFileName, fullDestFileName, overwrite); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void Encrypt(string path) { FileSystem.Encrypt(path ?? throw new ArgumentNullException(nameof(path))); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void Decrypt(string path) { FileSystem.Decrypt(path ?? throw new ArgumentNullException(nameof(path))); diff --git a/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs b/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs index 22135ab9cdab..e112060f7849 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/ref/System.IO.MemoryMappedFiles.cs @@ -33,11 +33,11 @@ internal MemoryMappedFile() { } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity) { throw null; } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateNew(string? mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.MemoryMappedFiles.MemoryMappedFileOptions options, System.IO.HandleInheritability inheritability) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile CreateOrOpen(string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.MemoryMappedFiles.MemoryMappedFileOptions options, System.IO.HandleInheritability inheritability) { throw null; } public System.IO.MemoryMappedFiles.MemoryMappedViewAccessor CreateViewAccessor() { throw null; } public System.IO.MemoryMappedFiles.MemoryMappedViewAccessor CreateViewAccessor(long offset, long size) { throw null; } @@ -47,11 +47,11 @@ internal MemoryMappedFile() { } public System.IO.MemoryMappedFiles.MemoryMappedViewStream CreateViewStream(long offset, long size, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access) { throw null; } public void Dispose() { } protected virtual void Dispose(bool disposing) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName, System.IO.MemoryMappedFiles.MemoryMappedFileRights desiredAccessRights) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IO.MemoryMappedFiles.MemoryMappedFile OpenExisting(string mapName, System.IO.MemoryMappedFiles.MemoryMappedFileRights desiredAccessRights, System.IO.HandleInheritability inheritability) { throw null; } } public enum MemoryMappedFileAccess diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs b/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs index fbd2fbc257c4..d2f04e84d27e 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs @@ -44,19 +44,19 @@ private MemoryMappedFile(SafeMemoryMappedFileHandle handle, FileStream fileStrea // the first override of this method. Note: having ReadWrite access to the object does not mean that we // have ReadWrite access to the pages mapping the file. The OS will check against the access on the pages // when a view is created. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile OpenExisting(string mapName) { return OpenExisting(mapName, MemoryMappedFileRights.ReadWrite, HandleInheritability.None); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile OpenExisting(string mapName, MemoryMappedFileRights desiredAccessRights) { return OpenExisting(mapName, desiredAccessRights, HandleInheritability.None); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile OpenExisting(string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability) { @@ -295,21 +295,21 @@ public static MemoryMappedFile CreateNew(string? mapName, long capacity, MemoryM // memory mapped file if one exists with the same name. The capacity, options, and // memoryMappedFileSecurity arguments will be ignored in the case of the later. // This is ideal for P2P style IPC. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity) { return CreateOrOpen(mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity, MemoryMappedFileAccess access) { return CreateOrOpen(mapName, capacity, access, MemoryMappedFileOptions.None, HandleInheritability.None); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static MemoryMappedFile CreateOrOpen(string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability) diff --git a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs index 54b3486328a8..8dfe980c49fb 100644 --- a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs +++ b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs @@ -48,7 +48,7 @@ public sealed partial class NamedPipeClientStream : System.IO.Pipes.PipeStream public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options, System.Security.Principal.TokenImpersonationLevel impersonationLevel) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } public NamedPipeClientStream(string serverName, string pipeName, System.IO.Pipes.PipeDirection direction, System.IO.Pipes.PipeOptions options, System.Security.Principal.TokenImpersonationLevel impersonationLevel, System.IO.HandleInheritability inheritability) : base (default(System.IO.Pipes.PipeDirection), default(int)) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public int NumberOfServerInstances { get { throw null; } } protected internal override void CheckPipePropertyOperations() { } public void Connect() { } @@ -129,7 +129,7 @@ protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle? hand public override int ReadByte() { throw null; } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } public override void SetLength(long value) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void WaitForPipeDrain() { } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } @@ -141,7 +141,7 @@ public override void WriteByte(byte value) { } public enum PipeTransmissionMode { Byte = 0, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] Message = 1, } } diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs index 89d8bb70179f..42fe518e0012 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs @@ -67,7 +67,7 @@ private bool TryConnect(int timeout, CancellationToken cancellationToken) return true; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public int NumberOfServerInstances { get diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs index a7f489497717..a082a3da8639 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs @@ -108,7 +108,7 @@ private bool TryConnect(int timeout, CancellationToken cancellationToken) return true; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public unsafe int NumberOfServerInstances { get diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs index b84999c721e3..6e6fa8a5c138 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs @@ -220,7 +220,7 @@ private IOException GetIOExceptionForSocketException(SocketException e) } // Blocks until the other end of the pipe has read in all written buffer. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void WaitForPipeDrain() { CheckWriteOperations(); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs index 1060da2ea372..b221c9880b6c 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs @@ -179,7 +179,7 @@ private Task WriteAsyncCore(ReadOnlyMemory buffer, CancellationToken cance } // Blocks until the other end of the pipe has read in all written buffer. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void WaitForPipeDrain() { CheckWriteOperations(); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs index 8ed232d3b458..c4d8f0956c04 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs @@ -8,7 +8,7 @@ namespace System.IO.Pipes public enum PipeTransmissionMode { Byte = 0, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] Message = 1, } } diff --git a/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs b/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs index c93cc4941d5b..27f33aac7a2a 100644 --- a/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs +++ b/src/libraries/System.Net.HttpListener/ref/System.Net.HttpListener.cs @@ -139,11 +139,11 @@ public partial class HttpListenerTimeoutManager { internal HttpListenerTimeoutManager() { } public System.TimeSpan DrainEntityBody { get { throw null; } set { } } - public System.TimeSpan EntityBody { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public System.TimeSpan HeaderWait { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public System.TimeSpan EntityBody { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public System.TimeSpan HeaderWait { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public System.TimeSpan IdleConnection { get { throw null; } set { } } - public long MinSendBytesPerSecond { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } - public System.TimeSpan RequestQueue { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public long MinSendBytesPerSecond { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public System.TimeSpan RequestQueue { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } } } namespace System.Net.WebSockets diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs index 8734f93b145f..8dda74410407 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerTimeoutManager.Managed.cs @@ -39,7 +39,7 @@ public TimeSpan IdleConnection public TimeSpan EntityBody { get => TimeSpan.Zero; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ValidateTimeout(value); @@ -50,7 +50,7 @@ public TimeSpan EntityBody public TimeSpan HeaderWait { get => TimeSpan.Zero; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ValidateTimeout(value); @@ -61,7 +61,7 @@ public TimeSpan HeaderWait public long MinSendBytesPerSecond { get => 0; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { if (value < 0 || value > uint.MaxValue) @@ -75,7 +75,7 @@ public long MinSendBytesPerSecond public TimeSpan RequestQueue { get => TimeSpan.Zero; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { ValidateTimeout(value); diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs index 13da1e11e963..a1af5b35b71a 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerTimeoutManager.Windows.cs @@ -83,7 +83,7 @@ public TimeSpan EntityBody { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody, value); @@ -121,7 +121,7 @@ public TimeSpan RequestQueue { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue, value); @@ -157,7 +157,7 @@ public TimeSpan HeaderWait { return GetTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { SetTimespanTimeout(Interop.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait, value); @@ -177,7 +177,7 @@ public long MinSendBytesPerSecond // return _minSendBytesPerSecond; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { // diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index c0d7c4e2dd19..11d3309cf116 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -8,70 +8,70 @@ namespace System.Net.Sockets { public enum IOControlCode : long { - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] EnableCircularQueuing = (long)671088642, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] Flush = (long)671088644, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AddressListChange = (long)671088663, DataToRead = (long)1074030207, OobDataRead = (long)1074033415, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] GetBroadcastAddress = (long)1207959557, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AddressListQuery = (long)1207959574, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] QueryTargetPnpHandle = (long)1207959576, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AsyncIO = (long)2147772029, NonBlockingIO = (long)2147772030, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AssociateHandle = (long)2281701377, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] MultipointLoopback = (long)2281701385, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] MulticastScope = (long)2281701386, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] SetQos = (long)2281701387, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] SetGroupQos = (long)2281701388, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] RoutingInterfaceChange = (long)2281701397, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] NamespaceChange = (long)2281701401, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] ReceiveAll = (long)2550136833, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] ReceiveAllMulticast = (long)2550136834, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] ReceiveAllIgmpMulticast = (long)2550136835, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] KeepAliveValues = (long)2550136836, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AbsorbRouterAlert = (long)2550136837, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] UnicastInterface = (long)2550136838, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] LimitBroadcasts = (long)2550136839, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] BindToInterface = (long)2550136840, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] MulticastInterface = (long)2550136841, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AddMulticastGroupOnInterface = (long)2550136842, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] DeleteMulticastGroupFromInterface = (long)2550136843, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] GetExtensionFunctionPointer = (long)3355443206, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] GetQos = (long)3355443207, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] GetGroupQos = (long)3355443208, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] TranslateHandle = (long)3355443213, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] RoutingInterfaceQuery = (long)3355443220, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] AddressListSort = (long)3355443225, } public partial struct IPPacketInformation @@ -254,7 +254,7 @@ public partial class Socket : System.IDisposable { public Socket(System.Net.Sockets.SafeSocketHandle handle) { } public Socket(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public Socket(System.Net.Sockets.SocketInformation socketInformation) { } public Socket(System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } public System.Net.Sockets.AddressFamily AddressFamily { get { throw null; } } @@ -326,7 +326,7 @@ public void Disconnect(bool reuseSocket) { } public bool DisconnectAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; } public void Dispose() { } protected virtual void Dispose(bool disposing) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public System.Net.Sockets.SocketInformation DuplicateAndClose(int targetProcessId) { throw null; } public System.Net.Sockets.Socket EndAccept(out byte[] buffer, System.IAsyncResult asyncResult) { throw null; } public System.Net.Sockets.Socket EndAccept(out byte[] buffer, out int bytesTransferred, System.IAsyncResult asyncResult) { throw null; } @@ -391,7 +391,7 @@ public void SendFile(string? fileName, byte[]? preBuffer, byte[]? postBuffer, Sy public int SendTo(byte[] buffer, System.Net.EndPoint remoteEP) { throw null; } public int SendTo(byte[] buffer, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEP) { throw null; } public bool SendToAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void SetIPProtectionLevel(System.Net.Sockets.IPProtectionLevel level) { } public void SetRawSocketOption(int optionLevel, int optionName, System.ReadOnlySpan optionValue) { } public void SetSocketOption(System.Net.Sockets.SocketOptionLevel optionLevel, System.Net.Sockets.SocketOptionName optionName, bool optionValue) { } @@ -626,7 +626,7 @@ public TcpListener(System.Net.IPEndPoint localEP) { } public System.Threading.Tasks.Task AcceptSocketAsync() { throw null; } public System.Net.Sockets.TcpClient AcceptTcpClient() { throw null; } public System.Threading.Tasks.Task AcceptTcpClientAsync() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void AllowNatTraversal(bool allowed) { } public System.IAsyncResult BeginAcceptSocket(System.AsyncCallback? callback, object? state) { throw null; } public System.IAsyncResult BeginAcceptTcpClient(System.AsyncCallback? callback, object? state) { throw null; } @@ -644,11 +644,11 @@ public enum TransmitFileOptions UseDefaultWorkerThread = 0, Disconnect = 1, ReuseSocket = 2, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] WriteBehind = 4, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] UseSystemThread = 16, - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] UseKernelApc = 32, } public partial class UdpClient : System.IDisposable @@ -667,7 +667,7 @@ public UdpClient(string hostname, int port) { } public bool ExclusiveAddressUse { get { throw null; } set { } } public bool MulticastLoopback { get { throw null; } set { } } public short Ttl { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void AllowNatTraversal(bool allowed) { } public System.IAsyncResult BeginReceive(System.AsyncCallback? requestCallback, object? state) { throw null; } public System.IAsyncResult BeginSend(byte[] datagram, int bytes, System.AsyncCallback? requestCallback, object? state) { throw null; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs index a2e4c9efd0ec..0039c85553c3 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/IOControlCode.cs @@ -7,70 +7,70 @@ namespace System.Net.Sockets { public enum IOControlCode : long { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AsyncIO = 0x8004667D, NonBlockingIO = 0x8004667E, // fionbio DataToRead = 0x4004667F, // fionread OobDataRead = 0x40047307, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AssociateHandle = 0x88000001, // SIO_ASSOCIATE_HANDLE - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] EnableCircularQueuing = 0x28000002, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] Flush = 0x28000004, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] GetBroadcastAddress = 0x48000005, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] GetExtensionFunctionPointer = 0xC8000006, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] GetQos = 0xC8000007, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] GetGroupQos = 0xC8000008, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] MultipointLoopback = 0x88000009, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] MulticastScope = 0x8800000A, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] SetQos = 0x8800000B, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] SetGroupQos = 0x8800000C, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] TranslateHandle = 0xC800000D, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] RoutingInterfaceQuery = 0xC8000014, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] RoutingInterfaceChange = 0x88000015, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AddressListQuery = 0x48000016, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AddressListChange = 0x28000017, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] QueryTargetPnpHandle = 0x48000018, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] NamespaceChange = 0x88000019, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AddressListSort = 0xC8000019, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] ReceiveAll = 0x98000001, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] ReceiveAllMulticast = 0x98000002, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] ReceiveAllIgmpMulticast = 0x98000003, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] KeepAliveValues = 0x98000004, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AbsorbRouterAlert = 0x98000005, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] UnicastInterface = 0x98000006, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] LimitBroadcasts = 0x98000007, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] BindToInterface = 0x98000008, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] MulticastInterface = 0x98000009, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] AddMulticastGroupOnInterface = 0x9800000A, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] DeleteMulticastGroupFromInterface = 0x9800000B } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs index e5905b7b70bf..fd9a6c80fcf4 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs @@ -10,7 +10,7 @@ namespace System.Net.Sockets { public partial class Socket { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public Socket(SocketInformation socketInformation) { // This constructor works in conjunction with DuplicateAndClose, which is not supported on Unix. @@ -18,7 +18,7 @@ public Socket(SocketInformation socketInformation) throw new PlatformNotSupportedException(SR.net_sockets_duplicateandclose_notsupported); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public SocketInformation DuplicateAndClose(int targetProcessId) { // DuplicateAndClose is not supported on Unix, since passing file descriptors between processes diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs index f4b87f2e4ff5..a8cb83dc651f 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs @@ -17,7 +17,7 @@ public partial class Socket internal void ReplaceHandleIfNecessaryAfterFailedConnect() { /* nop on Windows */ } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public Socket(SocketInformation socketInformation) { InitializeSockets(); @@ -106,7 +106,7 @@ private unsafe void LoadSocketTypeFromHandle( blocking = true; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public SocketInformation DuplicateAndClose(int targetProcessId) { ThrowIfDisposed(); diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index ac327f86f709..9fbc3c4c9a28 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -1989,7 +1989,7 @@ public int GetRawSocketOption(int optionLevel, int optionName, Span option return realOptionLength; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void SetIPProtectionLevel(IPProtectionLevel level) { if (level == IPProtectionLevel.Unspecified) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs index b32a6d105031..adb1c3f06dc1 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs @@ -112,7 +112,7 @@ public bool ExclusiveAddressUse } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void AllowNatTraversal(bool allowed) { if (_active) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs index 418e7a6ab070..32b69e7e53ca 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TransmitFileOptions.cs @@ -11,11 +11,11 @@ public enum TransmitFileOptions UseDefaultWorkerThread = 0x00, Disconnect = 0x01, ReuseSocket = 0x02, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] WriteBehind = 0x04, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] UseSystemThread = 0x10, - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] UseKernelApc = 0x20, }; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs index 4b19c4bf0063..e27a77da1f81 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs @@ -193,7 +193,7 @@ public bool ExclusiveAddressUse } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void AllowNatTraversal(bool allowed) { _clientSocket.SetIPProtectionLevel(allowed ? IPProtectionLevel.Unrestricted : IPProtectionLevel.EdgeRestricted); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs index c0d28b17cbf7..740d69aefde6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs @@ -22,7 +22,7 @@ public DispatchWrapper(object? obj) } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public object? WrappedObject { get; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs index 2a64a19a6a42..477717e9cb21 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs @@ -15,7 +15,7 @@ public static int GetHRForException(Exception? e) return e?.HResult ?? 0; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int AddRef(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -23,13 +23,13 @@ public static int AddRef(IntPtr pUnk) public static bool AreComObjectsAvailableForCleanup() => false; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object BindToMoniker(string monikerName) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -39,55 +39,55 @@ public static void CleanupUnusedObjectsInCurrentContext() { } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object? CreateWrapperOfType(object? o, Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static TWrapper CreateWrapperOfType([AllowNull] T o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void ChangeWrapperHandleStrength(object otp, bool fIsWeak) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int FinalReleaseComObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject(object o, Type T) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object? GetComObjectData(object obj, object key) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -103,92 +103,92 @@ public static IntPtr GetHINSTANCE(Module m) return (IntPtr)(-1); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetIDispatchForObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static IntPtr GetIUnknownForObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object GetTypedObjectForIUnknown(IntPtr pUnk, Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object GetObjectForIUnknown(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] [return: MaybeNull] public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object?[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int GetStartComSlot(Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int GetEndComSlot(Type t) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Type? GetTypeFromCLSID(Guid clsid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static string GetTypeInfoName(ITypeInfo typeInfo) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static object GetUniqueObjectForIUnknown(IntPtr unknown) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); @@ -213,25 +213,25 @@ public static bool IsTypeVisibleFromCom(Type t) return false; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int Release(IntPtr pUnk) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static int ReleaseComObject(object o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool SetComObjectData(object obj, object key, object? data) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs index 608838a786b4..f17eaddb5d13 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs @@ -28,7 +28,7 @@ public EventWaitHandle(bool initialState, EventResetMode mode, string? name, out CreateEventCore(initialState, mode, name, out createdNew); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static EventWaitHandle OpenExisting(string name) { switch (OpenExistingWorker(name, out EventWaitHandle? result)) @@ -45,7 +45,7 @@ public static EventWaitHandle OpenExisting(string name) } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool TryOpenExisting(string name, [NotNullWhen(true)] out EventWaitHandle? result) => OpenExistingWorker(name, out result!) == OpenExistingResult.Success; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs index 4836f7014865..fb386e9e8be9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs @@ -33,7 +33,7 @@ public Semaphore(int initialCount, int maximumCount, string? name, out bool crea CreateSemaphoreCore(initialCount, maximumCount, name, out createdNew); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static Semaphore OpenExisting(string name) { switch (OpenExistingWorker(name, out Semaphore? result)) @@ -50,7 +50,7 @@ public static Semaphore OpenExisting(string name) } } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public static bool TryOpenExisting(string name, [NotNullWhen(true)] out Semaphore? result) => OpenExistingWorker(name, out result!) == OpenExistingResult.Success; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index cb41f1b7dc41..ba36c3f14fa3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -227,7 +227,7 @@ public ApartmentState ApartmentState set => TrySetApartmentState(value); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public void SetApartmentState(ApartmentState state) { if (!TrySetApartmentState(state)) 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 5adee94bd662..67b487cb971b 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -317,7 +317,7 @@ public DefaultParameterValueAttribute(object? value) { } public sealed partial class DispatchWrapper { public DispatchWrapper(object? obj) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public object? WrappedObject { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Property, Inherited=false)] @@ -463,15 +463,15 @@ public static partial class Marshal { public static readonly int SystemDefaultCharSize; public static readonly int SystemMaxDBCSCharSize; - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int AddRef(System.IntPtr pUnk) { throw null; } public static System.IntPtr AllocCoTaskMem(int cb) { throw null; } public static System.IntPtr AllocHGlobal(int cb) { throw null; } public static System.IntPtr AllocHGlobal(System.IntPtr cb) { throw null; } public static bool AreComObjectsAvailableForCleanup() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object BindToMoniker(string monikerName) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void ChangeWrapperHandleStrength(object otp, bool fIsWeak) { } public static void CleanupUnusedObjectsInCurrentContext() { } public static void Copy(byte[] source, int startIndex, System.IntPtr destination, int length) { } @@ -490,41 +490,41 @@ public static void Copy(System.IntPtr source, System.IntPtr[] destination, int s public static void Copy(System.IntPtr source, float[] destination, int startIndex, int length) { } public static void Copy(System.IntPtr[] source, int startIndex, System.IntPtr destination, int length) { } public static void Copy(float[] source, int startIndex, System.IntPtr destination, int length) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, T o) where T : notnull { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("o")] public static object? CreateWrapperOfType(object? o, System.Type t) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static TWrapper CreateWrapperOfType([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T o) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void DestroyStructure(System.IntPtr ptr, System.Type structuretype) { } public static void DestroyStructure(System.IntPtr ptr) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int FinalReleaseComObject(object o) { throw null; } public static void FreeBSTR(System.IntPtr ptr) { } public static void FreeCoTaskMem(System.IntPtr ptr) { } public static void FreeHGlobal(System.IntPtr hglobal) { } public static System.Guid GenerateGuidForType(System.Type type) { throw null; } public static string? GenerateProgIdForType(System.Type type) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr GetComInterfaceForObject(object o, System.Type T) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr GetComInterfaceForObject(object o, System.Type T, System.Runtime.InteropServices.CustomQueryInterfaceMode mode) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IntPtr GetComInterfaceForObject([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T o) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object? GetComObjectData(object obj, object key) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.Delegate GetDelegateForFunctionPointer(System.IntPtr ptr, System.Type t) { throw null; } public static TDelegate GetDelegateForFunctionPointer(System.IntPtr ptr) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int GetEndComSlot(System.Type t) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("GetExceptionCode() may be unavailable in future releases.")] @@ -538,41 +538,41 @@ public static void FreeHGlobal(System.IntPtr hglobal) { } public static System.IntPtr GetHINSTANCE(System.Reflection.Module m) { throw null; } public static int GetHRForException(System.Exception? e) { throw null; } public static int GetHRForLastWin32Error() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IntPtr GetIDispatchForObject(object o) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.IntPtr GetIUnknownForObject(object o) { throw null; } public static int GetLastWin32Error() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void GetNativeVariantForObject(object? obj, System.IntPtr pDstNativeVariant) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void GetNativeVariantForObject([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T obj, System.IntPtr pDstNativeVariant) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object GetObjectForIUnknown(System.IntPtr pUnk) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object? GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static T GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object?[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static T[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int GetStartComSlot(System.Type t) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Type GetTypeFromCLSID(System.Guid clsid) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object GetUniqueObjectForIUnknown(System.IntPtr unknown) { throw null; } public static bool IsComObject(object o) { throw null; } public static bool IsTypeVisibleFromCom(System.Type t) { throw null; } @@ -597,7 +597,7 @@ public static void PtrToStructure(System.IntPtr ptr, object structure) { } [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static T PtrToStructure(System.IntPtr ptr) { throw null; } public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T structure) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { throw null; } public static byte ReadByte(System.IntPtr ptr) { throw null; } public static byte ReadByte(System.IntPtr ptr, int ofs) { throw null; } @@ -626,16 +626,16 @@ public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.Code public static System.IntPtr ReadIntPtr(object ptr, int ofs) { throw null; } public static System.IntPtr ReAllocCoTaskMem(System.IntPtr pv, int cb) { throw null; } public static System.IntPtr ReAllocHGlobal(System.IntPtr pv, System.IntPtr cb) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int Release(System.IntPtr pUnk) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int ReleaseComObject(object o) { throw null; } public static System.IntPtr SecureStringToBSTR(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToCoTaskMemAnsi(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToCoTaskMemUnicode(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToGlobalAllocAnsi(System.Security.SecureString s) { throw null; } public static System.IntPtr SecureStringToGlobalAllocUnicode(System.Security.SecureString s) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static bool SetComObjectData(object obj, object key, object? data) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static int SizeOf(object structure) { throw null; } diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs index ef1b0d7eb2b3..d7b4db182225 100644 --- a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs +++ b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs @@ -27,7 +27,7 @@ protected override void Dispose(bool disposing) { } public override void GenerateIV() { } public override void GenerateKey() { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public sealed partial class CspKeyContainerInfo { public CspKeyContainerInfo(System.Security.Cryptography.CspParameters parameters) { } @@ -87,11 +87,11 @@ public sealed partial class DSACryptoServiceProvider : System.Security.Cryptogra { public DSACryptoServiceProvider() { } public DSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public DSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public DSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } public override string? KeyExchangeAlgorithm { get { throw null; } } public override int KeySize { get { throw null; } } @@ -152,7 +152,7 @@ public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashNa public string HashName { get { throw null; } set { } } public int IterationCount { get { throw null; } set { } } public byte[]? Salt { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw null; } protected override void Dispose(bool disposing) { } [System.ObsoleteAttribute("Rfc2898DeriveBytes replaces PasswordDeriveBytes for deriving key material from a password and is preferred in new applications.")] @@ -164,7 +164,7 @@ public sealed partial class RC2CryptoServiceProvider : System.Security.Cryptogra { public RC2CryptoServiceProvider() { } public override int EffectiveKeySize { get { throw null; } set { } } - public bool UseSalt { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] set { } } + public bool UseSalt { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } public override void GenerateIV() { } @@ -188,11 +188,11 @@ public sealed partial class RSACryptoServiceProvider : System.Security.Cryptogra { public RSACryptoServiceProvider() { } public RSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public RSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public RSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } public override string? KeyExchangeAlgorithm { get { throw null; } } public override int KeySize { get { throw null; } } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs index 4ae3494de720..553634120b65 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs @@ -5,7 +5,7 @@ namespace System.Security.Cryptography { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public sealed class CspKeyContainerInfo { public CspKeyContainerInfo(CspParameters parameters) { throw GetPlatformNotSupported(); } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs index c707007cb931..ce73894fb36e 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs @@ -7,7 +7,7 @@ namespace System.Security.Cryptography { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public sealed class CspKeyContainerInfo { private readonly CspParameters _parameters; diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs index 0c324e1f5916..575055f33611 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs @@ -38,13 +38,13 @@ public DSACryptoServiceProvider(int dwKeySize) : base() KeySize = dwKeySize; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public DSACryptoServiceProvider(CspParameters parameters) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); @@ -56,7 +56,7 @@ public DSACryptoServiceProvider(CspParameters parameters) public override bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten) => _impl.TryCreateSignature(hash, destination, out bytesWritten); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public CspKeyContainerInfo CspKeyContainerInfo { get { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspKeyContainerInfo))); } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs index ef5d6f544a28..186f9c80100c 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs @@ -50,7 +50,7 @@ public DSACryptoServiceProvider(int dwKeySize) /// for the cryptographic service provider (CSP). /// /// The parameters for the CSP. - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public DSACryptoServiceProvider(CspParameters? parameters) : this(0, parameters) { @@ -63,7 +63,7 @@ public DSACryptoServiceProvider(CspParameters? parameters) /// The size of the key for the cryptographic algorithm in bits. /// The parameters for the CSP. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is required by the FIPS 186-2 DSA spec.")] - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public DSACryptoServiceProvider(int dwKeySize, CspParameters? parameters) { if (dwKeySize < 0) @@ -185,7 +185,7 @@ private SafeKeyHandle SafeKeyHandle /// /// Gets a CspKeyContainerInfo object that describes additional information about a cryptographic key pair. /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public CspKeyContainerInfo CspKeyContainerInfo { get diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs index 777b1d6e7ccb..62f31ccafb96 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs @@ -7,7 +7,7 @@ namespace System.Security.Cryptography { public partial class PasswordDeriveBytes : DeriveBytes { - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CryptDeriveKey))); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs index 41d8e23454cf..c51665301640 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs @@ -12,7 +12,7 @@ public partial class PasswordDeriveBytes : DeriveBytes { private SafeProvHandle? _safeProvHandle; - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { if (keySize < 0) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs index 559bd9647904..4aeb4ec3c607 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs @@ -104,7 +104,7 @@ public override PaddingMode Padding public bool UseSalt { get { return false; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { // Don't allow a true value diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs index 1118b136bfc1..d4760f31946e 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs @@ -44,7 +44,7 @@ public bool UseSalt { return _use40bitSalt; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] set { _use40bitSalt = value; diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs index d44478f7177f..168a456800e5 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs @@ -27,15 +27,15 @@ public RSACryptoServiceProvider(int dwKeySize) _impl = RSA.Create(dwKeySize); } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public RSACryptoServiceProvider(int dwKeySize, CspParameters parameters) => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public RSACryptoServiceProvider(CspParameters parameters) => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public CspKeyContainerInfo CspKeyContainerInfo => throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspKeyContainerInfo))); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs index f3a6586ee434..6843a3aa30fc 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs @@ -40,13 +40,13 @@ public RSACryptoServiceProvider(int dwKeySize) { } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public RSACryptoServiceProvider(int dwKeySize, CspParameters? parameters) : this(dwKeySize, parameters, false) { } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public RSACryptoServiceProvider(CspParameters? parameters) : this(0, parameters, true) { @@ -174,7 +174,7 @@ private SafeKeyHandle SafeKeyHandle /// /// CspKeyContainerInfo property /// - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public CspKeyContainerInfo CspKeyContainerInfo { get diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs index a0256d2581af..411c729bf0df 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs @@ -332,7 +332,7 @@ public partial class X509Chain : System.IDisposable { public X509Chain() { } public X509Chain(bool useMachineContext) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public X509Chain(System.IntPtr chainContext) { } public System.IntPtr ChainContext { get { throw null; } } public System.Security.Cryptography.X509Certificates.X509ChainElementCollection ChainElements { get { throw null; } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs index 348ed9249aaa..dbefadab5733 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs @@ -24,7 +24,7 @@ public X509Chain(bool useMachineContext) _useMachineContext = useMachineContext; } - [SupportedOSPlatform("windows7.0")] + [SupportedOSPlatform("windows")] public X509Chain(IntPtr chainContext) { _pal = ChainPal.FromHandle(chainContext); diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs index 294f9592e819..3fe3aea58faf 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs @@ -80,7 +80,7 @@ public static void MemoryBarrier() { } public static void ResetAbort() { } [System.ObsoleteAttribute("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. https://go.microsoft.com/fwlink/?linkid=14202", false)] public void Resume() { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void SetApartmentState(System.Threading.ApartmentState state) { } [System.ObsoleteAttribute("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")] public void SetCompressedStack(System.Threading.CompressedStack stack) { } diff --git a/src/libraries/System.Threading/ref/System.Threading.cs b/src/libraries/System.Threading/ref/System.Threading.cs index ac1c98dd4d57..d5fceaafaf60 100644 --- a/src/libraries/System.Threading/ref/System.Threading.cs +++ b/src/libraries/System.Threading/ref/System.Threading.cs @@ -115,11 +115,11 @@ public partial class EventWaitHandle : System.Threading.WaitHandle public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode) { } public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string? name) { } public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string? name, out bool createdNew) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Threading.EventWaitHandle OpenExisting(string name) { throw null; } public bool Reset() { throw null; } public bool Set() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static bool TryOpenExisting(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Threading.EventWaitHandle? result) { throw null; } } public sealed partial class ExecutionContext : System.IDisposable, System.Runtime.Serialization.ISerializable @@ -350,11 +350,11 @@ public sealed partial class Semaphore : System.Threading.WaitHandle public Semaphore(int initialCount, int maximumCount) { } public Semaphore(int initialCount, int maximumCount, string? name) { } public Semaphore(int initialCount, int maximumCount, string? name, out bool createdNew) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Threading.Semaphore OpenExisting(string name) { throw null; } public int Release() { throw null; } public int Release(int releaseCount) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static bool TryOpenExisting(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Threading.Semaphore? result) { throw null; } } public partial class SemaphoreFullException : System.SystemException From 6e922b89ec0d5dab38f999482b1496043938e24a Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 5 Aug 2020 18:25:25 +0200 Subject: [PATCH 264/755] Mark System.Security.Cryptography.OpenSsl as unsupported on Windows, fixes #40101 (#40377) --- eng/versioning.targets | 7 +++++++ .../Directory.Build.props | 2 ++ 2 files changed, 9 insertions(+) diff --git a/eng/versioning.targets b/eng/versioning.targets index f0cbf0e22899..2a2f10dbcafb 100644 --- a/eng/versioning.targets +++ b/eng/versioning.targets @@ -29,6 +29,13 @@ + + + + <_Parameter1>$(UnsupportedOSPlatform) + + + diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props index 63f02a0f817e..34e587248074 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props @@ -2,5 +2,7 @@ Microsoft + true + windows \ No newline at end of file From 5870d4f64f7803817252dd105ff654cb2cd96f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B8is=C3=A6ther=20Rasch?= Date: Wed, 5 Aug 2020 18:50:22 +0200 Subject: [PATCH 265/755] Add BindConfiguration extension method for OptionsBuilder (#39825) --- ...nsions.Options.ConfigurationExtensions.sln | 37 ++++++ ...ensions.Options.ConfigurationExtensions.cs | 1 + .../OptionsBuilderConfigurationExtensions.cs | 32 ++++++ .../tests/FakeOptions.cs | 7 ++ ...tions.ConfigurationExtensions.Tests.csproj | 19 ++++ ...ionsBuidlerConfigurationExtensionsTests.cs | 106 ++++++++++++++++++ 6 files changed, 202 insertions(+) create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/FakeOptions.cs create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Microsoft.Extensions.Options.ConfigurationExtensions.Tests.csproj create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/OptionsBuidlerConfigurationExtensionsTests.cs diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/Microsoft.Extensions.Options.ConfigurationExtensions.sln b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/Microsoft.Extensions.Options.ConfigurationExtensions.sln index 7628543f319a..4782d11b90ad 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/Microsoft.Extensions.Options.ConfigurationExtensions.sln +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/Microsoft.Extensions.Options.ConfigurationExtensions.sln @@ -11,6 +11,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Option EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.ConfigurationExtensions", "src\Microsoft.Extensions.Options.ConfigurationExtensions.csproj", "{D4C213E7-336F-4601-9F92-1D632D082422}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{4CB60D51-6D36-49DB-A3AC-B45664F39EFC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.ConfigurationExtensions.Tests", "tests\Microsoft.Extensions.Options.ConfigurationExtensions.Tests.csproj", "{5F41C8C2-663D-4D57-9211-2F495D7DFACE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{3EFE3DA9-F864-40A3-8892-899D731CC027}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.DependencyInjection", "..\Microsoft.Extensions.DependencyInjection\src\Microsoft.Extensions.DependencyInjection.csproj", "{D8AC9F6D-95FA-4377-A867-FF75683393AA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration", "..\Microsoft.Extensions.Configuration\src\Microsoft.Extensions.Configuration.csproj", "{1F88377A-7C91-466E-9351-1B0AE0DF78AB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj", "{D53344C9-58C5-4A2B-8182-74A48763A8FE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,6 +37,26 @@ Global {D4C213E7-336F-4601-9F92-1D632D082422}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4C213E7-336F-4601-9F92-1D632D082422}.Release|Any CPU.ActiveCfg = Release|Any CPU {D4C213E7-336F-4601-9F92-1D632D082422}.Release|Any CPU.Build.0 = Release|Any CPU + {5F41C8C2-663D-4D57-9211-2F495D7DFACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5F41C8C2-663D-4D57-9211-2F495D7DFACE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F41C8C2-663D-4D57-9211-2F495D7DFACE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5F41C8C2-663D-4D57-9211-2F495D7DFACE}.Release|Any CPU.Build.0 = Release|Any CPU + {3EFE3DA9-F864-40A3-8892-899D731CC027}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3EFE3DA9-F864-40A3-8892-899D731CC027}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3EFE3DA9-F864-40A3-8892-899D731CC027}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3EFE3DA9-F864-40A3-8892-899D731CC027}.Release|Any CPU.Build.0 = Release|Any CPU + {D8AC9F6D-95FA-4377-A867-FF75683393AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8AC9F6D-95FA-4377-A867-FF75683393AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8AC9F6D-95FA-4377-A867-FF75683393AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8AC9F6D-95FA-4377-A867-FF75683393AA}.Release|Any CPU.Build.0 = Release|Any CPU + {1F88377A-7C91-466E-9351-1B0AE0DF78AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F88377A-7C91-466E-9351-1B0AE0DF78AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F88377A-7C91-466E-9351-1B0AE0DF78AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F88377A-7C91-466E-9351-1B0AE0DF78AB}.Release|Any CPU.Build.0 = Release|Any CPU + {D53344C9-58C5-4A2B-8182-74A48763A8FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D53344C9-58C5-4A2B-8182-74A48763A8FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D53344C9-58C5-4A2B-8182-74A48763A8FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D53344C9-58C5-4A2B-8182-74A48763A8FE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -32,6 +64,11 @@ Global GlobalSection(NestedProjects) = preSolution {F0815ADD-0115-4368-886E-2135355BC439} = {9EDF28B3-F998-47FE-B23A-753205641B49} {D4C213E7-336F-4601-9F92-1D632D082422} = {BF3EE9AA-4B66-4410-B1D2-3971169F1E40} + {5F41C8C2-663D-4D57-9211-2F495D7DFACE} = {4CB60D51-6D36-49DB-A3AC-B45664F39EFC} + {3EFE3DA9-F864-40A3-8892-899D731CC027} = {4CB60D51-6D36-49DB-A3AC-B45664F39EFC} + {D8AC9F6D-95FA-4377-A867-FF75683393AA} = {4CB60D51-6D36-49DB-A3AC-B45664F39EFC} + {1F88377A-7C91-466E-9351-1B0AE0DF78AB} = {4CB60D51-6D36-49DB-A3AC-B45664F39EFC} + {D53344C9-58C5-4A2B-8182-74A48763A8FE} = {4CB60D51-6D36-49DB-A3AC-B45664F39EFC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0414F2BB-333F-487E-92AE-530AA983499B} diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs index 938fb6c1bb85..43e04c4327d5 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs @@ -8,6 +8,7 @@ namespace Microsoft.Extensions.DependencyInjection { public static partial class OptionsBuilderConfigurationExtensions { + public static Microsoft.Extensions.Options.OptionsBuilder BindConfiguration(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, string configSectionPath, System.Action configureBinder = null) where TOptions : class { throw null; } public static Microsoft.Extensions.Options.OptionsBuilder Bind(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } public static Microsoft.Extensions.Options.OptionsBuilder Bind(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config, System.Action configureBinder) where TOptions : class { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs index e1f642676c49..a102c2b49da4 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs @@ -40,5 +40,37 @@ public static OptionsBuilder Bind(this OptionsBuilder(optionsBuilder.Name, config, configureBinder); return optionsBuilder; } + + /// + /// Registers the dependency injection container to bind against + /// the obtained from the DI service provider. + /// + /// The options type to be configured. + /// The options builder to add the services to. + /// The name of the configuration section to bind from. + /// Optional. Used to configure the . + /// The so that additional calls can be chained. + /// + /// or is . + /// + /// + public static OptionsBuilder BindConfiguration( + this OptionsBuilder optionsBuilder, + string configSectionPath, + Action configureBinder = null) + where TOptions : class + { + _ = optionsBuilder ?? throw new ArgumentNullException(nameof(optionsBuilder)); + _ = configSectionPath ?? throw new ArgumentNullException(nameof(configSectionPath)); + + optionsBuilder.Configure((opts, config) => + { + IConfiguration section = string.Equals("", configSectionPath, StringComparison.OrdinalIgnoreCase) + ? config + : config.GetSection(configSectionPath); + section.Bind(opts, configureBinder); + }); + return optionsBuilder; + } } } diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/FakeOptions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/FakeOptions.cs new file mode 100644 index 000000000000..5a1b3d614427 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/FakeOptions.cs @@ -0,0 +1,7 @@ +namespace Microsoft.Extensions.Options.ConfigurationExtensions.Tests +{ + public class FakeOptions + { + public string? Message { get; set; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Microsoft.Extensions.Options.ConfigurationExtensions.Tests.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Microsoft.Extensions.Options.ConfigurationExtensions.Tests.csproj new file mode 100644 index 000000000000..91a11d65d3b1 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Microsoft.Extensions.Options.ConfigurationExtensions.Tests.csproj @@ -0,0 +1,19 @@ + + + + enable + $(NetCoreAppCurrent);net461 + true + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/OptionsBuidlerConfigurationExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/OptionsBuidlerConfigurationExtensionsTests.cs new file mode 100644 index 000000000000..2aa44c5fcd23 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/OptionsBuidlerConfigurationExtensionsTests.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.Extensions.Options.ConfigurationExtensions.Tests +{ + public class OptionsBuidlerConfigurationExtensionsTests + { + [Fact] + public static void BindConfiguration_ThrowsForNullBuilder() + { + OptionsBuilder optionsBuilder = null!; + + Assert.Throws("optionsBuilder", () => + { + optionsBuilder.BindConfiguration("test"); + }); + } + + [Fact] + public static void BindConfiguration_ThrowsForNullConfigurationSectionPath() + { + var services = new ServiceCollection(); + var optionsBuilder = new OptionsBuilder(services, Options.DefaultName); + string configSectionPath = null!; + + Assert.Throws("configSectionPath", () => + { + optionsBuilder.BindConfiguration(configSectionPath); + }); + } + + [Fact] + public static void BindConfiguration_ReturnsSameBuilderInstance() + { + var services = new ServiceCollection(); + var optionsBuilder = new OptionsBuilder(services, Options.DefaultName); + + var returnedBuilder = optionsBuilder.BindConfiguration("Test"); + + Assert.Same(optionsBuilder, returnedBuilder); + } + + [Fact] + public static void BindConfiguration_OptionsMaterializationThrowsIfNoConfigurationInDI() + { + var services = new ServiceCollection(); + var optionsBuilder = services.AddOptions(); + + _ = optionsBuilder.BindConfiguration("Test"); + using ServiceProvider serviceProvider = services.BuildServiceProvider(); + + Assert.ThrowsAny(() => + { + _ = serviceProvider.GetRequiredService>(); + }); + } + + [Fact] + public static void BindConfiguration_UsesConfigurationSectionPath() + { + const string configSectionName = "Test"; + const string messageValue = "This is a test"; + var configEntries = new Dictionary + { + [ConfigurationPath.Combine(configSectionName, nameof(FakeOptions.Message))] = messageValue + }; + var services = new ServiceCollection(); + services.AddSingleton(new ConfigurationBuilder() + .AddInMemoryCollection(configEntries) + .Build()); + var optionsBuilder = services.AddOptions(); + + _ = optionsBuilder.BindConfiguration(configSectionName); + + using ServiceProvider serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>().Value; + + Assert.Equal(messageValue, options.Message); + } + + [Fact] + public static void BindConfiguration_UsesConfigurationRootIfSectionNameIsEmptyString() + { + const string messageValue = "This is a test"; + var configEntries = new Dictionary + { + [nameof(FakeOptions.Message)] = messageValue + }; + var services = new ServiceCollection(); + services.AddSingleton(new ConfigurationBuilder() + .AddInMemoryCollection(configEntries) + .Build()); + var optionsBuilder = services.AddOptions(); + + _ = optionsBuilder.BindConfiguration(configSectionPath: ""); + + using ServiceProvider serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>().Value; + + Assert.Equal(messageValue, options.Message); + } + } +} From 8fc332fc1f5f928336e68fb6cde06184d72feeba Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Wed, 5 Aug 2020 10:48:27 -0700 Subject: [PATCH 266/755] remove dead code (#40363) Co-authored-by: Geoffrey Kizer --- .../src/System/Net/BufferAsyncResult.cs | 64 --------- .../src/System/Net/HelperAsyncResults.cs | 121 ------------------ 2 files changed, 185 deletions(-) delete mode 100644 src/libraries/System.Net.Security/src/System/Net/BufferAsyncResult.cs delete mode 100644 src/libraries/System.Net.Security/src/System/Net/HelperAsyncResults.cs diff --git a/src/libraries/System.Net.Security/src/System/Net/BufferAsyncResult.cs b/src/libraries/System.Net.Security/src/System/Net/BufferAsyncResult.cs deleted file mode 100644 index 456ca9a9b47e..000000000000 --- a/src/libraries/System.Net.Security/src/System/Net/BufferAsyncResult.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; - -namespace System.Net -{ - // - // Preserve the original request buffer & sizes for user IO requests. - // This is returned as an IAsyncResult to the application. - // - internal sealed class BufferAsyncResult : LazyAsyncResult - { - /// Stored into LazyAsyncResult.Result to indicate a completed result. - public static readonly object ResultSentinal = nameof(BufferAsyncResult) + "." + nameof(ResultSentinal); - /// Stores the input count or the output result of the operation. - private int _countOrResult; -#if DEBUG - /// true if backs , false if . - private bool _countOrResultIsResult; -#endif - - public BufferAsyncResult(object asyncObject, byte[] buffer, int offset, int count, object? asyncState, AsyncCallback? asyncCallback) - : base(asyncObject, asyncState, asyncCallback) - { - Buffer = buffer; - Offset = offset; - _countOrResult = count; - } - - public byte[] Buffer { get; } - public int Offset { get; } - public int Count - { - get - { -#if DEBUG - Debug.Assert(!_countOrResultIsResult, "Trying to get count after it's already the result"); -#endif - return _countOrResult; - } - } - - public int Int32Result // Int32Result to differentiate from the base's "object Result" - { - get - { -#if DEBUG - Debug.Assert(_countOrResultIsResult, "Still represents the count, not the result"); - Debug.Assert(ReferenceEquals(Result, ResultSentinal), "Expected the base object Result to be the sentinel"); -#endif - return _countOrResult; - } - set - { -#if DEBUG - Debug.Assert(!_countOrResultIsResult, "Should only be set when result hasn't yet been set"); - _countOrResultIsResult = true; -#endif - _countOrResult = value; - } - } - } -} diff --git a/src/libraries/System.Net.Security/src/System/Net/HelperAsyncResults.cs b/src/libraries/System.Net.Security/src/System/Net/HelperAsyncResults.cs deleted file mode 100644 index 0280f57c0ea9..000000000000 --- a/src/libraries/System.Net.Security/src/System/Net/HelperAsyncResults.cs +++ /dev/null @@ -1,121 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Threading; - -namespace System.Net -{ - // The callback type used with below AsyncProtocolRequest class - internal delegate void AsyncProtocolCallback(AsyncProtocolRequest asyncRequest); - - // - // The class mimics LazyAsyncResult although it does not need to be thread safe nor it does need an Event. - // We use this to implement iterative protocol logic: - // 1) It can be reused for handshake-like or multi-IO request protocols. - // 2) It won't block async IO since there is NO event handler exposed. - // - // UserAsyncResult property is a link into original user IO request (could be a BufferAsyncResult). - // - internal class AsyncProtocolRequest - { - private AsyncProtocolCallback? _callback; - private int _completionStatus; - - private const int StatusNotStarted = 0; - private const int StatusCompleted = 1; - private const int StatusCheckedOnSyncCompletion = 2; - - public LazyAsyncResult UserAsyncResult; - public int Result; - public readonly CancellationToken CancellationToken; - - public byte[]? Buffer; // Temporary buffer reused by a protocol. - public int Offset; - public int Count; - - public AsyncProtocolRequest(LazyAsyncResult userAsyncResult, CancellationToken cancellationToken = default) - { - if (userAsyncResult == null) - { - NetEventSource.Fail(this, "userAsyncResult == null"); - } - if (userAsyncResult!.InternalPeekCompleted) - { - NetEventSource.Fail(this, "userAsyncResult is already completed."); - } - UserAsyncResult = userAsyncResult; - CancellationToken = cancellationToken; - } - - public void SetNextRequest(byte[]? buffer, int offset, int count, AsyncProtocolCallback? callback) - { - if (_completionStatus != StatusNotStarted) - { - throw new InternalException(_completionStatus); // Pending operation is in progress. - } - - Buffer = buffer; - Offset = offset; - Count = count; - _callback = callback; - } - - internal object? AsyncObject => UserAsyncResult.AsyncObject; - - // - // Notify protocol so a next stage could be started. - // - internal void CompleteRequest(int result) - { - Result = result; - int status = Interlocked.Exchange(ref _completionStatus, StatusCompleted); - if (status == StatusCompleted) - { - throw new InternalException(); // Only allow one call. - } - - if (status == StatusCheckedOnSyncCompletion) - { - _completionStatus = StatusNotStarted; - _callback!(this); - } - } - - public bool MustCompleteSynchronously - { - get - { - int status = Interlocked.Exchange(ref _completionStatus, StatusCheckedOnSyncCompletion); - if (status == StatusCheckedOnSyncCompletion) - { - throw new InternalException(); // Only allow one call. - } - - if (status == StatusCompleted) - { - _completionStatus = StatusNotStarted; - return true; - } - return false; - } - } - - // - // Important: This will abandon _Callback and directly notify UserAsyncResult. - // - internal void CompleteUserWithError(Exception e) => UserAsyncResult.InvokeCallback(e); - - internal void CompleteUser() => UserAsyncResult.InvokeCallback(); - - internal void CompleteUser(int userResult) - { - Debug.Assert(UserAsyncResult is BufferAsyncResult, "CompleteUser(int) may only be used with a BufferAsyncResult"); - var bar = (BufferAsyncResult)UserAsyncResult; - bar.Int32Result = userResult; - bar.InvokeCallback(BufferAsyncResult.ResultSentinal); - } - - internal bool IsUserCompleted => UserAsyncResult.InternalPeekCompleted; - } -} From 1b338ff131e7df6bca749a4208da857e2a595d31 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Wed, 5 Aug 2020 11:33:30 -0700 Subject: [PATCH 267/755] Transform dead late arg store to NOP (#40348) When deleting a dead store, preserve the GTF_LATE_ARG and transform it to NOP. Fix #39742 --- src/coreclr/src/jit/compiler.h | 1 + src/coreclr/src/jit/liveness.cpp | 60 ++++++++++++++++++++------------ src/coreclr/src/jit/lower.cpp | 4 ++- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 23c3b687984c..9924c5ffe1db 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -4637,6 +4637,7 @@ class Compiler bool fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange); + void fgRemoveDeadStoreLIR(GenTree* store, BasicBlock* block); bool fgRemoveDeadStore(GenTree** pTree, LclVarDsc* varDsc, VARSET_VALARG_TP life, diff --git a/src/coreclr/src/jit/liveness.cpp b/src/coreclr/src/jit/liveness.cpp index 5c3c86010fda..cbc4ebbd05af 100644 --- a/src/coreclr/src/jit/liveness.cpp +++ b/src/coreclr/src/jit/liveness.cpp @@ -1986,10 +1986,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR Lowering::TransformUnusedIndirection(data->AsIndir(), this, block); } - blockRange.Remove(store); - - assert(!opts.MinOpts()); - fgStmtRemoved = true; + fgRemoveDeadStoreLIR(store, block); } } } @@ -2018,25 +2015,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR // Remove the store. DCE will iteratively clean up any ununsed operands. lclVarNode->gtOp1->SetUnusedValue(); - // If the store is marked as a late argument, it is referenced by a call. Instead of removing - // it, bash it to a NOP. - if ((node->gtFlags & GTF_LATE_ARG) != 0) - { - JITDUMP("node is a late arg; replacing with NOP\n"); - node->gtBashToNOP(); - - // NOTE: this is a bit of a hack. We need to keep these nodes around as they are - // referenced by the call, but they're considered side-effect-free non-value-producing - // nodes, so they will be removed if we don't do this. - node->gtFlags |= GTF_ORDER_SIDEEFF; - } - else - { - blockRange.Remove(node); - } - - assert(!opts.MinOpts()); - fgStmtRemoved = true; + fgRemoveDeadStoreLIR(node, block); } break; @@ -2179,6 +2158,41 @@ bool Compiler::fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange) return false; } +//--------------------------------------------------------------------- +// fgRemoveDeadStoreSimple - remove a dead store +// +// pTree - GenTree** to local, including store-form local or local addr (post-rationalize) +// varDsc - var that is being stored to +// life - current live tracked vars (maintained as we walk backwards) +// doAgain - out parameter, true if we should restart the statement +// pStmtInfoDirty - should defer the cost computation to the point after the reverse walk is completed? +// +void Compiler::fgRemoveDeadStoreLIR(GenTree* store, BasicBlock* block) +{ + LIR::Range& blockRange = LIR::AsRange(block); + + // If the store is marked as a late argument, it is referenced by a call. + // Instead of removing it, bash it to a NOP. + if ((store->gtFlags & GTF_LATE_ARG) != 0) + { + JITDUMP("node is a late arg; replacing with NOP\n"); + store->gtBashToNOP(); + + // NOTE: this is a bit of a hack. We need to keep these nodes around as they are + // referenced by the call, but they're considered side-effect-free non-value-producing + // nodes, so they will be removed if we don't do this. + store->gtFlags |= GTF_ORDER_SIDEEFF; + } + else + { + blockRange.Remove(store); + } + + assert(!opts.MinOpts()); + fgStmtRemoved = true; +} + +//--------------------------------------------------------------------- // fgRemoveDeadStore - remove a store to a local which has no exposed uses. // // pTree - GenTree** to local, including store-form local or local addr (post-rationalize) diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 61e15a339b4a..a401a843dd0a 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -3181,7 +3181,9 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) // Create the assignment node. lclStore->ChangeOper(GT_STORE_OBJ); GenTreeBlk* objStore = lclStore->AsObj(); - objStore->gtFlags = GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; + // Only the GTF_LATE_ARG flag (if present) is preserved. + objStore->gtFlags &= GTF_LATE_ARG; + objStore->gtFlags |= GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; #ifndef JIT32_GCENCODER objStore->gtBlkOpGcUnsafe = false; #endif From 890fe9778d6f063b080a35560de6e4499f4b8620 Mon Sep 17 00:00:00 2001 From: Werner Mairl Date: Wed, 5 Aug 2020 20:48:57 +0200 Subject: [PATCH 268/755] Issue 39764 fix: Host and Application Lifetime Notifications (#39832) --- .../src/Internal/Host.cs | 5 +- .../tests/UnitTests/Internal/HostTests.cs | 74 +++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs index 026727948c0c..1fcb8fd08fab 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs @@ -88,11 +88,12 @@ public async Task StopAsync(CancellationToken cancellationToken = default) } } + // Fire IHostApplicationLifetime.Stopped + _applicationLifetime.NotifyStopped(); + token.ThrowIfCancellationRequested(); await _hostLifetime.StopAsync(token).ConfigureAwait(false); - // Fire IHostApplicationLifetime.Stopped - _applicationLifetime.NotifyStopped(); if (exceptions.Count > 0) { diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs index 092ac4fe8b2c..d160f022c9ae 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs @@ -839,6 +839,78 @@ public async Task HostedServiceCanInjectApplicationLifetime() } } + [Fact] + public async Task HostShutdownFiresApplicationLifetimeStoppedBeforeHostLifetimeStopped() + { + var stoppingCalls = 0; + var startedCalls = 0; + var disposingCalls = 0; + + FakeHostLifetime fakeHostLifetime = null; + ApplicationLifetime applicationLifetime = null; + + using (var host = CreateBuilder() + .ConfigureServices((services) => + { + Action started = () => + { + startedCalls++; + }; + + Action stopping = () => + { + stoppingCalls++; + }; + + Action disposing = () => + { + disposingCalls++; + }; + + services.AddSingleton(_ => new DelegateHostedService(started, stopping, disposing)); + + services.AddSingleton(_ => + { + fakeHostLifetime = new FakeHostLifetime(); + + fakeHostLifetime.StopAction = () => + { + Assert.Equal(1, startedCalls); + Assert.Equal(1, stoppingCalls); + Assert.True(applicationLifetime.ApplicationStopped.IsCancellationRequested); + }; + return fakeHostLifetime; + } + ); + + }) + .Build()) + { + var lifetime = host.Services.GetRequiredService(); + var hostLifetime = host.Services.GetRequiredService(); + applicationLifetime = lifetime as ApplicationLifetime; + Assert.NotNull(applicationLifetime); + + Assert.Equal(0, startedCalls); + + await host.StartAsync(); + Assert.Equal(1, startedCalls); + Assert.Equal(0, stoppingCalls); + Assert.Equal(0, disposingCalls); + + Assert.True(lifetime.ApplicationStarted.IsCancellationRequested); + Assert.False(lifetime.ApplicationStopping.IsCancellationRequested); + Assert.False(lifetime.ApplicationStopped.IsCancellationRequested); + + await host.StopAsync(); + + Assert.True(lifetime.ApplicationStopping.IsCancellationRequested); + Assert.True(lifetime.ApplicationStopped.IsCancellationRequested); + Assert.Equal(1, startedCalls); + Assert.Equal(1, stoppingCalls); + } + } + [Fact] public async Task HostStopApplicationFiresStopOnHostedService() { @@ -1215,6 +1287,8 @@ public void Dispose() } } + + private class DelegateHostedService : IHostedService, IDisposable { private readonly Action _started; From 8250b0a24f24826a564c6caf55eaa550dd26db5b Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 5 Aug 2020 22:02:13 +0300 Subject: [PATCH 269/755] Add savepoint API to DbTransaction (#34561) Closes #33397 --- .../ref/System.Data.Common.cs | 7 ++ .../src/System/Data/Common/DbTransaction.cs | 116 ++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index a2f519c8c897..51be327e1446 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -2441,6 +2441,13 @@ protected virtual void Dispose(bool disposing) { } public virtual System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public abstract void Rollback(); public virtual System.Threading.Tasks.Task RollbackAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual bool SupportsSavepoints { get { throw null; } } + public virtual System.Threading.Tasks.Task SaveAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; } + public virtual System.Threading.Tasks.Task RollbackAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; } + public virtual System.Threading.Tasks.Task ReleaseAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; } + public virtual void Save(string savepointName) { throw null; } + public virtual void Rollback(string savepointName) { throw null; } + public virtual void Release(string savepointName) { throw null; } } public enum GroupByBehavior { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbTransaction.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbTransaction.cs index fe357a63413c..8728590fedeb 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbTransaction.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbTransaction.cs @@ -67,5 +67,121 @@ public virtual Task RollbackAsync(CancellationToken cancellationToken = default) return Task.FromException(e); } } + + #region Savepoints + + /// + /// Gets a value that indicates whether this instance supports database savepoints. + /// If , the methods , + /// and as + /// well as their synchronous counterparts are expected to throw . + /// + /// + /// if this instance supports database savepoints; otherwise, + /// . + /// + public virtual bool SupportsSavepoints => false; + + /// + /// Creates a savepoint in the transaction. This allows all commands that are executed after the savepoint was + /// established to be rolled back, restoring the transaction state to what it was at the time of the savepoint. + /// + /// The name of the savepoint to be created. + /// + /// An optional token to cancel the asynchronous operation. The default value is . + /// + /// A representing the asynchronous operation. + public virtual Task SaveAsync(string savepointName, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + try + { + Save(savepointName); + return Task.CompletedTask; + } + catch (Exception e) + { + return Task.FromException(e); + } + } + + /// + /// Rolls back all commands that were executed after the specified savepoint was established. + /// + /// The name of the savepoint to roll back to. + /// + /// An optional token to cancel the asynchronous operation. The default value is . + /// + /// A representing the asynchronous operation. + public virtual Task RollbackAsync(string savepointName, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + try + { + Rollback(savepointName); + return Task.CompletedTask; + } + catch (Exception e) + { + return Task.FromException(e); + } + } + + /// + /// Destroys a savepoint previously defined in the current transaction. This allows the system to + /// reclaim some resources before the transaction ends. + /// + /// The name of the savepoint to release. + /// + /// An optional token to cancel the asynchronous operation. The default value is . + /// + /// A representing the asynchronous operation. + public virtual Task ReleaseAsync(string savepointName, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + try + { + Release(savepointName); + return Task.CompletedTask; + } + catch (Exception e) + { + return Task.FromException(e); + } + } + + /// + /// Creates a savepoint in the transaction. This allows all commands that are executed after the savepoint was + /// established to be rolled back, restoring the transaction state to what it was at the time of the savepoint. + /// + /// The name of the savepoint to be created. + public virtual void Save(string savepointName) => throw new NotSupportedException(); + + /// + /// Rolls back all commands that were executed after the specified savepoint was established. + /// + /// The name of the savepoint to roll back to. + public virtual void Rollback(string savepointName) => throw new NotSupportedException(); + + /// + /// Destroys a savepoint previously defined in the current transaction. This allows the system to + /// reclaim some resources before the transaction ends. + /// + /// The name of the savepoint to release. + public virtual void Release(string savepointName) {} + + #endregion } } From 04e86c3b8a8925b5ecb8c16a78281b4f412b533e Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 5 Aug 2020 20:10:13 +0100 Subject: [PATCH 270/755] In mono_wasm_invoke_js_marshalled, pass through treatResultAsVoid parameter (#39435) --- src/mono/wasm/runtime/dotnet_support.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/dotnet_support.js b/src/mono/wasm/runtime/dotnet_support.js index 7411959b66b4..c1ddc08b902e 100644 --- a/src/mono/wasm/runtime/dotnet_support.js +++ b/src/mono/wasm/runtime/dotnet_support.js @@ -29,7 +29,7 @@ var DotNetSupportLib = { return MONO.string_decoder.copy (mono_obj); } }, - mono_wasm_invoke_js_marshalled: function(exceptionMessage, asyncHandleLongPtr, functionName, argsJson) { + mono_wasm_invoke_js_marshalled: function(exceptionMessage, asyncHandleLongPtr, functionName, argsJson, treatResultAsVoid) { var mono_string = DOTNET._dotnet_get_global()._mono_string_cached || (DOTNET._dotnet_get_global()._mono_string_cached = Module.cwrap('mono_wasm_string_from_js', 'number', ['string'])); @@ -54,10 +54,10 @@ var DotNetSupportLib = { } if (asyncHandleJsNumber) { - dotNetExports.jsCallDispatcher.beginInvokeJSFromDotNet(asyncHandleJsNumber, funcNameJsString, argsJsonJsString); + dotNetExports.jsCallDispatcher.beginInvokeJSFromDotNet(asyncHandleJsNumber, funcNameJsString, argsJsonJsString, treatResultAsVoid); return 0; } else { - var resultJson = dotNetExports.jsCallDispatcher.invokeJSFromDotNet(funcNameJsString, argsJsonJsString); + var resultJson = dotNetExports.jsCallDispatcher.invokeJSFromDotNet(funcNameJsString, argsJsonJsString, treatResultAsVoid); return resultJson === null ? 0 : mono_string(resultJson); } } catch (ex) { From 69b91f94cef1ae22f435fd132672b60ab5c8bd74 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 5 Aug 2020 12:54:45 -0700 Subject: [PATCH 271/755] Add support for reporting byrefs to RVA static fields of collectible assemblies (#40346) - Keep track of all RVA static field locations - For assemblies loaded from PE files, use a range that is the entire PE range - For assemblies dynamically created, use piecemeal ranges for each individual RVA static field - Report byref references via the GcReportLoaderAllocator mechanism in PromoteCarefully - Add a test to cover this scenario, and thread statics - disable test on Mono, as it doesn't pass there yet --- src/coreclr/src/vm/assembly.cpp | 13 ++ src/coreclr/src/vm/commodule.cpp | 6 + src/coreclr/src/vm/loaderallocator.cpp | 43 ++++++ src/coreclr/src/vm/loaderallocator.hpp | 13 +- src/coreclr/src/vm/lockedrangelist.h | 61 ++++++++ src/coreclr/src/vm/siginfo.cpp | 10 ++ src/coreclr/src/vm/stubmgr.h | 48 +----- src/coreclr/tests/issues.targets | 3 + .../ByRefLocals/ByRefLocals.cs | 142 ++++++++++++++++++ .../ByRefLocals/ByRefLocals.csproj | 13 ++ .../ByRefLocals/SpanAccessor.cs | 9 ++ .../ByRefLocals/SpanAccessor.csproj | 11 ++ .../ByRefLocals/Unloaded.cs | 26 ++++ .../ByRefLocals/Unloaded.csproj | 12 ++ 14 files changed, 362 insertions(+), 48 deletions(-) create mode 100644 src/coreclr/src/vm/lockedrangelist.h create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.csproj create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.csproj create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.csproj diff --git a/src/coreclr/src/vm/assembly.cpp b/src/coreclr/src/vm/assembly.cpp index 8bfb3d283a7c..4934ae689708 100644 --- a/src/coreclr/src/vm/assembly.cpp +++ b/src/coreclr/src/vm/assembly.cpp @@ -190,6 +190,19 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat // loading it entirely. //CacheFriendAssemblyInfo(); +#ifndef CROSSGEN_COMPILE + if (IsCollectible()) + { + COUNT_T size; + BYTE *start = (BYTE*)m_pManifest->GetFile()->GetLoadedImageContents(&size); + if (start != NULL) + { + GCX_COOP(); + LoaderAllocator::AssociateMemoryWithLoaderAllocator(start, start + size, m_pLoaderAllocator); + } + } +#endif + { CANNOTTHROWCOMPLUSEXCEPTION(); FAULT_FORBID(); diff --git a/src/coreclr/src/vm/commodule.cpp b/src/coreclr/src/vm/commodule.cpp index a1f2e27d2496..7ca511e7db6f 100644 --- a/src/coreclr/src/vm/commodule.cpp +++ b/src/coreclr/src/vm/commodule.cpp @@ -643,6 +643,12 @@ void QCALLTYPE COMModule::SetFieldRVAContent(QCall::ModuleHandle pModule, INT32 if (pContent != NULL) memcpy(pvBlob, pContent, length); + if (pReflectionModule->IsCollectible()) + { + GCX_COOP(); + LoaderAllocator::AssociateMemoryWithLoaderAllocator((BYTE*)pvBlob, ((BYTE*)pvBlob) + length, pReflectionModule->GetLoaderAllocator()); + } + // set FieldRVA into metadata. Note that this is not final RVA in the image if save to disk. We will do another round of fix up upon save. IfFailThrow( pRCW->GetEmitter()->SetFieldRVA(tkField, dwRVA) ); diff --git a/src/coreclr/src/vm/loaderallocator.cpp b/src/coreclr/src/vm/loaderallocator.cpp index 71f4a814be39..4215b8c2e7c9 100644 --- a/src/coreclr/src/vm/loaderallocator.cpp +++ b/src/coreclr/src/vm/loaderallocator.cpp @@ -662,6 +662,11 @@ BOOL QCALLTYPE LoaderAllocator::Destroy(QCall::LoaderAllocatorHandle pLoaderAllo STRESS_LOG1(LF_CLASSLOADER, LL_INFO100, "Begin LoaderAllocator::Destroy for loader allocator %p\n", reinterpret_cast(static_cast(pLoaderAllocator))); LoaderAllocatorID *pID = pLoaderAllocator->Id(); + { + GCX_COOP(); + LoaderAllocator::RemoveMemoryToLoaderAllocatorAssociation(pLoaderAllocator); + } + // This will probably change for shared code unloading _ASSERTE(pID->GetType() == LAT_Assembly); @@ -1984,6 +1989,44 @@ UMEntryThunkCache *LoaderAllocator::GetUMEntryThunkCache() return m_pUMEntryThunkCache; } +/* static */ +void LoaderAllocator::RemoveMemoryToLoaderAllocatorAssociation(LoaderAllocator* pLoaderAllocator) +{ + CONTRACTL { + THROWS; + MODE_COOPERATIVE; + } CONTRACTL_END; + + GlobalLoaderAllocator* pGlobalAllocator = (GlobalLoaderAllocator*)SystemDomain::GetGlobalLoaderAllocator(); + pGlobalAllocator->m_memoryAssociations.RemoveRanges(pLoaderAllocator); +} + +/* static */ +void LoaderAllocator::AssociateMemoryWithLoaderAllocator(BYTE *start, const BYTE *end, LoaderAllocator* pLoaderAllocator) +{ + CONTRACTL { + THROWS; + MODE_COOPERATIVE; + } CONTRACTL_END; + + GlobalLoaderAllocator* pGlobalAllocator = (GlobalLoaderAllocator*)SystemDomain::GetGlobalLoaderAllocator(); + pGlobalAllocator->m_memoryAssociations.AddRange(start, end, pLoaderAllocator); +} + +/* static */ +PTR_LoaderAllocator LoaderAllocator::GetAssociatedLoaderAllocator_Unsafe(TADDR ptr) +{ + LIMITED_METHOD_CONTRACT; + + GlobalLoaderAllocator* pGlobalAllocator = (GlobalLoaderAllocator*)SystemDomain::GetGlobalLoaderAllocator(); + LoaderAllocator* pLoaderAllocator; + if (pGlobalAllocator->m_memoryAssociations.IsInRangeWorker_Unlocked(ptr, reinterpret_cast(&pLoaderAllocator))) + { + return pLoaderAllocator; + } + return NULL; +} + #endif // !CROSSGEN_COMPILE #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/src/vm/loaderallocator.hpp b/src/coreclr/src/vm/loaderallocator.hpp index 70b7cd839cea..602849657398 100644 --- a/src/coreclr/src/vm/loaderallocator.hpp +++ b/src/coreclr/src/vm/loaderallocator.hpp @@ -23,6 +23,7 @@ class FuncPtrStubs; #include "methoddescbackpatchinfo.h" #include "crossloaderallocatorhash.h" #include "onstackreplacement.h" +#include "lockedrangelist.h" #define VPTRU_LoaderAllocator 0x3200 @@ -405,6 +406,13 @@ class LoaderAllocator virtual LoaderAllocatorID* Id() =0; BOOL IsCollectible() { WRAPPER_NO_CONTRACT; return m_IsCollectible; } + // This function may only be called while the runtime is suspended + // As it does not lock around access to a RangeList + static PTR_LoaderAllocator GetAssociatedLoaderAllocator_Unsafe(TADDR ptr); + + static void AssociateMemoryWithLoaderAllocator(BYTE *start, const BYTE *end, LoaderAllocator* pLoaderAllocator); + static void RemoveMemoryToLoaderAllocatorAssociation(LoaderAllocator* pLoaderAllocator); + #ifdef DACCESS_COMPILE void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif @@ -627,12 +635,16 @@ typedef VPTR(LoaderAllocator) PTR_LoaderAllocator; class GlobalLoaderAllocator : public LoaderAllocator { + friend class LoaderAllocator; VPTR_VTABLE_CLASS(GlobalLoaderAllocator, LoaderAllocator) VPTR_UNIQUE(VPTRU_LoaderAllocator+1) DAC_ALIGNAS(LoaderAllocator) // Align the first member to the alignment of the base class BYTE m_ExecutableHeapInstance[sizeof(LoaderHeap)]; + // Associate memory regions with loader allocator objects + LockedRangeList m_memoryAssociations; + protected: LoaderAllocatorID m_Id; @@ -712,7 +724,6 @@ class AssemblyLoaderAllocator : public LoaderAllocator typedef VPTR(AssemblyLoaderAllocator) PTR_AssemblyLoaderAllocator; - #include "loaderallocator.inl" #endif // __LoaderAllocator_h__ diff --git a/src/coreclr/src/vm/lockedrangelist.h b/src/coreclr/src/vm/lockedrangelist.h new file mode 100644 index 000000000000..9289b58cdd21 --- /dev/null +++ b/src/coreclr/src/vm/lockedrangelist.h @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __LockedRangeList_h__ +#define __LockedRangeList_h__ + +// ------------------------------------------------------- +// This just wraps the RangeList methods in a read or +// write lock depending on the operation. +// ------------------------------------------------------- + +class LockedRangeList : public RangeList +{ + public: + VPTR_VTABLE_CLASS(LockedRangeList, RangeList) + + LockedRangeList() : RangeList(), m_RangeListRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT) + { + LIMITED_METHOD_CONTRACT; + } + + ~LockedRangeList() + { + LIMITED_METHOD_CONTRACT; + } + + BOOL IsInRangeWorker_Unlocked(TADDR address, TADDR *pID = NULL) + { + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + return RangeList::IsInRangeWorker(address, pID); + } + + protected: + + virtual BOOL AddRangeWorker(const BYTE *start, const BYTE *end, void *id) + { + WRAPPER_NO_CONTRACT; + SimpleWriteLockHolder lh(&m_RangeListRWLock); + return RangeList::AddRangeWorker(start,end,id); + } + + virtual void RemoveRangesWorker(void *id, const BYTE *start = NULL, const BYTE *end = NULL) + { + WRAPPER_NO_CONTRACT; + SimpleWriteLockHolder lh(&m_RangeListRWLock); + RangeList::RemoveRangesWorker(id,start,end); + } + + virtual BOOL IsInRangeWorker(TADDR address, TADDR *pID = NULL) + { + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + SimpleReadLockHolder lh(&m_RangeListRWLock); + return RangeList::IsInRangeWorker(address, pID); + } + + SimpleRWLock m_RangeListRWLock; +}; + +#endif // __LockedRangeList_h__ \ No newline at end of file diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index 1d3fbbd746c1..5cdeb7af5dec 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -4900,6 +4900,16 @@ void PromoteCarefully(promote_func fn, return; } +#ifndef CROSSGEN_COMPILE + if (sc->promotion) + { + LoaderAllocator*pLoaderAllocator = LoaderAllocator::GetAssociatedLoaderAllocator_Unsafe(PTR_TO_TADDR(*ppObj)); + if (pLoaderAllocator != NULL) + { + GcReportLoaderAllocator(fn, sc, pLoaderAllocator); + } + } +#endif // CROSSGEN_COMPILE #endif // !defined(DACCESS_COMPILE) (*fn) (ppObj, sc, flags); diff --git a/src/coreclr/src/vm/stubmgr.h b/src/coreclr/src/vm/stubmgr.h index d36db9f9009f..471f456cf326 100644 --- a/src/coreclr/src/vm/stubmgr.h +++ b/src/coreclr/src/vm/stubmgr.h @@ -47,6 +47,7 @@ #define __stubmgr_h__ #include "simplerwlock.hpp" +#include "lockedrangelist.h" // When 'TraceStub' returns, it gives the address of where the 'target' is for a stub' // TraceType indicates what this 'target' is @@ -339,53 +340,6 @@ class StubManager #endif // !CROSSGEN_COMPILE }; -// ------------------------------------------------------- -// This just wraps the RangeList methods in a read or -// write lock depending on the operation. -// ------------------------------------------------------- - -class LockedRangeList : public RangeList -{ - public: - VPTR_VTABLE_CLASS(LockedRangeList, RangeList) - - LockedRangeList() : RangeList(), m_RangeListRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT) - { - LIMITED_METHOD_CONTRACT; - } - - ~LockedRangeList() - { - LIMITED_METHOD_CONTRACT; - } - - protected: - - virtual BOOL AddRangeWorker(const BYTE *start, const BYTE *end, void *id) - { - WRAPPER_NO_CONTRACT; - SimpleWriteLockHolder lh(&m_RangeListRWLock); - return RangeList::AddRangeWorker(start,end,id); - } - - virtual void RemoveRangesWorker(void *id, const BYTE *start = NULL, const BYTE *end = NULL) - { - WRAPPER_NO_CONTRACT; - SimpleWriteLockHolder lh(&m_RangeListRWLock); - RangeList::RemoveRangesWorker(id,start,end); - } - - virtual BOOL IsInRangeWorker(TADDR address, TADDR *pID = NULL) - { - WRAPPER_NO_CONTRACT; - SUPPORTS_DAC; - SimpleReadLockHolder lh(&m_RangeListRWLock); - return RangeList::IsInRangeWorker(address, pID); - } - - SimpleRWLock m_RangeListRWLock; -}; - #ifndef CROSSGEN_COMPILE //----------------------------------------------------------- diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index f15a2b532099..edfe25e42021 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -961,6 +961,9 @@ + + https://github.com/dotnet/runtime/issues/40394 + Handling for Copy constructors isn't present in mono interop diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs new file mode 100644 index 000000000000..834bc472497f --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs @@ -0,0 +1,142 @@ +// 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.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Loader; + +class Program +{ + static int Main(string[] args) + { + var holdResult = HoldAssembliesAliveThroughByRefFields(out GCHandle gch1, out GCHandle gch2); + if (holdResult != 100) + return holdResult; + + // At this point, nothing should keep the collectible assembly alive + // Loop for a bit forcing the GC to run, and then it should be freed + for (int i = 0; i < 10; i++) + { + GC.Collect(2); + GC.WaitForPendingFinalizers(); + } + + if (gch1.Target != null) + { + return 3; + } + if (gch2.Target != null) + { + return 4; + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int HoldAssembliesAliveThroughByRefFields(out GCHandle gch1, out GCHandle gch2) + { + // ThreadStatic lifetime check. Here we don't require the actual assembly to remain loaded, but we do require the field to remain accessible + var spanThreadStatic = LoadAssemblyThreadStatic(out GCHandle gchThreadStatic); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + + var span1 = LoadAssembly(out gch1); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + var span2 = CreateAssemblyDynamically(out gch2); + for (int i = 0; i < 10; i++) + { + Console.WriteLine(span1[0]); + Console.WriteLine(span2[0]); + Console.WriteLine(spanThreadStatic[0]); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + if (gch1.Target == null) + { + return 1; + } + if (gch2.Target == null) + { + return 2; + } + if (spanThreadStatic[0] != 7) + { + Console.WriteLine($"spanThreadStatic[0] = {spanThreadStatic[0]}"); + return 5; + } + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static ReadOnlySpan LoadAssembly(out GCHandle gchToAssembly) + { + var alc = new AssemblyLoadContext("test", isCollectible: true); + var a = alc.LoadFromAssemblyPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Unloaded.dll")); + gchToAssembly = GCHandle.Alloc(a, GCHandleType.WeakTrackResurrection); + + var spanAccessor = (IReturnSpan)Activator.CreateInstance(a.GetType("SpanAccessor")); + + alc.Unload(); + + return spanAccessor.GetSpan(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static ReadOnlySpan LoadAssemblyThreadStatic(out GCHandle gchToAssembly) + { + var alc = new AssemblyLoadContext("test", isCollectible: true); + var a = alc.LoadFromAssemblyPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Unloaded.dll")); + gchToAssembly = GCHandle.Alloc(a, GCHandleType.WeakTrackResurrection); + + var spanAccessor = (IReturnSpan)Activator.CreateInstance(a.GetType("ThreadStaticSpanAccessor")); + + alc.Unload(); + + return spanAccessor.GetSpan(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static ReadOnlySpan CreateAssemblyDynamically(out GCHandle gchToAssembly) + { + AssemblyBuilder ab = + AssemblyBuilder.DefineDynamicAssembly( + new AssemblyName("tempAssembly"), + AssemblyBuilderAccess.RunAndCollect); + ModuleBuilder modb = ab.DefineDynamicModule("tempAssembly.dll"); + + var byRefAccessField = modb.DefineInitializedData("RawBytes", new byte[] {1,2,3,4,5}, FieldAttributes.Public | FieldAttributes.Static); + modb.CreateGlobalFunctions(); + + TypeBuilder tb = modb.DefineType("GetSpanType", TypeAttributes.Class, typeof(object), new Type[]{typeof(IReturnSpan)}); + var mb = tb.DefineMethod("GetSpan", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(ReadOnlySpan), new Type[]{}); + ILGenerator myMethodIL = mb.GetILGenerator(); + myMethodIL.Emit(OpCodes.Ldsflda, byRefAccessField); + myMethodIL.Emit(OpCodes.Ldc_I4_4); + myMethodIL.Emit(OpCodes.Newobj, typeof(ReadOnlySpan).GetConstructor(new Type[]{typeof(void*), typeof(int)})); + myMethodIL.Emit(OpCodes.Ret); + + var getSpanType = tb.CreateType(); + + gchToAssembly = GCHandle.Alloc(getSpanType, GCHandleType.WeakTrackResurrection); + + var spanAccessor = (IReturnSpan)Activator.CreateInstance(getSpanType); + + return spanAccessor.GetSpan(); + } + +} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.csproj b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.csproj new file mode 100644 index 000000000000..7cde272f1077 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.csproj @@ -0,0 +1,13 @@ + + + true + Exe + BuildAndRun + 0 + + + + + + + \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.cs b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.cs new file mode 100644 index 000000000000..c05b5056798e --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.cs @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public interface IReturnSpan +{ + ReadOnlySpan GetSpan(); +} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.csproj b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.csproj new file mode 100644 index 000000000000..88e99d96176a --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/SpanAccessor.csproj @@ -0,0 +1,11 @@ + + + true + Library + BuildOnly + 0 + + + + + \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs new file mode 100644 index 000000000000..3f2615e99a02 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.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 System.Runtime.CompilerServices; + +public class SpanAccessor : IReturnSpan +{ + public static ReadOnlySpan RawData => new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + public ReadOnlySpan GetSpan() + { + return RawData; + } +} + +public class ThreadStaticSpanAccessor : IReturnSpan +{ + [ThreadStatic] + public static byte ThreadStaticByte = 7; + + public unsafe ReadOnlySpan GetSpan() + { + return new ReadOnlySpan(Unsafe.AsPointer(ref ThreadStaticByte), 1); + } +} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.csproj b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.csproj new file mode 100644 index 000000000000..6d13ecf2427e --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.csproj @@ -0,0 +1,12 @@ + + + true + Library + BuildOnly + 0 + + + + + + \ No newline at end of file From fe41d3c762695cfeb364a8a0b61e2e376d22da5a Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 5 Aug 2020 23:04:00 +0300 Subject: [PATCH 272/755] [mono] Pass delegate target when using CreateDelegate (#40321) * Pass delegate target when using CreateDelegate * [tests] Add test that checks `this` with CreateDelegate API --- .../System.Runtime/tests/System/DelegateTests.cs | 10 ++++++++++ .../System.Private.CoreLib/src/System/Delegate.Mono.cs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System/DelegateTests.cs b/src/libraries/System.Runtime/tests/System/DelegateTests.cs index 35ee59b92113..055fd8274e26 100644 --- a/src/libraries/System.Runtime/tests/System/DelegateTests.cs +++ b/src/libraries/System.Runtime/tests/System/DelegateTests.cs @@ -619,6 +619,10 @@ public static void CreateDelegate2() e = (E)Delegate.CreateDelegate(typeof(E), new C(), "DoExecute"); Assert.NotNull(e); Assert.Equal(102, e(new C())); + + e = (E)Delegate.CreateDelegate(typeof(E), new B() { field = 42 }, "GetField"); + Assert.NotNull(e); + Assert.Equal(42, e(new C())); } [Fact] @@ -1103,6 +1107,7 @@ public static void CreateDelegate9_Type_Null() public class B { + public int field; public virtual string retarg3(string s) { @@ -1136,6 +1141,11 @@ public int StartExecute(C c, B b) { return 3; } + + public int GetField(C c) + { + return field; + } } public class C : B, Iface diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs index af5a59415591..faf349979a6a 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs @@ -177,7 +177,7 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn return null; } - return CreateDelegate_internal(type, null, info, throwOnBindFailure); + return CreateDelegate_internal(type, target, info, throwOnBindFailure); } [RequiresUnreferencedCode("The target method might be removed")] From b62f48287f9883d5af1f1384f2b9a007066439c5 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 5 Aug 2020 13:45:22 -0700 Subject: [PATCH 273/755] System.Diagnostics.Activity Perf Improvement (#40362) --- .../src/System/Diagnostics/Activity.cs | 68 +++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index b5cd641c3eea..23834958a4f4 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -3,8 +3,10 @@ using System.Buffers.Binary; using System.Buffers.Text; +using System.Collections; using System.Collections.Generic; using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -33,6 +35,7 @@ public partial class Activity : IDisposable { #pragma warning disable CA1825 // Array.Empty() doesn't exist in all configurations private static readonly IEnumerable> s_emptyBaggageTags = new KeyValuePair[0]; + private static readonly IEnumerable> s_emptyTagObjects = new KeyValuePair[0]; private static readonly IEnumerable s_emptyLinks = new ActivityLink[0]; private static readonly IEnumerable s_emptyEvents = new ActivityEvent[0]; #pragma warning restore CA1825 @@ -255,7 +258,7 @@ public string? RootId #if ALLOW_PARTIALLY_TRUSTED_CALLERS [System.Security.SecuritySafeCriticalAttribute] #endif - get => _tags?.Enumerate() ?? Unsafe.As>>(s_emptyBaggageTags); + get => _tags ?? s_emptyTagObjects; } /// @@ -264,7 +267,7 @@ public string? RootId /// public IEnumerable Events { - get => _events != null ? _events.Enumerate() : s_emptyEvents; + get => _events ?? s_emptyEvents; } /// @@ -273,7 +276,7 @@ public IEnumerable Events /// public IEnumerable Links { - get => _links != null ? _links.Enumerate() : s_emptyLinks; + get => _links ?? s_emptyLinks; } /// @@ -1238,7 +1241,7 @@ private partial class LinkedListNode } // We are not using the public LinkedList because we need to ensure thread safety operation on the list. - private class LinkedList + private class LinkedList : IEnumerable { private LinkedListNode _first; private LinkedListNode _last; @@ -1269,18 +1272,12 @@ public void Add(T value) } } - public IEnumerable Enumerate() - { - LinkedListNode? current = _first; - do - { - yield return current.Value; - current = current.Next; - } while (current != null); - } + public Enumerator GetEnumerator() => new Enumerator(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); } - private class TagsLinkedList + private class TagsLinkedList : IEnumerable> { private LinkedListNode>? _first; private LinkedListNode>? _last; @@ -1382,6 +1379,10 @@ public void Set(KeyValuePair value) } } + public Enumerator> GetEnumerator() => new Enumerator>(_first); + IEnumerator> IEnumerable>.GetEnumerator() => new Enumerator>(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator>(_first); + public IEnumerable> EnumerateStringValues() { LinkedListNode>? current = _first; @@ -1390,22 +1391,47 @@ public void Set(KeyValuePair value) { if (current.Value.Value is string || current.Value.Value == null) { - yield return new KeyValuePair(current.Value.Key, (string?) current.Value.Value); + yield return new KeyValuePair(current.Value.Key, (string?)current.Value.Value); } current = current.Next; }; } + } - public IEnumerable> Enumerate() + private struct Enumerator : IEnumerator + { + private readonly LinkedListNode? _head; + private LinkedListNode? _nextNode; + [AllowNull, MaybeNull] private T _currentItem; + + public Enumerator(LinkedListNode? head) { - LinkedListNode>? current = _first; + _nextNode = _head = head; + _currentItem = default; + } - while (current != null) + public T Current => _currentItem!; + + object? IEnumerator.Current => Current; + + public bool MoveNext() + { + if (_nextNode == null) { - yield return current.Value; - current = current.Next; - }; + _currentItem = default; + return false; + } + + _currentItem = _nextNode.Value; + _nextNode = _nextNode.Next; + return true; + } + + public void Reset() => _nextNode = _head; + + public void Dispose() + { } } From 05e2cfbc6b0ec1495495ca22f4256917456c8719 Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Wed, 5 Aug 2020 14:38:10 -0700 Subject: [PATCH 274/755] Add wasm runs (#39548) * Add WASM microbenchmark runs This commit adds WASM microbenchmark support to the perf lab. * Increase timeout for first run * Add runkind * Update proj file selection --- eng/common/performance/microbenchmarks.proj | 6 +++- eng/common/performance/performance-setup.sh | 31 ++++++++++++++++--- eng/pipelines/coreclr/perf.yml | 30 ++++++++++++++++++ eng/pipelines/coreclr/templates/perf-job.yml | 19 +++++++++++- .../coreclr/templates/run-performance-job.yml | 4 +-- 5 files changed, 82 insertions(+), 8 deletions(-) diff --git a/eng/common/performance/microbenchmarks.proj b/eng/common/performance/microbenchmarks.proj index 185522fc739c..71114b074e1b 100644 --- a/eng/common/performance/microbenchmarks.proj +++ b/eng/common/performance/microbenchmarks.proj @@ -41,6 +41,10 @@ $HELIX_WORKITEM_ROOT/testResults.xml + + $(CliArguments) --wasm + + --corerun %HELIX_CORRELATION_PAYLOAD%\dotnet-mono\shared\Microsoft.NETCore.App\5.0.0\corerun.exe @@ -65,7 +69,7 @@ - 2:30 + 12:30 0:15 diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh index c87cbf0fc232..66f63a397a0f 100755 --- a/eng/common/performance/performance-setup.sh +++ b/eng/common/performance/performance-setup.sh @@ -24,6 +24,8 @@ run_from_perf_repo=false use_core_run=true use_baseline_core_run=true using_mono=false +wasm_runtime_loc= +using_wasm=false while (($# > 0)); do lowerI="$(echo $1 | awk '{print tolower($0)}')" @@ -70,7 +72,7 @@ while (($# > 0)); do ;; --kind) kind=$2 - configurations="CompliationMode=$compilation_mode RunKind=$kind" + configurations="CompilationMode=$compilation_mode RunKind=$kind" shift 2 ;; --runcategories) @@ -101,6 +103,10 @@ while (($# > 0)); do mono_dotnet=$2 shift 2 ;; + --wasm) + wasm_runtime_loc=$2 + shift 2 + ;; --compare) compare=true shift 1 @@ -130,6 +136,7 @@ while (($# > 0)); do echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\"" echo " --internal If the benchmarks are running as an official job." echo " --monodotnet Pass the path to the mono dotnet for mono performance testing." + echo " --wasm Path to the unpacled wasm runtime pack." echo "" exit 0 ;; @@ -141,7 +148,7 @@ if [ "$repository" == "dotnet/performance" ] || [ "$repository" == "dotnet-perfo fi if [ -z "$configurations" ]; then - configurations="CompliationMode=$compilation_mode" + configurations="CompilationMode=$compilation_mode" fi if [ -z "$core_root_directory" ]; then @@ -191,11 +198,15 @@ if [[ "$mono_dotnet" != "" ]]; then configurations="$configurations LLVM=$llvm MonoInterpreter=$monointerpreter MonoAOT=$monoaot" fi +if [[ "$wasm_runtime_loc" != "" ]]; then + configurations="CompilationMode=wasm;RunKind=micro" +fi + if [[ "$monointerpreter" == "true" ]]; then - extra_benchmark_dotnet_arguments="--category-exclusion-filter NoInterpreter" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter" fi -common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs $configurations --architecture $architecture" +common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs \"$configurations\" --architecture $architecture" setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments" @@ -217,6 +228,17 @@ else mv $docs_directory $workitem_directory fi +if [[ "$wasm_runtime_loc" != "" ]]; then + using_wasm=true + + wasm_dotnet_path=$payload_directory/dotnet-wasm + + mv $wasm_runtime_loc $wasm_dotnet_path + + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmMainJS \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm/runtime-test.js --wasmEngine /home/helixbot/.jsvu/v8 --customRuntimePack \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm" + +fi + if [[ "$mono_dotnet" != "" ]]; then using_mono=true mono_dotnet_path=$payload_directory/dotnet-mono @@ -259,3 +281,4 @@ Write-PipelineSetVariable -name "Kind" -value "$kind" -is_multi_job_variable fal Write-PipelineSetVariable -name "_BuildConfig" -value "$architecture.$kind.$framework" -is_multi_job_variable false Write-PipelineSetVariable -name "Compare" -value "$compare" -is_multi_job_variable false Write-PipelineSetVariable -name "MonoDotnet" -value "$using_mono" -is_multi_job_variable false +Write-PipelineSetVariable -name "WasmDotnet" -value "$using_wasm" -is_multi_job_variable false diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index cb97c408514f..0cbf812e809d 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -56,6 +56,21 @@ jobs: testGroup: perf # build mono +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + runtimeFlavor: mono + platforms: + - Browser_wasm + jobParameters: + buildArgs: -s mono+libs+installer -c $(_BuildConfig) + nameSuffix: wasm + isOfficialBuild: ${{ variables.isOfficialBuild }} + extraStepsTemplate: /eng/pipelines/common/upload-unsigned-artifacts-step.yml + extraStepsParameters: + name: MonoRuntimePacks + - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/mono/templates/build-job.yml @@ -97,6 +112,21 @@ jobs: runKind: micro_mono # run coreclr microbenchmarks perf job +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: wasm + platforms: + - Linux_x64 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + runtimeType: wasm + codeGenType: 'wasm' + projectFile: microbenchmarks.proj + runKind: micro + - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index 57df1c0dcb63..21799d64354d 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -43,6 +43,8 @@ jobs: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} - ${{ if eq(parameters.runtimeType, 'mono') }}: - ${{ format('mono_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ if eq(parameters.runtimeType, 'wasm') }}: + - ${{ format('build_{0}{1}_{2}_{3}_{4}', 'Browser', '', 'wasm', parameters.buildConfig, parameters.runtimeType) }} ${{ if eq(parameters.osGroup, 'Windows_NT') }}: ${{ if eq(parameters.runtimeType, 'mono') }}: @@ -52,7 +54,9 @@ jobs: ${{ if ne(parameters.osGroup, 'Windows_NT') }}: ${{ if eq(parameters.runtimeType, 'mono') }}: extraSetupParameters: --architecture ${{ parameters.archType }} --monodotnet $(Build.SourcesDirectory)/.dotnet-mono --kind micro_mono - ${{ if ne(parameters.runtimeType, 'mono') }}: + ${{ if eq(parameters.runtimeType, 'wasm') }}: + extraSetupParameters: --architecture ${{ parameters.archType }} --wasm $(librariesDownloadDir)/bin/wasm --kind micro + ${{ if eq(parameters.runtimeType, 'coreclr') }}: extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }} variables: ${{ parameters.variables }} @@ -90,6 +94,19 @@ jobs: artifactName: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)_$(archType)_$(buildConfig)' displayName: 'Mono runtime' + - ${{ if eq(parameters.runtimeType, 'wasm') }}: + # Download artifact + - task: DownloadBuildArtifacts@0 + displayName: 'Download WASM Runtime Pack' + inputs: + buildType: current + downloadType: single + downloadPath: '$(Build.SourcesDirectory)/__download__' + artifactName: 'IntermediateUnsignedArtifacts' + + - script: "mkdir $(librariesDownloadDir)/bin/wasm;unzip -o $(Build.SourcesDirectory)/__download__/IntermediateUnsignedArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.browser-wasm.5.0.0-ci.nupkg data/* runtimes/* -d $(librariesDownloadDir)/bin/wasm;cp src/mono/wasm/runtime-test.js $(librariesDownloadDir)/bin/wasm/runtime-test.js;find $(librariesDownloadDir)/bin/wasm -type f -exec chmod 664 {} \\;" + displayName: "Create wasm directory (Linux)" + # Create Core_Root - script: $(coreClrRepoRootDir)build-test$(scriptExt) $(buildConfig) $(archType) generatelayoutonly $(librariesOverrideArg) displayName: Create Core_Root diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 3d34f5a67a14..0e44fbb7cd28 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -53,7 +53,7 @@ jobs: - IsInternal: '' - HelixApiAccessToken: '' - HelixPreCommandStemWindows: 'py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install --user azure.storage.blob==12.0.0 --force-reinstall;py -3 -m pip install --user azure.storage.queue==12.0.0 --force-reinstall;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"' - ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"' - HelixPreCommand: '' @@ -73,7 +73,7 @@ jobs: - ${{ if eq( parameters.osGroup, 'Windows_NT') }}: - HelixPreCommand: $(ExtraMSBuildLogsWindows) - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - - HelixPreCommand: $(ExtraMSBuildLogsLinux) + - HelixPreCommand: $(ExtraMSBuildLogsLinux);npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8 - ${{ if and(eq(parameters.codeGenType, 'Interpreter'), eq(parameters.runtimeType, 'mono')) }}: From 5c29e1483e0ca803c8be3ea6a0a8cfe899b2a813 Mon Sep 17 00:00:00 2001 From: John Salem Date: Wed, 5 Aug 2020 14:39:45 -0700 Subject: [PATCH 275/755] [test] fix hang in macOS variants of reverse diagnostics server tests (#40225) Co-authored-by: Noah Falk --- .../debug/debug-pal/unix/diagnosticsipc.cpp | 17 ++++++---- src/coreclr/src/debug/inc/diagnosticsipc.h | 7 ++-- src/coreclr/src/vm/diagnosticserver.cpp | 2 ++ src/coreclr/src/vm/ipcstreamfactory.cpp | 33 +++++++++++++++++++ .../tracing/eventpipe/common/IpcUtils.cs | 2 +- src/tests/tracing/eventpipe/common/Reverse.cs | 22 ++++--------- .../eventpipe/reverseouter/reverseouter.cs | 10 ++++-- 7 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp index 632ac03a44c2..a718c2bc34e2 100644 --- a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp @@ -246,6 +246,8 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_ { if (pollfds[i].revents != 0) { + if (callback != nullptr) + callback("IpcStream::DiagnosticsIpc::Poll - poll revents", (uint32_t)pollfds[i].revents); // error check FIRST if (pollfds[i].revents & POLLHUP) { @@ -253,21 +255,22 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_ // will technically meet the requirements for POLLIN // i.e., a call to recv/read won't block rgIpcPollHandles[i].revents = (uint8_t)PollEvents::HANGUP; - delete[] pollfds; - return -1; } else if ((pollfds[i].revents & (POLLERR|POLLNVAL))) { if (callback != nullptr) callback("Poll error", (uint32_t)pollfds[i].revents); rgIpcPollHandles[i].revents = (uint8_t)PollEvents::ERR; - delete[] pollfds; - return -1; } else if (pollfds[i].revents & (POLLIN|POLLPRI)) { rgIpcPollHandles[i].revents = (uint8_t)PollEvents::SIGNALED; - break; + } + else + { + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::UNKNOWN; + if (callback != nullptr) + callback("unkown poll response", (uint32_t)pollfds[i].revents); } } } @@ -341,7 +344,7 @@ bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nByt pfd.fd = _clientSocket; pfd.events = POLLIN; int retval = poll(&pfd, 1, timeoutMs); - if (retval <= 0 || pfd.revents != POLLIN) + if (retval <= 0 || !(pfd.revents & POLLIN)) { // timeout or error return false; @@ -382,7 +385,7 @@ bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32 pfd.fd = _clientSocket; pfd.events = POLLOUT; int retval = poll(&pfd, 1, timeoutMs); - if (retval <= 0 || pfd.revents != POLLOUT) + if (retval <= 0 || !(pfd.revents & POLLOUT)) { // timeout or error return false; diff --git a/src/coreclr/src/debug/inc/diagnosticsipc.h b/src/coreclr/src/debug/inc/diagnosticsipc.h index 99d670ca6ca5..ecbf9db7dfef 100644 --- a/src/coreclr/src/debug/inc/diagnosticsipc.h +++ b/src/coreclr/src/debug/inc/diagnosticsipc.h @@ -16,6 +16,7 @@ typedef void (*ErrorCallback)(const char *szMessage, uint32_t code); class IpcStream final { + friend class IpcStreamFactory; public: static constexpr int32_t InfiniteTimeout = -1; ~IpcStream(); @@ -26,6 +27,7 @@ class IpcStream final class DiagnosticsIpc final { + friend class IpcStreamFactory; public: enum ConnectionMode { @@ -38,7 +40,8 @@ class IpcStream final NONE = 0x00, // no events SIGNALED = 0x01, // ready for use HANGUP = 0x02, // connection remotely closed - ERR = 0x04 // other error + ERR = 0x04, // error + UNKNOWN = 0x80 // unknown state }; // The bookeeping struct used for polling on server and client structs @@ -125,7 +128,7 @@ class IpcStream final private: #ifdef TARGET_UNIX int _clientSocket = -1; - IpcStream(int clientSocket, int serverSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER) + IpcStream(int clientSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER) : _clientSocket(clientSocket), _mode(mode) {} #else HANDLE _hPipe = INVALID_HANDLE_VALUE; diff --git a/src/coreclr/src/vm/diagnosticserver.cpp b/src/coreclr/src/vm/diagnosticserver.cpp index b04def7957b1..7688cabe1511 100644 --- a/src/coreclr/src/vm/diagnosticserver.cpp +++ b/src/coreclr/src/vm/diagnosticserver.cpp @@ -74,6 +74,8 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) continue; } + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "DiagnosticServer - received IPC message with command set (%d) and command id (%d)\n", message.GetHeader().CommandSet, message.GetHeader().CommandId); + switch ((DiagnosticsIpc::DiagnosticServerCommandSet)message.GetHeader().CommandSet) { case DiagnosticsIpc::DiagnosticServerCommandSet::EventPipe: diff --git a/src/coreclr/src/vm/ipcstreamfactory.cpp b/src/coreclr/src/vm/ipcstreamfactory.cpp index d24f14c8340e..6a82f166c1da 100644 --- a/src/coreclr/src/vm/ipcstreamfactory.cpp +++ b/src/coreclr/src/vm/ipcstreamfactory.cpp @@ -12,8 +12,10 @@ Volatile IpcStreamFactory::s_isShutdown = false; bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) { + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO1000, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - ENTER.\n"); if (_pStream == nullptr) { + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - cache was empty!\n"); // cache is empty, reconnect, e.g., there was a disconnect IpcStream *pConnection = _pIpc->Connect(callback); if (pConnection == nullptr) @@ -22,6 +24,11 @@ bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::Diagno callback("Failed to connect to client connection", -1); return false; } +#ifdef TARGET_UNIX + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - returned connection { _clientSocket = %d }\n", pConnection->_clientSocket); +#else + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - returned connection { _hPipe = %d, _oOverlap.hEvent = %d }\n", pConnection->_hPipe, pConnection->_oOverlap.hEvent); +#endif if (!DiagnosticsIpc::SendIpcAdvertise_V1(pConnection)) { if (callback != nullptr) @@ -33,6 +40,7 @@ bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::Diagno _pStream = pConnection; } *pIpcPollHandle = { nullptr, _pStream, 0, this }; + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - EXIT.\n"); return true; } @@ -139,6 +147,7 @@ int32_t IpcStreamFactory::GetNextTimeout(int32_t currentTimeoutMs) IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) { + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - ENTER"); IpcStream *pStream = nullptr; CQuickArrayList rgIpcPollHandles; @@ -168,6 +177,25 @@ IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) nPollAttempts++; STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - Poll attempt: %d, timeout: %dms.\n", nPollAttempts, pollTimeoutMs); + for (uint32_t i = 0; i < rgIpcPollHandles.Size(); i++) + { + if (rgIpcPollHandles[i].pIpc != nullptr) + { +#ifdef TARGET_UNIX + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "\tSERVER IpcPollHandle[%d] = { _serverSocket = %d }\n", i, rgIpcPollHandles[i].pIpc->_serverSocket); +#else + STRESS_LOG3(LF_DIAGNOSTICS_PORT, LL_INFO10, "\tSERVER IpcPollHandle[%d] = { _hPipe = %d, _oOverlap.hEvent = %d }\n", i, rgIpcPollHandles[i].pIpc->_hPipe, rgIpcPollHandles[i].pIpc->_oOverlap.hEvent); +#endif + } + else + { +#ifdef TARGET_UNIX + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "\tCLIENT IpcPollHandle[%d] = { _clientSocket = %d }\n", i, rgIpcPollHandles[i].pStream->_clientSocket); +#else + STRESS_LOG3(LF_DIAGNOSTICS_PORT, LL_INFO10, "\tCLIENT IpcPollHandle[%d] = { _hPipe = %d, _oOverlap.hEvent = %d }\n", i, rgIpcPollHandles[i].pStream->_hPipe, rgIpcPollHandles[i].pStream->_oOverlap.hEvent); +#endif + } + } int32_t retval = IpcStream::DiagnosticsIpc::Poll(rgIpcPollHandles.Ptr(), (uint32_t)rgIpcPollHandles.Size(), pollTimeoutMs, callback); bool fSawError = false; @@ -211,6 +239,11 @@ IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) rgIpcPollHandles.Pop(); } +#ifdef TARGET_UNIX + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - EXIT :: Poll attempt: %d, stream using handle %d.\n", nPollAttempts, pStream->_clientSocket); +#else + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - EXIT :: Poll attempt: %d, stream using handle %d.\n", nPollAttempts, pStream->_hPipe); +#endif return pStream; } diff --git a/src/tests/tracing/eventpipe/common/IpcUtils.cs b/src/tests/tracing/eventpipe/common/IpcUtils.cs index bf17e1e27e83..2f39237f4b58 100644 --- a/src/tests/tracing/eventpipe/common/IpcUtils.cs +++ b/src/tests/tracing/eventpipe/common/IpcUtils.cs @@ -70,7 +70,7 @@ public static async Task RunSubprocess(Assembly currentAssembly, Dictionar foreach ((string key, string value) in environment) process.StartInfo.Environment.Add(key, value); process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName; - process.StartInfo.Arguments = new Uri(currentAssembly.CodeBase).LocalPath + " 0"; + process.StartInfo.Arguments = new Uri(currentAssembly.Location).LocalPath + " 0"; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; process.StartInfo.RedirectStandardError = true; diff --git a/src/tests/tracing/eventpipe/common/Reverse.cs b/src/tests/tracing/eventpipe/common/Reverse.cs index 1b99f913d659..19c9b216ce84 100644 --- a/src/tests/tracing/eventpipe/common/Reverse.cs +++ b/src/tests/tracing/eventpipe/common/Reverse.cs @@ -102,7 +102,6 @@ public ReverseServer(string serverAddress, int bufferSize = 16 * 1024) socket.ReceiveBufferSize = Math.Max(bufferSize, 128); socket.Bind(remoteEP); socket.Listen(255); - socket.LingerState.Enabled = false; _server = socket; } } @@ -166,20 +165,13 @@ public void Shutdown() } break; case Socket socket: - try - { - socket.Shutdown(SocketShutdown.Both); - } - catch {} - finally - { - _clientSocket?.Close(); - socket.Close(); - socket.Dispose(); - _clientSocket?.Dispose(); - if (File.Exists(_serverAddress)) - File.Delete(_serverAddress); - } + if (File.Exists(_serverAddress)) + File.Delete(_serverAddress); + socket.Close(); + socket.Dispose(); + _clientSocket?.Shutdown(SocketShutdown.Both); + _clientSocket?.Close(); + _clientSocket?.Dispose(); break; default: throw new ArgumentException("Invalid server type"); diff --git a/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs b/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs index ff01fbc0f449..15eadb015f58 100644 --- a/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs +++ b/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs @@ -47,16 +47,22 @@ public static async Task TEST_ReverseConnectionCanRecycleWhileTracing() Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); - using var source = new EventPipeEventSource(stream); - Task readerTask = Task.Run(() => source.Process()); + // using var source = new EventPipeEventSource(stream); + using var memroyStream = new MemoryStream(); + Task readerTask = stream.CopyToAsync(memroyStream);//Task.Run(() => source.Process()); await Task.Delay(500); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); } + catch (Exception e) + { + Logger.logger.Log(e.ToString()); + } finally { + Logger.logger.Log("setting the MRE"); mre.Set(); } }); From 96f178d32b7ba62485917ac46ef1edcfd3c2d10d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 5 Aug 2020 15:16:05 -0700 Subject: [PATCH 276/755] Adding support for X86Base.CpuId (#40167) * Adding support for X86Base.CpuId * Rename getcpuid and getextcpuid to __cpuid and __cpuidex, respectively * Removing xchg from the Unix x64 __cpuid implementation * Add a comment as to why the X86/X86Base/CpuId test limits the checked vendors * Apply suggestions from code review Co-authored-by: Jan Kotas * Adding back a missing parentheses * Fixing a typo in the isGenuineIntel check * Avoid a conflict around cpuInfo * Avoid an implicit cast when comparing the cpuidInfo * Separate the __cpuidex qcall into coreclr and mono specific variants * Add the partial modifier to the X86Base.PlatformNotSupported.cs file Co-authored-by: Jan Kotas --- .../System.Private.CoreLib.csproj | 1 + .../Runtime/Intrinsics/X86/X86Base.CoreCLR.cs | 14 ++ .../src/classlibnative/bcltype/system.cpp | 10 +- .../src/classlibnative/bcltype/system.h | 4 + src/coreclr/src/vm/amd64/AsmHelpers.asm | 45 ----- src/coreclr/src/vm/amd64/unixstubs.cpp | 39 ++-- src/coreclr/src/vm/cgensys.h | 19 +- src/coreclr/src/vm/codeman.cpp | 100 +++++----- src/coreclr/src/vm/ecalllist.h | 10 + src/coreclr/src/vm/i386/cgenx86.cpp | 91 ++------- .../X86/Bmi1.PlatformNotSupported.cs | 8 +- .../src/System/Runtime/Intrinsics/X86/Bmi1.cs | 8 +- .../X86/Bmi2.PlatformNotSupported.cs | 8 +- .../src/System/Runtime/Intrinsics/X86/Bmi2.cs | 8 +- .../X86/Lzcnt.PlatformNotSupported.cs | 8 +- .../System/Runtime/Intrinsics/X86/Lzcnt.cs | 8 +- .../X86/Sse.PlatformNotSupported.cs | 8 +- .../src/System/Runtime/Intrinsics/X86/Sse.cs | 8 +- .../X86/X86Base.PlatformNotSupported.cs | 10 +- .../System/Runtime/Intrinsics/X86/X86Base.cs | 20 +- .../ref/System.Runtime.Intrinsics.cs | 44 +++-- .../System.Private.CoreLib.csproj | 1 + .../Runtime/Intrinsics/X86/X86Base.Mono.cs | 13 ++ .../HardwareIntrinsics/X86/X86Base/CpuId.cs | 186 ++++++++++++++++++ .../X86/X86Base/CpuId_r.csproj | 13 ++ .../X86/X86Base/CpuId_ro.csproj | 13 ++ .../JitBlue/Runtime_34587/Runtime_34587.cs | 25 ++- 27 files changed, 460 insertions(+), 262 deletions(-) create mode 100644 src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs create mode 100644 src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.Mono.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_ro.csproj diff --git a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj index 501487c6a111..1665f9ac6925 100644 --- a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -224,6 +224,7 @@ + diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs new file mode 100644 index 000000000000..e523487f0d6b --- /dev/null +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Runtime.Intrinsics.X86 +{ + public abstract partial class X86Base + { + [DllImport(RuntimeHelpers.QCall)] + private static extern unsafe void __cpuidex(int* cpuInfo, int functionId, int subFunctionId); + } +} diff --git a/src/coreclr/src/classlibnative/bcltype/system.cpp b/src/coreclr/src/classlibnative/bcltype/system.cpp index c037236f6959..6bd072f13ea8 100644 --- a/src/coreclr/src/classlibnative/bcltype/system.cpp +++ b/src/coreclr/src/classlibnative/bcltype/system.cpp @@ -607,9 +607,17 @@ BOOL QCALLTYPE SystemNative::WinRTSupported() #endif // FEATURE_COMINTEROP +#if defined(TARGET_X86) || defined(TARGET_AMD64) +void QCALLTYPE SystemNative::X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId) +{ + QCALL_CONTRACT; + BEGIN_QCALL; + __cpuidex(cpuInfo, functionId, subFunctionId); + END_QCALL; +} - +#endif // defined(TARGET_X86) || defined(TARGET_AMD64) diff --git a/src/coreclr/src/classlibnative/bcltype/system.h b/src/coreclr/src/classlibnative/bcltype/system.h index 20d357c17302..ff6720f0a8c0 100644 --- a/src/coreclr/src/classlibnative/bcltype/system.h +++ b/src/coreclr/src/classlibnative/bcltype/system.h @@ -81,6 +81,10 @@ class SystemNative // Return a method info for the method were the exception was thrown static FCDECL1(ReflectMethodObject*, GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE); +#if defined(TARGET_X86) || defined(TARGET_AMD64) + static void QCALLTYPE X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId); +#endif // defined(TARGET_X86) || defined(TARGET_AMD64) + private: // Common processing code for FailFast static void GenericFailFast(STRINGREF refMesgString, EXCEPTIONREF refExceptionForWatsonBucketing, UINT_PTR retAddress, UINT exitCode, STRINGREF errorSource); diff --git a/src/coreclr/src/vm/amd64/AsmHelpers.asm b/src/coreclr/src/vm/amd64/AsmHelpers.asm index cb5d1fad499d..172b800f3fea 100644 --- a/src/coreclr/src/vm/amd64/AsmHelpers.asm +++ b/src/coreclr/src/vm/amd64/AsmHelpers.asm @@ -667,27 +667,6 @@ NESTED_ENTRY ProfileTailcallNaked, _TEXT NESTED_END ProfileTailcallNaked, _TEXT -;; extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); -NESTED_ENTRY getcpuid, _TEXT - - push_nonvol_reg rbx - push_nonvol_reg rsi - END_PROLOGUE - - mov eax, ecx ; first arg - mov rsi, rdx ; second arg (result) - xor ecx, ecx ; clear ecx - needed for "Structured Extended Feature Flags" - cpuid - mov [rsi+ 0], eax - mov [rsi+ 4], ebx - mov [rsi+ 8], ecx - mov [rsi+12], edx - pop rsi - pop rbx - ret -NESTED_END getcpuid, _TEXT - - ;; extern "C" DWORD __stdcall xmmYmmStateSupport(); LEAF_ENTRY xmmYmmStateSupport, _TEXT mov ecx, 0 ; Specify xcr0 @@ -703,30 +682,6 @@ LEAF_ENTRY xmmYmmStateSupport, _TEXT ret LEAF_END xmmYmmStateSupport, _TEXT -;The following function uses Deterministic Cache Parameter leafs to determine the cache hierarchy information on Prescott & Above platforms. -; This function takes 3 arguments: -; Arg1 is an input to ECX. Used as index to specify which cache level to return information on by CPUID. -; Arg1 is already passed in ECX on call to getextcpuid, so no explicit assignment is required; -; Arg2 is an input to EAX. For deterministic code enumeration, we pass in 4H in arg2. -; Arg3 is a pointer to the return dwbuffer -NESTED_ENTRY getextcpuid, _TEXT - push_nonvol_reg rbx - push_nonvol_reg rsi - END_PROLOGUE - - mov eax, edx ; second arg (input to EAX) - mov rsi, r8 ; third arg (pointer to return dwbuffer) - cpuid - mov [rsi+ 0], eax - mov [rsi+ 4], ebx - mov [rsi+ 8], ecx - mov [rsi+12], edx - pop rsi - pop rbx - - ret -NESTED_END getextcpuid, _TEXT - ; EXTERN_C void moveOWord(LPVOID* src, LPVOID* target); ; diff --git a/src/coreclr/src/vm/amd64/unixstubs.cpp b/src/coreclr/src/vm/amd64/unixstubs.cpp index 1de9b9a5b9d1..517eea98f6b6 100644 --- a/src/coreclr/src/vm/amd64/unixstubs.cpp +++ b/src/coreclr/src/vm/amd64/unixstubs.cpp @@ -10,35 +10,26 @@ extern "C" PORTABILITY_ASSERT("Implement for PAL"); } - DWORD getcpuid(DWORD arg, unsigned char result[16]) + void __cpuid(int cpuInfo[4], int function_id) { - DWORD eax; - __asm(" xor %%ecx, %%ecx\n" \ - " cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax) /*output in eax*/\ - : "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\ - : "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; + // Based on the Clang implementation provided in cpuid.h: + // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h + + __asm(" cpuid\n" \ + : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \ + : "0"(function_id) + ); } - DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) + void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id) { - DWORD eax; + // Based on the Clang implementation provided in cpuid.h: + // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h + __asm(" cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax) /*output in eax*/\ - : "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\ - : "rbx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; + : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \ + : "0"(function_id), "2"(subFunction_id) + ); } DWORD xmmYmmStateSupport() diff --git a/src/coreclr/src/vm/cgensys.h b/src/coreclr/src/vm/cgensys.h index 7c732316695e..216729938ae1 100644 --- a/src/coreclr/src/vm/cgensys.h +++ b/src/coreclr/src/vm/cgensys.h @@ -95,21 +95,22 @@ inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo) #endif // !TARGET_X86 #if (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE) -extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); -extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]); +#ifdef TARGET_UNIX +// MSVC directly defines intrinsics for __cpuid and __cpuidex matching the below signatures +// We define matching signatures for use on Unix platforms. + +extern "C" void __stdcall __cpuid(int cpuInfo[4], int function_id); +extern "C" void __stdcall __cpuidex(int cpuInfo[4], int function_id, int subFunction_id); +#endif // TARGET_UNIX extern "C" DWORD __stdcall xmmYmmStateSupport(); #endif inline bool TargetHasAVXSupport() { #if (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE) - unsigned char buffer[16]; - // All x86/AMD64 targets support cpuid. - (void) getcpuid(1, buffer); - // getcpuid executes cpuid with eax set to its first argument, and ecx cleared. - // It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[]. - // The AVX feature is ECX bit 28. - return ((buffer[11] & 0x10) != 0); + int cpuInfo[4]; + __cpuid(cpuInfo, 0x00000001); // All x86/AMD64 targets support cpuid. + return ((cpuInfo[3] & (1 << 28)) != 0); // The AVX feature is ECX bit 28. #endif // (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE) return false; } diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index a04894fa77ed..ea39db725e60 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1308,115 +1308,110 @@ void EEJitManager::SetCpuInfo() // We will set the following flags: // CORJIT_FLAG_USE_SSE2 is required - // SSE - EDX bit 25 (buffer[15] & 0x02) - // SSE2 - EDX bit 26 (buffer[15] & 0x04) + // SSE - EDX bit 25 + // SSE2 - EDX bit 26 + // CORJIT_FLAG_USE_AES + // CORJIT_FLAG_USE_SSE2 + // AES - ECX bit 25 + // CORJIT_FLAG_USE_PCLMULQDQ + // CORJIT_FLAG_USE_SSE2 + // PCLMULQDQ - ECX bit 1 // CORJIT_FLAG_USE_SSE3 if the following feature bits are set (input EAX of 1) // CORJIT_FLAG_USE_SSE2 - // SSE3 - ECX bit 0 (buffer[8] & 0x01) + // SSE3 - ECX bit 0 // CORJIT_FLAG_USE_SSSE3 if the following feature bits are set (input EAX of 1) // CORJIT_FLAG_USE_SSE3 - // SSSE3 - ECX bit 9 (buffer[9] & 0x02) + // SSSE3 - ECX bit 9 // CORJIT_FLAG_USE_SSE41 if the following feature bits are set (input EAX of 1) // CORJIT_FLAG_USE_SSSE3 - // SSE4.1 - ECX bit 19 (buffer[10] & 0x08) + // SSE4.1 - ECX bit 19 // CORJIT_FLAG_USE_SSE42 if the following feature bits are set (input EAX of 1) // CORJIT_FLAG_USE_SSE41 - // SSE4.2 - ECX bit 20 (buffer[10] & 0x10) + // SSE4.2 - ECX bit 20 // CORJIT_FLAG_USE_POPCNT if the following feature bits are set (input EAX of 1) // CORJIT_FLAG_USE_SSE42 - // POPCNT - ECX bit 23 (buffer[10] & 0x80) + // POPCNT - ECX bit 23 // CORJIT_FLAG_USE_AVX if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1: // CORJIT_FLAG_USE_SSE42 - // OSXSAVE - ECX bit 27 (buffer[11] & 0x08) + // OSXSAVE - ECX bit 27 + // AVX - ECX bit 28 // XGETBV - XCR0[2:1] 11b - // AVX - ECX bit 28 (buffer[11] & 0x10) // CORJIT_FLAG_USE_FMA if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1: // CORJIT_FLAG_USE_AVX - // FMA - ECX bit 12 (buffer[9] & 0x10) + // FMA - ECX bit 12 // CORJIT_FLAG_USE_AVX2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): // CORJIT_FLAG_USE_AVX - // AVX2 - EBX bit 5 (buffer[4] & 0x20) + // AVX2 - EBX bit 5 // CORJIT_FLAG_USE_AVX_512 is not currently set, but defined so that it can be used in future without - // CORJIT_FLAG_USE_AES - // CORJIT_FLAG_USE_SSE2 - // AES - ECX bit 25 (buffer[11] & 0x01) - // CORJIT_FLAG_USE_PCLMULQDQ - // CORJIT_FLAG_USE_SSE2 - // PCLMULQDQ - ECX bit 1 (buffer[8] & 0x01) // CORJIT_FLAG_USE_BMI1 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): - // BMI1 - EBX bit 3 (buffer[4] & 0x08) + // BMI1 - EBX bit 3 // CORJIT_FLAG_USE_BMI2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): - // BMI2 - EBX bit 8 (buffer[5] & 0x01) + // BMI2 - EBX bit 8 // CORJIT_FLAG_USE_LZCNT if the following feature bits are set (input EAX of 80000001H) - // LZCNT - ECX bit 5 (buffer[8] & 0x20) + // LZCNT - ECX bit 5 // synchronously updating VM and JIT. - unsigned char buffer[16]; - DWORD maxCpuId = getcpuid(0, buffer); + int cpuidInfo[4]; + + __cpuid(cpuidInfo, 0x00000000); + uint32_t maxCpuId = static_cast(cpuidInfo[0]); if (maxCpuId >= 1) { - // getcpuid executes cpuid with eax set to its first argument, and ecx cleared. - // It returns the resulting eax in buffer[0-3], ebx in buffer[4-7], ecx in buffer[8-11], - // and edx in buffer[12-15]. - - (void) getcpuid(1, buffer); + __cpuid(cpuidInfo, 0x00000001); - // If SSE/SSE2 is not enabled, there is no point in checking the rest. - // SSE is bit 25 of EDX (buffer[15] & 0x02) - // SSE2 is bit 26 of EDX (buffer[15] & 0x04) - - if ((buffer[15] & 0x06) == 0x06) // SSE & SSE2 + if (((cpuidInfo[3] & (1 << 25)) != 0) && ((cpuidInfo[3] & (1 << 26)) != 0)) // SSE & SSE2 { CPUCompileFlags.Set(InstructionSet_SSE); CPUCompileFlags.Set(InstructionSet_SSE2); - if ((buffer[11] & 0x02) != 0) // AESNI + + if ((cpuidInfo[2] & (1 << 25)) != 0) // AESNI { CPUCompileFlags.Set(InstructionSet_AES); } - if ((buffer[8] & 0x02) != 0) // PCLMULQDQ + if ((cpuidInfo[2] & (1 << 1)) != 0) // PCLMULQDQ { CPUCompileFlags.Set(InstructionSet_PCLMULQDQ); } - if ((buffer[8] & 0x01) != 0) // SSE3 + if ((cpuidInfo[2] & (1 << 0)) != 0) // SSE3 { CPUCompileFlags.Set(InstructionSet_SSE3); - if ((buffer[9] & 0x02) != 0) // SSSE3 + if ((cpuidInfo[2] & (1 << 9)) != 0) // SSSE3 { CPUCompileFlags.Set(InstructionSet_SSSE3); - if ((buffer[10] & 0x08) != 0) // SSE4.1 + if ((cpuidInfo[2] & (1 << 19)) != 0) // SSE4.1 { CPUCompileFlags.Set(InstructionSet_SSE41); - if ((buffer[10] & 0x10) != 0) // SSE4.2 + if ((cpuidInfo[2] & (1 << 20)) != 0) // SSE4.2 { CPUCompileFlags.Set(InstructionSet_SSE42); - if ((buffer[10] & 0x80) != 0) // POPCNT + if ((cpuidInfo[2] & (1 << 23)) != 0) // POPCNT { CPUCompileFlags.Set(InstructionSet_POPCNT); } - if ((buffer[11] & 0x18) == 0x18) // AVX & OSXSAVE + if (((cpuidInfo[2] & (1 << 27)) != 0) && ((cpuidInfo[2] & (1 << 28)) != 0)) // OSXSAVE & AVX { - if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1)) + if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1)) // XGETBV == 11 { CPUCompileFlags.Set(InstructionSet_AVX); - if ((buffer[9] & 0x10) != 0) // FMA + if ((cpuidInfo[2] & (1 << 12)) != 0) // FMA { CPUCompileFlags.Set(InstructionSet_FMA); } if (maxCpuId >= 0x07) { - (void) getextcpuid(0, 0x07, buffer); + __cpuidex(cpuidInfo, 0x00000007, 0x00000000); - if ((buffer[4] & 0x20) != 0) // AVX2 + if ((cpuidInfo[1] & (1 << 5)) != 0) // AVX2 { CPUCompileFlags.Set(InstructionSet_AVX2); } @@ -1443,31 +1438,28 @@ void EEJitManager::SetCpuInfo() if (maxCpuId >= 0x07) { - (void)getextcpuid(0, 0x07, buffer); + __cpuidex(cpuidInfo, 0x00000007, 0x00000000); - if ((buffer[4] & 0x08) != 0) // BMI1 + if ((cpuidInfo[2] & (1 << 3)) != 0) // BMI1 { CPUCompileFlags.Set(InstructionSet_BMI1); } - if ((buffer[5] & 0x01) != 0) // BMI2 + if ((cpuidInfo[2] & (1 << 8)) != 0) // BMI2 { CPUCompileFlags.Set(InstructionSet_BMI2); } } } - DWORD maxCpuIdEx = getcpuid(0x80000000, buffer); + __cpuid(cpuidInfo, 0x80000000); + uint32_t maxCpuIdEx = static_cast(cpuidInfo[0]); if (maxCpuIdEx >= 0x80000001) { - // getcpuid executes cpuid with eax set to its first argument, and ecx cleared. - // It returns the resulting eax in buffer[0-3], ebx in buffer[4-7], ecx in buffer[8-11], - // and edx in buffer[12-15]. - - (void) getcpuid(0x80000001, buffer); + __cpuid(cpuidInfo, 0x80000001); - if ((buffer[8] & 0x20) != 0) // LZCNT + if ((cpuidInfo[3] & (1 << 5)) != 0) // LZCNT { CPUCompileFlags.Set(InstructionSet_LZCNT); } diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index e4896f2000f6..f1827fa3bd97 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -1088,6 +1088,12 @@ FCFuncStart(gPalOleAut32Funcs) FCFuncEnd() #endif +#if defined(TARGET_X86) || defined(TARGET_AMD64) +FCFuncStart(gX86BaseFuncs) + QCFuncElement("__cpuidex", SystemNative::X86BaseCpuId) +FCFuncEnd() +#endif // defined(TARGET_X86) || defined(TARGET_AMD64) + #ifdef FEATURE_COMINTEROP // @@ -1235,6 +1241,10 @@ FCClassElement("WaitHandle", "System.Threading", gWaitHandleFuncs) FCClassElement("WeakReference", "System", gWeakReferenceFuncs) FCClassElement("WeakReference`1", "System", gWeakReferenceOfTFuncs) +#if defined(TARGET_X86) || defined(TARGET_AMD64) +FCClassElement("X86Base", "System.Runtime.Intrinsics.X86", gX86BaseFuncs) +#endif // defined(TARGET_X86) || defined(TARGET_AMD64) + #if defined(FEATURE_EVENTSOURCE_XPLAT) FCClassElement("XplatEventLogger", "System.Diagnostics.Tracing", gEventLogger) #endif //defined(FEATURE_EVENTSOURCE_XPLAT) diff --git a/src/coreclr/src/vm/i386/cgenx86.cpp b/src/coreclr/src/vm/i386/cgenx86.cpp index 58cbf0ffa001..75ff1b7dff17 100644 --- a/src/coreclr/src/vm/i386/cgenx86.cpp +++ b/src/coreclr/src/vm/i386/cgenx86.cpp @@ -1139,54 +1139,6 @@ void ResumeAtJit(PCONTEXT pContext, LPVOID oldESP) #ifndef TARGET_UNIX #pragma warning(push) #pragma warning(disable: 4035) -extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]) -{ - LIMITED_METHOD_CONTRACT - - __asm - { - push ebx - push esi - mov eax, arg - cpuid - mov esi, result - mov [esi+ 0], eax - mov [esi+ 4], ebx - mov [esi+ 8], ecx - mov [esi+12], edx - pop esi - pop ebx - } -} - -// The following function uses Deterministic Cache Parameter leafs to determine the cache hierarchy information on Prescott & Above platforms. -// This function takes 3 arguments: -// Arg1 is an input to ECX. Used as index to specify which cache level to return infoformation on by CPUID. -// Arg2 is an input to EAX. For deterministic code enumeration, we pass in 4H in arg2. -// Arg3 is a pointer to the return buffer -// No need to check whether or not CPUID is supported because we have already called CPUID with success to come here. - -extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) -{ - LIMITED_METHOD_CONTRACT - - __asm - { - push ebx - push esi - mov ecx, arg1 - mov eax, arg2 - cpuid - mov esi, result - mov [esi+ 0], eax - mov [esi+ 4], ebx - mov [esi+ 8], ecx - mov [esi+12], edx - pop esi - pop ebx - } -} - extern "C" DWORD __stdcall xmmYmmStateSupport() { // No CONTRACT @@ -1207,41 +1159,30 @@ extern "C" DWORD __stdcall xmmYmmStateSupport() done: } } - #pragma warning(pop) #else // !TARGET_UNIX -extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]) +void __cpuid(int cpuInfo[4], int function_id) { - DWORD eax; - __asm(" xor %%ecx, %%ecx\n" \ - " cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax) /*output in eax*/\ - : "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\ - : "ebx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; + // Based on the Clang implementation provided in cpuid.h: + // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h + + __asm(" cpuid" + : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \ + : "0"(function_id) + ); } -extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) +void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id) { - DWORD eax; - DWORD ecx; - __asm(" cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax), "=c"(ecx) /*output in eax, ecx is rewritten*/\ - : "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\ - : "ebx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; + // Based on the Clang implementation provided in cpuid.h: + // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h + + __asm(" cpuid" + : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \ + : "0"(function_id), "2"(subFunction_id) + ); } extern "C" DWORD __stdcall xmmYmmStateSupport() diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs index 045a8a273b6d..56ff44adb7d9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs @@ -11,17 +11,17 @@ namespace System.Runtime.Intrinsics.X86 /// This class provides access to Intel BMI1 hardware instructions via intrinsics /// [CLSCompliant(false)] - public abstract class Bmi1 // : X86Base + public abstract class Bmi1 : X86Base { internal Bmi1() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } /// /// unsigned __int64 _andn_u64 (unsigned __int64 a, unsigned __int64 b) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.cs index 535d5f775720..82e501ca97de 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi1.cs @@ -10,18 +10,18 @@ namespace System.Runtime.Intrinsics.X86 /// [Intrinsic] [CLSCompliant(false)] - public abstract class Bmi1 // : X86Base + public abstract class Bmi1 : X86Base { internal Bmi1() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } [Intrinsic] - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } /// /// unsigned __int64 _andn_u64 (unsigned __int64 a, unsigned __int64 b) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs index 08a4204301a5..8c1a66ec9706 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs @@ -11,17 +11,17 @@ namespace System.Runtime.Intrinsics.X86 /// This class provides access to Intel BMI2 hardware instructions via intrinsics /// [CLSCompliant(false)] - public abstract class Bmi2 // : X86Base + public abstract class Bmi2 : X86Base { internal Bmi2() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } /// /// unsigned __int64 _bzhi_u64 (unsigned __int64 a, unsigned int index) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.cs index 81dff57da5a0..95104e6d2b92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Bmi2.cs @@ -10,18 +10,18 @@ namespace System.Runtime.Intrinsics.X86 /// [Intrinsic] [CLSCompliant(false)] - public abstract class Bmi2 // : X86Base + public abstract class Bmi2 : X86Base { internal Bmi2() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } [Intrinsic] - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } /// /// unsigned __int64 _bzhi_u64 (unsigned __int64 a, unsigned int index) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs index a800021bbab4..1c2eed20a3c8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs @@ -10,17 +10,17 @@ namespace System.Runtime.Intrinsics.X86 /// This class provides access to Intel LZCNT hardware instructions via intrinsics /// [CLSCompliant(false)] - public abstract class Lzcnt // : X86Base + public abstract class Lzcnt : X86Base { internal Lzcnt() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } /// /// unsigned __int64 _lzcnt_u64 (unsigned __int64 a) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs index d6d278c5d4c2..55e8f737de8f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs @@ -10,18 +10,18 @@ namespace System.Runtime.Intrinsics.X86 /// [Intrinsic] [CLSCompliant(false)] - public abstract class Lzcnt // : X86Base + public abstract class Lzcnt : X86Base { internal Lzcnt() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } [Intrinsic] - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } /// /// unsigned __int64 _lzcnt_u64 (unsigned __int64 a) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs index 00d3c684294f..1d92f91621b6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs @@ -11,17 +11,17 @@ namespace System.Runtime.Intrinsics.X86 /// This class provides access to Intel SSE hardware instructions via intrinsics /// [CLSCompliant(false)] - public abstract class Sse // : X86Base + public abstract class Sse : X86Base { internal Sse() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { [Intrinsic] get { return false; } } + public static new bool IsSupported { [Intrinsic] get { return false; } } /// /// __int64 _mm_cvtss_si64 (__m128 a) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.cs index 1e88751c3687..129f2ecbd09a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Sse.cs @@ -10,18 +10,18 @@ namespace System.Runtime.Intrinsics.X86 /// [Intrinsic] [CLSCompliant(false)] - public abstract class Sse // : X86Base + public abstract class Sse : X86Base { internal Sse() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } [Intrinsic] - public abstract class X64 // : X86Base.X64 + public new abstract class X64 : X86Base.X64 { internal X64() { } - public static bool IsSupported { get => IsSupported; } + public static new bool IsSupported { get => IsSupported; } /// /// __int64 _mm_cvtss_si64 (__m128 a) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.PlatformNotSupported.cs index a0e0e68fbd03..261ac82076ec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.PlatformNotSupported.cs @@ -9,13 +9,13 @@ namespace System.Runtime.Intrinsics.X86 /// /// This class provides access to the x86 base hardware instructions via intrinsics /// - internal abstract class X86Base + public abstract partial class X86Base { internal X86Base() { } public static bool IsSupported { [Intrinsic] get => false; } - internal abstract class X64 + public abstract class X64 { internal X64() { } @@ -65,5 +65,11 @@ internal X64() { } /// Its functionality is exposed in the public class. /// internal static uint BitScanReverse(uint value) { throw new PlatformNotSupportedException(); } + + /// + /// void __cpuidex(int cpuInfo[4], int function_id, int subfunction_id); + /// CPUID + /// + public static (int Eax, int Ebx, int Ecx, int Edx) CpuId(int functionId, int subFunctionId) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs index de49813d9de0..7f7576be50ad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Runtime.Intrinsics.X86 { @@ -9,13 +10,17 @@ namespace System.Runtime.Intrinsics.X86 /// This class provides access to the x86 base hardware instructions via intrinsics /// [Intrinsic] - internal abstract class X86Base + public abstract partial class X86Base { + internal X86Base() { } + public static bool IsSupported { get => IsSupported; } [Intrinsic] - internal abstract class X64 + public abstract class X64 { + internal X64() { } + public static bool IsSupported { get => IsSupported; } /// @@ -62,5 +67,16 @@ internal abstract class X64 /// Its functionality is exposed in the public class. /// internal static uint BitScanReverse(uint value) => BitScanReverse(value); + + /// + /// void __cpuidex(int cpuInfo[4], int function_id, int subfunction_id); + /// CPUID + /// + public static unsafe (int Eax, int Ebx, int Ecx, int Edx) CpuId(int functionId, int subFunctionId) + { + int* cpuInfo = stackalloc int[4]; + __cpuidex(cpuInfo, functionId, subFunctionId); + return (cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]); + } } } diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 4fc9a2dab9e8..fbb78cb5533f 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -3367,10 +3367,10 @@ internal X64() { } } } [System.CLSCompliantAttribute(false)] - public abstract partial class Bmi1 + public abstract partial class Bmi1 : System.Runtime.Intrinsics.X86.X86Base { internal Bmi1() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static uint AndNot(uint left, uint right) { throw null; } public static uint BitFieldExtract(uint value, byte start, byte length) { throw null; } public static uint BitFieldExtract(uint value, ushort control) { throw null; } @@ -3378,10 +3378,10 @@ internal Bmi1() { } public static uint GetMaskUpToLowestSetBit(uint value) { throw null; } public static uint ResetLowestSetBit(uint value) { throw null; } public static uint TrailingZeroCount(uint value) { throw null; } - public abstract partial class X64 + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.X86Base.X64 { internal X64() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static ulong AndNot(ulong left, ulong right) { throw null; } public static ulong BitFieldExtract(ulong value, byte start, byte length) { throw null; } public static ulong BitFieldExtract(ulong value, ushort control) { throw null; } @@ -3392,19 +3392,19 @@ internal X64() { } } } [System.CLSCompliantAttribute(false)] - public abstract partial class Bmi2 + public abstract partial class Bmi2 : System.Runtime.Intrinsics.X86.X86Base { internal Bmi2() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static uint MultiplyNoFlags(uint left, uint right) { throw null; } public unsafe static uint MultiplyNoFlags(uint left, uint right, uint* low) { throw null; } public static uint ParallelBitDeposit(uint value, uint mask) { throw null; } public static uint ParallelBitExtract(uint value, uint mask) { throw null; } public static uint ZeroHighBits(uint value, uint index) { throw null; } - public abstract partial class X64 + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.X86Base.X64 { internal X64() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static ulong MultiplyNoFlags(ulong left, ulong right) { throw null; } public unsafe static ulong MultiplyNoFlags(ulong left, ulong right, ulong* low) { throw null; } public static ulong ParallelBitDeposit(ulong value, ulong mask) { throw null; } @@ -3491,15 +3491,15 @@ internal X64() { } } } [System.CLSCompliantAttribute(false)] - public abstract partial class Lzcnt + public abstract partial class Lzcnt : System.Runtime.Intrinsics.X86.X86Base { internal Lzcnt() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static uint LeadingZeroCount(uint value) { throw null; } - public abstract partial class X64 + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.X86Base.X64 { internal X64() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static ulong LeadingZeroCount(ulong value) { throw null; } } } @@ -3530,10 +3530,10 @@ internal X64() { } } } [System.CLSCompliantAttribute(false)] - public abstract partial class Sse + public abstract partial class Sse : System.Runtime.Intrinsics.X86.X86Base { internal Sse() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static System.Runtime.Intrinsics.Vector128 Add(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 And(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } @@ -3621,10 +3621,10 @@ public unsafe static void StoreScalar(float* address, System.Runtime.Intrinsics. public static System.Runtime.Intrinsics.Vector128 UnpackHigh(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 UnpackLow(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Xor(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public abstract partial class X64 + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.X86Base.X64 { internal X64() { } - public static bool IsSupported { get { throw null; } } + public static new bool IsSupported { get { throw null; } } public static System.Runtime.Intrinsics.Vector128 ConvertScalarToVector128Single(System.Runtime.Intrinsics.Vector128 upper, long value) { throw null; } public static long ConvertToInt64(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static long ConvertToInt64WithTruncation(System.Runtime.Intrinsics.Vector128 value) { throw null; } @@ -4183,4 +4183,16 @@ internal X64() { } public static new bool IsSupported { get { throw null; } } } } + [System.CLSCompliantAttribute(false)] + public abstract partial class X86Base + { + internal X86Base() { } + public static bool IsSupported { get { throw null; } } + public static (int Eax, int Ebx, int Ecx, int Edx) CpuId(int functionId, int subFunctionId) { throw null; } + public abstract partial class X64 + { + internal X64() { } + public static bool IsSupported { get { throw null; } } + } + } } diff --git a/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj index 95e1e72845ad..e2435e591fa6 100644 --- a/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -266,6 +266,7 @@ + diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.Mono.cs new file mode 100644 index 000000000000..a4acdc99f350 --- /dev/null +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.Mono.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.Intrinsics.X86 +{ + public abstract partial class X86Base + { + private static unsafe void __cpuidex(int* cpuInfo, int functionId, int subFunctionId) + { + throw new PlatformNotSupportedException(); + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId.cs b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId.cs new file mode 100644 index 000000000000..39dd182e4e0b --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId.cs @@ -0,0 +1,186 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; + +namespace IntelHardwareIntrinsicTest +{ + class Program + { + const int Pass = 100; + const int Fail = 0; + + static unsafe int Main(string[] args) + { + int testResult = Pass; + + if (!X86Base.IsSupported) + { + return testResult; + } + + (int eax, int ebx, int ecx, int edx) = X86Base.CpuId(0x00000000, 0x00000000); + + bool isAuthenticAmd = (ebx == 0x68747541) && (ecx == 0x444D4163) && (edx == 0x69746E65); + bool isGenuineIntel = (ebx == 0x756E6547) && (ecx == 0x6C65746E) && (edx == 0x49656E69); + + if (!isAuthenticAmd && !isGenuineIntel) + { + // CPUID checks are vendor specific and aren't guaranteed to match up, even across Intel/AMD + // as such, we limit ourselves to just AuthenticAMD and GenuineIntel right now. Any other + // vendors would need to be validated against the checks below and added to the list as necessary. + + // An example of a difference is Intel/AMD for LZCNT. While the same underlying bit is used to + // represent presence of the LZCNT instruction, AMD began using this bit around 2007 for its + // ABM instruction set, which indicates LZCNT and POPCNT. Intel introduced a separate bit for + // POPCNT and didn't actually implement LZCNT and begin using the LZCNT bit until 2013. So + // while everything happens to line up today, it doesn't always and may not always do so. + + Console.WriteLine($"Unrecognized CPU vendor: EBX: {ebx:X8}, ECX: {ecx:X8}, EDX: {edx:X8}"); + testResult = Fail; + } + + int maxFunctionId = eax; + + if ((maxFunctionId < 0x00000001) || (Environment.GetEnvironmentVariable("COMPlus_EnableHWIntrinsic") is null)) + { + return testResult; + } + + (eax, ebx, ecx, edx) = X86Base.CpuId(0x00000001, 0x00000000); + + if (IsBitIncorrect(ecx, 28, Avx.IsSupported, "AVX")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:AVX != Avx.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 25, Aes.IsSupported, "AES")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:AES != Aes.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 23, Popcnt.IsSupported, "POPCNT")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:POPCNT != Popcnt.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 20, Sse42.IsSupported, "SSE42")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSE42 != Sse42.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 19, Sse41.IsSupported, "SSE41")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSE41 != Sse41.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 12, Fma.IsSupported, "FMA")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:FMA != Fma.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 9, Ssse3.IsSupported, "SSSE3")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSSE3 != Ssse3.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 1, Pclmulqdq.IsSupported, "PCLMULQDQ")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:PCLMULQDQ != Pclmulqdq.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ecx, 0, Sse3.IsSupported, "SSE3")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSE3 != Sse3.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(edx, 26, Sse2.IsSupported, "SSE2")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSE2 != Sse2.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(edx, 25, Sse.IsSupported, "SSE")) + { + Console.WriteLine("CPUID Fn0000_0001_ECX:SSE != Sse.IsSupported"); + testResult = Fail; + } + + if (maxFunctionId < 0x00000007) + { + return testResult; + } + + (eax, ebx, ecx, edx) = X86Base.CpuId(0x00000007, 0x00000000); + + if (IsBitIncorrect(ebx, 8, Bmi2.IsSupported, "BMI2")) + { + Console.WriteLine("CPUID Fn0000_0007_EBX:BMI2 != Bmi2.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ebx, 5, Avx2.IsSupported, "AVX2")) + { + Console.WriteLine("CPUID Fn0000_0007_EBX:AVX2 != Avx2.IsSupported"); + testResult = Fail; + } + + if (IsBitIncorrect(ebx, 3, Bmi1.IsSupported, "BMI1")) + { + Console.WriteLine("CPUID Fn0000_0001_EBX:BMI1 != Bmi1.IsSupported"); + testResult = Fail; + } + + (eax, ebx, ecx, edx) = X86Base.CpuId(unchecked((int)0x80000000), 0x00000000); + + if (isAuthenticAmd && ((ebx != 0x68747541) || (ecx != 0x444D4163) || (edx != 0x69746E65))) + { + Console.WriteLine("CPUID Fn8000_0000 reported different vendor info from Fn0000_0000"); + testResult = Fail; + } + + if (isGenuineIntel && ((ebx != 0x756E6547) && (ecx != 0x6C65746E) && (edx != 0x6C656E69))) + { + Console.WriteLine("CPUID Fn8000_0000 reported different vendor info from Fn0000_0000"); + testResult = Fail; + } + + int maxFunctionIdEx = eax; + + if (maxFunctionIdEx < 0x00000001) + { + return testResult; + } + + (eax, ebx, ecx, edx) = X86Base.CpuId(unchecked((int)0x80000001), 0x00000000); + + if (IsBitIncorrect(ecx, 5, Lzcnt.IsSupported, "LZCNT")) + { + Console.WriteLine("CPUID Fn8000_0001_ECX:LZCNT != Lzcnt.IsSupported"); + testResult = Fail; + } + + return testResult; + } + + static bool IsBitIncorrect(int register, int bitNumber, bool expectedResult, string name) + { + return ((register & (1 << bitNumber)) != ((expectedResult ? 1 : 0) << bitNumber)) + && (Environment.GetEnvironmentVariable($"COMPlus_Enable{name}") is null); + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_r.csproj new file mode 100644 index 000000000000..8c3ea60df00c --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_r.csproj @@ -0,0 +1,13 @@ + + + Exe + true + + + Embedded + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_ro.csproj new file mode 100644 index 000000000000..64875d4c153b --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId_ro.csproj @@ -0,0 +1,13 @@ + + + Exe + true + + + Embedded + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs index 7cea12d04c9a..cb06c86edf37 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs @@ -30,6 +30,7 @@ public static int Main() TestLibrary.TestFramework.LogInformation($" SSE4.1: {Sse41.IsSupported}"); TestLibrary.TestFramework.LogInformation($" SSE4.2: {Sse42.IsSupported}"); TestLibrary.TestFramework.LogInformation($" SSSE3: {Ssse3.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" X86Base: {X86Base.IsSupported}"); TestLibrary.TestFramework.LogInformation("Supported x64 ISAs:"); TestLibrary.TestFramework.LogInformation($" AES.X64: {X86Aes.X64.IsSupported}"); @@ -47,6 +48,7 @@ public static int Main() TestLibrary.TestFramework.LogInformation($" SSE4.1.X64: {Sse41.X64.IsSupported}"); TestLibrary.TestFramework.LogInformation($" SSE4.2.X64: {Sse42.X64.IsSupported}"); TestLibrary.TestFramework.LogInformation($" SSSE3.X64: {Ssse3.X64.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" X86Base.X64: {X86Base.X64.IsSupported}"); TestLibrary.TestFramework.LogInformation("Supported Arm ISAs:"); TestLibrary.TestFramework.LogInformation($" AdvSimd: {AdvSimd.IsSupported}"); @@ -240,6 +242,7 @@ public static bool ValidateX86() { bool succeeded = true; + succeeded &= ValidateX86Base(); succeeded &= ValidateSse(); succeeded &= ValidateSse2(); succeeded &= ValidateSse3(); @@ -258,19 +261,37 @@ public static bool ValidateX86() return succeeded; + static bool ValidateX86Base() + { + bool succeeded = true; + + if (X86Base.IsSupported) + { + succeeded &= (RuntimeInformation.OSArchitecture == Architecture.X86) || (RuntimeInformation.OSArchitecture == Architecture.X64); + } + + if (X86Base.X64.IsSupported) + { + succeeded &= X86Base.IsSupported; + succeeded &= (RuntimeInformation.OSArchitecture == Architecture.X64); + } + + return succeeded; + } + static bool ValidateSse() { bool succeeded = true; if (Sse.IsSupported) { - succeeded &= (RuntimeInformation.OSArchitecture == Architecture.X86) || (RuntimeInformation.OSArchitecture == Architecture.X64); + succeeded &= X86Base.IsSupported; } if (Sse.X64.IsSupported) { succeeded &= Sse.IsSupported; - succeeded &= (RuntimeInformation.OSArchitecture == Architecture.X64); + succeeded &= X86Base.X64.IsSupported; } return succeeded; From 8140826a72663ed8c2724d2099dd65d5ef689f18 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 5 Aug 2020 15:22:51 -0700 Subject: [PATCH 277/755] Build Globalization native shim as C++ and don't define __typeof (#40352) * Build Globalization native shim as C++ and don't define __typeof intrinsic * PR Feedback, use TYPEOF in all shims --- .../Native/Unix/Common/pal_compiler.h | 8 ++++++ .../CMakeLists.txt | 4 +++ .../System.Globalization.Native/pal_icushim.c | 6 ++--- .../pal_icushim_internal.h | 6 +---- .../System.Native/pal_networkstatistics.c | 4 +-- .../opensslshim.c | 26 +++++++++---------- .../opensslshim.h | 13 +++++----- 7 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/libraries/Native/Unix/Common/pal_compiler.h b/src/libraries/Native/Unix/Common/pal_compiler.h index 42e638cef11d..c53dc3996fed 100644 --- a/src/libraries/Native/Unix/Common/pal_compiler.h +++ b/src/libraries/Native/Unix/Common/pal_compiler.h @@ -33,3 +33,11 @@ #define EXTERN_C extern #endif // __cplusplus #endif // EXTERN_C + +#ifndef TYPEOF +#ifdef __cplusplus +#define TYPEOF decltype +#else +#define TYPEOF __typeof +#endif // __cplusplus +#endif // TYPEOF diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt index b08f49e88622..b42625298705 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt @@ -59,6 +59,10 @@ set(NATIVEGLOBALIZATION_SOURCES entrypoints.c ) +if (MSVC) + set_source_files_properties(${NATIVEGLOBALIZATION_SOURCES} PROPERTIES LANGUAGE CXX) +endif() + include_directories("../Common") if (GEN_SHARED_LIB) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c index d4780a2c06f5..43e1d4fb370b 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c @@ -19,7 +19,7 @@ #include "pal_icushim.h" // Define pointers to all the used ICU functions -#define PER_FUNCTION_BLOCK(fn, lib) __typeof(fn)* fn##_ptr; +#define PER_FUNCTION_BLOCK(fn, lib) TYPEOF(fn)* fn##_ptr; FOR_ALL_ICU_FUNCTIONS #undef PER_FUNCTION_BLOCK @@ -43,7 +43,7 @@ static void* libicui18n = NULL; #define PER_FUNCTION_BLOCK(fn, lib) \ c_static_assert_msg((sizeof(#fn) + MaxICUVersionStringWithSuffixLength + 1) <= sizeof(symbolName), "The symbolName is too small for symbol " #fn); \ sprintf(symbolName, #fn "%s", symbolVersion); \ - fn##_ptr = (__typeof(fn)*)dlsym(lib, symbolName); \ + fn##_ptr = (TYPEOF(fn)*)dlsym(lib, symbolName); \ if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from " #lib "\nError: %s\n", symbolName, dlerror()); abort(); } static int FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion, char* suffix) @@ -90,7 +90,7 @@ static int FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbo #define PER_FUNCTION_BLOCK(fn, lib) \ sprintf_s(symbolName, SYMBOL_NAME_SIZE, #fn "%s", symbolVersion); \ - fn##_ptr = (__typeof(fn)*)GetProcAddress((HMODULE)lib, symbolName); \ + fn##_ptr = (TYPEOF(fn)*)GetProcAddress((HMODULE)lib, symbolName); \ if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from " #lib "\nError: %u\n", symbolName, GetLastError()); abort(); } static int FindICULibs() diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h index fcb669e0fc6a..46d8064b2d1a 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h @@ -46,10 +46,6 @@ #include "icu.h" -#ifndef __typeof -#define __typeof decltype -#endif - #define HAVE_SET_MAX_VARIABLE 1 #define UDAT_STANDALONE_SHORTER_WEEKDAYS 1 @@ -180,7 +176,7 @@ FOR_ALL_OS_CONDITIONAL_ICU_FUNCTIONS // Declare pointers to all the used ICU functions -#define PER_FUNCTION_BLOCK(fn, lib) EXTERN_C __typeof(fn)* fn##_ptr; +#define PER_FUNCTION_BLOCK(fn, lib) EXTERN_C TYPEOF(fn)* fn##_ptr; FOR_ALL_ICU_FUNCTIONS #undef PER_FUNCTION_BLOCK diff --git a/src/libraries/Native/Unix/System.Native/pal_networkstatistics.c b/src/libraries/Native/Unix/System.Native/pal_networkstatistics.c index 142203293c44..4a7c394109e7 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networkstatistics.c +++ b/src/libraries/Native/Unix/System.Native/pal_networkstatistics.c @@ -193,8 +193,8 @@ int32_t SystemNative_GetIcmpv4GlobalStatistics(Icmpv4GlobalStatistics* retStats) return -1; } - __typeof(systemStats.icps_inhist[0])* inHist = systemStats.icps_inhist; - __typeof(systemStats.icps_outhist[0])* outHist = systemStats.icps_outhist; + TYPEOF(systemStats.icps_inhist[0])* inHist = systemStats.icps_inhist; + TYPEOF(systemStats.icps_outhist[0])* outHist = systemStats.icps_outhist; retStats->AddressMaskRepliesReceived = inHist[ICMP_MASKREPLY]; retStats->AddressMaskRepliesSent = outHist[ICMP_MASKREPLY]; diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c index 03e2c59fb707..8085b0258ca6 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c @@ -11,12 +11,12 @@ #include "opensslshim.h" // Define pointers to all the used OpenSSL functions -#define REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr; -#define NEW_REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr; -#define LIGHTUP_FUNCTION(fn) __typeof(fn) fn##_ptr; -#define FALLBACK_FUNCTION(fn) __typeof(fn) fn##_ptr; -#define RENAMED_FUNCTION(fn,oldfn) __typeof(fn) fn##_ptr; -#define LEGACY_FUNCTION(fn) __typeof(fn) fn##_ptr; +#define REQUIRED_FUNCTION(fn) TYPEOF(fn) fn##_ptr; +#define NEW_REQUIRED_FUNCTION(fn) TYPEOF(fn) fn##_ptr; +#define LIGHTUP_FUNCTION(fn) TYPEOF(fn) fn##_ptr; +#define FALLBACK_FUNCTION(fn) TYPEOF(fn) fn##_ptr; +#define RENAMED_FUNCTION(fn,oldfn) TYPEOF(fn) fn##_ptr; +#define LEGACY_FUNCTION(fn) TYPEOF(fn) fn##_ptr; FOR_ALL_OPENSSL_FUNCTIONS #undef LEGACY_FUNCTION #undef RENAMED_FUNCTION @@ -131,23 +131,23 @@ static void InitializeOpenSSLShim() // Get pointers to all the functions that are needed #define REQUIRED_FUNCTION(fn) \ - if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } + if (!(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } #define NEW_REQUIRED_FUNCTION(fn) \ - if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } + if (!v1_0_sentinel && !(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } #define LIGHTUP_FUNCTION(fn) \ - fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)); + fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)); #define FALLBACK_FUNCTION(fn) \ - if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fn##_ptr = (__typeof(fn))local_##fn; } + if (!(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)))) { fn##_ptr = (TYPEOF(fn))local_##fn; } #define RENAMED_FUNCTION(fn,oldfn) \ - if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } \ - if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #oldfn)))) { fprintf(stderr, "Cannot get required symbol " #oldfn " from libssl\n"); abort(); } + if (!v1_0_sentinel && !(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } \ + if (v1_0_sentinel && !(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #oldfn)))) { fprintf(stderr, "Cannot get required symbol " #oldfn " from libssl\n"); abort(); } #define LEGACY_FUNCTION(fn) \ - if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } + if (v1_0_sentinel && !(fn##_ptr = (TYPEOF(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } FOR_ALL_OPENSSL_FUNCTIONS #undef LEGACY_FUNCTION diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index d59533208f4e..825c8845838a 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -35,6 +35,7 @@ #include #include "pal_crypto_config.h" +#include "pal_compiler.h" #define OPENSSL_VERSION_1_1_1_RTM 0x10101000L #define OPENSSL_VERSION_1_1_0_RTM 0x10100000L #define OPENSSL_VERSION_1_0_2_RTM 0x10002000L @@ -579,12 +580,12 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi LIGHTUP_FUNCTION(EC_POINT_set_affine_coordinates_GF2m) \ // Declare pointers to all the used OpenSSL functions -#define REQUIRED_FUNCTION(fn) extern __typeof(fn)* fn##_ptr; -#define NEW_REQUIRED_FUNCTION(fn) extern __typeof(fn)* fn##_ptr; -#define LIGHTUP_FUNCTION(fn) extern __typeof(fn)* fn##_ptr; -#define FALLBACK_FUNCTION(fn) extern __typeof(fn)* fn##_ptr; -#define RENAMED_FUNCTION(fn,oldfn) extern __typeof(fn)* fn##_ptr; -#define LEGACY_FUNCTION(fn) extern __typeof(fn)* fn##_ptr; +#define REQUIRED_FUNCTION(fn) extern TYPEOF(fn)* fn##_ptr; +#define NEW_REQUIRED_FUNCTION(fn) extern TYPEOF(fn)* fn##_ptr; +#define LIGHTUP_FUNCTION(fn) extern TYPEOF(fn)* fn##_ptr; +#define FALLBACK_FUNCTION(fn) extern TYPEOF(fn)* fn##_ptr; +#define RENAMED_FUNCTION(fn,oldfn) extern TYPEOF(fn)* fn##_ptr; +#define LEGACY_FUNCTION(fn) extern TYPEOF(fn)* fn##_ptr; FOR_ALL_OPENSSL_FUNCTIONS #undef LEGACY_FUNCTION #undef RENAMED_FUNCTION From 03d2e48212d57f6ca9e44a127de965e528a1bf85 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Wed, 5 Aug 2020 19:34:41 -0300 Subject: [PATCH 278/755] [wasm] Moving wasm debugger to dotnet/runtime (#40146) * Moving Wasm debugger to dotnet/runtime The build is working. The tests are running. - make -C src/mono/wasm/ run-debugger-tests --- src/mono/wasm/Makefile | 24 + .../BrowserDebugHost/BrowserDebugHost.csproj | 11 + .../wasm/debugger/BrowserDebugHost/Program.cs | 92 + .../wasm/debugger/BrowserDebugHost/Startup.cs | 164 ++ .../BrowserDebugHost/TestHarnessStartup.cs | 255 +++ .../BrowserDebugProxy/AssemblyInfo.cs | 4 + .../BrowserDebugProxy.csproj | 15 + .../BrowserDebugProxy/BrowserDebugProxy.sln | 31 + .../debugger/BrowserDebugProxy/DebugStore.cs | 883 ++++++++++ .../BrowserDebugProxy/DebuggerProxy.cs | 29 + .../BrowserDebugProxy/DevToolsHelper.cs | 304 ++++ .../BrowserDebugProxy/DevToolsProxy.cs | 381 +++++ .../BrowserDebugProxy/EvaluateExpression.cs | 213 +++ .../debugger/BrowserDebugProxy/MonoProxy.cs | 998 +++++++++++ .../debugger/DebuggerTestSuite/ArrayTests.cs | 605 +++++++ .../DebuggerTestSuite/CallFunctionOnTests.cs | 857 ++++++++++ .../DebuggerTestSuite/DateTimeTests.cs | 67 + .../DebuggerTestSuite.csproj | 20 + .../DebuggerTestSuite/DelegateTests.cs | 306 ++++ .../DebuggerTestSuite/DevToolsClient.cs | 167 ++ .../EvaluateOnCallFrameTests.cs | 214 +++ .../DebuggerTestSuite/InspectorClient.cs | 81 + .../DebuggerTestSuite/PointerTests.cs | 560 +++++++ .../debugger/DebuggerTestSuite/Support.cs | 990 +++++++++++ .../wasm/debugger/DebuggerTestSuite/Tests.cs | 1483 +++++++++++++++++ .../DebuggerTestSuite/appsettings.json | 9 + .../debugger/tests/debugger-array-test.cs | 308 ++++ .../wasm/debugger/tests/debugger-cfo-test.cs | 64 + .../debugger/tests/debugger-datetime-test.cs | 29 + .../wasm/debugger/tests/debugger-driver.html | 124 ++ .../debugger/tests/debugger-evaluate-test.cs | 108 ++ .../debugger/tests/debugger-pointers-test.cs | 112 ++ src/mono/wasm/debugger/tests/debugger-test.cs | 325 ++++ .../wasm/debugger/tests/debugger-test.csproj | 49 + .../wasm/debugger/tests/debugger-test2.cs | 51 + .../tests/debugger-valuetypes-test.cs | 264 +++ src/mono/wasm/debugger/tests/dependency.cs | 44 + src/mono/wasm/debugger/tests/other.js | 33 + .../wasm/debugger/tests/runtime-debugger.js | 11 + src/mono/wasm/runtime/library_mono.js | 430 +++-- .../WasmAppBuilder/WasmAppBuilder.cs | 25 +- 41 files changed, 10627 insertions(+), 113 deletions(-) create mode 100644 src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj create mode 100644 src/mono/wasm/debugger/BrowserDebugHost/Program.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugHost/Startup.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.sln create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs create mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/Support.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/appsettings.json create mode 100644 src/mono/wasm/debugger/tests/debugger-array-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-cfo-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-datetime-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-driver.html create mode 100644 src/mono/wasm/debugger/tests/debugger-evaluate-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-pointers-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-test.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-test.csproj create mode 100644 src/mono/wasm/debugger/tests/debugger-test2.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs create mode 100644 src/mono/wasm/debugger/tests/dependency.cs create mode 100644 src/mono/wasm/debugger/tests/other.js create mode 100644 src/mono/wasm/debugger/tests/runtime-debugger.js diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 978bd1c1c4d3..398bd0e650bf 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -139,3 +139,27 @@ run-tests-jsc-%: run-tests-%: PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG) $(MSBUILD_ARGS) + +build-debugger-test-app: + $(DOTNET) build --configuration debug --nologo /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Debug /p:RuntimeConfiguration=$(CONFIG) $(TOP)/src/mono/wasm/debugger/tests + cp $(TOP)/src/mono/wasm/debugger/tests/debugger-driver.html $(TOP)/src/mono/wasm/debugger/tests/bin/Debug/publish + cp $(TOP)/src/mono/wasm/debugger/tests/other.js $(TOP)/src/mono/wasm/debugger/tests/bin/Debug/publish + cp $(TOP)/src/mono/wasm/debugger/tests/runtime-debugger.js $(TOP)/src/mono/wasm/debugger/tests/bin/Debug/publish + +run-debugger-tests: build-debugger-test-app build-dbg-testsuite + if [ ! -z "$(TEST_FILTER)" ]; then \ + export TEST_SUITE_PATH=$(TOP)/src/mono/wasm/debugger/tests/bin/Debug/publish; \ + export LC_ALL=en_US.UTF-8; \ + $(DOTNET) test $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite --filter FullyQualifiedName~$(TEST_FILTER); \ + unset TEST_SUITE_PATH LC_ALL; \ + else \ + export TEST_SUITE_PATH=$(TOP)/src/mono/wasm/debugger/tests/bin/Debug/publish; \ + export LC_ALL=en_US.UTF-8; \ + $(DOTNET) test $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite $(TEST_ARGS); \ + unset TEST_SUITE_PATH LC_ALL; \ + fi + +build-dbg-proxy: + $(DOTNET) build $(TOP)/src/mono/wasm/debugger/BrowserDebugHost +build-dbg-testsuite: + $(DOTNET) build $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite diff --git a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj new file mode 100644 index 000000000000..9a038a02e4bc --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.0 + + + + + + + diff --git a/src/mono/wasm/debugger/BrowserDebugHost/Program.cs b/src/mono/wasm/debugger/BrowserDebugHost/Program.cs new file mode 100644 index 000000000000..c45b9ce0065c --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugHost/Program.cs @@ -0,0 +1,92 @@ +// 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.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.WebAssembly.Diagnostics +{ + public class ProxyOptions + { + public Uri DevToolsUrl { get; set; } = new Uri("http://localhost:9222"); + } + + public class TestHarnessOptions : ProxyOptions + { + public string ChromePath { get; set; } + public string AppPath { get; set; } + public string PagePath { get; set; } + public string NodeApp { get; set; } + } + + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseSetting("UseIISIntegration", false.ToString()) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseStartup() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddCommandLine(args); + }) + .UseUrls("http://localhost:9300") + .Build(); + + host.Run(); + } + } + + public class TestHarnessProxy + { + static IWebHost host; + static Task hostTask; + static CancellationTokenSource cts = new CancellationTokenSource(); + static object proxyLock = new object(); + + public static readonly Uri Endpoint = new Uri("http://localhost:9400"); + + public static Task Start(string chromePath, string appPath, string pagePath) + { + lock(proxyLock) + { + if (host != null) + return hostTask; + + host = WebHost.CreateDefaultBuilder() + .UseSetting("UseIISIntegration", false.ToString()) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddEnvironmentVariables(prefix: "WASM_TESTS_"); + }) + .ConfigureServices((ctx, services) => + { + services.Configure(ctx.Configuration); + services.Configure(options => + { + options.ChromePath = options.ChromePath ?? chromePath; + options.AppPath = appPath; + options.PagePath = pagePath; + options.DevToolsUrl = new Uri("http://localhost:0"); + }); + }) + .UseStartup() + .UseUrls(Endpoint.ToString()) + .Build(); + hostTask = host.StartAsync(cts.Token); + } + + Console.WriteLine("WebServer Ready!"); + return hostTask; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs new file mode 100644 index 000000000000..16292f997e6b --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs @@ -0,0 +1,164 @@ +// 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 System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.WebAssembly.Diagnostics +{ + internal class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) => + services.AddRouting() + .Configure(Configuration); + + public Startup(IConfiguration configuration) => + Configuration = configuration; + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IOptionsMonitor optionsAccessor, IWebHostEnvironment env) + { + var options = optionsAccessor.CurrentValue; + app.UseDeveloperExceptionPage() + .UseWebSockets() + .UseDebugProxy(options); + } + } + + static class DebugExtensions + { + public static Dictionary MapValues(Dictionary response, HttpContext context, Uri debuggerHost) + { + var filtered = new Dictionary(); + var request = context.Request; + + foreach (var key in response.Keys) + { + switch (key) + { + case "devtoolsFrontendUrl": + var front = response[key]; + filtered[key] = $"{debuggerHost.Scheme}://{debuggerHost.Authority}{front.Replace ($"ws={debuggerHost.Authority}", $"ws={request.Host}")}"; + break; + case "webSocketDebuggerUrl": + var page = new Uri(response[key]); + filtered[key] = $"{page.Scheme}://{request.Host}{page.PathAndQuery}"; + break; + default: + filtered[key] = response[key]; + break; + } + } + return filtered; + } + + public static IApplicationBuilder UseDebugProxy(this IApplicationBuilder app, ProxyOptions options) => + UseDebugProxy(app, options, MapValues); + + public static IApplicationBuilder UseDebugProxy( + this IApplicationBuilder app, + ProxyOptions options, + Func, HttpContext, Uri, Dictionary> mapFunc) + { + var devToolsHost = options.DevToolsUrl; + app.UseRouter(router => + { + router.MapGet("/", Copy); + router.MapGet("/favicon.ico", Copy); + router.MapGet("json", RewriteArray); + router.MapGet("json/list", RewriteArray); + router.MapGet("json/version", RewriteSingle); + router.MapGet("json/new", RewriteSingle); + router.MapGet("devtools/page/{pageId}", ConnectProxy); + router.MapGet("devtools/browser/{pageId}", ConnectProxy); + + string GetEndpoint(HttpContext context) + { + var request = context.Request; + var requestPath = request.Path; + return $"{devToolsHost.Scheme}://{devToolsHost.Authority}{request.Path}{request.QueryString}"; + } + + async Task Copy(HttpContext context) + { + using(var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }) + { + var response = await httpClient.GetAsync(GetEndpoint(context)); + context.Response.ContentType = response.Content.Headers.ContentType.ToString(); + if ((response.Content.Headers.ContentLength ?? 0) > 0) + context.Response.ContentLength = response.Content.Headers.ContentLength; + var bytes = await response.Content.ReadAsByteArrayAsync(); + await context.Response.Body.WriteAsync(bytes); + + } + } + + async Task RewriteSingle(HttpContext context) + { + var version = await ProxyGetJsonAsync>(GetEndpoint(context)); + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync( + JsonSerializer.Serialize(mapFunc(version, context, devToolsHost))); + } + + async Task RewriteArray(HttpContext context) + { + var tabs = await ProxyGetJsonAsync[]>(GetEndpoint(context)); + var alteredTabs = tabs.Select(t => mapFunc(t, context, devToolsHost)).ToArray(); + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(JsonSerializer.Serialize(alteredTabs)); + } + + async Task ConnectProxy(HttpContext context) + { + if (!context.WebSockets.IsWebSocketRequest) + { + context.Response.StatusCode = 400; + return; + } + + var endpoint = new Uri($"ws://{devToolsHost.Authority}{context.Request.Path.ToString ()}"); + try + { + using var loggerFactory = LoggerFactory.Create( + builder => builder.AddConsole().AddFilter(null, LogLevel.Information)); + var proxy = new DebuggerProxy(loggerFactory); + var ideSocket = await context.WebSockets.AcceptWebSocketAsync(); + + await proxy.Run(endpoint, ideSocket); + } + catch (Exception e) + { + Console.WriteLine("got exception {0}", e); + } + } + }); + return app; + } + + static async Task ProxyGetJsonAsync(string url) + { + using(var httpClient = new HttpClient()) + { + var response = await httpClient.GetAsync(url); + return await JsonSerializer.DeserializeAsync(await response.Content.ReadAsStreamAsync()); + } + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs b/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs new file mode 100644 index 000000000000..953eb864f907 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs @@ -0,0 +1,255 @@ +// 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.Diagnostics; +using System.IO; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + public class TestHarnessStartup + { + static Regex parseConnection = new Regex(@"listening on (ws?s://[^\s]*)"); + public TestHarnessStartup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; set; } + + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + services.AddRouting() + .Configure(Configuration); + } + + async Task SendNodeVersion(HttpContext context) + { + Console.WriteLine("hello chrome! json/version"); + var resp_obj = new JObject(); + resp_obj["Browser"] = "node.js/v9.11.1"; + resp_obj["Protocol-Version"] = "1.1"; + + var response = resp_obj.ToString(); + await context.Response.WriteAsync(response, new CancellationTokenSource().Token); + } + + async Task SendNodeList(HttpContext context) + { + Console.WriteLine("hello chrome! json/list"); + try + { + var response = new JArray(JObject.FromObject(new + { + description = "node.js instance", + devtoolsFrontendUrl = "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4", + faviconUrl = "https://nodejs.org/static/favicon.ico", + id = "91d87807-8a81-4f49-878c-a5604103b0a4", + title = "foo.js", + type = "node", + webSocketDebuggerUrl = "ws://localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4" + })).ToString(); + + Console.WriteLine($"sending: {response}"); + await context.Response.WriteAsync(response, new CancellationTokenSource().Token); + } + catch (Exception e) { Console.WriteLine(e); } + } + + public async Task LaunchAndServe(ProcessStartInfo psi, HttpContext context, Func> extract_conn_url) + { + + if (!context.WebSockets.IsWebSocketRequest) + { + context.Response.StatusCode = 400; + return; + } + + var tcs = new TaskCompletionSource(); + + var proc = Process.Start(psi); + try + { + proc.ErrorDataReceived += (sender, e) => + { + var str = e.Data; + Console.WriteLine($"stderr: {str}"); + + if (tcs.Task.IsCompleted) + return; + + var match = parseConnection.Match(str); + if (match.Success) + { + tcs.TrySetResult(match.Groups[1].Captures[0].Value); + } + }; + + proc.OutputDataReceived += (sender, e) => + { + Console.WriteLine($"stdout: {e.Data}"); + }; + + proc.BeginErrorReadLine(); + proc.BeginOutputReadLine(); + + if (await Task.WhenAny(tcs.Task, Task.Delay(5000)) != tcs.Task) + { + Console.WriteLine("Didnt get the con string after 5s."); + throw new Exception("node.js timedout"); + } + var line = await tcs.Task; + var con_str = extract_conn_url != null ? await extract_conn_url(line) : line; + + Console.WriteLine($"launching proxy for {con_str}"); + + using var loggerFactory = LoggerFactory.Create( + builder => builder.AddConsole().AddFilter(null, LogLevel.Information)); + var proxy = new DebuggerProxy(loggerFactory); + var browserUri = new Uri(con_str); + var ideSocket = await context.WebSockets.AcceptWebSocketAsync(); + + await proxy.Run(browserUri, ideSocket); + Console.WriteLine("Proxy done"); + } + catch (Exception e) + { + Console.WriteLine("got exception {0}", e); + } + finally + { + proc.CancelErrorRead(); + proc.CancelOutputRead(); + proc.Kill(); + proc.WaitForExit(); + proc.Close(); + } + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IOptionsMonitor optionsAccessor, IWebHostEnvironment env) + { + app.UseWebSockets(); + app.UseStaticFiles(); + + TestHarnessOptions options = optionsAccessor.CurrentValue; + + var provider = new FileExtensionContentTypeProvider(); + provider.Mappings[".wasm"] = "application/wasm"; + + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider(options.AppPath), + ServeUnknownFileTypes = true, //Cuz .wasm is not a known file type :cry: + RequestPath = "", + ContentTypeProvider = provider + }); + + var devToolsUrl = options.DevToolsUrl; + app.UseRouter(router => + { + router.MapGet("launch-chrome-and-connect", async context => + { + Console.WriteLine("New test request"); + try + { + var client = new HttpClient(); + var psi = new ProcessStartInfo(); + + psi.Arguments = $"--headless --disable-gpu --lang=en-US --incognito --remote-debugging-port={devToolsUrl.Port} http://{TestHarnessProxy.Endpoint.Authority}/{options.PagePath}"; + psi.UseShellExecute = false; + psi.FileName = options.ChromePath; + psi.RedirectStandardError = true; + psi.RedirectStandardOutput = true; + + await LaunchAndServe(psi, context, async(str) => + { + var start = DateTime.Now; + JArray obj = null; + + while (true) + { + // Unfortunately it does look like we have to wait + // for a bit after getting the response but before + // making the list request. We get an empty result + // if we make the request too soon. + await Task.Delay(100); + + var res = await client.GetStringAsync(new Uri(new Uri(str), "/json/list")); + Console.WriteLine("res is {0}", res); + + if (!String.IsNullOrEmpty(res)) + { + // Sometimes we seem to get an empty array `[ ]` + obj = JArray.Parse(res); + if (obj != null && obj.Count >= 1) + break; + } + + var elapsed = DateTime.Now - start; + if (elapsed.Milliseconds > 5000) + { + Console.WriteLine($"Unable to get DevTools /json/list response in {elapsed.Seconds} seconds, stopping"); + return null; + } + } + + var wsURl = obj[0] ? ["webSocketDebuggerUrl"]?.Value(); + Console.WriteLine(">>> {0}", wsURl); + + return wsURl; + }); + } + catch (Exception ex) + { + Console.WriteLine($"launch-chrome-and-connect failed with {ex.ToString ()}"); + } + }); + }); + + if (options.NodeApp != null) + { + Console.WriteLine($"Doing the nodejs: {options.NodeApp}"); + var nodeFullPath = Path.GetFullPath(options.NodeApp); + Console.WriteLine(nodeFullPath); + var psi = new ProcessStartInfo(); + + psi.UseShellExecute = false; + psi.RedirectStandardError = true; + psi.RedirectStandardOutput = true; + + psi.Arguments = $"--inspect-brk=localhost:0 {nodeFullPath}"; + psi.FileName = "node"; + + app.UseRouter(router => + { + //Inspector API for using chrome devtools directly + router.MapGet("json", SendNodeList); + router.MapGet("json/list", SendNodeList); + router.MapGet("json/version", SendNodeVersion); + router.MapGet("launch-done-and-connect", async context => + { + await LaunchAndServe(psi, context, null); + }); + }); + } + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs b/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs new file mode 100644 index 000000000000..5d9d173c2446 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs @@ -0,0 +1,4 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj new file mode 100644 index 000000000000..4063416ceb07 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.1 + true + + + + + + + + + + diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.sln b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.sln new file mode 100644 index 000000000000..cfb208d1562f --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28407.52 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrowserDebugHost", "..\BrowserDebugHost\BrowserDebugHost.csproj", "{954F768A-23E6-4B14-90E0-27EA6B41FBCC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrowserDebugProxy", "BrowserDebugProxy.csproj", "{490128B6-9F21-46CA-878A-F22BCF51EF3C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {954F768A-23E6-4B14-90E0-27EA6B41FBCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {954F768A-23E6-4B14-90E0-27EA6B41FBCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {954F768A-23E6-4B14-90E0-27EA6B41FBCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {954F768A-23E6-4B14-90E0-27EA6B41FBCC}.Release|Any CPU.Build.0 = Release|Any CPU + {490128B6-9F21-46CA-878A-F22BCF51EF3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {490128B6-9F21-46CA-878A-F22BCF51EF3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {490128B6-9F21-46CA-878A-F22BCF51EF3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {490128B6-9F21-46CA-878A-F22BCF51EF3C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F8BA2C2D-8F28-4F9E-9C54-51E394EF941E} + EndGlobalSection +EndGlobal diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs new file mode 100644 index 000000000000..aedcfb27a449 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -0,0 +1,883 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Pdb; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + internal class BreakpointRequest + { + public string Id { get; private set; } + public string Assembly { get; private set; } + public string File { get; private set; } + public int Line { get; private set; } + public int Column { get; private set; } + public MethodInfo Method { get; private set; } + + JObject request; + + public bool IsResolved => Assembly != null; + public List Locations { get; } = new List(); + + public override string ToString() => $"BreakpointRequest Assembly: {Assembly} File: {File} Line: {Line} Column: {Column}"; + + public object AsSetBreakpointByUrlResponse(IEnumerable jsloc) => new { breakpointId = Id, locations = Locations.Select(l => l.Location.AsLocation()).Concat(jsloc) }; + + public BreakpointRequest() + { } + + public BreakpointRequest(string id, MethodInfo method) + { + Id = id; + Method = method; + } + + public BreakpointRequest(string id, JObject request) + { + Id = id; + this.request = request; + } + + public static BreakpointRequest Parse(string id, JObject args) + { + return new BreakpointRequest(id, args); + } + + public BreakpointRequest Clone() => new BreakpointRequest { Id = Id, request = request }; + + public bool IsMatch(SourceFile sourceFile) + { + var url = request?["url"]?.Value(); + if (url == null) + { + var urlRegex = request?["urlRegex"].Value(); + var regex = new Regex(urlRegex); + return regex.IsMatch(sourceFile.Url.ToString()) || regex.IsMatch(sourceFile.DocUrl); + } + + return sourceFile.Url.ToString() == url || sourceFile.DotNetUrl == url; + } + + public bool TryResolve(SourceFile sourceFile) + { + if (!IsMatch(sourceFile)) + return false; + + var line = request?["lineNumber"]?.Value(); + var column = request?["columnNumber"]?.Value(); + + if (line == null || column == null) + return false; + + Assembly = sourceFile.AssemblyName; + File = sourceFile.DebuggerFileName; + Line = line.Value; + Column = column.Value; + return true; + } + + public bool TryResolve(DebugStore store) + { + if (request == null || store == null) + return false; + + return store.AllSources().FirstOrDefault(source => TryResolve(source)) != null; + } + } + + internal class VarInfo + { + public VarInfo(VariableDebugInformation v) + { + this.Name = v.Name; + this.Index = v.Index; + } + + public VarInfo(ParameterDefinition p) + { + this.Name = p.Name; + this.Index = (p.Index + 1) * -1; + } + + public string Name { get; } + public int Index { get; } + + public override string ToString() => $"(var-info [{Index}] '{Name}')"; + } + + internal class CliLocation + { + public CliLocation(MethodInfo method, int offset) + { + Method = method; + Offset = offset; + } + + public MethodInfo Method { get; } + public int Offset { get; } + } + + internal class SourceLocation + { + SourceId id; + int line; + int column; + CliLocation cliLoc; + + public SourceLocation(SourceId id, int line, int column) + { + this.id = id; + this.line = line; + this.column = column; + } + + public SourceLocation(MethodInfo mi, SequencePoint sp) + { + this.id = mi.SourceId; + this.line = sp.StartLine - 1; + this.column = sp.StartColumn - 1; + this.cliLoc = new CliLocation(mi, sp.Offset); + } + + public SourceId Id { get => id; } + public int Line { get => line; } + public int Column { get => column; } + public CliLocation CliLocation => this.cliLoc; + + public override string ToString() => $"{id}:{Line}:{Column}"; + + public static SourceLocation Parse(JObject obj) + { + if (obj == null) + return null; + + if (!SourceId.TryParse(obj["scriptId"]?.Value(), out var id)) + return null; + + var line = obj["lineNumber"]?.Value(); + var column = obj["columnNumber"]?.Value(); + if (id == null || line == null || column == null) + return null; + + return new SourceLocation(id, line.Value, column.Value); + } + + internal class LocationComparer : EqualityComparer + { + public override bool Equals(SourceLocation l1, SourceLocation l2) + { + if (l1 == null && l2 == null) + return true; + else if (l1 == null || l2 == null) + return false; + + return (l1.Line == l2.Line && + l1.Column == l2.Column && + l1.Id == l2.Id); + } + + public override int GetHashCode(SourceLocation loc) + { + int hCode = loc.Line ^ loc.Column; + return loc.Id.GetHashCode() ^ hCode.GetHashCode(); + } + } + + internal object AsLocation() => new + { + scriptId = id.ToString(), + lineNumber = line, + columnNumber = column + }; + } + + internal class SourceId + { + const string Scheme = "dotnet://"; + + readonly int assembly, document; + + public int Assembly => assembly; + public int Document => document; + + internal SourceId(int assembly, int document) + { + this.assembly = assembly; + this.document = document; + } + + public SourceId(string id) + { + if (!TryParse(id, out assembly, out document)) + throw new ArgumentException("invalid source identifier", nameof(id)); + } + + public static bool TryParse(string id, out SourceId source) + { + source = null; + if (!TryParse(id, out var assembly, out var document)) + return false; + + source = new SourceId(assembly, document); + return true; + } + + static bool TryParse(string id, out int assembly, out int document) + { + assembly = document = 0; + if (id == null || !id.StartsWith(Scheme, StringComparison.Ordinal)) + return false; + + var sp = id.Substring(Scheme.Length).Split('_'); + if (sp.Length != 2) + return false; + + if (!int.TryParse(sp[0], out assembly)) + return false; + + if (!int.TryParse(sp[1], out document)) + return false; + + return true; + } + + public override string ToString() => $"{Scheme}{assembly}_{document}"; + + public override bool Equals(object obj) + { + if (obj == null) + return false; + SourceId that = obj as SourceId; + return that.assembly == this.assembly && that.document == this.document; + } + + public override int GetHashCode() => assembly.GetHashCode() ^ document.GetHashCode(); + + public static bool operator ==(SourceId a, SourceId b) => ((object) a == null) ? (object) b == null : a.Equals(b); + + public static bool operator !=(SourceId a, SourceId b) => !a.Equals(b); + } + + internal class MethodInfo + { + MethodDefinition methodDef; + SourceFile source; + + public SourceId SourceId => source.SourceId; + + public string Name => methodDef.Name; + public MethodDebugInformation DebugInformation => methodDef.DebugInformation; + + public SourceLocation StartLocation { get; } + public SourceLocation EndLocation { get; } + public AssemblyInfo Assembly { get; } + public uint Token => methodDef.MetadataToken.RID; + + public MethodInfo(AssemblyInfo assembly, MethodDefinition methodDef, SourceFile source) + { + this.Assembly = assembly; + this.methodDef = methodDef; + this.source = source; + + var sps = DebugInformation.SequencePoints; + if (sps == null || sps.Count() < 1) + return; + + SequencePoint start = sps[0]; + SequencePoint end = sps[0]; + + foreach (var sp in sps) + { + if (sp.StartLine < start.StartLine) + start = sp; + else if (sp.StartLine == start.StartLine && sp.StartColumn < start.StartColumn) + start = sp; + + if (sp.EndLine > end.EndLine) + end = sp; + else if (sp.EndLine == end.EndLine && sp.EndColumn > end.EndColumn) + end = sp; + } + + StartLocation = new SourceLocation(this, start); + EndLocation = new SourceLocation(this, end); + } + + public SourceLocation GetLocationByIl(int pos) + { + SequencePoint prev = null; + foreach (var sp in DebugInformation.SequencePoints) + { + if (sp.Offset > pos) + break; + prev = sp; + } + + if (prev != null) + return new SourceLocation(this, prev); + + return null; + } + + public VarInfo[] GetLiveVarsAt(int offset) + { + var res = new List(); + + res.AddRange(methodDef.Parameters.Select(p => new VarInfo(p))); + res.AddRange(methodDef.DebugInformation.GetScopes() + .Where(s => s.Start.Offset <= offset && (s.End.IsEndOfMethod || s.End.Offset > offset)) + .SelectMany(s => s.Variables) + .Where(v => !v.IsDebuggerHidden) + .Select(v => new VarInfo(v))); + + return res.ToArray(); + } + + public override string ToString() => "MethodInfo(" + methodDef.FullName + ")"; + } + + internal class TypeInfo + { + AssemblyInfo assembly; + TypeDefinition type; + List methods; + + public TypeInfo(AssemblyInfo assembly, TypeDefinition type) + { + this.assembly = assembly; + this.type = type; + methods = new List(); + } + + public string Name => type.Name; + public string FullName => type.FullName; + public List Methods => methods; + + public override string ToString() => "TypeInfo('" + FullName + "')"; + } + + class AssemblyInfo + { + static int next_id; + ModuleDefinition image; + readonly int id; + readonly ILogger logger; + Dictionary methods = new Dictionary(); + Dictionary sourceLinkMappings = new Dictionary(); + Dictionary typesByName = new Dictionary(); + readonly List sources = new List(); + internal string Url { get; } + + public AssemblyInfo(IAssemblyResolver resolver, string url, byte[] assembly, byte[] pdb) + { + this.id = Interlocked.Increment(ref next_id); + + try + { + Url = url; + ReaderParameters rp = new ReaderParameters( /*ReadingMode.Immediate*/ ); + rp.AssemblyResolver = resolver; + // set ReadSymbols = true unconditionally in case there + // is an embedded pdb then handle ArgumentException + // and assume that if pdb == null that is the cause + rp.ReadSymbols = true; + rp.SymbolReaderProvider = new PdbReaderProvider(); + if (pdb != null) + rp.SymbolStream = new MemoryStream(pdb); + rp.ReadingMode = ReadingMode.Immediate; + + this.image = ModuleDefinition.ReadModule(new MemoryStream(assembly), rp); + } + catch (BadImageFormatException ex) + { + logger.LogWarning($"Failed to read assembly as portable PDB: {ex.Message}"); + } + catch (ArgumentException) + { + // if pdb == null this is expected and we + // read the assembly without symbols below + if (pdb != null) + throw; + } + + if (this.image == null) + { + ReaderParameters rp = new ReaderParameters( /*ReadingMode.Immediate*/ ); + rp.AssemblyResolver = resolver; + if (pdb != null) + { + rp.ReadSymbols = true; + rp.SymbolReaderProvider = new PdbReaderProvider(); + rp.SymbolStream = new MemoryStream(pdb); + } + + rp.ReadingMode = ReadingMode.Immediate; + + this.image = ModuleDefinition.ReadModule(new MemoryStream(assembly), rp); + } + + Populate(); + } + + public AssemblyInfo(ILogger logger) + { + this.logger = logger; + } + + void Populate() + { + ProcessSourceLink(); + + var d2s = new Dictionary(); + + SourceFile FindSource(Document doc) + { + if (doc == null) + return null; + + if (d2s.TryGetValue(doc, out var source)) + return source; + + var src = new SourceFile(this, sources.Count, doc, GetSourceLinkUrl(doc.Url)); + sources.Add(src); + d2s[doc] = src; + return src; + }; + + foreach (var type in image.GetTypes()) + { + var typeInfo = new TypeInfo(this, type); + typesByName[type.FullName] = typeInfo; + + foreach (var method in type.Methods) + { + foreach (var sp in method.DebugInformation.SequencePoints) + { + var source = FindSource(sp.Document); + var methodInfo = new MethodInfo(this, method, source); + methods[method.MetadataToken.RID] = methodInfo; + if (source != null) + source.AddMethod(methodInfo); + + typeInfo.Methods.Add(methodInfo); + } + } + } + } + + private void ProcessSourceLink() + { + var sourceLinkDebugInfo = image.CustomDebugInformations.FirstOrDefault(i => i.Kind == CustomDebugInformationKind.SourceLink); + + if (sourceLinkDebugInfo != null) + { + var sourceLinkContent = ((SourceLinkDebugInformation) sourceLinkDebugInfo).Content; + + if (sourceLinkContent != null) + { + var jObject = JObject.Parse(sourceLinkContent) ["documents"]; + sourceLinkMappings = JsonConvert.DeserializeObject>(jObject.ToString()); + } + } + } + + private Uri GetSourceLinkUrl(string document) + { + if (sourceLinkMappings.TryGetValue(document, out string url)) + return new Uri(url); + + foreach (var sourceLinkDocument in sourceLinkMappings) + { + string key = sourceLinkDocument.Key; + + if (Path.GetFileName(key) != "*") + { + continue; + } + + var keyTrim = key.TrimEnd('*'); + + if (document.StartsWith(keyTrim, StringComparison.OrdinalIgnoreCase)) + { + var docUrlPart = document.Replace(keyTrim, ""); + return new Uri(sourceLinkDocument.Value.TrimEnd('*') + docUrlPart); + } + } + + return null; + } + + public IEnumerable Sources => this.sources; + + public Dictionary TypesByName => this.typesByName; + public int Id => id; + public string Name => image.Name; + + public SourceFile GetDocById(int document) + { + return sources.FirstOrDefault(s => s.SourceId.Document == document); + } + + public MethodInfo GetMethodByToken(uint token) + { + methods.TryGetValue(token, out var value); + return value; + } + + public TypeInfo GetTypeByName(string name) + { + typesByName.TryGetValue(name, out var res); + return res; + } + } + + internal class SourceFile + { + Dictionary methods; + AssemblyInfo assembly; + int id; + Document doc; + + internal SourceFile(AssemblyInfo assembly, int id, Document doc, Uri sourceLinkUri) + { + this.methods = new Dictionary(); + this.SourceLinkUri = sourceLinkUri; + this.assembly = assembly; + this.id = id; + this.doc = doc; + this.DebuggerFileName = doc.Url.Replace("\\", "/").Replace(":", ""); + + this.SourceUri = new Uri((Path.IsPathRooted(doc.Url) ? "file://" : "") + doc.Url, UriKind.RelativeOrAbsolute); + if (SourceUri.IsFile && File.Exists(SourceUri.LocalPath)) + { + this.Url = this.SourceUri.ToString(); + } + else + { + this.Url = DotNetUrl; + } + } + + internal void AddMethod(MethodInfo mi) + { + if (!this.methods.ContainsKey(mi.Token)) + this.methods[mi.Token] = mi; + } + + public string DebuggerFileName { get; } + public string Url { get; } + public string AssemblyName => assembly.Name; + public string DotNetUrl => $"dotnet://{assembly.Name}/{DebuggerFileName}"; + + public SourceId SourceId => new SourceId(assembly.Id, this.id); + public Uri SourceLinkUri { get; } + public Uri SourceUri { get; } + + public IEnumerable Methods => this.methods.Values; + + public string DocUrl => doc.Url; + + public(int startLine, int startColumn, int endLine, int endColumn) GetExtents() + { + var start = Methods.OrderBy(m => m.StartLocation.Line).ThenBy(m => m.StartLocation.Column).First(); + var end = Methods.OrderByDescending(m => m.EndLocation.Line).ThenByDescending(m => m.EndLocation.Column).First(); + return (start.StartLocation.Line, start.StartLocation.Column, end.EndLocation.Line, end.EndLocation.Column); + } + + async Task GetDataAsync(Uri uri, CancellationToken token) + { + var mem = new MemoryStream(); + try + { + if (uri.IsFile && File.Exists(uri.LocalPath)) + { + using(var file = File.Open(SourceUri.LocalPath, FileMode.Open)) + { + await file.CopyToAsync(mem, token).ConfigureAwait(false); + mem.Position = 0; + } + } + else if (uri.Scheme == "http" || uri.Scheme == "https") + { + var client = new HttpClient(); + using(var stream = await client.GetStreamAsync(uri)) + { + await stream.CopyToAsync(mem, token).ConfigureAwait(false); + mem.Position = 0; + } + } + } + catch (Exception) + { + return null; + } + return mem; + } + + static HashAlgorithm GetHashAlgorithm(DocumentHashAlgorithm algorithm) + { + switch (algorithm) + { + case DocumentHashAlgorithm.SHA1: + return SHA1.Create(); + case DocumentHashAlgorithm.SHA256: + return SHA256.Create(); + case DocumentHashAlgorithm.MD5: + return MD5.Create(); + } + return null; + } + + bool CheckPdbHash(byte[] computedHash) + { + if (computedHash.Length != doc.Hash.Length) + return false; + + for (var i = 0; i < computedHash.Length; i++) + if (computedHash[i] != doc.Hash[i]) + return false; + + return true; + } + + byte[] ComputePdbHash(Stream sourceStream) + { + var algorithm = GetHashAlgorithm(doc.HashAlgorithm); + if (algorithm != null) + using(algorithm) + return algorithm.ComputeHash(sourceStream); + + return Array.Empty(); + } + + public async Task GetSourceAsync(bool checkHash, CancellationToken token = default(CancellationToken)) + { + if (doc.EmbeddedSource.Length > 0) + return new MemoryStream(doc.EmbeddedSource, false); + + foreach (var url in new [] { SourceUri, SourceLinkUri }) + { + var mem = await GetDataAsync(url, token).ConfigureAwait(false); + if (mem != null && (!checkHash || CheckPdbHash(ComputePdbHash(mem)))) + { + mem.Position = 0; + return mem; + } + } + + return MemoryStream.Null; + } + + public object ToScriptSource(int executionContextId, object executionContextAuxData) + { + return new + { + scriptId = SourceId.ToString(), + url = Url, + executionContextId, + executionContextAuxData, + //hash: should be the v8 hash algo, managed implementation is pending + dotNetUrl = DotNetUrl, + }; + } + } + + internal class DebugStore + { + List assemblies = new List(); + readonly HttpClient client; + readonly ILogger logger; + + public DebugStore(ILogger logger, HttpClient client) + { + this.client = client; + this.logger = logger; + } + + public DebugStore(ILogger logger) : this(logger, new HttpClient()) + { } + + class DebugItem + { + public string Url { get; set; } + public Task Data { get; set; } + } + + public async IAsyncEnumerable Load(SessionId sessionId, string[] loaded_files, [EnumeratorCancellation] CancellationToken token) + { + static bool MatchPdb(string asm, string pdb) => Path.ChangeExtension(asm, "pdb") == pdb; + + var asm_files = new List(); + var pdb_files = new List(); + foreach (var file_name in loaded_files) + { + if (file_name.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase)) + pdb_files.Add(file_name); + else + asm_files.Add(file_name); + } + + List steps = new List(); + foreach (var url in asm_files) + { + try + { + var pdb = pdb_files.FirstOrDefault(n => MatchPdb(url, n)); + steps.Add( + new DebugItem + { + Url = url, + Data = Task.WhenAll(client.GetByteArrayAsync(url), pdb != null ? client.GetByteArrayAsync(pdb) : Task.FromResult(null)) + }); + } + catch (Exception e) + { + logger.LogDebug($"Failed to read {url} ({e.Message})"); + } + } + + var resolver = new DefaultAssemblyResolver(); + foreach (var step in steps) + { + AssemblyInfo assembly = null; + try + { + var bytes = await step.Data.ConfigureAwait(false); + assembly = new AssemblyInfo(resolver, step.Url, bytes[0], bytes[1]); + } + catch (Exception e) + { + logger.LogDebug($"Failed to load {step.Url} ({e.Message})"); + } + if (assembly == null) + continue; + + assemblies.Add(assembly); + foreach (var source in assembly.Sources) + yield return source; + } + } + + public IEnumerable AllSources() => assemblies.SelectMany(a => a.Sources); + + public SourceFile GetFileById(SourceId id) => AllSources().SingleOrDefault(f => f.SourceId.Equals(id)); + + public AssemblyInfo GetAssemblyByName(string name) => assemblies.FirstOrDefault(a => a.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); + + /* + V8 uses zero based indexing for both line and column. + PPDBs uses one based indexing for both line and column. + */ + static bool Match(SequencePoint sp, SourceLocation start, SourceLocation end) + { + var spStart = (Line: sp.StartLine - 1, Column: sp.StartColumn - 1); + var spEnd = (Line: sp.EndLine - 1, Column: sp.EndColumn - 1); + + if (start.Line > spEnd.Line) + return false; + + if (start.Column > spEnd.Column && start.Line == spEnd.Line) + return false; + + if (end.Line < spStart.Line) + return false; + + if (end.Column < spStart.Column && end.Line == spStart.Line) + return false; + + return true; + } + + public List FindPossibleBreakpoints(SourceLocation start, SourceLocation end) + { + //XXX FIXME no idea what todo with locations on different files + if (start.Id != end.Id) + { + logger.LogDebug($"FindPossibleBreakpoints: documents differ (start: {start.Id}) (end {end.Id}"); + return null; + } + + var sourceId = start.Id; + + var doc = GetFileById(sourceId); + + var res = new List(); + if (doc == null) + { + logger.LogDebug($"Could not find document {sourceId}"); + return res; + } + + foreach (var method in doc.Methods) + { + foreach (var sequencePoint in method.DebugInformation.SequencePoints) + { + if (!sequencePoint.IsHidden && Match(sequencePoint, start, end)) + res.Add(new SourceLocation(method, sequencePoint)); + } + } + return res; + } + + /* + V8 uses zero based indexing for both line and column. + PPDBs uses one based indexing for both line and column. + */ + static bool Match(SequencePoint sp, int line, int column) + { + var bp = (line: line + 1, column: column + 1); + + if (sp.StartLine > bp.line || sp.EndLine < bp.line) + return false; + + //Chrome sends a zero column even if getPossibleBreakpoints say something else + if (column == 0) + return true; + + if (sp.StartColumn > bp.column && sp.StartLine == bp.line) + return false; + + if (sp.EndColumn < bp.column && sp.EndLine == bp.line) + return false; + + return true; + } + + public IEnumerable FindBreakpointLocations(BreakpointRequest request) + { + request.TryResolve(this); + + var asm = assemblies.FirstOrDefault(a => a.Name.Equals(request.Assembly, StringComparison.OrdinalIgnoreCase)); + var sourceFile = asm?.Sources?.SingleOrDefault(s => s.DebuggerFileName.Equals(request.File, StringComparison.OrdinalIgnoreCase)); + + if (sourceFile == null) + yield break; + + foreach (var method in sourceFile.Methods) + { + foreach (var sequencePoint in method.DebugInformation.SequencePoints) + { + if (!sequencePoint.IsHidden && Match(sequencePoint, request.Line, request.Column)) + yield return new SourceLocation(method, sequencePoint); + } + } + } + + public string ToUrl(SourceLocation location) => location != null ? GetFileById(location.Id).Url : ""; + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs new file mode 100644 index 000000000000..359411196084 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Net.WebSockets; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.WebAssembly.Diagnostics +{ + + // This type is the public entrypoint that allows external code to attach the debugger proxy + // to a given websocket listener. Everything else in this package can be internal. + + public class DebuggerProxy + { + private readonly MonoProxy proxy; + + public DebuggerProxy(ILoggerFactory loggerFactory) + { + proxy = new MonoProxy(loggerFactory); + } + + public Task Run(Uri browserUri, WebSocket ideSocket) + { + return proxy.Run(browserUri, ideSocket); + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs new file mode 100644 index 000000000000..45edb968a549 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -0,0 +1,304 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + + public struct SessionId + { + public readonly string sessionId; + + public SessionId(string sessionId) + { + this.sessionId = sessionId; + } + + // hashset treats 0 as unset + public override int GetHashCode() => sessionId?.GetHashCode() ?? -1; + + public override bool Equals(object obj) => (obj is SessionId) ? ((SessionId) obj).sessionId == sessionId : false; + + public static bool operator ==(SessionId a, SessionId b) => a.sessionId == b.sessionId; + + public static bool operator !=(SessionId a, SessionId b) => a.sessionId != b.sessionId; + + public static SessionId Null { get; } = new SessionId(); + + public override string ToString() => $"session-{sessionId}"; + } + + public struct MessageId + { + public readonly string sessionId; + public readonly int id; + + public MessageId(string sessionId, int id) + { + this.sessionId = sessionId; + this.id = id; + } + + public static implicit operator SessionId(MessageId id) => new SessionId(id.sessionId); + + public override string ToString() => $"msg-{sessionId}:::{id}"; + + public override int GetHashCode() => (sessionId?.GetHashCode() ?? 0) ^ id.GetHashCode(); + + public override bool Equals(object obj) => (obj is MessageId) ? ((MessageId) obj).sessionId == sessionId && ((MessageId) obj).id == id : false; + } + + internal class DotnetObjectId + { + public string Scheme { get; } + public string Value { get; } + + public static bool TryParse(JToken jToken, out DotnetObjectId objectId) => TryParse(jToken?.Value(), out objectId); + + public static bool TryParse(string id, out DotnetObjectId objectId) + { + objectId = null; + if (id == null) + return false; + + if (!id.StartsWith("dotnet:")) + return false; + + var parts = id.Split(":", 3); + + if (parts.Length < 3) + return false; + + objectId = new DotnetObjectId(parts[1], parts[2]); + + return true; + } + + public DotnetObjectId(string scheme, string value) + { + Scheme = scheme; + Value = value; + } + + public override string ToString() => $"dotnet:{Scheme}:{Value}"; + } + + public struct Result + { + public JObject Value { get; private set; } + public JObject Error { get; private set; } + + public bool IsOk => Value != null; + public bool IsErr => Error != null; + + Result(JObject result, JObject error) + { + if (result != null && error != null) + throw new ArgumentException($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null."); + + bool resultHasError = String.Compare((result?["result"] as JObject) ? ["subtype"]?.Value(), "error") == 0; + if (result != null && resultHasError) + { + this.Value = null; + this.Error = result; + } + else + { + this.Value = result; + this.Error = error; + } + } + + public static Result FromJson(JObject obj) + { + //Log ("protocol", $"from result: {obj}"); + return new Result(obj["result"] as JObject, obj["error"] as JObject); + } + + public static Result Ok(JObject ok) => new Result(ok, null); + + public static Result OkFromObject(object ok) => Ok(JObject.FromObject(ok)); + + public static Result Err(JObject err) => new Result(null, err); + + public static Result Err(string msg) => new Result(null, JObject.FromObject(new { message = msg })); + + public static Result Exception(Exception e) => new Result(null, JObject.FromObject(new { message = e.Message })); + + public JObject ToJObject(MessageId target) + { + if (IsOk) + { + return JObject.FromObject(new + { + target.id, + target.sessionId, + result = Value + }); + } + else + { + return JObject.FromObject(new + { + target.id, + target.sessionId, + error = Error + }); + } + } + + public override string ToString() + { + return $"[Result: IsOk: {IsOk}, IsErr: {IsErr}, Value: {Value?.ToString ()}, Error: {Error?.ToString ()} ]"; + } + } + + internal class MonoCommands + { + public string expression { get; set; } + public string objectGroup { get; set; } = "mono-debugger"; + public bool includeCommandLineAPI { get; set; } = false; + public bool silent { get; set; } = false; + public bool returnByValue { get; set; } = true; + + public MonoCommands(string expression) => this.expression = expression; + + public static MonoCommands GetCallStack() => new MonoCommands("MONO.mono_wasm_get_call_stack()"); + + public static MonoCommands IsRuntimeReady() => new MonoCommands("MONO.mono_wasm_runtime_is_ready"); + + public static MonoCommands StartSingleStepping(StepKind kind) => new MonoCommands($"MONO.mono_wasm_start_single_stepping ({(int)kind})"); + + public static MonoCommands GetLoadedFiles() => new MonoCommands("MONO.mono_wasm_get_loaded_files()"); + + public static MonoCommands ClearAllBreakpoints() => new MonoCommands("MONO.mono_wasm_clear_all_breakpoints()"); + + public static MonoCommands GetDetails(DotnetObjectId objectId, JToken args = null) => new MonoCommands($"MONO.mono_wasm_get_details ('{objectId}', {(args ?? "{ }")})"); + + public static MonoCommands GetScopeVariables(int scopeId, params VarInfo[] vars) + { + var var_ids = vars.Select(v => new { index = v.Index, name = v.Name }).ToArray(); + return new MonoCommands($"MONO.mono_wasm_get_variables({scopeId}, {JsonConvert.SerializeObject (var_ids)})"); + } + + public static MonoCommands SetBreakpoint(string assemblyName, uint methodToken, int ilOffset) => new MonoCommands($"MONO.mono_wasm_set_breakpoint (\"{assemblyName}\", {methodToken}, {ilOffset})"); + + public static MonoCommands RemoveBreakpoint(int breakpointId) => new MonoCommands($"MONO.mono_wasm_remove_breakpoint({breakpointId})"); + + public static MonoCommands ReleaseObject(DotnetObjectId objectId) => new MonoCommands($"MONO.mono_wasm_release_object('{objectId}')"); + + public static MonoCommands CallFunctionOn(JToken args) => new MonoCommands($"MONO.mono_wasm_call_function_on ({args.ToString ()})"); + + public static MonoCommands Resume() => new MonoCommands($"MONO.mono_wasm_debugger_resume ()"); + } + + internal enum MonoErrorCodes + { + BpNotFound = 100000, + } + + internal class MonoConstants + { + public const string RUNTIME_IS_READY = "mono_wasm_runtime_ready"; + } + + class Frame + { + public Frame(MethodInfo method, SourceLocation location, int id) + { + this.Method = method; + this.Location = location; + this.Id = id; + } + + public MethodInfo Method { get; private set; } + public SourceLocation Location { get; private set; } + public int Id { get; private set; } + } + + class Breakpoint + { + public SourceLocation Location { get; private set; } + public int RemoteId { get; set; } + public BreakpointState State { get; set; } + public string StackId { get; private set; } + + public static bool TryParseId(string stackId, out int id) + { + id = -1; + if (stackId?.StartsWith("dotnet:", StringComparison.Ordinal) != true) + return false; + + return int.TryParse(stackId.Substring("dotnet:".Length), out id); + } + + public Breakpoint(string stackId, SourceLocation loc, BreakpointState state) + { + this.StackId = stackId; + this.Location = loc; + this.State = state; + } + } + + enum BreakpointState + { + Active, + Disabled, + Pending + } + + enum StepKind + { + Into, + Out, + Over + } + + internal class ExecutionContext + { + public string DebuggerId { get; set; } + public Dictionary BreakpointRequests { get; } = new Dictionary(); + + public TaskCompletionSource ready = null; + public bool IsRuntimeReady => ready != null && ready.Task.IsCompleted; + + public int Id { get; set; } + public object AuxData { get; set; } + + public List CallStack { get; set; } + + public string[] LoadedFiles { get; set; } + internal DebugStore store; + public TaskCompletionSource Source { get; } = new TaskCompletionSource(); + + public Dictionary LocalsCache = new Dictionary(); + + public DebugStore Store + { + get + { + if (store == null || !Source.Task.IsCompleted) + return null; + + return store; + } + } + + public void ClearState() + { + CallStack = null; + LocalsCache.Clear(); + } + + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs new file mode 100644 index 000000000000..656bd91c5091 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs @@ -0,0 +1,381 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + + class DevToolsQueue + { + Task current_send; + List pending; + + public WebSocket Ws { get; private set; } + public Task CurrentSend { get { return current_send; } } + public DevToolsQueue(WebSocket sock) + { + this.Ws = sock; + pending = new List(); + } + + public Task Send(byte[] bytes, CancellationToken token) + { + pending.Add(bytes); + if (pending.Count == 1) + { + if (current_send != null) + throw new Exception("current_send MUST BE NULL IF THERE'S no pending send"); + //logger.LogTrace ("sending {0} bytes", bytes.Length); + current_send = Ws.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, token); + return current_send; + } + return null; + } + + public Task Pump(CancellationToken token) + { + current_send = null; + pending.RemoveAt(0); + + if (pending.Count > 0) + { + if (current_send != null) + throw new Exception("current_send MUST BE NULL IF THERE'S no pending send"); + + current_send = Ws.SendAsync(new ArraySegment(pending[0]), WebSocketMessageType.Text, true, token); + return current_send; + } + return null; + } + } + + internal class DevToolsProxy + { + TaskCompletionSource side_exception = new TaskCompletionSource(); + TaskCompletionSource client_initiated_close = new TaskCompletionSource(); + Dictionary> pending_cmds = new Dictionary>(); + ClientWebSocket browser; + WebSocket ide; + int next_cmd_id; + List pending_ops = new List(); + List queues = new List(); + + protected readonly ILogger logger; + + public DevToolsProxy(ILoggerFactory loggerFactory) + { + logger = loggerFactory.CreateLogger(); + } + + protected virtual Task AcceptEvent(SessionId sessionId, string method, JObject args, CancellationToken token) + { + return Task.FromResult(false); + } + + protected virtual Task AcceptCommand(MessageId id, string method, JObject args, CancellationToken token) + { + return Task.FromResult(false); + } + + async Task ReadOne(WebSocket socket, CancellationToken token) + { + byte[] buff = new byte[4000]; + var mem = new MemoryStream(); + while (true) + { + + if (socket.State != WebSocketState.Open) + { + Log("error", $"DevToolsProxy: Socket is no longer open."); + client_initiated_close.TrySetResult(true); + return null; + } + + var result = await socket.ReceiveAsync(new ArraySegment(buff), token); + if (result.MessageType == WebSocketMessageType.Close) + { + client_initiated_close.TrySetResult(true); + return null; + } + + mem.Write(buff, 0, result.Count); + + if (result.EndOfMessage) + return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int) mem.Length); + } + } + + DevToolsQueue GetQueueForSocket(WebSocket ws) + { + return queues.FirstOrDefault(q => q.Ws == ws); + } + + DevToolsQueue GetQueueForTask(Task task) + { + return queues.FirstOrDefault(q => q.CurrentSend == task); + } + + void Send(WebSocket to, JObject o, CancellationToken token) + { + var sender = browser == to ? "Send-browser" : "Send-ide"; + + var method = o["method"]?.ToString(); + //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") + Log("protocol", $"{sender}: " + JsonConvert.SerializeObject(o)); + var bytes = Encoding.UTF8.GetBytes(o.ToString()); + + var queue = GetQueueForSocket(to); + + var task = queue.Send(bytes, token); + if (task != null) + pending_ops.Add(task); + } + + async Task OnEvent(SessionId sessionId, string method, JObject args, CancellationToken token) + { + try + { + if (!await AcceptEvent(sessionId, method, args, token)) + { + //logger.LogDebug ("proxy browser: {0}::{1}",method, args); + SendEventInternal(sessionId, method, args, token); + } + } + catch (Exception e) + { + side_exception.TrySetException(e); + } + } + + async Task OnCommand(MessageId id, string method, JObject args, CancellationToken token) + { + try + { + if (!await AcceptCommand(id, method, args, token)) + { + var res = await SendCommandInternal(id, method, args, token); + SendResponseInternal(id, res, token); + } + } + catch (Exception e) + { + side_exception.TrySetException(e); + } + } + + void OnResponse(MessageId id, Result result) + { + //logger.LogTrace ("got id {0} res {1}", id, result); + // Fixme + if (pending_cmds.Remove(id, out var task)) + { + task.SetResult(result); + return; + } + logger.LogError("Cannot respond to command: {id} with result: {result} - command is not pending", id, result); + } + + void ProcessBrowserMessage(string msg, CancellationToken token) + { + var res = JObject.Parse(msg); + + var method = res["method"]?.ToString(); + //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") + Log("protocol", $"browser: {msg}"); + + if (res["id"] == null) + pending_ops.Add(OnEvent(new SessionId(res["sessionId"]?.Value()), res["method"].Value(), res["params"] as JObject, token)); + else + OnResponse(new MessageId(res["sessionId"]?.Value(), res["id"].Value()), Result.FromJson(res)); + } + + void ProcessIdeMessage(string msg, CancellationToken token) + { + Log("protocol", $"ide: {msg}"); + if (!string.IsNullOrEmpty(msg)) + { + var res = JObject.Parse(msg); + pending_ops.Add(OnCommand( + new MessageId(res["sessionId"]?.Value(), res["id"].Value()), + res["method"].Value(), + res["params"] as JObject, token)); + } + } + + internal async Task SendCommand(SessionId id, string method, JObject args, CancellationToken token) + { + //Log ("verbose", $"sending command {method}: {args}"); + return await SendCommandInternal(id, method, args, token); + } + + Task SendCommandInternal(SessionId sessionId, string method, JObject args, CancellationToken token) + { + int id = Interlocked.Increment(ref next_cmd_id); + + var o = JObject.FromObject(new + { + id, + method, + @params = args + }); + if (sessionId.sessionId != null) + o["sessionId"] = sessionId.sessionId; + var tcs = new TaskCompletionSource(); + + var msgId = new MessageId(sessionId.sessionId, id); + //Log ("verbose", $"add cmd id {sessionId}-{id}"); + pending_cmds[msgId] = tcs; + + Send(this.browser, o, token); + return tcs.Task; + } + + public void SendEvent(SessionId sessionId, string method, JObject args, CancellationToken token) + { + //Log ("verbose", $"sending event {method}: {args}"); + SendEventInternal(sessionId, method, args, token); + } + + void SendEventInternal(SessionId sessionId, string method, JObject args, CancellationToken token) + { + var o = JObject.FromObject(new + { + method, + @params = args + }); + if (sessionId.sessionId != null) + o["sessionId"] = sessionId.sessionId; + + Send(this.ide, o, token); + } + + internal void SendResponse(MessageId id, Result result, CancellationToken token) + { + SendResponseInternal(id, result, token); + } + + void SendResponseInternal(MessageId id, Result result, CancellationToken token) + { + JObject o = result.ToJObject(id); + if (result.IsErr) + logger.LogError($"sending error response for id: {id} -> {result}"); + + Send(this.ide, o, token); + } + + // , HttpContext context) + public async Task Run(Uri browserUri, WebSocket ideSocket) + { + Log("info", $"DevToolsProxy: Starting on {browserUri}"); + using(this.ide = ideSocket) + { + Log("verbose", $"DevToolsProxy: IDE waiting for connection on {browserUri}"); + queues.Add(new DevToolsQueue(this.ide)); + using(this.browser = new ClientWebSocket()) + { + this.browser.Options.KeepAliveInterval = Timeout.InfiniteTimeSpan; + await this.browser.ConnectAsync(browserUri, CancellationToken.None); + queues.Add(new DevToolsQueue(this.browser)); + + Log("verbose", $"DevToolsProxy: Client connected on {browserUri}"); + var x = new CancellationTokenSource(); + + pending_ops.Add(ReadOne(browser, x.Token)); + pending_ops.Add(ReadOne(ide, x.Token)); + pending_ops.Add(side_exception.Task); + pending_ops.Add(client_initiated_close.Task); + + try + { + while (!x.IsCancellationRequested) + { + var task = await Task.WhenAny(pending_ops.ToArray()); + //logger.LogTrace ("pump {0} {1}", task, pending_ops.IndexOf (task)); + if (task == pending_ops[0]) + { + var msg = ((Task) task).Result; + if (msg != null) + { + pending_ops[0] = ReadOne(browser, x.Token); //queue next read + ProcessBrowserMessage(msg, x.Token); + } + } + else if (task == pending_ops[1]) + { + var msg = ((Task) task).Result; + if (msg != null) + { + pending_ops[1] = ReadOne(ide, x.Token); //queue next read + ProcessIdeMessage(msg, x.Token); + } + } + else if (task == pending_ops[2]) + { + var res = ((Task) task).Result; + throw new Exception("side task must always complete with an exception, what's going on???"); + } + else if (task == pending_ops[3]) + { + var res = ((Task) task).Result; + Log("verbose", $"DevToolsProxy: Client initiated close from {browserUri}"); + x.Cancel(); + } + else + { + //must be a background task + pending_ops.Remove(task); + var queue = GetQueueForTask(task); + if (queue != null) + { + var tsk = queue.Pump(x.Token); + if (tsk != null) + pending_ops.Add(tsk); + } + } + } + } + catch (Exception e) + { + Log("error", $"DevToolsProxy::Run: Exception {e}"); + //throw; + } + finally + { + if (!x.IsCancellationRequested) + x.Cancel(); + } + } + } + } + + protected void Log(string priority, string msg) + { + switch (priority) + { + case "protocol": + logger.LogTrace(msg); + break; + case "verbose": + logger.LogDebug(msg); + break; + case "info": + case "warning": + case "error": + default: + logger.LogDebug(msg); + break; + } + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs new file mode 100644 index 000000000000..982fa87592a6 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs @@ -0,0 +1,213 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Emit; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + + internal class EvaluateExpression + { + + class FindThisExpression : CSharpSyntaxWalker + { + public List thisExpressions = new List(); + public SyntaxTree syntaxTree; + public FindThisExpression(SyntaxTree syntax) + { + syntaxTree = syntax; + } + public override void Visit(SyntaxNode node) + { + if (node is ThisExpressionSyntax) + { + if (node.Parent is MemberAccessExpressionSyntax thisParent && thisParent.Name is IdentifierNameSyntax) + { + IdentifierNameSyntax var = thisParent.Name as IdentifierNameSyntax; + thisExpressions.Add(var.Identifier.Text); + var newRoot = syntaxTree.GetRoot().ReplaceNode(node.Parent, thisParent.Name); + syntaxTree = syntaxTree.WithRootAndOptions(newRoot, syntaxTree.Options); + this.Visit(GetExpressionFromSyntaxTree(syntaxTree)); + } + } + else + base.Visit(node); + } + + public async Task CheckIfIsProperty(MonoProxy proxy, MessageId msg_id, int scope_id, CancellationToken token) + { + foreach (var var in thisExpressions) + { + JToken value = await proxy.TryGetVariableValue(msg_id, scope_id, var, true, token); + if (value == null) + throw new Exception($"The property {var} does not exist in the current context"); + } + } + } + + class FindVariableNMethodCall : CSharpSyntaxWalker + { + public List variables = new List(); + public List thisList = new List(); + public List methodCall = new List(); + public List values = new List(); + + public override void Visit(SyntaxNode node) + { + if (node is IdentifierNameSyntax identifier && !variables.Any(x => x.Identifier.Text == identifier.Identifier.Text)) + variables.Add(identifier); + if (node is InvocationExpressionSyntax) + { + methodCall.Add(node as InvocationExpressionSyntax); + throw new Exception("Method Call is not implemented yet"); + } + if (node is AssignmentExpressionSyntax) + throw new Exception("Assignment is not implemented yet"); + base.Visit(node); + } + public async Task ReplaceVars(SyntaxTree syntaxTree, MonoProxy proxy, MessageId msg_id, int scope_id, CancellationToken token) + { + CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot(); + foreach (var var in variables) + { + ClassDeclarationSyntax classDeclaration = root.Members.ElementAt(0) as ClassDeclarationSyntax; + MethodDeclarationSyntax method = classDeclaration.Members.ElementAt(0) as MethodDeclarationSyntax; + + JToken value = await proxy.TryGetVariableValue(msg_id, scope_id, var.Identifier.Text, false, token); + + if (value == null) + throw new Exception($"The name {var.Identifier.Text} does not exist in the current context"); + + values.Add(ConvertJSToCSharpType(value["value"])); + + var updatedMethod = method.AddParameterListParameters( + SyntaxFactory.Parameter( + SyntaxFactory.Identifier(var.Identifier.Text)) + .WithType(SyntaxFactory.ParseTypeName(GetTypeFullName(value["value"])))); + root = root.ReplaceNode(method, updatedMethod); + } + syntaxTree = syntaxTree.WithRootAndOptions(root, syntaxTree.Options); + return syntaxTree; + } + + private object ConvertJSToCSharpType(JToken variable) + { + var value = variable["value"]; + var type = variable["type"].Value(); + var subType = variable["subtype"]?.Value(); + + switch (type) + { + case "string": + return value?.Value(); + case "number": + return value?.Value(); + case "boolean": + return value?.Value(); + case "object": + if (subType == "null") + return null; + break; + } + throw new Exception($"Evaluate of this datatype {type} not implemented yet"); + } + + private string GetTypeFullName(JToken variable) + { + var type = variable["type"].ToString(); + var subType = variable["subtype"]?.Value(); + object value = ConvertJSToCSharpType(variable); + + switch (type) + { + case "object": + { + if (subType == "null") + return variable["className"].Value(); + break; + } + default: + return value.GetType().FullName; + } + throw new Exception($"Evaluate of this datatype {type} not implemented yet"); + } + } + + static SyntaxNode GetExpressionFromSyntaxTree(SyntaxTree syntaxTree) + { + CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot(); + ClassDeclarationSyntax classDeclaration = root.Members.ElementAt(0) as ClassDeclarationSyntax; + MethodDeclarationSyntax methodDeclaration = classDeclaration.Members.ElementAt(0) as MethodDeclarationSyntax; + BlockSyntax blockValue = methodDeclaration.Body; + ReturnStatementSyntax returnValue = blockValue.Statements.ElementAt(0) as ReturnStatementSyntax; + InvocationExpressionSyntax expressionInvocation = returnValue.Expression as InvocationExpressionSyntax; + MemberAccessExpressionSyntax expressionMember = expressionInvocation.Expression as MemberAccessExpressionSyntax; + ParenthesizedExpressionSyntax expressionParenthesized = expressionMember.Expression as ParenthesizedExpressionSyntax; + return expressionParenthesized.Expression; + } + + internal static async Task CompileAndRunTheExpression(MonoProxy proxy, MessageId msg_id, int scope_id, string expression, CancellationToken token) + { + FindVariableNMethodCall findVarNMethodCall = new FindVariableNMethodCall(); + string retString; + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(@" + using System; + public class CompileAndRunTheExpression + { + public string Evaluate() + { + return (" + expression + @").ToString(); + } + }"); + + FindThisExpression findThisExpression = new FindThisExpression(syntaxTree); + var expressionTree = GetExpressionFromSyntaxTree(syntaxTree); + findThisExpression.Visit(expressionTree); + await findThisExpression.CheckIfIsProperty(proxy, msg_id, scope_id, token); + syntaxTree = findThisExpression.syntaxTree; + + expressionTree = GetExpressionFromSyntaxTree(syntaxTree); + findVarNMethodCall.Visit(expressionTree); + + syntaxTree = await findVarNMethodCall.ReplaceVars(syntaxTree, proxy, msg_id, scope_id, token); + + MetadataReference[] references = new MetadataReference[] + { + MetadataReference.CreateFromFile(typeof(object).Assembly.Location), + MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location) + }; + + CSharpCompilation compilation = CSharpCompilation.Create( + "compileAndRunTheExpression", + syntaxTrees : new [] { syntaxTree }, + references : references, + options : new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + using(var ms = new MemoryStream()) + { + EmitResult result = compilation.Emit(ms); + ms.Seek(0, SeekOrigin.Begin); + Assembly assembly = Assembly.Load(ms.ToArray()); + Type type = assembly.GetType("CompileAndRunTheExpression"); + object obj = Activator.CreateInstance(type); + var ret = type.InvokeMember("Evaluate", + BindingFlags.Default | BindingFlags.InvokeMethod, + null, + obj, + findVarNMethodCall.values.ToArray()); + retString = ret.ToString(); + } + return retString; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs new file mode 100644 index 000000000000..197d499cb897 --- /dev/null +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -0,0 +1,998 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + + internal class MonoProxy : DevToolsProxy + { + HashSet sessions = new HashSet(); + Dictionary contexts = new Dictionary(); + + public MonoProxy(ILoggerFactory loggerFactory, bool hideWebDriver = true) : base(loggerFactory) { hideWebDriver = true; } + + readonly bool hideWebDriver; + + internal ExecutionContext GetContext(SessionId sessionId) + { + if (contexts.TryGetValue(sessionId, out var context)) + return context; + + throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId)); + } + + bool UpdateContext(SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext) + { + var previous = contexts.TryGetValue(sessionId, out previousExecutionContext); + contexts[sessionId] = executionContext; + return previous; + } + + internal Task SendMonoCommand(SessionId id, MonoCommands cmd, CancellationToken token) => SendCommand(id, "Runtime.evaluate", JObject.FromObject(cmd), token); + + protected override async Task AcceptEvent(SessionId sessionId, string method, JObject args, CancellationToken token) + { + switch (method) + { + case "Runtime.consoleAPICalled": + { + var type = args["type"]?.ToString(); + if (type == "debug") + { + var a = args["args"]; + if (a?[0] ? ["value"]?.ToString() == MonoConstants.RUNTIME_IS_READY && + a?[1] ? ["value"]?.ToString() == "fe00e07a-5519-4dfe-b35a-f867dbaf2e28") + { + if (a.Count() > 2) + { + try + { + // The optional 3rd argument is the stringified assembly + // list so that we don't have to make more round trips + var context = GetContext(sessionId); + var loaded = a?[2] ? ["value"]?.ToString(); + if (loaded != null) + context.LoadedFiles = JToken.Parse(loaded).ToObject(); + } + catch (InvalidCastException ice) + { + Log("verbose", ice.ToString()); + } + } + await RuntimeReady(sessionId, token); + } + + } + break; + } + + case "Runtime.executionContextCreated": + { + SendEvent(sessionId, method, args, token); + var ctx = args?["context"]; + var aux_data = ctx?["auxData"] as JObject; + var id = ctx["id"].Value(); + if (aux_data != null) + { + var is_default = aux_data["isDefault"]?.Value(); + if (is_default == true) + { + await OnDefaultContext(sessionId, new ExecutionContext { Id = id, AuxData = aux_data }, token); + } + } + return true; + } + + case "Debugger.paused": + { + //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack + var top_func = args?["callFrames"] ? [0] ? ["functionName"]?.Value(); + + if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") + { + return await OnBreakpointHit(sessionId, args, token); + } + break; + } + + case "Debugger.breakpointResolved": + { + break; + } + + case "Debugger.scriptParsed": + { + var url = args?["url"]?.Value() ?? ""; + + switch (url) + { + case var _ when url == "": + case var _ when url.StartsWith("wasm://", StringComparison.Ordinal): + { + Log("verbose", $"ignoring wasm: Debugger.scriptParsed {url}"); + return true; + } + } + Log("verbose", $"proxying Debugger.scriptParsed ({sessionId.sessionId}) {url} {args}"); + break; + } + + case "Target.attachedToTarget": + { + if (args["targetInfo"]["type"]?.ToString() == "page") + await DeleteWebDriver(new SessionId(args["sessionId"]?.ToString()), token); + break; + } + + } + + return false; + } + + async Task IsRuntimeAlreadyReadyAlready(SessionId sessionId, CancellationToken token) + { + if (contexts.TryGetValue(sessionId, out var context) && context.IsRuntimeReady) + return true; + + var res = await SendMonoCommand(sessionId, MonoCommands.IsRuntimeReady(), token); + return res.Value?["result"] ? ["value"]?.Value() ?? false; + } + + static int bpIdGenerator; + + protected override async Task AcceptCommand(MessageId id, string method, JObject args, CancellationToken token) + { + // Inspector doesn't use the Target domain or sessions + // so we try to init immediately + if (hideWebDriver && id == SessionId.Null) + await DeleteWebDriver(id, token); + + if (!contexts.TryGetValue(id, out var context)) + return false; + + switch (method) + { + case "Target.attachToTarget": + { + var resp = await SendCommand(id, method, args, token); + await DeleteWebDriver(new SessionId(resp.Value["sessionId"]?.ToString()), token); + break; + } + + case "Debugger.enable": + { + System.Console.WriteLine("recebi o Debugger.enable"); + var resp = await SendCommand(id, method, args, token); + + context.DebuggerId = resp.Value["debuggerId"]?.ToString(); + + if (await IsRuntimeAlreadyReadyAlready(id, token)) + await RuntimeReady(id, token); + + SendResponse(id, resp, token); + return true; + } + + case "Debugger.getScriptSource": + { + var script = args?["scriptId"]?.Value(); + return await OnGetScriptSource(id, script, token); + } + + case "Runtime.compileScript": + { + var exp = args?["expression"]?.Value(); + if (exp.StartsWith("//dotnet:", StringComparison.Ordinal)) + { + OnCompileDotnetScript(id, token); + return true; + } + break; + } + + case "Debugger.getPossibleBreakpoints": + { + var resp = await SendCommand(id, method, args, token); + if (resp.IsOk && resp.Value["locations"].HasValues) + { + SendResponse(id, resp, token); + return true; + } + + var start = SourceLocation.Parse(args?["start"] as JObject); + //FIXME support variant where restrictToFunction=true and end is omitted + var end = SourceLocation.Parse(args?["end"] as JObject); + if (start != null && end != null && await GetPossibleBreakpoints(id, start, end, token)) + return true; + + SendResponse(id, resp, token); + return true; + } + + case "Debugger.setBreakpoint": + { + break; + } + + case "Debugger.setBreakpointByUrl": + { + var resp = await SendCommand(id, method, args, token); + if (!resp.IsOk) + { + SendResponse(id, resp, token); + return true; + } + + var bpid = resp.Value["breakpointId"]?.ToString(); + var locations = resp.Value["locations"]?.Values(); + var request = BreakpointRequest.Parse(bpid, args); + + // is the store done loading? + var loaded = context.Source.Task.IsCompleted; + if (!loaded) + { + // Send and empty response immediately if not + // and register the breakpoint for resolution + context.BreakpointRequests[bpid] = request; + SendResponse(id, resp, token); + } + + if (await IsRuntimeAlreadyReadyAlready(id, token)) + { + var store = await RuntimeReady(id, token); + + Log("verbose", $"BP req {args}"); + await SetBreakpoint(id, store, request, !loaded, token); + } + + if (loaded) + { + // we were already loaded so we should send a response + // with the locations included and register the request + context.BreakpointRequests[bpid] = request; + var result = Result.OkFromObject(request.AsSetBreakpointByUrlResponse(locations)); + SendResponse(id, result, token); + + } + return true; + } + + case "Debugger.removeBreakpoint": + { + await RemoveBreakpoint(id, args, token); + break; + } + + case "Debugger.resume": + { + await OnResume(id, token); + break; + } + + case "Debugger.stepInto": + { + return await Step(id, StepKind.Into, token); + } + + case "Debugger.stepOut": + { + return await Step(id, StepKind.Out, token); + } + + case "Debugger.stepOver": + { + return await Step(id, StepKind.Over, token); + } + + case "Debugger.evaluateOnCallFrame": + { + if (!DotnetObjectId.TryParse(args?["callFrameId"], out var objectId)) + return false; + + switch (objectId.Scheme) + { + case "scope": + return await OnEvaluateOnCallFrame(id, + int.Parse(objectId.Value), + args?["expression"]?.Value(), token); + default: + return false; + } + } + + case "Runtime.getProperties": + { + if (!DotnetObjectId.TryParse(args?["objectId"], out var objectId)) + break; + + var result = await RuntimeGetProperties(id, objectId, args, token); + SendResponse(id, result, token); + return true; + } + + case "Runtime.releaseObject": + { + if (!(DotnetObjectId.TryParse(args["objectId"], out var objectId) && objectId.Scheme == "cfo_res")) + break; + + await SendMonoCommand(id, MonoCommands.ReleaseObject(objectId), token); + SendResponse(id, Result.OkFromObject(new { }), token); + return true; + } + + // Protocol extensions + case "DotnetDebugger.getMethodLocation": + { + Console.WriteLine("set-breakpoint-by-method: " + id + " " + args); + + var store = await RuntimeReady(id, token); + string aname = args["assemblyName"]?.Value(); + string typeName = args["typeName"]?.Value(); + string methodName = args["methodName"]?.Value(); + if (aname == null || typeName == null || methodName == null) + { + SendResponse(id, Result.Err("Invalid protocol message '" + args + "'."), token); + return true; + } + + // GetAssemblyByName seems to work on file names + var assembly = store.GetAssemblyByName(aname); + if (assembly == null) + assembly = store.GetAssemblyByName(aname + ".exe"); + if (assembly == null) + assembly = store.GetAssemblyByName(aname + ".dll"); + if (assembly == null) + { + SendResponse(id, Result.Err("Assembly '" + aname + "' not found."), token); + return true; + } + + var type = assembly.GetTypeByName(typeName); + if (type == null) + { + SendResponse(id, Result.Err($"Type '{typeName}' not found."), token); + return true; + } + + var methodInfo = type.Methods.FirstOrDefault(m => m.Name == methodName); + if (methodInfo == null) + { + // Maybe this is an async method, in which case the debug info is attached + // to the async method implementation, in class named: + // `{type_name}/::MoveNext` + methodInfo = assembly.TypesByName.Values.SingleOrDefault(t => t.FullName.StartsWith($"{typeName}/<{methodName}>")) ? + .Methods.FirstOrDefault(mi => mi.Name == "MoveNext"); + } + + if (methodInfo == null) + { + SendResponse(id, Result.Err($"Method '{typeName}:{methodName}' not found."), token); + return true; + } + + var src_url = methodInfo.Assembly.Sources.Single(sf => sf.SourceId == methodInfo.SourceId).Url; + SendResponse(id, Result.OkFromObject(new + { + result = new { line = methodInfo.StartLocation.Line, column = methodInfo.StartLocation.Column, url = src_url } + }), token); + + return true; + } + case "Runtime.callFunctionOn": + { + if (!DotnetObjectId.TryParse(args["objectId"], out var objectId)) + return false; + + if (objectId.Scheme == "scope") + { + SendResponse(id, + Result.Exception(new ArgumentException( + $"Runtime.callFunctionOn not supported with scope ({objectId}).")), + token); + return true; + } + + var res = await SendMonoCommand(id, MonoCommands.CallFunctionOn(args), token); + var res_value_type = res.Value?["result"] ? ["value"]?.Type; + + if (res.IsOk && res_value_type == JTokenType.Object || res_value_type == JTokenType.Object) + res = Result.OkFromObject(new { result = res.Value["result"]["value"] }); + + SendResponse(id, res, token); + return true; + } + } + + return false; + } + + async Task RuntimeGetProperties(MessageId id, DotnetObjectId objectId, JToken args, CancellationToken token) + { + if (objectId.Scheme == "scope") + return await GetScopeProperties(id, int.Parse(objectId.Value), token); + + var res = await SendMonoCommand(id, MonoCommands.GetDetails(objectId, args), token); + if (res.IsErr) + return res; + + if (objectId.Scheme == "cfo_res") + { + // Runtime.callFunctionOn result object + var value_json_str = res.Value["result"] ? ["value"] ? ["__value_as_json_string__"]?.Value(); + if (value_json_str != null) + { + res = Result.OkFromObject(new + { + result = JArray.Parse(value_json_str) + }); + } + else + { + res = Result.OkFromObject(new { result = new { } }); + } + } + else + { + res = Result.Ok(JObject.FromObject(new { result = res.Value["result"]["value"] })); + } + + return res; + } + + //static int frame_id=0; + async Task OnBreakpointHit(SessionId sessionId, JObject args, CancellationToken token) + { + //FIXME we should send release objects every now and then? Or intercept those we inject and deal in the runtime + var res = await SendMonoCommand(sessionId, MonoCommands.GetCallStack(), token); + var orig_callframes = args?["callFrames"]?.Values(); + var context = GetContext(sessionId); + + if (res.IsErr) + { + //Give up and send the original call stack + return false; + } + + //step one, figure out where did we hit + var res_value = res.Value?["result"] ? ["value"]; + if (res_value == null || res_value is JValue) + { + //Give up and send the original call stack + return false; + } + + Log("verbose", $"call stack (err is {res.Error} value is:\n{res.Value}"); + var bp_id = res_value?["breakpoint_id"]?.Value(); + Log("verbose", $"We just hit bp {bp_id}"); + if (!bp_id.HasValue) + { + //Give up and send the original call stack + return false; + } + + var bp = context.BreakpointRequests.Values.SelectMany(v => v.Locations).FirstOrDefault(b => b.RemoteId == bp_id.Value); + + var callFrames = new List(); + foreach (var frame in orig_callframes) + { + var function_name = frame["functionName"]?.Value(); + var url = frame["url"]?.Value(); + if ("mono_wasm_fire_bp" == function_name ||"_mono_wasm_fire_bp" == function_name) + { + var frames = new List(); + int frame_id = 0; + var the_mono_frames = res.Value?["result"] ? ["value"] ? ["frames"]?.Values(); + + foreach (var mono_frame in the_mono_frames) + { + ++frame_id; + var il_pos = mono_frame["il_pos"].Value(); + var method_token = mono_frame["method_token"].Value(); + var assembly_name = mono_frame["assembly_name"].Value(); + + // This can be different than `method.Name`, like in case of generic methods + var method_name = mono_frame["method_name"]?.Value(); + + var store = await LoadStore(sessionId, token); + var asm = store.GetAssemblyByName(assembly_name); + if (asm == null) + { + Log("info", $"Unable to find assembly: {assembly_name}"); + continue; + } + + var method = asm.GetMethodByToken(method_token); + + if (method == null) + { + Log("info", $"Unable to find il offset: {il_pos} in method token: {method_token} assembly name: {assembly_name}"); + continue; + } + + var location = method?.GetLocationByIl(il_pos); + + // When hitting a breakpoint on the "IncrementCount" method in the standard + // Blazor project template, one of the stack frames is inside mscorlib.dll + // and we get location==null for it. It will trigger a NullReferenceException + // if we don't skip over that stack frame. + if (location == null) + { + continue; + } + + Log("info", $"frame il offset: {il_pos} method token: {method_token} assembly name: {assembly_name}"); + Log("info", $"\tmethod {method_name} location: {location}"); + frames.Add(new Frame(method, location, frame_id - 1)); + + callFrames.Add(new + { + functionName = method_name, + callFrameId = $"dotnet:scope:{frame_id-1}", + functionLocation = method.StartLocation.AsLocation(), + + location = location.AsLocation(), + + url = store.ToUrl(location), + + scopeChain = new [] + { + new + { + type = "local", + @object = new + { + @type = "object", + className = "Object", + description = "Object", + objectId = $"dotnet:scope:{frame_id-1}", + }, + name = method_name, + startLocation = method.StartLocation.AsLocation(), + endLocation = method.EndLocation.AsLocation(), + } + } + }); + + context.CallStack = frames; + + } + } + else if (!(function_name.StartsWith("wasm-function", StringComparison.Ordinal) || + url.StartsWith("wasm://wasm/", StringComparison.Ordinal))) + { + callFrames.Add(frame); + } + } + + var bp_list = new string[bp == null ? 0 : 1]; + if (bp != null) + bp_list[0] = bp.StackId; + + var o = JObject.FromObject(new + { + callFrames, + reason = "other", //other means breakpoint + hitBreakpoints = bp_list, + }); + + SendEvent(sessionId, "Debugger.paused", o, token); + return true; + } + + async Task OnDefaultContext(SessionId sessionId, ExecutionContext context, CancellationToken token) + { + Log("verbose", "Default context created, clearing state and sending events"); + if (UpdateContext(sessionId, context, out var previousContext)) + { + foreach (var kvp in previousContext.BreakpointRequests) + { + context.BreakpointRequests[kvp.Key] = kvp.Value.Clone(); + } + } + + if (await IsRuntimeAlreadyReadyAlready(sessionId, token)) + await RuntimeReady(sessionId, token); + } + + async Task OnResume(MessageId msg_id, CancellationToken token) + { + var ctx = GetContext(msg_id); + if (ctx.CallStack != null) + { + // Stopped on managed code + await SendMonoCommand(msg_id, MonoCommands.Resume(), token); + } + + //discard managed frames + GetContext(msg_id).ClearState(); + } + + async Task Step(MessageId msg_id, StepKind kind, CancellationToken token) + { + var context = GetContext(msg_id); + if (context.CallStack == null) + return false; + + if (context.CallStack.Count <= 1 && kind == StepKind.Out) + return false; + + var res = await SendMonoCommand(msg_id, MonoCommands.StartSingleStepping(kind), token); + + var ret_code = res.Value?["result"] ? ["value"]?.Value(); + + if (ret_code.HasValue && ret_code.Value == 0) + { + context.ClearState(); + await SendCommand(msg_id, "Debugger.stepOut", new JObject(), token); + return false; + } + + SendResponse(msg_id, Result.Ok(new JObject()), token); + + context.ClearState(); + + await SendCommand(msg_id, "Debugger.resume", new JObject(), token); + return true; + } + + internal bool TryFindVariableValueInCache(ExecutionContext ctx, string expression, bool only_search_on_this, out JToken obj) + { + if (ctx.LocalsCache.TryGetValue(expression, out obj)) + { + if (only_search_on_this && obj["fromThis"] == null) + return false; + return true; + } + return false; + } + + internal async Task TryGetVariableValue(MessageId msg_id, int scope_id, string expression, bool only_search_on_this, CancellationToken token) + { + JToken thisValue = null; + var context = GetContext(msg_id); + if (context.CallStack == null) + return null; + + if (TryFindVariableValueInCache(context, expression, only_search_on_this, out JToken obj)) + return obj; + + var scope = context.CallStack.FirstOrDefault(s => s.Id == scope_id); + var live_vars = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset); + //get_this + var res = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, live_vars), token); + + var scope_values = res.Value?["result"] ? ["value"]?.Values()?.ToArray(); + thisValue = scope_values?.FirstOrDefault(v => v["name"]?.Value() == "this"); + + if (!only_search_on_this) + { + if (thisValue != null && expression == "this") + return thisValue; + + var value = scope_values.SingleOrDefault(sv => sv["name"]?.Value() == expression); + if (value != null) + return value; + } + + //search in scope + if (thisValue != null) + { + if (!DotnetObjectId.TryParse(thisValue["value"]["objectId"], out var objectId)) + return null; + + res = await SendMonoCommand(msg_id, MonoCommands.GetDetails(objectId), token); + scope_values = res.Value?["result"] ? ["value"]?.Values().ToArray(); + var foundValue = scope_values.FirstOrDefault(v => v["name"].Value() == expression); + if (foundValue != null) + { + foundValue["fromThis"] = true; + context.LocalsCache[foundValue["name"].Value()] = foundValue; + return foundValue; + } + } + return null; + } + + async Task OnEvaluateOnCallFrame(MessageId msg_id, int scope_id, string expression, CancellationToken token) + { + try + { + var context = GetContext(msg_id); + if (context.CallStack == null) + return false; + + var varValue = await TryGetVariableValue(msg_id, scope_id, expression, false, token); + + if (varValue != null) + { + SendResponse(msg_id, Result.OkFromObject(new + { + result = varValue["value"] + }), token); + return true; + } + + string retValue = await EvaluateExpression.CompileAndRunTheExpression(this, msg_id, scope_id, expression, token); + SendResponse(msg_id, Result.OkFromObject(new + { + result = new + { + value = retValue + } + }), token); + return true; + } + catch (Exception e) + { + logger.LogDebug(e, $"Error in EvaluateOnCallFrame for expression '{expression}."); + } + return false; + } + + async Task GetScopeProperties(MessageId msg_id, int scope_id, CancellationToken token) + { + try + { + var ctx = GetContext(msg_id); + var scope = ctx.CallStack.FirstOrDefault(s => s.Id == scope_id); + if (scope == null) + return Result.Err(JObject.FromObject(new { message = $"Could not find scope with id #{scope_id}" })); + + var var_ids = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset); + var res = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, var_ids), token); + + //if we fail we just buble that to the IDE (and let it panic over it) + if (res.IsErr) + return res; + + var values = res.Value?["result"] ? ["value"]?.Values().ToArray(); + + if (values == null || values.Length == 0) + return Result.OkFromObject(new { result = Array.Empty() }); + + foreach (var value in values) + ctx.LocalsCache[value["name"]?.Value()] = value; + + return Result.OkFromObject(new { result = values }); + } + catch (Exception exception) + { + Log("verbose", $"Error resolving scope properties {exception.Message}"); + return Result.Exception(exception); + } + } + + async Task SetMonoBreakpoint(SessionId sessionId, string reqId, SourceLocation location, CancellationToken token) + { + var bp = new Breakpoint(reqId, location, BreakpointState.Pending); + var asm_name = bp.Location.CliLocation.Method.Assembly.Name; + var method_token = bp.Location.CliLocation.Method.Token; + var il_offset = bp.Location.CliLocation.Offset; + + var res = await SendMonoCommand(sessionId, MonoCommands.SetBreakpoint(asm_name, method_token, il_offset), token); + var ret_code = res.Value?["result"] ? ["value"]?.Value(); + + if (ret_code.HasValue) + { + bp.RemoteId = ret_code.Value; + bp.State = BreakpointState.Active; + //Log ("verbose", $"BP local id {bp.LocalId} enabled with remote id {bp.RemoteId}"); + } + + return bp; + } + + async Task LoadStore(SessionId sessionId, CancellationToken token) + { + var context = GetContext(sessionId); + + if (Interlocked.CompareExchange(ref context.store, new DebugStore(logger), null) != null) + return await context.Source.Task; + + try + { + var loaded_files = context.LoadedFiles; + + if (loaded_files == null) + { + var loaded = await SendMonoCommand(sessionId, MonoCommands.GetLoadedFiles(), token); + loaded_files = loaded.Value?["result"] ? ["value"]?.ToObject(); + } + + await + foreach (var source in context.store.Load(sessionId, loaded_files, token).WithCancellation(token)) + { + var scriptSource = JObject.FromObject(source.ToScriptSource(context.Id, context.AuxData)); + Log("verbose", $"\tsending {source.Url} {context.Id} {sessionId.sessionId}"); + + SendEvent(sessionId, "Debugger.scriptParsed", scriptSource, token); + + foreach (var req in context.BreakpointRequests.Values) + { + if (req.TryResolve(source)) + { + await SetBreakpoint(sessionId, context.store, req, true, token); + } + } + } + } + catch (Exception e) + { + context.Source.SetException(e); + } + + if (!context.Source.Task.IsCompleted) + context.Source.SetResult(context.store); + return context.store; + } + + async Task RuntimeReady(SessionId sessionId, CancellationToken token) + { + var context = GetContext(sessionId); + if (Interlocked.CompareExchange(ref context.ready, new TaskCompletionSource(), null) != null) + return await context.ready.Task; + + var clear_result = await SendMonoCommand(sessionId, MonoCommands.ClearAllBreakpoints(), token); + if (clear_result.IsErr) + { + Log("verbose", $"Failed to clear breakpoints due to {clear_result}"); + } + + var store = await LoadStore(sessionId, token); + + context.ready.SetResult(store); + SendEvent(sessionId, "Mono.runtimeReady", new JObject(), token); + return store; + } + + async Task RemoveBreakpoint(MessageId msg_id, JObject args, CancellationToken token) + { + var bpid = args?["breakpointId"]?.Value(); + + var context = GetContext(msg_id); + if (!context.BreakpointRequests.TryGetValue(bpid, out var breakpointRequest)) + return; + + foreach (var bp in breakpointRequest.Locations) + { + var res = await SendMonoCommand(msg_id, MonoCommands.RemoveBreakpoint(bp.RemoteId), token); + var ret_code = res.Value?["result"] ? ["value"]?.Value(); + + if (ret_code.HasValue) + { + bp.RemoteId = -1; + bp.State = BreakpointState.Disabled; + } + } + breakpointRequest.Locations.Clear(); + } + + async Task SetBreakpoint(SessionId sessionId, DebugStore store, BreakpointRequest req, bool sendResolvedEvent, CancellationToken token) + { + var context = GetContext(sessionId); + if (req.Locations.Any()) + { + Log("debug", $"locations already loaded for {req.Id}"); + return; + } + + var comparer = new SourceLocation.LocationComparer(); + // if column is specified the frontend wants the exact matches + // and will clear the bp if it isn't close enoug + var locations = store.FindBreakpointLocations(req) + .Distinct(comparer) + .Where(l => l.Line == req.Line && (req.Column == 0 || l.Column == req.Column)) + .OrderBy(l => l.Column) + .GroupBy(l => l.Id); + + logger.LogDebug("BP request for '{req}' runtime ready {context.RuntimeReady}", req, GetContext(sessionId).IsRuntimeReady); + + var breakpoints = new List(); + + foreach (var sourceId in locations) + { + var loc = sourceId.First(); + var bp = await SetMonoBreakpoint(sessionId, req.Id, loc, token); + + // If we didn't successfully enable the breakpoint + // don't add it to the list of locations for this id + if (bp.State != BreakpointState.Active) + continue; + + breakpoints.Add(bp); + + var resolvedLocation = new + { + breakpointId = req.Id, + location = loc.AsLocation() + }; + + if (sendResolvedEvent) + SendEvent(sessionId, "Debugger.breakpointResolved", JObject.FromObject(resolvedLocation), token); + } + + req.Locations.AddRange(breakpoints); + return; + } + + async Task GetPossibleBreakpoints(MessageId msg, SourceLocation start, SourceLocation end, CancellationToken token) + { + var bps = (await RuntimeReady(msg, token)).FindPossibleBreakpoints(start, end); + + if (bps == null) + return false; + + var response = new { locations = bps.Select(b => b.AsLocation()) }; + + SendResponse(msg, Result.OkFromObject(response), token); + return true; + } + + void OnCompileDotnetScript(MessageId msg_id, CancellationToken token) + { + SendResponse(msg_id, Result.OkFromObject(new { }), token); + } + + async Task OnGetScriptSource(MessageId msg_id, string script_id, CancellationToken token) + { + if (!SourceId.TryParse(script_id, out var id)) + return false; + + var src_file = (await LoadStore(msg_id, token)).GetFileById(id); + + try + { + var uri = new Uri(src_file.Url); + string source = $"// Unable to find document {src_file.SourceUri}"; + + using(var data = await src_file.GetSourceAsync(checkHash: false, token: token)) + { + if (data.Length == 0) + return false; + + using(var reader = new StreamReader(data)) + source = await reader.ReadToEndAsync(); + } + SendResponse(msg_id, Result.OkFromObject(new { scriptSource = source }), token); + } + catch (Exception e) + { + var o = new + { + scriptSource = $"// Unable to read document ({e.Message})\n" + + $"Local path: {src_file?.SourceUri}\n" + + $"SourceLink path: {src_file?.SourceLinkUri}\n" + }; + + SendResponse(msg_id, Result.OkFromObject(o), token); + } + return true; + } + + async Task DeleteWebDriver(SessionId sessionId, CancellationToken token) + { + // see https://github.com/mono/mono/issues/19549 for background + if (hideWebDriver && sessions.Add(sessionId)) + { + var res = await SendCommand(sessionId, + "Page.addScriptToEvaluateOnNewDocument", + JObject.FromObject(new { source = "delete navigator.constructor.prototype.webdriver" }), + token); + + if (sessionId != SessionId.Null && !res.IsOk) + sessions.Remove(sessionId); + } + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs new file mode 100644 index 000000000000..022e41cc042c --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -0,0 +1,605 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class ArrayTests : DebuggerTestBase + { + + [Theory] + [InlineData(19, 8, "PrimitiveTypeLocals", false, 0, false)] + [InlineData(19, 8, "PrimitiveTypeLocals", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectPrimitiveTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:PrimitiveTypeLocals", + method_name : method_name, + etype_name: "int", + local_var_name_prefix: "int", + array : new [] { TNumber(4), TNumber(70), TNumber(1) }, + array_elements : null, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + [Theory] + [InlineData(36, 8, "ValueTypeLocals", false, 0, false)] + [InlineData(36, 8, "ValueTypeLocals", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectValueTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:ValueTypeLocals", + method_name : method_name, + etype_name: "DebuggerTests.Point", + local_var_name_prefix: "point", + array : new [] + { + TValueType("DebuggerTests.Point"), + TValueType("DebuggerTests.Point"), + }, + array_elements : new [] + { + TPoint(5, -2, "point_arr#Id#0", "Green"), + TPoint(123, 0, "point_arr#Id#1", "Blue") + }, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + [Theory] + [InlineData(54, 8, "ObjectTypeLocals", false, 0, false)] + [InlineData(54, 8, "ObjectTypeLocals", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectObjectArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:ObjectTypeLocals", + method_name : method_name, + etype_name: "DebuggerTests.SimpleClass", + local_var_name_prefix: "class", + array : new [] + { + TObject("DebuggerTests.SimpleClass"), + TObject("DebuggerTests.SimpleClass", is_null : true), + TObject("DebuggerTests.SimpleClass") + }, + array_elements : new [] + { + TSimpleClass(5, -2, "class_arr#Id#0", "Green"), + null, // Element is null + TSimpleClass(123, 0, "class_arr#Id#2", "Blue") + }, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + [Theory] + [InlineData(72, 8, "GenericTypeLocals", false, 0, false)] + [InlineData(72, 8, "GenericTypeLocals", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectGenericTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericTypeLocals", + method_name : method_name, + etype_name: "DebuggerTests.GenericClass", + local_var_name_prefix: "gclass", + array : new [] + { + TObject("DebuggerTests.GenericClass", is_null : true), + TObject("DebuggerTests.GenericClass"), + TObject("DebuggerTests.GenericClass") + }, + array_elements : new [] + { + null, // Element is null + new + { + Id = TString("gclass_arr#1#Id"), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TNumber(5) + }, + new + { + Id = TString("gclass_arr#2#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + Value = TNumber(-12) + } + }, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + [Theory] + [InlineData(89, 8, "GenericValueTypeLocals", false, 0, false)] + [InlineData(89, 8, "GenericValueTypeLocals", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectGenericValueTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericValueTypeLocals", + method_name : method_name, + etype_name: "DebuggerTests.SimpleGenericStruct", + local_var_name_prefix: "gvclass", + array : new [] + { + TValueType("DebuggerTests.SimpleGenericStruct"), + TValueType("DebuggerTests.SimpleGenericStruct") + }, + array_elements : new [] + { + new + { + Id = TString("gvclass_arr#1#Id"), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(100, 200, "gvclass_arr#1#Value#Id", "Red") + }, + new + { + Id = TString("gvclass_arr#2#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + Value = TPoint(10, 20, "gvclass_arr#2#Value#Id", "Green") + } + }, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + [Theory] + [InlineData(213, 8, "GenericValueTypeLocals2", false, 0, false)] + [InlineData(213, 8, "GenericValueTypeLocals2", false, 0, true)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, false)] + [InlineData(100, 8, "YetAnotherMethod", true, 2, true)] + public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( + line, col, + entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericValueTypeLocals2", + method_name : method_name, + etype_name: "DebuggerTests.SimpleGenericStruct", + local_var_name_prefix: "gvclass", + array : new [] + { + TValueType("DebuggerTests.SimpleGenericStruct"), + TValueType("DebuggerTests.SimpleGenericStruct") + }, + array_elements : new [] + { + new + { + Id = TString("gvclass_arr#0#Id"), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = new [] + { + TPoint(100, 200, "gvclass_arr#0#0#Value#Id", "Red"), + TPoint(100, 200, "gvclass_arr#0#1#Value#Id", "Green") + } + }, + new + { + Id = TString("gvclass_arr#1#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + Value = new [] + { + TPoint(100, 200, "gvclass_arr#1#0#Value#Id", "Green"), + TPoint(100, 200, "gvclass_arr#1#1#Value#Id", "Blue") + } + } + }, + test_prev_frame : test_prev_frame, + frame_idx : frame_idx, + use_cfo : use_cfo); + + async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, string method_name, string etype_name, + string local_var_name_prefix, object[] array, object[] array_elements, + bool test_prev_frame = false, int frame_idx = 0, bool use_cfo = false) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() { invoke_static_method (" + + $"'{entry_method_name}', { (test_prev_frame ? "true" : "false") }" + + "); }, 1);"; + + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, method_name); + + var locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + Assert.Equal(4, locals.Count()); + CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]"); + CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]"); + CheckObject(locals, $"{local_var_name_prefix}_arr_null", $"{etype_name}[]", is_null : true); + CheckBool(locals, "call_other", test_prev_frame); + + var local_arr_name = $"{local_var_name_prefix}_arr"; + + JToken prefix_arr; + if (use_cfo) + { // Use `Runtime.callFunctionOn` to get the properties + var frame = pause_location["callFrames"][frame_idx]; + var name = local_arr_name; + var fl = await GetProperties(frame["callFrameId"].Value()); + var l_obj = GetAndAssertObjectWithName(locals, name); + var l_objectId = l_obj["value"]["objectId"]?.Value(); + + Assert.True(!String.IsNullOrEmpty(l_objectId), $"No objectId found for {name}"); + + prefix_arr = await GetObjectWithCFO(l_objectId); + } + else + { + prefix_arr = await GetObjectOnFrame(pause_location["callFrames"][frame_idx], local_arr_name); + } + + await CheckProps(prefix_arr, array, local_arr_name); + + if (array_elements?.Length > 0) + { + for (int i = 0; i < array_elements.Length; i++) + { + var i_str = i.ToString(); + var label = $"{local_var_name_prefix}_arr[{i}]"; + if (array_elements[i] == null) + { + var act_i = prefix_arr.FirstOrDefault(jt => jt["name"]?.Value() == i_str); + Assert.True(act_i != null, $"[{label}] Couldn't find array element [{i_str}]"); + + await CheckValue(act_i["value"], TObject(etype_name, is_null : true), label); + } + else + { + await CompareObjectPropertiesFor(prefix_arr, i_str, array_elements[i], label : label); + } + } + } + + var props = await GetObjectOnFrame(pause_location["callFrames"][frame_idx], $"{local_var_name_prefix}_arr_empty"); + await CheckProps(props, new object[0], "${local_var_name_prefix}_arr_empty"); + }); + + async Task GetObjectWithCFO(string objectId, JObject fn_args = null) + { + var fn_decl = "function () { return this; }"; + var cfo_args = JObject.FromObject(new + { + functionDeclaration = fn_decl, + objectId = objectId + }); + + if (fn_args != null) + cfo_args["arguments"] = fn_args; + + // callFunctionOn + var result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + + return await GetProperties(result.Value["result"]["objectId"]?.Value(), fn_args); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectObjectArrayMembers(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 227; + int col = 12; + string entry_method_name = "[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers"; + string method_name = "PlaceholderMethod"; + int frame_idx = 1; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() { invoke_static_method (" + + $"'{entry_method_name}'" + + "); }, 1);"; + + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, method_name); + var locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + Assert.Single(locals); + CheckObject(locals, "c", "DebuggerTests.Container"); + + var c_props = await GetObjectOnFrame(pause_location["callFrames"][frame_idx], "c"); + await CheckProps(c_props, new + { + id = TString("c#id"), + ClassArrayProperty = TArray("DebuggerTests.SimpleClass[]", 3), + ClassArrayField = TArray("DebuggerTests.SimpleClass[]", 3), + PointsProperty = TArray("DebuggerTests.Point[]", 2), + PointsField = TArray("DebuggerTests.Point[]", 2) + }, + "c" + ); + + await CompareObjectPropertiesFor(c_props, "ClassArrayProperty", + new [] + { + TSimpleClass(5, -2, "ClassArrayProperty#Id#0", "Green"), + TSimpleClass(30, 1293, "ClassArrayProperty#Id#1", "Green"), + TObject("DebuggerTests.SimpleClass", is_null : true) + }, + label: "InspectLocalsWithStructsStaticAsync"); + + await CompareObjectPropertiesFor(c_props, "ClassArrayField", + new [] + { + TObject("DebuggerTests.SimpleClass", is_null : true), + TSimpleClass(5, -2, "ClassArrayField#Id#1", "Blue"), + TSimpleClass(30, 1293, "ClassArrayField#Id#2", "Green") + }, + label: "c#ClassArrayField"); + + await CompareObjectPropertiesFor(c_props, "PointsProperty", + new [] + { + TPoint(5, -2, "PointsProperty#Id#0", "Green"), + TPoint(123, 0, "PointsProperty#Id#1", "Blue"), + }, + label: "c#PointsProperty"); + + await CompareObjectPropertiesFor(c_props, "PointsField", + new [] + { + TPoint(5, -2, "PointsField#Id#0", "Green"), + TPoint(123, 0, "PointsField#Id#1", "Blue"), + }, + label: "c#PointsField"); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectValueTypeArrayLocalsStaticAsync(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 157; + int col = 12; + string entry_method_name = "[debugger-test] DebuggerTests.ArrayTestsClass:ValueTypeLocalsAsync"; + string method_name = "MoveNext"; // BUG: this should be ValueTypeLocalsAsync + int frame_idx = 0; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() { invoke_static_method_async (" + + $"'{entry_method_name}', false" // *false* here keeps us only in the static method + + + "); }, 1);"; + + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, method_name); + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + call_other = TBool(false), + gvclass_arr = TArray("DebuggerTests.SimpleGenericStruct[]", 2), + gvclass_arr_empty = TArray("DebuggerTests.SimpleGenericStruct[]"), + gvclass_arr_null = TObject("DebuggerTests.SimpleGenericStruct[]", is_null : true), + gvclass = TValueType("DebuggerTests.SimpleGenericStruct"), + // BUG: this shouldn't be null! + points = TObject("DebuggerTests.Point[]", is_null : true) + }, "ValueTypeLocalsAsync#locals"); + + var local_var_name_prefix = "gvclass"; + await CompareObjectPropertiesFor(frame_locals, local_var_name_prefix, new + { + Id = TString(null), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(0, 0, null, "Red") + }); + + await CompareObjectPropertiesFor(frame_locals, $"{local_var_name_prefix}_arr", + new [] + { + new + { + Id = TString("gvclass_arr#1#Id"), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(100, 200, "gvclass_arr#1#Value#Id", "Red") + }, + new + { + Id = TString("gvclass_arr#2#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + Value = TPoint(10, 20, "gvclass_arr#2#Value#Id", "Green") + } + } + ); + await CompareObjectPropertiesFor(frame_locals, $"{local_var_name_prefix}_arr_empty", + new object[0]); + }); + } + + // TODO: Check previous frame too + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectValueTypeArrayLocalsInstanceAsync(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 170; + int col = 12; + string entry_method_name = "[debugger-test] DebuggerTests.ArrayTestsClass:ValueTypeLocalsAsync"; + int frame_idx = 0; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() { invoke_static_method_async (" + + $"'{entry_method_name}', true" + + "); }, 1);"; + + // BUG: Should be InspectValueTypeArrayLocalsInstanceAsync + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, "MoveNext"); + + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + t1 = TObject("DebuggerTests.SimpleGenericStruct"), + @this = TObject("DebuggerTests.ArrayTestsClass"), + point_arr = TArray("DebuggerTests.Point[]", 2), + point = TValueType("DebuggerTests.Point") + }, "InspectValueTypeArrayLocalsInstanceAsync#locals"); + + await CompareObjectPropertiesFor(frame_locals, "t1", + new + { + Id = TString("gvclass_arr#1#Id"), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(100, 200, "gvclass_arr#1#Value#Id", "Red") + }); + + await CompareObjectPropertiesFor(frame_locals, "point_arr", + new [] + { + TPoint(5, -2, "point_arr#Id#0", "Red"), + TPoint(123, 0, "point_arr#Id#1", "Blue"), + } + ); + + await CompareObjectPropertiesFor(frame_locals, "point", + TPoint(45, 51, "point#Id", "Green")); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectValueTypeArrayLocalsInAsyncStaticStructMethod(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 244; + int col = 12; + string entry_method_name = "[debugger-test] DebuggerTests.ArrayTestsClass:EntryPointForStructMethod"; + int frame_idx = 0; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + //await SetBreakpoint (debugger_test_loc, 143, 3); + + var eval_expr = "window.setTimeout(function() { invoke_static_method_async (" + + $"'{entry_method_name}', false" + + "); }, 1);"; + + // BUG: Should be InspectValueTypeArrayLocalsInstanceAsync + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, "MoveNext"); + + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + call_other = TBool(false), + local_i = TNumber(5), + sc = TSimpleClass(10, 45, "sc#Id", "Blue") + }, "InspectValueTypeArrayLocalsInAsyncStaticStructMethod#locals"); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectValueTypeArrayLocalsInAsyncInstanceStructMethod(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 251; + int col = 12; + string entry_method_name = "[debugger-test] DebuggerTests.ArrayTestsClass:EntryPointForStructMethod"; + int frame_idx = 0; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() { invoke_static_method_async (" + + $"'{entry_method_name}', true" + + "); }, 1);"; + + // BUG: Should be InspectValueTypeArrayLocalsInstanceAsync + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, "MoveNext"); + + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + sc_arg = TObject("DebuggerTests.SimpleClass"), + @this = TValueType("DebuggerTests.Point"), + local_gs = TValueType("DebuggerTests.SimpleGenericStruct") + }, + "locals#0"); + + await CompareObjectPropertiesFor(frame_locals, "local_gs", + new + { + Id = TString("local_gs#Id"), + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) + }, + label: "local_gs#0"); + + await CompareObjectPropertiesFor(frame_locals, "sc_arg", + TSimpleClass(10, 45, "sc_arg#Id", "Blue"), + label: "sc_arg#0"); + + await CompareObjectPropertiesFor(frame_locals, "this", + TPoint(90, -4, "point#Id", "Green"), + label: "this#0"); + }); + } + + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs new file mode 100644 index 000000000000..5c66bb2fb259 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs @@ -0,0 +1,857 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class CallFunctionOnTests : DebuggerTestBase + { + + // This tests `callFunctionOn` with a function that the vscode-js-debug extension uses + // Using this here as a non-trivial test case + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, 10, false)] + [InlineData("big_array_js_test (0);", "/other.js", 8, 1, 0, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, 10, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 0);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, 0, true)] + public async Task CheckVSCodeTestFunction1(string eval_fn, string bp_loc, int line, int col, int len, bool roundtrip) + { + string vscode_fn0 = "function(){const e={__proto__:this.__proto__},t=Object.getOwnPropertyNames(this);for(let r=0;r>>0;if(String(i>>>0)===n&&i>>>0!=4294967295)continue;const a=Object.getOwnPropertyDescriptor(this,n);a&&Object.defineProperty(e,n,a)}return e}"; + + await RunCallFunctionOn(eval_fn, vscode_fn0, "big", bp_loc, line, col, res_array_len : len, roundtrip : roundtrip, + test_fn : async(result) => + { + + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + + // Check for a __proto__ object + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + await CheckProps(obj_own.Value["result"], new + { + length = TNumber(len), + // __proto__ = TArray (type, 0) // Is this one really required? + }, $"obj_own", num_fields : is_js ? 2 : 1); + + }); + } + + void CheckJFunction(JToken actual, string className, string label) + { + AssertEqual("function", actual["type"]?.Value(), $"{label}-type"); + AssertEqual(className, actual["className"]?.Value(), $"{label}-className"); + } + + // This tests `callFunctionOn` with a function that the vscode-js-debug extension uses + // Using this here as a non-trivial test case + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, 10)] + [InlineData("big_array_js_test (0);", "/other.js", 8, 1, 0)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, 10)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 0);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, 0)] + public async Task CheckVSCodeTestFunction2(string eval_fn, string bp_loc, int line, int col, int len) + { + var fetch_start_idx = 2; + var num_elems_fetch = 3; + string vscode_fn1 = "function(e,t){const r={},n=-1===e?0:e,i=-1===t?this.length:e+t;for(let e=n;e + { + + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + + // isOwn = false, accessorPropertiesOnly = true + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + + // Ignoring the __proto__ property + + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + var num_elems_recd = len == 0 ? 0 : num_elems_fetch; + AssertEqual(is_js ? num_elems_recd + 1 : num_elems_recd, obj_own_val.Count(), $"obj_own-count"); + + if (is_js) + CheckObject(obj_own_val, "__proto__", "Object"); + + for (int i = fetch_start_idx; i < fetch_start_idx + num_elems_recd; i++) + CheckNumber(obj_own_val, i.ToString(), 1000 + i); + }); + } + + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] + public async Task RunOnArrayReturnEmptyArray(string eval_fn, string bp_loc, int line, int col, bool roundtrip) + { + var ret_len = 0; + + await RunCallFunctionOn(eval_fn, + "function () { return []; }", + "big", bp_loc, line, col, + res_array_len : ret_len, + roundtrip : roundtrip, + test_fn : async(result) => + { + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + + // getProperties (isOwn = false, accessorPropertiesOnly = true) + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + + // getProperties (isOwn = true, accessorPropertiesOnly = false) + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + await CheckProps(obj_own.Value["result"], new + { + length = TNumber(ret_len), + // __proto__ returned by js + }, $"obj_own", num_fields : is_js ? 2 : 1); + }); + } + + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] + public async Task RunOnArrayReturnArray(string eval_fn, string bp_loc, int line, int col, bool roundtrip) + { + var ret_len = 5; + await RunCallFunctionOn(eval_fn, + "function (m) { return Object.values (this).filter ((k, i) => i%m == 0); }", + "big", bp_loc, line, col, + fn_args : JArray.FromObject(new [] { new { value = 2 } }), + res_array_len : ret_len, + roundtrip : roundtrip, + test_fn : async(result) => + { + var is_js = bp_loc.EndsWith(".js"); + + // getProperties (own=false) + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + + // getProperties (own=true) + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + // AssertEqual (2, obj_own.Value ["result"].Count (), $"{label}-obj_own.count"); + + var obj_own_val = obj_own.Value["result"]; + await CheckProps(obj_own_val, new + { + length = TNumber(ret_len), + // __proto__ returned by JS + }, $"obj_own", num_fields: (is_js ? ret_len + 2 : ret_len + 1)); + + for (int i = 0; i < ret_len; i++) + CheckNumber(obj_own_val, i.ToString(), i * 2 + 1000); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task RunOnVTArray(bool roundtrip) => await RunCallFunctionOn( + "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", + "function (m) { return Object.values (this).filter ((k, i) => i%m == 0); }", + "ss_arr", + "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, + fn_args : JArray.FromObject(new [] { new { value = 2 } }), + res_array_len : 5, + roundtrip : roundtrip, + test_fn : async(result) => + { + var ret_len = 5; + + // getProperties (own=false) + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + + // getProperties (own=true) + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + await CheckProps(obj_own_val, new + { + length = TNumber(ret_len), + // __proto__ returned by JS + }, "obj_own", num_fields : ret_len + 1); + + for (int i = 0; i < ret_len; i++) + { + var act_i = CheckValueType(obj_own_val, i.ToString(), "Math.SimpleStruct"); + + // Valuetypes can get sent as part of the container's getProperties, so ensure that we can access it + var act_i_props = await GetProperties(act_i["value"]["objectId"]?.Value()); + await CheckProps(act_i_props, new + { + dt = TValueType("System.DateTime", new DateTime(2020 + (i * 2), 1, 2, 3, 4, 5).ToString()), + gs = TValueType("Math.GenericStruct") + }, "obj_own ss_arr[{i}]"); + + var gs_props = await GetObjectOnLocals(act_i_props, "gs"); + await CheckProps(gs_props, new + { + List = TObject("System.Collections.Generic.List", is_null : true), + StringField = TString($"ss_arr # {i*2} # gs # StringField") + }, "obj_own ss_arr[{i}].gs"); + + } + }); + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task RunOnCFOValueTypeResult(bool roundtrip) => await RunCallFunctionOn( + eval_fn: "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", + fn_decl: "function () { return this; }", + local_name: "simple_struct", + bp_loc: "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, + roundtrip : roundtrip, + test_fn : async(result) => + { + + // getProperties (own=false) + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + AssertEqual(0, obj_accessors.Value["result"].Count(), "obj_accessors-count"); + + // getProperties (own=true) + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + var dt = new DateTime(2020, 1, 2, 3, 4, 5); + await CheckProps(obj_own_val, new + { + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("Math.GenericStruct") + }, $"obj_own-props"); + + await CheckDateTime(obj_own_val, "dt", dt); + + var gs_props = await GetObjectOnLocals(obj_own_val, "gs"); + await CheckProps(gs_props, new + { + List = TObject("System.Collections.Generic.List", is_null : true), + StringField = TString($"simple_struct # gs # StringField") + }, "simple_struct.gs-props"); + }); + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task RunOnJSObject(bool roundtrip) => await RunCallFunctionOn( + "object_js_test ();", + "function () { return this; }", + "obj", "/other.js", 17, 1, + fn_args : JArray.FromObject(new [] { new { value = 2 } }), + roundtrip : roundtrip, + test_fn : async(result) => + { + + // getProperties (own=false) + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + + // getProperties (own=true) + // isOwn = true, accessorPropertiesOnly = false + var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + await CheckProps(obj_own_val, new + { + a_obj = TObject("Object"), + b_arr = TArray("Array", 2) + }, "obj_own", num_fields : 3); + }); + + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] + public async Task RunOnArrayReturnObjectArrayByValue(string eval_fn, string bp_loc, int line, int col, bool roundtrip) + { + var ret_len = 5; + await RunCallFunctionOn(eval_fn, + "function () { return Object.values (this).filter ((k, i) => i%2 == 0); }", + "big", bp_loc, line, col, returnByValue : true, roundtrip : roundtrip, + test_fn : async(result) => + { + // Check cfo result + AssertEqual(JTokenType.Object, result.Value["result"].Type, "cfo-result-jsontype"); + AssertEqual("object", result.Value["result"]["type"]?.Value(), "cfo-res-type"); + + AssertEqual(JTokenType.Array, result.Value["result"]["value"].Type, "cfo-res-value-jsontype"); + var actual = result.Value["result"] ? ["value"].Values().ToArray(); + AssertEqual(ret_len, actual.Length, "cfo-res-value-length"); + + for (int i = 0; i < ret_len; i++) + { + var exp_num = i * 2 + 1000; + if (bp_loc.EndsWith(".js", StringComparison.Ordinal)) + AssertEqual(exp_num, actual[i].Value(), $"[{i}]"); + else + { + AssertEqual("number", actual[i] ? ["type"]?.Value(), $"[{i}]-type"); + AssertEqual(exp_num.ToString(), actual[i] ? ["description"]?.Value(), $"[{i}]-description"); + AssertEqual(exp_num, actual[i] ? ["value"]?.Value(), $"[{i}]-value"); + } + } + await Task.CompletedTask; + }); + } + + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] + public async Task RunOnArrayReturnArrayByValue(string eval_fn, string bp_loc, int line, int col, bool roundtrip) => await RunCallFunctionOn(eval_fn, + "function () { return Object.getOwnPropertyNames (this); }", + "big", bp_loc, line, col, returnByValue : true, + roundtrip : roundtrip, + test_fn : async(result) => + { + // Check cfo result + AssertEqual("object", result.Value["result"]["type"]?.Value(), "cfo-res-type"); + + var exp = new JArray(); + for (int i = 0; i < 10; i++) + exp.Add(i.ToString()); + exp.Add("length"); + + var actual = result.Value["result"] ? ["value"]; + if (!JObject.DeepEquals(exp, actual)) + { + Assert.True(false, $"Results don't match.\nExpected: {exp}\nActual: {actual}"); + } + await Task.CompletedTask; + }); + + [Theory] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] + [InlineData("big_array_js_test (10);", "/other.js", 8, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] + public async Task RunOnArrayReturnPrimitive(string eval_fn, string bp_loc, int line, int col, bool return_by_val) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + await SetBreakpoint(bp_loc, line, col); + + // callFunctionOn + var eval_expr = $"window.setTimeout(function() {{ {eval_fn} }}, 1);"; + var result = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr }), ctx.token); + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + // Um for js we get "scriptId": "6" + // CheckLocation (bp_loc, line, col, ctx.scripts, pause_location ["callFrames"][0]["location"]); + + // Check the object at the bp + var frame_locals = await GetProperties(pause_location["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value()); + var obj = GetAndAssertObjectWithName(frame_locals, "big"); + var obj_id = obj["value"]["objectId"].Value(); + + var cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return 5; }", + objectId = obj_id + }); + + // value of @returnByValue doesn't matter, as the returned value + // is a primitive + if (return_by_val) + cfo_args["returnByValue"] = return_by_val; + + // callFunctionOn + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + await CheckValue(result.Value["result"], TNumber(5), "cfo-res"); + }); + } + + public static TheoryData SilentErrorsTestData(bool? silent) => new TheoryData + { { "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, silent }, + { "big_array_js_test (10);", "/other.js", 8, 1, silent } + }; + + [Theory] + [MemberData(nameof(SilentErrorsTestData), null)] + [MemberData(nameof(SilentErrorsTestData), false)] + [MemberData(nameof(SilentErrorsTestData), true)] + public async Task CFOWithSilentReturnsErrors(string eval_fn, string bp_loc, int line, int col, bool? silent) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + await SetBreakpoint(bp_loc, line, col); + + // callFunctionOn + var eval_expr = "window.setTimeout(function() { " + eval_fn + " }, 1);"; + var result = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr }), ctx.token); + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + var frame_locals = await GetProperties(pause_location["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value()); + var obj = GetAndAssertObjectWithName(frame_locals, "big"); + var big_obj_id = obj["value"]["objectId"].Value(); + var error_msg = "#This is an error message#"; + + // Check the object at the bp + var cfo_args = JObject.FromObject(new + { + functionDeclaration = $"function () {{ throw Error ('{error_msg}'); }}", + objectId = big_obj_id + }); + + if (silent.HasValue) + cfo_args["silent"] = silent; + + // callFunctionOn, Silent does not change the result, except that the error + // doesn't get reported, and the execution is NOT paused even with setPauseOnException=true + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + Assert.False(result.IsOk, "result.IsOk"); + Assert.True(result.IsErr, "result.IsErr"); + + var hasErrorMessage = result.Error["exceptionDetails"] ? ["exception"] ? ["description"]?.Value()?.Contains(error_msg); + Assert.True((hasErrorMessage ?? false), "Exception message not found"); + }); + } + + public static TheoryData, bool> GettersTestData(bool use_cfo) => new TheoryData, bool> + { + // Chrome sends this one + { + "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", + "PropertyGettersTest", + 30, + 12, + "function invokeGetter(arrayStr){ let result=this; const properties=JSON.parse(arrayStr); for(let i=0,n=properties.length;i JArray.FromObject(arg_strs).ToString(), + use_cfo + }, + { + "invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", + "MoveNext", + 38, + 12, + "function invokeGetter(arrayStr){ let result=this; const properties=JSON.parse(arrayStr); for(let i=0,n=properties.length;i JArray.FromObject(arg_strs).ToString(), + use_cfo + }, + + // VSCode sends this one + { + "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", + "PropertyGettersTest", + 30, + 12, + "function(e){return this[e]}", + (args_str) => args_str?.Length > 0 ? args_str[0] : String.Empty, + use_cfo + }, + { + "invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", + "MoveNext", + 38, + 12, + "function(e){return this[e]}", + (args_str) => args_str?.Length > 0 ? args_str[0] : String.Empty, + use_cfo + } + }; + + [Theory] + [MemberData(nameof(GettersTestData), parameters : false)] + [MemberData(nameof(GettersTestData), parameters : true)] + public async Task PropertyGettersOnObjectsTest(string eval_fn, string method_name, int line, int col, string cfo_fn, Func get_args_fn, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-cfo-test.cs", line, col, + method_name, + $"window.setTimeout(function() {{ {eval_fn} }}, 1);", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var dt = new DateTime(10, 9, 8, 7, 6, 5); + + await CheckProps(frame_locals, new + { + ptd = TObject("DebuggerTests.ClassWithProperties"), + swp = TObject("DebuggerTests.StructWithProperties"), + }, "locals#0"); + + var ptd = GetAndAssertObjectWithName(frame_locals, "ptd"); + + var ptd_props = await GetProperties(ptd?["value"] ? ["objectId"]?.Value()); + await CheckProps(ptd_props, new + { + Int = TGetter("Int"), + String = TGetter("String"), + DT = TGetter("DT"), + IntArray = TGetter("IntArray"), + DTArray = TGetter("DTArray") + }, "ptd", num_fields : 7); + + // Automatic properties don't have invokable getters, because we can get their + // value from the backing field directly + { + dt = new DateTime(4, 5, 6, 7, 8, 9); + var dt_auto_props = await GetObjectOnLocals(ptd_props, "DTAutoProperty"); + await CheckDateTime(ptd_props, "DTAutoProperty", dt); + } + + // Invoke getters, and check values + + var res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "Int" })); + Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "number", value = 5 }), "ptd.Int"); + + res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "String" })); + Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "string", value = "foobar" }), "ptd.String"); + + dt = new DateTime(3, 4, 5, 6, 7, 8); + res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "DT" })); + Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); + await CheckValue(res.Value["result"], TValueType("System.DateTime", dt.ToString()), "ptd.DT"); + await CheckDateTimeValue(res.Value["result"], dt); + + // Check arrays through getters + + res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "IntArray" })); + Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); + await CheckValue(res.Value["result"], TArray("int[]", 2), "ptd.IntArray"); + { + var arr_elems = await GetProperties(res.Value["result"] ? ["objectId"]?.Value()); + var exp_elems = new [] + { + TNumber(10), + TNumber(20) + }; + + await CheckProps(arr_elems, exp_elems, "ptd.IntArray"); + } + + res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "DTArray" })); + Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); + await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), "ptd.DTArray"); + { + var dt0 = new DateTime(6, 7, 8, 9, 10, 11); + var dt1 = new DateTime(1, 2, 3, 4, 5, 6); + + var arr_elems = await GetProperties(res.Value["result"] ? ["objectId"]?.Value()); + var exp_elems = new [] + { + TValueType("System.DateTime", dt0.ToString()), + TValueType("System.DateTime", dt1.ToString()), + }; + + await CheckProps(arr_elems, exp_elems, "ptd.DTArray"); + } + }); + + [Theory] + [InlineData("invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", "MoveNext", 38, 12)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "PropertyGettersTest", 30, 12)] + public async Task PropertyGettersOnStructsTest(string eval_fn, string method_name, int line, int col) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-cfo-test.cs", line, col, + method_name, + $"window.setTimeout(function() {{ {eval_fn} }}, 1);", + wait_for_event_fn : async(pause_location) => + { + var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + ptd = TObject("DebuggerTests.ClassWithProperties"), + swp = TObject("DebuggerTests.StructWithProperties"), + }, "locals#0"); + + var swp = GetAndAssertObjectWithName(frame_locals, "swp"); + + var swp_props = await GetProperties(swp?["value"] ? ["objectId"]?.Value()); + await CheckProps(swp_props, new + { + Int = TSymbol("int { get; }"), + String = TSymbol("string { get; }"), + DT = TSymbol("System.DateTime { get; }"), + IntArray = TSymbol("int[] { get; }"), + DTArray = TSymbol("System.DateTime[] { get; }") + }, "swp"); + }); + + [Theory] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 30, 12, false)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 30, 12, true)] + [InlineData("invoke_getters_js_test ();", "/other.js", 29, 1, false)] + [InlineData("invoke_getters_js_test ();", "/other.js", 29, 1, true)] + public async Task CheckAccessorsOnObjectsWithCFO(string eval_fn, string bp_loc, int line, int col, bool roundtrip) + { + await RunCallFunctionOn( + eval_fn, "function() { return this; }", "ptd", + bp_loc, line, col, + roundtrip : roundtrip, + test_fn : async(result) => + { + + var is_js = bp_loc.EndsWith(".js"); + + // Check with `accessorPropertiesOnly=true` + + var id = result.Value?["result"] ? ["objectId"]?.Value(); + var get_prop_req = JObject.FromObject(new + { + objectId = id, + accessorPropertiesOnly = true + }); + + var res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 6 : 5); // js returns extra `__proto__` member also + Assert.False(res.Value["result"].Any(jt => jt["name"]?.Value() == "StringField"), "StringField shouldn't be returned for `accessorPropertiesOnly`"); + + // Check with `accessorPropertiesOnly` unset, == false + get_prop_req = JObject.FromObject(new + { + objectId = id, + }); + + res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 8 : 7); // js returns a `__proto__` member also + Assert.True(res.Value["result"].Any(jt => jt["name"]?.Value() == "StringField"), "StringField should be returned for `accessorPropertiesOnly=false`"); + }); + + async Task GetPropertiesAndCheckAccessors(JObject get_prop_req, int num_fields) + { + var res = await ctx.cli.SendCommand("Runtime.getProperties", get_prop_req, ctx.token); + if (!res.IsOk) + Assert.True(false, $"Runtime.getProperties failed for {get_prop_req.ToString ()}, with Result: {res}"); + + var accessors = new string[] { "Int", "String", "DT", "IntArray", "DTArray" }; + foreach (var name in accessors) + { + var prop = GetAndAssertObjectWithName(res.Value["result"], name); + Assert.True(prop["value"] == null, $"{name} shouldn't have a `value`"); + + await CheckValue(prop, TGetter(name), $"{name}"); + } + + return res; + } + } + + async Task InvokeGetter(JToken obj, string fn, object arguments) => await ctx.cli.SendCommand( + "Runtime.callFunctionOn", + JObject.FromObject(new + { + functionDeclaration = fn, + objectId = obj["value"] ? ["objectId"]?.Value(), + arguments = new [] { new { value = arguments } } + }), ctx.token); + + /* + * 1. runs `Runtime.callFunctionOn` on the objectId, + * if @roundtrip == false, then + * -> calls @test_fn for that result (new objectId) + * else + * -> runs it again on the *result's* objectId. + * -> calls @test_fn on the *new* result objectId + * + * Returns: result of `Runtime.callFunctionOn` + */ + async Task RunCallFunctionOn(string eval_fn, string fn_decl, string local_name, string bp_loc, int line, int col, int res_array_len = -1, + Func test_fn = null, bool returnByValue = false, JArray fn_args = null, bool roundtrip = false) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + await SetBreakpoint(bp_loc, line, col); + + // callFunctionOn + var eval_expr = $"window.setTimeout(function() {{ {eval_fn} }}, 1);"; + var result = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr }), ctx.token); + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + // Um for js we get "scriptId": "6" + // CheckLocation (bp_loc, line, col, ctx.scripts, pause_location ["callFrames"][0]["location"]); + + // Check the object at the bp + var frame_locals = await GetProperties(pause_location["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value()); + var obj = GetAndAssertObjectWithName(frame_locals, local_name); + var obj_id = obj["value"]["objectId"].Value(); + + var cfo_args = JObject.FromObject(new + { + functionDeclaration = fn_decl, + objectId = obj_id + }); + + if (fn_args != null) + cfo_args["arguments"] = fn_args; + + if (returnByValue) + cfo_args["returnByValue"] = returnByValue; + + // callFunctionOn + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + await CheckCFOResult(result); + + // If it wasn't `returnByValue`, then try to run a new function + // on that *returned* object + // This second function, just returns the object as-is, so the same + // test_fn is re-usable. + if (!returnByValue && roundtrip) + { + cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return this; }", + objectId = result.Value["result"]["objectId"]?.Value() + }); + + if (fn_args != null) + cfo_args["arguments"] = fn_args; + + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + + await CheckCFOResult(result); + } + + if (test_fn != null) + await test_fn(result); + + return; + + async Task CheckCFOResult(Result result) + { + if (returnByValue) + return; + + if (res_array_len < 0) + await CheckValue(result.Value["result"], TObject("Object"), $"cfo-res"); + else + await CheckValue(result.Value["result"], TArray("Array", res_array_len), $"cfo-res"); + } + }); + } + } + +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs new file mode 100644 index 000000000000..6b7a5603d2d2 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Globalization; +using System.Threading.Tasks; +using Xunit; + +namespace DebuggerTests +{ + public class DateTimeList : DebuggerTestBase + { + + [Theory] + [InlineData("en-US")] + + // Currently not passing tests. Issue #19743 + // [InlineData ("ja-JP")] + // [InlineData ("es-ES")] + //[InlineData ("de-DE")] + //[InlineData ("ka-GE")] + //[InlineData ("hu-HU")] + public async Task CheckDateTimeLocale(string locale) + { + var insp = new Inspector(); + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-datetime-test.cs"; + + await SetBreakpointInMethod("debugger-test", "DebuggerTests.DateTimeTest", "LocaleTest", 15); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.DateTimeTest:LocaleTest'," + + $"'{locale}'); }}, 1);", + debugger_test_loc, 25, 12, "LocaleTest", + locals_fn : async(locals) => + { + DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(locale).DateTimeFormat; + CultureInfo.CurrentCulture = new CultureInfo(locale, false); + DateTime dt = new DateTime(2020, 1, 2, 3, 4, 5); + string dt_str = dt.ToString(); + + var fdtp = dtfi.FullDateTimePattern; + var ldp = dtfi.LongDatePattern; + var ltp = dtfi.LongTimePattern; + var sdp = dtfi.ShortDatePattern; + var stp = dtfi.ShortTimePattern; + + CheckString(locals, "fdtp", fdtp); + CheckString(locals, "ldp", ldp); + CheckString(locals, "ltp", ltp); + CheckString(locals, "sdp", sdp); + CheckString(locals, "stp", stp); + await CheckDateTime(locals, "dt", dt); + CheckString(locals, "dt_str", dt_str); + } + ); + + }); + } + + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj new file mode 100644 index 000000000000..09b79eb67dc2 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj @@ -0,0 +1,20 @@ + + + + $(NetCoreAppCurrent) + true + + + + + + + + + + + + + + + diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs new file mode 100644 index 000000000000..e186ddc5f71c --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs @@ -0,0 +1,306 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class DelegateTests : DebuggerTestBase + { + + [Theory] + [InlineData(0, 53, 8, "DelegatesTest", false)] + [InlineData(0, 53, 8, "DelegatesTest", true)] + [InlineData(2, 99, 8, "InnerMethod2", false)] + [InlineData(2, 99, 8, "InnerMethod2", true)] + public async Task InspectLocalsWithDelegatesAtBreakpointSite(int frame, int line, int col, string method_name, bool use_cfo) => + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", line, col, method_name, + "window.setTimeout(function() { invoke_delegates_test (); }, 1);", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func", "bool |(Math)"), + fn_func_null = TObject("System.Func", is_null : true), + fn_func_arr = TArray("System.Func[]", 1), + fn_del = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), + fn_del_null = TObject("Math.IsMathNull", is_null : true), + fn_del_arr = TArray("Math.IsMathNull[]", 1), + + // Unused locals + fn_func_unused = TDelegate("System.Func", "bool |(Math)"), + fn_func_null_unused = TObject("System.Func", is_null : true), + fn_func_arr_unused = TArray("System.Func[]", 1), + + fn_del_unused = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), + fn_del_null_unused = TObject("Math.IsMathNull", is_null : true), + fn_del_arr_unused = TArray("Math.IsMathNull[]", 1), + + res = TBool(false), + m_obj = TObject("Math") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] + { + TDelegate( + "System.Func", + "bool |(Math)") + }, "locals#fn_func_arr"); + + await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] + { + TDelegate( + "Math.IsMathNull", + "bool IsMathNullDelegateTarget (Math)") + }, "locals#fn_del_arr"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr_unused", new [] + { + TDelegate( + "System.Func", + "bool |(Math)") + }, "locals#fn_func_arr_unused"); + + await CompareObjectPropertiesFor(locals, "fn_del_arr_unused", new [] + { + TDelegate( + "Math.IsMathNull", + "bool IsMathNullDelegateTarget (Math)") + }, "locals#fn_del_arr_unused"); + } + ); + + [Theory] + [InlineData(0, 202, 8, "DelegatesSignatureTest", false)] + [InlineData(0, 202, 8, "DelegatesSignatureTest", true)] + [InlineData(2, 99, 8, "InnerMethod2", false)] + [InlineData(2, 99, 8, "InnerMethod2", true)] + public async Task InspectDelegateSignaturesWithFunc(int frame, int line, int col, string bp_method, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", + line, col, + bp_method, + "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:DelegatesSignatureTest'); }, 1)", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func>, Math.GenericStruct>", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + + fn_func_del = TDelegate("System.Func>, Math.GenericStruct>", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + + fn_func_null = TObject("System.Func>, Math.GenericStruct>", is_null : true), + fn_func_only_ret = TDelegate("System.Func", "bool |()"), + fn_func_arr = TArray("System.Func>, Math.GenericStruct>[]", 1), + + fn_del = TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + + fn_del_l = TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + + fn_del_null = TObject("Math.DelegateForSignatureTest", is_null : true), + fn_del_arr = TArray("Math.DelegateForSignatureTest[]", 2), + m_obj = TObject("Math"), + gs_gs = TValueType("Math.GenericStruct>"), + fn_void_del = TDelegate("Math.DelegateWithVoidReturn", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), + + fn_void_del_arr = TArray("Math.DelegateWithVoidReturn[]", 1), + fn_void_del_null = TObject("Math.DelegateWithVoidReturn", is_null : true), + gs = TValueType("Math.GenericStruct"), + rets = TArray("Math.GenericStruct[]", 6) + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] + { + TDelegate( + "System.Func>, Math.GenericStruct>", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + }, "locals#fn_func_arr"); + + await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] + { + TDelegate( + "Math.DelegateForSignatureTest", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + TDelegate( + "Math.DelegateForSignatureTest", + "Math.GenericStruct |(Math,Math.GenericStruct>)") + }, "locals#fn_del_arr"); + + await CompareObjectPropertiesFor(locals, "fn_void_del_arr", new [] + { + TDelegate( + "Math.DelegateWithVoidReturn", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)") + }, "locals#fn_void_del_arr"); + }); + + [Theory] + [InlineData(0, 224, 8, "ActionTSignatureTest", false)] + [InlineData(0, 224, 8, "ActionTSignatureTest", true)] + [InlineData(2, 99, 8, "InnerMethod2", false)] + [InlineData(2, 99, 8, "InnerMethod2", true)] + public async Task ActionTSignatureTest(int frame, int line, int col, string bp_method, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", line, col, + bp_method, + "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:ActionTSignatureTest'); }, 1)", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_action = TDelegate("System.Action>", + "void |(Math.GenericStruct)"), + fn_action_del = TDelegate("System.Action>", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), + fn_action_bare = TDelegate("System.Action", + "void|()"), + + fn_action_null = TObject("System.Action>", is_null : true), + + fn_action_arr = TArray("System.Action>[]", 3), + + gs = TValueType("Math.GenericStruct"), + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_action_arr", new [] + { + TDelegate( + "System.Action>", + "void |(Math.GenericStruct)"), + TDelegate( + "System.Action>", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), + TObject("System.Action>", is_null : true) + }, "locals#fn_action_arr"); + }); + + [Theory] + [InlineData(0, 242, 8, "NestedDelegatesTest", false)] + [InlineData(0, 242, 8, "NestedDelegatesTest", true)] + [InlineData(2, 99, 8, "InnerMethod2", false)] + [InlineData(2, 99, 8, "InnerMethod2", true)] + public async Task NestedDelegatesTest(int frame, int line, int col, string bp_method, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", line, col, + bp_method, + "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:NestedDelegatesTest'); }, 1)", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func, bool>", + "bool |(Func)"), + fn_func_null = TObject("System.Func, bool>", is_null : true), + fn_func_arr = TArray("System.Func, bool>[]", 1), + fn_del_arr = TArray("System.Func, bool>[]", 1), + + m_obj = TObject("Math"), + fn_del_null = TObject("System.Func, bool>", is_null : true), + fs = TDelegate("System.Func", + "bool |(int)") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] + { + TDelegate( + "System.Func, bool>", + "bool |(System.Func)") + }, "locals#fn_func_arr"); + + await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] + { + TDelegate( + "System.Func, bool>", + "bool DelegateTargetForNestedFunc (Func)") + }, "locals#fn_del_arr"); + }); + + [Theory] + [InlineData(0, 262, 8, "MethodWithDelegateArgs", false)] + [InlineData(0, 262, 8, "MethodWithDelegateArgs", true)] + [InlineData(2, 99, 8, "InnerMethod2", false)] + [InlineData(2, 99, 8, "InnerMethod2", true)] + public async Task DelegatesAsMethodArgsTest(int frame, int line, int col, string bp_method, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", line, col, + bp_method, + "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:DelegatesAsMethodArgsTest'); }, 1)", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + @this = TObject("Math"), + dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + fn_func = TDelegate("System.Func", + "bool |(char[])"), + fn_action = TDelegate("System.Action[]>", + "void |(Math.GenericStruct[])") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "dst_arr", new [] + { + TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + }, "locals#dst_arr"); + }); + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task MethodWithDelegatesAsyncTest(bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", 281, 8, + "MoveNext", //"DelegatesAsMethodArgsTestAsync" + "window.setTimeout (function () { invoke_static_method_async ('[debugger-test] Math:MethodWithDelegatesAsyncTest'); }, 1)", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + await CheckProps(locals, new + { + @this = TObject("Math"), + _dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + _fn_func = TDelegate("System.Func", + "bool |(char[])"), + _fn_action = TDelegate("System.Action[]>", + "void |(Math.GenericStruct[])") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "_dst_arr", new [] + { + TDelegate( + "Math.DelegateForSignatureTest", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + TDelegate( + "Math.DelegateForSignatureTest", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + }, "locals#dst_arr"); + }); + } + +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs new file mode 100644 index 000000000000..bedba1310041 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs @@ -0,0 +1,167 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.WebAssembly.Diagnostics +{ + internal class DevToolsClient : IDisposable + { + ClientWebSocket socket; + List pending_ops = new List(); + TaskCompletionSource side_exit = new TaskCompletionSource(); + List pending_writes = new List(); + Task current_write; + readonly ILogger logger; + + public DevToolsClient(ILogger logger) + { + this.logger = logger; + } + + ~DevToolsClient() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + } + + public async Task Close(CancellationToken cancellationToken) + { + if (socket.State == WebSocketState.Open) + await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Closing", cancellationToken); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + socket.Dispose(); + } + + Task Pump(Task task, CancellationToken token) + { + if (task != current_write) + return null; + current_write = null; + + pending_writes.RemoveAt(0); + + if (pending_writes.Count > 0) + { + current_write = socket.SendAsync(new ArraySegment(pending_writes[0]), WebSocketMessageType.Text, true, token); + return current_write; + } + return null; + } + + async Task ReadOne(CancellationToken token) + { + byte[] buff = new byte[4000]; + var mem = new MemoryStream(); + while (true) + { + var result = await this.socket.ReceiveAsync(new ArraySegment(buff), token); + if (result.MessageType == WebSocketMessageType.Close) + { + return null; + } + + if (result.EndOfMessage) + { + mem.Write(buff, 0, result.Count); + return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int) mem.Length); + } + else + { + mem.Write(buff, 0, result.Count); + } + } + } + + protected void Send(byte[] bytes, CancellationToken token) + { + pending_writes.Add(bytes); + if (pending_writes.Count == 1) + { + if (current_write != null) + throw new Exception("Internal state is bad. current_write must be null if there are no pending writes"); + + current_write = socket.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, token); + pending_ops.Add(current_write); + } + } + + async Task MarkCompleteAfterward(Func send, CancellationToken token) + { + try + { + await send(token); + side_exit.SetResult(true); + } + catch (Exception e) + { + side_exit.SetException(e); + } + } + + protected async Task ConnectWithMainLoops( + Uri uri, + Func receive, + Func send, + CancellationToken token) + { + + logger.LogDebug("connecting to {0}", uri); + this.socket = new ClientWebSocket(); + this.socket.Options.KeepAliveInterval = Timeout.InfiniteTimeSpan; + + await this.socket.ConnectAsync(uri, token); + pending_ops.Add(ReadOne(token)); + pending_ops.Add(side_exit.Task); + pending_ops.Add(MarkCompleteAfterward(send, token)); + + while (!token.IsCancellationRequested) + { + var task = await Task.WhenAny(pending_ops); + if (task == pending_ops[0]) + { //pending_ops[0] is for message reading + var msg = ((Task) task).Result; + pending_ops[0] = ReadOne(token); + Task tsk = receive(msg, token); + if (tsk != null) + pending_ops.Add(tsk); + } + else if (task == pending_ops[1]) + { + var res = ((Task) task).Result; + //it might not throw if exiting successfull + return res; + } + else + { //must be a background task + pending_ops.Remove(task); + var tsk = Pump(task, token); + if (tsk != null) + pending_ops.Add(tsk); + } + } + + return false; + } + + protected virtual void Log(string priority, string msg) + { + // + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs new file mode 100644 index 000000000000..f2836d3bc352 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -0,0 +1,214 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class EvaluateOnCallFrameTests : DebuggerTestBase + { + + [Fact] + public async Task EvaluateThisProperties() => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, + "run", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); + CheckContentValue(evaluate, "3"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dt"); + await CheckDateTimeValue(evaluate, new DateTime(2000, 5, 4, 3, 2, 1)); + }); + + [Theory] + [InlineData(63, 12, "EvaluateTestsStructInstanceMethod")] + [InlineData(79, 12, "GenericInstanceMethodOnStruct")] + [InlineData(102, 12, "EvaluateTestsGenericStructInstanceMethod")] + public async Task EvaluateThisPropertiesOnStruct(int line, int col, string method_name) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", line, col, + method_name, + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); + CheckContentValue(evaluate, "3"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dateTime"); + await CheckDateTimeValue(evaluate, new DateTime(2020, 1, 2, 3, 4, 5)); + }); + + [Fact] + public async Task EvaluateParameters() => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, + "run", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "g"); + CheckContentValue(evaluate, "100"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "h"); + CheckContentValue(evaluate, "200"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "valString"); + CheckContentValue(evaluate, "test"); + }); + + [Fact] + public async Task EvaluateLocals() => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, + "run", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d"); + CheckContentValue(evaluate, "101"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e"); + CheckContentValue(evaluate, "102"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "f"); + CheckContentValue(evaluate, "103"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_dt"); + await CheckDateTimeValue(evaluate, new DateTime(2010, 9, 8, 7, 6, 5)); + }); + + [Fact] + public async Task EvaluateLocalsAsync() + { + var bp_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + int line = 249; + int col = 12; + var function_name = "MoveNext"; + await CheckInspectLocalsAtBreakpointSite( + bp_loc, line, col, + function_name, + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.ArrayTestsClass:EntryPointForStructMethod', true); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + // sc_arg + { + var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); + await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#1"); + + var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); + await CheckProps(sc_arg_props, new + { + X = TNumber(10), + Y = TNumber(45), + Id = TString("sc#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + PointWithCustomGetter = TGetter("PointWithCustomGetter") + }, "sc_arg_props#1"); + } + + // local_gs + { + var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); + await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#1"); + + var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); + await CheckProps(local_gs_props, new + { + Id = TObject("string", is_null : true), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TNumber(0) + }, "local_gs_props#1"); + } + + // step, check local_gs + pause_location = await StepAndCheck(StepKind.Over, bp_loc, line + 1, col, function_name); + { + var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); + await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#2"); + + var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); + await CheckProps(local_gs_props, new + { + Id = TString("local_gs#Id"), + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) + }, "local_gs_props#2"); + } + + // step check sc_arg.Id + pause_location = await StepAndCheck(StepKind.Over, bp_loc, line + 2, col, function_name); + { + var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); + await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#2"); + + var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); + await CheckProps(sc_arg_props, new + { + X = TNumber(10), + Y = TNumber(45), + Id = TString("sc_arg#Id"), // <------- This changed + Color = TEnum("DebuggerTests.RGB", "Blue"), + PointWithCustomGetter = TGetter("PointWithCustomGetter") + }, "sc_arg_props#2"); + } + }); + } + + [Fact] + public async Task EvaluateExpressions() => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, + "run", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d + e"); + CheckContentValue(evaluate, "203"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e + 10"); + CheckContentValue(evaluate, "112"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a + a"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a + this.b"); + CheckContentValue(evaluate, "3"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "\"test\" + \"test\""); + CheckContentValue(evaluate, "testtest"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "5 + 5"); + CheckContentValue(evaluate, "10"); + }); + + [Fact] + public async Task EvaluateThisExpressions() => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, + "run", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.c"); + CheckContentValue(evaluate, "3"); + + // FIXME: not supported yet + // evaluate = await EvaluateOnCallFrame (pause_location ["callFrames"][0] ["callFrameId"].Value (), "this.dt"); + // await CheckDateTimeValue (evaluate, new DateTime (2000, 5, 4, 3, 2, 1)); + }); + } + +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs b/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs new file mode 100644 index 000000000000..d62bfc21f0aa --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs @@ -0,0 +1,81 @@ +// 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.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.WebAssembly.Diagnostics +{ + internal class InspectorClient : DevToolsClient + { + List < (int, TaskCompletionSource) > pending_cmds = new List < (int, TaskCompletionSource) > (); + Func onEvent; + int next_cmd_id; + + public InspectorClient(ILogger logger) : base(logger) { } + + Task HandleMessage(string msg, CancellationToken token) + { + var res = JObject.Parse(msg); + if (res["id"] == null) + DumpProtocol(string.Format("Event method: {0} params: {1}", res["method"], res["params"])); + else + DumpProtocol(string.Format("Response id: {0} res: {1}", res["id"], res)); + + if (res["id"] == null) + return onEvent(res["method"].Value(), res["params"] as JObject, token); + var id = res["id"].Value(); + var idx = pending_cmds.FindIndex(e => e.Item1 == id); + var item = pending_cmds[idx]; + pending_cmds.RemoveAt(idx); + item.Item2.SetResult(Result.FromJson(res)); + return null; + } + + public async Task Connect( + Uri uri, + Func onEvent, + Func send, + CancellationToken token) + { + + this.onEvent = onEvent; + await ConnectWithMainLoops(uri, HandleMessage, send, token); + } + + public Task SendCommand(string method, JObject args, CancellationToken token) + { + int id = ++next_cmd_id; + if (args == null) + args = new JObject(); + + var o = JObject.FromObject(new + { + id = id, + method = method, + @params = args + }); + + var tcs = new TaskCompletionSource(); + pending_cmds.Add((id, tcs)); + + var str = o.ToString(); + //Log ("protocol", $"SendCommand: id: {id} method: {method} params: {args}"); + + var bytes = Encoding.UTF8.GetBytes(str); + Send(bytes, token); + return tcs.Task; + } + + protected virtual void DumpProtocol(string msg) + { + // Console.WriteLine (msg); + //XXX make logging not stupid + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs new file mode 100644 index 000000000000..e121870d3192 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs @@ -0,0 +1,560 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class PointerTests : DebuggerTestBase + { + + public static TheoryData PointersTestData => + new TheoryData + { { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", false }, + { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", true }, + { $"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", false }, + { $"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", true } + }; + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointersToPrimitiveTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ip = TPointer("int*"), + ip_null = TPointer("int*", is_null : true), + ipp = TPointer("int**"), + ipp_null = TPointer("int**"), + + cvalue0 = TSymbol("113 'q'"), + cp = TPointer("char*"), + + vp = TPointer("void*"), + vp_null = TPointer("void*", is_null : true), + }, "locals", num_fields : 26); + + var props = await GetObjectOnLocals(locals, "ip"); + await CheckPointerValue(props, "*ip", TNumber(5), "locals"); + + { + var ipp_props = await GetObjectOnLocals(locals, "ipp"); + await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); + + ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); + await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); + } + + { + var ipp_props = await GetObjectOnLocals(locals, "ipp_null"); + await CheckPointerValue(ipp_props, "*ipp_null", TPointer("int*", is_null : true)); + } + + // *cp + props = await GetObjectOnLocals(locals, "cp"); + await CheckPointerValue(props, "*cp", TSymbol("113 'q'")); + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointerArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ipa = TArray("int*[]", 3) + }, "locals", num_fields : 26); + + var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new [] + { + TPointer("int*"), + TPointer("int*"), + TPointer("int*", is_null : true) + }); + + await CheckArrayElements(ipa_elems, new [] + { + TNumber(5), + TNumber(10), + null + }); + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalDoublePointerToPrimitiveTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ippa = TArray("int**[]", 5) + }, "locals", num_fields : 26); + + var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new [] + { + TPointer("int**"), + TPointer("int**"), + TPointer("int**"), + TPointer("int**"), + TPointer("int**", is_null : true) + }); + + { + var actual_elems = await CheckArrayElements(ippa_elems, new [] + { + TPointer("int*"), + TPointer("int*", is_null : true), + TPointer("int*"), + TPointer("int*", is_null : true), + null + }); + + var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); + await CheckPointerValue(val, "**[0]", TNumber(5)); + + val = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckPointerValue(val, "**[2]", TNumber(5)); + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointersToValueTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dt = TValueType("System.DateTime", dt.ToString()), + dtp = TPointer("System.DateTime*"), + dtp_null = TPointer("System.DateTime*", is_null : true), + + gsp = TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), + gsp_null = TPointer("DebuggerTests.GenericStructWithUnmanagedT*") + }, "locals", num_fields : 26); + + await CheckDateTime(locals, "dt", dt); + + // *dtp + var props = await GetObjectOnLocals(locals, "dtp"); + await CheckDateTime(props, "*dtp", dt); + + var gsp_props = await GetObjectOnLocals(locals, "gsp"); + await CheckPointerValue(gsp_props, "*gsp", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); + + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + + var gsp_deref_props = await GetObjectOnLocals(gsp_props, "*gsp"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); + + var dtpp_deref_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); + await CheckDateTime(dtpp_deref_props, "**DTPP", dt); + } + } + + // gsp_null + var gsp_w_n_props = await GetObjectOnLocals(locals, "gsp_null"); + await CheckPointerValue(gsp_w_n_props, "*gsp_null", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); + + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + + var gsp_deref_props = await GetObjectOnLocals(gsp_w_n_props, "*gsp_null"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null : true), "locals#*gsp"); + } + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtpa = TArray("System.DateTime*[]", 2) + }, "locals", num_fields : 26); + + // dtpa + var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new [] + { + TPointer("System.DateTime*"), + TPointer("System.DateTime*", is_null : true) + })); + { + var actual_elems = await CheckArrayElements(dtpa_elems, new [] + { + TValueType("System.DateTime", dt.ToString()), + null + }); + + await CheckDateTime(actual_elems[0], "*[0]", dt); + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointersToGenericValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT*[]", 3), + }, "locals", num_fields : 26); + + // dtpa + var gspa_elems = await CompareObjectPropertiesFor(locals, "gspa", new [] + { + TPointer("DebuggerTests.GenericStructWithUnmanagedT*", is_null : true), + TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), + TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), + }); + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + var actual_elems = await CheckArrayElements(gspa_elems, new [] + { + null, + TValueType("DebuggerTests.GenericStructWithUnmanagedT"), + TValueType("DebuggerTests.GenericStructWithUnmanagedT") + }); + + // *[1] + { + var gsp_deref_props = await GetObjectOnLocals(actual_elems[1], "*[1]"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); + + dtpp_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); + await CheckDateTime(dtpp_props, "**DTPP", dt); + } + } + + // *[2] + { + var gsp_deref_props = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null : true), "locals#*gsp"); + } + } + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalDoublePointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtppa = TArray("System.DateTime**[]", 3), + }, "locals", num_fields : 26); + + // DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null }; + var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new [] + { + TPointer("System.DateTime**"), + TPointer("System.DateTime**"), + TPointer("System.DateTime**", is_null : true) + })); + + var exp_elems = new [] + { + TPointer("System.DateTime*"), + TPointer("System.DateTime*", is_null : true), + null + }; + + var actual_elems = new JToken[exp_elems.Length]; + for (int i = 0; i < exp_elems.Length; i++) + { + if (exp_elems[i] != null) + { + actual_elems[i] = await GetObjectOnLocals(dtppa_elems, i.ToString()); + await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->"); + } + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersTestData))] + public async Task InspectLocalPointersInClasses(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + cwp = TObject("DebuggerTests.GenericClassWithPointers"), + cwp_null = TObject("DebuggerTests.GenericClassWithPointers") + }, "locals", num_fields : 26); + + var cwp_props = await GetObjectOnLocals(locals, "cwp"); + var ptr_props = await GetObjectOnLocals(cwp_props, "Ptr"); + await CheckDateTime(ptr_props, "*Ptr", dt); + }); + + public static TheoryData PointersAsMethodArgsTestData => + new TheoryData + { { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", false }, + { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", true }, + }; + + [Theory] + [MemberDataAttribute(nameof(PointersAsMethodArgsTestData))] + public async Task InspectPrimitiveTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ip = TPointer("int*"), + ipp = TPointer("int**"), + ipa = TArray("int*[]", 3), + ippa = TArray("int**[]", 5) + }, "locals", num_fields : 8); + + // ip + var props = await GetObjectOnLocals(locals, "ip"); + await CheckPointerValue(props, "*ip", TNumber(5), "locals"); + + // ipp + var ipp_props = await GetObjectOnLocals(locals, "ipp"); + await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); + + ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); + await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); + + // ipa + var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new [] + { + TPointer("int*"), + TPointer("int*"), + TPointer("int*", is_null : true) + }); + + await CheckArrayElements(ipa_elems, new [] + { + TNumber(5), + TNumber(10), + null + }); + + // ippa + var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new [] + { + TPointer("int**"), + TPointer("int**"), + TPointer("int**"), + TPointer("int**"), + TPointer("int**", is_null : true) + }); + + { + var actual_elems = await CheckArrayElements(ippa_elems, new [] + { + TPointer("int*"), + TPointer("int*", is_null : true), + TPointer("int*"), + TPointer("int*", is_null : true), + null + }); + + var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); + await CheckPointerValue(val, "**[0]", TNumber(5)); + + val = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckPointerValue(val, "**[2]", TNumber(5)); + } + }); + + [Theory] + [MemberDataAttribute(nameof(PointersAsMethodArgsTestData))] + public async Task InspectValueTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtp = TPointer("System.DateTime*"), + dtpp = TPointer("System.DateTime**"), + dtpa = TArray("System.DateTime*[]", 2), + dtppa = TArray("System.DateTime**[]", 3) + }, "locals", num_fields : 8); + + // *dtp + var dtp_props = await GetObjectOnLocals(locals, "dtp"); + await CheckDateTime(dtp_props, "*dtp", dt); + + // *dtpp + var dtpp_props = await GetObjectOnLocals(locals, "dtpp"); + await CheckPointerValue(dtpp_props, "*dtpp", TPointer("System.DateTime*"), "locals"); + + dtpp_props = await GetObjectOnLocals(dtpp_props, "*dtpp"); + await CheckDateTime(dtpp_props, "**dtpp", dt); + + // dtpa + var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new [] + { + TPointer("System.DateTime*"), + TPointer("System.DateTime*", is_null : true) + })); + { + var actual_elems = await CheckArrayElements(dtpa_elems, new [] + { + TValueType("System.DateTime", dt.ToString()), + null + }); + + await CheckDateTime(actual_elems[0], "*[0]", dt); + } + + // dtppa = new DateTime**[] { &dtp, &dtp_null, null }; + var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new [] + { + TPointer("System.DateTime**"), + TPointer("System.DateTime**"), + TPointer("System.DateTime**", is_null : true) + })); + + var exp_elems = new [] + { + TPointer("System.DateTime*"), + TPointer("System.DateTime*", is_null : true), + null + }; + + await CheckArrayElements(dtppa_elems, exp_elems); + }); + + [Theory] + [InlineData("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", false)] + [InlineData("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", true)] + public async Task DerefNonPointerObject(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + type, method, line_offset, bp_function_name, + "window.setTimeout(function() { " + eval_fn + " })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + + // this will generate the object ids + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var complex = GetAndAssertObjectWithName(locals, "complex"); + + // try to deref the non-pointer object, as a pointer + var props = await GetProperties(complex["value"]["objectId"].Value().Replace(":object:", ":pointer:")); + Assert.Empty(props.Values()); + + // try to deref an invalid pointer id + props = await GetProperties("dotnet:pointer:123897"); + Assert.Empty(props.Values()); + }); + + async Task CheckArrayElements(JToken array, JToken[] exp_elems) + { + var actual_elems = new JToken[exp_elems.Length]; + for (int i = 0; i < exp_elems.Length; i++) + { + if (exp_elems[i] != null) + { + actual_elems[i] = await GetObjectOnLocals(array, i.ToString()); + await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->"); + } + } + + return actual_elems; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs new file mode 100644 index 000000000000..b038d2cd8385 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs @@ -0,0 +1,990 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + class Inspector + { + // InspectorClient client; + Dictionary> notifications = new Dictionary>(); + Dictionary> eventListeners = new Dictionary>(); + + public const string PAUSE = "pause"; + public const string READY = "ready"; + + public Task WaitFor(string what) + { + if (notifications.ContainsKey(what)) + throw new Exception($"Invalid internal state, waiting for {what} while another wait is already setup"); + var n = new TaskCompletionSource(); + notifications[what] = n; + return n.Task; + } + + void NotifyOf(string what, JObject args) + { + if (!notifications.ContainsKey(what)) + throw new Exception($"Invalid internal state, notifying of {what}, but nobody waiting"); + notifications[what].SetResult(args); + notifications.Remove(what); + } + + public void On(string evtName, Func cb) + { + eventListeners[evtName] = cb; + } + + void FailAllWaitersWithException(JObject exception) + { + foreach (var tcs in notifications.Values) + tcs.SetException(new ArgumentException(exception.ToString())); + } + + async Task OnMessage(string method, JObject args, CancellationToken token) + { + //System.Console.WriteLine("OnMessage " + method + args); + switch (method) + { + case "Debugger.paused": + NotifyOf(PAUSE, args); + break; + case "Mono.runtimeReady": + NotifyOf(READY, args); + break; + case "Runtime.consoleAPICalled": + Console.WriteLine("CWL: {0}", args?["args"] ? [0] ? ["value"]); + break; + } + if (eventListeners.ContainsKey(method)) + await eventListeners[method](args, token); + else if (String.Compare(method, "Runtime.exceptionThrown") == 0) + FailAllWaitersWithException(args); + } + + public async Task Ready(Func cb = null, TimeSpan? span = null) + { + using(var cts = new CancellationTokenSource()) + { + cts.CancelAfter(span?.Milliseconds ?? 60 * 1000); //tests have 1 minute to complete by default + var uri = new Uri($"ws://{TestHarnessProxy.Endpoint.Authority}/launch-chrome-and-connect"); + using var loggerFactory = LoggerFactory.Create( + builder => builder.AddConsole().AddFilter(null, LogLevel.Information)); + using(var client = new InspectorClient(loggerFactory.CreateLogger())) + { + await client.Connect(uri, OnMessage, async token => + { + Task[] init_cmds = { + client.SendCommand("Profiler.enable", null, token), + client.SendCommand("Runtime.enable", null, token), + client.SendCommand("Debugger.enable", null, token), + client.SendCommand("Runtime.runIfWaitingForDebugger", null, token), + WaitFor(READY), + }; + // await Task.WhenAll (init_cmds); + Console.WriteLine("waiting for the runtime to be ready"); + await init_cmds[4]; + Console.WriteLine("runtime ready, TEST TIME"); + if (cb != null) + { + Console.WriteLine("await cb(client, token)"); + await cb(client, token); + } + + }, cts.Token); + await client.Close(cts.Token); + } + } + } + } + + public class DebuggerTestBase + { + protected Task startTask; + + static string FindTestPath() + { + //FIXME how would I locate it otherwise? + var test_path = Environment.GetEnvironmentVariable("TEST_SUITE_PATH"); + //Lets try to guest + if (test_path != null && Directory.Exists(test_path)) + return test_path; + + var cwd = Environment.CurrentDirectory; + Console.WriteLine("guessing from {0}", cwd); + //tests run from DebuggerTestSuite/bin/Debug/netcoreapp2.1 + var new_path = Path.Combine(cwd, "../../../../bin/debugger-test-suite"); + if (File.Exists(Path.Combine(new_path, "debugger-driver.html"))) + return new_path; + + throw new Exception("Missing TEST_SUITE_PATH env var and could not guess path from CWD"); + } + + static string[] PROBE_LIST = { + "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", + "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge", + "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary", + "/usr/bin/chromium", + "/usr/bin/chromium-browser", + }; + static string chrome_path; + + static string FindChromePath() + { + if (chrome_path != null) + return chrome_path; + + foreach (var s in PROBE_LIST) + { + if (File.Exists(s)) + { + chrome_path = s; + Console.WriteLine($"Using chrome path: ${s}"); + return s; + } + } + throw new Exception("Could not find an installed Chrome to use"); + } + + public DebuggerTestBase(string driver = "debugger-driver.html") + { + startTask = TestHarnessProxy.Start(FindChromePath(), FindTestPath(), driver); + } + + public Task Ready() => startTask; + + internal DebugTestContext ctx; + internal Dictionary dicScriptsIdToUrl; + internal Dictionary dicFileToUrl; + internal Dictionary SubscribeToScripts(Inspector insp) + { + dicScriptsIdToUrl = new Dictionary(); + dicFileToUrl = new Dictionary(); + insp.On("Debugger.scriptParsed", async(args, c) => + { + var script_id = args?["scriptId"]?.Value(); + var url = args["url"]?.Value(); + if (script_id.StartsWith("dotnet://")) + { + var dbgUrl = args["dotNetUrl"]?.Value(); + var arrStr = dbgUrl.Split("/"); + dbgUrl = arrStr[0] + "/" + arrStr[1] + "/" + arrStr[2] + "/" + arrStr[arrStr.Length - 1]; + dicScriptsIdToUrl[script_id] = dbgUrl; + dicFileToUrl[dbgUrl] = args["url"]?.Value(); + } + else if (!String.IsNullOrEmpty(url)) + { + dicFileToUrl[new Uri(url).AbsolutePath] = url; + } + await Task.FromResult(0); + }); + return dicScriptsIdToUrl; + } + + internal async Task CheckInspectLocalsAtBreakpointSite(string url_key, int line, int column, string function_name, string eval_expression, + Action test_fn = null, Func wait_for_event_fn = null, bool use_cfo = false) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + var bp = await SetBreakpoint(url_key, line, column); + + await EvaluateAndCheck( + eval_expression, url_key, line, column, + function_name, + wait_for_event_fn : async(pause_location) => + { + //make sure we're on the right bp + + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + + var scope = top_frame["scopeChain"][0]; + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + if (wait_for_event_fn != null) + await wait_for_event_fn(pause_location); + else + await Task.CompletedTask; + }, + locals_fn: (locals) => + { + if (test_fn != null) + test_fn(locals); + } + ); + }); + } + + // sets breakpoint by method name and line offset + internal async Task CheckInspectLocalsAtBreakpointSite(string type, string method, int line_offset, string bp_function_name, string eval_expression, + Action locals_fn = null, Func wait_for_event_fn = null, bool use_cfo = false, string assembly = "debugger-test.dll", int col = 0) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + var bp = await SetBreakpointInMethod(assembly, type, method, line_offset, col); + + var args = JObject.FromObject(new { expression = eval_expression }); + var res = await ctx.cli.SendCommand("Runtime.evaluate", args, ctx.token); + if (!res.IsOk) + { + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + } + + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + if (bp_function_name != null) + Assert.Equal(bp_function_name, pause_location["callFrames"] ? [0] ? ["functionName"]?.Value()); + + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + + var scope = top_frame["scopeChain"][0]; + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + + if (wait_for_event_fn != null) + await wait_for_event_fn(pause_location); + + if (locals_fn != null) + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + locals_fn(locals); + } + }); + } + + internal void CheckLocation(string script_loc, int line, int column, Dictionary scripts, JToken location) + { + var loc_str = $"{ scripts[location["scriptId"].Value()] }" + + $"#{ location ["lineNumber"].Value () }" + + $"#{ location ["columnNumber"].Value () }"; + + var expected_loc_str = $"{script_loc}#{line}#{column}"; + Assert.Equal(expected_loc_str, loc_str); + } + + internal void CheckNumber(JToken locals, string name, T value) + { + foreach (var l in locals) + { + if (name != l["name"]?.Value()) + continue; + var val = l["value"]; + Assert.Equal("number", val["type"]?.Value()); + Assert.Equal(value, val["value"].Value()); + return; + } + Assert.True(false, $"Could not find variable '{name}'"); + } + + internal void CheckString(JToken locals, string name, string value) + { + foreach (var l in locals) + { + if (name != l["name"]?.Value()) + continue; + var val = l["value"]; + if (value == null) + { + Assert.Equal("object", val["type"]?.Value()); + Assert.Equal("null", val["subtype"]?.Value()); + } + else + { + Assert.Equal("string", val["type"]?.Value()); + Assert.Equal(value, val["value"]?.Value()); + } + return; + } + Assert.True(false, $"Could not find variable '{name}'"); + } + + internal JToken CheckSymbol(JToken locals, string name, string value) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + Assert.Equal("symbol", val["type"]?.Value()); + Assert.Equal(value, val["value"]?.Value()); + return l; + } + + internal JToken CheckObject(JToken locals, string name, string class_name, string subtype = null, bool is_null = false) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + Assert.Equal("object", val["type"]?.Value()); + Assert.True(val["isValueType"] == null || !val["isValueType"].Value()); + Assert.Equal(class_name, val["className"]?.Value()); + + var has_null_subtype = val["subtype"] != null && val["subtype"]?.Value() == "null"; + Assert.Equal(is_null, has_null_subtype); + if (subtype != null) + Assert.Equal(subtype, val["subtype"]?.Value()); + + return l; + } + + internal async Task CheckPointerValue(JToken locals, string name, JToken expected, string label = null) + { + var l = GetAndAssertObjectWithName(locals, name); + await CheckValue(l["value"], expected, $"{label ?? String.Empty}-{name}"); + return l; + } + + internal async Task CheckDateTime(JToken locals, string name, DateTime expected) + { + var obj = GetAndAssertObjectWithName(locals, name); + await CheckDateTimeValue(obj["value"], expected); + } + + internal async Task CheckDateTimeValue(JToken value, DateTime expected) + { + AssertEqual("System.DateTime", value["className"]?.Value(), "className"); + AssertEqual(expected.ToString(), value["description"]?.Value(), "description"); + + var members = await GetProperties(value["objectId"]?.Value()); + + // not checking everything + CheckNumber(members, "Year", expected.Year); + CheckNumber(members, "Month", expected.Month); + CheckNumber(members, "Day", expected.Day); + CheckNumber(members, "Hour", expected.Hour); + CheckNumber(members, "Minute", expected.Minute); + CheckNumber(members, "Second", expected.Second); + + // FIXME: check some float properties too + } + + internal JToken CheckBool(JToken locals, string name, bool expected) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + Assert.Equal("boolean", val["type"]?.Value()); + if (val["value"] == null) + Assert.True(false, "expected bool value not found for variable named {name}"); + Assert.Equal(expected, val["value"]?.Value()); + + return l; + } + + internal void CheckContentValue(JToken token, string value) + { + var val = token["value"].Value(); + Assert.Equal(value, val); + } + + internal JToken CheckValueType(JToken locals, string name, string class_name) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + Assert.Equal("object", val["type"]?.Value()); + Assert.True(val["isValueType"] != null && val["isValueType"].Value()); + Assert.Equal(class_name, val["className"]?.Value()); + return l; + } + + internal JToken CheckEnum(JToken locals, string name, string class_name, string descr) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + Assert.Equal("object", val["type"]?.Value()); + Assert.True(val["isEnum"] != null && val["isEnum"].Value()); + Assert.Equal(class_name, val["className"]?.Value()); + Assert.Equal(descr, val["description"]?.Value()); + return l; + } + + internal void CheckArray(JToken locals, string name, string class_name) + { + foreach (var l in locals) + { + if (name != l["name"]?.Value()) + continue; + + var val = l["value"]; + Assert.Equal("object", val["type"]?.Value()); + Assert.Equal("array", val["subtype"]?.Value()); + Assert.Equal(class_name, val["className"]?.Value()); + + //FIXME: elements? + return; + } + Assert.True(false, $"Could not find variable '{name}'"); + } + + internal JToken GetAndAssertObjectWithName(JToken obj, string name) + { + var l = obj.FirstOrDefault(jt => jt["name"]?.Value() == name); + if (l == null) + Assert.True(false, $"Could not find variable '{name}'"); + return l; + } + + internal async Task SendCommand(string method, JObject args) + { + var res = await ctx.cli.SendCommand(method, args, ctx.token); + if (!res.IsOk) + { + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + } + return res; + } + + internal async Task Evaluate(string expression) + { + return await SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = expression })); + } + + internal void AssertLocation(JObject args, string methodName) + { + Assert.Equal(methodName, args["callFrames"] ? [0] ? ["functionName"]?.Value()); + } + + // Place a breakpoint in the given method and run until its hit + // Return the Debugger.paused data + internal async Task RunUntil(string methodName) + { + await SetBreakpointInMethod("debugger-test", "DebuggerTest", methodName); + // This will run all the tests until it hits the bp + await Evaluate("window.setTimeout(function() { invoke_run_all (); }, 1);"); + var wait_res = await ctx.insp.WaitFor(Inspector.PAUSE); + AssertLocation(wait_res, "locals_inner"); + return wait_res; + } + + internal async Task StepAndCheck(StepKind kind, string script_loc, int line, int column, string function_name, + Func wait_for_event_fn = null, Action locals_fn = null, int times = 1) + { + for (int i = 0; i < times - 1; i++) + { + await SendCommandAndCheck(null, $"Debugger.step{kind.ToString ()}", null, -1, -1, null); + } + + // Check for method/line etc only at the last step + return await SendCommandAndCheck( + null, $"Debugger.step{kind.ToString ()}", script_loc, line, column, function_name, + wait_for_event_fn : wait_for_event_fn, + locals_fn : locals_fn); + } + + internal async Task EvaluateAndCheck(string expression, string script_loc, int line, int column, string function_name, + Func wait_for_event_fn = null, Action locals_fn = null) => await SendCommandAndCheck( + JObject.FromObject(new { expression = expression }), + "Runtime.evaluate", script_loc, line, column, function_name, + wait_for_event_fn : wait_for_event_fn, + locals_fn : locals_fn); + + internal async Task SendCommandAndCheck(JObject args, string method, string script_loc, int line, int column, string function_name, + Func wait_for_event_fn = null, Action locals_fn = null, string waitForEvent = Inspector.PAUSE) + { + var res = await ctx.cli.SendCommand(method, args, ctx.token); + if (!res.IsOk) + { + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + } + + var wait_res = await ctx.insp.WaitFor(waitForEvent); + + if (function_name != null) + Assert.Equal(function_name, wait_res["callFrames"] ? [0] ? ["functionName"]?.Value()); + + if (script_loc != null) + CheckLocation(script_loc, line, column, ctx.scripts, wait_res["callFrames"][0]["location"]); + + if (wait_for_event_fn != null) + await wait_for_event_fn(wait_res); + + if (locals_fn != null) + { + var locals = await GetProperties(wait_res["callFrames"][0]["callFrameId"].Value()); + locals_fn(locals); + } + + return wait_res; + } + + internal async Task CheckDelegate(JToken locals, string name, string className, string target) + { + var l = GetAndAssertObjectWithName(locals, name); + var val = l["value"]; + + await CheckDelegate(l, TDelegate(className, target), name); + } + + internal async Task CheckDelegate(JToken actual_val, JToken exp_val, string label) + { + AssertEqual("object", actual_val["type"]?.Value(), $"{label}-type"); + AssertEqual(exp_val["className"]?.Value(), actual_val["className"]?.Value(), $"{label}-className"); + + var actual_target = actual_val["description"]?.Value(); + Assert.True(actual_target != null, $"${label}-description"); + var exp_target = exp_val["target"].Value(); + + CheckDelegateTarget(actual_target, exp_target); + + var del_props = await GetProperties(actual_val["objectId"]?.Value()); + AssertEqual(1, del_props.Count(), $"${label}-delegate-properties-count"); + + var obj = del_props.Where(jt => jt["name"]?.Value() == "Target").FirstOrDefault(); + Assert.True(obj != null, $"[{label}] Property named 'Target' found found in delegate properties"); + + AssertEqual("symbol", obj["value"] ? ["type"]?.Value(), $"{label}#Target#type"); + CheckDelegateTarget(obj["value"] ? ["value"]?.Value(), exp_target); + + return; + + void CheckDelegateTarget(string actual_target, string exp_target) + { + var parts = exp_target.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 1) + { + // not a generated method + AssertEqual(exp_target, actual_target, $"{label}-description"); + } + else + { + bool prefix = actual_target.StartsWith(parts[0], StringComparison.Ordinal); + Assert.True(prefix, $"{label}-description, Expected target to start with '{parts[0]}'. Actual: '{actual_target}'"); + + var remaining = actual_target.Substring(parts[0].Length); + bool suffix = remaining.EndsWith(parts[1], StringComparison.Ordinal); + Assert.True(prefix, $"{label}-description, Expected target to end with '{parts[1]}'. Actual: '{remaining}'"); + } + } + } + + internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string label) + { + var ctype = exp_val["__custom_type"].Value(); + switch (ctype) + { + case "delegate": + await CheckDelegate(actual_val, exp_val, label); + break; + + case "pointer": + { + + if (exp_val["is_null"]?.Value() == true) + { + AssertEqual("symbol", actual_val["type"]?.Value(), $"{label}-type"); + + var exp_val_str = $"({exp_val ["type_name"]?.Value()}) 0"; + AssertEqual(exp_val_str, actual_val["value"]?.Value(), $"{label}-value"); + AssertEqual(exp_val_str, actual_val["description"]?.Value(), $"{label}-description"); + } + else if (exp_val["is_void"]?.Value() == true) + { + AssertEqual("symbol", actual_val["type"]?.Value(), $"{label}-type"); + + var exp_val_str = $"({exp_val ["type_name"]?.Value()})"; + AssertStartsWith(exp_val_str, actual_val["value"]?.Value(), $"{label}-value"); + AssertStartsWith(exp_val_str, actual_val["description"]?.Value(), $"{label}-description"); + } + else + { + AssertEqual("object", actual_val["type"]?.Value(), $"{label}-type"); + + var exp_prefix = $"({exp_val ["type_name"]?.Value()})"; + AssertStartsWith(exp_prefix, actual_val["className"]?.Value(), $"{label}-className"); + AssertStartsWith(exp_prefix, actual_val["description"]?.Value(), $"{label}-description"); + Assert.False(actual_val["className"]?.Value() == $"{exp_prefix} 0", $"[{label}] Expected a non-null value, but got {actual_val}"); + } + break; + } + + case "getter": + { + // For getter, `actual_val` is not `.value`, instead it's the container object + // which has a `.get` instead of a `.value` + var get = actual_val["get"]; + Assert.True(get != null, $"[{label}] No `get` found. {(actual_val != null ? "Make sure to pass the container object for testing getters, and not the ['value']": String.Empty)}"); + + AssertEqual("Function", get["className"]?.Value(), $"{label}-className"); + AssertStartsWith($"get {exp_val ["type_name"]?.Value ()} ()", get["description"]?.Value(), $"{label}-description"); + AssertEqual("function", get["type"]?.Value(), $"{label}-type"); + + break; + } + + case "ignore_me": + // nothing to check ;) + break; + + default: + throw new ArgumentException($"{ctype} not supported"); + } + } + + internal async Task CheckProps(JToken actual, object exp_o, string label, int num_fields = -1) + { + if (exp_o.GetType().IsArray || exp_o is JArray) + { + if (!(actual is JArray actual_arr)) + { + Assert.True(false, $"[{label}] Expected to get an array here but got {actual}"); + return; + } + + var exp_v_arr = JArray.FromObject(exp_o); + AssertEqual(exp_v_arr.Count, actual_arr.Count(), $"{label}-count"); + + for (int i = 0; i < exp_v_arr.Count; i++) + { + var exp_i = exp_v_arr[i]; + var act_i = actual_arr[i]; + + AssertEqual(i.ToString(), act_i["name"]?.Value(), $"{label}-[{i}].name"); + if (exp_i != null) + await CheckValue(act_i["value"], exp_i, $"{label}-{i}th value"); + } + + return; + } + + // Not an array + var exp = exp_o as JObject; + if (exp == null) + exp = JObject.FromObject(exp_o); + + num_fields = num_fields < 0 ? exp.Values().Count() : num_fields; + Assert.True(num_fields == actual.Count(), $"[{label}] Number of fields don't match, Expected: {num_fields}, Actual: {actual.Count()}"); + + foreach (var kvp in exp) + { + var exp_name = kvp.Key; + var exp_val = kvp.Value; + + var actual_obj = actual.FirstOrDefault(jt => jt["name"]?.Value() == exp_name); + if (actual_obj == null) + { + Assert.True(actual_obj != null, $"[{label}] Could not find property named '{exp_name}'"); + } + + Assert.True(actual_obj != null, $"[{label}] not value found for property named '{exp_name}'"); + + var actual_val = actual_obj["value"]; + if (exp_val.Type == JTokenType.Array) + { + var actual_props = await GetProperties(actual_val["objectId"]?.Value()); + await CheckProps(actual_props, exp_val, $"{label}-{exp_name}"); + } + else if (exp_val["__custom_type"] != null && exp_val["__custom_type"]?.Value() == "getter") + { + // hack: for getters, actual won't have a .value + await CheckCustomType(actual_obj, exp_val, $"{label}#{exp_name}"); + } + else + { + await CheckValue(actual_val, exp_val, $"{label}#{exp_name}"); + } + } + } + + internal async Task CheckValue(JToken actual_val, JToken exp_val, string label) + { + if (exp_val["__custom_type"] != null) + { + await CheckCustomType(actual_val, exp_val, label); + return; + } + + if (exp_val["type"] == null && actual_val["objectId"] != null) + { + var new_val = await GetProperties(actual_val["objectId"].Value()); + await CheckProps(new_val, exp_val, $"{label}-{actual_val["objectId"]?.Value()}"); + return; + } + + foreach (var jp in exp_val.Values()) + { + if (jp.Value.Type == JTokenType.Object) + { + var new_val = await GetProperties(actual_val["objectId"].Value()); + await CheckProps(new_val, jp.Value, $"{label}-{actual_val["objectId"]?.Value()}"); + + continue; + } + + var exp_val_str = jp.Value.Value(); + bool null_or_empty_exp_val = String.IsNullOrEmpty(exp_val_str); + + var actual_field_val = actual_val.Values().FirstOrDefault(a_jp => a_jp.Name == jp.Name); + var actual_field_val_str = actual_field_val?.Value?.Value(); + if (null_or_empty_exp_val && String.IsNullOrEmpty(actual_field_val_str)) + continue; + + Assert.True(actual_field_val != null, $"[{label}] Could not find value field named {jp.Name}"); + + Assert.True(exp_val_str == actual_field_val_str, + $"[{label}] Value for json property named {jp.Name} didn't match.\n" + + $"Expected: {jp.Value.Value ()}\n" + + $"Actual: {actual_field_val.Value.Value ()}"); + } + } + + internal async Task GetLocalsForFrame(JToken frame, string script_loc, int line, int column, string function_name) + { + CheckLocation(script_loc, line, column, ctx.scripts, frame["location"]); + Assert.Equal(function_name, frame["functionName"].Value()); + + return await GetProperties(frame["callFrameId"].Value()); + } + + internal async Task GetObjectOnFrame(JToken frame, string name) + { + var locals = await GetProperties(frame["callFrameId"].Value()); + return await GetObjectOnLocals(locals, name); + } + + // Find an object with @name, *fetch* the object, and check against @o + internal async Task CompareObjectPropertiesFor(JToken locals, string name, object o, string label = null, int num_fields = -1) + { + if (label == null) + label = name; + var props = await GetObjectOnLocals(locals, name); + try + { + if (o != null) + await CheckProps(props, o, label, num_fields); + return props; + } + catch + { + throw; + } + } + + internal async Task GetObjectOnLocals(JToken locals, string name) + { + var obj = GetAndAssertObjectWithName(locals, name); + var objectId = obj["value"]["objectId"]?.Value(); + Assert.True(!String.IsNullOrEmpty(objectId), $"No objectId found for {name}"); + + return await GetProperties(objectId); + } + + /* @fn_args is for use with `Runtime.callFunctionOn` only */ + internal async Task GetProperties(string id, JToken fn_args = null) + { + if (ctx.UseCallFunctionOnBeforeGetProperties && !id.StartsWith("dotnet:scope:")) + { + var fn_decl = "function () { return this; }"; + var cfo_args = JObject.FromObject(new + { + functionDeclaration = fn_decl, + objectId = id + }); + if (fn_args != null) + cfo_args["arguments"] = fn_args; + + var result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + AssertEqual(true, result.IsOk, $"Runtime.getProperties failed for {cfo_args.ToString ()}, with Result: {result}"); + id = result.Value["result"] ? ["objectId"]?.Value(); + } + + var get_prop_req = JObject.FromObject(new + { + objectId = id + }); + + var frame_props = await ctx.cli.SendCommand("Runtime.getProperties", get_prop_req, ctx.token); + if (!frame_props.IsOk) + Assert.True(false, $"Runtime.getProperties failed for {get_prop_req.ToString ()}, with Result: {frame_props}"); + + var locals = frame_props.Value["result"]; + // FIXME: Should be done when generating the list in library_mono.js, but not sure yet + // whether to remove it, and how to do it correctly. + if (locals is JArray) + { + foreach (var p in locals) + { + if (p["name"]?.Value() == "length" && p["enumerable"]?.Value() != true) + { + p.Remove(); + break; + } + } + } + + return locals; + } + + internal async Task EvaluateOnCallFrame(string id, string expression) + { + var evaluate_req = JObject.FromObject(new + { + callFrameId = id, + expression = expression + }); + + var frame_evaluate = await ctx.cli.SendCommand("Debugger.evaluateOnCallFrame", evaluate_req, ctx.token); + if (!frame_evaluate.IsOk) + Assert.True(false, $"Debugger.evaluateOnCallFrame failed for {evaluate_req.ToString ()}, with Result: {frame_evaluate}"); + + var evaluate_result = frame_evaluate.Value["result"]; + return evaluate_result; + } + + internal async Task SetBreakpoint(string url_key, int line, int column, bool expect_ok = true, bool use_regex = false) + { + var bp1_req = !use_regex ? + JObject.FromObject(new { lineNumber = line, columnNumber = column, url = dicFileToUrl[url_key], }) : + JObject.FromObject(new { lineNumber = line, columnNumber = column, urlRegex = url_key, }); + + var bp1_res = await ctx.cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, ctx.token); + Assert.True(expect_ok ? bp1_res.IsOk : bp1_res.IsErr); + + return bp1_res; + } + + internal async Task SetBreakpointInMethod(string assembly, string type, string method, int lineOffset = 0, int col = 0) + { + var req = JObject.FromObject(new { assemblyName = assembly, typeName = type, methodName = method, lineOffset = lineOffset }); + + // Protocol extension + var res = await ctx.cli.SendCommand("DotnetDebugger.getMethodLocation", req, ctx.token); + Assert.True(res.IsOk); + + var m_url = res.Value["result"]["url"].Value(); + var m_line = res.Value["result"]["line"].Value(); + + var bp1_req = JObject.FromObject(new + { + lineNumber = m_line + lineOffset, + columnNumber = col, + url = m_url + }); + + res = await ctx.cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, ctx.token); + Assert.True(res.IsOk); + + return res; + } + + internal void AssertEqual(object expected, object actual, string label) => Assert.True(expected?.Equals(actual), + $"[{label}]\n" + + $"Expected: {expected?.ToString()}\n" + + $"Actual: {actual?.ToString()}\n"); + + internal void AssertStartsWith(string expected, string actual, string label) => Assert.True(actual?.StartsWith(expected), $"[{label}] Does not start with the expected string\nExpected: {expected}\nActual: {actual}"); + + internal static Func TSimpleClass = (X, Y, Id, Color) => new + { + X = TNumber(X), + Y = TNumber(Y), + Id = TString(Id), + Color = TEnum("DebuggerTests.RGB", Color), + PointWithCustomGetter = TGetter("PointWithCustomGetter") + }; + + internal static Func TPoint = (X, Y, Id, Color) => new + { + X = TNumber(X), + Y = TNumber(Y), + Id = TString(Id), + Color = TEnum("DebuggerTests.RGB", Color), + }; + + //FIXME: um maybe we don't need to convert jobject right here! + internal static JObject TString(string value) => + value == null ? + TObject("string", is_null : true) : + JObject.FromObject(new { type = "string", value = @value, description = @value }); + + internal static JObject TNumber(int value) => + JObject.FromObject(new { type = "number", value = @value.ToString(), description = value.ToString() }); + + internal static JObject TValueType(string className, string description = null, object members = null) => + JObject.FromObject(new { type = "object", isValueType = true, className = className, description = description ?? className }); + + internal static JObject TEnum(string className, string descr, object members = null) => + JObject.FromObject(new { type = "object", isEnum = true, className = className, description = descr }); + + internal static JObject TObject(string className, string description = null, bool is_null = false) => + is_null ? + JObject.FromObject(new { type = "object", className = className, description = description ?? className, subtype = is_null ? "null" : null }) : + JObject.FromObject(new { type = "object", className = className, description = description ?? className }); + + internal static JObject TArray(string className, int length = 0) => JObject.FromObject(new { type = "object", className = className, description = $"{className}({length})", subtype = "array" }); + + internal static JObject TBool(bool value) => JObject.FromObject(new { type = "boolean", value = @value, description = @value ? "true" : "false" }); + + internal static JObject TSymbol(string value) => JObject.FromObject(new { type = "symbol", value = @value, description = @value }); + + /* + For target names with generated method names like + `void b__11_0 (Math.GenericStruct)` + + .. pass target "as `target: "void |(Math.GenericStruct)"` + */ + internal static JObject TDelegate(string className, string target) => JObject.FromObject(new + { + __custom_type = "delegate", + className = className, + target = target + }); + + internal static JObject TPointer(string type_name, bool is_null = false) => JObject.FromObject(new { __custom_type = "pointer", type_name = type_name, is_null = is_null, is_void = type_name.StartsWith("void*") }); + + internal static JObject TIgnore() => JObject.FromObject(new { __custom_type = "ignore_me" }); + + internal static JObject TGetter(string type) => JObject.FromObject(new { __custom_type = "getter", type_name = type }); + } + + class DebugTestContext + { + public InspectorClient cli; + public Inspector insp; + public CancellationToken token; + public Dictionary scripts; + + public bool UseCallFunctionOnBeforeGetProperties; + + public DebugTestContext(InspectorClient cli, Inspector insp, CancellationToken token, Dictionary scripts) + { + this.cli = cli; + this.insp = insp; + this.token = token; + this.scripts = scripts; + } + } + + enum StepKind + { + Into, + Over, + Out + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs new file mode 100644 index 000000000000..03964dd207d0 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -0,0 +1,1483 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +[assembly : CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] + +namespace DebuggerTests +{ + + public class SourceList : DebuggerTestBase + { + + [Fact] + public async Task CheckThatAllSourcesAreSent() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + //all sources are sent before runtime ready is sent, nothing to check + await insp.Ready(); + Assert.Contains("dotnet://debugger-test.dll/debugger-test.cs", scripts.Values); + Assert.Contains("dotnet://debugger-test.dll/debugger-test2.cs", scripts.Values); + Assert.Contains("dotnet://debugger-test.dll/dependency.cs", scripts.Values); + } + + [Fact] + public async Task CreateGoodBreakpoint() + { + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp1_res = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); + + Assert.EndsWith("debugger-test.cs", bp1_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); + + var loc = bp1_res.Value["locations"]?.Value() [0]; + + Assert.NotNull(loc["scriptId"]); + Assert.Equal("dotnet://debugger-test.dll/debugger-test.cs", scripts[loc["scriptId"]?.Value()]); + Assert.Equal(10, loc["lineNumber"]); + Assert.Equal(8, loc["columnNumber"]); + }); + } + + [Fact] + public async Task CreateJSBreakpoint() + { + // Test that js breakpoints get set correctly + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + // 13 24 + // 13 31 + var bp1_res = await SetBreakpoint("/debugger-driver.html", 13, 24); + + Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); + + var loc = bp1_res.Value["locations"]?.Value() [0]; + + Assert.NotNull(loc["scriptId"]); + Assert.Equal(13, loc["lineNumber"]); + Assert.Equal(24, loc["columnNumber"]); + + var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 31); + + Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); + + var loc2 = bp2_res.Value["locations"]?.Value() [0]; + + Assert.NotNull(loc2["scriptId"]); + Assert.Equal(13, loc2["lineNumber"]); + Assert.Equal(31, loc2["columnNumber"]); + }); + } + + [Fact] + public async Task CreateJS0Breakpoint() + { + // Test that js column 0 does as expected + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + // 13 24 + // 13 31 + var bp1_res = await SetBreakpoint("/debugger-driver.html", 13, 0); + + Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); + + var loc = bp1_res.Value["locations"]?.Value() [0]; + + Assert.NotNull(loc["scriptId"]); + Assert.Equal(13, loc["lineNumber"]); + Assert.Equal(24, loc["columnNumber"]); + + var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 31); + + Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); + + var loc2 = bp2_res.Value["locations"]?.Value() [0]; + + Assert.NotNull(loc2["scriptId"]); + Assert.Equal(13, loc2["lineNumber"]); + Assert.Equal(31, loc2["columnNumber"]); + }); + } + + [Theory] + [InlineData(0)] + [InlineData(50)] + public async Task CheckMultipleBreakpointsOnSameLine(int col) + { + var insp = new Inspector(); + + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp1_res = await SetBreakpoint("dotnet://debugger-test.dll/debugger-array-test.cs", 219, col); + Assert.EndsWith("debugger-array-test.cs", bp1_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); + + var loc = bp1_res.Value["locations"]?.Value() [0]; + + CheckLocation("dotnet://debugger-test.dll/debugger-array-test.cs", 219, 50, scripts, loc); + + var bp2_res = await SetBreakpoint("dotnet://debugger-test.dll/debugger-array-test.cs", 219, 55); + Assert.EndsWith("debugger-array-test.cs", bp2_res.Value["breakpointId"].ToString()); + Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); + + var loc2 = bp2_res.Value["locations"]?.Value() [0]; + + CheckLocation("dotnet://debugger-test.dll/debugger-array-test.cs", 219, 55, scripts, loc2); + }); + } + + [Fact] + public async Task CreateBadBreakpoint() + { + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + var bp1_req = JObject.FromObject(new + { + lineNumber = 8, + columnNumber = 2, + url = "dotnet://debugger-test.dll/this-file-doesnt-exist.cs", + }); + + var bp1_res = await cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, token); + + Assert.True(bp1_res.IsOk); + Assert.Empty(bp1_res.Value["locations"].Values()); + //Assert.Equal ((int)MonoErrorCodes.BpNotFound, bp1_res.Error ["code"]?.Value ()); + }); + } + + [Fact] + public async Task CreateGoodBreakpointAndHit() + { + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); + + var eval_req = JObject.FromObject(new + { + expression = "window.setTimeout(function() { invoke_add(); }, 1);", + }); + + await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, + "IntAdd", + wait_for_event_fn: (pause_location) => + { + Assert.Equal("other", pause_location["reason"]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + Assert.Equal("IntAdd", top_frame["functionName"].Value()); + Assert.Contains("debugger-test.cs", top_frame["url"].Value()); + + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); + + //now check the scope + var scope = top_frame["scopeChain"][0]; + Assert.Equal("local", scope["type"]); + Assert.Equal("IntAdd", scope["name"]); + + Assert.Equal("object", scope["object"]["type"]); + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, scope["startLocation"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 14, 4, scripts, scope["endLocation"]); + return Task.CompletedTask; + } + ); + + }); + } + + [Fact] + public async Task ExceptionThrownInJS() + { + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + var eval_req = JObject.FromObject(new + { + expression = "invoke_bad_js_test();" + }); + + var eval_res = await cli.SendCommand("Runtime.evaluate", eval_req, token); + Assert.True(eval_res.IsErr); + Assert.Equal("Uncaught", eval_res.Error["exceptionDetails"] ? ["text"]?.Value()); + }); + } + + [Fact] + public async Task ExceptionThrownInJSOutOfBand() + { + var insp = new Inspector(); + + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetBreakpoint("/debugger-driver.html", 27, 2); + + var eval_req = JObject.FromObject(new + { + expression = "window.setTimeout(function() { invoke_bad_js_test(); }, 1);", + }); + + var eval_res = await cli.SendCommand("Runtime.evaluate", eval_req, token); + // Response here will be the id for the timer from JS! + Assert.True(eval_res.IsOk); + + var ex = await Assert.ThrowsAsync(async() => await insp.WaitFor("Runtime.exceptionThrown")); + var ex_json = JObject.Parse(ex.Message); + Assert.Equal(dicFileToUrl["/debugger-driver.html"], ex_json["exceptionDetails"] ? ["url"]?.Value()); + }); + + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsAtBreakpointSite(bool use_cfo) => + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd", + "window.setTimeout(function() { invoke_add(); }, 1);", + use_cfo : use_cfo, + test_fn: (locals) => + { + CheckNumber(locals, "a", 10); + CheckNumber(locals, "b", 20); + CheckNumber(locals, "c", 30); + CheckNumber(locals, "d", 0); + CheckNumber(locals, "e", 0); + } + ); + + [Fact] + public async Task InspectPrimitiveTypeLocalsAtBreakpointSite() => + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", 154, 8, "PrimitiveTypesTest", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:PrimitiveTypesTest'); }, 1);", + test_fn: (locals) => + { + CheckSymbol(locals, "c0", "8364 '€'"); + CheckSymbol(locals, "c1", "65 'A'"); + } + ); + + [Fact] + public async Task InspectLocalsTypesAtBreakpointSite() => + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test2.cs", 48, 8, "Types", + "window.setTimeout(function() { invoke_static_method (\"[debugger-test] Fancy:Types\")(); }, 1);", + use_cfo : false, + test_fn: (locals) => + { + CheckNumber(locals, "dPI", Math.PI); + CheckNumber(locals, "fPI", (float) Math.PI); + CheckNumber(locals, "iMax", int.MaxValue); + CheckNumber(locals, "iMin", int.MinValue); + CheckNumber(locals, "uiMax", uint.MaxValue); + CheckNumber(locals, "uiMin", uint.MinValue); + + CheckNumber(locals, "l", uint.MaxValue * (long) 2); + //CheckNumber (locals, "lMax", long.MaxValue); // cannot be represented as double + //CheckNumber (locals, "lMin", long.MinValue); // cannot be represented as double + + CheckNumber(locals, "sbMax", sbyte.MaxValue); + CheckNumber(locals, "sbMin", sbyte.MinValue); + CheckNumber(locals, "bMax", byte.MaxValue); + CheckNumber(locals, "bMin", byte.MinValue); + + CheckNumber(locals, "sMax", short.MaxValue); + CheckNumber(locals, "sMin", short.MinValue); + CheckNumber(locals, "usMin", ushort.MinValue); + CheckNumber(locals, "usMax", ushort.MaxValue); + } + ); + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsWithGenericTypesAtBreakpointSite(bool use_cfo) => + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", 74, 8, "GenericTypesTest", + "window.setTimeout(function() { invoke_generic_types_test (); }, 1);", + use_cfo : use_cfo, + test_fn: (locals) => + { + CheckObject(locals, "list", "System.Collections.Generic.Dictionary"); + CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null : true); + + CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]"); + CheckObject(locals, "list_arr_null", "System.Collections.Generic.Dictionary[]", is_null : true); + + // Unused locals + CheckObject(locals, "list_unused", "System.Collections.Generic.Dictionary"); + CheckObject(locals, "list_null_unused", "System.Collections.Generic.Dictionary", is_null : true); + + CheckObject(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]"); + CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null : true); + } + ); + + object TGenericStruct(string typearg, string stringField) => new + { + List = TObject($"System.Collections.Generic.List<{typearg}>"), + StringField = TString(stringField) + }; + + [Fact] + public async Task RuntimeGetPropertiesWithInvalidScopeIdTest() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 49, 8); + + await EvaluateAndCheck( + "window.setTimeout(function() { invoke_delegates_test (); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 49, 8, + "DelegatesTest", + wait_for_event_fn : async(pause_location) => + { + //make sure we're on the right bp + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + + var scope = top_frame["scopeChain"][0]; + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + + // Try to get an invalid scope! + var get_prop_req = JObject.FromObject(new + { + objectId = "dotnet:scope:23490871", + }); + + var frame_props = await cli.SendCommand("Runtime.getProperties", get_prop_req, token); + Assert.True(frame_props.IsErr); + } + ); + }); + } + + [Fact] + public async Task TrivalStepping() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); + + await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, + "IntAdd", + wait_for_event_fn: (pause_location) => + { + //make sure we're on the right bp + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); + return Task.CompletedTask; + } + ); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 11, 8, "IntAdd", + wait_for_event_fn: (pause_location) => + { + var top_frame = pause_location["callFrames"][0]; + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); + return Task.CompletedTask; + } + ); + }); + } + + [Fact] + public async Task InspectLocalsDuringStepping() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs"; + await SetBreakpoint(debugger_test_loc, 10, 8); + + await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + debugger_test_loc, 10, 8, "IntAdd", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 10); + CheckNumber(locals, "b", 20); + CheckNumber(locals, "c", 30); + CheckNumber(locals, "d", 0); + CheckNumber(locals, "e", 0); + } + ); + + await StepAndCheck(StepKind.Over, debugger_test_loc, 11, 8, "IntAdd", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 10); + CheckNumber(locals, "b", 20); + CheckNumber(locals, "c", 30); + CheckNumber(locals, "d", 50); + CheckNumber(locals, "e", 0); + } + ); + + //step and get locals + await StepAndCheck(StepKind.Over, debugger_test_loc, 12, 8, "IntAdd", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 10); + CheckNumber(locals, "b", 20); + CheckNumber(locals, "c", 30); + CheckNumber(locals, "d", 50); + CheckNumber(locals, "e", 60); + } + ); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + var dep_cs_loc = "dotnet://debugger-test.dll/dependency.cs"; + await SetBreakpoint(dep_cs_loc, 33, 8); + + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs"; + + // Will stop in Complex.DoEvenMoreStuff + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_use_complex (); }, 1);", + dep_cs_loc, 33, 8, "DoEvenMoreStuff", + locals_fn: (locals) => + { + Assert.Single(locals); + CheckObject(locals, "this", "Simple.Complex"); + } + ); + + var props = await GetObjectOnFrame(pause_location["callFrames"][0], "this"); + Assert.Equal(3, props.Count()); + CheckNumber(props, "A", 10); + CheckString(props, "B", "xx"); + CheckObject(props, "c", "object"); + + // Check UseComplex frame + var locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][3], debugger_test_loc, 23, 8, "UseComplex"); + Assert.Equal(7, locals_m1.Count()); + + CheckNumber(locals_m1, "a", 10); + CheckNumber(locals_m1, "b", 20); + CheckObject(locals_m1, "complex", "Simple.Complex"); + CheckNumber(locals_m1, "c", 30); + CheckNumber(locals_m1, "d", 50); + CheckNumber(locals_m1, "e", 60); + CheckNumber(locals_m1, "f", 0); + + props = await GetObjectOnFrame(pause_location["callFrames"][3], "complex"); + Assert.Equal(3, props.Count()); + CheckNumber(props, "A", 10); + CheckString(props, "B", "xx"); + CheckObject(props, "c", "object"); + + pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 23, 8, "DoStuff", times : 2); + // Check UseComplex frame again + locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][1], debugger_test_loc, 23, 8, "UseComplex"); + Assert.Equal(7, locals_m1.Count()); + + CheckNumber(locals_m1, "a", 10); + CheckNumber(locals_m1, "b", 20); + CheckObject(locals_m1, "complex", "Simple.Complex"); + CheckNumber(locals_m1, "c", 30); + CheckNumber(locals_m1, "d", 50); + CheckNumber(locals_m1, "e", 60); + CheckNumber(locals_m1, "f", 0); + + props = await GetObjectOnFrame(pause_location["callFrames"][1], "complex"); + Assert.Equal(3, props.Count()); + CheckNumber(props, "A", 10); + CheckString(props, "B", "xx"); + CheckObject(props, "c", "object"); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs"; + await SetBreakpoint(debugger_test_loc, 111, 12); + + // Will stop in InnerMethod + var wait_res = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_outer_method(); }, 1);", + debugger_test_loc, 111, 12, "InnerMethod", + locals_fn: (locals) => + { + Assert.Equal(4, locals.Count()); + CheckNumber(locals, "i", 5); + CheckNumber(locals, "j", 24); + CheckString(locals, "foo_str", "foo"); + CheckObject(locals, "this", "Math.NestedInMath"); + } + ); + + var this_props = await GetObjectOnFrame(wait_res["callFrames"][0], "this"); + Assert.Equal(2, this_props.Count()); + CheckObject(this_props, "m", "Math"); + CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct"); + + var ss_props = await GetObjectOnLocals(this_props, "SimpleStructProperty"); + Assert.Equal(2, ss_props.Count()); + CheckValueType(ss_props, "dt", "System.DateTime"); + CheckValueType(ss_props, "gs", "Math.GenericStruct"); + + await CheckDateTime(ss_props, "dt", new DateTime(2020, 1, 2, 3, 4, 5)); + + // Check OuterMethod frame + var locals_m1 = await GetLocalsForFrame(wait_res["callFrames"][1], debugger_test_loc, 87, 8, "OuterMethod"); + Assert.Equal(5, locals_m1.Count()); + // FIXME: Failing test CheckNumber (locals_m1, "i", 5); + // FIXME: Failing test CheckString (locals_m1, "text", "Hello"); + CheckNumber(locals_m1, "new_i", 0); + CheckNumber(locals_m1, "k", 0); + CheckObject(locals_m1, "nim", "Math.NestedInMath"); + + // step back into OuterMethod + await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times : 9, + locals_fn: (locals) => + { + Assert.Equal(5, locals.Count()); + + // FIXME: Failing test CheckNumber (locals_m1, "i", 5); + CheckString(locals, "text", "Hello"); + // FIXME: Failing test CheckNumber (locals, "new_i", 24); + CheckNumber(locals, "k", 19); + CheckObject(locals, "nim", "Math.NestedInMath"); + } + ); + + //await StepAndCheck (StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 81, 2, "OuterMethod", times: 2); + + // step into InnerMethod2 + await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 96, 4, "InnerMethod2", + locals_fn: (locals) => + { + Assert.Equal(3, locals.Count()); + + CheckString(locals, "s", "test string"); + //out var: CheckNumber (locals, "k", 0); + CheckNumber(locals, "i", 24); + } + ); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times : 4, + locals_fn: (locals) => + { + Assert.Equal(3, locals.Count()); + + CheckString(locals, "s", "test string"); + // FIXME: Failing test CheckNumber (locals, "k", 34); + CheckNumber(locals, "i", 24); + } + ); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times : 2, + locals_fn: (locals) => + { + Assert.Equal(5, locals.Count()); + + CheckString(locals, "text", "Hello"); + // FIXME: failing test CheckNumber (locals, "i", 5); + CheckNumber(locals, "new_i", 22); + CheckNumber(locals, "k", 34); + CheckObject(locals, "nim", "Math.NestedInMath"); + } + ); + }); + } + + [Fact] + public async Task InspectLocalsDuringSteppingIn() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 86, 8); + + await EvaluateAndCheck("window.setTimeout(function() { invoke_outer_method(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 86, 8, "OuterMethod", + locals_fn: (locals) => + { + Assert.Equal(5, locals.Count()); + + CheckObject(locals, "nim", "Math.NestedInMath"); + CheckNumber(locals, "i", 5); + CheckNumber(locals, "k", 0); + CheckNumber(locals, "new_i", 0); + CheckString(locals, "text", null); + } + ); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 87, 8, "OuterMethod", + locals_fn: (locals) => + { + Assert.Equal(5, locals.Count()); + + CheckObject(locals, "nim", "Math.NestedInMath"); + // FIXME: Failing test CheckNumber (locals, "i", 5); + CheckNumber(locals, "k", 0); + CheckNumber(locals, "new_i", 0); + CheckString(locals, "text", "Hello"); + } + ); + + // Step into InnerMethod + await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 105, 8, "InnerMethod"); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 109, 12, "InnerMethod", times : 5, + locals_fn: (locals) => + { + Assert.Equal(4, locals.Count()); + + CheckNumber(locals, "i", 5); + CheckNumber(locals, "j", 15); + CheckString(locals, "foo_str", "foo"); + CheckObject(locals, "this", "Math.NestedInMath"); + } + ); + + // Step back to OuterMethod + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 88, 8, "OuterMethod", times : 6, + locals_fn: (locals) => + { + Assert.Equal(5, locals.Count()); + + CheckObject(locals, "nim", "Math.NestedInMath"); + // FIXME: Failing test CheckNumber (locals, "i", 5); + CheckNumber(locals, "k", 0); + CheckNumber(locals, "new_i", 24); + CheckString(locals, "text", "Hello"); + } + ); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsInAsyncMethods(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs"; + + await SetBreakpoint(debugger_test_loc, 120, 12); + await SetBreakpoint(debugger_test_loc, 135, 12); + + // Will stop in Asyncmethod0 + var wait_res = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_async_method_with_await(); }, 1);", + debugger_test_loc, 120, 12, "MoveNext", //FIXME: + locals_fn: (locals) => + { + Assert.Equal(4, locals.Count()); + CheckString(locals, "s", "string from js"); + CheckNumber(locals, "i", 42); + CheckString(locals, "local0", "value0"); + CheckObject(locals, "this", "Math.NestedInMath"); + } + ); + Console.WriteLine(wait_res); + +#if false // Disabled for now, as we don't have proper async traces + var locals = await GetProperties(wait_res["callFrames"][2]["callFrameId"].Value()); + Assert.Equal(4, locals.Count()); + CheckString(locals, "ls", "string from jstest"); + CheckNumber(locals, "li", 52); +#endif + + // TODO: previous frames have async machinery details, so no point checking that right now + + var pause_loc = await SendCommandAndCheck(null, "Debugger.resume", debugger_test_loc, 135, 12, /*FIXME: "AsyncMethodNoReturn"*/ "MoveNext", + locals_fn: (locals) => + { + Assert.Equal(4, locals.Count()); + CheckString(locals, "str", "AsyncMethodNoReturn's local"); + CheckObject(locals, "this", "Math.NestedInMath"); + //FIXME: check fields + CheckValueType(locals, "ss", "Math.SimpleStruct"); + CheckArray(locals, "ss_arr", "Math.SimpleStruct[]"); + // TODO: struct fields + } + ); + + var this_props = await GetObjectOnFrame(pause_loc["callFrames"][0], "this"); + Assert.Equal(2, this_props.Count()); + CheckObject(this_props, "m", "Math"); + CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct"); + + // TODO: Check `this` properties + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsWithStructs(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + await SetBreakpoint(debugger_test_loc, 22, 8); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_method_with_structs(); }, 1);", + debugger_test_loc, 22, 8, "MethodWithLocalStructs", + locals_fn: (locals) => + { + Assert.Equal(3, locals.Count()); + + CheckValueType(locals, "ss_local", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckValueType(locals, "gs_local", "DebuggerTests.ValueTypesTest.GenericStruct"); + CheckObject(locals, "vt_local", "DebuggerTests.ValueTypesTest"); + } + ); + + var dt = new DateTime(2021, 2, 3, 4, 6, 7); + // Check ss_local's properties + var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); + await CheckProps(ss_local_props, new + { + str_member = TString("set in MethodWithLocalStructs#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") + }, "ss_local"); + + { + // Check ss_local.dt + await CheckDateTime(ss_local_props, "dt", dt); + + // Check ss_local.gs + var gs_props = await GetObjectOnLocals(ss_local_props, "gs"); + CheckString(gs_props, "StringField", "set in MethodWithLocalStructs#SimpleStruct#gs#StringField"); + CheckObject(gs_props, "List", "System.Collections.Generic.List"); + } + + // Check gs_local's properties + var gs_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "gs_local"); + await CheckProps(gs_local_props, new + { + StringField = TString("gs_local#GenericStruct#StringField"), + List = TObject("System.Collections.Generic.List", is_null : true), + Options = TEnum("DebuggerTests.Options", "None") + }, "gs_local"); + + // Check vt_local's properties + var vt_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "vt_local"); + Assert.Equal(5, vt_local_props.Count()); + + CheckString(vt_local_props, "StringField", "string#0"); + CheckValueType(vt_local_props, "SimpleStructField", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckValueType(vt_local_props, "SimpleStructProperty", "DebuggerTests.ValueTypesTest.SimpleStruct"); + await CheckDateTime(vt_local_props, "DT", new DateTime(2020, 1, 2, 3, 4, 5)); + CheckEnum(vt_local_props, "RGB", "DebuggerTests.RGB", "Blue"); + + { + // SimpleStructProperty + dt = new DateTime(2022, 3, 4, 5, 7, 8); + var ssp_props = await CompareObjectPropertiesFor(vt_local_props, "SimpleStructProperty", + new + { + str_member = TString("SimpleStructProperty#string#0#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") + }, + label: "vt_local_props.SimpleStructProperty"); + + await CheckDateTime(ssp_props, "dt", dt); + + // SimpleStructField + dt = new DateTime(2025, 6, 7, 8, 10, 11); + var ssf_props = await CompareObjectPropertiesFor(vt_local_props, "SimpleStructField", + new + { + str_member = TString("SimpleStructField#string#0#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Local") + }, + label: "vt_local_props.SimpleStructField"); + + await CheckDateTime(ssf_props, "dt", dt); + } + + // FIXME: check ss_local.gs.List's members + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectValueTypeMethodArgs(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + await SetBreakpoint(debugger_test_loc, 34, 12); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:TestStructsAsMethodArgs'); }, 1);", + debugger_test_loc, 34, 12, "MethodWithStructArgs", + locals_fn: (locals) => + { + Assert.Equal(3, locals.Count()); + + CheckString(locals, "label", "TestStructsAsMethodArgs#label"); + CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckNumber(locals, "x", 3); + } + ); + + var dt = new DateTime(2025, 6, 7, 8, 10, 11); + var ss_local_as_ss_arg = new + { + str_member = TString("ss_local#SimpleStruct#string#0#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Local") + }; + var ss_local_gs = new + { + StringField = TString("ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField"), + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option1") + }; + + // Check ss_arg's properties + var ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg"); + await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_arg"); + + { + // Check ss_local.dt + await CheckDateTime(ss_arg_props, "dt", dt); + + // Check ss_local.gs + await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs); + } + + pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 38, 8, "MethodWithStructArgs", times : 4, + locals_fn: (locals) => + { + Assert.Equal(3, locals.Count()); + + CheckString(locals, "label", "TestStructsAsMethodArgs#label"); + CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckNumber(locals, "x", 3); + + } + ); + + var ss_arg_updated = new + { + str_member = TString("ValueTypesTest#MethodWithStructArgs#updated#ss_arg#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") + }; + + ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg"); + await CheckProps(ss_arg_props, ss_arg_updated, "ss_ar"); + + { + // Check ss_local.gs + await CompareObjectPropertiesFor(ss_arg_props, "gs", new + { + StringField = TString("ValueTypesTest#MethodWithStructArgs#updated#gs#StringField#3"), + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option1") + }); + + await CheckDateTime(ss_arg_props, "dt", dt); + } + + // Check locals on previous frame, same as earlier in this test + ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][1], "ss_local"); + await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local"); + + { + // Check ss_local.dt + await CheckDateTime(ss_arg_props, "dt", dt); + + // Check ss_local.gs + var gs_props = await GetObjectOnLocals(ss_arg_props, "gs"); + CheckString(gs_props, "StringField", "ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField"); + CheckObject(gs_props, "List", "System.Collections.Generic.List"); + } + + // ----------- Step back to the caller --------- + + pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 28, 12, "TestStructsAsMethodArgs", + times : 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(locals, new + { + ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"), + ss_ret = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct") + }, + "locals#0"); + + ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); + await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local"); + + { + // Check ss_local.gs + await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs, label: "ss_local_gs"); + } + + // FIXME: check ss_local.gs.List's members + }); + } + + [Fact] + public async Task CheckUpdatedValueTypeFieldsOnResume() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + var lines = new [] { 202, 205 }; + await SetBreakpoint(debugger_test_loc, lines[0], 12); + await SetBreakpoint(debugger_test_loc, lines[1], 12); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeMembers'); }, 1);", + debugger_test_loc, lines[0], 12, "MethodUpdatingValueTypeMembers"); + + var dt = new DateTime(1, 2, 3, 4, 5, 6); + await CheckLocals(pause_location, dt); + + // Resume + dt = new DateTime(9, 8, 7, 6, 5, 4); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingValueTypeMembers"); + await CheckLocals(pause_location, dt); + }); + + async Task CheckLocals(JToken pause_location, DateTime dt) + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(locals, new + { + obj = TObject("DebuggerTests.ClassForToStringTests"), + vt = TObject("DebuggerTests.StructForToStringTests") + }, "locals"); + + var obj_props = await GetObjectOnLocals(locals, "obj"); + { + await CheckProps(obj_props, new + { + DT = TValueType("System.DateTime", dt.ToString()) + }, "locals#obj.DT", num_fields : 5); + + await CheckDateTime(obj_props, "DT", dt); + } + + var vt_props = await GetObjectOnLocals(locals, "obj"); + { + await CheckProps(vt_props, new + { + DT = TValueType("System.DateTime", dt.ToString()) + }, "locals#obj.DT", num_fields : 5); + + await CheckDateTime(vt_props, "DT", dt); + } + } + } + + [Fact] + public async Task CheckUpdatedValueTypeLocalsOnResumeAsync() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + var lines = new [] { 211, 213 }; + await SetBreakpoint(debugger_test_loc, lines[0], 12); + await SetBreakpoint(debugger_test_loc, lines[1], 12); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeLocalsAsync'); }, 1);", + debugger_test_loc, lines[0], 12, "MoveNext"); + + var dt = new DateTime(1, 2, 3, 4, 5, 6); + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckDateTime(locals, "dt", dt); + + // Resume + dt = new DateTime(9, 8, 7, 6, 5, 4); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MoveNext"); + locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckDateTime(locals, "dt", dt); + }); + } + + [Fact] + public async Task CheckUpdatedVTArrayMembersOnResume() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + var lines = new [] { 222, 224 }; + await SetBreakpoint(debugger_test_loc, lines[0], 12); + await SetBreakpoint(debugger_test_loc, lines[1], 12); + + var dt = new DateTime(1, 2, 3, 4, 5, 6); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingVTArrayMembers'); }, 1);", + debugger_test_loc, lines[0], 12, "MethodUpdatingVTArrayMembers"); + await CheckArrayElements(pause_location, dt); + + // Resume + dt = new DateTime(9, 8, 7, 6, 5, 4); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingVTArrayMembers"); + await CheckArrayElements(pause_location, dt); + }); + + async Task CheckArrayElements(JToken pause_location, DateTime dt) + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(locals, new + { + ssta = TArray("DebuggerTests.StructForToStringTests[]", 1) + }, "locals"); + + var ssta = await GetObjectOnLocals(locals, "ssta"); + var sst0 = await GetObjectOnLocals(ssta, "0"); + await CheckProps(sst0, new + { + DT = TValueType("System.DateTime", dt.ToString()) + }, "dta [0]", num_fields : 5); + + await CheckDateTime(sst0, "DT", dt); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsWithStructsStaticAsync(bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + await SetBreakpoint(debugger_test_loc, 54, 12); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method_async (" + + "'[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalStructsStaticAsync'" + + "); }, 1);", + debugger_test_loc, 54, 12, "MoveNext"); //BUG: method name + + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(locals, new + { + ss_local = TObject("DebuggerTests.ValueTypesTest.SimpleStruct"), + gs_local = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + result = TBool(true) + }, + "locals#0"); + + var dt = new DateTime(2021, 2, 3, 4, 6, 7); + // Check ss_local's properties + var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); + await CheckProps(ss_local_props, new + { + str_member = TString("set in MethodWithLocalStructsStaticAsync#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") + }, "ss_local"); + + { + // Check ss_local.dt + await CheckDateTime(ss_local_props, "dt", dt); + + // Check ss_local.gs + await CompareObjectPropertiesFor(ss_local_props, "gs", + new + { + StringField = TString("set in MethodWithLocalStructsStaticAsync#SimpleStruct#gs#StringField"), + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option1") + } + ); + } + + // Check gs_local's properties + var gs_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "gs_local"); + await CheckProps(gs_local_props, new + { + StringField = TString("gs_local#GenericStruct#StringField"), + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option2") + }, "gs_local"); + + // FIXME: check ss_local.gs.List's members + }); + } + + [Theory] + [InlineData(134, 12, "MethodWithLocalsForToStringTest", false, false)] + [InlineData(144, 12, "MethodWithArgumentsForToStringTest", true, false)] + [InlineData(189, 12, "MethodWithArgumentsForToStringTestAsync", true, true)] + [InlineData(179, 12, "MethodWithArgumentsForToStringTestAsync", false, true)] + public async Task InspectLocalsForToStringDescriptions(int line, int col, string method_name, bool call_other, bool invoke_async) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + string entry_method_name = $"[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalsForToStringTest{(invoke_async ? "Async" : String.Empty)}"; + int frame_idx = 0; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; + + await SetBreakpoint(debugger_test_loc, line, col); + + var eval_expr = "window.setTimeout(function() {" + + (invoke_async ? "invoke_static_method_async (" : "invoke_static_method (") + + $"'{entry_method_name}'," + + (call_other ? "true" : "false") + + "); }, 1);"; + Console.WriteLine($"{eval_expr}"); + + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, line, col, invoke_async ? "MoveNext" : method_name); + + var dt0 = new DateTime(2020, 1, 2, 3, 4, 5); + var dt1 = new DateTime(2010, 5, 4, 3, 2, 1); + var ts = dt0 - dt1; + var dto = new DateTimeOffset(dt0, new TimeSpan(4, 5, 0)); + + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + await CheckProps(frame_locals, new + { + call_other = TBool(call_other), + dt0 = TValueType("System.DateTime", dt0.ToString()), + dt1 = TValueType("System.DateTime", dt1.ToString()), + dto = TValueType("System.DateTimeOffset", dto.ToString()), + ts = TValueType("System.TimeSpan", ts.ToString()), + dec = TValueType("System.Decimal", "123987123"), + guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014"), + dts = TArray("System.DateTime[]", 2), + obj = TObject("DebuggerTests.ClassForToStringTests"), + sst = TObject("DebuggerTests.StructForToStringTests") + }, "locals#0"); + + var dts_0 = new DateTime(1983, 6, 7, 5, 6, 10); + var dts_1 = new DateTime(1999, 10, 15, 1, 2, 3); + var dts_elements = await GetObjectOnLocals(frame_locals, "dts"); + await CheckDateTime(dts_elements, "0", dts_0); + await CheckDateTime(dts_elements, "1", dts_1); + + // TimeSpan + await CompareObjectPropertiesFor(frame_locals, "ts", + new + { + Days = TNumber(3530), + Minutes = TNumber(2), + Seconds = TNumber(4), + }, "ts_props", num_fields : 12); + + // DateTimeOffset + await CompareObjectPropertiesFor(frame_locals, "dto", + new + { + Day = TNumber(2), + Year = TNumber(2020), + DayOfWeek = TEnum("System.DayOfWeek", "Thursday") + }, "dto_props", num_fields : 22); + + var DT = new DateTime(2004, 10, 15, 1, 2, 3); + var DTO = new DateTimeOffset(dt0, new TimeSpan(2, 14, 0)); + + var obj_props = await CompareObjectPropertiesFor(frame_locals, "obj", + new + { + DT = TValueType("System.DateTime", DT.ToString()), + DTO = TValueType("System.DateTimeOffset", DTO.ToString()), + TS = TValueType("System.TimeSpan", ts.ToString()), + Dec = TValueType("System.Decimal", "1239871"), + Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") + }, "obj_props"); + + DTO = new DateTimeOffset(dt0, new TimeSpan(3, 15, 0)); + var sst_props = await CompareObjectPropertiesFor(frame_locals, "sst", + new + { + DT = TValueType("System.DateTime", DT.ToString()), + DTO = TValueType("System.DateTimeOffset", DTO.ToString()), + TS = TValueType("System.TimeSpan", ts.ToString()), + Dec = TValueType("System.Decimal", "1239871"), + Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") + }, "sst_props"); + }); + } + + [Fact] + public async Task InspectLocals() + { + var insp = new Inspector(); + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var wait_res = await RunUntil("locals_inner"); + var locals = await GetProperties(wait_res["callFrames"][1]["callFrameId"].Value()); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectLocalsForStructInstanceMethod(bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-array-test.cs", 258, 12, + "GenericInstanceMethod", + "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EntryClass:run'); })", + use_cfo : use_cfo, + wait_for_event_fn : async(pause_location) => + { + var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + await CheckProps(frame_locals, new + { + sc_arg = TObject("DebuggerTests.SimpleClass"), + @this = TValueType("DebuggerTests.Point"), + local_gs = TValueType("DebuggerTests.SimpleGenericStruct") + }, + "locals#0"); + + await CompareObjectPropertiesFor(frame_locals, "local_gs", + new + { + Id = TString("local_gs#Id"), + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) + }, + label: "local_gs#0"); + + await CompareObjectPropertiesFor(frame_locals, "sc_arg", + TSimpleClass(10, 45, "sc_arg#Id", "Blue"), + label: "sc_arg#0"); + + await CompareObjectPropertiesFor(frame_locals, "this", + TPoint(90, -4, "point#Id", "Green"), + label: "this#0"); + + }); + + [Fact] + public async Task SteppingIntoMscorlib() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 83, 8); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:OuterMethod'); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 83, 8, + "OuterMethod"); + + //make sure we're on the right bp + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + + pause_location = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null); + var top_frame = pause_location["callFrames"][0]; + + AssertEqual("WriteLine", top_frame["functionName"]?.Value(), "Expected to be in WriteLine method"); + var script_id = top_frame["functionLocation"]["scriptId"].Value(); + AssertEqual("dotnet://System.Console.dll/Console.cs", scripts[script_id], "Expected to stopped in System.Console.WriteLine"); + }); + } + + //TODO add tests covering basic stepping behavior as step in/out/over + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/appsettings.json b/src/mono/wasm/debugger/DebuggerTestSuite/appsettings.json new file mode 100644 index 000000000000..0cda8d48a36c --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Error", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/mono/wasm/debugger/tests/debugger-array-test.cs b/src/mono/wasm/debugger/tests/debugger-array-test.cs new file mode 100644 index 000000000000..95e2fb1504e9 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-array-test.cs @@ -0,0 +1,308 @@ +// 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.Threading.Tasks; +namespace DebuggerTests +{ + public class ArrayTestsClass + { + public static void PrimitiveTypeLocals(bool call_other = false) + { + var int_arr = new int[] { 4, 70, 1 }; + var int_arr_empty = new int[0]; + int[] int_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"int_arr: {int_arr.Length}, {int_arr_empty.Length}, {int_arr_null?.Length}"); + } + + public static void ValueTypeLocals(bool call_other = false) + { + var point_arr = new Point[] + { + new Point { X = 5, Y = -2, Id = "point_arr#Id#0", Color = RGB.Green }, + new Point { X = 123, Y = 0, Id = "point_arr#Id#1", Color = RGB.Blue }, + }; + + var point_arr_empty = new Point[0]; + Point[] point_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"point_arr: {point_arr.Length}, {point_arr_empty.Length}, {point_arr_null?.Length}"); + } + + public static void ObjectTypeLocals(bool call_other = false) + { + var class_arr = new SimpleClass[] + { + new SimpleClass { X = 5, Y = -2, Id = "class_arr#Id#0", Color = RGB.Green }, + null, + new SimpleClass { X = 123, Y = 0, Id = "class_arr#Id#2", Color = RGB.Blue }, + }; + + var class_arr_empty = new SimpleClass[0]; + SimpleClass[] class_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"class_arr: {class_arr.Length}, {class_arr_empty.Length}, {class_arr_null?.Length}"); + } + + public static void GenericTypeLocals(bool call_other = false) + { + var gclass_arr = new GenericClass[] + { + null, + new GenericClass { Id = "gclass_arr#1#Id", Color = RGB.Red, Value = 5 }, + new GenericClass { Id = "gclass_arr#2#Id", Color = RGB.Blue, Value = -12 }, + }; + + var gclass_arr_empty = new GenericClass[0]; + GenericClass[] gclass_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"gclass_arr: {gclass_arr.Length}, {gclass_arr_empty.Length}, {gclass_arr_null?.Length}"); + } + + public static void GenericValueTypeLocals(bool call_other = false) + { + var gvclass_arr = new SimpleGenericStruct[] + { + new SimpleGenericStruct { Id = "gvclass_arr#1#Id", Color = RGB.Red, Value = new Point { X = 100, Y = 200, Id = "gvclass_arr#1#Value#Id", Color = RGB.Red } }, + new SimpleGenericStruct { Id = "gvclass_arr#2#Id", Color = RGB.Blue, Value = new Point { X = 10, Y = 20, Id = "gvclass_arr#2#Value#Id", Color = RGB.Green } } + }; + + var gvclass_arr_empty = new SimpleGenericStruct[0]; + SimpleGenericStruct[] gvclass_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"gvclass_arr: {gvclass_arr.Length}, {gvclass_arr_empty.Length}, {gvclass_arr_null?.Length}"); + } + + static void OtherMethod() + { + YetAnotherMethod(); + Console.WriteLine($"Just a placeholder for breakpoints"); + } + + static void YetAnotherMethod() + { + Console.WriteLine($"Just a placeholder for breakpoints"); + } + + public static void ObjectArrayMembers() + { + var c = new Container + { + id = "c#id", + ClassArrayProperty = new SimpleClass[] + { + new SimpleClass { X = 5, Y = -2, Id = "ClassArrayProperty#Id#0", Color = RGB.Green }, + new SimpleClass { X = 30, Y = 1293, Id = "ClassArrayProperty#Id#1", Color = RGB.Green }, + null + }, + ClassArrayField = new SimpleClass[] + { + null, + new SimpleClass { X = 5, Y = -2, Id = "ClassArrayField#Id#1", Color = RGB.Blue }, + new SimpleClass { X = 30, Y = 1293, Id = "ClassArrayField#Id#2", Color = RGB.Green }, + }, + PointsProperty = new Point[] + { + new Point { X = 5, Y = -2, Id = "PointsProperty#Id#0", Color = RGB.Green }, + new Point { X = 123, Y = 0, Id = "PointsProperty#Id#1", Color = RGB.Blue }, + }, + PointsField = new Point[] + { + new Point { X = 5, Y = -2, Id = "PointsField#Id#0", Color = RGB.Green }, + new Point { X = 123, Y = 0, Id = "PointsField#Id#1", Color = RGB.Blue }, + } + }; + + Console.WriteLine($"Back from PlaceholderMethod, {c.ClassArrayProperty?.Length}"); + c.PlaceholderMethod(); + Console.WriteLine($"Back from PlaceholderMethod, {c.id}"); + } + + public static async Task ValueTypeLocalsAsync(bool call_other = false) + { + var gvclass_arr = new SimpleGenericStruct[] + { + new SimpleGenericStruct { Id = "gvclass_arr#1#Id", Color = RGB.Red, Value = new Point { X = 100, Y = 200, Id = "gvclass_arr#1#Value#Id", Color = RGB.Red } }, + new SimpleGenericStruct { Id = "gvclass_arr#2#Id", Color = RGB.Blue, Value = new Point { X = 10, Y = 20, Id = "gvclass_arr#2#Value#Id", Color = RGB.Green } } + }; + + var gvclass_arr_empty = new SimpleGenericStruct[0]; + SimpleGenericStruct[] gvclass_arr_null = null; + Console.WriteLine($"ValueTypeLocalsAsync: call_other: {call_other}"); + SimpleGenericStruct gvclass; + Point[] points = null; + + if (call_other) + { + (gvclass, points) = await new ArrayTestsClass().InstanceMethodValueTypeLocalsAsync>(gvclass_arr[0]); + Console.WriteLine($"* gvclass: {gvclass}, points: {points.Length}"); + } + + Console.WriteLine($"gvclass_arr: {gvclass_arr.Length}, {gvclass_arr_empty.Length}, {gvclass_arr_null?.Length}"); + return true; + } + + public async Task < (T, Point[]) > InstanceMethodValueTypeLocalsAsync(T t1) + { + var point_arr = new Point[] + { + new Point { X = 5, Y = -2, Id = "point_arr#Id#0", Color = RGB.Red }, + new Point { X = 123, Y = 0, Id = "point_arr#Id#1", Color = RGB.Blue } + }; + var point = new Point { X = 45, Y = 51, Id = "point#Id", Color = RGB.Green }; + + Console.WriteLine($"point_arr: {point_arr.Length}, T: {t1}, point: {point}"); + return (t1, new Point[] { point_arr[0], point_arr[1], point }); + } + + // A workaround for method invocations on structs not working right now + public static async Task EntryPointForStructMethod(bool call_other = false) + { + await Point.AsyncMethod(call_other); + } + + public static void GenericValueTypeLocals2(bool call_other = false) + { + var gvclass_arr = new SimpleGenericStruct[] + { + new SimpleGenericStruct + { + Id = "gvclass_arr#0#Id", + Color = RGB.Red, + Value = new Point[] + { + new Point { X = 100, Y = 200, Id = "gvclass_arr#0#0#Value#Id", Color = RGB.Red }, + new Point { X = 100, Y = 200, Id = "gvclass_arr#0#1#Value#Id", Color = RGB.Green } + } + }, + + new SimpleGenericStruct + { + Id = "gvclass_arr#1#Id", + Color = RGB.Blue, + Value = new Point[] + { + new Point { X = 100, Y = 200, Id = "gvclass_arr#1#0#Value#Id", Color = RGB.Green }, + new Point { X = 100, Y = 200, Id = "gvclass_arr#1#1#Value#Id", Color = RGB.Blue } + } + }, + }; + + var gvclass_arr_empty = new SimpleGenericStruct[0]; + SimpleGenericStruct[] gvclass_arr_null = null; + + if (call_other) + OtherMethod(); + + Console.WriteLine($"gvclass_arr: {gvclass_arr.Length}, {gvclass_arr_empty.Length}, {gvclass_arr_null?.Length}"); + } + } + + public class Container + { + public string id; + public SimpleClass[] ClassArrayProperty { get; set; } + public SimpleClass[] ClassArrayField; + + public Point[] PointsProperty { get; set; } + public Point[] PointsField; + + public void PlaceholderMethod() + { + Console.WriteLine($"Container.PlaceholderMethod"); + } + } + + public struct Point + { + public int X, Y; + public string Id { get; set; } + public RGB Color { get; set; } + + /* instance too */ + public static async Task AsyncMethod(bool call_other) + { + int local_i = 5; + var sc = new SimpleClass { X = 10, Y = 45, Id = "sc#Id", Color = RGB.Blue }; + if (call_other) + await new Point { X = 90, Y = -4, Id = "point#Id", Color = RGB.Green }.AsyncInstanceMethod(sc); + Console.WriteLine($"AsyncMethod local_i: {local_i}, sc: {sc.Id}"); + } + + public async Task AsyncInstanceMethod(SimpleClass sc_arg) + { + var local_gs = new SimpleGenericStruct { Id = "local_gs#Id", Color = RGB.Green, Value = 4 }; + sc_arg.Id = "sc_arg#Id"; + Console.WriteLine($"AsyncInstanceMethod sc_arg: {sc_arg.Id}, local_gs: {local_gs.Id}"); + } + + public void GenericInstanceMethod(T sc_arg) where T : SimpleClass + { + var local_gs = new SimpleGenericStruct { Id = "local_gs#Id", Color = RGB.Green, Value = 4 }; + sc_arg.Id = "sc_arg#Id"; + Console.WriteLine($"AsyncInstanceMethod sc_arg: {sc_arg.Id}, local_gs: {local_gs.Id}"); + } + } + + public class SimpleClass + { + public int X, Y; + public string Id { get; set; } + public RGB Color { get; set; } + + public Point PointWithCustomGetter { get { return new Point { X = 100, Y = 400, Id = "SimpleClass#Point#gen#Id", Color = RGB.Green }; } } + } + + public class GenericClass + { + public string Id { get; set; } + public RGB Color { get; set; } + public T Value { get; set; } + } + + public struct SimpleGenericStruct + { + public string Id { get; set; } + public RGB Color { get; set; } + public T Value { get; set; } + } + + public class EntryClass + { + public static void run() + { + ArrayTestsClass.PrimitiveTypeLocals(true); + ArrayTestsClass.ValueTypeLocals(true); + ArrayTestsClass.ObjectTypeLocals(true); + + ArrayTestsClass.GenericTypeLocals(true); + ArrayTestsClass.GenericValueTypeLocals(true); + ArrayTestsClass.GenericValueTypeLocals2(true); + + ArrayTestsClass.ObjectArrayMembers(); + + ArrayTestsClass.ValueTypeLocalsAsync(true).Wait(); + + ArrayTestsClass.EntryPointForStructMethod(true).Wait(); + + var sc = new SimpleClass { X = 10, Y = 45, Id = "sc#Id", Color = RGB.Blue }; + new Point { X = 90, Y = -4, Id = "point#Id", Color = RGB.Green }.GenericInstanceMethod(sc); + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-cfo-test.cs b/src/mono/wasm/debugger/tests/debugger-cfo-test.cs new file mode 100644 index 000000000000..ad3b12cf6c8f --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-cfo-test.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace DebuggerTests +{ + public class CallFunctionOnTest + { + public static void LocalsTest(int len) + { + var big = new int[len]; + for (int i = 0; i < len; i++) + big[i] = i + 1000; + + var simple_struct = new Math.SimpleStruct() { dt = new DateTime(2020, 1, 2, 3, 4, 5), gs = new Math.GenericStruct { StringField = $"simple_struct # gs # StringField" } }; + + var ss_arr = new Math.SimpleStruct[len]; + for (int i = 0; i < len; i++) + ss_arr[i] = new Math.SimpleStruct() { dt = new DateTime(2020 + i, 1, 2, 3, 4, 5), gs = new Math.GenericStruct { StringField = $"ss_arr # {i} # gs # StringField" } }; + + var nim = new Math.NestedInMath { SimpleStructProperty = new Math.SimpleStruct() { dt = new DateTime(2010, 6, 7, 8, 9, 10) } }; + Action> action = Math.DelegateTargetWithVoidReturn; + Console.WriteLine("foo"); + } + + public static void PropertyGettersTest() + { + var ptd = new ClassWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9) }; + var swp = new StructWithProperties(); + System.Console.WriteLine("break here"); + } + + public static async System.Threading.Tasks.Task PropertyGettersTestAsync() + { + var ptd = new ClassWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9) }; + var swp = new StructWithProperties(); + System.Console.WriteLine("break here"); + await System.Threading.Tasks.Task.CompletedTask; + } + } + + class ClassWithProperties + { + public int Int { get { return 5; } } + public string String { get { return "foobar"; } } + public DateTime DT { get { return new DateTime(3, 4, 5, 6, 7, 8); } } + + public int[] IntArray { get { return new int[] { 10, 20 }; } } + public DateTime[] DTArray { get { return new DateTime[] { new DateTime(6, 7, 8, 9, 10, 11), new DateTime(1, 2, 3, 4, 5, 6) }; } } + public DateTime DTAutoProperty { get; set; } + public string StringField; + } + + struct StructWithProperties + { + public int Int { get { return 5; } } + public string String { get { return "foobar"; } } + public DateTime DT { get { return new DateTime(3, 4, 5, 6, 7, 8); } } + + public int[] IntArray { get { return new int[] { 10, 20 }; } } + public DateTime[] DTArray { get { return new DateTime[] { new DateTime(6, 7, 8, 9, 10, 11), new DateTime(1, 2, 3, 4, 5, 6) }; } } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-datetime-test.cs b/src/mono/wasm/debugger/tests/debugger-datetime-test.cs new file mode 100644 index 000000000000..8ea265079e1f --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-datetime-test.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Globalization; +namespace DebuggerTests +{ + public class DateTimeTest + { + public static string LocaleTest(string locale) + { + CultureInfo.CurrentCulture = new CultureInfo(locale, false); + Console.WriteLine("CurrentCulture is {0}", CultureInfo.CurrentCulture.Name); + + DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(locale).DateTimeFormat; + var fdtp = dtfi.FullDateTimePattern; + var ldp = dtfi.LongDatePattern; + var ltp = dtfi.LongTimePattern; + var sdp = dtfi.ShortDatePattern; + var stp = dtfi.ShortTimePattern; + + DateTime dt = new DateTime(2020, 1, 2, 3, 4, 5); + string dt_str = dt.ToString(); + Console.WriteLine("Current time is {0}", dt_str); + + return dt_str; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-driver.html b/src/mono/wasm/debugger/tests/debugger-driver.html new file mode 100644 index 000000000000..049b6b65c600 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-driver.html @@ -0,0 +1,124 @@ + + + + + + + + + + + Stuff goes here + + + +17 sdks/wasm/debugger-test.cs +@@ -0,0 +1,17 @@ +using System; + +public class Math { //Only append content to this class as the test suite depends on line info + public static int IntAdd (int a, int b) { + int c = a + b; + int d = c + b; + int e = d + a; + + return e; + } + + public static int UseComplex () { + var complex = new Simple.Complex (10, "xx"); + var res = complex.DoStuff (); + return res; + } +} + +19 sdks/wasm/debugger-test2.cs +@@ -0,0 +1,19 @@ +using System; + +public class Misc { //Only append content to this class as the test suite depends on line info + public static int CreateObject (int foo, int bar) { + var f = new Fancy () { + Foo = foo, + Bar = bar, + }; + + Console.WriteLine ($"{f.Foo} {f.Bar}"); + return f.Foo + f.Bar; + } +} + +public class Fancy { + public int Foo; + public int Bar { get ; set; } +} diff --git a/src/mono/wasm/debugger/tests/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-evaluate-test.cs new file mode 100644 index 000000000000..4d958cd004d9 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-evaluate-test.cs @@ -0,0 +1,108 @@ +// 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.Threading.Tasks; +namespace DebuggerTests +{ + public class EvaluateTestsClass + { + public class TestEvaluate + { + public int a; + public int b; + public int c; + public DateTime dt = new DateTime(2000, 5, 4, 3, 2, 1); + public void run(int g, int h, string valString) + { + int d = g + 1; + int e = g + 2; + int f = g + 3; + int i = d + e + f; + var local_dt = new DateTime(2010, 9, 8, 7, 6, 5); + a = 1; + b = 2; + c = 3; + a = a + 1; + b = b + 1; + c = c + 1; + } + } + + public static void EvaluateLocals() + { + TestEvaluate f = new TestEvaluate(); + f.run(100, 200, "test"); + + var f_s = new EvaluateTestsStruct(); + f_s.EvaluateTestsStructInstanceMethod(100, 200, "test"); + f_s.GenericInstanceMethodOnStruct(100, 200, "test"); + + var f_g_s = new EvaluateTestsGenericStruct(); + f_g_s.EvaluateTestsGenericStructInstanceMethod(100, 200, "test"); + Console.WriteLine($"a: {f.a}, b: {f.b}, c: {f.c}"); + } + + } + + public struct EvaluateTestsStruct + { + public int a; + public int b; + public int c; + DateTime dateTime; + public void EvaluateTestsStructInstanceMethod(int g, int h, string valString) + { + int d = g + 1; + int e = g + 2; + int f = g + 3; + int i = d + e + f; + a = 1; + b = 2; + c = 3; + dateTime = new DateTime(2020, 1, 2, 3, 4, 5); + a = a + 1; + b = b + 1; + c = c + 1; + } + + public void GenericInstanceMethodOnStruct(int g, int h, string valString) + { + int d = g + 1; + int e = g + 2; + int f = g + 3; + int i = d + e + f; + a = 1; + b = 2; + c = 3; + dateTime = new DateTime(2020, 1, 2, 3, 4, 5); + T t = default(T); + a = a + 1; + b = b + 1; + c = c + 1; + } + } + + public struct EvaluateTestsGenericStruct + { + public int a; + public int b; + public int c; + DateTime dateTime; + public void EvaluateTestsGenericStructInstanceMethod(int g, int h, string valString) + { + int d = g + 1; + int e = g + 2; + int f = g + 3; + int i = d + e + f; + a = 1; + b = 2; + c = 3; + dateTime = new DateTime(2020, 1, 2, 3, 4, 5); + T t = default(T); + a = a + 1; + b = b + 2; + c = c + 3; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-pointers-test.cs b/src/mono/wasm/debugger/tests/debugger-pointers-test.cs new file mode 100644 index 000000000000..122a080ba459 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-pointers-test.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; + +namespace DebuggerTests +{ + public class PointerTests + { + + public static unsafe void LocalPointers() + { + int ivalue0 = 5; + int ivalue1 = 10; + + int* ip = &ivalue0; + int* ip_null = null; + int** ipp = &ip; + int** ipp_null = &ip_null; + int*[] ipa = new int*[] { &ivalue0, &ivalue1, null }; + int**[] ippa = new int**[] { &ip, &ip_null, ipp, ipp_null, null }; + char cvalue0 = 'q'; + char* cp = &cvalue0; + + DateTime dt = new DateTime(5, 6, 7, 8, 9, 10); + void* vp = &dt; + void* vp_null = null; + void** vpp = &vp; + void** vpp_null = &vp_null; + + DateTime* dtp = &dt; + DateTime* dtp_null = null; + DateTime*[] dtpa = new DateTime*[] { dtp, dtp_null }; + DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null }; + Console.WriteLine($"-- break here: ip_null==null: {ip_null == null}, ipp_null: {ipp_null == null}, *ipp_null==ip_null: {*ipp_null == ip_null}, *ipp_null==null: {*ipp_null == null}"); + + var gs = new GenericStructWithUnmanagedT { Value = new DateTime(1, 2, 3, 4, 5, 6), IntField = 4, DTPP = &dtp }; + var gs_null = new GenericStructWithUnmanagedT { Value = new DateTime(1, 2, 3, 4, 5, 6), IntField = 4, DTPP = &dtp_null }; + var gsp = &gs; + var gsp_null = &gs_null; + var gspa = new GenericStructWithUnmanagedT*[] { null, gsp, gsp_null }; + + var cwp = new GenericClassWithPointers { Ptr = dtp }; + var cwp_null = new GenericClassWithPointers(); + Console.WriteLine($"{(int)*ip}, {(int)**ipp}, {ipp_null == null}, {ip_null == null}, {ippa == null}, {ipa}, {(char)*cp}, {(vp == null ? "null" : "not null")}, {dtp->Second}, {gsp->IntField}, {cwp}, {cwp_null}, {gs_null}"); + + PointersAsArgsTest(ip, ipp, ipa, ippa, &dt, &dtp, dtpa, dtppa); + } + + static unsafe void PointersAsArgsTest(int* ip, int** ipp, int*[] ipa, int**[] ippa, + DateTime* dtp, DateTime** dtpp, DateTime*[] dtpa, DateTime**[] dtppa) + { + Console.WriteLine($"break here!"); + if (ip == null) + Console.WriteLine($"ip is null"); + Console.WriteLine($"done!"); + } + + public static unsafe async Task LocalPointersAsync() + { + int ivalue0 = 5; + int ivalue1 = 10; + + int* ip = &ivalue0; + int* ip_null = null; + int** ipp = &ip; + int** ipp_null = &ip_null; + int*[] ipa = new int*[] { &ivalue0, &ivalue1, null }; + int**[] ippa = new int**[] { &ip, &ip_null, ipp, ipp_null, null }; + char cvalue0 = 'q'; + char* cp = &cvalue0; + + DateTime dt = new DateTime(5, 6, 7, 8, 9, 10); + void* vp = &dt; + void* vp_null = null; + void** vpp = &vp; + void** vpp_null = &vp_null; + + DateTime* dtp = &dt; + DateTime* dtp_null = null; + DateTime*[] dtpa = new DateTime*[] { dtp, dtp_null }; + DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null }; + Console.WriteLine($"-- break here: ip_null==null: {ip_null == null}, ipp_null: {ipp_null == null}, *ipp_null==ip_null: {*ipp_null == ip_null}, *ipp_null==null: {*ipp_null == null}"); + + var gs = new GenericStructWithUnmanagedT { Value = new DateTime(1, 2, 3, 4, 5, 6), IntField = 4, DTPP = &dtp }; + var gs_null = new GenericStructWithUnmanagedT { Value = new DateTime(1, 2, 3, 4, 5, 6), IntField = 4, DTPP = &dtp_null }; + var gsp = &gs; + var gsp_null = &gs_null; + var gspa = new GenericStructWithUnmanagedT*[] { null, gsp, gsp_null }; + + var cwp = new GenericClassWithPointers { Ptr = dtp }; + var cwp_null = new GenericClassWithPointers(); + Console.WriteLine($"{(int)*ip}, {(int)**ipp}, {ipp_null == null}, {ip_null == null}, {ippa == null}, {ipa}, {(char)*cp}, {(vp == null ? "null" : "not null")}, {dtp->Second}, {gsp->IntField}, {cwp}, {cwp_null}, {gs_null}"); + } + + // async methods cannot have unsafe params, so no test for that + } + + public unsafe struct GenericStructWithUnmanagedT where T : unmanaged + { + public T Value; + public int IntField; + + public DateTime** DTPP; + } + + public unsafe class GenericClassWithPointers where T : unmanaged + { + public unsafe T* Ptr; + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test.cs new file mode 100644 index 000000000000..55a13d572ae2 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-test.cs @@ -0,0 +1,325 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public partial class Math +{ //Only append content to this class as the test suite depends on line info + public static int IntAdd(int a, int b) + { + int c = a + b; + int d = c + b; + int e = d + a; + int f = 0; + return e; + } + + public static int UseComplex(int a, int b) + { + var complex = new Simple.Complex(10, "xx"); + int c = a + b; + int d = c + b; + int e = d + a; + int f = 0; + e += complex.DoStuff(); + return e; + } + + delegate bool IsMathNull(Math m); + + public static int DelegatesTest() + { + Func fn_func = (Math m) => m == null; + Func fn_func_null = null; + Func[] fn_func_arr = new Func[] { + (Math m) => m == null }; + + Math.IsMathNull fn_del = Math.IsMathNullDelegateTarget; + var fn_del_arr = new Math.IsMathNull[] { Math.IsMathNullDelegateTarget }; + var m_obj = new Math(); + Math.IsMathNull fn_del_null = null; + bool res = fn_func(m_obj) && fn_del(m_obj) && fn_del_arr[0](m_obj) && fn_del_null == null && fn_func_null == null && fn_func_arr[0] != null; + + // Unused locals + + Func fn_func_unused = (Math m) => m == null; + Func fn_func_null_unused = null; + Func[] fn_func_arr_unused = new Func[] { (Math m) => m == null }; + + Math.IsMathNull fn_del_unused = Math.IsMathNullDelegateTarget; + Math.IsMathNull fn_del_null_unused = null; + var fn_del_arr_unused = new Math.IsMathNull[] { Math.IsMathNullDelegateTarget }; + OuterMethod(); + Console.WriteLine("Just a test message, ignore"); + return res ? 0 : 1; + } + + public static int GenericTypesTest() + { + var list = new System.Collections.Generic.Dictionary(); + System.Collections.Generic.Dictionary list_null = null; + + var list_arr = new System.Collections.Generic.Dictionary[] { new System.Collections.Generic.Dictionary() }; + System.Collections.Generic.Dictionary[] list_arr_null = null; + + Console.WriteLine($"list_arr.Length: {list_arr.Length}, list.Count: {list.Count}"); + + // Unused locals + + var list_unused = new System.Collections.Generic.Dictionary(); + System.Collections.Generic.Dictionary list_null_unused = null; + + var list_arr_unused = new System.Collections.Generic.Dictionary[] { new System.Collections.Generic.Dictionary() }; + System.Collections.Generic.Dictionary[] list_arr_null_unused = null; + + OuterMethod(); + Console.WriteLine("Just a test message, ignore"); + return 0; + } + + static bool IsMathNullDelegateTarget(Math m) => m == null; + + public static void OuterMethod() + { + Console.WriteLine($"OuterMethod called"); + var nim = new Math.NestedInMath(); + var i = 5; + var text = "Hello"; + var new_i = nim.InnerMethod(i); + Console.WriteLine($"i: {i}"); + Console.WriteLine($"-- InnerMethod returned: {new_i}, nim: {nim}, text: {text}"); + int k = 19; + new_i = InnerMethod2("test string", new_i, out k); + Console.WriteLine($"-- InnerMethod2 returned: {new_i}, and k: {k}"); + } + + static int InnerMethod2(string s, int i, out int k) + { + k = i + 10; + Console.WriteLine($"s: {s}, i: {i}, k: {k}"); + return i - 2; + } + + public class NestedInMath + { + public int InnerMethod(int i) + { + SimpleStructProperty = new SimpleStruct() { dt = new DateTime(2020, 1, 2, 3, 4, 5) }; + int j = i + 10; + string foo_str = "foo"; + Console.WriteLine($"i: {i} and j: {j}, foo_str: {foo_str} "); + j += 9; + Console.WriteLine($"i: {i} and j: {j}"); + return j; + } + + Math m = new Math(); + public async System.Threading.Tasks.Task AsyncMethod0(string s, int i) + { + string local0 = "value0"; + await System.Threading.Tasks.Task.Delay(1); + Console.WriteLine($"* time for the second await, local0: {local0}"); + await AsyncMethodNoReturn(); + return true; + } + + public async System.Threading.Tasks.Task AsyncMethodNoReturn() + { + var ss = new SimpleStruct() { dt = new DateTime(2020, 1, 2, 3, 4, 5) }; + var ss_arr = new SimpleStruct[] { }; + //ss.gs.StringField = "field in GenericStruct"; + + //Console.WriteLine ($"Using the struct: {ss.dt}, {ss.gs.StringField}, ss_arr: {ss_arr.Length}"); + string str = "AsyncMethodNoReturn's local"; + //Console.WriteLine ($"* field m: {m}"); + await System.Threading.Tasks.Task.Delay(1); + Console.WriteLine($"str: {str}"); + } + + public static async System.Threading.Tasks.Task AsyncTest(string s, int i) + { + var li = 10 + i; + var ls = s + "test"; + return await new NestedInMath().AsyncMethod0(s, i); + } + + public SimpleStruct SimpleStructProperty { get; set; } + } + + public static void PrimitiveTypesTest() + { + char c0 = '€'; + char c1 = 'A'; + // TODO: other types! + // just trying to ensure vars don't get optimized out + if (c0 < 32 || c1 > 32) + Console.WriteLine($"{c0}, {c1}"); + } + + public static int DelegatesSignatureTest() + { + Func>, GenericStruct> fn_func = (m, gs) => new GenericStruct(); + Func>, GenericStruct> fn_func_del = GenericStruct.DelegateTargetForSignatureTest; + Func>, GenericStruct> fn_func_null = null; + Func fn_func_only_ret = () => { Console.WriteLine ($"hello"); return true; }; + var fn_func_arr = new Func>, GenericStruct>[] { + (m, gs) => new GenericStruct () }; + + Math.DelegateForSignatureTest fn_del = GenericStruct.DelegateTargetForSignatureTest; + Math.DelegateForSignatureTest fn_del_l = (m, gs) => new GenericStruct { StringField = "fn_del_l#lambda" }; + var fn_del_arr = new Math.DelegateForSignatureTest[] { GenericStruct.DelegateTargetForSignatureTest, (m, gs) => new GenericStruct { StringField = "fn_del_arr#1#lambda" } }; + var m_obj = new Math(); + Math.DelegateForSignatureTest fn_del_null = null; + var gs_gs = new GenericStruct> + { + List = new System.Collections.Generic.List> + { + new GenericStruct { StringField = "gs#List#0#StringField" }, + new GenericStruct { StringField = "gs#List#1#StringField" } + } + }; + + Math.DelegateWithVoidReturn fn_void_del = Math.DelegateTargetWithVoidReturn; + var fn_void_del_arr = new Math.DelegateWithVoidReturn[] { Math.DelegateTargetWithVoidReturn }; + Math.DelegateWithVoidReturn fn_void_del_null = null; + + var rets = new GenericStruct[] + { + fn_func(m_obj, gs_gs), + fn_func_del(m_obj, gs_gs), + fn_del(m_obj, gs_gs), + fn_del_l(m_obj, gs_gs), + fn_del_arr[0](m_obj, gs_gs), + fn_func_arr[0](m_obj, gs_gs) + }; + + var gs = new GenericStruct(); + fn_void_del(gs); + fn_void_del_arr[0](gs); + fn_func_only_ret(); + foreach (var ret in rets) Console.WriteLine($"ret: {ret}"); + OuterMethod(); + Console.WriteLine($"- {gs_gs.List[0].StringField}"); + return 0; + } + + public static int ActionTSignatureTest() + { + Action> fn_action = (_) => { }; + Action> fn_action_del = Math.DelegateTargetWithVoidReturn; + Action fn_action_bare = () => { }; + Action> fn_action_null = null; + var fn_action_arr = new Action>[] + { + (gs) => new GenericStruct(), + Math.DelegateTargetWithVoidReturn, + null + }; + + var gs = new GenericStruct(); + fn_action(gs); + fn_action_del(gs); + fn_action_arr[0](gs); + fn_action_bare(); + OuterMethod(); + return 0; + } + + public static int NestedDelegatesTest() + { + Func, bool> fn_func = (_) => { return true; }; + Func, bool> fn_func_null = null; + var fn_func_arr = new Func, bool>[] { + (gs) => { return true; } }; + + var fn_del_arr = new Func, bool>[] { DelegateTargetForNestedFunc> }; + var m_obj = new Math(); + Func, bool> fn_del_null = null; + Func fs = (i) => i == 0; + fn_func(fs); + fn_del_arr[0](fs); + fn_func_arr[0](fs); + OuterMethod(); + return 0; + } + + public static void DelegatesAsMethodArgsTest() + { + var _dst_arr = new DelegateForSignatureTest[] + { + GenericStruct.DelegateTargetForSignatureTest, + (m, gs) => new GenericStruct() + }; + Func _fn_func = (cs) => cs.Length == 0; + Action[]> _fn_action = (gss) => { }; + + new Math().MethodWithDelegateArgs(_dst_arr, _fn_func, _fn_action); + } + + void MethodWithDelegateArgs(Math.DelegateForSignatureTest[] dst_arr, Func fn_func, + Action[]> fn_action) + { + Console.WriteLine($"Placeholder for breakpoint"); + OuterMethod(); + } + + public static async System.Threading.Tasks.Task MethodWithDelegatesAsyncTest() + { + await new Math().MethodWithDelegatesAsync(); + } + + async System.Threading.Tasks.Task MethodWithDelegatesAsync() + { + var _dst_arr = new DelegateForSignatureTest[] + { + GenericStruct.DelegateTargetForSignatureTest, + (m, gs) => new GenericStruct() + }; + Func _fn_func = (cs) => cs.Length == 0; + Action[]> _fn_action = (gss) => { }; + + Console.WriteLine($"Placeholder for breakpoint"); + await System.Threading.Tasks.Task.CompletedTask; + } + + public delegate void DelegateWithVoidReturn(GenericStruct gs); + public static void DelegateTargetWithVoidReturn(GenericStruct gs) { } + + delegate GenericStruct DelegateForSignatureTest(Math m, GenericStruct> gs); + static bool DelegateTargetForNestedFunc(T arg) => true; + + public struct SimpleStruct + { + public DateTime dt; + public GenericStruct gs; + } + + public struct GenericStruct + { + public System.Collections.Generic.List List; + public string StringField; + + public static GenericStruct DelegateTargetForSignatureTest(Math m, GenericStruct> gs) => new GenericStruct(); + } + +} + +public class DebuggerTest +{ + public static void run_all() + { + locals(); + } + + public static int locals() + { + int l_int = 1; + char l_char = 'A'; + long l_long = Int64.MaxValue; + ulong l_ulong = UInt64.MaxValue; + locals_inner(); + return 0; + } + + static void locals_inner() { } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test.csproj new file mode 100644 index 000000000000..310ec8138098 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-test.csproj @@ -0,0 +1,49 @@ + + + $(NetCoreAppCurrent) + wasm + Browser + $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\Release\runtimes\browser-wasm\ + $(MSBuildThisFileDirectory)obj\$(Configuration)\wasm + $(MSBuildThisFileDirectory)bin\$(Configuration)\publish + $(Configuration) + true + Library + 219 + portable + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mono/wasm/debugger/tests/debugger-test2.cs b/src/mono/wasm/debugger/tests/debugger-test2.cs new file mode 100644 index 000000000000..26817a2ea4e1 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-test2.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public class Misc +{ //Only append content to this class as the test suite depends on line info + public static int CreateObject(int foo, int bar) + { + var f = new Fancy() + { + Foo = foo, + Bar = bar, + }; + + Console.WriteLine($"{f.Foo} {f.Bar}"); + return f.Foo + f.Bar; + } +} + +public class Fancy +{ + public int Foo; + public int Bar { get; set; } + public static void Types() + { + double dPI = System.Math.PI; + float fPI = (float) System.Math.PI; + + int iMax = int.MaxValue; + int iMin = int.MinValue; + uint uiMax = uint.MaxValue; + uint uiMin = uint.MinValue; + + long l = uiMax * (long) 2; + long lMax = long.MaxValue; // cannot be represented as double + long lMin = long.MinValue; // cannot be represented as double + + sbyte sbMax = sbyte.MaxValue; + sbyte sbMin = sbyte.MinValue; + byte bMax = byte.MaxValue; + byte bMin = byte.MinValue; + + short sMax = short.MaxValue; + short sMin = short.MinValue; + ushort usMin = ushort.MinValue; + ushort usMax = ushort.MaxValue; + + var d = usMin + usMax; + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs b/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs new file mode 100644 index 000000000000..3a4ceeaa48b8 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs @@ -0,0 +1,264 @@ +// 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.Threading.Tasks; +namespace DebuggerTests +{ + public class ValueTypesTest + { //Only append content to this class as the test suite depends on line info + + public static void MethodWithLocalStructs() + { + var ss_local = new SimpleStruct("set in MethodWithLocalStructs", 1, DateTimeKind.Utc); + var gs_local = new GenericStruct { StringField = "gs_local#GenericStruct#StringField" }; + + ValueTypesTest vt_local = new ValueTypesTest + { + StringField = "string#0", + SimpleStructField = new SimpleStruct("SimpleStructField#string#0", 5, DateTimeKind.Local), + SimpleStructProperty = new SimpleStruct("SimpleStructProperty#string#0", 2, DateTimeKind.Utc), DT = new DateTime(2020, 1, 2, 3, 4, 5), RGB = RGB.Blue + }; + Console.WriteLine($"Using the struct: {ss_local.gs.StringField}, gs: {gs_local.StringField}, {vt_local.StringField}"); + } + + public static void TestStructsAsMethodArgs() + { + var ss_local = new SimpleStruct("ss_local#SimpleStruct#string#0", 5, DateTimeKind.Local); + var ss_ret = MethodWithStructArgs("TestStructsAsMethodArgs#label", ss_local, 3); + Console.WriteLine($"got back ss_local: {ss_local.gs.StringField}, ss_ret: {ss_ret.gs.StringField}"); + } + + static SimpleStruct MethodWithStructArgs(string label, SimpleStruct ss_arg, int x) + { + Console.WriteLine($"- ss_arg: {ss_arg.str_member}"); + ss_arg.Kind = DateTimeKind.Utc; + ss_arg.str_member = $"ValueTypesTest#MethodWithStructArgs#updated#ss_arg#str_member"; + ss_arg.gs.StringField = $"ValueTypesTest#MethodWithStructArgs#updated#gs#StringField#{x}"; + return ss_arg; + } + + public static async Task MethodWithLocalStructsStaticAsync() + { + var ss_local = new SimpleStruct("set in MethodWithLocalStructsStaticAsync", 1, DateTimeKind.Utc); + var gs_local = new GenericStruct + { + StringField = "gs_local#GenericStruct#StringField", + List = new System.Collections.Generic.List { 5, 3 }, + Options = Options.Option2 + + }; + + var result = await ss_local.AsyncMethodWithStructArgs(gs_local); + Console.WriteLine($"Using the struct: {ss_local.gs.StringField}, result: {result}"); + + return result; + } + + public string StringField; + public SimpleStruct SimpleStructProperty { get; set; } + public SimpleStruct SimpleStructField; + + public struct SimpleStruct + { + public string str_member; + public DateTime dt; + public GenericStruct gs; + public DateTimeKind Kind; + + public SimpleStruct(string str, int f, DateTimeKind kind) + { + str_member = $"{str}#SimpleStruct#str_member"; + dt = new DateTime(2020 + f, 1 + f, 2 + f, 3 + f, 5 + f, 6 + f); + gs = new GenericStruct + { + StringField = $"{str}#SimpleStruct#gs#StringField", + List = new System.Collections.Generic.List { new DateTime(2010 + f, 2 + f, 3 + f, 10 + f, 2 + f, 3 + f) }, + Options = Options.Option1 + }; + Kind = kind; + } + + public Task AsyncMethodWithStructArgs(GenericStruct gs) + { + Console.WriteLine($"placeholder line for a breakpoint"); + if (gs.List.Count > 0) + return Task.FromResult(true); + + return Task.FromResult(false); + } + } + + public struct GenericStruct + { + public System.Collections.Generic.List List; + public string StringField; + + public Options Options { get; set; } + } + + public DateTime DT { get; set; } + public RGB RGB; + + public static void MethodWithLocalsForToStringTest(bool call_other) + { + var dt0 = new DateTime(2020, 1, 2, 3, 4, 5); + var dt1 = new DateTime(2010, 5, 4, 3, 2, 1); + var ts = dt0 - dt1; + var dto = new DateTimeOffset(dt0, new TimeSpan(4, 5, 0)); + decimal dec = 123987123; + var guid = new Guid("3d36e07e-ac90-48c6-b7ec-a481e289d014"); + + var dts = new DateTime[] + { + new DateTime(1983, 6, 7, 5, 6, 10), + new DateTime(1999, 10, 15, 1, 2, 3) + }; + + var obj = new ClassForToStringTests + { + DT = new DateTime(2004, 10, 15, 1, 2, 3), + DTO = new DateTimeOffset(dt0, new TimeSpan(2, 14, 0)), + TS = ts, + Dec = 1239871, + Guid = guid + }; + + var sst = new StructForToStringTests + { + DT = new DateTime(2004, 10, 15, 1, 2, 3), + DTO = new DateTimeOffset(dt0, new TimeSpan(3, 15, 0)), + TS = ts, + Dec = 1239871, + Guid = guid + }; + Console.WriteLine($"MethodWithLocalsForToStringTest: {dt0}, {dt1}, {ts}, {dec}, {guid}, {dts[0]}, {obj.DT}, {sst.DT}"); + if (call_other) + MethodWithArgumentsForToStringTest(call_other, dt0, dt1, ts, dto, dec, guid, dts, obj, sst); + } + + static void MethodWithArgumentsForToStringTest( + bool call_other, // not really used, just to help with using common code in the tests + DateTime dt0, DateTime dt1, TimeSpan ts, DateTimeOffset dto, decimal dec, + Guid guid, DateTime[] dts, ClassForToStringTests obj, StructForToStringTests sst) + { + Console.WriteLine($"MethodWithArgumentsForToStringTest: {dt0}, {dt1}, {ts}, {dec}, {guid}, {dts[0]}, {obj.DT}, {sst.DT}"); + } + + public static async Task MethodWithLocalsForToStringTestAsync(bool call_other) + { + var dt0 = new DateTime(2020, 1, 2, 3, 4, 5); + var dt1 = new DateTime(2010, 5, 4, 3, 2, 1); + var ts = dt0 - dt1; + var dto = new DateTimeOffset(dt0, new TimeSpan(4, 5, 0)); + decimal dec = 123987123; + var guid = new Guid("3d36e07e-ac90-48c6-b7ec-a481e289d014"); + + var dts = new DateTime[] + { + new DateTime(1983, 6, 7, 5, 6, 10), + new DateTime(1999, 10, 15, 1, 2, 3) + }; + + var obj = new ClassForToStringTests + { + DT = new DateTime(2004, 10, 15, 1, 2, 3), + DTO = new DateTimeOffset(dt0, new TimeSpan(2, 14, 0)), + TS = ts, + Dec = 1239871, + Guid = guid + }; + + var sst = new StructForToStringTests + { + DT = new DateTime(2004, 10, 15, 1, 2, 3), + DTO = new DateTimeOffset(dt0, new TimeSpan(3, 15, 0)), + TS = ts, + Dec = 1239871, + Guid = guid + }; + Console.WriteLine($"MethodWithLocalsForToStringTest: {dt0}, {dt1}, {ts}, {dec}, {guid}, {dts[0]}, {obj.DT}, {sst.DT}"); + if (call_other) + await MethodWithArgumentsForToStringTestAsync(call_other, dt0, dt1, ts, dto, dec, guid, dts, obj, sst); + } + + static async Task MethodWithArgumentsForToStringTestAsync( + bool call_other, // not really used, just to help with using common code in the tests + DateTime dt0, DateTime dt1, TimeSpan ts, DateTimeOffset dto, decimal dec, + Guid guid, DateTime[] dts, ClassForToStringTests obj, StructForToStringTests sst) + { + Console.WriteLine($"MethodWithArgumentsForToStringTest: {dt0}, {dt1}, {ts}, {dec}, {guid}, {dts[0]}, {obj.DT}, {sst.DT}"); + } + + public static void MethodUpdatingValueTypeMembers() + { + var obj = new ClassForToStringTests + { + DT = new DateTime(1, 2, 3, 4, 5, 6) + }; + var vt = new StructForToStringTests + { + DT = new DateTime(4, 5, 6, 7, 8, 9) + }; + Console.WriteLine($"#1"); + obj.DT = new DateTime(9, 8, 7, 6, 5, 4); + vt.DT = new DateTime(5, 1, 3, 7, 9, 10); + Console.WriteLine($"#2"); + } + + public static async Task MethodUpdatingValueTypeLocalsAsync() + { + var dt = new DateTime(1, 2, 3, 4, 5, 6); + Console.WriteLine($"#1"); + dt = new DateTime(9, 8, 7, 6, 5, 4); + Console.WriteLine($"#2"); + } + + public static void MethodUpdatingVTArrayMembers() + { + var ssta = new [] + { + new StructForToStringTests { DT = new DateTime(1, 2, 3, 4, 5, 6) } + }; + Console.WriteLine($"#1"); + ssta[0].DT = new DateTime(9, 8, 7, 6, 5, 4); + Console.WriteLine($"#2"); + } + } + + class ClassForToStringTests + { + public DateTime DT; + public DateTimeOffset DTO; + public TimeSpan TS; + public decimal Dec; + public Guid Guid; + } + + struct StructForToStringTests + { + public DateTime DT; + public DateTimeOffset DTO; + public TimeSpan TS; + public decimal Dec; + public Guid Guid; + } + + public enum RGB + { + Red, + Green, + Blue + } + + [Flags] + public enum Options + { + None = 0, + Option1 = 1, + Option2 = 2, + Option3 = 4, + + All = Option1 | Option3 + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/dependency.cs b/src/mono/wasm/debugger/tests/dependency.cs new file mode 100644 index 000000000000..3581a5aac8a2 --- /dev/null +++ b/src/mono/wasm/debugger/tests/dependency.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Simple +{ + public class Complex + { + public int A { get; set; } + public string B { get; set; } + object c; + + public Complex(int a, string b) + { + A = a; + B = b; + this.c = this; + } + + public int DoStuff() + { + return DoOtherStuff(); + } + + public int DoOtherStuff() + { + return DoEvenMoreStuff() - 1; + } + + public int DoEvenMoreStuff() + { + return 1 + BreakOnThisMethod(); + } + + public int BreakOnThisMethod() + { + var x = A + 10; + c = $"{x}_{B}"; + + return x; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/other.js b/src/mono/wasm/debugger/tests/other.js new file mode 100644 index 000000000000..7ba8e66c8fa5 --- /dev/null +++ b/src/mono/wasm/debugger/tests/other.js @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +function big_array_js_test (len) { + var big = new Array(len); + for (let i=0; i < len; i ++) { + big[i]=i + 1000; + } + console.log('break here'); +}; + +function object_js_test () { + var obj = { + a_obj: { aa: 5, ab: 'foo' }, + b_arr: [ 10, 12 ] + }; + + return obj; +}; + +function getters_js_test () { + var ptd = { + get Int () { return 5; }, + get String () { return "foobar"; }, + get DT () { return "dt"; }, + get IntArray () { return [1,2,3]; }, + get DTArray () { return ["dt0", "dt1"]; }, + DTAutoProperty: "dt", + StringField: "string field value" + }; + console.log (`break here`); + return ptd; +} diff --git a/src/mono/wasm/debugger/tests/runtime-debugger.js b/src/mono/wasm/debugger/tests/runtime-debugger.js new file mode 100644 index 000000000000..2e341d08f1f8 --- /dev/null +++ b/src/mono/wasm/debugger/tests/runtime-debugger.js @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +var Module = { + onRuntimeInitialized: function () { + config.loaded_cb = function () { + App.init (); + }; + MONO.mono_load_runtime_and_bcl_args (config) + }, +}; diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 093b9fdf6970..0692c65b3624 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -73,6 +73,12 @@ var MonoSupportLib = { }, }, + mono_wasm_get_exception_object: function() { + var exception_obj = MONO.active_exception; + MONO.active_exception = null; + return exception_obj ; + }, + mono_wasm_get_call_stack: function() { if (!this.mono_wasm_current_bp_id) this.mono_wasm_current_bp_id = Module.cwrap ("mono_wasm_current_bp_id", 'number'); @@ -114,8 +120,10 @@ var MonoSupportLib = { continue; } - if (i + 1 < var_list.length) - o.value = _fixup_value(var_list[i + 1].value); + if (i + 1 < var_list.length) { + _fixup_value(var_list[i + 1].value); + o = Object.assign (o, var_list [i + 1]); + } out_list.push (o); i += 2; @@ -145,6 +153,25 @@ var MonoSupportLib = { return final_var_list; }, + // Given `dotnet:object:foo:bar`, + // returns [ 'dotnet', 'object', 'foo:bar'] + _split_object_id: function (id, delimiter = ':', count = 3) { + if (id === undefined || id == "") + return []; + + if (delimiter === undefined) delimiter = ':'; + if (count === undefined) count = 3; + + var var_arr = id.split (delimiter); + var result = var_arr.splice (0, count - 1); + + if (var_arr.length > 0) + result.push (var_arr.join (delimiter)); + return result; + }, + + // + // @var_list: [ { index: , name: }, .. ] mono_wasm_get_variables: function(scope, var_list) { if (!this.mono_wasm_get_var_info) this.mono_wasm_get_var_info = Module.cwrap ("mono_wasm_get_var_info", null, [ 'number', 'number', 'number']); @@ -153,26 +180,34 @@ var MonoSupportLib = { var numBytes = var_list.length * Int32Array.BYTES_PER_ELEMENT; var ptr = Module._malloc(numBytes); var heapBytes = new Int32Array(Module.HEAP32.buffer, ptr, numBytes); - for (let i=0; i') > 0) - res [i].name = name.substring (1, name.indexOf ('>')); - } + var res_name = res [i].name; + + var value = res[i].value; + if (this._async_method_objectId != 0) { + //Async methods are special in the way that local variables can be lifted to generated class fields + //value of "this" comes here either + if (res_name !== undefined && res_name.indexOf ('>') > 0) { + // For async methods, we get the names too, so use that + // ALTHOUGH, the name wouldn't have `<>` for method args + res [i].name = res_name.substring (1, res_name.indexOf ('>')); + } - if (this._async_method_objectId != 0) { - for (let i in res) { - if (res [i].value.isValueType != undefined && res [i].value.isValueType) - res [i].value.objectId = `dotnet:valuetype:${this._async_method_objectId}:${res [i].fieldOffset}`; + if (value.isValueType) + value.objectId = `dotnet:valuetype:${this._async_method_objectId}:${res [i].fieldOffset}`; + } else if (res_name === undefined && var_list [i] !== undefined) { + // For non-async methods, we just have the var id, but we have the name + // from the caller + res [i].name = var_list [i].name; } } @@ -182,6 +217,7 @@ var MonoSupportLib = { return res; }, + mono_wasm_get_object_properties: function(objId, expandValueTypes) { if (!this.mono_wasm_get_object_properties_info) this.mono_wasm_get_object_properties_info = Module.cwrap ("mono_wasm_get_object_properties", null, [ 'number', 'bool' ]); @@ -191,8 +227,10 @@ var MonoSupportLib = { var res = MONO._filter_automatic_properties (MONO._fixup_name_value_objects (this.var_info)); for (var i = 0; i < res.length; i++) { - if (res [i].value.isValueType != undefined && res [i].value.isValueType) - res [i].value.objectId = `dotnet:valuetype:${objId}:${res [i].fieldOffset}`; + var res_val = res [i].value; + // we might not have a `.value`, like in case of getters which have a `.get` instead + if (res_val !== undefined && res_val.isValueType != undefined && res_val.isValueType) + res_val.objectId = `dotnet:valuetype:${objId}:${res [i].fieldOffset}`; } this.var_info = []; @@ -209,8 +247,14 @@ var MonoSupportLib = { var res = MONO._fixup_name_value_objects (this.var_info); for (var i = 0; i < res.length; i++) { - if (res [i].value.isValueType != undefined && res [i].value.isValueType) + var prop_value = res [i].value; + if (prop_value.isValueType) { res [i].value.objectId = `dotnet:array:${objId}:${i}`; + } else if (prop_value.objectId !== undefined && prop_value.objectId.startsWith("dotnet:pointer")) { + prop_value.objectId = this._get_updated_ptr_id (prop_value.objectId, { + varName: `[${i}]` + }); + } } this.var_info = []; @@ -255,12 +299,26 @@ var MonoSupportLib = { for (let i in var_list) { var value = var_list [i].value; - if (value == undefined || value.type != "object") + if (value === undefined) continue; - if (value.isValueType != true || value.expanded != true) // undefined would also give us false + if (value.objectId !== undefined && value.objectId.startsWith ("dotnet:pointer:")) { + var ptr_args = this._get_ptr_args (value.objectId); + if (ptr_args.varName === undefined) { + // It might have been already set in some cases, like arrays + // where the name would be `0`, but we want `[0]` for pointers, + // so the deref would look like `*[0]` + value.objectId = this._get_updated_ptr_id (value.objectId, { + varName: var_list [i].name + }); + } + } + + if (value.type != "object" || value.isValueType != true || value.expanded != true) // undefined would also give us false continue; + // Generate objectId for expanded valuetypes + var objectId = value.objectId; if (objectId == undefined) objectId = `dotnet:valuetype:${this._next_value_type_id ()}`; @@ -309,6 +367,104 @@ var MonoSupportLib = { } }, + _get_cfo_res_details: function (objectId, args) { + if (!(objectId in this._call_function_res_cache)) + throw new Error(`Could not find any object with id ${objectId}`); + + var real_obj = this._call_function_res_cache [objectId]; + + var descriptors = Object.getOwnPropertyDescriptors (real_obj); + if (args.accessorPropertiesOnly) { + Object.keys (descriptors).forEach (k => { + if (descriptors [k].get === undefined) + Reflect.deleteProperty (descriptors, k); + }); + } + + var res_details = []; + Object.keys (descriptors).forEach (k => { + var new_obj; + var prop_desc = descriptors [k]; + if (typeof prop_desc.value == "object") { + // convert `{value: { type='object', ... }}` + // to `{ name: 'foo', value: { type='object', ... }} + new_obj = Object.assign ({ name: k }, prop_desc); + } else if (prop_desc.value !== undefined) { + // This is needed for values that were not added by us, + // thus are like { value: 5 } + // instead of { value: { type = 'number', value: 5 }} + // + // This can happen, for eg., when `length` gets added for arrays + // or `__proto__`. + new_obj = { + name: k, + // merge/add `type` and `description` to `d.value` + value: Object.assign ({ type: (typeof prop_desc.value), description: '' + prop_desc.value }, + prop_desc) + }; + } else if (prop_desc.get !== undefined) { + // The real_obj has the actual getter. We are just returning a placeholder + // If the caller tries to run function on the cfo_res object, + // that accesses this property, then it would be run on `real_obj`, + // which *has* the original getter + new_obj = { + name: k, + get: { + className: "Function", + description: `get ${k} () {}`, + type: "function" + } + }; + } else { + new_obj = { name: k, value: { type: "symbol", value: "", description: ""} }; + } + + res_details.push (new_obj); + }); + + return { __value_as_json_string__: JSON.stringify (res_details) }; + }, + + _get_ptr_args: function (objectId) { + var parts = this._split_object_id (objectId); + if (parts.length != 3) + throw new Error (`Bug: Unexpected objectId format for a pointer, expected 3 parts: ${objectId}`); + return JSON.parse (parts [2]); + }, + + _get_updated_ptr_id: function (objectId, new_args) { + var old_args = {}; + if (typeof (objectId) === 'string' && objectId.length) + old_args = this._get_ptr_args (objectId); + + return `dotnet:pointer:${JSON.stringify ( Object.assign (old_args, new_args) )}`; + }, + + _get_deref_ptr_value: function (objectId) { + if (!this.mono_wasm_get_deref_ptr_value_info) + this.mono_wasm_get_deref_ptr_value_info = Module.cwrap("mono_wasm_get_deref_ptr_value", null, ['number', 'number']); + + var ptr_args = this._get_ptr_args (objectId); + if (ptr_args.ptr_addr == 0 || ptr_args.klass_addr == 0) + throw new Error (`Both ptr_addr and klass_addr need to be non-zero, to dereference a pointer. objectId: ${objectId}`); + + this.var_info = []; + var value_addr = new DataView (Module.HEAPU8.buffer).getUint32 (ptr_args.ptr_addr, /* littleEndian */ true); + this.mono_wasm_get_deref_ptr_value_info (value_addr, ptr_args.klass_addr); + + var res = MONO._fixup_name_value_objects(this.var_info); + if (res.length > 0) { + if (ptr_args.varName === undefined) + throw new Error (`Bug: no varName found for the pointer. objectId: ${objectId}`); + + res [0].name = `*${ptr_args.varName}`; + } + + res = this._post_process_details (res); + this.var_info = []; + return res; + }, + mono_wasm_get_details: function (objectId, args) { var parts = objectId.split(":"); if (parts[0] != "dotnet") @@ -334,51 +490,11 @@ var MonoSupportLib = { var containerObjectId = parts[2]; return this._get_details_for_value_type(objectId, () => this.mono_wasm_get_object_properties(containerObjectId, true)); - case "cfo_res": { - if (!(objectId in this._call_function_res_cache)) - throw new Error(`Could not find any object with id ${objectId}`); - - var real_obj = this._call_function_res_cache [objectId]; - if (args.accessorPropertiesOnly) { - // var val_accessors = JSON.stringify ([ - // { - // name: "__proto__", - // get: { type: "function", className: "Function", description: "function get __proto__ () {}", objectId: "dotnet:cfo_res:9999" }, - // set: { type: "function", className: "Function", description: "function set __proto__ () {}", objectId: "dotnet:cfo_res:8888" }, - // isOwn: false - // }], undefined, 4); - return { __value_as_json_string__: "[]" }; - } - - // behaving as if (args.ownProperties == true) - var descriptors = Object.getOwnPropertyDescriptors (real_obj); - var own_properties = []; - Object.keys (descriptors).forEach (k => { - var new_obj; - var prop_desc = descriptors [k]; - if (typeof prop_desc.value == "object") { - // convert `{value: { type='object', ... }}` - // to `{ name: 'foo', value: { type='object', ... }} - new_obj = Object.assign ({ name: k}, prop_desc); - } else { - // This is needed for values that were not added by us, - // thus are like { value: 5 } - // instead of { value: { type = 'number', value: 5 }} - // - // This can happen, for eg., when `length` gets added for arrays - // or `__proto__`. - new_obj = { - name: k, - // merge/add `type` and `description` to `d.value` - value: Object.assign ({ type: (typeof prop_desc.value), description: '' + prop_desc.value }, - prop_desc) - }; - } + case "cfo_res": + return this._get_cfo_res_details (objectId, args); - own_properties.push (new_obj); - }); - - return { __value_as_json_string__: JSON.stringify (own_properties) }; + case "pointer": { + return this._get_deref_ptr_value (objectId); } default: @@ -397,39 +513,83 @@ var MonoSupportLib = { delete this._cache_call_function_res[objectId]; }, + _invoke_getter_on_object: function (objectId, name) { + if (!this.mono_wasm_invoke_getter_on_object) + this.mono_wasm_invoke_getter_on_object = Module.cwrap ("mono_wasm_invoke_getter_on_object", 'void', [ 'number', 'string' ]); + + if (objectId < 0) { + // invalid id + return []; + } + + this.mono_wasm_invoke_getter_on_object (objectId, name); + var getter_res = MONO._post_process_details (MONO.var_info); + + MONO.var_info = []; + return getter_res [0]; + }, + + _create_proxy_from_object_id: function (objectId) { + var details = this.mono_wasm_get_details(objectId); + + if (this._is_object_id_array (objectId)) + return details.map (p => p.value); + + var objIdParts = objectId.split (':'); + var objIdNum = -1; + if (objectId.startsWith ("dotnet:object:")) + objIdNum = objIdParts [2]; + + var proxy = {}; + Object.keys (details).forEach (p => { + var prop = details [p]; + if (prop.get !== undefined) { + // TODO: `set` + + // We don't add a `get` for non-object types right now, + // so, we shouldn't get here with objIdNum==-1 + Object.defineProperty (proxy, + prop.name, + { get () { return MONO._invoke_getter_on_object (objIdNum, prop.name); } } + ); + } else { + proxy [prop.name] = prop.value; + } + }); + + return proxy; + }, + mono_wasm_call_function_on: function (request) { + if (request.arguments != undefined && !Array.isArray (request.arguments)) + throw new Error (`"arguments" should be an array, but was ${request.arguments}`); + var objId = request.objectId; var proxy; if (objId in this._call_function_res_cache) { proxy = this._call_function_res_cache [objId]; } else if (!objId.startsWith ('dotnet:cfo_res:')) { - var details = this.mono_wasm_get_details(objId); - var target_is_array = this._is_object_id_array (objId); - proxy = target_is_array ? [] : {}; - - Object.keys(details).forEach(p => { - var prop = details[p]; - if (target_is_array) { - proxy.push(prop.value); - } else { - if (prop.name != undefined) - proxy [prop.name] = prop.value; - else // when can this happen?? - proxy[''+p] = prop.value; - } - }); + proxy = this._create_proxy_from_object_id (objId); } - var fn_args = request.arguments != undefined ? request.arguments.map(a => a.value) : []; + var fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : []; var fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`; var fn_res = eval (fn_eval_str); - if (request.returnByValue) + if (fn_res == undefined) // should we just return undefined? + throw Error ('Function returned undefined result'); + + // primitive type + if (Object (fn_res) !== fn_res) return fn_res; - if (fn_res == undefined) - throw Error ('Function returned undefined result'); + // return .value, if it is a primitive type + if (fn_res.value !== undefined && Object (fn_res.value.value) !== fn_res.value.value) + return fn_res.value; + + if (request.returnByValue) + return {type: "object", value: fn_res}; var fn_res_id = this._cache_call_function_res (fn_res); if (Object.getPrototypeOf (fn_res) == Array.prototype) { @@ -445,24 +605,46 @@ var MonoSupportLib = { } }, + _clear_per_step_state: function () { + this._next_value_type_id_var = 0; + this._value_types_cache = {}; + }, + + mono_wasm_debugger_resume: function () { + this._clear_per_step_state (); + }, + mono_wasm_start_single_stepping: function (kind) { console.log (">> mono_wasm_start_single_stepping " + kind); if (!this.mono_wasm_setup_single_step) this.mono_wasm_setup_single_step = Module.cwrap ("mono_wasm_setup_single_step", 'number', [ 'number']); - this._next_value_type_id_var = 0; - this._value_types_cache = {}; + this._clear_per_step_state (); return this.mono_wasm_setup_single_step (kind); }, + mono_wasm_set_pause_on_exceptions: function (state) { + if (!this.mono_wasm_pause_on_exceptions) + this.mono_wasm_pause_on_exceptions = Module.cwrap ("mono_wasm_pause_on_exceptions", 'number', [ 'number']); + var state_enum = 0; + switch (state) { + case 'uncaught': + state_enum = 1; //EXCEPTION_MODE_UNCAUGHT + break; + case 'all': + state_enum = 2; //EXCEPTION_MODE_ALL + break; + } + return this.mono_wasm_pause_on_exceptions (state_enum); + }, + mono_wasm_runtime_ready: function () { this.mono_wasm_runtime_is_ready = true; // DO NOT REMOVE - magic debugger init function console.debug ("mono_wasm_runtime_ready", "fe00e07a-5519-4dfe-b35a-f867dbaf2e28"); - this._next_value_type_id_var = 0; - this._value_types_cache = {}; + this._clear_per_step_state (); // FIXME: where should this go? this._next_call_function_res_id = 0; @@ -484,7 +666,7 @@ var MonoSupportLib = { }, // Set environment variable NAME to VALUE - // Should be called before mono_load_runtime_and_bcl () in most cases + // Should be called before mono_load_runtime_and_bcl () in most cases mono_wasm_setenv: function (name, value) { if (!this.wasm_setenv) this.wasm_setenv = Module.cwrap ('mono_wasm_setenv', null, ['string', 'string']); @@ -663,12 +845,12 @@ var MonoSupportLib = { // deprecated mono_load_runtime_and_bcl: function ( - unused_vfs_prefix, deploy_prefix, enable_debugging, file_list, loaded_cb, fetch_file_cb + unused_vfs_prefix, deploy_prefix, debug_level, file_list, loaded_cb, fetch_file_cb ) { var args = { fetch_file_cb: fetch_file_cb, loaded_cb: loaded_cb, - enable_debugging: enable_debugging, + debug_level: debug_level, assembly_root: deploy_prefix, assets: [] }; @@ -693,7 +875,7 @@ var MonoSupportLib = { // Initializes the runtime and loads assemblies, debug information, and other files. // @args is a dictionary-style Object with the following properties: // assembly_root: (required) the subfolder containing managed assemblies and pdbs - // enable_debugging: (required) + // debug_level or enable_debugging: (required) // assets: (required) a list of assets to load along with the runtime. each asset // is a dictionary-style Object with the following properties: // name: (required) the name of the asset, including extension. @@ -777,7 +959,7 @@ var MonoSupportLib = { if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) { try { - load_runtime ("unused", args.enable_debugging); + load_runtime ("unused", args.debug_level); } catch (ex) { print ("MONO_WASM: load_runtime () failed: " + ex); print ("MONO_WASM: Stacktrace: \n"); @@ -787,7 +969,7 @@ var MonoSupportLib = { wasm_exit (1); } } else { - load_runtime ("unused", args.enable_debugging); + load_runtime ("unused", args.debug_level); } MONO.mono_wasm_runtime_ready (); @@ -795,6 +977,8 @@ var MonoSupportLib = { }, _load_assets_and_runtime: function (args) { + if (args.enable_debugging) + args.debug_level = args.enable_debugging; if (args.assembly_list) throw new Error ("Invalid args (assembly_list was replaced by assets)"); if (args.runtime_assets) @@ -999,16 +1183,31 @@ var MonoSupportLib = { }); }, - _mono_wasm_add_getter_var: function(className) { + _mono_wasm_add_getter_var: function(className, invokable) { fixed_class_name = MONO._mono_csharp_fixup_class_name (className); - var value = `${fixed_class_name} { get; }`; - MONO.var_info.push({ - value: { - type: "symbol", - value: value, - description: value - } - }); + if (invokable != 0) { + var name; + if (MONO.var_info.length > 0) + name = MONO.var_info [MONO.var_info.length - 1].name; + name = (name === undefined) ? "" : name; + + MONO.var_info.push({ + get: { + className: "Function", + description: `get ${name} () {}`, + type: "function", + } + }); + } else { + var value = `${fixed_class_name} { get; }`; + MONO.var_info.push({ + value: { + type: "symbol", + description: value, + value: value, + } + }); + } }, _mono_wasm_add_array_var: function(className, objectId, length) { @@ -1069,7 +1268,7 @@ var MonoSupportLib = { break; case "getter": - MONO._mono_wasm_add_getter_var (str_value); + MONO._mono_wasm_add_getter_var (str_value, value); break; case "array": @@ -1077,13 +1276,26 @@ var MonoSupportLib = { break; case "pointer": { - MONO.var_info.push ({ - value: { - type: "symbol", - value: str_value, - description: str_value - } - }); + var fixed_value_str = MONO._mono_csharp_fixup_class_name (str_value); + if (value.klass_addr == 0 || value.ptr_addr == 0 || fixed_value_str.startsWith ('(void*')) { + // null or void*, which we can't deref + MONO.var_info.push({ + value: { + type: "symbol", + value: fixed_value_str, + description: fixed_value_str + } + }); + } else { + MONO.var_info.push({ + value: { + type: "object", + className: fixed_value_str, + description: fixed_value_str, + objectId: this._get_updated_ptr_id ('', value) + } + }); + } } break; diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index a9a6ffc7e789..4ca72c5e61b1 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -29,6 +29,7 @@ public class WasmAppBuilder : Task public string? MainJS { get; set; } [Required] public ITaskItem[]? AssemblySearchPaths { get; set; } + public int DebugLevel { get; set; } public ITaskItem[]? ExtraAssemblies { get; set; } public ITaskItem[]? FilesToIncludeInFileSystem { get; set; } public ITaskItem[]? RemoteSources { get; set; } @@ -41,8 +42,8 @@ private class WasmAppConfig { [JsonPropertyName("assembly_root")] public string AssemblyRoot { get; set; } = "managed"; - [JsonPropertyName("enable_debugging")] - public int EnableDebugging { get; set; } = 0; + [JsonPropertyName("debug_level")] + public int DebugLevel { get; set; } = 0; [JsonPropertyName("assets")] public List Assets { get; } = new List(); [JsonPropertyName("remote_sources")] @@ -116,8 +117,15 @@ public override bool Execute () // Create app Directory.CreateDirectory(AppDir!); Directory.CreateDirectory(Path.Join(AppDir, config.AssemblyRoot)); - foreach (var assembly in _assemblies!.Values) + foreach (var assembly in _assemblies!.Values) { File.Copy(assembly.Location, Path.Join(AppDir, config.AssemblyRoot, Path.GetFileName(assembly.Location)), true); + if (DebugLevel > 0) { + var pdb = assembly.Location; + pdb = Path.ChangeExtension(pdb, ".pdb"); + if (File.Exists(pdb)) + File.Copy(pdb, Path.Join(AppDir, config.AssemblyRoot, Path.GetFileName(pdb)), true); + } + } List nativeAssets = new List() { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat" }; @@ -130,8 +138,17 @@ public override bool Execute () File.Copy(Path.Join (MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true); File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true); - foreach (var assembly in _assemblies.Values) + foreach (var assembly in _assemblies.Values) { config.Assets.Add(new AssemblyEntry (Path.GetFileName(assembly.Location))); + if (DebugLevel > 0) { + var pdb = assembly.Location; + pdb = Path.ChangeExtension(pdb, ".pdb"); + if (File.Exists(pdb)) + config.Assets.Add(new AssemblyEntry (Path.GetFileName(pdb))); + } + } + + config.DebugLevel = DebugLevel; if (FilesToIncludeInFileSystem != null) { From 9a9d5c43138eb0b8e80f4d1a872e8467eec82780 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Wed, 5 Aug 2020 15:59:28 -0700 Subject: [PATCH 279/755] Refactor Microsoft.Extensions TargetFrameworks (#40397) I went through every Microsoft.Extensions project to try to either reduce the number of TargetFrameworks they build for, or add a TargetFramework to avoid the need of bringing an additional dependency on Microsoft.Bcl.AsyncInterfaces. --- .../Microsoft.Extensions.Configuration.CommandLine.csproj | 4 +--- .../src/Microsoft.Extensions.Configuration.Json.csproj | 6 ++---- .../Microsoft.Extensions.Configuration.UserSecrets.csproj | 4 +--- .../src/Microsoft.Extensions.Configuration.Xml.csproj | 4 +--- .../src/Microsoft.Extensions.Hosting.Abstractions.csproj | 4 +--- .../src/Microsoft.Extensions.Hosting.csproj | 4 +--- .../src/Microsoft.Extensions.Logging.Configuration.csproj | 4 +--- .../src/Microsoft.Extensions.Logging.Console.csproj | 8 +++++--- .../src/Microsoft.Extensions.Logging.Debug.csproj | 4 +--- .../src/Microsoft.Extensions.Logging.EventLog.csproj | 4 +--- .../src/Microsoft.Extensions.Logging.EventSource.csproj | 3 ++- .../src/Microsoft.Extensions.Logging.TraceSource.csproj | 4 +--- .../src/Microsoft.Extensions.Logging.csproj | 2 +- ...soft.Extensions.Options.ConfigurationExtensions.csproj | 4 +--- .../Microsoft.Extensions.Options.DataAnnotations.csproj | 8 +++++--- 15 files changed, 25 insertions(+), 42 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj index 5797401b7fe5..0c2ba3fbdfe6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/Microsoft.Extensions.Configuration.CommandLine.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj index 0f4b2c3d3253..aa7b6ae1a865 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj @@ -1,11 +1,9 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.1;netstandard2.0;net461 true true - - false @@ -13,12 +11,12 @@ + - diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj index fe99bc62fc99..d4378be0324a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj index c90577e4fe84..e1dad4a470de 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/Microsoft.Extensions.Configuration.Xml.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index aa4670aa7d35..1b488e022839 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -1,11 +1,9 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.1;netstandard2.0;net461 Microsoft.Extensions.Hosting true - - false diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 5106330045e6..13dd4bc402e5 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj index b666c263a402..d12a37aa4175 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index a5286643df9b..29bfc3f99068 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -1,7 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 + true true annotations $(DefineConstants);NO_SUPPRESS_GC_TRANSITION @@ -27,9 +28,10 @@ Link="Common\Interop\Windows\Interop.GetStdHandle.cs" /> - - + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj b/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj index a6a8adb91caf..a025ca9fc851 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/src/Microsoft.Extensions.Logging.Debug.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj index 893cded069d0..9ae5802d972d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/Microsoft.Extensions.Logging.EventLog.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);net461;netstandard2.0;netstandard2.1 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj index e1c994d8b547..b6cd4860ebc8 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj @@ -1,7 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 + true true true diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj index 30ddca780a41..89bb3fe1b9e7 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/Microsoft.Extensions.Logging.TraceSource.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj index 4029a142486f..49781fe7a450 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj +++ b/src/libraries/Microsoft.Extensions.Logging/src/Microsoft.Extensions.Logging.csproj @@ -1,7 +1,7 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.1;netstandard2.0;net461 true false diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index 1f9712661344..5a43205e7f0c 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.0;net461 true - - false diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj index 1936fb85d671..bcf5ce56123e 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -1,10 +1,8 @@ - $(NetCoreAppCurrent);netstandard2.0;net461 + netstandard2.1;netstandard2.0;net461 true - - false @@ -16,6 +14,10 @@ + + + + From c8ecf5519c5eaba24419a41aabad1eaca0437558 Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Wed, 5 Aug 2020 16:12:54 -0700 Subject: [PATCH 280/755] Turnoff wasm runs for CI (#40421) --- eng/pipelines/coreclr/perf.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index 0cbf812e809d..0cb8d81f925c 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -111,22 +111,22 @@ jobs: projectFile: microbenchmarks.proj runKind: micro_mono + # run mono wasm microbenchmarks perf job + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: wasm + platforms: + - Linux_x64 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + runtimeType: wasm + codeGenType: 'wasm' + projectFile: microbenchmarks.proj + runKind: micro # run coreclr microbenchmarks perf job -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml - buildConfig: release - runtimeFlavor: wasm - platforms: - - Linux_x64 - jobParameters: - testGroup: perf - liveLibrariesBuildConfig: Release - runtimeType: wasm - codeGenType: 'wasm' - projectFile: microbenchmarks.proj - runKind: micro - - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml From 1a39b6c63dbc12721348281bd591ef5a8d75b4ae Mon Sep 17 00:00:00 2001 From: imhameed Date: Wed, 5 Aug 2020 17:49:12 -0700 Subject: [PATCH 281/755] [mono] Don't save byref `System.Void` into `MonoDomain::typeof_void`. (#40405) `mono_type_get_object_checked` will return the `MonoReflectionType` referred to by `MonoDomain::typeof_void` if present. If a byref `System.Void` is stored in this field, then `get_ContainsGenericParameters` applied to `System.Void` will loop indefinitely, because our implementation of `get_ContainsGenericParameters` expects `GetElementType` to yield a `MonoReflectionType` with one layer of "type function application" removed. Fixes https://github.com/dotnet/runtime/issues/37489. --- src/mono/mono/metadata/reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/reflection.c b/src/mono/mono/metadata/reflection.c index c28ce829a499..09851b355a1f 100644 --- a/src/mono/mono/metadata/reflection.c +++ b/src/mono/mono/metadata/reflection.c @@ -570,7 +570,7 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err res->type = type; mono_g_hash_table_insert_internal (domain->type_hash, type, res); - if (type->type == MONO_TYPE_VOID) + if (type->type == MONO_TYPE_VOID && !type->byref) domain->typeof_void = (MonoObject*)res; mono_domain_unlock (domain); From 222415c56c9ea73530444768c0e68413eb374f5d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 5 Aug 2020 17:52:34 -0700 Subject: [PATCH 282/755] Fix crossgenning of sparse COM interface types on non-Windows and add test (#40404) --- src/coreclr/src/zap/zapimage.cpp | 4 ---- .../typeequivalence/contracts/TypeContracts.csproj | 2 -- src/tests/baseservices/typeequivalence/impl/TypeImpl.csproj | 2 -- src/tests/baseservices/typeequivalence/simple/Simple.cs | 4 ++++ src/tests/baseservices/typeequivalence/simple/Simple.csproj | 2 -- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/coreclr/src/zap/zapimage.cpp b/src/coreclr/src/zap/zapimage.cpp index e1139427f268..693921963d84 100644 --- a/src/coreclr/src/zap/zapimage.cpp +++ b/src/coreclr/src/zap/zapimage.cpp @@ -1894,7 +1894,6 @@ void ZapImage::TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub //----------------------------------------------------------------------------- BOOL ZapImage::IsVTableGapMethod(mdMethodDef md) { -#ifdef FEATURE_COMINTEROP HRESULT hr; DWORD dwAttributes; @@ -1916,9 +1915,6 @@ BOOL ZapImage::IsVTableGapMethod(mdMethodDef md) // If we make it to here we have a vtable gap method. return TRUE; -#else - return FALSE; -#endif // FEATURE_COMINTEROP } //----------------------------------------------------------------------------- diff --git a/src/tests/baseservices/typeequivalence/contracts/TypeContracts.csproj b/src/tests/baseservices/typeequivalence/contracts/TypeContracts.csproj index ce626dfdd026..306758e5a5b8 100644 --- a/src/tests/baseservices/typeequivalence/contracts/TypeContracts.csproj +++ b/src/tests/baseservices/typeequivalence/contracts/TypeContracts.csproj @@ -1,8 +1,6 @@ Library - - true diff --git a/src/tests/baseservices/typeequivalence/impl/TypeImpl.csproj b/src/tests/baseservices/typeequivalence/impl/TypeImpl.csproj index 4c64a59beda1..b916b7007609 100644 --- a/src/tests/baseservices/typeequivalence/impl/TypeImpl.csproj +++ b/src/tests/baseservices/typeequivalence/impl/TypeImpl.csproj @@ -1,8 +1,6 @@ Library - - true diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.cs b/src/tests/baseservices/typeequivalence/simple/Simple.cs index 9b0a63ecf2d1..fbfb5dbdb370 100644 --- a/src/tests/baseservices/typeequivalence/simple/Simple.cs +++ b/src/tests/baseservices/typeequivalence/simple/Simple.cs @@ -216,6 +216,10 @@ private static void TestGenericInterfaceEquivalence() public static int Main(string[] noArgs) { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return 100; + } try { InterfaceTypesFromDifferentAssembliesAreEquivalent(); diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.csproj b/src/tests/baseservices/typeequivalence/simple/Simple.csproj index e53815c61324..028b3cc152ef 100644 --- a/src/tests/baseservices/typeequivalence/simple/Simple.csproj +++ b/src/tests/baseservices/typeequivalence/simple/Simple.csproj @@ -1,8 +1,6 @@ Exe - - true From 4da9d986fc863ba051441d8d9d1dab7b6a099325 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 5 Aug 2020 21:54:00 -0400 Subject: [PATCH 283/755] Fix -numproc script handling (#40437) --- eng/native/build-commons.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index e5bec2b3b8ce..29c29a194e61 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -229,6 +229,20 @@ __BuildOS=$os __msbuildonunsupportedplatform=0 +# Get the number of processors available to the scheduler +# Other techniques such as `nproc` only get the number of +# processors available to a single process. +platform="$(uname)" +if [[ "$platform" == "FreeBSD" ]]; then + __NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }') +elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then + __NumProc=$(($(getconf NPROCESSORS_ONLN)+1)) +elif [[ "$platform" == "Darwin" ]]; then + __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1)) +else + __NumProc=$(nproc --all) +fi + while :; do if [[ "$#" -le 0 ]]; then break @@ -395,20 +409,6 @@ while :; do shift done -# Get the number of processors available to the scheduler -# Other techniques such as `nproc` only get the number of -# processors available to a single process. -platform="$(uname)" -if [[ "$platform" == "FreeBSD" ]]; then - __NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }') -elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then - __NumProc=$(($(getconf NPROCESSORS_ONLN)+1)) -elif [[ "$platform" == "Darwin" ]]; then - __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1)) -else - __NumProc=$(nproc --all) -fi - __CommonMSBuildArgs="/p:TargetArchitecture=$__BuildArch /p:Configuration=$__BuildType /p:TargetOS=$__TargetOS /nodeReuse:false $__OfficialBuildIdArg $__SignTypeArg $__SkipRestoreArg" # Configure environment if we are doing a verbose build From 5a3b5f43c8e92fa59459065957736cdd321353e1 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 5 Aug 2020 21:28:31 -0500 Subject: [PATCH 284/755] Consider debug levels less than zero disabled (#40429) --- src/mono/wasm/runtime/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 0400c39f8e15..971cd5761bfc 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -386,7 +386,7 @@ mono_wasm_load_runtime (const char *unused, int enable_debugging) #endif #else mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_ONLY); - if (enable_debugging) { + if (enable_debugging > 0) { // Disable optimizations which interfere with debugging interp_opts = "-all"; mono_wasm_enable_debugging (enable_debugging); From 53d70b08ab088c318e4137ea1f1b67ac0fb06a60 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Thu, 6 Aug 2020 04:56:52 +0200 Subject: [PATCH 285/755] Add HeaderEncodingSelector to MultipartContent (#39169) * Add HeaderEncodingSelector to MultipartContent * Test cleanup * Avoid WriteLatin1 logic duplication * Move to common HeaderEncodingSelector * Fix indentation --- .../System.Net.Http/ref/System.Net.Http.cs | 1 + .../src/System/Net/Http/MultipartContent.cs | 153 ++++++++++-------- .../FunctionalTests/MultipartContentTest.cs | 117 ++++++++++++++ .../UnitTests/Headers/MultipartContentTest.cs | 86 ++++++++++ .../System.Net.Http.Unit.Tests.csproj | 5 +- 5 files changed, 298 insertions(+), 64 deletions(-) create mode 100644 src/libraries/System.Net.Http/tests/UnitTests/Headers/MultipartContentTest.cs diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index f259892c5bc9..415a52f71b17 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -285,6 +285,7 @@ public partial class MultipartContent : System.Net.Http.HttpContent, System.Coll public MultipartContent() { } public MultipartContent(string subtype) { } public MultipartContent(string subtype, string boundary) { } + public System.Net.Http.HeaderEncodingSelector? HeaderEncodingSelector { get { throw null; } set { } } public virtual void Add(System.Net.Http.HttpContent content) { } protected override System.IO.Stream CreateContentReadStream(System.Threading.CancellationToken cancellationToken) { throw null; } protected override System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs index 4f1a1dd23acf..7ea8eb232f03 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs @@ -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.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -18,10 +19,10 @@ public class MultipartContent : HttpContent, IEnumerable private const string CrLf = "\r\n"; - private static readonly int s_crlfLength = GetEncodedLength(CrLf); - private static readonly int s_dashDashLength = GetEncodedLength("--"); - private static readonly int s_colonSpaceLength = GetEncodedLength(": "); - private static readonly int s_commaSpaceLength = GetEncodedLength(", "); + private const int CrLfLength = 2; + private const int DashDashLength = 2; + private const int ColonSpaceLength = 2; + private const int CommaSpaceLength = 2; private readonly List _nestedContent; private readonly string _boundary; @@ -157,6 +158,12 @@ Collections.IEnumerator Collections.IEnumerable.GetEnumerator() #region Serialization + /// + /// Gets or sets a callback that returns the to decode the value for the specified response header name, + /// or to use the default behavior. + /// + public HeaderEncodingSelector? HeaderEncodingSelector { get; set; } + // for-each content // write "--" + boundary // for-each content header @@ -171,20 +178,19 @@ protected override void SerializeToStream(Stream stream, TransportContext? conte try { // Write start boundary. - EncodeStringToStream(stream, "--" + _boundary + CrLf); + WriteToStream(stream, "--" + _boundary + CrLf); // Write each nested content. - var output = new StringBuilder(); for (int contentIndex = 0; contentIndex < _nestedContent.Count; contentIndex++) { // Write divider, headers, and content. HttpContent content = _nestedContent[contentIndex]; - EncodeStringToStream(stream, SerializeHeadersToString(output, contentIndex, content)); + SerializeHeadersToStream(stream, content, writeDivider: contentIndex != 0); content.CopyTo(stream, context, cancellationToken); } // Write footer boundary. - EncodeStringToStream(stream, CrLf + "--" + _boundary + "--" + CrLf); + WriteToStream(stream, CrLf + "--" + _boundary + "--" + CrLf); } catch (Exception ex) { @@ -219,12 +225,17 @@ private protected async Task SerializeToStreamAsyncCore(Stream stream, Transport await EncodeStringToStreamAsync(stream, "--" + _boundary + CrLf, cancellationToken).ConfigureAwait(false); // Write each nested content. - var output = new StringBuilder(); + var output = new MemoryStream(); for (int contentIndex = 0; contentIndex < _nestedContent.Count; contentIndex++) { // Write divider, headers, and content. HttpContent content = _nestedContent[contentIndex]; - await EncodeStringToStreamAsync(stream, SerializeHeadersToString(output, contentIndex, content), cancellationToken).ConfigureAwait(false); + + output.SetLength(0); + SerializeHeadersToStream(output, content, writeDivider: contentIndex != 0); + output.Position = 0; + await output.CopyToAsync(stream, cancellationToken).ConfigureAwait(false); + await content.CopyToAsync(stream, context, cancellationToken).ConfigureAwait(false); } @@ -259,7 +270,6 @@ private async ValueTask CreateContentReadStreamAsyncCore(bool async, Can try { var streams = new Stream[2 + (_nestedContent.Count * 2)]; - var scratch = new StringBuilder(); int streamIndex = 0; // Start boundary. @@ -271,7 +281,7 @@ private async ValueTask CreateContentReadStreamAsyncCore(bool async, Can cancellationToken.ThrowIfCancellationRequested(); HttpContent nestedContent = _nestedContent[contentIndex]; - streams[streamIndex++] = EncodeStringToNewStream(SerializeHeadersToString(scratch, contentIndex, nestedContent)); + streams[streamIndex++] = EncodeHeadersToNewStream(nestedContent, writeDivider: contentIndex != 0); Stream readStream; if (async) @@ -312,43 +322,35 @@ private async ValueTask CreateContentReadStreamAsyncCore(bool async, Can } } - private string SerializeHeadersToString(StringBuilder scratch, int contentIndex, HttpContent content) + private void SerializeHeadersToStream(Stream stream, HttpContent content, bool writeDivider) { - scratch.Clear(); - // Add divider. - if (contentIndex != 0) // Write divider for all but the first content. + if (writeDivider) // Write divider for all but the first content. { - scratch.Append(CrLf + "--"); // const strings - scratch.Append(_boundary); - scratch.Append(CrLf); + WriteToStream(stream, CrLf + "--"); // const strings + WriteToStream(stream, _boundary); + WriteToStream(stream, CrLf); } // Add headers. foreach (KeyValuePair> headerPair in content.Headers) { - scratch.Append(headerPair.Key); - scratch.Append(": "); + Encoding headerValueEncoding = HeaderEncodingSelector?.Invoke(headerPair.Key, content) ?? HttpRuleParser.DefaultHttpEncoding; + + WriteToStream(stream, headerPair.Key); + WriteToStream(stream, ": "); string delim = string.Empty; foreach (string value in headerPair.Value) { - scratch.Append(delim); - scratch.Append(value); + WriteToStream(stream, delim); + WriteToStream(stream, value, headerValueEncoding); delim = ", "; } - scratch.Append(CrLf); + WriteToStream(stream, CrLf); } // Extra CRLF to end headers (even if there are no headers). - scratch.Append(CrLf); - - return scratch.ToString(); - } - - private static void EncodeStringToStream(Stream stream, string input) - { - byte[] buffer = HttpRuleParser.DefaultHttpEncoding.GetBytes(input); - stream.Write(buffer); + WriteToStream(stream, CrLf); } private static ValueTask EncodeStringToStreamAsync(Stream stream, string input, CancellationToken cancellationToken) @@ -362,55 +364,55 @@ private static Stream EncodeStringToNewStream(string input) return new MemoryStream(HttpRuleParser.DefaultHttpEncoding.GetBytes(input), writable: false); } + private Stream EncodeHeadersToNewStream(HttpContent content, bool writeDivider) + { + var stream = new MemoryStream(); + SerializeHeadersToStream(stream, content, writeDivider); + stream.Position = 0; + return stream; + } + internal override bool AllowDuplex => false; protected internal override bool TryComputeLength(out long length) { - int boundaryLength = GetEncodedLength(_boundary); - - long currentLength = 0; - long internalBoundaryLength = s_crlfLength + s_dashDashLength + boundaryLength + s_crlfLength; - // Start Boundary. - currentLength += s_dashDashLength + boundaryLength + s_crlfLength; + long currentLength = DashDashLength + _boundary.Length + CrLfLength; - bool first = true; - foreach (HttpContent content in _nestedContent) + if (_nestedContent.Count > 1) { - if (first) - { - first = false; // First boundary already written. - } - else - { - // Internal Boundary. - currentLength += internalBoundaryLength; - } + // Internal boundaries + currentLength += (_nestedContent.Count - 1) * (CrLfLength + DashDashLength + _boundary.Length + CrLfLength); + } + foreach (HttpContent content in _nestedContent) + { // Headers. foreach (KeyValuePair> headerPair in content.Headers) { - currentLength += GetEncodedLength(headerPair.Key) + s_colonSpaceLength; + currentLength += headerPair.Key.Length + ColonSpaceLength; + + Encoding headerValueEncoding = HeaderEncodingSelector?.Invoke(headerPair.Key, content) ?? HttpRuleParser.DefaultHttpEncoding; int valueCount = 0; foreach (string value in headerPair.Value) { - currentLength += GetEncodedLength(value); + currentLength += headerValueEncoding.GetByteCount(value); valueCount++; } + if (valueCount > 1) { - currentLength += (valueCount - 1) * s_commaSpaceLength; + currentLength += (valueCount - 1) * CommaSpaceLength; } - currentLength += s_crlfLength; + currentLength += CrLfLength; } - currentLength += s_crlfLength; + currentLength += CrLfLength; // Content. - long tempContentLength = 0; - if (!content.TryComputeLength(out tempContentLength)) + if (!content.TryComputeLength(out long tempContentLength)) { length = 0; return false; @@ -419,17 +421,12 @@ protected internal override bool TryComputeLength(out long length) } // Terminating boundary. - currentLength += s_crlfLength + s_dashDashLength + boundaryLength + s_dashDashLength + s_crlfLength; + currentLength += CrLfLength + DashDashLength + _boundary.Length + DashDashLength + CrLfLength; length = currentLength; return true; } - private static int GetEncodedLength(string input) - { - return HttpRuleParser.DefaultHttpEncoding.GetByteCount(input); - } - private sealed class ContentReadStream : Stream { private readonly Stream[] _streams; @@ -671,6 +668,36 @@ public override void Flush() { } public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { throw new NotSupportedException(); } public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { throw new NotSupportedException(); } } + + + private static void WriteToStream(Stream stream, string content) => + WriteToStream(stream, content, HttpRuleParser.DefaultHttpEncoding); + + private static void WriteToStream(Stream stream, string content, Encoding encoding) + { + const int StackallocThreshold = 1024; + + int maxLength = encoding.GetMaxByteCount(content.Length); + + byte[]? rentedBuffer = null; + Span buffer = maxLength <= StackallocThreshold + ? stackalloc byte[StackallocThreshold] + : (rentedBuffer = ArrayPool.Shared.Rent(maxLength)); + + try + { + int written = encoding.GetBytes(content, buffer); + stream.Write(buffer.Slice(0, written)); + } + finally + { + if (rentedBuffer != null) + { + ArrayPool.Shared.Return(rentedBuffer); + } + } + } + #endregion Serialization } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MultipartContentTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MultipartContentTest.cs index 7565e5b69831..a945cc3db3ea 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MultipartContentTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MultipartContentTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; +using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -387,6 +388,122 @@ public void ReadAsStream_CreateContentReadStreamThrows() Assert.Throws(() => mc.ReadAsStream()); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ReadAsStreamAsync_CustomEncodingSelector_SelectorIsCalledWithCustomState(bool async) + { + var mc = new MultipartContent(); + + var stringContent = new StringContent("foo"); + stringContent.Headers.Add("StringContent", "foo"); + mc.Add(stringContent); + + var byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("foo")); + byteArrayContent.Headers.Add("ByteArrayContent", "foo"); + mc.Add(byteArrayContent); + + bool seenStringContent = false, seenByteArrayContent = false; + + mc.HeaderEncodingSelector = (name, content) => + { + if (ReferenceEquals(content, stringContent) && name == "StringContent") + { + seenStringContent = true; + } + + if (ReferenceEquals(content, byteArrayContent) && name == "ByteArrayContent") + { + seenByteArrayContent = true; + } + + return null; + }; + + var dummy = new MemoryStream(); + if (async) + { + await (await mc.ReadAsStreamAsync()).CopyToAsync(dummy); + } + else + { + mc.ReadAsStream().CopyTo(dummy); + } + + Assert.True(seenStringContent); + Assert.True(seenByteArrayContent); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ReadAsStreamAsync_CustomEncodingSelector_CustomEncodingIsUsed(bool async) + { + var mc = new MultipartContent("subtype", "fooBoundary"); + + var stringContent = new StringContent("bar1"); + stringContent.Headers.Add("latin1", "\uD83D\uDE00"); + mc.Add(stringContent); + + var byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar2")); + byteArrayContent.Headers.Add("utf8", "\uD83D\uDE00"); + mc.Add(byteArrayContent); + + byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar3")); + byteArrayContent.Headers.Add("ascii", "\uD83D\uDE00"); + mc.Add(byteArrayContent); + + byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar4")); + byteArrayContent.Headers.Add("default", "\uD83D\uDE00"); + mc.Add(byteArrayContent); + + mc.HeaderEncodingSelector = (name, _) => name switch + { + "latin1" => Encoding.Latin1, + "utf8" => Encoding.UTF8, + "ascii" => Encoding.ASCII, + _ => null + }; + + var ms = new MemoryStream(); + if (async) + { + await (await mc.ReadAsStreamAsync()).CopyToAsync(ms); + } + else + { + mc.ReadAsStream().CopyTo(ms); + } + + byte[] expected = Concat( + Encoding.Latin1.GetBytes("--fooBoundary\r\n"), + Encoding.Latin1.GetBytes("Content-Type: text/plain; charset=utf-8\r\n"), + Encoding.Latin1.GetBytes("latin1: "), + Encoding.Latin1.GetBytes("\uD83D\uDE00"), + Encoding.Latin1.GetBytes("\r\n\r\n"), + Encoding.Latin1.GetBytes("bar1"), + Encoding.Latin1.GetBytes("\r\n--fooBoundary\r\n"), + Encoding.Latin1.GetBytes("utf8: "), + Encoding.UTF8.GetBytes("\uD83D\uDE00"), + Encoding.Latin1.GetBytes("\r\n\r\n"), + Encoding.Latin1.GetBytes("bar2"), + Encoding.Latin1.GetBytes("\r\n--fooBoundary\r\n"), + Encoding.Latin1.GetBytes("ascii: "), + Encoding.ASCII.GetBytes("\uD83D\uDE00"), + Encoding.Latin1.GetBytes("\r\n\r\n"), + Encoding.Latin1.GetBytes("bar3"), + Encoding.Latin1.GetBytes("\r\n--fooBoundary\r\n"), + Encoding.Latin1.GetBytes("default: "), + Encoding.Latin1.GetBytes("\uD83D\uDE00"), + Encoding.Latin1.GetBytes("\r\n\r\n"), + Encoding.Latin1.GetBytes("bar4"), + Encoding.Latin1.GetBytes("\r\n--fooBoundary--\r\n")); + + Assert.Equal(expected, ms.ToArray()); + + static byte[] Concat(params byte[][] arrays) => arrays.SelectMany(b => b).ToArray(); + } + #region Helpers private static async Task MultipartContentToStringAsync(MultipartContent content, MultipartContentToStringMode mode, bool async) diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/MultipartContentTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/MultipartContentTest.cs new file mode 100644 index 000000000000..e89d38c204bf --- /dev/null +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/MultipartContentTest.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Http.Tests +{ + public class MultipartContentTest + { + public static IEnumerable MultipartContent_TestData() + { + var multipartContents = new List(); + + var complexContent = new MultipartContent(); + + var stringContent = new StringContent("bar1"); + stringContent.Headers.Add("latin1", "\uD83D\uDE00"); + complexContent.Add(stringContent); + + var byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar2")); + byteArrayContent.Headers.Add("utf8", "\uD83D\uDE00"); + complexContent.Add(byteArrayContent); + + byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar3")); + byteArrayContent.Headers.Add("ascii", "\uD83D\uDE00"); + complexContent.Add(byteArrayContent); + + byteArrayContent = new ByteArrayContent(Encoding.ASCII.GetBytes("bar4")); + byteArrayContent.Headers.Add("default", "\uD83D\uDE00"); + complexContent.Add(byteArrayContent); + + stringContent = new StringContent("bar5"); + stringContent.Headers.Add("foo", "bar"); + complexContent.Add(stringContent); + + multipartContents.Add(complexContent); + multipartContents.Add(new MultipartContent()); + multipartContents.Add(new MultipartFormDataContent()); + + var encodingSelectors = new HeaderEncodingSelector[] + { + (_, _) => null, + (_, _) => Encoding.ASCII, + (_, _) => Encoding.Latin1, + (_, _) => Encoding.UTF8, + (name, _) => name switch + { + "latin1" => Encoding.Latin1, + "utf8" => Encoding.UTF8, + "ascii" => Encoding.ASCII, + _ => null + } + }; + + foreach (MultipartContent multipartContent in multipartContents) + { + foreach (HeaderEncodingSelector encodingSelector in encodingSelectors) + { + multipartContent.HeaderEncodingSelector = encodingSelector; + yield return new object[] { multipartContent }; + } + } + } + + [Theory] + [MemberData(nameof(MultipartContent_TestData))] + public async Task MultipartContent_TryComputeLength_ReturnsSameLengthAsCopyToAsync(MultipartContent multipartContent) + { + Assert.True(multipartContent.TryComputeLength(out long length)); + + var copyToStream = new MemoryStream(); + multipartContent.CopyTo(copyToStream, context: null, cancellationToken: default); + Assert.Equal(length, copyToStream.Length); + + var copyToAsyncStream = new MemoryStream(); + await multipartContent.CopyToAsync(copyToAsyncStream, context: null, cancellationToken: default); + Assert.Equal(length, copyToAsyncStream.Length); + + Assert.Equal(copyToStream.ToArray(), copyToAsyncStream.ToArray()); + } + } +} diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index c4d16823b074..19de137c6434 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -1,4 +1,4 @@ - + ../../src/Resources/Strings.resx true @@ -90,6 +90,8 @@ Link="ProductionCode\System\Net\Http\EmptyReadStream.cs" /> + + From 189e1aa8f91632c196fe0e6cb1410a85bb7d2283 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Wed, 5 Aug 2020 21:16:21 -0700 Subject: [PATCH 286/755] Improve dictionary & hashset lookup perf for OrdinalIgnoreCase (#36252) --- .../Dictionary/Dictionary.Generic.Tests.cs | 34 +++ .../OutOfBoundsRegression.cs | 237 ++++++++++++++++++ .../System.Private.CoreLib.Shared.projitems | 2 + .../System/Collections/Generic/Dictionary.cs | 52 +++- .../src/System/Collections/Generic/HashSet.cs | 52 +++- .../IInternalStringEqualityComparer.cs | 36 +++ .../NonRandomizedStringEqualityComparer.cs | 94 ++++++- .../RandomizedStringEqualityComparer.cs | 124 +++++++++ .../src/System/String.Comparison.cs | 66 ++++- .../src/System/StringComparer.cs | 24 +- .../tests/TestData.resources | Bin 8184 -> 8046 bytes 11 files changed, 678 insertions(+), 43 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IInternalStringEqualityComparer.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs diff --git a/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.cs b/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.cs index 3de72528d02c..32f277e82b15 100644 --- a/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.cs @@ -3,7 +3,9 @@ using Common.System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Runtime.Serialization; using Xunit; namespace System.Collections.Tests @@ -610,5 +612,37 @@ public void TrimExcess_Generic_DoesInvalidateEnumeration() } #endregion + + #region Non-randomized comparers + [Fact] + public void Dictionary_Comparer_NonRandomizedStringComparers() + { + RunTest(null); + RunTest(EqualityComparer.Default); + RunTest(StringComparer.Ordinal); + RunTest(StringComparer.OrdinalIgnoreCase); + RunTest(StringComparer.InvariantCulture); + RunTest(StringComparer.InvariantCultureIgnoreCase); + RunTest(StringComparer.Create(CultureInfo.InvariantCulture, ignoreCase: false)); + RunTest(StringComparer.Create(CultureInfo.InvariantCulture, ignoreCase: true)); + + void RunTest(IEqualityComparer comparer) + { + // First, instantiate the dictionary and check its Comparer property + + Dictionary dict = new Dictionary(comparer); + object expected = comparer ?? EqualityComparer.Default; + + Assert.Same(expected, dict.Comparer); + + // Then pretend to serialize the dictionary and check the stored Comparer instance + + SerializationInfo si = new SerializationInfo(typeof(Dictionary), new FormatterConverter()); + dict.GetObjectData(si, new StreamingContext(StreamingContextStates.All)); + + Assert.Same(expected, si.GetValue("Comparer", typeof(IEqualityComparer))); + } + } + #endregion } } diff --git a/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs b/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs index bc8308847cda..934e57aafe4c 100644 --- a/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs +++ b/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs @@ -2,6 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Numerics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; using Xunit; namespace System.Collections.Tests @@ -37,5 +41,238 @@ public static void OutOfBoundsRegression() dictionary.Remove(key); } } + + [Fact] + public static void ComparerImplementations_Dictionary_WithWellKnownStringComparers() + { + Type nonRandomizedOrdinalComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.NonRandomizedStringEqualityComparer+OrdinalComparer", throwOnError: true); + Type nonRandomizedOrdinalIgnoreCaseComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.NonRandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer", throwOnError: true); + Type randomizedOrdinalComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.RandomizedStringEqualityComparer+OrdinalComparer", throwOnError: true); + Type randomizedOrdinalIgnoreCaseComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.RandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer", throwOnError: true); + + // null comparer + + RunDictionaryTest( + equalityComparer: null, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: EqualityComparer.Default.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // EqualityComparer.Default comparer + + RunDictionaryTest( + equalityComparer: EqualityComparer.Default, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: EqualityComparer.Default.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // Ordinal comparer + + RunDictionaryTest( + equalityComparer: StringComparer.Ordinal, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: StringComparer.Ordinal.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // OrdinalIgnoreCase comparer + + RunDictionaryTest( + equalityComparer: StringComparer.OrdinalIgnoreCase, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalIgnoreCaseComparerType, + expectedPublicComparerBeforeCollisionThreshold: StringComparer.OrdinalIgnoreCase.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalIgnoreCaseComparerType); + + // linguistic comparer (not optimized) + + RunDictionaryTest( + equalityComparer: StringComparer.InvariantCulture, + expectedInternalComparerBeforeCollisionThreshold: StringComparer.InvariantCulture.GetType(), + expectedPublicComparerBeforeCollisionThreshold: StringComparer.InvariantCulture.GetType(), + expectedComparerAfterCollisionThreshold: StringComparer.InvariantCulture.GetType()); + + static void RunDictionaryTest( + IEqualityComparer equalityComparer, + Type expectedInternalComparerBeforeCollisionThreshold, + Type expectedPublicComparerBeforeCollisionThreshold, + Type expectedComparerAfterCollisionThreshold) + { + RunCollectionTestCommon( + () => new Dictionary(equalityComparer), + (dictionary, key) => dictionary.Add(key, null), + (dictionary, key) => dictionary.ContainsKey(key), + dictionary => dictionary.Comparer, + expectedInternalComparerBeforeCollisionThreshold, + expectedPublicComparerBeforeCollisionThreshold, + expectedComparerAfterCollisionThreshold); + } + } + + [Fact] + public static void ComparerImplementations_HashSet_WithWellKnownStringComparers() + { + Type nonRandomizedOrdinalComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.NonRandomizedStringEqualityComparer+OrdinalComparer", throwOnError: true); + Type nonRandomizedOrdinalIgnoreCaseComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.NonRandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer", throwOnError: true); + Type randomizedOrdinalComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.RandomizedStringEqualityComparer+OrdinalComparer", throwOnError: true); + Type randomizedOrdinalIgnoreCaseComparerType = typeof(object).Assembly.GetType("System.Collections.Generic.RandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer", throwOnError: true); + + // null comparer + + RunHashSetTest( + equalityComparer: null, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: EqualityComparer.Default.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // EqualityComparer.Default comparer + + RunHashSetTest( + equalityComparer: EqualityComparer.Default, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: EqualityComparer.Default.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // Ordinal comparer + + RunHashSetTest( + equalityComparer: StringComparer.Ordinal, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalComparerType, + expectedPublicComparerBeforeCollisionThreshold: StringComparer.Ordinal.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalComparerType); + + // OrdinalIgnoreCase comparer + + RunHashSetTest( + equalityComparer: StringComparer.OrdinalIgnoreCase, + expectedInternalComparerBeforeCollisionThreshold: nonRandomizedOrdinalIgnoreCaseComparerType, + expectedPublicComparerBeforeCollisionThreshold: StringComparer.OrdinalIgnoreCase.GetType(), + expectedComparerAfterCollisionThreshold: randomizedOrdinalIgnoreCaseComparerType); + + // linguistic comparer (not optimized) + + RunHashSetTest( + equalityComparer: StringComparer.InvariantCulture, + expectedInternalComparerBeforeCollisionThreshold: StringComparer.InvariantCulture.GetType(), + expectedPublicComparerBeforeCollisionThreshold: StringComparer.InvariantCulture.GetType(), + expectedComparerAfterCollisionThreshold: StringComparer.InvariantCulture.GetType()); + + static void RunHashSetTest( + IEqualityComparer equalityComparer, + Type expectedInternalComparerBeforeCollisionThreshold, + Type expectedPublicComparerBeforeCollisionThreshold, + Type expectedComparerAfterCollisionThreshold) + { + RunCollectionTestCommon( + () => new HashSet(equalityComparer), + (set, key) => Assert.True(set.Add(key)), + (set, key) => set.Contains(key), + set => set.Comparer, + expectedInternalComparerBeforeCollisionThreshold, + expectedPublicComparerBeforeCollisionThreshold, + expectedComparerAfterCollisionThreshold); + } + } + + private static void RunCollectionTestCommon( + Func collectionFactory, + Action addKeyCallback, + Func containsKeyCallback, + Func> getComparerCallback, + Type expectedInternalComparerBeforeCollisionThreshold, + Type expectedPublicComparerBeforeCollisionThreshold, + Type expectedComparerAfterCollisionThreshold) + { + TCollection collection = collectionFactory(); + List allKeys = new List(); + + const int StartOfRange = 0xE020; // use the Unicode Private Use range to avoid accidentally creating strings that really do compare as equal OrdinalIgnoreCase + const int Stride = 0x40; // to ensure we don't accidentally reset the 0x20 bit of the seed, which is used to negate OrdinalIgnoreCase effects + + // First, go right up to the collision threshold, but don't exceed it. + + for (int i = 0; i < 100; i++) + { + string newKey = GenerateCollidingString(i * Stride + StartOfRange); + Assert.Equal(0, _lazyGetNonRandomizedHashCodeDel.Value(newKey)); // ensure has a zero hash code Ordinal + Assert.Equal(0x24716ca0, _lazyGetNonRandomizedOrdinalIgnoreCaseHashCodeDel.Value(newKey)); // ensure has a zero hash code OrdinalIgnoreCase + + addKeyCallback(collection, newKey); + allKeys.Add(newKey); + } + + FieldInfo internalComparerField = collection.GetType().GetField("_comparer", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull(internalComparerField); + + Assert.Equal(expectedInternalComparerBeforeCollisionThreshold, internalComparerField.GetValue(collection)?.GetType()); + Assert.Equal(expectedPublicComparerBeforeCollisionThreshold, getComparerCallback(collection).GetType()); + + // Now exceed the collision threshold, which should rebucket entries. + // Continue adding a few more entries to ensure we didn't corrupt internal state. + + for (int i = 100; i < 110; i++) + { + string newKey = GenerateCollidingString(i * Stride + StartOfRange); + Assert.Equal(0, _lazyGetNonRandomizedHashCodeDel.Value(newKey)); // ensure has a zero hash code Ordinal + Assert.Equal(0x24716ca0, _lazyGetNonRandomizedOrdinalIgnoreCaseHashCodeDel.Value(newKey)); // ensure has a zero hash code OrdinalIgnoreCase + + addKeyCallback(collection, newKey); + allKeys.Add(newKey); + } + + Assert.Equal(expectedComparerAfterCollisionThreshold, internalComparerField.GetValue(collection)?.GetType()); + Assert.Equal(expectedPublicComparerBeforeCollisionThreshold, getComparerCallback(collection).GetType()); // shouldn't change this return value after collision threshold met + + // And validate that all strings are present in the dictionary. + + foreach (string key in allKeys) + { + Assert.True(containsKeyCallback(collection, key)); + } + + // Also make sure we didn't accidentally put the internal comparer in the serialized object data. + + collection = collectionFactory(); + SerializationInfo si = new SerializationInfo(collection.GetType(), new FormatterConverter()); + ((ISerializable)collection).GetObjectData(si, new StreamingContext()); + + object serializedComparer = si.GetValue("Comparer", typeof(IEqualityComparer)); + Assert.Equal(expectedPublicComparerBeforeCollisionThreshold, serializedComparer.GetType()); + } + + private static Lazy> _lazyGetNonRandomizedHashCodeDel = new Lazy>( + () => GetStringHashCodeOpenDelegate("GetNonRandomizedHashCode")); + + private static Lazy> _lazyGetNonRandomizedOrdinalIgnoreCaseHashCodeDel = new Lazy>( + () => GetStringHashCodeOpenDelegate("GetNonRandomizedHashCodeOrdinalIgnoreCase")); + + // Generates a string with a well-known non-randomized hash code: + // - string.GetNonRandomizedHashCode returns 0. + // - string.GetNonRandomizedHashCodeOrdinalIgnoreCase returns 0x24716ca0. + // Provide a different seed to produce a different string. + private static string GenerateCollidingString(int seed) + { + return string.Create(8, seed, (span, seed) => + { + Span asBytes = MemoryMarshal.AsBytes(span); + + uint hash1 = (5381 << 16) + 5381; + uint hash2 = BitOperations.RotateLeft(hash1, 5) + hash1; + + MemoryMarshal.Write(asBytes, ref seed); + MemoryMarshal.Write(asBytes.Slice(4), ref hash2); // set hash2 := 0 (for Ordinal) + + hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (uint)seed; + hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1); + + MemoryMarshal.Write(asBytes.Slice(8), ref hash1); // set hash1 := 0 (for Ordinal) + }); + } + + private static Func GetStringHashCodeOpenDelegate(string methodName) + { + MethodInfo method = typeof(string).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); + Assert.NotNull(method); + + return method.CreateDelegate>(target: null); // create open delegate unbound to 'this' + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 1715d433f8d0..4278e25e67dc 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -169,6 +169,7 @@ + @@ -179,6 +180,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index ac4fd58338df..6c5682e613b6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -59,10 +59,24 @@ public Dictionary(int capacity, IEqualityComparer? comparer) _comparer = comparer; } - if (typeof(TKey) == typeof(string) && _comparer == null) + // Special-case EqualityComparer.Default, StringComparer.Ordinal, and StringComparer.OrdinalIgnoreCase. + // We use a non-randomized comparer for improved perf, falling back to a randomized comparer if the + // hash buckets become unbalanced. + + if (typeof(TKey) == typeof(string)) { - // To start, move off default comparer for string which is randomised - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.Default; + if (_comparer is null) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundDefaultComparer; + } + else if (ReferenceEquals(_comparer, StringComparer.Ordinal)) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinal; + } + else if (ReferenceEquals(_comparer, StringComparer.OrdinalIgnoreCase)) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinalIgnoreCase; + } } } @@ -125,10 +139,20 @@ protected Dictionary(SerializationInfo info, StreamingContext context) HashHelpers.SerializationInfoTable.Add(this, info); } - public IEqualityComparer Comparer => - (_comparer == null || _comparer is NonRandomizedStringEqualityComparer) ? - EqualityComparer.Default : - _comparer; + public IEqualityComparer Comparer + { + get + { + if (typeof(TKey) == typeof(string)) + { + return (IEqualityComparer)IInternalStringEqualityComparer.GetUnderlyingEqualityComparer((IEqualityComparer?)_comparer); + } + else + { + return _comparer ?? EqualityComparer.Default; + } + } + } public int Count => _count - _freeCount; @@ -299,7 +323,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte } info.AddValue(VersionName, _version); - info.AddValue(ComparerName, _comparer ?? EqualityComparer.Default, typeof(IEqualityComparer)); + info.AddValue(ComparerName, Comparer, typeof(IEqualityComparer)); info.AddValue(HashSizeName, _buckets == null ? 0 : _buckets.Length); // This is the length of the bucket array if (_buckets != null) @@ -633,7 +657,6 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior) { // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing // i.e. EqualityComparer.Default. - _comparer = null; Resize(entries.Length, true); } @@ -702,14 +725,21 @@ private void Resize(int newSize, bool forceNewHashCodes) if (!typeof(TKey).IsValueType && forceNewHashCodes) { + Debug.Assert(_comparer is NonRandomizedStringEqualityComparer); + _comparer = (IEqualityComparer)((NonRandomizedStringEqualityComparer)_comparer).GetRandomizedEqualityComparer(); + for (int i = 0; i < count; i++) { if (entries[i].next >= -1) { - Debug.Assert(_comparer == null); - entries[i].hashCode = (uint)entries[i].key.GetHashCode(); + entries[i].hashCode = (uint)_comparer.GetHashCode(entries[i].key); } } + + if (ReferenceEquals(_comparer, EqualityComparer.Default)) + { + _comparer = null; + } } // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs index f86c16fb8e71..394b0ff6fa62 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs @@ -60,10 +60,24 @@ public HashSet(IEqualityComparer? comparer) _comparer = comparer; } - if (typeof(T) == typeof(string) && _comparer == null) + // Special-case EqualityComparer.Default, StringComparer.Ordinal, and StringComparer.OrdinalIgnoreCase. + // We use a non-randomized comparer for improved perf, falling back to a randomized comparer if the + // hash buckets become unbalanced. + + if (typeof(T) == typeof(string)) { - // To start, move off default comparer for string which is randomized. - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.Default; + if (_comparer is null) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundDefaultComparer; + } + else if (ReferenceEquals(_comparer, StringComparer.Ordinal)) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinal; + } + else if (ReferenceEquals(_comparer, StringComparer.OrdinalIgnoreCase)) + { + _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinalIgnoreCase; + } } } @@ -380,7 +394,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte } info.AddValue(VersionName, _version); // need to serialize version to avoid problems with serializing while enumerating - info.AddValue(ComparerName, _comparer ?? EqualityComparer.Default, typeof(IEqualityComparer)); + info.AddValue(ComparerName, Comparer, typeof(IEqualityComparer)); info.AddValue(CapacityName, _buckets == null ? 0 : _buckets.Length); if (_buckets != null) @@ -912,10 +926,20 @@ public int RemoveWhere(Predicate match) } /// Gets the object that is used to determine equality for the values in the set. - public IEqualityComparer Comparer => - (_comparer == null || _comparer is NonRandomizedStringEqualityComparer) ? - EqualityComparer.Default : - _comparer; + public IEqualityComparer Comparer + { + get + { + if (typeof(T) == typeof(string)) + { + return (IEqualityComparer)IInternalStringEqualityComparer.GetUnderlyingEqualityComparer((IEqualityComparer?)_comparer); + } + else + { + return _comparer ?? EqualityComparer.Default; + } + } + } /// Ensures that this hash set can hold the specified number of elements without growing. public int EnsureCapacity(int capacity) @@ -957,15 +981,22 @@ private void Resize(int newSize, bool forceNewHashCodes) if (!typeof(T).IsValueType && forceNewHashCodes) { + Debug.Assert(_comparer is NonRandomizedStringEqualityComparer); + _comparer = (IEqualityComparer)((NonRandomizedStringEqualityComparer)_comparer).GetRandomizedEqualityComparer(); + for (int i = 0; i < count; i++) { ref Entry entry = ref entries[i]; if (entry.Next >= -1) { - Debug.Assert(_comparer == null); - entry.HashCode = entry.Value != null ? entry.Value!.GetHashCode() : 0; + entry.HashCode = entry.Value != null ? _comparer!.GetHashCode(entry.Value) : 0; } } + + if (ReferenceEquals(_comparer, EqualityComparer.Default)) + { + _comparer = null; + } } // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails @@ -1185,7 +1216,6 @@ private bool AddIfNotPresent(T value, out int location) { // If we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing // i.e. EqualityComparer.Default. - _comparer = null; Resize(entries.Length, forceNewHashCodes: true); location = FindItemIndex(value); Debug.Assert(location >= 0); diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IInternalStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IInternalStringEqualityComparer.cs new file mode 100644 index 000000000000..28c2ab9a07c9 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IInternalStringEqualityComparer.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Collections.Generic +{ + /// + /// Represents an that's meant for internal + /// use only and isn't intended to be serialized or returned back to the user. + /// Use the method to get the object + /// that should actually be returned to the caller. + /// + internal interface IInternalStringEqualityComparer : IEqualityComparer + { + IEqualityComparer GetUnderlyingEqualityComparer(); + + /// + /// Unwraps the internal equality comparer, if proxied. + /// Otherwise returns the equality comparer itself or its default equivalent. + /// + internal static IEqualityComparer GetUnderlyingEqualityComparer(IEqualityComparer? outerComparer) + { + if (outerComparer is null) + { + return EqualityComparer.Default; + } + else if (outerComparer is IInternalStringEqualityComparer internalComparer) + { + return internalComparer.GetUnderlyingEqualityComparer(); + } + else + { + return outerComparer; + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs index b75ebd52e38b..0ec1a501d56f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs @@ -1,7 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; +using System.Globalization; using System.Runtime.Serialization; +using Internal.Runtime.CompilerServices; namespace System.Collections.Generic { @@ -11,23 +14,100 @@ namespace System.Collections.Generic // randomized string hashing. [Serializable] // Required for compatibility with .NET Core 2.0 as we exposed the NonRandomizedStringEqualityComparer inside the serialization blob // Needs to be public to support binary serialization compatibility - public sealed class NonRandomizedStringEqualityComparer : EqualityComparer, ISerializable + public class NonRandomizedStringEqualityComparer : IEqualityComparer, IInternalStringEqualityComparer, ISerializable { - internal static new IEqualityComparer Default { get; } = new NonRandomizedStringEqualityComparer(); + // Dictionary<...>.Comparer and similar methods need to return the original IEqualityComparer + // that was passed in to the ctor. The caller chooses one of these singletons so that the + // GetUnderlyingEqualityComparer method can return the correct value. - private NonRandomizedStringEqualityComparer() { } + internal static readonly NonRandomizedStringEqualityComparer WrappedAroundDefaultComparer = new OrdinalComparer(EqualityComparer.Default); + internal static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinal = new OrdinalComparer(StringComparer.Ordinal); + internal static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinalIgnoreCase = new OrdinalIgnoreCaseComparer(StringComparer.OrdinalIgnoreCase); + + private readonly IEqualityComparer _underlyingComparer; + + private NonRandomizedStringEqualityComparer(IEqualityComparer underlyingComparer) + { + Debug.Assert(underlyingComparer != null); + _underlyingComparer = underlyingComparer; + } // This is used by the serialization engine. - private NonRandomizedStringEqualityComparer(SerializationInfo information, StreamingContext context) { } + protected NonRandomizedStringEqualityComparer(SerializationInfo information, StreamingContext context) + : this(EqualityComparer.Default) + { + } + + public virtual bool Equals(string? x, string? y) + { + // This instance may have been deserialized into a class that doesn't guarantee + // these parameters are non-null. Can't short-circuit the null checks. + + return string.Equals(x, y); + } + + public virtual int GetHashCode(string? obj) + { + // This instance may have been deserialized into a class that doesn't guarantee + // these parameters are non-null. Can't short-circuit the null checks. + + return obj?.GetNonRandomizedHashCode() ?? 0; + } - public sealed override bool Equals(string? x, string? y) => string.Equals(x, y); + internal virtual RandomizedStringEqualityComparer GetRandomizedEqualityComparer() + { + return RandomizedStringEqualityComparer.Create(_underlyingComparer, ignoreCase: false); + } - public sealed override int GetHashCode(string? obj) => obj?.GetNonRandomizedHashCode() ?? 0; + // Gets the comparer that should be returned back to the caller when querying the + // ICollection.Comparer property. Also used for serialization purposes. + public virtual IEqualityComparer GetUnderlyingEqualityComparer() => _underlyingComparer; - public void GetObjectData(SerializationInfo info, StreamingContext context) + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { // We are doing this to stay compatible with .NET Framework. + // Our own collection types will never call this (since this type is a wrapper), + // but perhaps third-party collection types could try serializing an instance + // of this. info.SetType(typeof(GenericEqualityComparer)); } + + private sealed class OrdinalComparer : NonRandomizedStringEqualityComparer + { + internal OrdinalComparer(IEqualityComparer wrappedComparer) + : base(wrappedComparer) + { + } + + public override bool Equals(string? x, string? y) => string.Equals(x, y); + + public override int GetHashCode(string? obj) + { + Debug.Assert(obj != null, "This implementation is only called from first-party collection types that guarantee non-null parameters."); + return obj.GetNonRandomizedHashCode(); + } + + } + + private sealed class OrdinalIgnoreCaseComparer : NonRandomizedStringEqualityComparer + { + internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) + : base(wrappedComparer) + { + } + + public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + + public override int GetHashCode(string? obj) + { + Debug.Assert(obj != null, "This implementation is only called from first-party collection types that guarantee non-null parameters."); + return obj.GetNonRandomizedHashCodeOrdinalIgnoreCase(); + } + + internal override RandomizedStringEqualityComparer GetRandomizedEqualityComparer() + { + return RandomizedStringEqualityComparer.Create(_underlyingComparer, ignoreCase: true); + } + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs new file mode 100644 index 000000000000..168959d83386 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Runtime.CompilerServices; + +namespace System.Collections.Generic +{ + /// + /// A randomized which uses a different seed on each + /// construction as a general good hygiene + defense-in-depth mechanism. This implementation + /// *does not* need to stay in sync with , which for stability + /// is required to use an app-global seed. + /// + internal abstract class RandomizedStringEqualityComparer : EqualityComparer, IInternalStringEqualityComparer + { + private readonly MarvinSeed _seed; + private readonly IEqualityComparer _underlyingComparer; + + private unsafe RandomizedStringEqualityComparer(IEqualityComparer underlyingComparer) + { + _underlyingComparer = underlyingComparer; + + fixed (MarvinSeed* seed = &_seed) + { + Interop.GetRandomBytes((byte*)seed, sizeof(MarvinSeed)); + } + } + + internal static RandomizedStringEqualityComparer Create(IEqualityComparer underlyingComparer, bool ignoreCase) + { + if (!ignoreCase) + { + return new OrdinalComparer(underlyingComparer); + } + else + { + return new OrdinalIgnoreCaseComparer(underlyingComparer); + } + } + + public IEqualityComparer GetUnderlyingEqualityComparer() => _underlyingComparer; + + private struct MarvinSeed + { + internal uint p0; + internal uint p1; + } + + private sealed class OrdinalComparer : RandomizedStringEqualityComparer + { + internal OrdinalComparer(IEqualityComparer wrappedComparer) + : base(wrappedComparer) + { + } + + public override bool Equals(string? x, string? y) => string.Equals(x, y); + + public override int GetHashCode(string? obj) + { + if (obj is null) + { + return 0; + } + + // The Ordinal version of Marvin32 operates over bytes. + // The multiplication from # chars -> # bytes will never integer overflow. + return Marvin.ComputeHash32( + ref Unsafe.As(ref obj.GetRawStringData()), + (uint)obj.Length * 2, + _seed.p0, _seed.p1); + } + } + + private sealed class OrdinalIgnoreCaseComparer : RandomizedStringEqualityComparer + { + internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) + : base(wrappedComparer) + { + } + + public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + + public override int GetHashCode(string? obj) + { + if (obj is null) + { + return 0; + } + + // The Ordinal version of Marvin32 operates over bytes, so convert + // char count -> byte count. Guaranteed not to integer overflow. + return Marvin.ComputeHash32( + ref Unsafe.As(ref obj.GetRawStringData()), + (uint)obj.Length * sizeof(char), + _seed.p0, _seed.p1); + } + } + + private sealed class RandomizedOrdinalIgnoreCaseComparer : RandomizedStringEqualityComparer + { + internal RandomizedOrdinalIgnoreCaseComparer(IEqualityComparer underlyingComparer) + : base(underlyingComparer) + { + } + + public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + + public override int GetHashCode(string? obj) + { + if (obj is null) + { + return 0; + } + + // The OrdinalIgnoreCase version of Marvin32 operates over chars, + // so pass in the char count directly. + return Marvin.ComputeHash32OrdinalIgnoreCase( + ref obj.GetRawStringData(), + obj.Length, + _seed.p0, _seed.p1); + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index d93701185fa6..40f63176236c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs @@ -42,7 +42,27 @@ private static int CompareOrdinalHelper(string strA, int indexA, int countA, str return SpanHelpers.SequenceCompareTo(ref Unsafe.Add(ref strA.GetRawStringData(), indexA), countA, ref Unsafe.Add(ref strB.GetRawStringData(), indexB), countB); } - private static bool EqualsOrdinalIgnoreCase(string strA, string strB) + internal static bool EqualsOrdinalIgnoreCase(string? strA, string? strB) + { + if (ReferenceEquals(strA, strB)) + { + return true; + } + + if (strA is null || strB is null) + { + return false; + } + + if (strA.Length != strB.Length) + { + return false; + } + + return EqualsOrdinalIgnoreCaseNoLengthCheck(strA, strB); + } + + private static bool EqualsOrdinalIgnoreCaseNoLengthCheck(string strA, string strB) { Debug.Assert(strA.Length == strB.Length); @@ -645,7 +665,7 @@ public bool Equals(string? value, StringComparison comparisonType) if (this.Length != value.Length) return false; - return EqualsOrdinalIgnoreCase(this, value); + return EqualsOrdinalIgnoreCaseNoLengthCheck(this, value); default: throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); @@ -701,7 +721,7 @@ public static bool Equals(string? a, string? b, StringComparison comparisonType) if (a.Length != b.Length) return false; - return EqualsOrdinalIgnoreCase(a, b); + return EqualsOrdinalIgnoreCaseNoLengthCheck(a, b); default: throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); @@ -811,6 +831,46 @@ internal unsafe int GetNonRandomizedHashCode() } } + // Use this if and only if 'Denial of Service' attacks are not a concern (i.e. never used for free-form user input), + // or are otherwise mitigated + internal unsafe int GetNonRandomizedHashCodeOrdinalIgnoreCase() + { + fixed (char* src = &_firstChar) + { + Debug.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'"); + Debug.Assert(((int)src) % 4 == 0, "Managed string should start at 4 bytes boundary"); + + uint hash1 = (5381 << 16) + 5381; + uint hash2 = hash1; + + uint* ptr = (uint*)src; + int length = this.Length; + + // We "normalize to lowercase" every char by ORing with 0x0020. This casts + // a very wide net because it will change, e.g., '^' to '~'. But that should + // be ok because we expect this to be very rare in practice. + + const uint NormalizeToLowercase = 0x0020_0020u; // valid both for big-endian and for little-endian + + while (length > 2) + { + length -= 4; + // Where length is 4n-1 (e.g. 3,7,11,15,19) this additionally consumes the null terminator + hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (ptr[0] | NormalizeToLowercase); + hash2 = (BitOperations.RotateLeft(hash2, 5) + hash2) ^ (ptr[1] | NormalizeToLowercase); + ptr += 2; + } + + if (length > 0) + { + // Where length is 4n-3 (e.g. 1,5,9,13,17) this additionally consumes the null terminator + hash2 = (BitOperations.RotateLeft(hash2, 5) + hash2) ^ (ptr[0] | NormalizeToLowercase); + } + + return (int)(hash1 + (hash2 * 1566083941)); + } + } + // Determines whether a specified string is a prefix of the current instance // public bool StartsWith(string value) diff --git a/src/libraries/System.Private.CoreLib/src/System/StringComparer.cs b/src/libraries/System.Private.CoreLib/src/System/StringComparer.cs index e935c3d33163..39791cf55a61 100644 --- a/src/libraries/System.Private.CoreLib/src/System/StringComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/StringComparer.cs @@ -12,14 +12,9 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class StringComparer : IComparer, IEqualityComparer, IComparer, IEqualityComparer { - private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.None); - private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.IgnoreCase); - private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer(); - private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer(); + public static StringComparer InvariantCulture => CultureAwareComparer.InvariantCaseSensitiveInstance; - public static StringComparer InvariantCulture => s_invariantCulture; - - public static StringComparer InvariantCultureIgnoreCase => s_invariantCultureIgnoreCase; + public static StringComparer InvariantCultureIgnoreCase => CultureAwareComparer.InvariantIgnoreCaseInstance; public static StringComparer CurrentCulture => new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.None); @@ -27,9 +22,9 @@ public abstract class StringComparer : IComparer, IEqualityComparer, IComparer new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.IgnoreCase); - public static StringComparer Ordinal => s_ordinal; + public static StringComparer Ordinal => OrdinalCaseSensitiveComparer.Instance; - public static StringComparer OrdinalIgnoreCase => s_ordinalIgnoreCase; + public static StringComparer OrdinalIgnoreCase => OrdinalIgnoreCaseComparer.Instance; // Convert a StringComparison to a StringComparer public static StringComparer FromComparison(StringComparison comparisonType) @@ -128,6 +123,9 @@ public int GetHashCode(object obj) [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class CultureAwareComparer : StringComparer, ISerializable { + internal static readonly CultureAwareComparer InvariantCaseSensitiveInstance = new CultureAwareComparer(CompareInfo.Invariant, CompareOptions.None); + internal static readonly CultureAwareComparer InvariantIgnoreCaseInstance = new CultureAwareComparer(CompareInfo.Invariant, CompareOptions.IgnoreCase); + private const CompareOptions ValidCompareMaskOffFlags = ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort); private readonly CompareInfo _compareInfo; // Do not rename (binary serialization) @@ -286,7 +284,9 @@ public override int GetHashCode() [Serializable] internal sealed class OrdinalCaseSensitiveComparer : OrdinalComparer, ISerializable { - public OrdinalCaseSensitiveComparer() : base(false) + internal static readonly OrdinalCaseSensitiveComparer Instance = new OrdinalCaseSensitiveComparer(); + + private OrdinalCaseSensitiveComparer() : base(false) { } @@ -313,7 +313,9 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) [Serializable] internal sealed class OrdinalIgnoreCaseComparer : OrdinalComparer, ISerializable { - public OrdinalIgnoreCaseComparer() : base(true) + internal static readonly OrdinalIgnoreCaseComparer Instance = new OrdinalIgnoreCaseComparer(); + + private OrdinalIgnoreCaseComparer() : base(true) { } diff --git a/src/libraries/System.Resources.Extensions/tests/TestData.resources b/src/libraries/System.Resources.Extensions/tests/TestData.resources index b2f4b4cd1928883e15073f7033e78217b6800728..b6006779769ebd20430d4c0cbd6515d76cbd2bb4 100644 GIT binary patch delta 710 zcmcIh&ubH55PjQbH(z$YO*dJZ+PLJ0f`=kXdJw!QTIfZsE$Bg!hFG^z8&gTLLJNxi z2jcu29u!aNL8uoGy@(1zE}nX8J$O)iiElR%#FG~fJM6soX1+HwKThwRde*l6cPT*M zz&avaM++fdDS2d9r`{^S3(+Qi2X%6{_`j{>rCl{L(zlD=d zsd&z0`7?n7T{hcf_55GW`&vAA+T5Y0Buj2-Y*)*Id))t)2aOVE zJ*4H0TkEvtnHB$a6DzlKbfMl!%dx$v_p5sJQhZo;KxS{+zKd+xexFX@aS> vaHD4N(y;C|T2WXtz7Gb2eSTJ46w|X7k1(QVoioP&bv5(vu3kKt+El*)LO!4n delta 734 zcmcgpO=}ZT6g`tCwyL|%WdJuoTkz{>3U^KN3mLw&sv5awjkvExVO^1)d9={OTk3Yj zc_*L|NqhLnnqAaBu`Y3gv-a5Vx&@e#zKt2Yw}FvC!ItTXa@F3iedQPXp!S0$$2Zar zP+8!lDr--8(J3B2r2xMpCNInUCb|+kv9TGP70T+0&qV!&BO~tx8kndbrP5s^mTt$O_}vinf2m4OQ9sSU@L~J$~7G%5rv(w#*aRwZw|aoVQAMNaw!% zw4OxLe8A^=k3NdVEwq$H%G>C) zax1@^FZ{xU5jD*Qi!~!HnQ@~v7X~$LQ*@EmkUx#-aYH_EK#$wUwg2aE?B5-(eDjyg EpS^LpWB>pF From 370aba46e74102cfbaf269d7bd6733e22b8c9afe Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 6 Aug 2020 07:58:39 +0300 Subject: [PATCH 287/755] Fix Docker cross-build command (#40433) --- docs/workflow/requirements/freebsd-requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/workflow/requirements/freebsd-requirements.md b/docs/workflow/requirements/freebsd-requirements.md index 59b3c64d928f..66e50ec878b3 100644 --- a/docs/workflow/requirements/freebsd-requirements.md +++ b/docs/workflow/requirements/freebsd-requirements.md @@ -21,7 +21,7 @@ with all needed prerequisites to build. As the example bellow may become stale, ```sh TAG=mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-11-20200430154008-a84b0d2 -docker run --rm --volume $(pwd):$(pwd) --workdir $(pwd) --env ROOTFS_DIR=/crossrootfs/x64 -ti $TAG ./build.sh -cross -FreeBSD +docker run --rm --volume $(pwd):$(pwd) --workdir $(pwd) --env ROOTFS_DIR=/crossrootfs/x64 -ti $TAG ./build.sh -cross -os FreeBSD ``` Build using Toolchain Setup From 0f7370baa68c5809f93095cbce9bf614f44cc731 Mon Sep 17 00:00:00 2001 From: SUN Guoyun <40024232+sunny868@users.noreply.github.com> Date: Thu, 6 Aug 2020 13:06:02 +0800 Subject: [PATCH 288/755] Define SIGSTOP for architecture mips (#40299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit define SIGSTOP 19 is just ok for architecture x86、arm、s390、powerpc and so on. but others architecture has different values. Co-Authored-By: hev --- src/libraries/Native/Unix/CMakeLists.txt | 3 +++ .../Native/Unix/System.Native/pal_process.c | 18 ++++++++++++++++-- .../Native/Unix/System.Native/pal_process.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 3168c7e55c83..a4f8970239d1 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -64,6 +64,9 @@ elseif (CLR_CMAKE_TARGET_ARCH_WASM) elseif (CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DTARGET_64BIT=1) add_definitions(-DTARGET_ARM64) +elseif (CLR_CMAKE_TARGET_ARCH_MIPS64) + add_definitions(-DTARGET_64BIT=1) + add_definitions(-DTARGET_MIPS64) elseif (CLR_CMAKE_TARGET_ARCH_ARM) add_definitions(-DTARGET_32BIT=1) add_definitions(-DTARGET_ARM) diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index 6d86efe48190..a1559e85f996 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -28,8 +28,6 @@ #include #endif -// Validate that our Signals enum values are correct for the platform -c_static_assert(PAL_SIGKILL == SIGKILL); // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); @@ -653,6 +651,22 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit int32_t SystemNative_Kill(int32_t pid, int32_t signal) { + switch (signal) + { + case PAL_SIGKILL: + signal = SIGKILL; + break; + + case PAL_SIGSTOP: + signal = SIGSTOP; + break; + + default: + assert_msg(false, "Unknown signal",signal); + errno = EINVAL; + return -1; + } + return kill(pid, signal); } diff --git a/src/libraries/Native/Unix/System.Native/pal_process.h b/src/libraries/Native/Unix/System.Native/pal_process.h index 92eaf66e1dbc..6c79cef0857c 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.h +++ b/src/libraries/Native/Unix/System.Native/pal_process.h @@ -73,6 +73,7 @@ typedef enum typedef enum { PAL_SIGKILL = 9, /* kill the specified process */ + PAL_SIGSTOP = 19, } Signals; /** From 8f6a77a8f6bdbee005aefc4576069130676c914f Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Thu, 6 Aug 2020 09:42:59 +0200 Subject: [PATCH 289/755] Remove EventSourceAttribute usages when EventSource feature is disabled (#40329) --- .../ILLink/ILLink.LinkAttributes.Shared.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml index 1fc80202571c..8df05e609708 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml @@ -30,4 +30,25 @@ + + + + + + + + + + + + + + + + + + + + + From a778b7e09722c45891ab66f0cd38785d3156c839 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Thu, 6 Aug 2020 00:57:33 -0700 Subject: [PATCH 290/755] Check more patterns for retBuffer. (#40340) * Check more patterns for retBuffer. We force return buffers containing GC pointers to be on the stack and before we make a copy we check if the return buffer is already on the stack. Fix the check by adding `LCL_VAR_ADDR`, `ADD(LCL_VAR_ADDR, CNST)` patterns. * Clear `EnableExtraSuperPmiQueries` during SPMI replay. It is set during collection for easier test of struct promotion enhancements but it could let to chk/rel diffs if used during replay. --- src/coreclr/scripts/superpmi.py | 10 +++++++--- src/coreclr/src/jit/morph.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py index 377af07e0a9d..12be260c67a9 100755 --- a/src/coreclr/scripts/superpmi.py +++ b/src/coreclr/scripts/superpmi.py @@ -860,7 +860,8 @@ def replay(self): altjit_string = "*" if self.coreclr_args.altjit else "" altjit_flags = [ "-jitoption", "force", "AltJit=" + altjit_string, - "-jitoption", "force", "AltJitNgen=" + altjit_string + "-jitoption", "force", "AltJitNgen=" + altjit_string, + "-jitoption", "force", "EnableExtraSuperPmiQueries=0" ] flags += altjit_flags @@ -1032,8 +1033,10 @@ def replay_with_asm_diffs(self): altjit_flags = [ "-jitoption", "force", "AltJit=" + altjit_string, "-jitoption", "force", "AltJitNgen=" + altjit_string, + "-jitoption", "force", "EnableExtraSuperPmiQueries=0", "-jit2option", "force", "AltJit=" + altjit_string, - "-jit2option", "force", "AltJitNgen=" + altjit_string + "-jit2option", "force", "AltJitNgen=" + altjit_string, + "-jit2option", "force", "EnableExtraSuperPmiQueries=0" ] flags += altjit_flags @@ -1208,7 +1211,8 @@ def replay_with_asm_diffs(self): altjit_string = "*" if self.coreclr_args.altjit else "" altjit_flags = [ "-jitoption", "force", "AltJit=" + altjit_string, - "-jitoption", "force", "AltJitNgen=" + altjit_string + "-jitoption", "force", "AltJitNgen=" + altjit_string, + "-jitoption", "force", "EnableExtraSuperPmiQueries=0" ] async def create_asm(print_prefix, item, self, text_differences, base_asm_location, diff_asm_location): diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index d5cf8a892395..61ad9937b048 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -8946,7 +8946,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) GenTree* dest = call->gtCallArgs->GetNode(); assert(dest->OperGet() != GT_ARGPLACE); // If it was, we'd be in a remorph, which we've already excluded above. - if (dest->gtType == TYP_BYREF && !(dest->OperGet() == GT_ADDR && dest->AsOp()->gtOp1->OperGet() == GT_LCL_VAR)) + if (dest->TypeIs(TYP_BYREF) && !dest->IsLocalAddrExpr()) { // We'll exempt helper calls from this, assuming that the helper implementation // follows the old convention, and does whatever barrier is required. From ff47b4bb937553eaf92d891e47085aeba663a8d6 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Thu, 6 Aug 2020 12:28:06 +0100 Subject: [PATCH 291/755] [System.Console] Fix manual test (#39460) * do not report '\n' as Ctrl+Enter on unix * add macos instructions * add windows test instructions --- .../src/System/IO/StdInReader.cs | 5 --- .../tests/ManualTests/ManualTests.cs | 42 ++++++++++++++----- .../tests/ManualTests/Readme.md | 17 ++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.Console/src/System/IO/StdInReader.cs b/src/libraries/System.Console/src/System/IO/StdInReader.cs index c60b0fd1f2a5..99ebbd34c614 100644 --- a/src/libraries/System.Console/src/System/IO/StdInReader.cs +++ b/src/libraries/System.Console/src/System/IO/StdInReader.cs @@ -254,11 +254,6 @@ internal ConsoleKey GetKeyFromCharValue(char x, out bool isShift, out bool isCtr case '\r': return ConsoleKey.Enter; - case '\n': - // Windows compatibility; LF is Ctrl+Enter - isCtrl = true; - return ConsoleKey.Enter; - case (char)(0x1B): return ConsoleKey.Escape; diff --git a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs index 4c019a908e21..43688d799eba 100644 --- a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs +++ b/src/libraries/System.Console/tests/ManualTests/ManualTests.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.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -67,17 +69,9 @@ public static void ReadKey() } [ConditionalTheory(nameof(ManualTestsEnabled))] - [InlineData('\x01', ConsoleKey.A, ConsoleModifiers.Control)] - [InlineData('\x01', ConsoleKey.A, ConsoleModifiers.Control | ConsoleModifiers.Alt)] - [InlineData('\r', ConsoleKey.Enter, (ConsoleModifiers)0)] - [InlineData('\n', ConsoleKey.Enter, ConsoleModifiers.Control)] - public static void ReadKey_KeyChords(char keyChar, ConsoleKey key, ConsoleModifiers modifiers) + [MemberData(nameof(GetKeyChords))] + public static void ReadKey_KeyChords(ConsoleKeyInfo expected) { - var expected = new ConsoleKeyInfo(keyChar, key, - control: modifiers.HasFlag(ConsoleModifiers.Control), - alt: modifiers.HasFlag(ConsoleModifiers.Alt), - shift: modifiers.HasFlag(ConsoleModifiers.Shift)); - Console.Write($"Please type key chord {RenderKeyChord(expected)}: "); var actual = Console.ReadKey(intercept: true); Console.WriteLine(); @@ -96,6 +90,34 @@ static string RenderKeyChord(ConsoleKeyInfo key) } } + public static IEnumerable GetKeyChords() + { + yield return MkConsoleKeyInfo('\x01', ConsoleKey.A, ConsoleModifiers.Control); + yield return MkConsoleKeyInfo('\x01', ConsoleKey.A, ConsoleModifiers.Control | ConsoleModifiers.Alt); + yield return MkConsoleKeyInfo('\r', ConsoleKey.Enter, (ConsoleModifiers)0); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // windows will report '\n' as 'Ctrl+Enter', which is typically not picked up by Unix terminals + yield return MkConsoleKeyInfo('\n', ConsoleKey.Enter, ConsoleModifiers.Control); + } + else + { + yield return MkConsoleKeyInfo('\n', ConsoleKey.J, ConsoleModifiers.Control); + } + + static object[] MkConsoleKeyInfo (char keyChar, ConsoleKey consoleKey, ConsoleModifiers modifiers) + { + return new object[] + { + new ConsoleKeyInfo(keyChar, consoleKey, + control: modifiers.HasFlag(ConsoleModifiers.Control), + alt: modifiers.HasFlag(ConsoleModifiers.Alt), + shift: modifiers.HasFlag(ConsoleModifiers.Shift)) + }; + } + } + [ConditionalFact(nameof(ManualTestsEnabled))] public static void OpenStandardInput() { diff --git a/src/libraries/System.Console/tests/ManualTests/Readme.md b/src/libraries/System.Console/tests/ManualTests/Readme.md index 983015f62203..7d77e7fe3e1e 100644 --- a/src/libraries/System.Console/tests/ManualTests/Readme.md +++ b/src/libraries/System.Console/tests/ManualTests/Readme.md @@ -7,3 +7,20 @@ To run the suite, follow these steps: 2. Using a terminal, navigate to the current folder. 3. Enable manual testing by defining the `MANUAL_TESTS` environment variable (e.g. on bash `export MANUAL_TESTS=true`). 4. Run `dotnet test` and follow the instructions in the command prompt. + +## Instructions for Windows testers + +VsTest on Windows redirects console input, so in order to properly execute the manual tests, +`xunit-console` must be invoked directly. To do this first run + +``` +> dotnet build -t:Test +``` + +And then copy and execute the commands logged under the `To repro directly:` section of the output logs. + +## Instructions for MacOS testers + +By default, Alt-Key does not work on the MacOS terminal. +Before running the tests, navigate to `Terminal > Preferences > Settings > Keyboard` +and check "Use option as meta key" at the bottom. From 3f25803a298ba022ddcd10e58839f1bb12ca8511 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Thu, 6 Aug 2020 10:52:46 -0400 Subject: [PATCH 292/755] [wasm] Fix GC support in ves_icall_get_trace (). (#40384) * [wasm] Fix GC support in ves_icall_get_trace (). * Fix a c++-ism. --- src/mono/mono/metadata/handle.h | 2 +- src/mono/mono/mini/mini-exceptions.c | 47 +++++++++++++++++----------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/mono/mono/metadata/handle.h b/src/mono/mono/metadata/handle.h index 6a9ad056deb7..bdffa0fad1c1 100644 --- a/src/mono/mono/metadata/handle.h +++ b/src/mono/mono/metadata/handle.h @@ -517,7 +517,7 @@ TYPED_HANDLE_DECL (MonoException); TYPED_HANDLE_DECL (MonoAppContext); /* Simpler version of MONO_HANDLE_NEW if the handle is not used */ -#define MONO_HANDLE_PIN(object) MONO_HANDLE_NEW (MonoObject, (object)) +#define MONO_HANDLE_PIN(object) MONO_HANDLE_NEW (MonoObject, (MonoObject*)(object)) // Structs cannot be cast to structs. // As well, a function is needed because an anonymous struct cannot be initialized in C. diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index e75267929377..9f88c52baa2a 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -1047,19 +1048,28 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info return res; } + HANDLE_FUNCTION_ENTER (); + + MONO_HANDLE_PIN (ta); + len = mono_array_length_internal (ta) / TRACE_IP_ENTRY_SIZE; res = mono_array_new_checked (domain, mono_defaults.stack_frame_class, len > skip ? len - skip : 0, error); - if (mono_error_set_pending_exception (error)) - return NULL; + if (!is_ok (error)) + goto fail; + + MONO_HANDLE_PIN (res); + + MonoObjectHandle sf_h; + sf_h = MONO_HANDLE_NEW (MonoObject, NULL); for (i = skip; i < len; i++) { MonoJitInfo *ji; MonoStackFrame *sf = (MonoStackFrame *)mono_object_new_checked (domain, mono_defaults.stack_frame_class, error); - if (!is_ok (error)) { - mono_error_set_pending_exception (error); - return NULL; - } + if (!is_ok (error)) + goto fail; + MONO_HANDLE_ASSIGN_RAW (sf_h, sf); + ExceptionTraceIp trace_ip; memcpy (&trace_ip, mono_array_addr_fast (ta, ExceptionTraceIp, i), sizeof (ExceptionTraceIp)); gpointer ip = trace_ip.ip; @@ -1091,18 +1101,14 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info s = mono_method_get_name_full (method, TRUE, FALSE, MONO_TYPE_NAME_FORMAT_REFLECTION); MonoString *name = mono_string_new_checked (domain, s, error); g_free (s); - if (!is_ok (error)) { - mono_error_set_pending_exception (error); - return NULL; - } + if (!is_ok (error)) + goto fail; MONO_OBJECT_SETREF_INTERNAL (sf, internal_method_name, name); } else { MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, NULL, error); - if (!is_ok (error)) { - mono_error_set_pending_exception (error); - return NULL; - } + if (!is_ok (error)) + goto fail; MONO_OBJECT_SETREF_INTERNAL (sf, method, rm); } @@ -1129,10 +1135,8 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info if (need_file_info) { if (location && location->source_file) { MonoString *filename = mono_string_new_checked (domain, location->source_file, error); - if (!is_ok (error)) { - mono_error_set_pending_exception (error); - return NULL; - } + if (!is_ok (error)) + goto fail; MONO_OBJECT_SETREF_INTERNAL (sf, filename, filename); sf->line = location->row; sf->column = location->column; @@ -1145,8 +1149,13 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info mono_debug_free_source_location (location); mono_array_setref_internal (res, i - skip, sf); } + goto exit; - return res; + fail: + mono_error_set_pending_exception (error); + res = NULL; + exit: + HANDLE_FUNCTION_RETURN_VAL (res); } static void From 2f7215e37a1060249ac12531ec2cbaf4db38fa17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Thu, 6 Aug 2020 18:39:42 +0200 Subject: [PATCH 293/755] Fix several typos in bash script generation for Crossgen2 (#40417) --- src/coreclr/tests/src/CLRTest.CrossGen.targets | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/tests/src/CLRTest.CrossGen.targets b/src/coreclr/tests/src/CLRTest.CrossGen.targets index 3fd4b4a530c9..96a8233cb341 100644 --- a/src/coreclr/tests/src/CLRTest.CrossGen.targets +++ b/src/coreclr/tests/src/CLRTest.CrossGen.targets @@ -86,10 +86,10 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then __ResponseFile="$__OutputFile.rsp" rm $__ResponseFile - // Suppress the GC stress COMPlus for the duration of Crossgen2 execution - local gcStressModeToRestore = $COMPlus_GCStress; - local heapVerifyModeToRestore = $COMPlus_HeapVerify; - local readyToRunModeToRestore = $COMPlus_ReadyToRun; + # Suppress the GC stress COMPlus for the duration of Crossgen2 execution + local gcStressModeToRestore=$COMPlus_GCStress; + local heapVerifyModeToRestore=$COMPlus_HeapVerify; + local readyToRunModeToRestore=$COMPlus_ReadyToRun; export COMPlus_GCStress= export COMPlus_HeapVerify= export COMPlus_ReadyToRun= @@ -127,7 +127,7 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then } if [ ! -z ${CompositeBuildMode+x} ]%3B then - ExtraCrossGen2Args+= --composite + ExtraCrossGen2Args+=" --composite" OneFileCrossgen2 "$PWD/composite-r2r.dll" "$PWD/IL/*.dll" else ExtraCrossGen2Args+= -r:$PWD/IL/*.dll From a69d919a62ee358b3d6786170577c92fc56ef988 Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Thu, 6 Aug 2020 10:35:56 -0700 Subject: [PATCH 294/755] Add nodejs and npm install steps (#40474) --- eng/pipelines/coreclr/templates/run-performance-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 0e44fbb7cd28..7b7cf524758a 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -53,7 +53,7 @@ jobs: - IsInternal: '' - HelixApiAccessToken: '' - HelixPreCommandStemWindows: 'py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install --user azure.storage.blob==12.0.0 --force-reinstall;py -3 -m pip install --user azure.storage.queue==12.0.0 --force-reinstall;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get install nodejs;sudo apt-get install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"' - ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"' - HelixPreCommand: '' From c5ca43e49a8c1f762ff0c82078bae701df8ea3d8 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Thu, 6 Aug 2020 13:19:59 -0500 Subject: [PATCH 295/755] Re-enable debug_levels less than zero to indicate debugging without debug logging (#40458) --- src/mono/wasm/runtime/driver.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 971cd5761bfc..3fc1a7e7ecff 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -358,7 +358,7 @@ void mono_initialize_internals () } EMSCRIPTEN_KEEPALIVE void -mono_wasm_load_runtime (const char *unused, int enable_debugging) +mono_wasm_load_runtime (const char *unused, int debug_level) { const char *interp_opts = ""; @@ -386,10 +386,18 @@ mono_wasm_load_runtime (const char *unused, int enable_debugging) #endif #else mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_ONLY); - if (enable_debugging > 0) { + + /* + * debug_level > 0 enables debugging and sets the debug log level to debug_level + * debug_level == 0 disables debugging and enables interpreter optimizations + * debug_level < 0 enabled debugging and disables debug logging. + * + * Note: when debugging is enabled interpreter optimizations are disabled. + */ + if (debug_level) { // Disable optimizations which interfere with debugging interp_opts = "-all"; - mono_wasm_enable_debugging (enable_debugging); + mono_wasm_enable_debugging (debug_level); } #endif From f4179b944eef55ec8f8de40f7de2609df6f6b272 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 6 Aug 2020 19:25:59 +0100 Subject: [PATCH 296/755] Simplify JS interop for Blazor WebAssembly (#40467) --- src/mono/wasm/runtime/dotnet_support.js | 20 ++++++++++++++++++++ src/mono/wasm/runtime/driver.c | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/src/mono/wasm/runtime/dotnet_support.js b/src/mono/wasm/runtime/dotnet_support.js index c1ddc08b902e..2b4a16ec89a3 100644 --- a/src/mono/wasm/runtime/dotnet_support.js +++ b/src/mono/wasm/runtime/dotnet_support.js @@ -29,6 +29,24 @@ var DotNetSupportLib = { return MONO.string_decoder.copy (mono_obj); } }, + + mono_wasm_invoke_js_blazor: function(exceptionMessage, callInfo, arg0, arg1, arg2) { + try { + var blazorExports = DOTNET._dotnet_get_global().Blazor; + if (!blazorExports) { + throw new Error('The blazor.webassembly.js library is not loaded.'); + } + + return blazorExports._internal.invokeJSFromDotNet(callInfo, arg0, arg1, arg2); + } catch (ex) { + var exceptionJsString = ex.message + '\n' + ex.stack; + var exceptionSystemString = mono_string(exceptionJsString); + setValue (exceptionMessage, exceptionSystemString, 'i32'); // *exceptionMessage = exceptionSystemString; + return 0; + } + }, + + // This is for back-compat only and will eventually be removed mono_wasm_invoke_js_marshalled: function(exceptionMessage, asyncHandleLongPtr, functionName, argsJson, treatResultAsVoid) { var mono_string = DOTNET._dotnet_get_global()._mono_string_cached @@ -67,6 +85,8 @@ var DotNetSupportLib = { return 0; } }, + + // This is for back-compat only and will eventually be removed mono_wasm_invoke_js_unmarshalled: function(exceptionMessage, funcName, arg0, arg1, arg2) { try { // Get the function you're trying to invoke diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 3fc1a7e7ecff..8e68329cb6d0 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -24,6 +24,8 @@ void core_initialize_internals (); #endif // Blazor specific custom routines - see dotnet_support.js for backing code +extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *callInfo, void* arg0, void* arg1, void* arg2); +// The following two are for back-compat and will eventually be removed extern void* mono_wasm_invoke_js_marshalled (MonoString **exceptionMessage, void *asyncHandleLongPtr, MonoString *funcName, MonoString *argsJson); extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, MonoString *funcName, void* arg0, void* arg1, void* arg2); @@ -348,6 +350,8 @@ void mono_initialize_internals () // TODO: what happens when two types in different assemblies have the same FQN? // Blazor specific custom routines - see dotnet_support.js for backing code + mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJS", mono_wasm_invoke_js_blazor); + // The following two are for back-compat and will eventually be removed mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSMarshalled", mono_wasm_invoke_js_marshalled); mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSUnmarshalled", mono_wasm_invoke_js_unmarshalled); From 0adf9b52fa4d0118b16088d34e0df4c0e0dafbf7 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 6 Aug 2020 11:35:48 -0700 Subject: [PATCH 297/755] Revert " Define SIGSTOP for architecture mips (#40299)" (#40470) This reverts commit 0f7370baa68c5809f93095cbce9bf614f44cc731. --- src/libraries/Native/Unix/CMakeLists.txt | 3 --- .../Native/Unix/System.Native/pal_process.c | 18 ++---------------- .../Native/Unix/System.Native/pal_process.h | 1 - 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index a4f8970239d1..3168c7e55c83 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -64,9 +64,6 @@ elseif (CLR_CMAKE_TARGET_ARCH_WASM) elseif (CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DTARGET_64BIT=1) add_definitions(-DTARGET_ARM64) -elseif (CLR_CMAKE_TARGET_ARCH_MIPS64) - add_definitions(-DTARGET_64BIT=1) - add_definitions(-DTARGET_MIPS64) elseif (CLR_CMAKE_TARGET_ARCH_ARM) add_definitions(-DTARGET_32BIT=1) add_definitions(-DTARGET_ARM) diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index a1559e85f996..6d86efe48190 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -28,6 +28,8 @@ #include #endif +// Validate that our Signals enum values are correct for the platform +c_static_assert(PAL_SIGKILL == SIGKILL); // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); @@ -651,22 +653,6 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit int32_t SystemNative_Kill(int32_t pid, int32_t signal) { - switch (signal) - { - case PAL_SIGKILL: - signal = SIGKILL; - break; - - case PAL_SIGSTOP: - signal = SIGSTOP; - break; - - default: - assert_msg(false, "Unknown signal",signal); - errno = EINVAL; - return -1; - } - return kill(pid, signal); } diff --git a/src/libraries/Native/Unix/System.Native/pal_process.h b/src/libraries/Native/Unix/System.Native/pal_process.h index 6c79cef0857c..92eaf66e1dbc 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.h +++ b/src/libraries/Native/Unix/System.Native/pal_process.h @@ -73,7 +73,6 @@ typedef enum typedef enum { PAL_SIGKILL = 9, /* kill the specified process */ - PAL_SIGSTOP = 19, } Signals; /** From 89788004d214b64b3e70542e24e3470621766bc2 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 6 Aug 2020 12:01:01 -0700 Subject: [PATCH 298/755] JIT: Properly handle a switch opt case during early flow opts (#40434) Don't try rethreading statement lists if we're doing and early flow opt. Fixes #40195. --- src/coreclr/src/jit/flowgraph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 89ce176fe024..242a4c56791e 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -14704,9 +14704,9 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) LIR::ReadOnlyRange range(zeroConstNode, switchTree); m_pLowering->LowerRange(block, range); } - else + else if (fgStmtListThreaded) { - // Re-link the nodes for this statement. + gtSetStmtInfo(switchStmt); fgSetStmtSeq(switchStmt); } From 2021d54c49da2864d85d4ba5188729365410a228 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Thu, 6 Aug 2020 12:20:25 -0700 Subject: [PATCH 299/755] map TcpListener APM methods to Task-based methods (#40476) Co-authored-by: Geoffrey Kizer --- .../src/System.Net.Sockets.csproj | 4 +-- .../src/System/Net/Sockets/TCPListener.cs | 35 ++++--------------- 2 files changed, 8 insertions(+), 31 deletions(-) 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 3d4d3c791e27..ae0f96d5351e 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -80,6 +80,8 @@ Link="Common\System\Net\SocketAddress.cs" /> + @@ -215,8 +217,6 @@ Link="Common\System\Net\SocketProtocolSupportPal.Unix" /> - + TaskToApm.Begin(AcceptSocketAsync(), callback, state); - public Socket EndAcceptSocket(IAsyncResult asyncResult) - { - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } - - LazyAsyncResult? lazyResult = asyncResult as LazyAsyncResult; - Socket? asyncSocket = lazyResult == null ? null : lazyResult.AsyncObject as Socket; - if (asyncSocket == null) - { - throw new ArgumentException(SR.net_io_invalidasyncresult, nameof(asyncResult)); - } - - // This will throw ObjectDisposedException if Stop() has been called. - return asyncSocket.EndAccept(asyncResult); - } + public Socket EndAcceptSocket(IAsyncResult asyncResult) => + TaskToApm.End(asyncResult); public IAsyncResult BeginAcceptTcpClient(AsyncCallback? callback, object? state) => - BeginAcceptSocket(callback, state); + TaskToApm.Begin(AcceptTcpClientAsync(), callback, state); public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult) => - new TcpClient(EndAcceptSocket(asyncResult)); + TaskToApm.End(asyncResult); public Task AcceptSocketAsync() { From a34177e1ec1f32720daa07e4e88d955cd23c397c Mon Sep 17 00:00:00 2001 From: Cory Nelson Date: Thu, 6 Aug 2020 12:43:49 -0700 Subject: [PATCH 300/755] QUIC and HTTP/3 fixes (#40468) Update/fix MsQuic P/invoke layer. Fix a race condition in MsQuicListener setting MsQuicConnection.Connected. Some MsQuic cleanup. Remove (un-reviewed) HttpVersion.Version30 and SslApplicationProtocol.Http3 APIs. Fix Alt-Svc support. Make Alt-Svc tests timeout properly. --- .../MsQuic/Internal/MsQuicAddressHelpers.cs | 2 +- .../MsQuic/Internal/MsQuicApi.cs | 33 +++- .../MsQuic/Internal/MsQuicSession.cs | 8 +- .../MsQuic/MsQuicConnection.cs | 141 ++++++++---------- .../Implementations/MsQuic/MsQuicListener.cs | 36 +++-- .../Implementations/MsQuic/MsQuicStream.cs | 25 ++-- .../aspnetcore/Quic/Interop/Interop.MsQuic.cs | 4 +- .../aspnetcore/Quic/Interop/MsQuicEnums.cs | 51 +++++-- .../Quic/Interop/MsQuicNativeMethods.cs | 110 +++++++++----- .../System/Net/Http/Http3LoopbackServer.cs | 4 +- .../Net/Http/HttpClientHandlerTestBase.cs | 2 + .../Net/Http/Headers/AltSvcHeaderValue.cs | 28 ++++ .../SocketsHttpHandler/Http2Connection.cs | 2 +- .../SocketsHttpHandler/Http3Connection.cs | 5 + .../SocketsHttpHandler/Http3RequestStream.cs | 9 +- .../Http/SocketsHttpHandler/HttpAuthority.cs | 3 +- .../SocketsHttpHandler/HttpConnectionPool.cs | 6 +- .../HttpConnectionSettings.cs | 2 +- .../HttpClientHandlerTest.AltSvc.cs | 89 +++++++---- .../HttpClientHandlerTest.Http3.cs | 2 +- ...lientHandlerTestBase.SocketsHttpHandler.cs | 2 +- .../HttpClientMiniStressTest.cs | 2 +- .../tests/FunctionalTests/MsQuicTests.cs | 137 ++++++++++------- .../FunctionalTests/SocketsHttpHandlerTest.cs | 12 +- .../ref/System.Net.Primitives.cs | 1 - .../src/System/Net/HttpVersion.cs | 1 - .../ref/System.Net.Security.cs | 1 - .../Net/Security/SslApplicationProtocol.cs | 3 - .../src/System/Net/Security/TlsFrameHelper.cs | 5 - 29 files changed, 438 insertions(+), 288 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs index 38eb74b06acc..a06a08f3b424 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs @@ -11,7 +11,7 @@ internal static class MsQuicAddressHelpers internal const ushort IPv4 = 2; internal const ushort IPv6 = 23; - internal static unsafe IPEndPoint INetToIPEndPoint(SOCKADDR_INET inetAddress) + internal static unsafe IPEndPoint INetToIPEndPoint(ref SOCKADDR_INET inetAddress) { if (inetAddress.si_family == IPv4) { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs index 73c3e551ab4c..5c62f1dbc659 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs @@ -23,7 +23,7 @@ private unsafe MsQuicApi() try { - uint status = Interop.MsQuic.MsQuicOpen(version: 1, out registration); + uint status = Interop.MsQuic.MsQuicOpen(out registration); if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { throw new NotSupportedException(SR.net_quic_notsupported); @@ -123,7 +123,13 @@ private unsafe MsQuicApi() Marshal.GetDelegateForFunctionPointer( nativeRegistration.GetParam); - RegistrationOpenDelegate(Encoding.UTF8.GetBytes("SystemNetQuic"), out IntPtr ctx); + var registrationConfig = new MsQuicNativeMethods.RegistrationConfig + { + AppName = "SystemNetQuic", + ExecutionProfile = QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY + }; + + RegistrationOpenDelegate(ref registrationConfig, out IntPtr ctx); _registrationContext = ctx; } @@ -312,15 +318,26 @@ void SecCfgCreateCallbackHandler( return secConfig; } - public IntPtr SessionOpen(byte[] alpn) + public unsafe IntPtr SessionOpen(byte[] alpn) { IntPtr sessionPtr = IntPtr.Zero; + uint status; - uint status = SessionOpenDelegate( - _registrationContext, - alpn, - IntPtr.Zero, - ref sessionPtr); + fixed (byte* pAlpn = alpn) + { + var alpnBuffer = new MsQuicNativeMethods.QuicBuffer + { + Length = (uint)alpn.Length, + Buffer = pAlpn + }; + + status = SessionOpenDelegate( + _registrationContext, + &alpnBuffer, + 1, + IntPtr.Zero, + ref sessionPtr); + } QuicExceptionHelpers.ThrowIfFailed(status, "Could not open session."); diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs index e35493a7745c..d5f1c11c4bf2 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs @@ -28,7 +28,7 @@ public IntPtr ConnectionOpen(QuicClientConnectionOptions options) QuicExceptionHelpers.ThrowIfFailed(MsQuicApi.Api.ConnectionOpenDelegate( _nativeObjPtr, - MsQuicConnection.NativeCallbackHandler, + MsQuicConnection.s_connectionDelegate, IntPtr.Zero, out IntPtr connectionPtr), "Could not open the connection."); @@ -83,15 +83,15 @@ public void Dispose() public void SetPeerBiDirectionalStreamCount(ushort count) { - SetUshortParamter(QUIC_PARAM_SESSION.PEER_BIDI_STREAM_COUNT, count); + SetUshortParameter(QUIC_PARAM_SESSION.PEER_BIDI_STREAM_COUNT, count); } public void SetPeerUnidirectionalStreamCount(ushort count) { - SetUshortParamter(QUIC_PARAM_SESSION.PEER_UNIDI_STREAM_COUNT, count); + SetUshortParameter(QUIC_PARAM_SESSION.PEER_UNIDI_STREAM_COUNT, count); } - private unsafe void SetUshortParamter(QUIC_PARAM_SESSION param, ushort count) + private unsafe void SetUshortParameter(QUIC_PARAM_SESSION param, ushort count) { var buffer = new MsQuicNativeMethods.QuicBuffer() { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs index 0046c56abb0d..708e15ee2ce4 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. #nullable enable +using System.Diagnostics; using System.IO; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; +using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -16,7 +18,7 @@ namespace System.Net.Quic.Implementations.MsQuic { internal sealed class MsQuicConnection : QuicConnectionProvider { - private MsQuicSession? _session; + private readonly MsQuicSession? _session; // Pointer to the underlying connection // TODO replace all IntPtr with SafeHandles @@ -26,15 +28,17 @@ internal sealed class MsQuicConnection : QuicConnectionProvider private GCHandle _handle; // Delegate that wraps the static function that will be called when receiving an event. - // TODO investigate if the delegate can be static instead. - private ConnectionCallbackDelegate? _connectionDelegate; + internal static readonly ConnectionCallbackDelegate s_connectionDelegate = new ConnectionCallbackDelegate(NativeCallbackHandler); // Endpoint to either connect to or the endpoint already accepted. private IPEndPoint? _localEndPoint; private readonly IPEndPoint _remoteEndPoint; - private readonly ResettableCompletionSource _connectTcs = new ResettableCompletionSource(); - private readonly ResettableCompletionSource _shutdownTcs = new ResettableCompletionSource(); + private SslApplicationProtocol _negotiatedAlpnProtocol; + + // TODO: only allocate these when there is an outstanding connect/shutdown. + private readonly TaskCompletionSource _connectTcs = new TaskCompletionSource(); + private readonly TaskCompletionSource _shutdownTcs = new TaskCompletionSource(); private bool _disposed; private bool _connected; @@ -54,6 +58,7 @@ public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, Int _localEndPoint = localEndPoint; _remoteEndPoint = remoteEndPoint; _ptr = nativeObjPtr; + _connected = true; SetCallbackHandler(); SetIdleTimeout(TimeSpan.FromSeconds(120)); @@ -89,125 +94,96 @@ internal async ValueTask SetSecurityConfigForConnection(X509Certificate cert, st internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint.Address, _remoteEndPoint.Port); - internal override SslApplicationProtocol NegotiatedApplicationProtocol => throw new NotImplementedException(); + internal override SslApplicationProtocol NegotiatedApplicationProtocol => _negotiatedAlpnProtocol; internal override bool Connected => _connected; internal uint HandleEvent(ref ConnectionEvent connectionEvent) { - uint status = MsQuicStatusCodes.Success; try { switch (connectionEvent.Type) { - // Connection is connected, can start to create streams. case QUIC_CONNECTION_EVENT.CONNECTED: - { - status = HandleEventConnected( - connectionEvent); - } - break; - - // Connection is being closed by the transport + return HandleEventConnected(ref connectionEvent); case QUIC_CONNECTION_EVENT.SHUTDOWN_INITIATED_BY_TRANSPORT: - { - status = HandleEventShutdownInitiatedByTransport( - connectionEvent); - } - break; - - // Connection is being closed by the peer + return HandleEventShutdownInitiatedByTransport(ref connectionEvent); case QUIC_CONNECTION_EVENT.SHUTDOWN_INITIATED_BY_PEER: - { - status = HandleEventShutdownInitiatedByPeer( - connectionEvent); - } - break; - - // Connection has been shutdown + return HandleEventShutdownInitiatedByPeer(ref connectionEvent); case QUIC_CONNECTION_EVENT.SHUTDOWN_COMPLETE: - { - status = HandleEventShutdownComplete( - connectionEvent); - } - break; - + return HandleEventShutdownComplete(ref connectionEvent); case QUIC_CONNECTION_EVENT.PEER_STREAM_STARTED: - { - status = HandleEventNewStream( - connectionEvent); - } - break; - + return HandleEventNewStream(ref connectionEvent); case QUIC_CONNECTION_EVENT.STREAMS_AVAILABLE: - { - status = HandleEventStreamsAvailable( - connectionEvent); - } - break; - + return HandleEventStreamsAvailable(ref connectionEvent); default: - break; + return MsQuicStatusCodes.Success; } } - catch (Exception) + catch (Exception ex) { - // TODO we may want to either add a debug assert here or return specific error codes - // based on the exception caught. + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(this, $"Exception occurred during connection callback: {ex.Message}"); + } + + // TODO: trigger an exception on any outstanding async calls. + return MsQuicStatusCodes.InternalError; } - - return status; } - private uint HandleEventConnected(ConnectionEvent connectionEvent) + private uint HandleEventConnected(ref ConnectionEvent connectionEvent) { - SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS); - _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(inetAddress); + if (!_connected) + { + // _connected will already be true for connections accepted from a listener. - _connected = true; - // I don't believe we need to lock here because - // handle event connected will not be called at the same time as - // handle event shutdown initiated by transport - _connectTcs.Complete(MsQuicStatusCodes.Success); + SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS); + _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress); + + SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength); + + _connected = true; + _connectTcs.SetResult(MsQuicStatusCodes.Success); + } return MsQuicStatusCodes.Success; } - private uint HandleEventShutdownInitiatedByTransport(ConnectionEvent connectionEvent) + private uint HandleEventShutdownInitiatedByTransport(ref ConnectionEvent connectionEvent) { if (!_connected) { - _connectTcs.CompleteException(new IOException("Connection has been shutdown.")); + _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException("Connection has been shutdown."))); } _acceptQueue.Writer.Complete(); - return MsQuicStatusCodes.Success; } - private uint HandleEventShutdownInitiatedByPeer(ConnectionEvent connectionEvent) + private uint HandleEventShutdownInitiatedByPeer(ref ConnectionEvent connectionEvent) { - _abortErrorCode = connectionEvent.Data.ShutdownBeginPeer.ErrorCode; + _abortErrorCode = connectionEvent.Data.ShutdownInitiatedByPeer.ErrorCode; _acceptQueue.Writer.Complete(); return MsQuicStatusCodes.Success; } - private uint HandleEventShutdownComplete(ConnectionEvent connectionEvent) + private uint HandleEventShutdownComplete(ref ConnectionEvent connectionEvent) { - _shutdownTcs.Complete(MsQuicStatusCodes.Success); + _shutdownTcs.SetResult(MsQuicStatusCodes.Success); return MsQuicStatusCodes.Success; } - private uint HandleEventNewStream(ConnectionEvent connectionEvent) + private uint HandleEventNewStream(ref ConnectionEvent connectionEvent) { - MsQuicStream msQuicStream = new MsQuicStream(this, connectionEvent.StreamFlags, connectionEvent.Data.NewStream.Stream, inbound: true); + MsQuicStream msQuicStream = new MsQuicStream(this, connectionEvent.StreamFlags, connectionEvent.Data.StreamStarted.Stream, inbound: true); _acceptQueue.Writer.TryWrite(msQuicStream); return MsQuicStatusCodes.Success; } - private uint HandleEventStreamsAvailable(ConnectionEvent connectionEvent) + private uint HandleEventStreamsAvailable(ref ConnectionEvent connectionEvent) { return MsQuicStatusCodes.Success; } @@ -275,7 +251,7 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d (ushort)_remoteEndPoint.Port), "Failed to connect to peer."); - return _connectTcs.GetTypelessValueTask(); + return new ValueTask(_connectTcs.Task); } private MsQuicStream StreamOpen( @@ -286,7 +262,7 @@ private MsQuicStream StreamOpen( MsQuicApi.Api.StreamOpenDelegate( _ptr, (uint)flags, - MsQuicStream.NativeCallbackHandler, + MsQuicStream.s_streamDelegate, IntPtr.Zero, out streamPtr), "Failed to open stream to peer."); @@ -296,11 +272,12 @@ private MsQuicStream StreamOpen( private void SetCallbackHandler() { + Debug.Assert(!_handle.IsAllocated); _handle = GCHandle.Alloc(this); - _connectionDelegate = new ConnectionCallbackDelegate(NativeCallbackHandler); + MsQuicApi.Api.SetCallbackHandlerDelegate( _ptr, - _connectionDelegate, + s_connectionDelegate, GCHandle.ToIntPtr(_handle)); } @@ -314,10 +291,20 @@ private ValueTask ShutdownAsync( ErrorCode); QuicExceptionHelpers.ThrowIfFailed(status, "Failed to shutdown connection."); - return _shutdownTcs.GetTypelessValueTask(); + return new ValueTask(_shutdownTcs.Task); + } + + internal void SetNegotiatedAlpn(IntPtr alpn, int alpnLength) + { + if (alpn != IntPtr.Zero && alpnLength != 0) + { + var buffer = new byte[alpnLength]; + Marshal.Copy(alpn, buffer, 0, alpnLength); + _negotiatedAlpnProtocol = new SslApplicationProtocol(buffer); + } } - internal static uint NativeCallbackHandler( + private static uint NativeCallbackHandler( IntPtr connection, IntPtr context, ref ConnectionEvent connectionEventStruct) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs index c8d338832398..721a8e554e4a 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #nullable enable +using System.Diagnostics; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; using System.Runtime.InteropServices; @@ -15,7 +16,7 @@ namespace System.Net.Quic.Implementations.MsQuic internal sealed class MsQuicListener : QuicListenerProvider, IDisposable { // Security configuration for MsQuic - private MsQuicSession _session; + private readonly MsQuicSession _session; // Pointer to the underlying listener // TODO replace all IntPtr with SafeHandles @@ -25,10 +26,10 @@ internal sealed class MsQuicListener : QuicListenerProvider, IDisposable private GCHandle _handle; // Delegate that wraps the static function that will be called when receiving an event. - private ListenerCallbackDelegate? _listenerDelegate; + private static readonly ListenerCallbackDelegate s_listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler); // Ssl listening options (ALPN, cert, etc) - private SslServerAuthenticationOptions _sslOptions; + private readonly SslServerAuthenticationOptions _sslOptions; private QuicListenerOptions _options; private volatile bool _disposed; @@ -142,11 +143,10 @@ private unsafe void SetListenPort() { SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS); - _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(inetAddress); + _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress); } - internal unsafe uint ListenerCallbackHandler( - ref ListenerEvent evt) + internal unsafe uint ListenerCallbackHandler(ref ListenerEvent evt) { try { @@ -154,10 +154,14 @@ internal unsafe uint ListenerCallbackHandler( { case QUIC_LISTENER_EVENT.NEW_CONNECTION: { - NewConnectionInfo connectionInfo = *(NewConnectionInfo*)evt.Data.NewConnection.Info; - IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(*(SOCKADDR_INET*)connectionInfo.LocalAddress); - IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(*(SOCKADDR_INET*)connectionInfo.RemoteAddress); + ref NewConnectionInfo connectionInfo = ref *(NewConnectionInfo*)evt.Data.NewConnection.Info; + + IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET*)connectionInfo.LocalAddress); + IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET*)connectionInfo.RemoteAddress); + MsQuicConnection msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, evt.Data.NewConnection.Connection); + msQuicConnection.SetNegotiatedAlpn(connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength); + _acceptConnectionQueue.Writer.TryWrite(msQuicConnection); } // Always pend the new connection to wait for the security config to be resolved @@ -167,8 +171,15 @@ internal unsafe uint ListenerCallbackHandler( return MsQuicStatusCodes.InternalError; } } - catch (Exception) + catch (Exception ex) { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(this, $"Exception occurred during connection callback: {ex.Message}"); + } + + // TODO: trigger an exception on any outstanding async calls. + return MsQuicStatusCodes.InternalError; } } @@ -191,11 +202,12 @@ internal static uint NativeCallbackHandler( internal void SetCallbackHandler() { + Debug.Assert(!_handle.IsAllocated); _handle = GCHandle.Alloc(this); - _listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler); + MsQuicApi.Api.SetCallbackHandlerDelegate( _ptr, - _listenerDelegate, + s_listenerDelegate, GCHandle.ToIntPtr(_handle)); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs index 6b8e9ce362d9..fc451a7630b7 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -23,7 +23,7 @@ internal sealed class MsQuicStream : QuicStreamProvider private GCHandle _handle; // Delegate that wraps the static function that will be called when receiving an event. - private StreamCallbackDelegate? _callback; + internal static readonly StreamCallbackDelegate s_streamDelegate = new StreamCallbackDelegate(NativeCallbackHandler); // Backing for StreamId private long _streamId = -1; @@ -62,10 +62,10 @@ internal sealed class MsQuicStream : QuicStreamProvider private volatile bool _disposed; - private List _receiveQuicBuffers = new List(); + private readonly List _receiveQuicBuffers = new List(); // TODO consider using Interlocked.Exchange instead of a sync if we can avoid it. - private object _sync = new object(); + private readonly object _sync = new object(); // Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) @@ -79,17 +79,19 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); SetCallbackHandler(); + bool isBidirectional = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); + if (inbound) { - _started = true; - _canWrite = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); _canRead = true; + _canWrite = isBidirectional; + _started = true; } else { + _canRead = isBidirectional; _canWrite = true; - _canRead = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); - StartWrites(); + StartLocalStream(); } } @@ -715,7 +717,6 @@ private uint HandleEventSendComplete(ref StreamEvent evt) CleanupSendState(); // TODO throw if a write was canceled. - uint errorCode = evt.Data.SendComplete.Canceled; bool shouldComplete = false; lock (_sync) @@ -753,10 +754,9 @@ private void SetCallbackHandler() { _handle = GCHandle.Alloc(this); - _callback = new StreamCallbackDelegate(NativeCallbackHandler); MsQuicApi.Api.SetCallbackHandlerDelegate( _ptr, - _callback, + s_streamDelegate, GCHandle.ToIntPtr(_handle)); } @@ -921,7 +921,10 @@ private unsafe ValueTask SendReadOnlyMemoryListAsync( return _sendResettableCompletionSource.GetTypelessValueTask(); } - private void StartWrites() + /// + /// Assigns a stream ID and begins process the stream. + /// + private void StartLocalStream() { Debug.Assert(!_started); uint status = MsQuicApi.Api.StreamStartDelegate( diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/Interop.MsQuic.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/Interop.MsQuic.cs index ab68320c1f77..b873b789f1d2 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/Interop.MsQuic.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/Interop.MsQuic.cs @@ -9,7 +9,7 @@ internal static partial class Interop { internal static class MsQuic { - [DllImport(Libraries.MsQuic)] - internal static unsafe extern uint MsQuicOpen(int version, out MsQuicNativeMethods.NativeApi* registration); + [DllImport(Libraries.MsQuic, CallingConvention = CallingConvention.Cdecl)] + internal static unsafe extern uint MsQuicOpen(out MsQuicNativeMethods.NativeApi* registration); } } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicEnums.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicEnums.cs index 62f8fab346c6..5fc281c8670d 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicEnums.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicEnums.cs @@ -3,19 +3,26 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { + internal enum QUIC_EXECUTION_PROFILE : uint + { + QUIC_EXECUTION_PROFILE_LOW_LATENCY, // Default + QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT, + QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER, + QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME + } + /// /// Flags to pass when creating a security config. /// [Flags] internal enum QUIC_SEC_CONFIG_FLAG : uint { - NONE = 0, CERT_HASH = 0x00000001, CERT_HASH_STORE = 0x00000002, CERT_CONTEXT = 0x00000004, CERT_FILE = 0x00000008, ENABL_OCSP = 0x00000010, - CERT_NULL = 0xF0000000, + CERT_NULL = 0xF0000000 // TODO: only valid for stub TLS. } [Flags] @@ -67,22 +74,30 @@ internal enum QUIC_SEND_FLAG : uint NONE = 0, ALLOW_0_RTT = 0x00000001, FIN = 0x00000002, + DGRAM_PRIORITY = 0x00000004 } internal enum QUIC_PARAM_LEVEL : uint { - REGISTRATION = 0, - SESSION = 1, - LISTENER = 2, - CONNECTION = 3, - TLS = 4, - STREAM = 5, + GLOBAL, + REGISTRATION, + SESSION, + LISTENER, + CONNECTION, + TLS, + STREAM } - internal enum QUIC_PARAM_REGISTRATION : uint + internal enum QUIC_PARAM_GLOBAL : uint { RETRY_MEMORY_PERCENT = 0, - CID_PREFIX = 1 + SUPPORTED_VERSIONS = 1, + LOAD_BALANCING_MODE = 2, + } + + internal enum QUIC_PARAM_REGISTRATION : uint + { + CID_PREFIX = 0 } internal enum QUIC_PARAM_SESSION : uint @@ -92,7 +107,10 @@ internal enum QUIC_PARAM_SESSION : uint PEER_UNIDI_STREAM_COUNT = 2, IDLE_TIMEOUT = 3, DISCONNECT_TIMEOUT = 4, - MAX_BYTES_PER_KEY = 5 + MAX_BYTES_PER_KEY = 5, + MIGRATION_ENABLED = 6, + DATAGRAM_RECEIVE_ENABLED = 7, + SERVER_RESUMPTION_LEVEL = 8 } internal enum QUIC_PARAM_LISTENER : uint @@ -122,7 +140,11 @@ internal enum QUIC_PARAM_CONN : uint SEND_PACING = 16, SHARE_UDP_BINDING = 17, IDEAL_PROCESSOR = 18, - MAX_STREAM_IDS = 19 + MAX_STREAM_IDS = 19, + STREAM_SCHEDULING_SCHEME = 20, + DATAGRAM_RECEIVE_ENABLED = 21, + DATAGRAM_SEND_ENABLED = 22, + DISABLE_1RTT_ENCRYPTION = 23 } internal enum QUIC_PARAM_STREAM : uint @@ -149,6 +171,11 @@ internal enum QUIC_CONNECTION_EVENT : uint STREAMS_AVAILABLE = 7, PEER_NEEDS_STREAMS = 8, IDEAL_PROCESSOR_CHANGED = 9, + DATAGRAM_STATE_CHANGED = 10, + DATAGRAM_RECEIVED = 11, + DATAGRAM_SEND_STATE_CHANGED = 12, + RESUMED = 13, + RESUMPTION_TICKET_RECEIVED = 14 } internal enum QUIC_STREAM_EVENT : uint diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs index 644787ea232b..49903de27ece 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs @@ -16,8 +16,6 @@ internal static unsafe class MsQuicNativeMethods [StructLayout(LayoutKind.Sequential)] internal struct NativeApi { - internal uint Version; - internal IntPtr SetContext; internal IntPtr GetContext; internal IntPtr SetCallbackHandler; @@ -44,6 +42,7 @@ internal struct NativeApi internal IntPtr ConnectionClose; internal IntPtr ConnectionShutdown; internal IntPtr ConnectionStart; + internal IntPtr ConnectionSendResumptionTicket; internal IntPtr StreamOpen; internal IntPtr StreamClose; @@ -52,20 +51,26 @@ internal struct NativeApi internal IntPtr StreamSend; internal IntPtr StreamReceiveComplete; internal IntPtr StreamReceiveSetEnabled; + + internal IntPtr DatagramSend; } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint SetContextDelegate( IntPtr handle, IntPtr context); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetContextDelegate( IntPtr handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetCallbackHandlerDelegate( IntPtr handle, Delegate del, IntPtr context); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint SetParamDelegate( IntPtr handle, uint level, @@ -73,6 +78,7 @@ internal delegate uint SetParamDelegate( uint bufferLength, byte* buffer); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint GetParamDelegate( IntPtr handle, uint level, @@ -80,36 +86,53 @@ internal delegate uint GetParamDelegate( uint* bufferLength, byte* buffer); - internal delegate uint RegistrationOpenDelegate(byte[] appName, out IntPtr registrationContext); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate uint RegistrationOpenDelegate(ref RegistrationConfig config, out IntPtr registrationContext); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void RegistrationCloseDelegate(IntPtr registrationContext); + [StructLayout(LayoutKind.Sequential)] + internal struct RegistrationConfig + { + [MarshalAs(UnmanagedType.LPUTF8Str)] + internal string AppName; + internal QUIC_EXECUTION_PROFILE ExecutionProfile; + } + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SecConfigCreateCompleteDelegate(IntPtr context, uint status, IntPtr securityConfig); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint SecConfigCreateDelegate( IntPtr registrationContext, uint flags, IntPtr certificate, - [MarshalAs(UnmanagedType.LPStr)]string? principal, + [MarshalAs(UnmanagedType.LPUTF8Str)]string? principal, IntPtr context, SecConfigCreateCompleteDelegate completionHandler); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SecConfigDeleteDelegate( IntPtr securityConfig); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint SessionOpenDelegate( IntPtr registrationContext, - byte[] utf8String, + QuicBuffer *alpnBuffers, + uint alpnBufferCount, IntPtr context, ref IntPtr session); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SessionCloseDelegate( IntPtr session); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SessionShutdownDelegate( IntPtr session, uint flags, - ushort errorCode); + ulong errorCode); [StructLayout(LayoutKind.Sequential)] internal struct ListenerEvent @@ -139,49 +162,58 @@ internal struct NewConnectionInfo internal uint QuicVersion; internal IntPtr LocalAddress; internal IntPtr RemoteAddress; - internal ushort CryptoBufferLength; + internal uint CryptoBufferLength; internal ushort AlpnListLength; internal ushort ServerNameLength; + internal byte NegotiatedAlpnLength; internal IntPtr CryptoBuffer; - internal IntPtr AlpnList; + internal IntPtr ClientAlpnList; + internal IntPtr NegotiatedAlpn; internal IntPtr ServerName; } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ListenerCallbackDelegate( IntPtr listener, IntPtr context, ref ListenerEvent evt); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ListenerOpenDelegate( IntPtr session, ListenerCallbackDelegate handler, IntPtr context, out IntPtr listener); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ListenerCloseDelegate( IntPtr listener); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ListenerStartDelegate( IntPtr listener, ref SOCKADDR_INET localAddress); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ListenerStopDelegate( IntPtr listener); [StructLayout(LayoutKind.Sequential)] internal struct ConnectionEventDataConnected { - internal bool EarlyDataAccepted; + internal bool SessionResumed; + internal byte NegotiatedAlpnLength; + internal IntPtr NegotiatedAlpn; } [StructLayout(LayoutKind.Sequential)] - internal struct ConnectionEventDataShutdownBegin + internal struct ConnectionEventDataShutdownInitiatedByTransport { internal uint Status; } [StructLayout(LayoutKind.Sequential)] - internal struct ConnectionEventDataShutdownBeginPeer + internal struct ConnectionEventDataShutdownInitiatedByPeer { internal long ErrorCode; } @@ -205,7 +237,7 @@ internal struct ConnectionEventDataPeerAddrChanged } [StructLayout(LayoutKind.Sequential)] - internal struct ConnectionEventDataNewStream + internal struct ConnectionEventDataStreamStarted { internal IntPtr Stream; internal QUIC_STREAM_OPEN_FLAG Flags; @@ -218,12 +250,6 @@ internal struct ConnectionEventDataStreamsAvailable internal ushort UniDirectionalCount; } - [StructLayout(LayoutKind.Sequential)] - internal struct ConnectionEventDataIdealSendBuffer - { - internal ulong NumBytes; - } - [StructLayout(LayoutKind.Explicit)] internal struct ConnectionEventDataUnion { @@ -231,10 +257,10 @@ internal struct ConnectionEventDataUnion internal ConnectionEventDataConnected Connected; [FieldOffset(0)] - internal ConnectionEventDataShutdownBegin ShutdownBegin; + internal ConnectionEventDataShutdownInitiatedByTransport ShutdownInitiatedByTransport; [FieldOffset(0)] - internal ConnectionEventDataShutdownBeginPeer ShutdownBeginPeer; + internal ConnectionEventDataShutdownInitiatedByPeer ShutdownInitiatedByPeer; [FieldOffset(0)] internal ConnectionEventDataShutdownComplete ShutdownComplete; @@ -246,13 +272,10 @@ internal struct ConnectionEventDataUnion internal ConnectionEventDataPeerAddrChanged PeerAddrChanged; [FieldOffset(0)] - internal ConnectionEventDataNewStream NewStream; + internal ConnectionEventDataStreamStarted StreamStarted; [FieldOffset(0)] internal ConnectionEventDataStreamsAvailable StreamsAvailable; - - [FieldOffset(0)] - internal ConnectionEventDataIdealSendBuffer IdealSendBuffer; } [StructLayout(LayoutKind.Sequential)] @@ -261,37 +284,42 @@ internal struct ConnectionEvent internal QUIC_CONNECTION_EVENT Type; internal ConnectionEventDataUnion Data; - internal bool EarlyDataAccepted => Data.Connected.EarlyDataAccepted; - internal ulong NumBytes => Data.IdealSendBuffer.NumBytes; - internal uint ShutdownBeginStatus => Data.ShutdownBegin.Status; - internal long ShutdownBeginPeerStatus => Data.ShutdownBeginPeer.ErrorCode; + internal bool EarlyDataAccepted => Data.Connected.SessionResumed; + //internal ulong NumBytes => Data.IdealSendBuffer.NumBytes; + internal uint ShutdownBeginStatus => Data.ShutdownInitiatedByTransport.Status; + internal long ShutdownBeginPeerStatus => Data.ShutdownInitiatedByPeer.ErrorCode; internal bool ShutdownTimedOut => Data.ShutdownComplete.TimedOut; internal ushort BiDirectionalCount => Data.StreamsAvailable.BiDirectionalCount; internal ushort UniDirectionalCount => Data.StreamsAvailable.UniDirectionalCount; - internal QUIC_STREAM_OPEN_FLAG StreamFlags => Data.NewStream.Flags; + internal QUIC_STREAM_OPEN_FLAG StreamFlags => Data.StreamStarted.Flags; } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ConnectionCallbackDelegate( IntPtr connection, IntPtr context, ref ConnectionEvent connectionEvent); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ConnectionOpenDelegate( IntPtr session, ConnectionCallbackDelegate handler, IntPtr context, out IntPtr connection); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ConnectionCloseDelegate( IntPtr connection); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ConnectionStartDelegate( IntPtr connection, ushort family, - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPUTF8Str)] string serverName, ushort serverPort); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint ConnectionShutdownDelegate( IntPtr connection, uint flags, @@ -304,21 +332,14 @@ internal struct StreamEventDataRecv internal ulong TotalBufferLength; internal QuicBuffer* Buffers; internal uint BufferCount; - internal uint Flags; + internal QUIC_RECEIVE_FLAG Flags; } - [StructLayout(LayoutKind.Explicit)] + [StructLayout(LayoutKind.Sequential)] internal struct StreamEventDataSendComplete { - [FieldOffset(0)] - internal byte Canceled; - [FieldOffset(1)] + internal bool Canceled; internal IntPtr ClientContext; - - internal bool IsCanceled() - { - return Canceled != 0; - } } [StructLayout(LayoutKind.Sequential)] @@ -432,11 +453,13 @@ internal struct SOCKADDR_INET internal ushort si_family; } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamCallbackDelegate( IntPtr stream, IntPtr context, ref StreamEvent streamEvent); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamOpenDelegate( IntPtr connection, uint flags, @@ -444,18 +467,22 @@ internal delegate uint StreamOpenDelegate( IntPtr context, out IntPtr stream); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamStartDelegate( IntPtr stream, uint flags); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamCloseDelegate( IntPtr stream); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamShutdownDelegate( IntPtr stream, uint flags, long errorCode); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamSendDelegate( IntPtr stream, QuicBuffer* buffers, @@ -463,12 +490,15 @@ internal delegate uint StreamSendDelegate( uint flags, IntPtr clientSendContext); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamReceiveCompleteDelegate( IntPtr stream, ulong bufferLength); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate uint StreamReceiveSetEnabledDelegate( IntPtr stream, + [MarshalAs(UnmanagedType.U1)] bool enabled); [StructLayout(LayoutKind.Sequential)] diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 6c033a8548c0..b290c5a074ab 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -28,7 +28,7 @@ public Http3LoopbackServer(GenericLoopbackOptions options = null) var sslOpts = new SslServerAuthenticationOptions { EnabledSslProtocols = options.SslProtocols, - ApplicationProtocols = new List { SslApplicationProtocol.Http3 }, + ApplicationProtocols = new List { new SslApplicationProtocol("h3") }, //ServerCertificate = _cert, ClientCertificateRequired = false }; @@ -66,7 +66,7 @@ public sealed class Http3LoopbackServerFactory : LoopbackServerFactory { public static Http3LoopbackServerFactory Singleton { get; } = new Http3LoopbackServerFactory(); - public override Version Version => HttpVersion.Version30; + public override Version Version { get; } = new Version(3, 0); public override GenericLoopbackServer CreateServer(GenericLoopbackOptions options = null) { diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs index 9d0e62ea4f44..7aaeb06224c1 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs @@ -20,6 +20,8 @@ namespace System.Net.Http.Functional.Tests public abstract partial class HttpClientHandlerTestBase : FileCleanupTestBase { + public static readonly Version HttpVersion30 = new Version(3, 0); + public readonly ITestOutputHelper _output; protected virtual Version UseVersion => HttpVersion.Version11; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs index c4400b63b745..ce534b0e1d54 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; +using System.Text; + namespace System.Net.Http.Headers { /// @@ -44,5 +47,30 @@ public AltSvcHeaderValue(string alpnProtocolName, string? host, int port, TimeSp /// /// TODO: if made public, this should be made internal as Persist is left open-ended and can be non-boolean in the future. public bool Persist { get; } + + public override string ToString() + { + StringBuilder sb = StringBuilderCache.Acquire(capacity: AlpnProtocolName.Length + (Host?.Length ?? 0) + 64); + + sb.Append(AlpnProtocolName); + sb.Append("=\""); + if (Host != null) sb.Append(Host); + sb.Append(':'); + sb.Append(Port.ToString(CultureInfo.InvariantCulture)); + sb.Append('"'); + + if (MaxAge != TimeSpan.FromTicks(AltSvcHeaderParser.DefaultMaxAgeTicks)) + { + sb.Append("; ma="); + sb.Append((MaxAge.Ticks / TimeSpan.TicksPerSecond).ToString(CultureInfo.InvariantCulture)); + } + + if (Persist) + { + sb.Append("; persist=1"); + } + + return StringBuilderCache.GetStringAndRelease(sb); + } } } 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 bb59149fb6e9..289fd7a1cb77 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 @@ -490,7 +490,7 @@ private void ProcessAltSvcFrame(FrameHeader frameHeader) // - On stream 0, the origin will be specified. HTTP/2 can service multiple origins per connection, and so the server can report origins other than what our pool is using. // - Otherwise, the origin is implicitly defined by the request stream and must be of length 0. - if ((frameHeader.StreamId != 0 && originLength == 0) || (frameHeader.StreamId == 0 && span.Length >= originLength && span.Slice(originLength).SequenceEqual(_pool.Http2AltSvcOriginUri))) + if ((frameHeader.StreamId != 0 && originLength == 0) || (frameHeader.StreamId == 0 && span.Length >= originLength && span.Slice(0, originLength).SequenceEqual(_pool.Http2AltSvcOriginUri))) { span = span.Slice(originLength); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index 54fe0e9c8bb7..9ee2bdf910b8 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -9,11 +9,16 @@ using System.Collections.Generic; using System.Diagnostics; using System.Net.Http.Headers; +using System.Net.Security; namespace System.Net.Http { internal sealed class Http3Connection : HttpConnectionBase, IDisposable { + // TODO: once HTTP/3 is standardized, create APIs for these. + public static readonly Version HttpVersion30 = new Version(3, 0); + public static readonly SslApplicationProtocol Http3ApplicationProtocol = new SslApplicationProtocol("h3"); + /// /// If we receive a settings frame larger than this, tear down the connection with an error. /// 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 72e8090e76d9..b5afcb5f9d8f 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 @@ -12,8 +12,6 @@ using System.Runtime.CompilerServices; using System.Net.Http.QPack; using System.Runtime.ExceptionServices; -using System.Buffers; -using System.Diagnostics.CodeAnalysis; namespace System.Net.Http { @@ -292,11 +290,9 @@ public async Task SendAsync(CancellationToken cancellationT /// /// Waits for the initial response headers to be completed, including e.g. Expect 100 Continue. /// - /// - /// private async Task ReadResponseAsync(CancellationToken cancellationToken) { - Debug.Assert(_response != null); + Debug.Assert(_response == null); do { _headerState = HeaderState.StatusHeader; @@ -313,6 +309,7 @@ private async Task ReadResponseAsync(CancellationToken cancellationToken) } await ReadHeadersAsync(payloadLength, cancellationToken).ConfigureAwait(false); + Debug.Assert(_response != null); } while ((int)_response.StatusCode < 200); @@ -886,7 +883,7 @@ private void OnHeader(int? staticIndex, HeaderDescriptor descriptor, string? sta _response = new HttpResponseMessage() { - Version = HttpVersion.Version30, + Version = Http3Connection.HttpVersion30, RequestMessage = _request, Content = new HttpConnectionResponseContent(), StatusCode = (HttpStatusCode)statusCode diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs index de4a6a5b9323..43a4181aa60c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs @@ -31,8 +31,7 @@ public HttpAuthority(string host, int port) public bool Equals(HttpAuthority? other) { - Debug.Assert(other != null); - return string.Equals(IdnHost, other.IdnHost) && Port == other.Port; + return other != null && string.Equals(IdnHost, other.IdnHost) && Port == other.Port; } public override bool Equals(object? obj) 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 af9e2cd61420..e2c2e3664248 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 @@ -124,7 +124,7 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK } _http2Enabled = _poolManager.Settings._maxHttpVersion >= HttpVersion.Version20; - _http3Enabled = _poolManager.Settings._maxHttpVersion >= HttpVersion.Version30; + _http3Enabled = _poolManager.Settings._maxHttpVersion >= Http3Connection.HttpVersion30; switch (kind) { @@ -259,7 +259,7 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK if (NetEventSource.Log.IsEnabled()) Trace($"{this}"); } - private static readonly List s_http3ApplicationProtocols = new List() { SslApplicationProtocol.Http3 }; + private static readonly List s_http3ApplicationProtocols = new List() { Http3Connection.Http3ApplicationProtocol }; private static readonly List s_http2ApplicationProtocols = new List() { SslApplicationProtocol.Http2, SslApplicationProtocol.Http11 }; private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnectionPoolManager poolManager, string sslHostName) @@ -883,7 +883,7 @@ internal void HandleAltSvc(IEnumerable altSvcHeaderValues, TimeSpan? res { int parseIdx = 0; - while (AltSvcHeaderParser.Parser.TryParseValue(altSvcHeaderValue, null, ref parseIdx, out object? parsedValue)) + if (AltSvcHeaderParser.Parser.TryParseValue(altSvcHeaderValue, null, ref parseIdx, out object? parsedValue)) { var value = (AltSvcHeaderValue?)parsedValue; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 507af88f3aea..42b67aabc31a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -69,7 +69,7 @@ public HttpConnectionSettings() { bool allowHttp2 = AllowHttp2; _maxHttpVersion = - AllowDraftHttp3 && allowHttp2 ? HttpVersion.Version30 : + AllowDraftHttp3 && allowHttp2 ? Http3Connection.HttpVersion30 : allowHttp2 ? HttpVersion.Version20 : HttpVersion.Version11; _allowUnencryptedHttp2 = allowHttp2 && AllowUnencryptedHttp2; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index b09815bcee6b..7fcd9372198d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -20,43 +20,59 @@ public HttpClientHandler_AltSvc_Test(ITestOutputHelper output) : base(output) /// protected override HttpClient CreateHttpClient() { - HttpClientHandler handler = CreateHttpClientHandler(HttpVersion.Version30); + bool http3Enabled = (bool)typeof(SocketsHttpHandler) + .Assembly + .GetType("System.Net.Http.HttpConnectionSettings", throwOnError: true) + .GetProperty("AllowDraftHttp3", Reflection.BindingFlags.Static | Reflection.BindingFlags.NonPublic) + .GetValue(null); + + Assert.True(http3Enabled, "HTTP/3 draft support must be enabled for this test."); + + HttpClientHandler handler = CreateHttpClientHandler(HttpVersion30); SetUsePrenegotiatedHttp3(handler, usePrenegotiatedHttp3: false); return CreateHttpClient(handler); } - [Fact] - public async Task AltSvc_Header_UpgradeFrom11_Success() + [Theory] + [MemberData(nameof(AltSvcHeaderUpgradeVersions))] + public async Task AltSvc_Header_Upgrade_Success(Version fromVersion) { - await AltSvc_Header_Upgrade_Success(HttpVersion.Version11).ConfigureAwait(false); - } + // The test makes a request to a HTTP/1 or HTTP/2 server first, which supplies an Alt-Svc header pointing to the second server. + using GenericLoopbackServer firstServer = + fromVersion.Major switch + { + 1 => new LoopbackServer(new LoopbackServer.Options { UseSsl = true }), + 2 => Http2LoopbackServer.CreateServer(), + _ => throw new Exception("Unknown HTTP version.") + }; + + // The second request is expected to come in on this HTTP/3 server. + using var secondServer = new Http3LoopbackServer(); - [Fact] - public async Task AltSvc_Header_UpgradeFrom20_Success() - { - await AltSvc_Header_Upgrade_Success(HttpVersion.Version20).ConfigureAwait(false); - } - - private async Task AltSvc_Header_Upgrade_Success(Version fromVersion) - { - using GenericLoopbackServer firstServer = GetFactoryForVersion(fromVersion).CreateServer(); - using Http3LoopbackServer secondServer = new Http3LoopbackServer(); using HttpClient client = CreateHttpClient(); Task firstResponseTask = client.GetAsync(firstServer.Address); - - await firstServer.AcceptConnectionSendResponseAndCloseAsync(additionalHeaders: new[] + Task serverTask = firstServer.AcceptConnectionSendResponseAndCloseAsync(additionalHeaders: new[] { - new HttpHeaderData("Alt-Svc", $"h3={secondServer.Address.IdnHost}:{secondServer.Address.Port}") + new HttpHeaderData("Alt-Svc", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"") }); - HttpResponseMessage firstResponse = await firstResponseTask; + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); + + using HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); } + public static TheoryData AltSvcHeaderUpgradeVersions => + new TheoryData + { + { HttpVersion.Version11 }, + { HttpVersion.Version20 } + }; + [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { @@ -65,15 +81,18 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() using HttpClient client = CreateHttpClient(); Task firstResponseTask = client.GetAsync(firstServer.Address); - - using (Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync()) + Task serverTask = Task.Run(async () => { + using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + int streamId = await connection.ReadRequestHeaderAsync(); + await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); await connection.SendDefaultResponseAsync(streamId); - await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3={secondServer.Address.IdnHost}:{secondServer.Address.Port}", 0)); - } + }); + + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); - HttpResponseMessage firstResponse = await firstResponseTask; + HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); @@ -87,16 +106,19 @@ public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() using HttpClient client = CreateHttpClient(); Task firstResponseTask = client.GetAsync(firstServer.Address); - - using (Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync()) + Task serverTask = Task.Run(async () => { + using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + int streamId = await connection.ReadRequestHeaderAsync(); await connection.SendDefaultResponseHeadersAsync(streamId); - await connection.WriteFrameAsync(new AltSvcFrame("", $"h3={secondServer.Address.IdnHost}:{secondServer.Address.Port}", streamId)); + await connection.WriteFrameAsync(new AltSvcFrame("", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId)); await connection.SendResponseDataAsync(streamId, Array.Empty(), true); - } + }); + + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); - HttpResponseMessage firstResponse = await firstResponseTask; + HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); @@ -105,12 +127,15 @@ public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Http3LoopbackServer secondServer, HttpClient client) { Task secondResponseTask = client.GetAsync(firstServer.Address); + Task secondRequestTask = secondServer.AcceptConnectionSendResponseAndCloseAsync(); + + await new[] { (Task)secondResponseTask, secondRequestTask }.WhenAllOrAnyFailed(30_000); + + HttpRequestData secondRequest = secondRequestTask.Result; + using HttpResponseMessage secondResponse = secondResponseTask.Result; - HttpRequestData secondRequest = await secondServer.AcceptConnectionSendResponseAndCloseAsync(); string altUsed = secondRequest.GetSingleHeaderValue("Alt-Used"); Assert.Equal($"{secondServer.Address.IdnHost}:{secondServer.Address.Port}", altUsed); - - HttpResponseMessage secondResponse = await secondResponseTask; Assert.True(secondResponse.IsSuccessStatusCode); } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index 145ecd06a11d..27d4b77c536a 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -19,7 +19,7 @@ namespace System.Net.Http.Functional.Tests { public abstract class HttpClientHandlerTest_Http3 : HttpClientHandlerTestBase { - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; public static bool SupportsAlpn => PlatformDetection.SupportsAlpn; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs index 90fddb4008cd..bc718b29d667 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs @@ -22,7 +22,7 @@ protected static HttpClientHandler CreateHttpClientHandler(Version useVersion = handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; } - if (useVersion == HttpVersion.Version30) + if (useVersion == HttpVersion30) { SetUsePrenegotiatedHttp3(handler, usePrenegotiatedHttp3: true); } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs index 8a316d0a9739..5c89f6969e08 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs @@ -35,7 +35,7 @@ public void CreateAndDestroyManyClients(int numClients) public sealed class SocketsHttpHandler_HttpClientMiniStress_Http3 : HttpClientMiniStress { public SocketsHttpHandler_HttpClientMiniStress_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } public sealed class SocketsHttpHandler_HttpClientMiniStress_Http2 : HttpClientMiniStress diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MsQuicTests.cs index a8a5b93855a4..76fe3c5277e7 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MsQuicTests.cs @@ -215,42 +215,76 @@ public async Task MultipleStreamsOnSingleConnection() await (new[] { listenTask, clientTask }).WhenAllOrAnyFailed(millisecondsTimeout: 60000); } + [Fact] + public async Task TestConnect() + { + SslServerAuthenticationOptions serverOpts = GetSslServerAuthenticationOptions(); + + using QuicListener listener = new QuicListener( + QuicImplementationProviders.MsQuic, + new IPEndPoint(IPAddress.Loopback, 0), + serverOpts); + + listener.Start(); + IPEndPoint listenEndPoint = listener.ListenEndPoint; + Assert.NotEqual(0, listenEndPoint.Port); + + using QuicConnection clientConnection = new QuicConnection( + QuicImplementationProviders.MsQuic, + listenEndPoint, + GetSslClientAuthenticationOptions()); + + Assert.False(clientConnection.Connected); + Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); + + ValueTask connectTask = clientConnection.ConnectAsync(); + QuicConnection serverConnection = await listener.AcceptConnectionAsync(); + await connectTask; + + Assert.True(clientConnection.Connected); + Assert.True(serverConnection.Connected); + Assert.Equal(listenEndPoint, serverConnection.LocalEndPoint); + Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); + Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint); + Assert.Equal(serverOpts.ApplicationProtocols[0].ToString(), clientConnection.NegotiatedApplicationProtocol.ToString()); + Assert.Equal(serverOpts.ApplicationProtocols[0].ToString(), serverConnection.NegotiatedApplicationProtocol.ToString()); + } + [Fact] public async Task TestStreams() { - using (QuicListener listener = new QuicListener( + using QuicListener listener = new QuicListener( QuicImplementationProviders.MsQuic, new IPEndPoint(IPAddress.Loopback, 0), - GetSslServerAuthenticationOptions())) - { - listener.Start(); - IPEndPoint listenEndPoint = listener.ListenEndPoint; + GetSslServerAuthenticationOptions()); - using (QuicConnection clientConnection = new QuicConnection( - QuicImplementationProviders.MsQuic, - listenEndPoint, - sslClientAuthenticationOptions: new SslClientAuthenticationOptions { ApplicationProtocols = new List() { new SslApplicationProtocol("quictest") } })) - { - Assert.False(clientConnection.Connected); - Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); - - ValueTask connectTask = clientConnection.ConnectAsync(); - QuicConnection serverConnection = await listener.AcceptConnectionAsync(); - await connectTask; - - Assert.True(clientConnection.Connected); - Assert.True(serverConnection.Connected); - Assert.Equal(listenEndPoint, serverConnection.LocalEndPoint); - Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); - Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint); - - await CreateAndTestBidirectionalStream(clientConnection, serverConnection); - await CreateAndTestBidirectionalStream(serverConnection, clientConnection); - await CreateAndTestUnidirectionalStream(serverConnection, clientConnection); - await CreateAndTestUnidirectionalStream(clientConnection, serverConnection); - await clientConnection.CloseAsync(errorCode: 0); - } - } + listener.Start(); + IPEndPoint listenEndPoint = listener.ListenEndPoint; + Assert.NotEqual(0, listenEndPoint.Port); + + using QuicConnection clientConnection = new QuicConnection( + QuicImplementationProviders.MsQuic, + listenEndPoint, + GetSslClientAuthenticationOptions()); + + Assert.False(clientConnection.Connected); + Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); + + ValueTask connectTask = clientConnection.ConnectAsync(); + QuicConnection serverConnection = await listener.AcceptConnectionAsync(); + await connectTask; + + Assert.True(clientConnection.Connected); + Assert.True(serverConnection.Connected); + Assert.Equal(listenEndPoint, serverConnection.LocalEndPoint); + Assert.Equal(listenEndPoint, clientConnection.RemoteEndPoint); + Assert.Equal(clientConnection.LocalEndPoint, serverConnection.RemoteEndPoint); + + await CreateAndTestBidirectionalStream(clientConnection, serverConnection); + await CreateAndTestBidirectionalStream(serverConnection, clientConnection); + await CreateAndTestUnidirectionalStream(serverConnection, clientConnection); + await CreateAndTestUnidirectionalStream(clientConnection, serverConnection); + await clientConnection.CloseAsync(errorCode: 0); } [Fact] @@ -336,36 +370,31 @@ public async Task GetStreamIdWithoutStartWorks() private static async Task CreateAndTestBidirectionalStream(QuicConnection c1, QuicConnection c2) { - using (QuicStream s1 = c1.OpenBidirectionalStream()) - { - Assert.True(s1.CanRead); - Assert.True(s1.CanWrite); + using QuicStream s1 = c1.OpenBidirectionalStream(); + Assert.True(s1.CanRead); + Assert.True(s1.CanWrite); - ValueTask writeTask = s1.WriteAsync(s_data); - using (QuicStream s2 = await c2.AcceptStreamAsync()) - { - await ReceiveDataAsync(s_data, s2); - await writeTask; - await TestBidirectionalStream(s1, s2); - } - } + ValueTask writeTask = s1.WriteAsync(s_data); + + using QuicStream s2 = await c2.AcceptStreamAsync(); + await ReceiveDataAsync(s_data, s2); + await writeTask; + await TestBidirectionalStream(s1, s2); } private static async Task CreateAndTestUnidirectionalStream(QuicConnection c1, QuicConnection c2) { - using (QuicStream s1 = c1.OpenUnidirectionalStream()) - { - Assert.False(s1.CanRead); - Assert.True(s1.CanWrite); + using QuicStream s1 = c1.OpenUnidirectionalStream(); - ValueTask writeTask = s1.WriteAsync(s_data); - using (QuicStream s2 = await c2.AcceptStreamAsync()) - { - await ReceiveDataAsync(s_data, s2); - await writeTask; - await TestUnidirectionalStream(s1, s2); - } - } + Assert.False(s1.CanRead); + Assert.True(s1.CanWrite); + + ValueTask writeTask = s1.WriteAsync(s_data); + + using QuicStream s2 = await c2.AcceptStreamAsync(); + await ReceiveDataAsync(s_data, s2); + await writeTask; + await TestUnidirectionalStream(s1, s2); } private static async Task TestBidirectionalStream(QuicStream s1, QuicStream s2) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 18b603637010..f0964613b0bd 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -2323,7 +2323,7 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http2(ITestOutputH public sealed class SocketsHttpHandler_HttpClientHandler_Finalization_Http3_Test : HttpClientHandler_Finalization_Test { public SocketsHttpHandler_HttpClientHandler_Finalization_Http3_Test(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] @@ -2336,34 +2336,34 @@ public SocketsHttpHandlerTest_Http3(ITestOutputHelper output) : base(output) { } public sealed class SocketsHttpHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies { public SocketsHttpHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Http3 : HttpClientHandlerTest { public SocketsHttpHandlerTest_HttpClientHandlerTest_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3 : HttpClientHandlerTest_Headers { public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3 : HttpClientHandler_Cancellation_Test { public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3 : HttpClientHandler_AltSvc_Test { public SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3(ITestOutputHelper output) : base(output) { } - protected override Version UseVersion => HttpVersion.Version30; + protected override Version UseVersion => HttpVersion30; } } diff --git a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs index 979baf5e9f1e..899fa7d7d68e 100644 --- a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs +++ b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs @@ -208,7 +208,6 @@ public static partial class HttpVersion public static readonly System.Version Version10; public static readonly System.Version Version11; public static readonly System.Version Version20; - public static readonly System.Version Version30; } public partial interface ICredentials { diff --git a/src/libraries/System.Net.Primitives/src/System/Net/HttpVersion.cs b/src/libraries/System.Net.Primitives/src/System/Net/HttpVersion.cs index f293df83da61..55a2b50ad255 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/HttpVersion.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/HttpVersion.cs @@ -9,6 +9,5 @@ public static class HttpVersion public static readonly Version Version10 = new Version(1, 0); public static readonly Version Version11 = new Version(1, 1); public static readonly Version Version20 = new Version(2, 0); - public static readonly Version Version30 = new Version(3, 0); } } diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.cs b/src/libraries/System.Net.Security/ref/System.Net.Security.cs index 3ef7ad8ab16f..9092eb24326e 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.cs +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.cs @@ -119,7 +119,6 @@ public readonly struct SslClientHelloInfo private readonly int _dummyPrimitive; public static readonly System.Net.Security.SslApplicationProtocol Http11; public static readonly System.Net.Security.SslApplicationProtocol Http2; - public static readonly System.Net.Security.SslApplicationProtocol Http3; public SslApplicationProtocol(byte[] protocol) { throw null; } public SslApplicationProtocol(string protocol) { throw null; } public System.ReadOnlyMemory Protocol { get { throw null; } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs index 0c1e3239160a..6b1a91258806 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs @@ -10,13 +10,10 @@ namespace System.Net.Security public readonly struct SslApplicationProtocol : IEquatable { private static readonly Encoding s_utf8 = Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback); - private static readonly byte[] s_http3Utf8 = new byte[] { 0x68, 0x33 }; // "h3" private static readonly byte[] s_http2Utf8 = new byte[] { 0x68, 0x32 }; // "h2" private static readonly byte[] s_http11Utf8 = new byte[] { 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 }; // "http/1.1" // Refer to IANA on ApplicationProtocols: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids - // h3 - public static readonly SslApplicationProtocol Http3 = new SslApplicationProtocol(s_http3Utf8, copy: false); // h2 public static readonly SslApplicationProtocol Http2 = new SslApplicationProtocol(s_http2Utf8, copy: false); // http/1.1 diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs index e3657030abec..7140fea2cf55 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs @@ -111,7 +111,6 @@ public enum ApplicationProtocolInfo None = 0, Http11 = 1, Http2 = 2, - Http3 = 4, Other = 128 } @@ -673,10 +672,6 @@ private static bool TryGetApplicationProtocolsFromExtension(ReadOnlySpan e { alpn |= ApplicationProtocolInfo.Http2; } - else if (protocol.SequenceEqual(SslApplicationProtocol.Http3.Protocol.Span)) - { - alpn |= ApplicationProtocolInfo.Http3; - } else { alpn |= ApplicationProtocolInfo.Other; From a1da393cac02d0588ae499f68d37a3d6e07572f7 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 6 Aug 2020 14:56:56 -0700 Subject: [PATCH 301/755] [Arm64] Treat Math/MathF.FusedMultiplyAdd as intrinsics (#40124) * Transform Math{F}.FusedMultiplyAdd(x,y,z) into AdvSimd.FusedMultiplyAddScalar( Vector64.CreateScalarUnsafe(z), Vector64.CreateScalarUnsafe(y), Vector64.CreateScalarUnsafe(x)).ToScalar() on Arm64 in importer.cpp * Add containment analysis for AdvSimd_FusedMultiplyAddScalar in lower.h lowerarmarch.cpp * Set tgtPrefOp1 for intrinsics with SIMD-to-SIMD move semantics in lsraarm64.cpp --- src/coreclr/src/jit/importer.cpp | 39 +++++++++++++-- src/coreclr/src/jit/lower.h | 4 +- src/coreclr/src/jit/lowerarmarch.cpp | 74 ++++++++++++++++++++++++++++ src/coreclr/src/jit/lsraarm64.cpp | 21 ++++++-- 4 files changed, 129 insertions(+), 9 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index d1111583e32a..8d485e6eac70 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -4201,9 +4201,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // We are constructing a chain of intrinsics similar to: // return FMA.MultiplyAddScalar( - // Vector128.CreateScalar(x), - // Vector128.CreateScalar(y), - // Vector128.CreateScalar(z) + // Vector128.CreateScalarUnsafe(x), + // Vector128.CreateScalarUnsafe(y), + // Vector128.CreateScalarUnsafe(z) // ).ToScalar(); GenTree* op3 = gtNewSimdHWIntrinsicNode(TYP_SIMD16, impPopStack().val, @@ -4217,7 +4217,38 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, retNode = gtNewSimdHWIntrinsicNode(callType, res, NI_Vector128_ToScalar, callType, 16); } -#endif // TARGET_XARCH +#elif defined(TARGET_ARM64) + if (compExactlyDependsOn(InstructionSet_AdvSimd)) + { + assert(varTypeIsFloating(callType)); + + // We are constructing a chain of intrinsics similar to: + // return AdvSimd.FusedMultiplyAddScalar( + // Vector64.Create{ScalarUnsafe}(z), + // Vector64.Create{ScalarUnsafe}(y), + // Vector64.Create{ScalarUnsafe}(x) + // ).ToScalar(); + + NamedIntrinsic createVector64 = + (callType == TYP_DOUBLE) ? NI_Vector64_Create : NI_Vector64_CreateScalarUnsafe; + + constexpr unsigned int simdSize = 8; + + GenTree* op3 = + gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize); + GenTree* op2 = + gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize); + GenTree* op1 = + gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize); + + // Note that AdvSimd.FusedMultiplyAddScalar(op1,op2,op3) corresponds to op1 + op2 * op3 + // while Math{F}.FusedMultiplyAddScalar(op1,op2,op3) corresponds to op1 * op2 + op3 + retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op3, op2, op1, NI_AdvSimd_FusedMultiplyAddScalar, + callType, simdSize); + + retNode = gtNewSimdHWIntrinsicNode(callType, retNode, NI_Vector64_ToScalar, callType, simdSize); + } +#endif break; } #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 135446c7e84d..ff13302c1ba9 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -327,12 +327,12 @@ class Lowering final : public Phase void LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp); void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node); void LowerHWIntrinsicDot(GenTreeHWIntrinsic* node); - void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); - #if defined(TARGET_XARCH) + void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); void LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node); #elif defined(TARGET_ARM64) bool IsValidConstForMovImm(GenTreeHWIntrinsic* node); + void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node); #endif // !TARGET_XARCH && !TARGET_ARM64 union VectorConstant { diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 2ab6fa947822..6d46545f718d 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -517,6 +517,76 @@ void Lowering::LowerSIMD(GenTreeSIMD* simdNode) #endif // FEATURE_SIMD #ifdef FEATURE_HW_INTRINSICS + +//---------------------------------------------------------------------------------------------- +// LowerHWIntrinsicFusedMultiplyAddScalar: Lowers AdvSimd_FusedMultiplyAddScalar intrinsics +// when some of the operands are negated by "containing" such negation. +// +// Arguments: +// node - The original hardware intrinsic node +// +// | op1 | op2 | op3 | +// | + | + | + | AdvSimd_FusedMultiplyAddScalar +// | + | + | - | AdvSimd_FusedMultiplySubtractScalar +// | + | - | + | AdvSimd_FusedMultiplySubtractScalar +// | + | - | - | AdvSimd_FusedMultiplyAddScalar +// | - | + | + | AdvSimd_FusedMultiplySubtractNegatedScalar +// | - | + | - | AdvSimd_FusedMultiplyAddNegatedScalar +// | - | - | + | AdvSimd_FusedMultiplyAddNegatedScalar +// | - | - | - | AdvSimd_FusedMultiplySubtractNegatedScalar +// +void Lowering::LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node) +{ + assert(node->gtHWIntrinsicId == NI_AdvSimd_FusedMultiplyAddScalar); + + const HWIntrinsic intrin(node); + + GenTree* op1 = intrin.op1; + GenTree* op2 = intrin.op2; + GenTree* op3 = intrin.op3; + + auto lowerOperand = [this](GenTree* op) { + bool wasNegated = false; + + if (op->OperIsHWIntrinsic() && + ((op->AsHWIntrinsic()->gtHWIntrinsicId == NI_AdvSimd_Arm64_DuplicateToVector64) || + (op->AsHWIntrinsic()->gtHWIntrinsicId == NI_Vector64_CreateScalarUnsafe))) + { + GenTreeHWIntrinsic* createVector64 = op->AsHWIntrinsic(); + GenTree* valueOp = createVector64->gtGetOp1(); + + if (valueOp->OperIs(GT_NEG)) + { + createVector64->gtOp1 = valueOp->gtGetOp1(); + BlockRange().Remove(valueOp); + wasNegated = true; + } + } + + return wasNegated; + }; + + const bool op1WasNegated = lowerOperand(op1); + const bool op2WasNegated = lowerOperand(op2); + const bool op3WasNegated = lowerOperand(op3); + + if (op1WasNegated) + { + if (op2WasNegated != op3WasNegated) + { + node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplyAddNegatedScalar; + } + else + { + node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractNegatedScalar; + } + } + else if (op2WasNegated != op3WasNegated) + { + node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractScalar; + } +} + //---------------------------------------------------------------------------------------------- // Lowering::LowerHWIntrinsic: Perform containment analysis for a hardware intrinsic node. // @@ -573,6 +643,10 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) return; } + case NI_AdvSimd_FusedMultiplyAddScalar: + LowerHWIntrinsicFusedMultiplyAddScalar(node); + break; + default: break; } diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index bdb626d7d98d..2138b782c53e 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -1050,9 +1050,24 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) if (intrin.op1 != nullptr) { - // If we have an RMW intrinsic, we want to preference op1Reg to the target if - // op1 is not contained. - if (isRMW) + bool simdRegToSimdRegMove = false; + + if ((intrin.id == NI_Vector64_CreateScalarUnsafe) || (intrin.id == NI_Vector128_CreateScalarUnsafe)) + { + simdRegToSimdRegMove = varTypeIsFloating(intrin.op1); + } + else if (intrin.id == NI_AdvSimd_Arm64_DuplicateToVector64) + { + simdRegToSimdRegMove = (intrin.op1->TypeGet() == TYP_DOUBLE); + } + else if ((intrin.id == NI_Vector64_ToScalar) || (intrin.id == NI_Vector128_ToScalar)) + { + simdRegToSimdRegMove = varTypeIsFloating(intrinsicTree); + } + + // If we have an RMW intrinsic or an intrinsic with simple move semantic between two SIMD registers, + // we want to preference op1Reg to the target if op1 is not contained. + if (isRMW || simdRegToSimdRegMove) { tgtPrefOp1 = !intrin.op1->isContained(); } From 9b2f548c3b0da290bc57f1a0460cd0c5c408095e Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Thu, 6 Aug 2020 15:00:33 -0700 Subject: [PATCH 302/755] Allow execution of R2R code in singlefile app on windows. (#40104) * Keep executable PE sections executable in LayoutILOnly. * Install unwind handlers if present * do not do RtlAddFunctionTable on x86 * Check for Cor header before checking for R2R header. * Delete function table in image dtor * Avoid PAGE_EXECUTE_READWRITE, we should not need writeable for R2R * Do relocations in ConvertedImageLayout only if the file is in a bundle. (otherwise R2R stays disabled) --- src/coreclr/src/utilcode/pedecoder.cpp | 29 +++++---- src/coreclr/src/vm/peimagelayout.cpp | 82 ++++++++++++++++++++++---- src/coreclr/src/vm/peimagelayout.h | 8 ++- 3 files changed, 97 insertions(+), 22 deletions(-) diff --git a/src/coreclr/src/utilcode/pedecoder.cpp b/src/coreclr/src/utilcode/pedecoder.cpp index d0854bbc043f..91fde64d297c 100644 --- a/src/coreclr/src/utilcode/pedecoder.cpp +++ b/src/coreclr/src/utilcode/pedecoder.cpp @@ -1770,20 +1770,29 @@ void PEDecoder::LayoutILOnly(void *base, BOOL allowFullPE) const PAGE_READONLY, &oldProtection)) ThrowLastError(); - // Finally, apply proper protection to copied sections - section = sectionStart; - while (section < sectionEnd) + // Finally, apply proper protection to copied sections + for (section = sectionStart; section < sectionEnd; section++) { // Add appropriate page protection. - if ((section->Characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) == 0) +#if defined(CROSSGEN_COMPILE) || defined(TARGET_UNIX) + if (section->Characteristics & IMAGE_SCN_MEM_WRITE) + continue; + + DWORD newProtection = PAGE_READONLY; +#else + DWORD newProtection = section->Characteristics & IMAGE_SCN_MEM_EXECUTE ? + PAGE_EXECUTE_READ : + section->Characteristics & IMAGE_SCN_MEM_WRITE ? + PAGE_READWRITE : + PAGE_READONLY; +#endif + + if (!ClrVirtualProtect((void*)((BYTE*)base + VAL32(section->VirtualAddress)), + VAL32(section->Misc.VirtualSize), + newProtection, &oldProtection)) { - if (!ClrVirtualProtect((void *) ((BYTE *)base + VAL32(section->VirtualAddress)), - VAL32(section->Misc.VirtualSize), - PAGE_READONLY, &oldProtection)) - ThrowLastError(); + ThrowLastError(); } - - section++; } RETURN; diff --git a/src/coreclr/src/vm/peimagelayout.cpp b/src/coreclr/src/vm/peimagelayout.cpp index 88b27ba5d1b0..00098c2748a0 100644 --- a/src/coreclr/src/vm/peimagelayout.cpp +++ b/src/coreclr/src/vm/peimagelayout.cpp @@ -39,7 +39,7 @@ PEImageLayout* PEImageLayout::LoadFromFlat(PEImageLayout* pflatimage) return new ConvertedImageLayout(pflatimage); } -PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner) +PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner, BOOL isInBundle) { STANDARD_VM_CONTRACT; @@ -47,7 +47,7 @@ PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner) if (!pFlat->CheckFormat()) ThrowHR(COR_E_BADIMAGEFORMAT); - return new ConvertedImageLayout(pFlat); + return new ConvertedImageLayout(pFlat, isInBundle); } PEImageLayout* PEImageLayout::Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThrowOnError) @@ -59,7 +59,7 @@ PEImageLayout* PEImageLayout::Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThro #else if (pOwner->IsInBundle()) { - return PEImageLayout::LoadConverted(pOwner); + return PEImageLayout::LoadConverted(pOwner, true); } PEImageLayoutHolder pAlloc(new LoadedImageLayout(pOwner,bNTSafeLoad,bThrowOnError)); @@ -386,7 +386,7 @@ RawImageLayout::RawImageLayout(const void *mapped, PEImage* pOwner, BOOL bTakeOw IfFailThrow(Init((void*)mapped,(bool)(bFixedUp!=FALSE))); } -ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source) +ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source, BOOL isInBundle) { CONTRACTL { @@ -397,23 +397,37 @@ ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source) m_Layout=LAYOUT_LOADED; m_pOwner=source->m_pOwner; _ASSERTE(!source->IsMapped()); + m_isInBundle = isInBundle; + + m_pExceptionDir = NULL; if (!source->HasNTHeaders()) EEFileLoadException::Throw(GetPath(), COR_E_BADIMAGEFORMAT); LOG((LF_LOADER, LL_INFO100, "PEImage: Opening manually mapped stream\n")); +#if !defined(CROSSGEN_COMPILE) && !defined(TARGET_UNIX) + // on Windows we may want to enable execution if the image contains R2R sections + // so must ensure the mapping is compatible with that + m_FileMap.Assign(WszCreateFileMapping(INVALID_HANDLE_VALUE, NULL, + PAGE_EXECUTE_READWRITE, 0, + source->GetVirtualSize(), NULL)); + DWORD allAccess = FILE_MAP_EXECUTE | FILE_MAP_WRITE; +#else m_FileMap.Assign(WszCreateFileMapping(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, - source->GetVirtualSize(), NULL)); + PAGE_READWRITE, 0, + source->GetVirtualSize(), NULL)); + + DWORD allAccess = FILE_MAP_ALL_ACCESS; +#endif + if (m_FileMap == NULL) ThrowLastError(); - - m_FileView.Assign(CLRMapViewOfFile(m_FileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0, + m_FileView.Assign(CLRMapViewOfFile(m_FileMap, allAccess, 0, 0, 0, (void *) source->GetPreferredBase())); if (m_FileView == NULL) - m_FileView.Assign(CLRMapViewOfFile(m_FileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0)); + m_FileView.Assign(CLRMapViewOfFile(m_FileMap, allAccess, 0, 0, 0)); if (m_FileView == NULL) ThrowLastError(); @@ -421,9 +435,57 @@ ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source) source->LayoutILOnly(m_FileView, TRUE); //@TODO should be false for streams IfFailThrow(Init(m_FileView)); -#ifdef CROSSGEN_COMPILE +#if defined(CROSSGEN_COMPILE) if (HasNativeHeader()) + { ApplyBaseRelocations(); + } +#elif !defined(TARGET_UNIX) + if (m_isInBundle && + HasCorHeader() && + (HasNativeHeader() || HasReadyToRunHeader()) && + g_fAllowNativeImages) + { + if (!IsNativeMachineFormat()) + ThrowHR(COR_E_BADIMAGEFORMAT); + + // Do base relocation for PE, if necessary. + // otherwise R2R will be disabled for this image. + ApplyBaseRelocations(); + + // Check if there is a static function table and install it. (except x86) +#if !defined(TARGET_X86) + COUNT_T cbSize = 0; + PT_RUNTIME_FUNCTION pExceptionDir = (PT_RUNTIME_FUNCTION)GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_EXCEPTION, &cbSize); + DWORD tableSize = cbSize / sizeof(T_RUNTIME_FUNCTION); + + if (pExceptionDir != NULL) + { + if (!RtlAddFunctionTable(pExceptionDir, tableSize, (DWORD64)this->GetBase())) + ThrowLastError(); + + m_pExceptionDir = pExceptionDir; + } +#endif //TARGET_X86 + } +#endif +} + +ConvertedImageLayout::~ConvertedImageLayout() +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + +#if !defined(CROSSGEN_COMPILE) && !defined(TARGET_UNIX) && !defined(TARGET_X86) + if (m_pExceptionDir) + { + RtlDeleteFunctionTable(m_pExceptionDir); + } #endif } diff --git a/src/coreclr/src/vm/peimagelayout.h b/src/coreclr/src/vm/peimagelayout.h index 7a0242de4f22..b5b0573a376f 100644 --- a/src/coreclr/src/vm/peimagelayout.h +++ b/src/coreclr/src/vm/peimagelayout.h @@ -53,7 +53,7 @@ class PEImageLayout : public PEDecoder static PEImageLayout* LoadFromFlat(PEImageLayout* pflatimage); static PEImageLayout* Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThrowOnError = TRUE); static PEImageLayout* LoadFlat(PEImage* pOwner); - static PEImageLayout* LoadConverted(PEImage* pOwner); + static PEImageLayout* LoadConverted(PEImage* pOwner, BOOL isInBundle = FALSE); static PEImageLayout* LoadNative(LPCWSTR fullPath); static PEImageLayout* Map(PEImage* pOwner); #endif @@ -109,8 +109,12 @@ class ConvertedImageLayout: public PEImageLayout CLRMapViewHolder m_FileView; public: #ifndef DACCESS_COMPILE - ConvertedImageLayout(PEImageLayout* source); + ConvertedImageLayout(PEImageLayout* source, BOOL isInBundle = FALSE); + virtual ~ConvertedImageLayout(); #endif +private: + bool m_isInBundle; + PT_RUNTIME_FUNCTION m_pExceptionDir; }; class MappedImageLayout: public PEImageLayout From e2b42c53045dee35e8f318ded412c26614ce3445 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Thu, 6 Aug 2020 16:08:09 -0700 Subject: [PATCH 303/755] import array access as OBJ for structs. (#40488) --- src/coreclr/src/jit/importer.cpp | 13 +- .../JitBlue/Runtime_40440/Runtime_40440.cs | 175 ++++++++++++++++++ .../Runtime_40440/Runtime_40440.csproj | 12 ++ 3 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.csproj diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 8d485e6eac70..5e575d1f2f49 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -1392,8 +1392,8 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, } else if (asgType == TYP_STRUCT) { - asgType = impNormStructType(structHnd); - src->gtType = asgType; + // It should already have the appropriate type. + assert(asgType == impNormStructType(structHnd)); } if ((dest == nullptr) && (destAddr->OperGet() == GT_ADDR)) { @@ -4886,7 +4886,14 @@ GenTree* Compiler::impArrayAccessIntrinsic( if (intrinsicID != CORINFO_INTRINSIC_Array_Address) { - arrElem = gtNewOperNode(GT_IND, elemType, arrElem); + if (varTypeIsStruct(elemType)) + { + arrElem = gtNewObjNode(sig->retTypeClass, arrElem); + } + else + { + arrElem = gtNewOperNode(GT_IND, elemType, arrElem); + } } if (intrinsicID == CORINFO_INTRINSIC_Array_Set) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.cs b/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.cs new file mode 100644 index 000000000000..000045a5f3d8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.cs @@ -0,0 +1,175 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Diagnostics; +using System.Runtime.Intrinsics; +using System.Security.Cryptography; + +class Runtime_40440 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static bool UseArrayElementAsCallArgument(T[,,] a, T b) + { + return G(b, a[1, 2, 3]); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool G(T a, T b) + { + if (typeof(T) == typeof(Vector)) + { + return (Vector)(object)a == (Vector)(object)b; + } + else if (typeof(T) == typeof(Vector2)) + { + return (Vector2)(object)a == (Vector2)(object)b; + } + else if (typeof(T) == typeof(Vector3)) + { + return (Vector3)(object)a == (Vector3)(object)b; + } + else if (typeof(T) == typeof(Vector4)) + { + return (Vector4)(object)a == (Vector4)(object)b; + } + else if (typeof(T) == typeof(Vector64)) + { + return a.Equals(b); + } + else if (typeof(T) == typeof(SmallStruct)) + { + return a.Equals(b); + } + else if (typeof(T) == typeof(LargeStruct)) + { + return a.Equals(b); + } + return false; + } + + static bool CheckVectorFloat() + { + var v = new Vector[4, 4, 4]; + var e = new Vector(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + static bool CheckVector2() + { + var v = new Vector2[4, 4, 4]; + var e = new Vector2(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + static bool CheckVector3() + { + var v = new Vector3[4, 4, 4]; + var e = new Vector3(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + static bool CheckVector4() + { + var v = new Vector3[4, 4, 4]; + var e = new Vector3(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + static bool CheckVector64() + { + var v = new Vector64[4, 4, 4]; + var e = Vector64.Create(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + struct SmallStruct + { + float f; + + public SmallStruct(float f) + { + this.f = f; + } + + public override bool Equals(object obj) + { + if (!(obj is SmallStruct)) + { + return false; + } + return f == ((SmallStruct)obj).f; + } + } + + static bool CheckSmallStruct() + { + var v = new SmallStruct[4, 4, 4]; + var e = new SmallStruct(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + struct LargeStruct + { + float f1; + float f2; + float f3; + float f4; + float f5; + + public LargeStruct(float f) + { + f1 = f; + f2 = f; + f3 = f; + f4 = f; + f5 = f; + } + + public override bool Equals(object obj) + { + if (!(obj is LargeStruct)) + { + return false; + } + LargeStruct s2 = (LargeStruct)obj; + return (f1 == s2.f1) && (f2 == s2.f2) && (f3 == s2.f3) && (f4 == s2.f4) && (f5 == s2.f5); + } + } + + static bool CheckBigStruct() + { + var v = new LargeStruct[4, 4, 4]; + var e = new LargeStruct(33f); + v[1, 2, 3] = e; + return UseArrayElementAsCallArgument(v, e); + } + + public static int Main() + { + bool f = true; + f &= CheckVectorFloat(); + Debug.Assert(f); + f &= CheckVector2(); + Debug.Assert(f); + f &= CheckVector3(); + Debug.Assert(f); + f &= CheckVector4(); + Debug.Assert(f); + f &= CheckVector64(); + Debug.Assert(f); + f &= CheckSmallStruct(); + Debug.Assert(f); + f &= CheckBigStruct(); + Debug.Assert(f); + + return f ? 100 : 0; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.csproj new file mode 100644 index 000000000000..986494e092b5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_40440/Runtime_40440.csproj @@ -0,0 +1,12 @@ + + + Exe + + + + True + + + + + From fe81abd171228e738bdea44aedb86acc9b32f239 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 6 Aug 2020 16:44:35 -0700 Subject: [PATCH 304/755] Remove workaround in DefaultValueAttributeCtorTest trimming test (#40448) --- .../tests/TrimmingTests/DefaultValueAttributeCtorTest.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libraries/System.Runtime/tests/TrimmingTests/DefaultValueAttributeCtorTest.cs b/src/libraries/System.Runtime/tests/TrimmingTests/DefaultValueAttributeCtorTest.cs index 0aa104fb79f9..1d9a6ec40126 100644 --- a/src/libraries/System.Runtime/tests/TrimmingTests/DefaultValueAttributeCtorTest.cs +++ b/src/libraries/System.Runtime/tests/TrimmingTests/DefaultValueAttributeCtorTest.cs @@ -13,10 +13,6 @@ class Program { static int Main(string[] args) { - // workaround TypeConverterAttribute not being annotated correctly - // https://github.com/dotnet/runtime/issues/39125 - var _ = new MyStringConverter(); - TypeDescriptor.AddAttributes(typeof(string), new TypeConverterAttribute(typeof(MyStringConverter))); var attribute = new DefaultValueAttribute(typeof(string), "Hello, world!"); From 0e73b9ba818148078f07c8db21fe6e6b7df54251 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 6 Aug 2020 16:48:52 -0700 Subject: [PATCH 305/755] Fix gc stress coverage handling of epilogs on X86 (#40432) Epilog checking relies on precise control of when instrumentation for the first prolog instruction is enabled or disabled. In particular, if a function has multiple epilogs, or the first execution of the function terminates via an exception, and subsequent completions do not, then the function may trigger a false stress fault if epilog checks are not disabled. This fix makes it so that if the first instruction is hit during a GC coverage in a situation where the epilog could be examined in the future, that the epilog verification is disabled. Also an opportunistic fix for a probably unimportant race condition around checking the callerThread during epilog processing. --- src/coreclr/src/vm/gccover.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/coreclr/src/vm/gccover.cpp b/src/coreclr/src/vm/gccover.cpp index 2f6001a0858f..cbe3873f364f 100644 --- a/src/coreclr/src/vm/gccover.cpp +++ b/src/coreclr/src/vm/gccover.cpp @@ -1222,7 +1222,7 @@ bool IsGcCoverageInterrupt(LPVOID ip) // original instruction. Only one instruction must be used, // because multiple threads can be executing the same code stream. -void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr) +void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr, GCCoverageInfo* gcCover, DWORD offset) { #ifdef TARGET_ARM if (GetARMInstructionLength(savedInstrPtr) == 2) @@ -1235,6 +1235,17 @@ void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr) *(BYTE *)instrPtr = *savedInstrPtr; #endif +#ifdef TARGET_X86 + // Epilog checking relies on precise control of when instrumentation for the first prolog + // instruction is enabled or disabled. In particular, if a function has multiple epilogs, or + // the first execution of the function terminates via an exception, and subsequent completions + // do not, then the function may trigger a false stress fault if epilog checks are not disabled. + if (offset == 0) + { + gcCover->doingEpilogChecks = false; + } +#endif // TARGET_X86 + FlushInstructionCache(GetCurrentProcess(), (LPCVOID)instrPtr, 4); } @@ -1290,7 +1301,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs) // where the call could be coming from a thread unknown to the CLR and // we haven't created a thread yet - see PreStubWorker_Preemptive(). _ASSERTE(pMD->HasUnmanagedCallersOnlyAttribute()); - RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr); + RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr, gcCover, offset); return TRUE; } @@ -1304,7 +1315,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs) // anything for this method at this point. if (!pThread->PreemptiveGCDisabled() && pMD->HasUnmanagedCallersOnlyAttribute()) { - RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr); + RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr, gcCover, offset); return TRUE; } @@ -1315,7 +1326,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs) Frame* pFrame = pThread->GetFrame(); if (InlinedCallFrame::FrameHasActiveCall(pFrame)) { - RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr); + RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr, gcCover, offset); return TRUE; } } @@ -1325,7 +1336,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs) // location. if (!pThread->CheckForAndDoRedirectForGCStress(regs)) { - RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr); + RemoveGcCoverageInterrupt(instrPtr, savedInstrPtr, gcCover, offset); } #else // !USE_REDIRECT_FOR_GCSTRESS @@ -1440,12 +1451,10 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) bool bShouldUpdateProlog = true; if (gcCover->doingEpilogChecks) { if (offset == 0) { - if (gcCover->callerThread == 0) { - if (FastInterlockCompareExchangePointer(&gcCover->callerThread, pThread, 0) == 0) { - gcCover->callerRegs = *regs; - gcCover->gcCount = GCHeapUtilities::GetGCHeap()->GetGcCount(); - bShouldUpdateProlog = false; - } + if ((gcCover->callerThread == 0) && (FastInterlockCompareExchangePointer(&gcCover->callerThread, pThread, 0) == 0)) { + gcCover->callerRegs = *regs; + gcCover->gcCount = GCHeapUtilities::GetGCHeap()->GetGcCount(); + bShouldUpdateProlog = false; } else { // We have been in this routine before. Give up on epilog checking because From 9c6ef07c34f0be0f78f3d76da7d17d6ad77509a2 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Thu, 6 Aug 2020 17:00:09 -0700 Subject: [PATCH 306/755] Add nullability annotations for *XPath* files in Xml/Dom and Xml/Xsl (#40295) * Add nullability annotations for *XPath* files in Xml/Dom and Xml/Xsl * Fix build issues * Address feedback * Add TODO for replacing MaybeNull attributes --- .../System/Xml/Dom/DocumentXPathNavigator.cs | 326 +++++++++--------- .../src/System/Xml/Dom/DocumentXmlWriter.cs | 2 +- .../src/System/Xml/Dom/XmlElement.cs | 4 +- .../src/System/Xml/Dom/XmlNode.cs | 2 +- .../System/Xml/Xsl/XPath/IXPathEnvironment.cs | 1 + .../src/System/Xml/Xsl/XPath/IXpathBuilder.cs | 11 +- .../src/System/Xml/Xsl/XPath/XPathAxis.cs | 1 + .../src/System/Xml/Xsl/XPath/XPathBuilder.cs | 57 +-- .../Xml/Xsl/XPath/XPathCompileException.cs | 13 +- .../src/System/Xml/Xsl/XPath/XPathContext.cs | 1 + .../src/System/Xml/Xsl/XPath/XPathOperator.cs | 1 + .../src/System/Xml/Xsl/XPath/XPathParser.cs | 75 ++-- .../System/Xml/Xsl/XPath/XPathQilFactory.cs | 5 +- .../src/System/Xml/Xsl/XPath/XPathScanner.cs | 9 +- .../src/System/Xml/Xsl/XPathConvert.cs | 5 +- .../Xml/Xsl/Xslt/XPathPatternBuilder.cs | 21 +- .../System/Xml/Xsl/Xslt/XPathPatternParser.cs | 49 +-- 17 files changed, 307 insertions(+), 276 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXPathNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXPathNavigator.cs index 2b9f90a9523e..c9c16dda81cd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXPathNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXPathNavigator.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -8,6 +9,7 @@ using System.Xml.Schema; using System.Xml.XPath; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -16,7 +18,7 @@ internal sealed class DocumentXPathNavigator : XPathNavigator, IHasXmlNode private readonly XmlDocument _document; // owner document private XmlNode _source; // navigator position private int _attributeIndex; // index in attribute collection for attribute - private XmlElement _namespaceParent; // parent for namespace + private XmlElement? _namespaceParent; // parent for namespace public DocumentXPathNavigator(XmlDocument document, XmlNode node) { @@ -70,7 +72,7 @@ public override void SetValue(string value) { throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly); } - DeleteToFollowingSibling(node.NextSibling, end); + DeleteToFollowingSibling(node.NextSibling!, end); } goto case XmlNodeType.Element; case XmlNodeType.Element: @@ -113,8 +115,7 @@ public override string NamespaceURI { get { - XmlAttribute attribute = _source as XmlAttribute; - if (attribute != null + if (_source is XmlAttribute attribute && attribute.IsNamespace) { return string.Empty; @@ -153,8 +154,7 @@ public override string Prefix { get { - XmlAttribute attribute = _source as XmlAttribute; - if (attribute != null + if (_source is XmlAttribute attribute && attribute.IsNamespace) { return string.Empty; @@ -180,6 +180,11 @@ public override string Value case XmlNodeType.SignificantWhitespace: return ValueText; default: + Debug.Assert(_source.Value != null); + // TODO-NULLABLE: Consider switching this.Value to nullable even if that implies switching it in the base type. + // Also consider the following: + // * this.SetValue() does not accept null. + // * _source.Value is nullable. return _source.Value; } } @@ -189,7 +194,7 @@ private string ValueDocument { get { - XmlElement element = _document.DocumentElement; + XmlElement? element = _document.DocumentElement; if (element != null) { return element.InnerText; @@ -204,8 +209,8 @@ private string ValueText { CalibrateText(); - string value = _source.Value; - XmlNode nextSibling = NextSibling(_source); + string? value = _source.Value; + XmlNode? nextSibling = NextSibling(_source); if (nextSibling != null && nextSibling.IsText) { @@ -219,6 +224,9 @@ private string ValueText && nextSibling.IsText); value = builder.ToString(); } + // TODO-NULLABLE: Consider making this nullable given that _source.Value is nullable, + // OR we could change this getter to return string.Empty if _source.Value == null. + Debug.Assert(value != null); return value; } } @@ -235,8 +243,7 @@ public override bool IsEmptyElement { get { - XmlElement element = _source as XmlElement; - if (element != null) + if (_source is XmlElement element) { return element.IsEmpty; } @@ -266,8 +273,7 @@ public override bool HasAttributes { get { - XmlElement element = _source as XmlElement; - if (element != null + if (_source is XmlElement element && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; @@ -291,8 +297,7 @@ public override string GetAttribute(string localName, string namespaceURI) public override bool MoveToAttribute(string localName, string namespaceURI) { - XmlElement element = _source as XmlElement; - if (element != null + if (_source is XmlElement element && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; @@ -320,8 +325,7 @@ public override bool MoveToAttribute(string localName, string namespaceURI) public override bool MoveToFirstAttribute() { - XmlElement element = _source as XmlElement; - if (element != null + if (_source is XmlElement element && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; @@ -341,13 +345,12 @@ public override bool MoveToFirstAttribute() public override bool MoveToNextAttribute() { - XmlAttribute attribute = _source as XmlAttribute; - if (attribute == null + if (!(_source is XmlAttribute attribute) || attribute.IsNamespace) { return false; } - XmlAttributeCollection attributes; + XmlAttributeCollection? attributes; if (!CheckAttributePosition(attribute, out attributes, _attributeIndex) && !ResetAttributePosition(attribute, attributes, out _attributeIndex)) { @@ -368,12 +371,11 @@ public override bool MoveToNextAttribute() public override string GetNamespace(string name) { - XmlNode node = _source; + XmlNode? node = _source; while (node != null && node.NodeType != XmlNodeType.Element) { - XmlAttribute attribute = node as XmlAttribute; - if (attribute != null) + if (node is XmlAttribute attribute) { node = attribute.OwnerElement; } @@ -383,7 +385,7 @@ public override string GetNamespace(string name) } } - XmlElement element = node as XmlElement; + XmlElement? element = node as XmlElement; if (element != null) { string localName; @@ -400,7 +402,7 @@ public override string GetNamespace(string name) do { - XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); + XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return attribute.Value; @@ -427,7 +429,7 @@ public override bool MoveToNamespace(string name) { return false; } - XmlElement element = _source as XmlElement; + XmlElement? element = _source as XmlElement; if (element != null) { string localName; @@ -444,7 +446,7 @@ public override bool MoveToNamespace(string name) do { - XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); + XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { _namespaceParent = (XmlElement)_source; @@ -467,8 +469,7 @@ public override bool MoveToNamespace(string name) public override bool MoveToFirstNamespace(XPathNamespaceScope scope) { - XmlElement element = _source as XmlElement; - if (element == null) + if (!(_source is XmlElement element)) { return false; } @@ -553,7 +554,7 @@ private static bool MoveToFirstNamespaceGlobal(ref XmlAttributeCollection attrib } Debug.Assert(attributes != null && attributes.parent != null); - XmlElement element = attributes.parent.ParentNode as XmlElement; + XmlElement? element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) @@ -571,13 +572,12 @@ private static bool MoveToFirstNamespaceGlobal(ref XmlAttributeCollection attrib public override bool MoveToNextNamespace(XPathNamespaceScope scope) { - XmlAttribute attribute = _source as XmlAttribute; - if (attribute == null + if (!(_source is XmlAttribute attribute) || !attribute.IsNamespace) { return false; } - XmlAttributeCollection attributes; + XmlAttributeCollection? attributes; int index = _attributeIndex; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) @@ -668,7 +668,7 @@ private static bool MoveToNextNamespaceGlobal(ref XmlAttributeCollection attribu } Debug.Assert(attributes != null && attributes.parent != null); - XmlElement element = attributes.parent.ParentNode as XmlElement; + XmlElement? element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) @@ -684,25 +684,26 @@ private static bool MoveToNextNamespaceGlobal(ref XmlAttributeCollection attribu return false; } - private bool PathHasDuplicateNamespace(XmlElement top, XmlElement bottom, string localName) + private bool PathHasDuplicateNamespace(XmlElement? top, XmlElement bottom, string localName) { + XmlElement? current = bottom; string namespaceUri = _document.strReservedXmlns; - while (bottom != null - && bottom != top) + while (current != null + && current != top) { - XmlAttribute attribute = bottom.GetAttributeNode(localName, namespaceUri); + XmlAttribute? attribute = current.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return true; } - bottom = bottom.ParentNode as XmlElement; + current = current.ParentNode as XmlElement; } return false; } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { - string ns = base.LookupNamespace(prefix); + string? ns = base.LookupNamespace(prefix); if (ns != null) { ns = this.NameTable.Add(ns); @@ -712,7 +713,7 @@ public override string LookupNamespace(string prefix) public override bool MoveToNext() { - XmlNode sibling = NextSibling(_source); + XmlNode? sibling = NextSibling(_source); if (sibling == null) { return false; @@ -728,7 +729,7 @@ public override bool MoveToNext() } } } - XmlNode parent = ParentNode(sibling); + XmlNode? parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { @@ -744,7 +745,7 @@ public override bool MoveToNext() public override bool MoveToPrevious() { - XmlNode sibling = PreviousSibling(_source); + XmlNode? sibling = PreviousSibling(_source); if (sibling == null) { return false; @@ -764,7 +765,7 @@ public override bool MoveToPrevious() sibling = TextStart(sibling); } } - XmlNode parent = ParentNode(sibling); + XmlNode? parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { @@ -787,12 +788,12 @@ public override bool MoveToFirst() { return false; } - XmlNode parent = ParentNode(_source); + XmlNode? parent = ParentNode(_source); if (parent == null) { return false; } - XmlNode sibling = FirstChild(parent); + XmlNode? sibling = FirstChild(parent); Debug.Assert(sibling != null); while (!IsValidChild(parent, sibling)) { @@ -808,7 +809,7 @@ public override bool MoveToFirst() public override bool MoveToFirstChild() { - XmlNode child; + XmlNode? child; switch (_source.NodeType) { case XmlNodeType.Element: @@ -843,14 +844,13 @@ public override bool MoveToFirstChild() public override bool MoveToParent() { - XmlNode parent = ParentNode(_source); + XmlNode? parent = ParentNode(_source); if (parent != null) { _source = parent; return true; } - XmlAttribute attribute = _source as XmlAttribute; - if (attribute != null) + if (_source is XmlAttribute attribute) { parent = attribute.IsNamespace ? _namespaceParent : attribute.OwnerElement; if (parent != null) @@ -867,11 +867,10 @@ public override void MoveToRoot() { while (true) { - XmlNode parent = _source.ParentNode; + XmlNode? parent = _source.ParentNode; if (parent == null) { - XmlAttribute attribute = _source as XmlAttribute; - if (attribute == null) + if (!(_source is XmlAttribute attribute)) { break; } @@ -888,8 +887,7 @@ public override void MoveToRoot() public override bool MoveTo(XPathNavigator other) { - DocumentXPathNavigator that = other as DocumentXPathNavigator; - if (that != null + if (other is DocumentXPathNavigator that && _document == that._document) { _source = that._source; @@ -902,7 +900,7 @@ public override bool MoveTo(XPathNavigator other) public override bool MoveToId(string id) { - XmlElement element = _document.GetElementById(id); + XmlElement? element = _document.GetElementById(id); if (element != null) { _source = element; @@ -919,7 +917,7 @@ public override bool MoveToChild(string localName, string namespaceUri) return false; } - XmlNode child = FirstChild(_source); + XmlNode? child = FirstChild(_source); if (child != null) { do @@ -945,7 +943,7 @@ public override bool MoveToChild(XPathNodeType type) return false; } - XmlNode child = FirstChild(_source); + XmlNode? child = FirstChild(_source); if (child != null) { int mask = GetContentKindMask(type); @@ -967,11 +965,10 @@ public override bool MoveToChild(XPathNodeType type) return false; } - public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator end) + public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator? end) { - XmlNode pastFollowing = null; - DocumentXPathNavigator that = end as DocumentXPathNavigator; - if (that != null) + XmlNode? pastFollowing = null; + if (end is DocumentXPathNavigator that) { if (_document != that._document) { @@ -990,7 +987,7 @@ public override bool MoveToFollowing(string localName, string namespaceUri, XPat pastFollowing = that._source; } - XmlNode following = _source; + XmlNode? following = _source; if (following.NodeType == XmlNodeType.Attribute) { following = ((XmlAttribute)following).OwnerElement; @@ -1001,7 +998,7 @@ public override bool MoveToFollowing(string localName, string namespaceUri, XPat } do { - XmlNode firstChild = following.FirstChild; + XmlNode? firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; @@ -1010,7 +1007,7 @@ public override bool MoveToFollowing(string localName, string namespaceUri, XPat { while (true) { - XmlNode nextSibling = following.NextSibling; + XmlNode? nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; @@ -1018,7 +1015,7 @@ public override bool MoveToFollowing(string localName, string namespaceUri, XPat } else { - XmlNode parent = following.ParentNode; + XmlNode? parent = following.ParentNode; if (parent != null) { following = parent; @@ -1043,11 +1040,10 @@ public override bool MoveToFollowing(string localName, string namespaceUri, XPat return true; } - public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) + public override bool MoveToFollowing(XPathNodeType type, XPathNavigator? end) { - XmlNode pastFollowing = null; - DocumentXPathNavigator that = end as DocumentXPathNavigator; - if (that != null) + XmlNode? pastFollowing = null; + if (end is DocumentXPathNavigator that) { if (_document != that._document) { @@ -1071,7 +1067,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { return false; } - XmlNode following = _source; + XmlNode? following = _source; switch (following.NodeType) { case XmlNodeType.Attribute: @@ -1090,7 +1086,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) } do { - XmlNode firstChild = following.FirstChild; + XmlNode? firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; @@ -1099,7 +1095,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { while (true) { - XmlNode nextSibling = following.NextSibling; + XmlNode? nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; @@ -1107,7 +1103,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) } else { - XmlNode parent = following.ParentNode; + XmlNode? parent = following.ParentNode; if (parent != null) { following = parent; @@ -1132,7 +1128,7 @@ public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) public override bool MoveToNext(string localName, string namespaceUri) { - XmlNode sibling = NextSibling(_source); + XmlNode? sibling = NextSibling(_source); if (sibling == null) { return false; @@ -1154,7 +1150,7 @@ public override bool MoveToNext(string localName, string namespaceUri) public override bool MoveToNext(XPathNodeType type) { - XmlNode sibling = NextSibling(_source); + XmlNode? sibling = NextSibling(_source); if (sibling == null) { return false; @@ -1191,7 +1187,7 @@ public override bool HasChildren { get { - XmlNode child; + XmlNode? child; switch (_source.NodeType) { case XmlNodeType.Element: @@ -1225,8 +1221,7 @@ public override bool HasChildren public override bool IsSamePosition(XPathNavigator other) { - DocumentXPathNavigator that = other as DocumentXPathNavigator; - if (that != null) + if (other is DocumentXPathNavigator that) { this.CalibrateText(); that.CalibrateText(); @@ -1237,10 +1232,9 @@ public override bool IsSamePosition(XPathNavigator other) return false; } - public override bool IsDescendant(XPathNavigator other) + public override bool IsDescendant(XPathNavigator? other) { - DocumentXPathNavigator that = other as DocumentXPathNavigator; - if (that != null) + if (other is DocumentXPathNavigator that) { return IsDescendant(_source, that._source); } @@ -1257,7 +1251,7 @@ public override IXmlSchemaInfo SchemaInfo public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) { - XmlDocument ownerDocument; + XmlDocument? ownerDocument; if (_source.NodeType == XmlNodeType.Document) { @@ -1282,20 +1276,21 @@ public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler throw new InvalidOperationException(SR.XmlDocument_NoSchemaInfo); } + // DocumentSchemaValidator assumes that ownedDocument can never be null. + Debug.Assert(ownerDocument != null); DocumentSchemaValidator validator = new DocumentSchemaValidator(ownerDocument, schemas, validationEventHandler); validator.PsviAugmentation = false; return validator.Validate(_source); } - private static XmlNode OwnerNode(XmlNode node) + private static XmlNode? OwnerNode(XmlNode node) { - XmlNode parent = node.ParentNode; + XmlNode? parent = node.ParentNode; if (parent != null) { return parent; } - XmlAttribute attribute = node as XmlAttribute; - if (attribute != null) + if (node is XmlAttribute attribute) { return attribute.OwnerElement; } @@ -1305,7 +1300,7 @@ private static XmlNode OwnerNode(XmlNode node) private static int GetDepth(XmlNode node) { int depth = 0; - XmlNode owner = OwnerNode(node); + XmlNode? owner = OwnerNode(node); while (owner != null) { depth++; @@ -1327,7 +1322,8 @@ private XmlNodeOrder Compare(XmlNode node1, XmlNode node2) { if (node2.XPNodeType == XPathNodeType.Attribute) { - XmlElement element = ((XmlAttribute)node1).OwnerElement; + XmlElement? element = ((XmlAttribute)node1).OwnerElement; + Debug.Assert(element != null); if (element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; @@ -1357,7 +1353,7 @@ private XmlNodeOrder Compare(XmlNode node1, XmlNode node2) } //neither of the node is Namespace node or Attribute node - XmlNode nextNode = node1.NextSibling; + XmlNode? nextNode = node1.NextSibling; while (nextNode != null && nextNode != node2) nextNode = nextNode.NextSibling; if (nextNode == null) @@ -1368,10 +1364,9 @@ private XmlNodeOrder Compare(XmlNode node1, XmlNode node2) return XmlNodeOrder.Before; } - public override XmlNodeOrder ComparePosition(XPathNavigator other) + public override XmlNodeOrder ComparePosition(XPathNavigator? other) { - DocumentXPathNavigator that = other as DocumentXPathNavigator; - if (that == null) + if (!(other is DocumentXPathNavigator that)) { return XmlNodeOrder.Unknown; } @@ -1391,11 +1386,11 @@ public override XmlNodeOrder ComparePosition(XPathNavigator other) return base.ComparePosition(other); } - XmlNode node1 = _source; - XmlNode node2 = that._source; + XmlNode? node1 = _source; + XmlNode? node2 = that._source; - XmlNode parent1 = OwnerNode(node1); - XmlNode parent2 = OwnerNode(node2); + XmlNode? parent1 = OwnerNode(node1); + XmlNode? parent2 = OwnerNode(node2); if (parent1 == parent2) { if (parent1 == null) @@ -1423,6 +1418,7 @@ public override XmlNodeOrder ComparePosition(XPathNavigator other) { return XmlNodeOrder.Before; } + Debug.Assert(node2 != null); parent2 = OwnerNode(node2); } else if (depth1 > depth2) @@ -1437,6 +1433,7 @@ public override XmlNodeOrder ComparePosition(XPathNavigator other) { return XmlNodeOrder.After; } + Debug.Assert(node1 != null); parent1 = OwnerNode(node1); } @@ -1461,13 +1458,13 @@ public override XmlNodeOrder ComparePosition(XPathNavigator other) public override XPathNodeIterator SelectDescendants(string localName, string namespaceURI, bool matchSelf) { - string nsAtom = _document.NameTable.Get(namespaceURI); + string? nsAtom = _document.NameTable.Get(namespaceURI); if (nsAtom == null || _source.NodeType == XmlNodeType.Attribute) return new DocumentXPathNodeIterator_Empty(this); Debug.Assert(this.NodeType != XPathNodeType.Attribute && this.NodeType != XPathNodeType.Namespace && this.NodeType != XPathNodeType.All); - string localNameAtom = _document.NameTable.Get(localName); + string? localNameAtom = _document.NameTable.Get(localName); if (localNameAtom == null) return new DocumentXPathNodeIterator_Empty(this); @@ -1606,8 +1603,7 @@ public override XmlWriter CreateAttributes() public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace) { - DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator; - if (that == null) + if (!(lastSiblingToReplace is DocumentXPathNavigator that)) { if (lastSiblingToReplace == null) { @@ -1664,8 +1660,7 @@ public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace) public override void DeleteRange(XPathNavigator lastSiblingToDelete) { - DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator; - if (that == null) + if (!(lastSiblingToDelete is DocumentXPathNavigator that)) { if (lastSiblingToDelete == null) { @@ -1693,7 +1688,7 @@ public override void DeleteRange(XPathNavigator lastSiblingToDelete) { goto default; } - XmlNode parent = OwnerNode(attribute); + XmlNode? parent = OwnerNode(attribute); DeleteAttribute(attribute, _attributeIndex); if (parent != null) { @@ -1730,7 +1725,7 @@ public override void DeleteRange(XPathNavigator lastSiblingToDelete) { throw new InvalidOperationException(SR.Xpn_BadPosition); } - XmlNode parent = OwnerNode(node); + XmlNode? parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { @@ -1752,7 +1747,7 @@ public override void DeleteSelf() { goto default; } - XmlNode parent = OwnerNode(attribute); + XmlNode? parent = OwnerNode(attribute); DeleteAttribute(attribute, _attributeIndex); if (parent != null) { @@ -1785,7 +1780,7 @@ public override void DeleteSelf() private static void DeleteAttribute(XmlAttribute attribute, int index) { - XmlAttributeCollection attributes; + XmlAttributeCollection? attributes; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) @@ -1801,7 +1796,7 @@ private static void DeleteAttribute(XmlAttribute attribute, int index) internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end) { - XmlNode parent = node.ParentNode; + XmlNode? parent = node.ParentNode; if (parent == null) { @@ -1814,22 +1809,22 @@ internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end) } while (node != end) { + Debug.Assert(node != null, "This method needs to be called with the beforehand check of NextSibling being not null from node to end"); XmlNode temp = node; - node = node.NextSibling; + node = node.NextSibling!; parent.RemoveChild(temp); } parent.RemoveChild(node); } - private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument document) + private static XmlNamespaceManager GetNamespaceManager(XmlNode? node, XmlDocument document) { XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable); List elements = new List(); while (node != null) { - XmlElement element = node as XmlElement; - if (element != null + if (node is XmlElement element && element.HasAttributes) { elements.Add(element); @@ -1853,15 +1848,15 @@ private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument return namespaceManager; } + [MemberNotNull(nameof(_source))] internal void ResetPosition(XmlNode node) { Debug.Assert(node != null, "Undefined navigator position"); Debug.Assert(node == _document || node.OwnerDocument == _document, "Navigator switched documents"); _source = node; - XmlAttribute attribute = node as XmlAttribute; - if (attribute != null) + if (node is XmlAttribute attribute) { - XmlElement element = attribute.OwnerElement; + XmlElement? element = attribute.OwnerElement; if (element != null) { ResetAttributePosition(attribute, element.Attributes, out _attributeIndex); @@ -1873,7 +1868,7 @@ internal void ResetPosition(XmlNode node) } } - private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeCollection attributes, out int index) + private static bool ResetAttributePosition(XmlAttribute attribute, [NotNullWhen(true)] XmlAttributeCollection? attributes, out int index) { if (attributes != null) { @@ -1890,9 +1885,9 @@ private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeC return false; } - private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttributeCollection attributes, int index) + private static bool CheckAttributePosition(XmlAttribute attribute, [NotNullWhen(true)] out XmlAttributeCollection? attributes, int index) { - XmlElement element = attribute.OwnerElement; + XmlElement? element = attribute.OwnerElement; if (element != null) { attributes = element.Attributes; @@ -1912,7 +1907,7 @@ private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttrib private void CalibrateText() { - XmlNode text = PreviousText(_source); + XmlNode? text = PreviousText(_source); while (text != null) { ResetPosition(text); @@ -1920,9 +1915,9 @@ private void CalibrateText() } } - private XmlNode ParentNode(XmlNode node) + private XmlNode? ParentNode(XmlNode node) { - XmlNode parent = node.ParentNode; + XmlNode? parent = node.ParentNode; if (!_document.HasEntityReferences) { @@ -1931,7 +1926,7 @@ private XmlNode ParentNode(XmlNode node) return ParentNodeTail(parent); } - private XmlNode ParentNodeTail(XmlNode parent) + private XmlNode? ParentNodeTail(XmlNode? parent) { while (parent != null && parent.NodeType == XmlNodeType.EntityReference) @@ -1941,9 +1936,9 @@ private XmlNode ParentNodeTail(XmlNode parent) return parent; } - private XmlNode FirstChild(XmlNode node) + private XmlNode? FirstChild(XmlNode node) { - XmlNode child = node.FirstChild; + XmlNode? child = node.FirstChild; if (!_document.HasEntityReferences) { @@ -1952,7 +1947,7 @@ private XmlNode FirstChild(XmlNode node) return FirstChildTail(child); } - private XmlNode FirstChildTail(XmlNode child) + private XmlNode? FirstChildTail(XmlNode? child) { while (child != null && child.NodeType == XmlNodeType.EntityReference) @@ -1962,9 +1957,9 @@ private XmlNode FirstChildTail(XmlNode child) return child; } - private XmlNode NextSibling(XmlNode node) + private XmlNode? NextSibling(XmlNode node) { - XmlNode sibling = node.NextSibling; + XmlNode? sibling = node.NextSibling; if (!_document.HasEntityReferences) { @@ -1973,17 +1968,18 @@ private XmlNode NextSibling(XmlNode node) return NextSiblingTail(node, sibling); } - private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling) + private XmlNode? NextSiblingTail(XmlNode node, XmlNode? sibling) { + XmlNode? current = node; while (sibling == null) { - node = node.ParentNode; - if (node == null - || node.NodeType != XmlNodeType.EntityReference) + current = current.ParentNode; + if (current == null + || current.NodeType != XmlNodeType.EntityReference) { return null; } - sibling = node.NextSibling; + sibling = current.NextSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) @@ -1993,9 +1989,9 @@ private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling) return sibling; } - private XmlNode PreviousSibling(XmlNode node) + private XmlNode? PreviousSibling(XmlNode node) { - XmlNode sibling = node.PreviousSibling; + XmlNode? sibling = node.PreviousSibling; if (!_document.HasEntityReferences) { @@ -2004,17 +2000,18 @@ private XmlNode PreviousSibling(XmlNode node) return PreviousSiblingTail(node, sibling); } - private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling) + private XmlNode? PreviousSiblingTail(XmlNode node, XmlNode? sibling) { + XmlNode? current = node; while (sibling == null) { - node = node.ParentNode; - if (node == null - || node.NodeType != XmlNodeType.EntityReference) + current = current.ParentNode; + if (current == null + || current.NodeType != XmlNodeType.EntityReference) { return null; } - sibling = node.PreviousSibling; + sibling = current.PreviousSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) @@ -2024,9 +2021,9 @@ private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling) return sibling; } - private XmlNode PreviousText(XmlNode node) + private XmlNode? PreviousText(XmlNode node) { - XmlNode text = node.PreviousText; + XmlNode? text = node.PreviousText; if (!_document.HasEntityReferences) { @@ -2035,7 +2032,7 @@ private XmlNode PreviousText(XmlNode node) return PreviousTextTail(node, text); } - private XmlNode PreviousTextTail(XmlNode node, XmlNode text) + private XmlNode? PreviousTextTail(XmlNode node, XmlNode? text) { if (text != null) { @@ -2045,16 +2042,17 @@ private XmlNode PreviousTextTail(XmlNode node, XmlNode text) { return null; } - XmlNode sibling = node.PreviousSibling; + XmlNode? sibling = node.PreviousSibling; + XmlNode? current = node; while (sibling == null) { - node = node.ParentNode; - if (node == null - || node.NodeType != XmlNodeType.EntityReference) + current = current.ParentNode; + if (current == null + || current.NodeType != XmlNodeType.EntityReference) { return null; } - sibling = node.PreviousSibling; + sibling = current.PreviousSibling; } while (sibling != null) { @@ -2075,16 +2073,17 @@ private XmlNode PreviousTextTail(XmlNode node, XmlNode text) return null; } - internal static bool IsFollowingSibling(XmlNode left, XmlNode right) + internal static bool IsFollowingSibling(XmlNode left, [NotNullWhen(true)] XmlNode? right) { + XmlNode? currentLeft = left; while (true) { - left = left.NextSibling; - if (left == null) + currentLeft = currentLeft.NextSibling; + if (currentLeft == null) { break; } - if (left == right) + if (currentLeft == right) { return true; } @@ -2096,11 +2095,10 @@ private static bool IsDescendant(XmlNode top, XmlNode bottom) { while (true) { - XmlNode parent = bottom.ParentNode; + XmlNode? parent = bottom.ParentNode; if (parent == null) { - XmlAttribute attribute = bottom as XmlAttribute; - if (attribute == null) + if (!(bottom is XmlAttribute attribute)) { break; } @@ -2156,28 +2154,30 @@ private static bool IsValidChild(XmlNode parent, XmlNode child) private XmlNode TextStart(XmlNode node) { XmlNode start; + XmlNode? current = node; do { - start = node; - node = PreviousSibling(node); + start = current; + current = PreviousSibling(current); } - while (node != null - && node.IsText); + while (current != null + && current.IsText); return start; } private XmlNode TextEnd(XmlNode node) { XmlNode end; + XmlNode? current = node; do { - end = node; - node = NextSibling(node); + end = current; + current = NextSibling(current); } - while (node != null - && node.IsText); + while (current != null + && current.IsText); return end; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs index 8012cea5dfa3..5019c9bdf9e9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs @@ -472,7 +472,7 @@ private void CloseWithReplaceToFollowingSibling() throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly); } - DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling, _end); + DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling!, _end); } XmlNode fragment0 = _fragment[0]; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs index 1715d66ab828..600160070540 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs @@ -634,10 +634,10 @@ internal override void SetParent(XmlNode? node) internal override string XPLocalName { get { return LocalName; } } - internal override string? GetXPAttribute(string localName, string ns) + internal override string GetXPAttribute(string localName, string ns) { if (ns == OwnerDocument.strReservedXmlns) - return null; + return string.Empty; XmlAttribute? attr = GetAttributeNode(localName, ns); if (attr != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs index 75e429ee2ac1..c31e084a6e2e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs @@ -1408,7 +1408,7 @@ internal virtual string XPLocalName } } - internal virtual string? GetXPAttribute(string localName, string namespaceURI) + internal virtual string GetXPAttribute(string localName, string namespaceURI) { return string.Empty; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs index e0a391256c7e..077c176e6418 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.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. +#nullable enable using System.Collections.Generic; using System.Xml.Xsl.Qil; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXpathBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXpathBuilder.cs index 6b1740e34c30..a8c33e48f1cb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXpathBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXpathBuilder.cs @@ -1,27 +1,32 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Xml.XPath; namespace System.Xml.Xsl.XPath { + // TODO-NULLABLE: Replace [MaybeNull] with ? once https://github.com/dotnet/runtime/pull/40197 is in. internal interface IXPathBuilder { // Should be called once per build void StartBuild(); // Should be called after build for result tree post-processing - Node EndBuild(Node result); + [return: MaybeNull] + [return: NotNullIfNotNull("result")] + Node EndBuild([AllowNull] Node result); Node String(string value); Node Number(double value); - Node Operator(XPathOperator op, Node left, Node right); + Node Operator(XPathOperator op, [AllowNull] Node left, [AllowNull] Node right); - Node Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name); + Node Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name); Node JoinStep(Node left, Node right); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathAxis.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathAxis.cs index ee3a212595bc..18977c9a45b6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathAxis.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathAxis.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. +#nullable enable namespace System.Xml.Xsl.XPath { // Order is important - we use them as an index in QilAxis & AxisMask arrays diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs index 8be18af0ed13..43631e67c32d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Xml.Schema; using System.Xml.XPath; @@ -69,7 +71,8 @@ public virtual void StartBuild() numFixupCurrent = numFixupPosition = numFixupLast = 0; } - public virtual QilNode EndBuild(QilNode result) + [return: NotNullIfNotNull("result")] + public virtual QilNode? EndBuild(QilNode? result) { if (result == null) { // special door to clean builder state in exception handlers @@ -109,17 +112,21 @@ public virtual QilNode Number(double value) return _f.Double(value); } - public virtual QilNode Operator(XPathOperator op, QilNode left, QilNode right) + public virtual QilNode Operator(XPathOperator op, QilNode? left, QilNode? right) { Debug.Assert(op != XPathOperator.Unknown); - switch (s_operatorGroup[(int)op]) + XPathOperatorGroup opGroup = s_operatorGroup[(int)op]; + + Debug.Assert((opGroup != XPathOperatorGroup.Negate && right != null) || (opGroup == XPathOperatorGroup.Negate && right == null)); + + switch (opGroup) { - case XPathOperatorGroup.Logical: return LogicalOperator(op, left, right); - case XPathOperatorGroup.Equality: return EqualityOperator(op, left, right); - case XPathOperatorGroup.Relational: return RelationalOperator(op, left, right); - case XPathOperatorGroup.Arithmetic: return ArithmeticOperator(op, left, right); - case XPathOperatorGroup.Negate: return NegateOperator(op, left, right); - case XPathOperatorGroup.Union: return UnionOperator(op, left, right); + case XPathOperatorGroup.Logical: return LogicalOperator(op, left!, right!); + case XPathOperatorGroup.Equality: return EqualityOperator(op, left!, right!); + case XPathOperatorGroup.Relational: return RelationalOperator(op, left!, right!); + case XPathOperatorGroup.Arithmetic: return ArithmeticOperator(op, left!, right!); + case XPathOperatorGroup.Negate: return NegateOperator(op, left!); + case XPathOperatorGroup.Union: return UnionOperator(op, left, right!); default: Debug.Fail(op + " is not a valid XPathOperator"); return null; @@ -268,10 +275,9 @@ private QilNode RelationalOperator(XPathOperator op, QilNode left, QilNode right } } - private QilNode NegateOperator(XPathOperator op, QilNode left, QilNode right) + private QilNode NegateOperator(XPathOperator op, QilNode left) { Debug.Assert(op == XPathOperator.UnaryMinus); - Debug.Assert(right == null); return _f.Negate(_f.ConvertToNumber(left)); } @@ -292,7 +298,7 @@ private QilNode ArithmeticOperator(XPathOperator op, QilNode left, QilNode right } } - private QilNode UnionOperator(XPathOperator op, QilNode left, QilNode right) + private QilNode UnionOperator(XPathOperator op, QilNode? left, QilNode right) { Debug.Assert(op == XPathOperator.Union); if (left == null) @@ -321,7 +327,7 @@ public static XmlNodeKindFlags AxisTypeMask(XmlNodeKindFlags inputTypeMask, XPat ); } - private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeType nodeType, string name, string nsUri) + private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeType nodeType, string? name, string? nsUri) { XmlNodeKindFlags original = qilAxis.XmlType.NodeKinds; XmlNodeKindFlags required = AxisTypeMask(original, nodeType, xpathAxis); @@ -383,7 +389,7 @@ private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeT /*All */ XmlNodeKindFlags.Any }; - private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string nsUri, string name) + private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string? nsUri, string? name) { QilNode currentNode = GetCurrentNode(); QilNode qilAxis; @@ -406,7 +412,7 @@ private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string ns // Can be done using BuildAxisFilter() but f.Root() sets wrong XmlNodeKindFlags case XPathAxis.Root: return _f.Root(currentNode); default: - qilAxis = null; + qilAxis = null!; Debug.Fail("Invalid EnumValue 'XPathAxis'"); break; } @@ -425,9 +431,9 @@ private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string ns return result; } - public virtual QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name) + public virtual QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name) { - string nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix); + string? nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix); return BuildAxis(xpathAxis, nodeType, nsUri, name); } @@ -557,7 +563,7 @@ public virtual QilNode Function(string prefix, string name, IList args) Debug.Assert(!args.IsReadOnly, "Writable collection expected"); if (prefix.Length == 0) { - FunctionInfo func; + FunctionInfo? func; if (FunctionTable.TryGetValue(name, out func)) { func.CastArguments(args, name, _f); @@ -827,10 +833,10 @@ internal class FixupVisitor : QilReplaceVisitor { private new readonly QilPatternFactory f; private readonly QilNode _fixupCurrent, _fixupPosition, _fixupLast; // fixup nodes we are replacing - private QilIterator _current; - private QilNode _last; // expressions we are using to replace fixupNodes + private QilIterator? _current; + private QilNode? _last; // expressions we are using to replace fixupNodes private bool _justCount; // Don't change tree, just count - private IXPathEnvironment _environment; // temp solution + private IXPathEnvironment? _environment; // temp solution public int numCurrent, numPosition, numLast; // here we are counting all replacements we have made public FixupVisitor(QilPatternFactory f, QilNode fixupCurrent, QilNode fixupPosition, QilNode fixupLast) : base(f.BaseFactory) @@ -841,7 +847,7 @@ public FixupVisitor(QilPatternFactory f, QilNode fixupCurrent, QilNode fixupPosi _fixupLast = fixupLast; } - public QilNode Fixup(QilNode inExpr, QilIterator current, QilNode last) + public QilNode Fixup(QilNode inExpr, QilIterator current, QilNode? last) { QilDepthChecker.Check(inExpr); _current = current; @@ -975,11 +981,11 @@ internal class FunctionInfo public T id; public int minArgs; public int maxArgs; - public XmlTypeCode[] argTypes; + public XmlTypeCode[]? argTypes; public const int Infinity = int.MaxValue; - public FunctionInfo(T id, int minArgs, int maxArgs, XmlTypeCode[] argTypes) + public FunctionInfo(T id, int minArgs, int maxArgs, XmlTypeCode[]? argTypes) { Debug.Assert(maxArgs == 0 || maxArgs == Infinity || argTypes != null && argTypes.Length == maxArgs); this.id = id; @@ -1039,9 +1045,10 @@ public void CastArguments(IList args, string name, XPathQilFactory f) } else { + Debug.Assert(args.Count == 0 || argTypes != null); for (int i = 0; i < args.Count; i++) { - if (argTypes[i] == XmlTypeCode.Node && f.CannotBeNodeSet(args[i])) + if (argTypes![i] == XmlTypeCode.Node && f.CannotBeNodeSet(args[i])) { throw new XPathCompileException(SR.XPath_NodeSetArgumentExpected, name, (i + 1).ToString(CultureInfo.InvariantCulture)); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs index 353fa402fd66..cc10b5257d90 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.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. +#nullable enable using System.Runtime.Serialization; using System.Text; @@ -9,7 +10,7 @@ namespace System.Xml.Xsl.XPath [Serializable] internal class XPathCompileException : XslLoadException { - public string queryString; + public string? queryString; public int startChar; public int endChar; @@ -28,9 +29,9 @@ internal XPathCompileException(string resId, params string[] args) internal XPathCompileException(SerializationInfo info, StreamingContext context) : base(info, context) { - queryString = (string)info.GetValue("QueryString", typeof(string)); - startChar = (int)info.GetValue("StartChar", typeof(int)); - endChar = (int)info.GetValue("EndChar", typeof(int)); + queryString = (string)info.GetValue("QueryString", typeof(string))!; + startChar = (int)info.GetValue("StartChar", typeof(int))!; + endChar = (int)info.GetValue("EndChar", typeof(int))!; } public override void GetObjectData(SerializationInfo info, StreamingContext context) @@ -79,7 +80,7 @@ private static void AppendTrimmed(StringBuilder sb, string value, int startIndex } } - internal string MarkOutError() + internal string? MarkOutError() { if (queryString == null || queryString.Trim(' ').Length == 0) { @@ -105,7 +106,7 @@ internal string MarkOutError() internal override string FormatDetailedMessage() { string message = Message; - string error = MarkOutError(); + string? error = MarkOutError(); if (error != null && error.Length > 0) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathContext.cs index f1b073d2e95a..f863ef75540a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathContext.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. +#nullable enable #if DontUse // XPathContext is not used any more but comments in it and Replacer visitor may be used to // optimize code XSLT generates on last(). diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathOperator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathOperator.cs index 58765d248f85..adc8c37e681e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathOperator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathOperator.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. +#nullable enable namespace System.Xml.Xsl.XPath { // order is importent. We are using them as an index in OperatorGroup & QilOperator & XPathOperatorToQilNodeType arrays diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs index ab3f0ae91b68..d707ad52d5dd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs @@ -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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; @@ -10,8 +11,8 @@ namespace System.Xml.Xsl.XPath internal class XPathParser { - private XPathScanner _scanner; - private IXPathBuilder _builder; + private XPathScanner? _scanner; + private IXPathBuilder? _builder; private readonly Stack _posInfo = new Stack(); // Six possible causes of exceptions in the builder: @@ -56,7 +57,7 @@ public Node Parse(XPathScanner scanner, IXPathBuilder builder, LexKind end #endif } Debug.Assert(_posInfo.Count == 0, "PushPosInfo() and PopPosInfo() calls have been unbalanced"); - return result; + return result!; } #region Location paths and node tests @@ -81,10 +82,10 @@ internal static bool IsStep(LexKind lexKind) */ private Node ParseLocationPath() { - if (_scanner.Kind == LexKind.Slash) + if (_scanner!.Kind == LexKind.Slash) { _scanner.NextLex(); - Node opnd = _builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null); + Node opnd = _builder!.Axis(XPathAxis.Root, XPathNodeType.All, null, null); if (IsStep(_scanner.Kind)) { @@ -95,7 +96,7 @@ private Node ParseLocationPath() else if (_scanner.Kind == LexKind.SlashSlash) { _scanner.NextLex(); - return _builder.JoinStep( + return _builder!.JoinStep( _builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null), _builder.JoinStep( _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), @@ -121,19 +122,19 @@ private Node ParseRelativeLocationPath() { if (LocalAppContextSwitches.LimitXPathComplexity) { - throw _scanner.CreateException(SR.Xslt_InputTooComplex); + throw _scanner!.CreateException(SR.Xslt_InputTooComplex); } } Node opnd = ParseStep(); - if (_scanner.Kind == LexKind.Slash) + if (_scanner!.Kind == LexKind.Slash) { _scanner.NextLex(); - opnd = _builder.JoinStep(opnd, ParseRelativeLocationPath()); + opnd = _builder!.JoinStep(opnd, ParseRelativeLocationPath()); } else if (_scanner.Kind == LexKind.SlashSlash) { _scanner.NextLex(); - opnd = _builder.JoinStep(opnd, + opnd = _builder!.JoinStep(opnd, _builder.JoinStep( _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativeLocationPath() @@ -150,10 +151,10 @@ private Node ParseRelativeLocationPath() private Node ParseStep() { Node opnd; - if (LexKind.Dot == _scanner.Kind) + if (LexKind.Dot == _scanner!.Kind) { // '.' _scanner.NextLex(); - opnd = _builder.Axis(XPathAxis.Self, XPathNodeType.All, null, null); + opnd = _builder!.Axis(XPathAxis.Self, XPathNodeType.All, null, null); if (LexKind.LBracket == _scanner.Kind) { throw _scanner.CreateException(SR.XPath_PredicateAfterDot); @@ -162,7 +163,7 @@ private Node ParseStep() else if (LexKind.DotDot == _scanner.Kind) { // '..' _scanner.NextLex(); - opnd = _builder.Axis(XPathAxis.Parent, XPathNodeType.All, null, null); + opnd = _builder!.Axis(XPathAxis.Parent, XPathNodeType.All, null, null); if (LexKind.LBracket == _scanner.Kind) { throw _scanner.CreateException(SR.XPath_PredicateAfterDotDot); @@ -195,7 +196,7 @@ private Node ParseStep() while (LexKind.LBracket == _scanner.Kind) { - opnd = _builder.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis)); + opnd = _builder!.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis)); } } return opnd; @@ -216,12 +217,12 @@ private static bool IsReverseAxis(XPathAxis axis) private Node ParseNodeTest(XPathAxis axis) { XPathNodeType nodeType; - string nodePrefix, nodeName; + string? nodePrefix, nodeName; - int startChar = _scanner.LexStart; + int startChar = _scanner!.LexStart; InternalParseNodeTest(_scanner, axis, out nodeType, out nodePrefix, out nodeName); PushPosInfo(startChar, _scanner.PrevLexEnd); - Node result = _builder.Axis(axis, nodeType, nodePrefix, nodeName); + Node result = _builder!.Axis(axis, nodeType, nodePrefix, nodeName); PopPosInfo(); return result; } @@ -245,7 +246,7 @@ private static XPathNodeType PrincipalNodeType(XPathAxis axis) ); } - internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, out XPathNodeType nodeType, out string nodePrefix, out string nodeName) + internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, out XPathNodeType nodeType, out string? nodePrefix, out string? nodeName) { switch (scanner.Kind) { @@ -311,7 +312,7 @@ internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, */ private Node ParsePredicate() { - _scanner.PassToken(LexKind.LBracket); + _scanner!.PassToken(LexKind.LBracket); Node opnd = ParseExpr(); _scanner.PassToken(LexKind.RBracket); return opnd; @@ -349,7 +350,7 @@ private Node ParseSubExpr(int callerPrec) { if (LocalAppContextSwitches.LimitXPathComplexity) { - throw _scanner.CreateException(SR.Xslt_InputTooComplex); + throw _scanner!.CreateException(SR.Xslt_InputTooComplex); } } @@ -357,12 +358,12 @@ private Node ParseSubExpr(int callerPrec) Node opnd; // Check for unary operators - if (_scanner.Kind == LexKind.Minus) + if (_scanner!.Kind == LexKind.Minus) { op = XPathOperator.UnaryMinus; int opPrec = s_XPathOperatorPrecedence[(int)op]; _scanner.NextLex(); - opnd = _builder.Operator(op, ParseSubExpr(opPrec), default(Node)); + opnd = _builder!.Operator(op, ParseSubExpr(opPrec), default(Node)); } else { @@ -381,7 +382,7 @@ private Node ParseSubExpr(int callerPrec) // Operator's precedence is greater than the one of our caller, so process it here _scanner.NextLex(); - opnd = _builder.Operator(op, opnd, ParseSubExpr(/*callerPrec:*/opPrec)); + opnd = _builder!.Operator(op, opnd, ParseSubExpr(/*callerPrec:*/opPrec)); } --_parseSubExprDepth; return opnd; @@ -411,13 +412,13 @@ private Node ParseSubExpr(int callerPrec) */ private Node ParseUnionExpr() { - int startChar = _scanner.LexStart; + int startChar = _scanner!.LexStart; Node opnd1 = ParsePathExpr(); if (_scanner.Kind == LexKind.Union) { PushPosInfo(startChar, _scanner.PrevLexEnd); - opnd1 = _builder.Operator(XPathOperator.Union, default(Node), opnd1); + opnd1 = _builder!.Operator(XPathOperator.Union, default(Node), opnd1); PopPosInfo(); while (_scanner.Kind == LexKind.Union) @@ -441,7 +442,7 @@ private Node ParsePathExpr() // Here we distinguish FilterExpr from LocationPath - the former starts with PrimaryExpr if (IsPrimaryExpr()) { - int startChar = _scanner.LexStart; + int startChar = _scanner!.LexStart; Node opnd = ParseFilterExpr(); int endChar = _scanner.PrevLexEnd; @@ -449,14 +450,14 @@ private Node ParsePathExpr() { _scanner.NextLex(); PushPosInfo(startChar, endChar); - opnd = _builder.JoinStep(opnd, ParseRelativeLocationPath()); + opnd = _builder!.JoinStep(opnd, ParseRelativeLocationPath()); PopPosInfo(); } else if (_scanner.Kind == LexKind.SlashSlash) { _scanner.NextLex(); PushPosInfo(startChar, endChar); - opnd = _builder.JoinStep(opnd, + opnd = _builder!.JoinStep(opnd, _builder.JoinStep( _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativeLocationPath() @@ -477,14 +478,14 @@ private Node ParsePathExpr() */ private Node ParseFilterExpr() { - int startChar = _scanner.LexStart; + int startChar = _scanner!.LexStart; Node opnd = ParsePrimaryExpr(); int endChar = _scanner.PrevLexEnd; while (_scanner.Kind == LexKind.LBracket) { PushPosInfo(startChar, endChar); - opnd = _builder.Predicate(opnd, ParsePredicate(), /*reverseStep:*/false); + opnd = _builder!.Predicate(opnd, ParsePredicate(), /*reverseStep:*/false); PopPosInfo(); } return opnd; @@ -493,7 +494,7 @@ private Node ParseFilterExpr() private bool IsPrimaryExpr() { return ( - _scanner.Kind == LexKind.String || + _scanner!.Kind == LexKind.String || _scanner.Kind == LexKind.Number || _scanner.Kind == LexKind.Dollar || _scanner.Kind == LexKind.LParens || @@ -508,14 +509,14 @@ private Node ParsePrimaryExpr() { Debug.Assert(IsPrimaryExpr()); Node opnd; - switch (_scanner.Kind) + switch (_scanner!.Kind) { case LexKind.String: - opnd = _builder.String(_scanner.StringValue); + opnd = _builder!.String(_scanner.StringValue); _scanner.NextLex(); break; case LexKind.Number: - opnd = _builder.Number(XPathConvert.StringToDouble(_scanner.RawValue)); + opnd = _builder!.Number(XPathConvert.StringToDouble(_scanner.RawValue)); _scanner.NextLex(); break; case LexKind.Dollar: @@ -523,7 +524,7 @@ private Node ParsePrimaryExpr() _scanner.NextLex(); _scanner.CheckToken(LexKind.Name); PushPosInfo(startChar, _scanner.LexStart + _scanner.LexSize); - opnd = _builder.Variable(_scanner.Prefix, _scanner.Name); + opnd = _builder!.Variable(_scanner.Prefix, _scanner.Name); PopPosInfo(); _scanner.NextLex(); break; @@ -549,7 +550,7 @@ private Node ParsePrimaryExpr() private Node ParseFunctionCall() { List argList = new List(); - string name = _scanner.Name; + string name = _scanner!.Name; string prefix = _scanner.Prefix; int startChar = _scanner.LexStart; @@ -572,7 +573,7 @@ private Node ParseFunctionCall() _scanner.NextLex(); // move off the ')' PushPosInfo(startChar, _scanner.PrevLexEnd); - Node result = _builder.Function(prefix, name, argList); + Node result = _builder!.Function(prefix, name, argList); PopPosInfo(); return result; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs index b6fe069bf884..f92d203ff81e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.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. +#nullable enable using System.Diagnostics; using System.Xml.Schema; using System.Xml.Xsl.Qil; @@ -289,7 +290,7 @@ public QilNode ConvertToNodeSet(QilNode n) } // Returns null if the given expression is never a node-set - public QilNode TryEnsureNodeSet(QilNode n) + public QilNode? TryEnsureNodeSet(QilNode n) { if (n.XmlType.IsNode && n.XmlType.IsNotRtf) { @@ -307,7 +308,7 @@ public QilNode TryEnsureNodeSet(QilNode n) // Throws an exception if the given expression is never a node-set public QilNode EnsureNodeSet(QilNode n) { - QilNode result = TryEnsureNodeSet(n); + QilNode? result = TryEnsureNodeSet(n); if (result == null) { throw new XPathCompileException(SR.XPath_NodeSetExpected); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathScanner.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathScanner.cs index 0221f1dc5487..e6509bf15801 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathScanner.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathScanner.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. +#nullable enable // http://www.w3.org/TR/xpath#exprlex //------------------------------------------------------------------------------ @@ -62,9 +63,9 @@ internal sealed class XPathScanner private int _curIndex; private char _curChar; private LexKind _kind; - private string _name; - private string _prefix; - private string _stringValue; + private string? _name; + private string? _prefix; + private string? _stringValue; private bool _canBeFunction; private int _lexStart; private int _prevLexEnd; @@ -423,6 +424,8 @@ private bool CheckOperator(bool star) } else { + Debug.Assert(_prefix != null); + Debug.Assert(_name != null); if (_prefix.Length != 0 || _name.Length > 3) return false; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs index abf171ee651b..c31f265cbb9f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs @@ -8,7 +8,9 @@ * */ +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Xml.Xsl @@ -2016,8 +2018,9 @@ public void ShiftRight(int cbit) AssertValid(); } - public int CompareTo(object obj) + public int CompareTo(object? obj) { + Debug.Assert(obj != null); BigInteger bi = (BigInteger)obj; AssertValid(); bi.AssertValid(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs index 9f6a873260a9..ef4f222eace8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.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. +#nullable enable using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -9,6 +10,7 @@ using System.Xml.Schema; using System.Xml.Xsl.Qil; using System.Xml.Xsl.XPath; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Xslt { @@ -61,7 +63,8 @@ private void FixupFilterBinding(QilLoop filter, QilNode newBinding) filter.Variable.Binding = newBinding; } - public virtual QilNode EndBuild(QilNode result) + [return: NotNullIfNotNull("result")] + public virtual QilNode? EndBuild(QilNode? result) { Debug.Assert(_inTheBuild, "StartBuild() wasn't called"); if (result == null) @@ -78,7 +81,7 @@ public virtual QilNode EndBuild(QilNode result) return result; } - public QilNode Operator(XPathOperator op, QilNode left, QilNode right) + public QilNode Operator(XPathOperator op, QilNode? left, QilNode? right) { Debug.Assert(op == XPathOperator.Union); Debug.Assert(left != null); @@ -97,7 +100,7 @@ public QilNode Operator(XPathOperator op, QilNode left, QilNode right) } } - private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPathAxis xpathAxis, XPathNodeType nodeType, string name, string nsUri) + private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPathAxis xpathAxis, XPathNodeType nodeType, string? name, string? nsUri) { QilNode nameTest = ( name != null && nsUri != null ? f.Eq(f.NameOf(itr), f.QName(name, nsUri)) : // ns:bar || bar @@ -120,7 +123,7 @@ private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPa return filter; } - public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name) + public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name) { Debug.Assert( xpathAxis == XPathAxis.Child || @@ -141,7 +144,7 @@ public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, priority = 0.5; break; default: - string nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix); + string? nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix); result = BuildAxisFilter(_f, _f.For(_fixupNode), xpathAxis, nodeType, name, nsUri); switch (nodeType) { @@ -214,7 +217,9 @@ public QilNode JoinStep(QilNode left, QilNode right) } } Debug.Assert(right.NodeType == QilNodeType.Filter); - QilLoop lastParent = GetLastParent(right); + QilLoop? lastParent = GetLastParent(right); + Debug.Assert(lastParent != null); + FixupFilterBinding(parentFilter, ancestor ? _f.Ancestor(lastParent.Variable) : _f.Parent(lastParent.Variable)); lastParent.Body = _f.And(lastParent.Body, _f.Not(_f.IsEmpty(parentFilter))); SetPriority(right, 0.5); @@ -336,7 +341,7 @@ public QilNode Variable(string prefix, string name) private class Annotation { public double Priority; - public QilLoop Parent; + public QilLoop? Parent; } public static void SetPriority(QilNode node, double priority) @@ -359,7 +364,7 @@ private static void SetLastParent(QilNode node, QilLoop parent) node.Annotation = ann; } - private static QilLoop GetLastParent(QilNode node) + private static QilLoop? GetLastParent(QilNode node) { return ((Annotation)node.Annotation).Parent; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternParser.cs index 7b33bf0d364f..16d29830538d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternParser.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml; @@ -19,15 +20,15 @@ public interface IPatternBuilder : IXPathBuilder IXPathBuilder GetPredicateBuilder(QilNode context); } - private XPathScanner _scanner; - private IPatternBuilder _ptrnBuilder; + private XPathScanner? _scanner; + private IPatternBuilder? _ptrnBuilder; private readonly XPathParser _predicateParser = new XPathParser(); public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder) { Debug.Assert(_scanner == null && _ptrnBuilder == null); Debug.Assert(scanner != null && ptrnBuilder != null); - QilNode result = null; + QilNode? result = null; ptrnBuilder.StartBuild(); try { @@ -44,7 +45,7 @@ public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder) _scanner = null; #endif } - return result; + return result!; } /* @@ -54,10 +55,10 @@ private QilNode ParsePattern() { QilNode opnd = ParseLocationPathPattern(); - while (_scanner.Kind == LexKind.Union) + while (_scanner!.Kind == LexKind.Union) { _scanner.NextLex(); - opnd = _ptrnBuilder.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern()); + opnd = _ptrnBuilder!.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern()); } return opnd; } @@ -69,11 +70,11 @@ private QilNode ParseLocationPathPattern() { QilNode opnd; - switch (_scanner.Kind) + switch (_scanner!.Kind) { case LexKind.Slash: _scanner.NextLex(); - opnd = _ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null); + opnd = _ptrnBuilder!.Axis(XPathAxis.Root, XPathNodeType.All, null, null); if (XPathParser.IsStep(_scanner.Kind)) { @@ -82,7 +83,7 @@ private QilNode ParseLocationPathPattern() return opnd; case LexKind.SlashSlash: _scanner.NextLex(); - return _ptrnBuilder.JoinStep( + return _ptrnBuilder!.JoinStep( _ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null), _ptrnBuilder.JoinStep( _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), @@ -97,11 +98,11 @@ private QilNode ParseLocationPathPattern() { case LexKind.Slash: _scanner.NextLex(); - opnd = _ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); + opnd = _ptrnBuilder!.JoinStep(opnd, ParseRelativePathPattern()); break; case LexKind.SlashSlash: _scanner.NextLex(); - opnd = _ptrnBuilder.JoinStep(opnd, + opnd = _ptrnBuilder!.JoinStep(opnd, _ptrnBuilder.JoinStep( _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() @@ -122,7 +123,7 @@ private QilNode ParseLocationPathPattern() */ private QilNode ParseIdKeyPattern() { - Debug.Assert(_scanner.CanBeFunction); + Debug.Assert(_scanner!.CanBeFunction); Debug.Assert(_scanner.Prefix.Length == 0); Debug.Assert(_scanner.Name == "id" || _scanner.Name == "key"); List args = new List(2); @@ -132,7 +133,7 @@ private QilNode ParseIdKeyPattern() _scanner.NextLex(); _scanner.PassToken(LexKind.LParens); _scanner.CheckToken(LexKind.String); - args.Add(_ptrnBuilder.String(_scanner.StringValue)); + args.Add(_ptrnBuilder!.String(_scanner.StringValue)); _scanner.NextLex(); _scanner.PassToken(LexKind.RParens); return _ptrnBuilder.Function("", "id", args); @@ -142,7 +143,7 @@ private QilNode ParseIdKeyPattern() _scanner.NextLex(); _scanner.PassToken(LexKind.LParens); _scanner.CheckToken(LexKind.String); - args.Add(_ptrnBuilder.String(_scanner.StringValue)); + args.Add(_ptrnBuilder!.String(_scanner.StringValue)); _scanner.NextLex(); _scanner.PassToken(LexKind.Comma); _scanner.CheckToken(LexKind.String); @@ -165,19 +166,19 @@ private QilNode ParseRelativePathPattern() { if (LocalAppContextSwitches.LimitXPathComplexity) { - throw _scanner.CreateException(SR.Xslt_InputTooComplex); + throw _scanner!.CreateException(SR.Xslt_InputTooComplex); } } QilNode opnd = ParseStepPattern(); - if (_scanner.Kind == LexKind.Slash) + if (_scanner!.Kind == LexKind.Slash) { _scanner.NextLex(); - opnd = _ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); + opnd = _ptrnBuilder!.JoinStep(opnd, ParseRelativePathPattern()); } else if (_scanner.Kind == LexKind.SlashSlash) { _scanner.NextLex(); - opnd = _ptrnBuilder.JoinStep(opnd, + opnd = _ptrnBuilder!.JoinStep(opnd, _ptrnBuilder.JoinStep( _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() @@ -197,7 +198,7 @@ private QilNode ParseStepPattern() QilNode opnd; XPathAxis axis; - switch (_scanner.Kind) + switch (_scanner!.Kind) { case LexKind.Dot: case LexKind.DotDot: @@ -225,11 +226,11 @@ private QilNode ParseStepPattern() } XPathNodeType nodeType; - string nodePrefix, nodeName; + string? nodePrefix, nodeName; XPathParser.InternalParseNodeTest(_scanner, axis, out nodeType, out nodePrefix, out nodeName); - opnd = _ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName); + opnd = _ptrnBuilder!.Axis(axis, nodeType, nodePrefix, nodeName); - XPathPatternBuilder xpathPatternBuilder = _ptrnBuilder as XPathPatternBuilder; + XPathPatternBuilder? xpathPatternBuilder = _ptrnBuilder as XPathPatternBuilder; if (xpathPatternBuilder != null) { //for XPathPatternBuilder, get all predicates and then build them @@ -256,9 +257,9 @@ private QilNode ParseStepPattern() */ private QilNode ParsePredicate(QilNode context) { - Debug.Assert(_scanner.Kind == LexKind.LBracket); + Debug.Assert(_scanner!.Kind == LexKind.LBracket); _scanner.NextLex(); - QilNode result = _predicateParser.Parse(_scanner, _ptrnBuilder.GetPredicateBuilder(context), LexKind.RBracket); + QilNode result = _predicateParser.Parse(_scanner, _ptrnBuilder!.GetPredicateBuilder(context), LexKind.RBracket); Debug.Assert(_scanner.Kind == LexKind.RBracket); _scanner.NextLex(); return result; From 2d160e42f97b42285abd50a592c2bd21251439a2 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 6 Aug 2020 17:35:14 -0700 Subject: [PATCH 307/755] Make ComponentModel intrinsic TypeConverters linker-safe (#39973) * Make ComponentModel intrinsic TypeConverters linker-safe * Avoid reflection in converter func lookup * Re-add code path that supports editors * Consolidate intrinsic converter caches, move converter-specific code to new method, add trimming tests * Address feedback * Revert change to GetIntrinsicTypeEditor method * Handle inheritance with Uri and CultureInfo types * Add heirarchy-related comments to cache docs --- ...peDescriptionProvider.ReflectedTypeData.cs | 4 +- .../ReflectTypeDescriptionProvider.cs | 187 ++++++++++++++---- .../tests/TrimmingTests/TypeConverterTest.cs | 182 +++++++++++++++++ .../tests/TypeDescriptorTests.cs | 28 +++ 4 files changed, 362 insertions(+), 39 deletions(-) create mode 100644 src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/TypeConverterTest.cs diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs index d2b7d59ef781..70c8024c825e 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs @@ -218,7 +218,7 @@ internal TypeConverter GetConverter(object instance) { // We did not get a converter. Traverse up the base class chain until // we find one in the stock hashtable. - _converter = (TypeConverter)SearchIntrinsicTable(IntrinsicTypeConverters, _type); + _converter = GetIntrinsicTypeConverter(_type); Debug.Assert(_converter != null, "There is no intrinsic setup in the hashtable for the Object type"); } } @@ -348,7 +348,7 @@ internal object GetEditor(object instance, Type editorBaseType) Hashtable intrinsicEditors = GetEditorTable(editorBaseType); if (intrinsicEditors != null) { - editor = SearchIntrinsicTable(intrinsicEditors, _type); + editor = GetIntrinsicTypeEditor(intrinsicEditors, _type); } // As a quick sanity check, check to see that the editor we got back is of diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs index 5423539159f7..ff4cd113da6f 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.ComponentModel.Design; using System.Diagnostics; -using System.Drawing; using System.Globalization; using System.Linq; using System.Reflection; @@ -38,7 +37,7 @@ internal sealed partial class ReflectTypeDescriptionProvider : TypeDescriptionPr // This is where we store the various converters, etc for the intrinsic types. // private static Hashtable s_editorTables; - private static Hashtable s_intrinsicTypeConverters; + private static Dictionary s_intrinsicTypeConverters; // For converters, etc that are bound to class attribute data, rather than a class // type, we have special key sentinel values that we put into the hash table. @@ -94,45 +93,88 @@ internal ReflectTypeDescriptionProvider() private static Hashtable EditorTables => LazyInitializer.EnsureInitialized(ref s_editorTables, () => new Hashtable(4)); /// - /// This is a table we create for intrinsic types. - /// There should be entries here ONLY for intrinsic - /// types, as all other types we should be able to - /// add attributes directly as metadata. + /// Provides a way to create instances, and cache them where applicable. /// - private static Hashtable IntrinsicTypeConverters => LazyInitializer.EnsureInitialized(ref s_intrinsicTypeConverters, () => new Hashtable + private class IntrinsicTypeConverterData + { + private readonly Func _constructionFunc; + + private readonly bool _cacheConverterInstance; + + private TypeConverter _converterInstance; + + /// + /// Creates a new instance of . + /// + /// + /// A func that creates a new instance. + /// + /// + /// Indicates whether to cache created instances. This is false when the converter handles multiple types, + /// specifically , , and . + /// + public IntrinsicTypeConverterData(Func constructionFunc, bool cacheConverterInstance = true) + { + _constructionFunc = constructionFunc; + _cacheConverterInstance = cacheConverterInstance; + } + + public TypeConverter GetOrCreateConverterInstance(Type innerType) + { + if (!_cacheConverterInstance) + { + return _constructionFunc(innerType); + } + + _converterInstance ??= _constructionFunc(innerType); + return _converterInstance; + } + } + + /// + /// This is a table we create for intrinsic types.There should be entries here ONLY for + /// intrinsic types, as all other types we should be able to add attributes directly as metadata. + /// + /// + /// and are the only types that can be inherited for which + /// we have intrinsic converters for. The appropriate converter needs to be fetched when look-ups are done + /// for deriving types. When adding to this cache, consider whether the type can be inherited and add the + /// appropriate logic to handle this in below. + /// + private static Dictionary IntrinsicTypeConverters + => LazyInitializer.EnsureInitialized(ref s_intrinsicTypeConverters, () => new Dictionary(27) { // Add the intrinsics // - [typeof(bool)] = typeof(BooleanConverter), - [typeof(byte)] = typeof(ByteConverter), - [typeof(sbyte)] = typeof(SByteConverter), - [typeof(char)] = typeof(CharConverter), - [typeof(double)] = typeof(DoubleConverter), - [typeof(string)] = typeof(StringConverter), - [typeof(int)] = typeof(Int32Converter), - [typeof(short)] = typeof(Int16Converter), - [typeof(long)] = typeof(Int64Converter), - [typeof(float)] = typeof(SingleConverter), - [typeof(ushort)] = typeof(UInt16Converter), - [typeof(uint)] = typeof(UInt32Converter), - [typeof(ulong)] = typeof(UInt64Converter), - [typeof(object)] = typeof(TypeConverter), - [typeof(void)] = typeof(TypeConverter), - [typeof(CultureInfo)] = typeof(CultureInfoConverter), - [typeof(DateTime)] = typeof(DateTimeConverter), - [typeof(DateTimeOffset)] = typeof(DateTimeOffsetConverter), - [typeof(decimal)] = typeof(DecimalConverter), - [typeof(TimeSpan)] = typeof(TimeSpanConverter), - [typeof(Guid)] = typeof(GuidConverter), - [typeof(Uri)] = typeof(UriTypeConverter), - [typeof(Version)] = typeof(VersionConverter), + [typeof(bool)] = new IntrinsicTypeConverterData((type) => new BooleanConverter()), + [typeof(byte)] = new IntrinsicTypeConverterData((type) => new ByteConverter()), + [typeof(sbyte)] = new IntrinsicTypeConverterData((type) => new SByteConverter()), + [typeof(char)] = new IntrinsicTypeConverterData((type) => new CharConverter()), + [typeof(double)] = new IntrinsicTypeConverterData((type) => new DoubleConverter()), + [typeof(string)] = new IntrinsicTypeConverterData((type) => new StringConverter()), + [typeof(int)] = new IntrinsicTypeConverterData((type) => new Int32Converter()), + [typeof(short)] = new IntrinsicTypeConverterData((type) => new Int16Converter()), + [typeof(long)] = new IntrinsicTypeConverterData((type) => new Int64Converter()), + [typeof(float)] = new IntrinsicTypeConverterData((type) => new SingleConverter()), + [typeof(ushort)] = new IntrinsicTypeConverterData((type) => new UInt16Converter()), + [typeof(uint)] = new IntrinsicTypeConverterData((type) => new UInt32Converter()), + [typeof(ulong)] = new IntrinsicTypeConverterData((type) => new UInt64Converter()), + [typeof(object)] = new IntrinsicTypeConverterData((type) => new TypeConverter()), + [typeof(CultureInfo)] = new IntrinsicTypeConverterData((type) => new CultureInfoConverter()), + [typeof(DateTime)] = new IntrinsicTypeConverterData((type) => new DateTimeConverter()), + [typeof(DateTimeOffset)] = new IntrinsicTypeConverterData((type) => new DateTimeOffsetConverter()), + [typeof(decimal)] = new IntrinsicTypeConverterData((type) => new DecimalConverter()), + [typeof(TimeSpan)] = new IntrinsicTypeConverterData((type) => new TimeSpanConverter()), + [typeof(Guid)] = new IntrinsicTypeConverterData((type) => new GuidConverter()), + [typeof(Uri)] = new IntrinsicTypeConverterData((type) => new UriTypeConverter()), + [typeof(Version)] = new IntrinsicTypeConverterData((type) => new VersionConverter()), // Special cases for things that are not bound to a specific type // - [typeof(Array)] = typeof(ArrayConverter), - [typeof(ICollection)] = typeof(CollectionConverter), - [typeof(Enum)] = typeof(EnumConverter), - [s_intrinsicNullableKey] = typeof(NullableConverter), - [s_intrinsicReferenceKey] = typeof(ReferenceConverter), + [typeof(Array)] = new IntrinsicTypeConverterData((type) => new ArrayConverter()), + [typeof(ICollection)] = new IntrinsicTypeConverterData((type) => new CollectionConverter()), + [typeof(Enum)] = new IntrinsicTypeConverterData((type) => new EnumConverter(type), cacheConverterInstance: false), + [s_intrinsicNullableKey] = new IntrinsicTypeConverterData((type) => new NullableConverter(type), cacheConverterInstance: false), + [s_intrinsicReferenceKey] = new IntrinsicTypeConverterData((type) => new ReferenceConverter(type), cacheConverterInstance: false), }); private static Hashtable PropertyCache => LazyInitializer.EnsureInitialized(ref s_propertyCache, () => new Hashtable()); @@ -1216,14 +1258,14 @@ internal void Refresh(Type type) /// /// Searches the provided intrinsic hashtable for a match with the object type. - /// At the beginning, the hashtable contains types for the various converters. + /// At the beginning, the hashtable contains types for the various editors. /// As this table is searched, the types for these objects /// are replaced with instances, so we only create as needed. This method /// does the search up the base class hierarchy and will create instances /// for types as needed. These instances are stored back into the table /// for the base type, and for the original component type, for fast access. /// - private static object SearchIntrinsicTable(Hashtable table, Type callingType) + private static object GetIntrinsicTypeEditor(Hashtable table, Type callingType) { object hashEntry = null; @@ -1338,5 +1380,76 @@ private static object SearchIntrinsicTable(Hashtable table, Type callingType) return hashEntry; } + + /// + /// Searches the intrinsic converter dictionary for a match with the object type. + /// The strongly-typed dictionary maps object types to converter data objects which lazily + /// creates (and caches for re-use, where applicable) converter instances. + /// + private static TypeConverter GetIntrinsicTypeConverter(Type callingType) + { + TypeConverter converter; + + // We take a lock on this dictionary. Nothing in this code calls out to + // other methods that lock, so it should be fairly safe to grab this lock. + lock (IntrinsicTypeConverters) + { + if (!IntrinsicTypeConverters.TryGetValue(callingType, out IntrinsicTypeConverterData converterData)) + { + if (callingType.IsEnum) + { + converterData = IntrinsicTypeConverters[typeof(Enum)]; + } + else if (callingType.IsArray) + { + converterData = IntrinsicTypeConverters[typeof(Array)]; + } + else if (callingType.IsGenericType && callingType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + converterData = IntrinsicTypeConverters[s_intrinsicNullableKey]; + } + else if (typeof(ICollection).IsAssignableFrom(callingType)) + { + converterData = IntrinsicTypeConverters[typeof(ICollection)]; + } + else if (callingType.IsInterface) + { + converterData = IntrinsicTypeConverters[s_intrinsicReferenceKey]; + } + else + { + // Uri and CultureInfo are the only types that can be derived from for which we have intrinsic converters. + // Check if the calling type derives from either and return the appropriate converter. + + // We should have fetched converters for these types above. + Debug.Assert(callingType != typeof(Uri) && callingType != typeof(CultureInfo)); + + Type key = null; + + Type baseType = callingType.BaseType; + while (baseType != null && baseType != typeof(object)) + { + if (baseType == typeof(Uri) || baseType == typeof(CultureInfo)) + { + key = baseType; + break; + } + + baseType = baseType.BaseType; + } + + // Handle other reference and value types. An instance of TypeConverter itself created and returned below. + key ??= typeof(object); + + converterData = IntrinsicTypeConverters[key]; + } + } + + // This needs to be done within the lock as the dictionary value may be mutated in the following method call. + converter = converterData.GetOrCreateConverterInstance(callingType); + } + + return converter; + } } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/TypeConverterTest.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/TypeConverterTest.cs new file mode 100644 index 000000000000..dca3536084d2 --- /dev/null +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/TypeConverterTest.cs @@ -0,0 +1,182 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; + +/// +/// Tests that the relevant constructors of intrinsic TypeConverter types are preserved when needed in a trimmed application. +/// +class Program +{ + static int Main(string[] args) + { + if (!RunTest(targetType: typeof(bool), expectedConverterType: typeof(BooleanConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(byte), expectedConverterType: typeof(ByteConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(sbyte), expectedConverterType: typeof(SByteConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(char), expectedConverterType: typeof(CharConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(double), expectedConverterType: typeof(DoubleConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(string), expectedConverterType: typeof(StringConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(short), expectedConverterType: typeof(Int16Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(int), expectedConverterType: typeof(Int32Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(long), expectedConverterType: typeof(Int64Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(float), expectedConverterType: typeof(SingleConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(ushort), expectedConverterType: typeof(UInt16Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(uint), expectedConverterType: typeof(UInt32Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(ulong), expectedConverterType: typeof(UInt64Converter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(object), expectedConverterType: typeof(TypeConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(DateTime), expectedConverterType: typeof(DateTimeConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(DateTimeOffset), expectedConverterType: typeof(DateTimeOffsetConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(decimal), expectedConverterType: typeof(DecimalConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(TimeSpan), expectedConverterType: typeof(TimeSpanConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(Guid), expectedConverterType: typeof(GuidConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(Array), expectedConverterType: typeof(ArrayConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(ICollection), expectedConverterType: typeof(CollectionConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(Enum), expectedConverterType: typeof(EnumConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(DayOfWeek), expectedConverterType: typeof(EnumConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(SomeValueType?), expectedConverterType: typeof(NullableConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(ClassWithNoConverter), expectedConverterType: typeof(TypeConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(Uri), expectedConverterType: typeof(UriTypeConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(CultureInfo), expectedConverterType: typeof(CultureInfoConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(Version), expectedConverterType: typeof(VersionConverter))) + { + return -1; + } + + if (!RunTest(targetType: typeof(IFooComponent), expectedConverterType: typeof(ReferenceConverter))) + { + return -1; + } + + return 100; + } + + private static bool RunTest(Type targetType, Type expectedConverterType) + { + TypeConverter retrievedConverter = TypeDescriptor.GetConverter(targetType); + return retrievedConverter.GetType() == expectedConverterType && retrievedConverter.CanConvertTo(typeof(string)); + } + + private struct SomeValueType + { + } + + // TypeDescriptor should default to the TypeConverter in this case. + private class ClassWithNoConverter + { + } + + private interface IFooComponent + { + } +} diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs index 16c67b724059..39a37f6bfb39 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs @@ -469,7 +469,9 @@ public void GetAssociationReturnsDesigner() [InlineData(typeof(TimeSpan), typeof(TimeSpanConverter))] [InlineData(typeof(Guid), typeof(GuidConverter))] [InlineData(typeof(Array), typeof(ArrayConverter))] + [InlineData(typeof(int[]), typeof(ArrayConverter))] [InlineData(typeof(ICollection), typeof(CollectionConverter))] + [InlineData(typeof(Stack), typeof(CollectionConverter))] [InlineData(typeof(Enum), typeof(EnumConverter))] [InlineData(typeof(SomeEnum), typeof(EnumConverter))] [InlineData(typeof(SomeValueType?), typeof(NullableConverter))] @@ -482,7 +484,11 @@ public void GetAssociationReturnsDesigner() [InlineData(typeof(ClassIBase), typeof(IBaseConverter))] [InlineData(typeof(ClassIDerived), typeof(IBaseConverter))] [InlineData(typeof(Uri), typeof(UriTypeConverter))] + [InlineData(typeof(DerivedUri), typeof(UriTypeConverter))] + [InlineData(typeof(TwiceDerivedUri), typeof(UriTypeConverter))] [InlineData(typeof(CultureInfo), typeof(CultureInfoConverter))] + [InlineData(typeof(DerivedCultureInfo), typeof(CultureInfoConverter))] + [InlineData(typeof(TwiceDerivedCultureInfo), typeof(CultureInfoConverter))] [InlineData(typeof(Version), typeof(VersionConverter))] [InlineData(typeof(IComponent), typeof(ComponentConverter))] [InlineData(typeof(IFooComponent), typeof(ReferenceConverter))] @@ -1157,5 +1163,27 @@ interface IFooComponent { bool Flag { get; set; } } + + class DerivedUri : Uri + { + protected DerivedUri() : base("https://hello") + { + } + } + + class TwiceDerivedUri : DerivedUri + { + } + + class DerivedCultureInfo : CultureInfo + { + protected DerivedCultureInfo() : base("hello") + { + } + } + + class TwiceDerivedCultureInfo : DerivedCultureInfo + { + } } } From a81e48ffb17aa98adf6144eec4d52e10acf5e999 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 6 Aug 2020 22:03:19 -0500 Subject: [PATCH 308/755] Add DesignerAttribute to types that had it in full framework (#40425) * Add DesignerAttribute to types that had it in full framework * Move DesignerAttributeTests to Primitives and fix test errors * Remove DesignerAttribute.cs from TypeConverter --- eng/DefaultGenApiDocIds.txt | 1 - .../ref/System.ComponentModel.Primitives.cs | 16 ++++++++++++++++ .../System.ComponentModel.Primitives.csproj | 1 + .../ComponentModel/DesignerAttribute.cs | 16 ++++++++-------- .../src/System/ComponentModel/IComponent.cs | 2 ++ ...tem.ComponentModel.Primitives.Tests.csproj | 1 + .../ComponentModel}/DesignerAttributeTests.cs | 4 ++-- ...m.ComponentModel.TypeConverter.Forwards.cs | 3 ++- .../System.ComponentModel.TypeConverter.cs | 19 +++---------------- ...System.ComponentModel.TypeConverter.csproj | 1 - ....ComponentModel.TypeConverter.Tests.csproj | 5 +---- .../ref/System.Data.Common.cs | 15 +++++++++------ .../src/System/Data/DataSet.cs | 1 + .../src/System/Data/DataView.cs | 1 + .../src/System/Data/DataViewManager.cs | 1 + .../System.Data.Odbc/ref/System.Data.Odbc.cs | 19 +++++++++++-------- .../src/System/Data/Odbc/OdbcCommand.cs | 1 + .../src/System/Data/Odbc/OdbcDataAdapter.cs | 2 ++ .../ref/System.Data.OleDb.cs | 16 +++++++++------- .../System.Data.OleDb/src/OleDbCommand.cs | 1 + .../System.Data.OleDb/src/OleDbDataAdapter.cs | 1 + .../ref/System.Diagnostics.Process.cs | 9 ++++++--- .../src/System/Diagnostics/Process.cs | 1 + .../src/System/Diagnostics/ProcessModule.cs | 1 + .../src/System/Diagnostics/ProcessThread.cs | 1 + ...System.ServiceProcess.ServiceController.cs | 1 + .../ServiceProcess/ServiceController.cs | 1 + 27 files changed, 84 insertions(+), 57 deletions(-) rename src/libraries/{System.ComponentModel.TypeConverter => System.ComponentModel.Primitives}/src/System/ComponentModel/DesignerAttribute.cs (92%) rename src/libraries/{System.ComponentModel.TypeConverter/tests => System.ComponentModel.Primitives/tests/System/ComponentModel}/DesignerAttributeTests.cs (95%) diff --git a/eng/DefaultGenApiDocIds.txt b/eng/DefaultGenApiDocIds.txt index 5576d9fad6ae..51ea5986f536 100644 --- a/eng/DefaultGenApiDocIds.txt +++ b/eng/DefaultGenApiDocIds.txt @@ -1,6 +1,5 @@ // These attributes should be excluded from reference assemblies. -T:System.ComponentModel.DesignerAttribute T:System.ComponentModel.Design.Serialization.DesignerSerializerAttribute T:System.ComponentModel.Design.Serialization.RootDesignerSerializerAttribute T:System.ComponentModel.EditorAttribute diff --git a/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs b/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs index 11285fc40906..77a375bcc40f 100644 --- a/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs +++ b/src/libraries/System.ComponentModel.Primitives/ref/System.ComponentModel.Primitives.cs @@ -86,6 +86,20 @@ public DescriptionAttribute(string description) { } public override int GetHashCode() { throw null; } public override bool IsDefaultAttribute() { throw null; } } + [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple=true, Inherited=true)] + public sealed partial class DesignerAttribute : System.Attribute + { + public DesignerAttribute(string designerTypeName) { } + public DesignerAttribute(string designerTypeName, string designerBaseTypeName) { } + public DesignerAttribute(string designerTypeName, System.Type designerBaseType) { } + public DesignerAttribute(System.Type designerType) { } + public DesignerAttribute(System.Type designerType, System.Type designerBaseType) { } + public string DesignerBaseTypeName { get { throw null; } } + public string DesignerTypeName { get { throw null; } } + public override object TypeId { get { throw null; } } + public override bool Equals(object? obj) { throw null; } + public override int GetHashCode() { throw null; } + } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public sealed partial class DesignerCategoryAttribute : System.Attribute { @@ -153,6 +167,8 @@ public void AddHandlers(System.ComponentModel.EventHandlerList listToAddFrom) { public void Dispose() { } public void RemoveHandler(object key, System.Delegate? value) { } } + [System.ComponentModel.DesignerAttribute("System.ComponentModel.Design.ComponentDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] + [System.ComponentModel.DesignerAttribute("System.Windows.Forms.Design.ComponentDocumentDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] [System.ComponentModel.TypeConverterAttribute("System.ComponentModel.ComponentConverter, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public partial interface IComponent : System.IDisposable { diff --git a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj index aa386aae2df8..52c0c0738612 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj +++ b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj @@ -10,6 +10,7 @@ + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DesignerAttribute.cs b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/DesignerAttribute.cs similarity index 92% rename from src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DesignerAttribute.cs rename to src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/DesignerAttribute.cs index 06f34b933759..bde0162bbdf0 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DesignerAttribute.cs +++ b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/DesignerAttribute.cs @@ -11,7 +11,7 @@ namespace System.ComponentModel [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)] public sealed class DesignerAttribute : Attribute { - private string _typeId; + private string? _typeId; /// /// Initializes a new instance of the class using the name of the type that @@ -20,7 +20,7 @@ public sealed class DesignerAttribute : Attribute public DesignerAttribute(string designerTypeName) { DesignerTypeName = designerTypeName ?? throw new ArgumentNullException(nameof(designerTypeName)); - DesignerBaseTypeName = typeof(IDesigner).FullName; + DesignerBaseTypeName = "System.ComponentModel.Design.IDesigner, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } /// @@ -34,8 +34,8 @@ public DesignerAttribute(Type designerType) throw new ArgumentNullException(nameof(designerType)); } - DesignerTypeName = designerType.AssemblyQualifiedName; - DesignerBaseTypeName = typeof(IDesigner).FullName; + DesignerTypeName = designerType.AssemblyQualifiedName!; + DesignerBaseTypeName = "System.ComponentModel.Design.IDesigner, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } /// @@ -64,7 +64,7 @@ public DesignerAttribute(string designerTypeName, Type designerBaseType) } DesignerTypeName = designerTypeName; - DesignerBaseTypeName = designerBaseType.AssemblyQualifiedName; + DesignerBaseTypeName = designerBaseType.AssemblyQualifiedName!; } /// @@ -82,8 +82,8 @@ public DesignerAttribute(Type designerType, Type designerBaseType) throw new ArgumentNullException(nameof(designerBaseType)); } - DesignerTypeName = designerType.AssemblyQualifiedName; - DesignerBaseTypeName = designerBaseType.AssemblyQualifiedName; + DesignerTypeName = designerType.AssemblyQualifiedName!; + DesignerBaseTypeName = designerBaseType.AssemblyQualifiedName!; } /// @@ -121,7 +121,7 @@ public override object TypeId } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == this) { diff --git a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/IComponent.cs b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/IComponent.cs index a94e4f765880..bf953543bdd1 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/IComponent.cs +++ b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/IComponent.cs @@ -19,6 +19,8 @@ namespace System.ComponentModel /// provided "site". /// Provides functionality required by all components. /// + [Designer("System.ComponentModel.Design.ComponentDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] + [Designer("System.Windows.Forms.Design.ComponentDocumentDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] [TypeConverter("System.ComponentModel.ComponentConverter, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public interface IComponent : IDisposable { diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System.ComponentModel.Primitives.Tests.csproj b/src/libraries/System.ComponentModel.Primitives/tests/System.ComponentModel.Primitives.Tests.csproj index 2994d54eb742..ab75a03e9833 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System.ComponentModel.Primitives.Tests.csproj +++ b/src/libraries/System.ComponentModel.Primitives/tests/System.ComponentModel.Primitives.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DesignerAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs similarity index 95% rename from src/libraries/System.ComponentModel.TypeConverter/tests/DesignerAttributeTests.cs rename to src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs index fcd64ecbfaf9..4b7246eadd00 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DesignerAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs @@ -17,7 +17,7 @@ public void Ctor_String(string designerTypeName) { var attribute = new DesignerAttribute(designerTypeName); Assert.Equal(designerTypeName, attribute.DesignerTypeName); - Assert.Equal(typeof(IDesigner).FullName, attribute.DesignerBaseTypeName); + Assert.Equal("System.ComponentModel.Design.IDesigner, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", attribute.DesignerBaseTypeName); } [Theory] @@ -28,7 +28,7 @@ public void Ctor_Type(Type designerType) { var attribute = new DesignerAttribute(designerType); Assert.Equal(designerType.AssemblyQualifiedName, attribute.DesignerTypeName); - Assert.Equal(typeof(IDesigner).FullName, attribute.DesignerBaseTypeName); + Assert.Equal("System.ComponentModel.Design.IDesigner, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", attribute.DesignerBaseTypeName); } [Theory] diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.Forwards.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.Forwards.cs index a789d29492d2..9fa699750635 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.Forwards.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.Forwards.cs @@ -4,9 +4,10 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.Component))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.DesignerAttribute))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.InvalidAsynchronousStateException))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.InvalidEnumArgumentException))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.Component))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.ISupportInitialize))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.TypeConverterAttribute))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.TypeDescriptionProviderAttribute))] diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs index 74a1e68eade5..cfe811bb42df 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs @@ -381,20 +381,6 @@ public DefaultPropertyAttribute(string name) { } public override bool Equals(object obj) { throw null; } public override int GetHashCode() { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple=true, Inherited=true)] - public sealed partial class DesignerAttribute : System.Attribute - { - public DesignerAttribute(string designerTypeName) { } - public DesignerAttribute(string designerTypeName, string designerBaseTypeName) { } - public DesignerAttribute(string designerTypeName, System.Type designerBaseType) { } - public DesignerAttribute(System.Type designerType) { } - public DesignerAttribute(System.Type designerType, System.Type designerBaseType) { } - public string DesignerBaseTypeName { get { throw null; } } - public string DesignerTypeName { get { throw null; } } - public override object TypeId { get { throw null; } } - public override bool Equals(object obj) { throw null; } - public override int GetHashCode() { throw null; } - } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Interface)] public sealed partial class DesignTimeVisibleAttribute : System.Attribute { @@ -833,6 +819,7 @@ public LookupBindingPropertiesAttribute(string dataSource, string displayMember, public override bool Equals(object obj) { throw null; } public override int GetHashCode() { throw null; } } + [System.ComponentModel.DesignerAttribute("System.Windows.Forms.Design.ComponentDocumentDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.ComponentModel.Design.IRootDesigner))] [System.ComponentModel.DesignerCategoryAttribute("Component")] [System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.ComponentConverter))] public partial class MarshalByValueComponent : System.ComponentModel.IComponent, System.IDisposable, System.IServiceProvider @@ -1349,9 +1336,9 @@ public sealed partial class TypeDescriptor internal TypeDescriptor() { } [System.ObsoleteAttribute("This property has been deprecated. Use a type description provider to supply type information for COM types instead. https://go.microsoft.com/fwlink/?linkid=14202")] public static System.ComponentModel.IComNativeDescriptorHandler ComNativeDescriptorHandler { get { throw null; } set { } } - public static System.Type ComObjectType { get { throw null; } } + public static System.Type ComObjectType { [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public static System.Type InterfaceType { get { throw null; } } + public static System.Type InterfaceType { [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { throw null; } } public static event System.ComponentModel.RefreshEventHandler Refreshed { add { } remove { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] public static System.ComponentModel.TypeDescriptionProvider AddAttributes(object instance, params System.Attribute[] attributes) { throw null; } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj index dfdb2e989362..f102c5431630 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj @@ -119,7 +119,6 @@ - diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj b/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj index eb8dda3696e8..a7d84bb1ff6c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj @@ -6,14 +6,12 @@ 9.9.9.9 $(NetCoreAppCurrent) - + - - @@ -72,7 +70,6 @@ - diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index 51be327e1446..24cdb3d274eb 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -65,7 +65,7 @@ public sealed partial class ConstraintCollection : System.Data.InternalDataColle { internal ConstraintCollection() { } public System.Data.Constraint this[int index] { get { throw null; } } - public System.Data.Constraint this[string name] { get { throw null; } } + public System.Data.Constraint? this[string? name] { get { throw null; } } protected override System.Collections.ArrayList List { get { throw null; } } public event System.ComponentModel.CollectionChangeEventHandler? CollectionChanged { add { } remove { } } public void Add(System.Data.Constraint constraint) { } @@ -167,7 +167,7 @@ internal DataColumnCollection() { } public System.Data.DataColumn this[int index] { get { throw null; } } public System.Data.DataColumn? this[string name] { get { throw null; } } protected override System.Collections.ArrayList List { get { throw null; } } - public event System.ComponentModel.CollectionChangeEventHandler CollectionChanged { add { } remove { } } + public event System.ComponentModel.CollectionChangeEventHandler? CollectionChanged { add { } remove { } } public System.Data.DataColumn Add() { throw null; } public void Add(System.Data.DataColumn column) { } public System.Data.DataColumn Add(string? columnName) { throw null; } @@ -261,7 +261,7 @@ public abstract partial class DataRelationCollection : System.Data.InternalDataC { protected DataRelationCollection() { } public abstract System.Data.DataRelation this[int index] { get; } - public abstract System.Data.DataRelation? this[string name] { get; } + public abstract System.Data.DataRelation? this[string? name] { get; } public event System.ComponentModel.CollectionChangeEventHandler? CollectionChanged { add { } remove { } } public virtual System.Data.DataRelation Add(System.Data.DataColumn parentColumn, System.Data.DataColumn childColumn) { throw null; } public virtual System.Data.DataRelation Add(System.Data.DataColumn[] parentColumns, System.Data.DataColumn[] childColumns) { throw null; } @@ -274,7 +274,7 @@ protected virtual void AddCore(System.Data.DataRelation relation) { } public virtual void AddRange(System.Data.DataRelation[]? relations) { } public virtual bool CanRemove(System.Data.DataRelation? relation) { throw null; } public virtual void Clear() { } - public virtual bool Contains(string name) { throw null; } + public virtual bool Contains(string? name) { throw null; } public void CopyTo(System.Data.DataRelation[] array, int index) { } protected abstract System.Data.DataSet GetDataSet(); public virtual int IndexOf(System.Data.DataRelation? relation) { throw null; } @@ -378,8 +378,8 @@ internal DataRowCollection() { } public void Add(System.Data.DataRow row) { } public System.Data.DataRow Add(params object?[] values) { throw null; } public void Clear() { } - public bool Contains(object key) { throw null; } - public bool Contains(object[] keys) { throw null; } + public bool Contains(object? key) { throw null; } + public bool Contains(object?[] keys) { throw null; } public override void CopyTo(System.Array ar, int index) { } public void CopyTo(System.Data.DataRow[] array, int index) { } public System.Data.DataRow? Find(object? key) { throw null; } @@ -477,6 +477,7 @@ public void EndEdit() { } object System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(System.ComponentModel.PropertyDescriptor pd) { throw null; } #nullable enable } + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.DataSetDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [System.ComponentModel.DefaultPropertyAttribute("DataSetName")] [System.Xml.Serialization.XmlRootAttribute("DataSet")] [System.Xml.Serialization.XmlSchemaProviderAttribute("GetDataSetSchema")] @@ -868,6 +869,7 @@ public override void Close() { } public override bool NextResult() { throw null; } public override bool Read() { throw null; } } + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.DataViewDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [System.ComponentModel.DefaultEventAttribute("PositionChanged")] [System.ComponentModel.DefaultPropertyAttribute("Table")] public partial class DataView : System.ComponentModel.MarshalByValueComponent, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.ComponentModel.IBindingList, System.ComponentModel.IBindingListView, System.ComponentModel.ISupportInitialize, System.ComponentModel.ISupportInitializeNotification, System.ComponentModel.ITypedList @@ -965,6 +967,7 @@ void System.ComponentModel.IBindingListView.RemoveFilter() { } protected void UpdateIndex() { } protected virtual void UpdateIndex(bool force) { } } + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.DataViewManagerDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public partial class DataViewManager : System.ComponentModel.MarshalByValueComponent, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.ComponentModel.IBindingList, System.ComponentModel.ITypedList { public DataViewManager() { } diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs index 10e27f30cbbc..20af21299567 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs @@ -23,6 +23,7 @@ namespace System.Data /// /// Represents an in-memory cache of data. /// + [Designer("Microsoft.VSDesigner.Data.VS.DataSetDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [DefaultProperty(nameof(DataSetName))] [Serializable] [XmlSchemaProvider(nameof(GetDataSetSchema))] diff --git a/src/libraries/System.Data.Common/src/System/Data/DataView.cs b/src/libraries/System.Data.Common/src/System/Data/DataView.cs index 931f1ebd5fe6..aa750a44d741 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataView.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataView.cs @@ -15,6 +15,7 @@ namespace System.Data /// Represents a databindable, customized view of a /// for sorting, filtering, searching, editing, and navigation. /// + [Designer("Microsoft.VSDesigner.Data.VS.DataViewDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [DefaultProperty(nameof(Table))] [DefaultEvent("PositionChanged")] public class DataView : MarshalByValueComponent, IBindingListView, System.ComponentModel.ITypedList, ISupportInitializeNotification diff --git a/src/libraries/System.Data.Common/src/System/Data/DataViewManager.cs b/src/libraries/System.Data.Common/src/System/Data/DataViewManager.cs index e10db2488dc4..0f76e3d604c8 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataViewManager.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataViewManager.cs @@ -10,6 +10,7 @@ namespace System.Data { + [Designer("Microsoft.VSDesigner.Data.VS.DataViewManagerDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class DataViewManager : MarshalByValueComponent, IBindingList, System.ComponentModel.ITypedList { private DataViewSettingCollection _dataViewSettingsCollection; diff --git a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs index 934b48caba6e..858ecbf6e8fe 100644 --- a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs +++ b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs @@ -6,6 +6,7 @@ namespace System.Data.Odbc { + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OdbcCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class OdbcCommand : System.Data.Common.DbCommand, System.ICloneable { public OdbcCommand() { } @@ -44,7 +45,7 @@ protected override void Dispose(bool disposing) { } public override object? ExecuteScalar() { throw null; } public override void Prepare() { } public void ResetCommandTimeout() { } - object System.ICloneable.Clone() { throw null; } + object? System.ICloneable.Clone() { throw null; } } public sealed partial class OdbcCommandBuilder : System.Data.Common.DbCommandBuilder { @@ -63,16 +64,17 @@ public static void DeriveParameters(System.Data.Odbc.OdbcCommand command) { } public new System.Data.Odbc.OdbcCommand GetUpdateCommand() { throw null; } public new System.Data.Odbc.OdbcCommand GetUpdateCommand(bool useColumnsForParameterNames) { throw null; } public override string QuoteIdentifier(string unquotedIdentifier) { throw null; } - public string QuoteIdentifier(string unquotedIdentifier, System.Data.Odbc.OdbcConnection connection) { throw null; } + public string QuoteIdentifier(string unquotedIdentifier, System.Data.Odbc.OdbcConnection? connection) { throw null; } protected override void SetRowUpdatingHandler(System.Data.Common.DbDataAdapter adapter) { } public override string UnquoteIdentifier(string quotedIdentifier) { throw null; } - public string UnquoteIdentifier(string quotedIdentifier, System.Data.Odbc.OdbcConnection connection) { throw null; } + public string UnquoteIdentifier(string quotedIdentifier, System.Data.Odbc.OdbcConnection? connection) { throw null; } } public sealed partial class OdbcConnection : System.Data.Common.DbConnection, System.ICloneable { public OdbcConnection() { } public OdbcConnection(string? connectionString) { } - public override string? ConnectionString { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] + public override string ConnectionString { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(15)] [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public new int ConnectionTimeout { get { throw null; } set { } } @@ -120,8 +122,9 @@ public OdbcConnectionStringBuilder(string? connectionString) { } public override void Clear() { } public override bool ContainsKey(string keyword) { throw null; } public override bool Remove(string keyword) { throw null; } - public override bool TryGetValue(string keyword, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out object? value) { throw null; } + public override bool TryGetValue(string keyword, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? value) { throw null; } } + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OdbcDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class OdbcDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable { public OdbcDataAdapter() { } @@ -142,7 +145,7 @@ public event System.Data.Odbc.OdbcRowUpdatingEventHandler? RowUpdating { add { } protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs value) { } protected override void OnRowUpdating(System.Data.Common.RowUpdatingEventArgs value) { } - object System.ICloneable.Clone() { throw null; } + object? System.ICloneable.Clone() { throw null; } } public sealed partial class OdbcDataReader : System.Data.Common.DbDataReader { @@ -252,7 +255,7 @@ public OdbcParameter() { } public OdbcParameter(string? name, System.Data.Odbc.OdbcType type) { } public OdbcParameter(string? name, System.Data.Odbc.OdbcType type, int size) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public OdbcParameter(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object? value) { } + public OdbcParameter(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string? srcColumn, System.Data.DataRowVersion srcVersion, object? value) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] public OdbcParameter(string? parameterName, System.Data.Odbc.OdbcType odbcType, int size, System.Data.ParameterDirection parameterDirection, byte precision, byte scale, string? sourceColumn, System.Data.DataRowVersion sourceVersion, bool sourceColumnNullMapping, object? value) { } public OdbcParameter(string? name, System.Data.Odbc.OdbcType type, int size, string? sourcecolumn) { } @@ -275,7 +278,7 @@ public OdbcParameter(string? name, object? value) { } public override object? Value { get { throw null; } set { } } public override void ResetDbType() { } public void ResetOdbcType() { } - object System.ICloneable.Clone() { throw null; } + object? System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } } public sealed partial class OdbcParameterCollection : System.Data.Common.DbParameterCollection diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs index ad7b21c9a90e..ca88997ebdbd 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs @@ -16,6 +16,7 @@ namespace System.Data.Odbc { + [Designer("Microsoft.VSDesigner.Data.VS.OdbcCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed class OdbcCommand : DbCommand, ICloneable { private static int s_objectTypeCount; // Bid counter diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs index 29b6dcc149f7..77630d1f2869 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; using System.Data.Common; namespace System.Data.Odbc { + [Designer("Microsoft.VSDesigner.Data.VS.OdbcDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed class OdbcDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable { private static readonly object s_eventRowUpdated = new object(); diff --git a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs index 7ad5fdf0812d..eaaff8244c59 100644 --- a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs +++ b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs @@ -6,6 +6,7 @@ namespace System.Data.OleDb { + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OleDbCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class OleDbCommand : System.Data.Common.DbCommand, System.Data.IDbCommand, System.ICloneable, System.IDisposable { public OleDbCommand() { } @@ -108,7 +109,7 @@ public override void Close() { } protected override System.Data.Common.DbCommand CreateDbCommand() { throw null; } protected override void Dispose(bool disposing) { } public override void EnlistTransaction(System.Transactions.Transaction? transaction) { } - public System.Data.DataTable GetOleDbSchemaTable(System.Guid schema, object?[]? restrictions) { throw null; } + public System.Data.DataTable? GetOleDbSchemaTable(System.Guid schema, object?[]? restrictions) { throw null; } public override System.Data.DataTable GetSchema() { throw null; } public override System.Data.DataTable GetSchema(string collectionName) { throw null; } public override System.Data.DataTable GetSchema(string collectionName, string?[]? restrictionValues) { throw null; } @@ -140,6 +141,7 @@ public override void Clear() { } public override bool Remove(string keyword) { throw null; } public override bool TryGetValue(string keyword, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out object? value) { throw null; } } + [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class OleDbDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable { public OleDbDataAdapter() { } @@ -160,13 +162,13 @@ public OleDbDataAdapter(string? selectCommandText, string? selectConnectionStrin public new System.Data.OleDb.OleDbCommand? UpdateCommand { get { throw null; } set { } } public event System.Data.OleDb.OleDbRowUpdatedEventHandler? RowUpdated { add { } remove { } } public event System.Data.OleDb.OleDbRowUpdatingEventHandler? RowUpdating { add { } remove { } } - protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } - protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } + protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) { throw null; } public int Fill(System.Data.DataSet dataSet, object ADODBRecordSet, string srcTable) { throw null; } public int Fill(System.Data.DataTable dataTable, object ADODBRecordSet) { throw null; } protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs value) { } protected override void OnRowUpdating(System.Data.Common.RowUpdatingEventArgs value) { } - object System.ICloneable.Clone() { throw null; } + object? System.ICloneable.Clone() { throw null; } } public sealed partial class OleDbDataReader : System.Data.Common.DbDataReader { @@ -350,7 +352,7 @@ public OleDbParameter(string? name, object? value) { } public override object? Value { get { throw null; } set { } } public override void ResetDbType() { } public void ResetOleDbType() { } - object System.ICloneable.Clone() { throw null; } + object? System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } } public sealed partial class OleDbParameterCollection : System.Data.Common.DbParameterCollection @@ -399,13 +401,13 @@ protected override void SetParameter(string parameterName, System.Data.Common.Db } public sealed partial class OleDbRowUpdatedEventArgs : System.Data.Common.RowUpdatedEventArgs { - public OleDbRowUpdatedEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } + public OleDbRowUpdatedEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } public new System.Data.OleDb.OleDbCommand? Command { get { throw null; } } } public delegate void OleDbRowUpdatedEventHandler(object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e); public sealed partial class OleDbRowUpdatingEventArgs : System.Data.Common.RowUpdatingEventArgs { - public OleDbRowUpdatingEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } + public OleDbRowUpdatingEventArgs(System.Data.DataRow dataRow, System.Data.IDbCommand? command, System.Data.StatementType statementType, System.Data.Common.DataTableMapping tableMapping) : base (default(System.Data.DataRow), default(System.Data.IDbCommand), default(System.Data.StatementType), default(System.Data.Common.DataTableMapping)) { } protected override System.Data.IDbCommand? BaseCommand { get { throw null; } set { } } public new System.Data.OleDb.OleDbCommand? Command { get { throw null; } set { } } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index 329200e7f2ed..458335b605ac 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -12,6 +12,7 @@ namespace System.Data.OleDb { + [Designer("Microsoft.VSDesigner.Data.VS.OleDbCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed class OleDbCommand : DbCommand, ICloneable, IDbCommand { // command data diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 05714cef63f9..e4e7ba472378 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -8,6 +8,7 @@ namespace System.Data.OleDb { + [Designer("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable { private static readonly object EventRowUpdated = new object(); diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index 57c2a5cfc612..74fa2a149c4d 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -26,6 +26,7 @@ public partial class MonitoringDescriptionAttribute : System.ComponentModel.Desc public MonitoringDescriptionAttribute(string description) { } public override string Description { get { throw null; } } } + [System.ComponentModel.DesignerAttribute("System.Diagnostics.Design.ProcessDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public partial class Process : System.ComponentModel.Component, System.IDisposable { public Process() { } @@ -117,17 +118,18 @@ public void Refresh() { } public static System.Diagnostics.Process Start(string fileName, string arguments) { throw null; } [System.CLSCompliantAttribute(false)] [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public static System.Diagnostics.Process Start(string fileName, string userName, System.Security.SecureString password, string domain) { throw null; } + public static System.Diagnostics.Process? Start(string fileName, string userName, System.Security.SecureString password, string domain) { throw null; } [System.CLSCompliantAttribute(false)] [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public static System.Diagnostics.Process Start(string fileName, string arguments, string userName, System.Security.SecureString password, string domain) { throw null; } + public static System.Diagnostics.Process? Start(string fileName, string arguments, string userName, System.Security.SecureString password, string domain) { throw null; } public override string ToString() { throw null; } public void WaitForExit() { } public bool WaitForExit(int milliseconds) { throw null; } - public System.Threading.Tasks.Task WaitForExitAsync(System.Threading.CancellationToken cancellationToken = default) { throw null; } + public System.Threading.Tasks.Task WaitForExitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public bool WaitForInputIdle() { throw null; } public bool WaitForInputIdle(int milliseconds) { throw null; } } + [System.ComponentModel.DesignerAttribute("System.Diagnostics.Design.ProcessModuleDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public partial class ProcessModule : System.ComponentModel.Component { internal ProcessModule() { } @@ -194,6 +196,7 @@ public ProcessStartInfo(string fileName, string arguments) { } public System.Diagnostics.ProcessWindowStyle WindowStyle { get { throw null; } set { } } public string WorkingDirectory { get { throw null; } set { } } } + [System.ComponentModel.DesignerAttribute("System.Diagnostics.Design.ProcessThreadDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public partial class ProcessThread : System.ComponentModel.Component { internal ProcessThread() { } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index 6d33ac04877c..7349b3112e40 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -20,6 +20,7 @@ namespace System.Diagnostics /// processes. Enables you to start and stop system processes. /// /// + [Designer("System.Diagnostics.Design.ProcessDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public partial class Process : Component { private bool _haveProcessId; diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs index 4d6f5aadad27..b2abe8263bc8 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs @@ -10,6 +10,7 @@ namespace System.Diagnostics /// a particular process. Using this component, you can determine /// information about the module. /// + [Designer("System.Diagnostics.Design.ProcessModuleDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public class ProcessModule : Component { private FileVersionInfo? _fileVersionInfo; diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs index f5ec77c8e564..6ff4cafba849 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThread.cs @@ -13,6 +13,7 @@ namespace System.Diagnostics /// returned from the System.Diagnostics.Process.ProcessThread property of the System.Diagnostics.Process component. /// /// + [Designer("System.Diagnostics.Design.ProcessThreadDesigner, System.Design, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a")] public partial class ProcessThread : Component { private readonly bool _isRemoteMachine; diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs index e11cbf46e246..8fc328bf373d 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs @@ -57,6 +57,7 @@ public static void Run(System.ServiceProcess.ServiceBase[] services) { } public void ServiceMainCallback(int argCount, System.IntPtr argPointer) { } public void Stop() { } } + [System.ComponentModel.DesignerAttribute("System.ServiceProcess.Design.ServiceControllerDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public partial class ServiceController : System.ComponentModel.Component { public ServiceController() { } diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs index 6717adaf246a..fdb4d99d19df 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs @@ -17,6 +17,7 @@ namespace System.ServiceProcess { /// This class represents an NT service. It allows you to connect to a running or stopped service /// and manipulate it or get information about it. + [Designer("System.ServiceProcess.Design.ServiceControllerDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class ServiceController : Component { private string _machineName; // Never null From 74611e5a2148a94b9854e6e38a956a94ace37b19 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 6 Aug 2020 20:56:25 -0700 Subject: [PATCH 309/755] Fix caching EH clause type handle problem in a conservative fashion (#40493) This caching was intended to improve performance of repeatedly catching exceptions. As it happens, the critical section that was being used to protect the cache could trigger a GC, and cause a failure under stress. However, some years ago, the eh clause as operated on by the ResolveEHClause method was changed to be a copy of the EHClause stored during the JIT operation, and thus the caching efforts done in this function did not provide value, and in fact are a minor source of multithread scaling concerns. - Remove the dynamic caching. (Note, the TypeHandle member variable and the HasCachedTypeHandle function, are still used for LCG dynamic methods.) - Rename the critical section used to protect the cache, as it is now only used to protect from loading multiple copies of the JIT. --- src/coreclr/src/vm/codeman.cpp | 62 ++++++---------------------------- src/coreclr/src/vm/codeman.h | 2 +- 2 files changed, 11 insertions(+), 53 deletions(-) diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index ea39db725e60..8b8070bdf2d5 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1203,7 +1203,7 @@ EEJitManager::EEJitManager() m_CodeHeapCritSec( CrstSingleUseLock, CrstFlags(CRST_UNSAFE_ANYMODE|CRST_DEBUGGER_THREAD|CRST_TAKEN_DURING_SHUTDOWN)), m_CPUCompileFlags(), - m_EHClauseCritSec( CrstSingleUseLock ) + m_JitLoadCritSec( CrstSingleUseLock ) { CONTRACTL { THROWS; @@ -1702,8 +1702,8 @@ BOOL EEJitManager::LoadJIT() if (IsJitLoaded()) return TRUE; - // Abuse m_EHClauseCritSec to ensure that the JIT is loaded on one thread only - CrstHolder chRead(&m_EHClauseCritSec); + // Use m_JitLoadCritSec to ensure that the JIT is loaded on one thread only + CrstHolder chRead(&m_JitLoadCritSec); // Did someone load the JIT before we got the lock? if (IsJitLoaded()) @@ -3048,21 +3048,14 @@ TypeHandle EEJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, TypeHandle typeHnd = TypeHandle(); mdToken typeTok = mdTokenNil; + // CachedTypeHandle's are filled in at JIT time, and not cached when accessed multiple times + if (HasCachedTypeHandle(pEHClause)) { - CrstHolder chRead(&m_EHClauseCritSec); - if (HasCachedTypeHandle(pEHClause)) - { - typeHnd = TypeHandle::FromPtr(pEHClause->TypeHandle); - } - else - { - typeTok = pEHClause->ClassToken; - } + return TypeHandle::FromPtr(pEHClause->TypeHandle); } - - if (!typeHnd.IsNull()) + else { - return typeHnd; + typeTok = pEHClause->ClassToken; } MethodDesc* pMD = pCf->GetFunction(); @@ -3100,43 +3093,8 @@ TypeHandle EEJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, } } - typeHnd = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, typeTok, &typeContext, - ClassLoader::ReturnNullIfNotFound); - - // If the type (pModule,typeTok) was not loaded or not - // restored then the exception object won't have this type, because an - // object of this type has not been allocated. - if (typeHnd.IsNull()) - return typeHnd; - - // We can cache any exception specification except: - // - If the type contains type variables in generic code, - // e.g. catch E where T is a type variable. - // We CANNOT cache E in non-shared instantiations of generic code because - // there is only one EHClause cache for the IL, shared across all instantiations. - // - if((k & hasAnyVarsMask) == 0) - { - CrstHolder chWrite(&m_EHClauseCritSec); - - // Note another thread might have beaten us to it ... - if (!HasCachedTypeHandle(pEHClause)) - { - // We should never cache a NULL typeHnd. - _ASSERTE(!typeHnd.IsNull()); - pEHClause->TypeHandle = typeHnd.AsPtr(); - SetHasCachedTypeHandle(pEHClause); - } - else - { - // If we raced in here with another thread and got held up on the lock, then we just need to return the - // type handle that the other thread put into the clause. - // The typeHnd we found and the typeHnd the racing thread found should always be the same - _ASSERTE(typeHnd.AsPtr() == pEHClause->TypeHandle); - typeHnd = TypeHandle::FromPtr(pEHClause->TypeHandle); - } - } - return typeHnd; + return ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, typeTok, &typeContext, + ClassLoader::ReturnNullIfNotFound); } void EEJitManager::RemoveJitData (CodeHeader * pCHdr, size_t GCinfo_len, size_t EHinfo_len) diff --git a/src/coreclr/src/vm/codeman.h b/src/coreclr/src/vm/codeman.h index cba802dc03b6..97d8b5f2b7f3 100644 --- a/src/coreclr/src/vm/codeman.h +++ b/src/coreclr/src/vm/codeman.h @@ -1116,7 +1116,7 @@ protected : private : PTR_HostCodeHeap m_cleanupList; //When EH Clauses are resolved we need to atomically update the TypeHandle - Crst m_EHClauseCritSec; + Crst m_JitLoadCritSec; #if !defined CROSSGEN_COMPILE // must hold critical section to access this structure. From c073e574a6d144dfe5499bc2aa96122581250325 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 7 Aug 2020 09:16:19 +0200 Subject: [PATCH 310/755] Implement platform guards in OperatingSystem class (#40457) * add Is$OsName methods to OperatingSystem class * add OperatingSystem.*VersionAtLeast methods * add IsOSPlatform and IsOSPlatformVersionAtLeast * add xml comments * address code review suggestions * move TARGET_* defines to a common file --- src/coreclr/clr.featuredefines.props | 4 - .../System.Private.CoreLib.Shared.projitems | 11 + .../src/System/OperatingSystem.cs | 192 ++++++++++++++++++ .../tests/System/OperatingSystemTests.cs | 166 +++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 18 ++ .../System.Private.CoreLib.csproj | 6 - 6 files changed, 387 insertions(+), 10 deletions(-) diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index b5979c8d2390..c5119c80424d 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -66,9 +66,5 @@ $(DefineConstants);PROFILING_SUPPORTED $(DefineConstants);FEATURE_PROFAPI_ATTACH_DETACH - - $(DefineConstants);TARGET_UNIX - $(DefineConstants);TARGET_WINDOWS - $(DefineConstants);TARGET_OSX diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 4278e25e67dc..27bccfced38f 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -15,6 +15,17 @@ true $(MSBuildThisFileDirectory)ILLink\ + + $(DefineConstants);TARGET_UNIX + $(DefineConstants);TARGET_WINDOWS + $(DefineConstants);TARGET_OSX + $(DefineConstants);TARGET_IOS + $(DefineConstants);TARGET_TVOS + $(DefineConstants);TARGET_BROWSER + $(DefineConstants);TARGET_ANDROID + $(DefineConstants);TARGET_LINUX + $(DefineConstants);TARGET_FREEBSD + diff --git a/src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs b/src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs index 718f67cc9096..6b3a5b5682f4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs +++ b/src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs @@ -8,6 +8,10 @@ namespace System { public sealed class OperatingSystem : ISerializable, ICloneable { +#if TARGET_UNIX && !TARGET_OSX + private static readonly string s_osPlatformName = Interop.Sys.GetUnixName(); +#endif + private readonly Version _version; private readonly PlatformID _platform; private readonly string? _servicePack; @@ -79,5 +83,193 @@ public string VersionString return _versionString; } } + + /// + /// Indicates whether the current application is running on the specified platform. + /// + /// Case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows. + public static bool IsOSPlatform(string platform) + { + if (platform == null) + { + throw new ArgumentNullException(nameof(platform)); + } + +#if TARGET_BROWSER + return platform.Equals("BROWSER", StringComparison.OrdinalIgnoreCase); +#elif TARGET_WINDOWS + return platform.Equals("WINDOWS", StringComparison.OrdinalIgnoreCase); +#elif TARGET_OSX + return platform.Equals("OSX", StringComparison.OrdinalIgnoreCase) || platform.Equals("MACOS", StringComparison.OrdinalIgnoreCase); +#elif TARGET_UNIX + return platform.Equals(s_osPlatformName, StringComparison.OrdinalIgnoreCase); +#else +#error Unknown OS +#endif + } + + /// + /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. + /// + /// Case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows. + /// Major OS version number. + /// Minor OS version number (optional). + /// Build OS version number (optional). + /// Revision OS version number (optional). + public static bool IsOSPlatformVersionAtLeast(string platform, int major, int minor = 0, int build = 0, int revision = 0) + => IsOSPlatform(platform) && IsOSVersionAtLeast(major, minor, build, revision); + + /// + /// Indicates whether the current application is running as WASM in a Browser. + /// + public static bool IsBrowser() => +#if TARGET_BROWSER + true; +#else + false; +#endif + + /// + /// Indicates whether the current application is running on Linux. + /// + public static bool IsLinux() => +#if TARGET_LINUX + true; +#else + false; +#endif + + /// + /// Indicates whether the current application is running on FreeBSD. + /// + public static bool IsFreeBSD() => +#if TARGET_FREEBSD + true; +#else + false; +#endif + + /// + /// Check for the FreeBSD version (returned by 'uname') with a >= version comparison. Used to guard APIs that were added in the given FreeBSD release. + /// + public static bool IsFreeBSDVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) + => IsFreeBSD() && IsOSVersionAtLeast(major, minor, build, revision); + + /// + /// Indicates whether the current application is running on Android. + /// + public static bool IsAndroid() => +#if TARGET_ANDROID + true; +#else + false; +#endif + + /// + /// Check for the Android version (returned by 'uname') with a >= version comparison. Used to guard APIs that were added in the given Android release. + /// + public static bool IsAndroidVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) + => IsAndroid() && IsOSVersionAtLeast(major, minor, build, revision); + + /// + /// Indicates whether the current application is running on iOS. + /// + public static bool IsIOS() => +#if TARGET_IOS + true; +#else + false; +#endif + + /// + /// Check for the iOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given iOS release. + /// + public static bool IsIOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsIOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on macOS. + /// + public static bool IsMacOS() => +#if TARGET_OSX + true; +#else + false; +#endif + + /// + /// Check for the macOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given macOS release. + /// + public static bool IsMacOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsMacOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on tvOS. + /// + public static bool IsTvOS() => +#if TARGET_TVOS + true; +#else + false; +#endif + + /// + /// Check for the tvOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given tvOS release. + /// + public static bool IsTvOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsTvOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on watchOS. + /// + public static bool IsWatchOS() => +#if TARGET_WATCHOS + true; +#else + false; +#endif + + /// + /// Check for the watchOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given watchOS release. + /// + public static bool IsWatchOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsWatchOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on Windows. + /// + public static bool IsWindows() => +#if TARGET_WINDOWS + true; +#else + false; +#endif + + /// + /// Check for the Windows version (returned by 'RtlGetVersion') with a >= version comparison. Used to guard APIs that were added in the given Windows release. + /// + public static bool IsWindowsVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) + => IsWindows() && IsOSVersionAtLeast(major, minor, build, revision); + + private static bool IsOSVersionAtLeast(int major, int minor, int build, int revision) + { + Version current = Environment.OSVersion.Version; + + if (current.Major != major) + { + return current.Major > major; + } + if (current.Minor != minor) + { + return current.Minor > minor; + } + if (current.Build != build) + { + return current.Build > build; + } + + return current.Revision >= revision + || (current.Revision == -1 && revision == 0); // it is unavailable on OSX and Environment.OSVersion.Version.Revision returns -1 + } } } diff --git a/src/libraries/System.Runtime.Extensions/tests/System/OperatingSystemTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/OperatingSystemTests.cs index b6e7005d62f3..c355baf8e2ae 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/OperatingSystemTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/OperatingSystemTests.cs @@ -7,6 +7,19 @@ namespace System.Tests { public static class OperatingSystemTests { + private static readonly string[] AllKnownPlatformNames = new[] + { + "Android", + "macOS", + "iOS", + "tvOS", + "watchOS", + "Windows", + "Linux", + "FreeBSD", + "Browser" + }; + [Theory] [InlineData(PlatformID.Other, "1.0.0.0")] [InlineData(PlatformID.MacOSX, "1.2")] @@ -47,5 +60,158 @@ public static void Clone() Assert.Equal(os.Version, os2.Version); Assert.Equal(os.VersionString, os2.VersionString); } + + [Fact] + public static void IsOSPlatform_InvalidArgs_Throws() + { + AssertExtensions.Throws("platform", () => OperatingSystem.IsOSPlatform(null)); + } + + [Fact] + public static void IsOSPlatformVersionAtLeast_InvalidArgs_Throws() + { + AssertExtensions.Throws("platform", () => OperatingSystem.IsOSPlatformVersionAtLeast(null, 1)); + } + + [Fact, PlatformSpecific(TestPlatforms.Browser)] + public static void TestIsOSPlatform_Browser() => TestIsOSPlatform("BROWSER", OperatingSystem.IsBrowser); + + [Fact, PlatformSpecific(TestPlatforms.Browser)] + public static void TestIsOSVersionAtLeast_Browser() => TestIsOSVersionAtLeast("BROWSER"); + + [Fact, PlatformSpecific(TestPlatforms.Linux)] + public static void TestIsOSPlatform_Linux() => TestIsOSPlatform("Linux", OperatingSystem.IsLinux); + + [Fact, PlatformSpecific(TestPlatforms.Linux)] + public static void TestIsOSVersionAtLeast_Linux() => TestIsOSVersionAtLeast("Linux"); + + [Fact, PlatformSpecific(TestPlatforms.FreeBSD)] + public static void TestIsOSPlatform_FreeBSD() => TestIsOSPlatform("FreeBSD", OperatingSystem.IsFreeBSD); + + [Fact, PlatformSpecific(TestPlatforms.FreeBSD)] + public static void TestIsOSVersionAtLeast_FreeBSD() => TestIsOSVersionAtLeast("FreeBSD"); + + [Fact, PlatformSpecific(TestPlatforms.Android)] + public static void TestIsOSPlatform_Android() => TestIsOSPlatform("Android", OperatingSystem.IsAndroid); + + [Fact, PlatformSpecific(TestPlatforms.Android)] + public static void TestIsOSVersionAtLeast_Android() => TestIsOSVersionAtLeast("Android"); + + [Fact, PlatformSpecific(TestPlatforms.iOS)] + public static void TestIsOSPlatform_IOS() => TestIsOSPlatform("iOS", OperatingSystem.IsIOS); + + [Fact, PlatformSpecific(TestPlatforms.iOS)] + public static void TestIsOSVersionAtLeast_IOS() => TestIsOSVersionAtLeast("iOS"); + + [Fact, PlatformSpecific(TestPlatforms.OSX)] + public static void TestIsOSPlatform_MacOS() => TestIsOSPlatform("macOS", OperatingSystem.IsMacOS); + + [Fact, PlatformSpecific(TestPlatforms.OSX)] + public static void TestIsOSVersionAtLeast_MacOS() => TestIsOSVersionAtLeast("macOS"); + + [Fact, PlatformSpecific(TestPlatforms.OSX)] + public static void OSX_Is_Treated_as_macOS() + { + // we prefer "macOS", but still accept "OSX" + + Assert.True(OperatingSystem.IsOSPlatform("OSX")); + + AssertVersionChecks(true, (major, minor, build, revision) => OperatingSystem.IsOSPlatformVersionAtLeast("OSX", major, minor, build, revision)); + AssertVersionChecks(true, (major, minor, build, revision) => OperatingSystem.IsOSPlatformVersionAtLeast("osx", major, minor, build, revision)); + AssertVersionChecks(true, (major, minor, build) => OperatingSystem.IsOSPlatformVersionAtLeast("OSX", major, minor, build)); + AssertVersionChecks(true, (major, minor, build) => OperatingSystem.IsOSPlatformVersionAtLeast("osx", major, minor, build)); + } + + [Fact, PlatformSpecific(TestPlatforms.tvOS)] + public static void TestIsOSPlatform_TvOS() => TestIsOSPlatform("tvOS", OperatingSystem.IsTvOS); + + [Fact, PlatformSpecific(TestPlatforms.tvOS)] + public static void TestIsOSVersionAtLeast_TvOS() => TestIsOSVersionAtLeast("tvOS"); + + [Fact, PlatformSpecific(TestPlatforms.Windows)] + public static void TestIsOSPlatform_Windows() => TestIsOSPlatform("Windows", OperatingSystem.IsWindows); + + [Fact, PlatformSpecific(TestPlatforms.Windows)] + public static void TestIsOSVersionAtLeast_Windows() => TestIsOSVersionAtLeast("Windows"); + + private static void TestIsOSPlatform(string currentOSName, Func currentOSCheck) + { + foreach (string platfromName in AllKnownPlatformNames) + { + bool expected = currentOSName.Equals(platfromName, StringComparison.OrdinalIgnoreCase); + + Assert.Equal(expected, OperatingSystem.IsOSPlatform(platfromName)); + Assert.Equal(expected, OperatingSystem.IsOSPlatform(platfromName.ToUpper())); + Assert.Equal(expected, OperatingSystem.IsOSPlatform(platfromName.ToLower())); + } + + Assert.True(currentOSCheck()); + + bool[] allResults = new bool[] + { + OperatingSystem.IsBrowser(), + OperatingSystem.IsLinux(), + OperatingSystem.IsFreeBSD(), + OperatingSystem.IsAndroid(), + OperatingSystem.IsIOS(), + OperatingSystem.IsMacOS(), + OperatingSystem.IsTvOS(), + OperatingSystem.IsWatchOS(), + OperatingSystem.IsWindows() + }; + + Assert.Single(allResults, true); + } + + private static void TestIsOSVersionAtLeast(string currentOSName) + { + foreach (string platfromName in AllKnownPlatformNames) + { + bool isCurrentOS = currentOSName.Equals(platfromName, StringComparison.OrdinalIgnoreCase); + + AssertVersionChecks(isCurrentOS, (major, minor, build, revision) => OperatingSystem.IsOSPlatformVersionAtLeast(platfromName, major, minor, build, revision)); + AssertVersionChecks(isCurrentOS, (major, minor, build, revision) => OperatingSystem.IsOSPlatformVersionAtLeast(platfromName.ToLower(), major, minor, build, revision)); + AssertVersionChecks(isCurrentOS, (major, minor, build, revision) => OperatingSystem.IsOSPlatformVersionAtLeast(platfromName.ToUpper(), major, minor, build, revision)); + } + + AssertVersionChecks(currentOSName.Equals("Android", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsAndroidVersionAtLeast); + AssertVersionChecks(currentOSName.Equals("iOS", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsIOSVersionAtLeast); + AssertVersionChecks(currentOSName.Equals("macOS", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsMacOSVersionAtLeast); + AssertVersionChecks(currentOSName.Equals("tvOS", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsTvOSVersionAtLeast); + AssertVersionChecks(currentOSName.Equals("watchOS", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsWatchOSVersionAtLeast); + AssertVersionChecks(currentOSName.Equals("Windows", StringComparison.OrdinalIgnoreCase), OperatingSystem.IsWindowsVersionAtLeast); + } + + private static void AssertVersionChecks(bool isCurrentOS, Func isOSVersionAtLeast) + { + Version current = Environment.OSVersion.Version; + + Assert.False(isOSVersionAtLeast(current.Major + 1, current.Minor, current.Build, current.Revision)); + Assert.False(isOSVersionAtLeast(current.Major, current.Minor + 1, current.Build, current.Revision)); + Assert.False(isOSVersionAtLeast(current.Major, current.Minor, current.Build + 1, current.Revision)); + Assert.False(isOSVersionAtLeast(current.Major, current.Minor, current.Build, Math.Max(current.Revision + 1, 1))); // OSX Revision reports -1 + + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor, current.Build, current.Revision)); + + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major - 1, current.Minor, current.Build, current.Revision)); + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor - 1, current.Build, current.Revision)); + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor, current.Build - 1, current.Revision)); + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor, current.Build, current.Revision - 1)); + } + + private static void AssertVersionChecks(bool isCurrentOS, Func isOSVersionAtLeast) + { + Version current = Environment.OSVersion.Version; + + Assert.False(isOSVersionAtLeast(current.Major + 1, current.Minor, current.Build)); + Assert.False(isOSVersionAtLeast(current.Major, current.Minor + 1, current.Build)); + Assert.False(isOSVersionAtLeast(current.Major, current.Minor, current.Build + 1)); + + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor, current.Build)); + + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major - 1, current.Minor, current.Build)); + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor - 1, current.Build)); + Assert.Equal(isCurrentOS, isOSVersionAtLeast(current.Major, current.Minor, current.Build - 1)); + } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index da360cbad7cd..aaaf4da863d9 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -3044,6 +3044,24 @@ public OperatingSystem(System.PlatformID platform, System.Version version) { } public object Clone() { throw null; } public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public override string ToString() { throw null; } + public static bool IsOSPlatform(string platform) { throw null; } + public static bool IsOSPlatformVersionAtLeast(string platform, int major, int minor = 0, int build = 0, int revision = 0) { throw null; } + public static bool IsBrowser() { throw null; } + public static bool IsLinux() { throw null; } + public static bool IsFreeBSD() { throw null; } + public static bool IsFreeBSDVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) { throw null; } + public static bool IsAndroid() { throw null; } + public static bool IsAndroidVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) { throw null; } + public static bool IsIOS() { throw null; } + public static bool IsIOSVersionAtLeast(int major, int minor = 0, int build = 0) { throw null; } + public static bool IsMacOS() { throw null; } + public static bool IsMacOSVersionAtLeast(int major, int minor = 0, int build = 0) { throw null; } + public static bool IsTvOS() { throw null; } + public static bool IsTvOSVersionAtLeast(int major, int minor = 0, int build = 0) { throw null; } + public static bool IsWatchOS() { throw null; } + public static bool IsWatchOSVersionAtLeast(int major, int minor = 0, int build = 0) { throw null; } + public static bool IsWindows() { throw null; } + public static bool IsWindowsVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) { throw null; } } public partial class OperationCanceledException : System.SystemException { diff --git a/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj index e2435e591fa6..af48a96262b6 100644 --- a/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/netcore/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -132,12 +132,6 @@ $(DefineConstants);FEATURE_MANAGED_ETW_CHANNELS $(DefineConstants);FEATURE_PERFTRACING $(DefineConstants);FEATURE_DEFAULT_INTERFACES - $(DefineConstants);TARGET_UNIX - $(DefineConstants);TARGET_WINDOWS - $(DefineConstants);TARGET_OSX - $(DefineConstants);TARGET_IOS - $(DefineConstants);TARGET_TVOS - $(DefineConstants);TARGET_BROWSER From 851e32a888d68c775783d7ccdb21b16084923bbb Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Fri, 7 Aug 2020 11:03:27 +0200 Subject: [PATCH 311/755] Trim async debugging when debugging feature is disabled (#40400) --- .../src/ILLink/ILLink.Substitutions.Shared.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml index 81e98c3f71b5..9831ce9b6e2d 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml @@ -15,5 +15,8 @@ + + + From 3ea278dae3906826fe85a032a45e04d9c1975d94 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 7 Aug 2020 12:18:34 +0200 Subject: [PATCH 312/755] Remove new platform members from OSPlatform (#40373) * Remove new platform members from OSPlatform * remove IsOSPlatformEarlierThan and IsOSPlatformOrLater methods * remove unused resource and dependency * delegate RuntimeInformation.IsOSPlatform to call OperatingSystem.IsOSPlatform. it won't compile now as the new guards have not been merged yet (#40457) * remove OSPlatform.Browser and it's usage --- .../tests/MemoryMappedFilesTestsBase.Unix.cs | 2 +- .../tests/System/EnvironmentTests.cs | 4 +- ...time.InteropServices.RuntimeInformation.cs | 17 -- .../src/Resources/Strings.resx | 3 - ....InteropServices.RuntimeInformation.csproj | 4 - .../RuntimeInformation/OSPlatform.cs | 28 +- .../RuntimeInformation.Browser.cs | 2 - .../RuntimeInformation.PlatformVersion.cs | 131 --------- .../RuntimeInformation.Unix.cs | 9 - .../RuntimeInformation.Windows.cs | 2 - .../RuntimeInformation/RuntimeInformation.cs | 2 +- .../tests/CheckPlatformTests.cs | 8 - .../tests/PlatformVersionTests.cs | 259 ------------------ ...opServices.RuntimeInformation.Tests.csproj | 1 - 14 files changed, 10 insertions(+), 462 deletions(-) delete mode 100644 src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.PlatformVersion.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/PlatformVersionTests.cs diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs index c754fcb8daaf..86cc494976bb 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs @@ -14,7 +14,7 @@ public abstract partial class MemoryMappedFilesTestBase : FileCleanupTestBase /// Gets the system's page size. protected static Lazy s_pageSize = new Lazy(() => { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Browser)) + if (OperatingSystem.IsBrowser()) return Environment.SystemPageSize; int pageSize; diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index 136e7a928175..9b6574036d61 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -127,7 +127,7 @@ public void OSVersion_Idempotent() public void OSVersion_MatchesPlatform() { PlatformID id = Environment.OSVersion.Platform; - PlatformID expected = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PlatformID.Win32NT : RuntimeInformation.IsOSPlatform(OSPlatform.Browser) ? PlatformID.Other : PlatformID.Unix; + PlatformID expected = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PlatformID.Win32NT : OperatingSystem.IsBrowser() ? PlatformID.Other : PlatformID.Unix; Assert.Equal(expected, id); } @@ -142,7 +142,7 @@ public void OSVersion_ValidVersion() Assert.Contains(version.ToString(2), versionString); - string expectedOS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Windows " : RuntimeInformation.IsOSPlatform(OSPlatform.Browser) ? "Other " : "Unix "; + string expectedOS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Windows " : OperatingSystem.IsBrowser() ? "Other " : "Unix "; Assert.Contains(expectedOS, versionString); } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs index 59b347af089b..eb1abb41102b 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs @@ -18,16 +18,9 @@ public enum Architecture { private readonly object _dummy; private readonly int _dummyPrimitive; - public static System.Runtime.InteropServices.OSPlatform Android { get { throw null; } } - public static System.Runtime.InteropServices.OSPlatform Browser { get { throw null; } } public static System.Runtime.InteropServices.OSPlatform FreeBSD { get { throw null; } } - public static System.Runtime.InteropServices.OSPlatform iOS { get { throw null; } } public static System.Runtime.InteropServices.OSPlatform Linux { get { throw null; } } - public static System.Runtime.InteropServices.OSPlatform macOS { get { throw null; } } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public static System.Runtime.InteropServices.OSPlatform OSX { get { throw null; } } - public static System.Runtime.InteropServices.OSPlatform tvOS { get { throw null; } } - public static System.Runtime.InteropServices.OSPlatform watchOS { get { throw null; } } public static System.Runtime.InteropServices.OSPlatform Windows { get { throw null; } } public static System.Runtime.InteropServices.OSPlatform Create(string osPlatform) { throw null; } public override bool Equals(object? obj) { throw null; } @@ -45,15 +38,5 @@ public static partial class RuntimeInformation public static System.Runtime.InteropServices.Architecture ProcessArchitecture { get { throw null; } } public static string RuntimeIdentifier { get { throw null; } } public static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform osPlatform) { throw null; } - public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; } - public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; } - public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; } - public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; } - public static bool IsOSPlatformEarlierThan(string platformName) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; } - public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; } - public static bool IsOSPlatformOrLater(string platformName) { throw null; } } } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/Resources/Strings.resx index c7f9079719cc..e554cfe1fe2e 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/Resources/Strings.resx @@ -60,9 +60,6 @@ Value cannot be empty. - - "{0}" is not a valid platform name. It must contain both name and version (with at least major and minor number specified). Example: "ios14.0". - RuntimeInformation is not supported for Portable Class Libraries. diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj index 02fa495e1397..12aab18e3e97 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj @@ -7,7 +7,6 @@ - @@ -16,8 +15,6 @@ - - diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/OSPlatform.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/OSPlatform.cs index 18e45643d216..91dcbad86e17 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/OSPlatform.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/OSPlatform.cs @@ -5,38 +5,22 @@ namespace System.Runtime.InteropServices { public readonly struct OSPlatform : IEquatable { - private readonly string _osPlatform; - - public static OSPlatform Android { get; } = new OSPlatform("ANDROID"); - - public static OSPlatform Browser { get; } = new OSPlatform("BROWSER"); - public static OSPlatform FreeBSD { get; } = new OSPlatform("FREEBSD"); public static OSPlatform Linux { get; } = new OSPlatform("LINUX"); - public static OSPlatform macOS { get; } = new OSPlatform("MACOS"); - - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] // superseded by macOS public static OSPlatform OSX { get; } = new OSPlatform("OSX"); - public static OSPlatform iOS { get; } = new OSPlatform("IOS"); - - public static OSPlatform tvOS { get; } = new OSPlatform("TVOS"); - - public static OSPlatform watchOS { get; } = new OSPlatform("WATCHOS"); - public static OSPlatform Windows { get; } = new OSPlatform("WINDOWS"); - internal bool IsCurrent { get; } // this information is cached because it's frequently used + internal string Name { get; } private OSPlatform(string osPlatform) { if (osPlatform == null) throw new ArgumentNullException(nameof(osPlatform)); if (osPlatform.Length == 0) throw new ArgumentException(SR.Argument_EmptyValue, nameof(osPlatform)); - _osPlatform = osPlatform; - IsCurrent = RuntimeInformation.IsCurrentOSPlatform(osPlatform); + Name = osPlatform; } /// @@ -50,12 +34,12 @@ public static OSPlatform Create(string osPlatform) public bool Equals(OSPlatform other) { - return Equals(other._osPlatform); + return Equals(other.Name); } internal bool Equals(string? other) { - return string.Equals(_osPlatform, other, StringComparison.OrdinalIgnoreCase); + return string.Equals(Name, other, StringComparison.OrdinalIgnoreCase); } public override bool Equals(object? obj) @@ -65,12 +49,12 @@ public override bool Equals(object? obj) public override int GetHashCode() { - return _osPlatform == null ? 0 : _osPlatform.GetHashCode(StringComparison.OrdinalIgnoreCase); + return Name == null ? 0 : Name.GetHashCode(StringComparison.OrdinalIgnoreCase); } public override string ToString() { - return _osPlatform ?? string.Empty; + return Name ?? string.Empty; } public static bool operator ==(OSPlatform left, OSPlatform right) diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Browser.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Browser.cs index 838aa49c2e76..c702ef839bce 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Browser.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Browser.cs @@ -5,8 +5,6 @@ namespace System.Runtime.InteropServices { public static partial class RuntimeInformation { - internal static bool IsCurrentOSPlatform(string osPlatform) => osPlatform.Equals("BROWSER", StringComparison.OrdinalIgnoreCase); - public static string OSDescription => "Browser"; public static Architecture OSArchitecture => Architecture.Wasm; diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.PlatformVersion.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.PlatformVersion.cs deleted file mode 100644 index 0eec21939bfa..000000000000 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.PlatformVersion.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices -{ - public static partial class RuntimeInformation - { - /// - /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. - /// - /// OS name concatenated with a version number. - /// The version number must contain at least major and minor numbers separated with a dot. - /// Example: "ios14.0" is OK, "ios14" is NOT OK. - public static bool IsOSPlatformOrLater(string platformName) - { - (OSPlatform platform, Version version) = Parse(platformName); - - return IsOSPlatformOrLater(platform, version.Major, version.Minor, version.Build, version.Revision); - } - - /// - /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. - /// - public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major) - => IsOSPlatform(osPlatform) && Environment.OSVersion.Version.Major >= major; - - /// - /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. - /// - public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor) - => IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, int.MinValue, int.MinValue); - - /// - /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. - /// - public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor, int build) - => IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, build, int.MinValue); - - /// - /// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release. - /// - public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor, int build, int revision) - => IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, build, revision); - - /// - /// Check for the OS with a < version comparison. Used to guard APIs that were obsoleted or removed in the given OS release. - /// - /// OS name concatenated with a version number. - /// The version number must contain at least major and minor numbers separated with a dot. - /// Example: "ios14.0" is OK, "ios14" is NOT OK. - public static bool IsOSPlatformEarlierThan(string platformName) - { - (OSPlatform platform, Version version) = Parse(platformName); - - return IsOSPlatformEarlierThan(platform, version.Major, version.Minor, version.Build, version.Revision); - } - - /// - /// Check for the OS with a < version comparison. Used to guard APIs that were obsoleted or removed in the given OS release. - /// - public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major) - => IsOSPlatform(osPlatform) && Environment.OSVersion.Version.Major < major; - - /// - /// Check for the OS with a < version comparison. Used to guard APIs that were obsoleted or removed in the given OS release. - /// - public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor) - => IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, int.MinValue, int.MinValue); - - /// - /// Check for the OS with a < version comparison. Used to guard APIs that were obsoleted or removed in the given OS release. - /// - public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor, int build) - => IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, build, int.MinValue); - - /// - /// Check for the OS with a < version comparison. Used to guard APIs that were obsoleted or removed in the given OS release. - /// - public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor, int build, int revision) - => IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, build, revision); - - private static bool IsOSVersionOrLater(int major, int minor, int build, int revision) - { - Version current = Environment.OSVersion.Version; - if (current.Major != major) - { - return current.Major > major; - } - if (current.Minor != minor) - { - return current.Minor > minor; - } - if (current.Build != build) - { - return current.Build > build; - } - - return current.Revision >= revision; - } - - private static (OSPlatform, Version) Parse(string platformName) - { - if (platformName == null) - { - throw new ArgumentNullException(nameof(platformName)); - } - if (platformName.Length == 0) - { - throw new ArgumentException(SR.Argument_EmptyValue, nameof(platformName)); - } - - // iterate from the begining, as digits in the middle of the names are not supported by design - for (int i = 0; i < platformName.Length; i++) - { - if (char.IsDigit(platformName[i])) - { - if (i > 0 && Version.TryParse(platformName.AsSpan(i), out Version? version)) - { - return (OSPlatform.Create(platformName.Substring(0, i)), version); - } - else - { - break; - } - } - } - - throw new ArgumentException(SR.Format(SR.Argument_InvalidPlatfromName, platformName), nameof(platformName)); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs index 232c7fc8aa55..0a8147db34af 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs @@ -7,17 +7,8 @@ namespace System.Runtime.InteropServices { public static partial class RuntimeInformation { - private static string? s_osPlatformName; private static string? s_osDescription; - internal static bool IsCurrentOSPlatform(string osPlatform) - { - string name = s_osPlatformName ??= Interop.Sys.GetUnixName(); - - return osPlatform.Equals(name, StringComparison.OrdinalIgnoreCase) - || (name == "OSX" && osPlatform.Equals("MACOS", StringComparison.OrdinalIgnoreCase)); // GetUnixName returns OSX on macOS - } - public static string OSDescription => s_osDescription ??= Interop.Sys.GetUnixVersion(); public static Architecture OSArchitecture { get; } = Map((Interop.Sys.ProcessorArchitecture)Interop.Sys.GetOSArchitecture()); diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Windows.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Windows.cs index 668b84391b76..0177eec2317c 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Windows.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Windows.cs @@ -11,8 +11,6 @@ public static partial class RuntimeInformation private static volatile int s_osArch = -1; private static volatile int s_processArch = -1; - internal static bool IsCurrentOSPlatform(string osPlatform) => osPlatform.Equals("WINDOWS", StringComparison.OrdinalIgnoreCase); - public static string OSDescription { get diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs index 95b1b62b4cdb..df0fb53273d4 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs @@ -52,6 +52,6 @@ public static string FrameworkDescription /// /// Indicates whether the current application is running on the specified platform. /// - public static bool IsOSPlatform(OSPlatform osPlatform) => osPlatform.IsCurrent; + public static bool IsOSPlatform(OSPlatform osPlatform) => OperatingSystem.IsOSPlatform(osPlatform.Name); } } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckPlatformTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckPlatformTests.cs index e40f9f8b310a..76ea344cff31 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckPlatformTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckPlatformTests.cs @@ -51,10 +51,6 @@ public void CheckOSX() Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("OSX"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx"))); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.macOS)); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACOS"))); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("macOS"))); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("macos"))); Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"))); Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD"))); @@ -71,7 +67,6 @@ public void CheckOSX() [Fact, PlatformSpecific(TestPlatforms.iOS)] // Tests RuntimeInformation OS platform public void CheckiOS() { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.iOS)); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("iOS"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios"))); @@ -92,7 +87,6 @@ public void CheckiOS() [Fact, PlatformSpecific(TestPlatforms.tvOS)] // Tests RuntimeInformation OS platform public void ChecktvOS() { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS)); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("tvOS"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("tvos"))); @@ -113,7 +107,6 @@ public void ChecktvOS() [Fact, PlatformSpecific(TestPlatforms.Android)] // Tests RuntimeInformation OS platform public void CheckAndroid() { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Android)); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("android"))); @@ -133,7 +126,6 @@ public void CheckAndroid() [Fact, PlatformSpecific(TestPlatforms.Browser)] // Tests RuntimeInformation OS platform public void CheckBrowser() { - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Browser)); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("browser"))); diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/PlatformVersionTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/PlatformVersionTests.cs deleted file mode 100644 index b612d2e065bc..000000000000 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/PlatformVersionTests.cs +++ /dev/null @@ -1,259 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.RuntimeInformationTests -{ - public class PlatformVersionTests - { - public static IEnumerable AllKnownOsPlatforms() - { - yield return new object[] { OSPlatform.Windows }; - yield return new object[] { OSPlatform.Linux }; - yield return new object[] { OSPlatform.OSX }; - yield return new object[] { OSPlatform.Browser }; - yield return new object[] { OSPlatform.macOS }; - yield return new object[] { OSPlatform.iOS }; - yield return new object[] { OSPlatform.tvOS }; - yield return new object[] { OSPlatform.watchOS }; - yield return new object[] { OSPlatform.Android }; - } - - [Fact] - public void IsOSPlatformOrLater_Null_ThrowsArgumentNullExceptionWithArgumentName() - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformOrLater(null)); - } - - [Fact] - public void IsOSPlatformOrLater_Empty_ThrowsArgumentNullExceptionWithArgumentName() - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformOrLater(string.Empty)); - } - - [Theory] - [InlineData("ios")] // missing version number - [InlineData("ios14")] // ios14.0 is fine, ios14 is not: https://github.com/dotnet/runtime/pull/39005#discussion_r452541491 - [InlineData("ios14.0.0.0.0.0")] // too many numbers - [InlineData("ios14.0.")] // version should not end with dot (but OS name could potentially end with dot, imagine "NET.") - [InlineData("numbers1.2inplatformname1.2")] // numbers in platform names are not supported https://github.com/dotnet/runtime/pull/39005#discussion_r452644601 - public void IsOSPlatformOrLater_InvalidVersionNumber_ThrowsArgumentExceptionWithArgumentName(string platformName) - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformOrLater(platformName)); - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformOrLater_ReturnsTrue_ForCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformOrLater("xyz1.2.3.4") running as "xyz1.2.3.4" should return true - - bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform); - Version current = Environment.OSVersion.Version; - - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{current}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{current}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{current}")); - - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major)); - - if (current.Minor >= 0) - { - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor)); - - if (current.Build >= 0) - { - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor, current.Build)); - - if (current.Revision >= 0) - { - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor, current.Build, current.Revision)); - } - } - } - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformOrLater_ReturnsFalse_ForNewerVersionOfCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformOrLater("xyz11.0") running as "xyz10.0" should return false - - Version currentVersion = Environment.OSVersion.Version; - - Version newer = new Version(currentVersion.Major + 1, 0); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major)); - - newer = new Version(currentVersion.Major, currentVersion.Minor + 1); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor)); - - newer = new Version(currentVersion.Major, currentVersion.Minor, currentVersion.Build + 1); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor, newer.Build)); - - newer = new Version(currentVersion.Major, currentVersion.Minor, currentVersion.Build, currentVersion.Revision + 1); - Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}")); - Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor, newer.Build, newer.Revision)); - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformOrLater_ReturnsTrue_ForOlderVersionOfCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformOrLater("xyz10.0") running as "xyz11.0" should return true - - bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform); - Version current = Environment.OSVersion.Version; - - Version older = new Version(current.Major - 1, 0); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major)); - - if (current.Minor > 0) - { - older = new Version(current.Major, current.Minor - 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor)); - } - - if (current.Build > 0) - { - older = new Version(current.Major, current.Minor, current.Build - 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor, older.Build)); - } - - if (current.Revision > 0) - { - older = new Version(current.Major, current.Minor, current.Build, current.Revision - 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor, older.Build, older.Revision)); - } - } - - [Fact] - public void IsOSPlatformEarlierThan_Null_ThrowsArgumentNullExceptionWithArgumentName() - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(null)); - } - - [Fact] - public void IsOSPlatformEarlierThan_Empty_ThrowsArgumentNullExceptionWithArgumentName() - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(string.Empty)); - } - - [Theory] - [InlineData("ios")] // missing version number - [InlineData("ios14")] // ios14.0 is fine, ios14 is not: https://github.com/dotnet/runtime/pull/39005#discussion_r452541491 - [InlineData("ios14.0.0.0.0.0")] // too many numbers - [InlineData("ios14.0.")] // version should not end with dot (but OS name could potentially end with dot, imagine "NET.") - [InlineData("numbers1.2inplatformname1.2")] // numbers in platform names are not supported https://github.com/dotnet/runtime/pull/39005#discussion_r452644601 - public void IsOSPlatformEarlierThan_InvalidVersionNumber_ThrowsArgumentExceptionWithArgumentName(string platformName) - { - Assert.Throws("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(platformName)); - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformEarlierThan_ReturnsFalse_ForCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformEarlierThan("xyz1.2.3.4") running as "xyz1.2.3.4" should return false - - Version current = Environment.OSVersion.Version; - - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{current}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{current}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{current}")); - - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major)); - - if (current.Minor >= 0) - { - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor)); - - if (current.Build >= 0) - { - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor, current.Build)); - - if (current.Revision >= 0) - { - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor, current.Build, current.Revision)); - } - } - } - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformEarlierThan_ReturnsTrue_ForNewerVersionOfCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformEarlierThan("xyz11.0") running as "xyz10.0" should return true - - bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform); - Version current = Environment.OSVersion.Version; - - Version newer = new Version(current.Major + 1, 0); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major)); - - newer = new Version(current.Major, current.Minor + 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor)); - - newer = new Version(current.Major, current.Minor, current.Build + 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor, newer.Build)); - - newer = new Version(current.Major, current.Minor, current.Build, current.Revision + 1); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}")); - Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor, newer.Build, newer.Revision)); - } - - [Theory] - [MemberData(nameof(AllKnownOsPlatforms))] - public void IsOSPlatformEarlierThan_ReturnsFalse_ForOlderVersionOfCurrentOS(OSPlatform osPlatform) - { - // IsOSPlatformEarlierThan("xyz10.0") running as "xyz11.0" should return false - - Version current = Environment.OSVersion.Version; - - Version older = new Version(current.Major - 1, 0); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major)); - - if (current.Minor > 0) - { - older = new Version(current.Major, current.Minor - 1); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor)); - } - - if (current.Build > 0) - { - older = new Version(current.Major, current.Minor, current.Build - 1); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor, older.Build)); - } - - if (current.Revision > 0) - { - older = new Version(current.Major, current.Minor, current.Build, current.Revision - 1); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}")); - Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor, older.Build, older.Revision)); - } - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj index e3745518d39e..de6d696e095a 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj @@ -8,7 +8,6 @@ - From 56b865af0a2e23903991d4922e9f6e3993b740e4 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 7 Aug 2020 11:52:56 +0100 Subject: [PATCH 313/755] Enable CBOR property tests in CI runs (#40135) * enable cbor property tests in CI runs * address feedback --- .../tests/PropertyTests/CborPropertyTests.cs | 8 +++---- .../tests/System.Formats.Cbor.Tests.csproj | 21 +++++-------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs index 6aca08ffc7bc..d265baec831d 100644 --- a/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs +++ b/src/libraries/System.Formats.Cbor/tests/PropertyTests/CborPropertyTests.cs @@ -12,7 +12,7 @@ namespace System.Formats.Cbor.Tests public static class CborPropertyTests { private const string? ReplaySeed = "(42,42)"; // set a seed for deterministic runs, null for randomized runs - private const int MaxTests = 10_000; + private const int MaxTests = 100; // FsCheck default is 100 [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] public static void Roundtrip_Int64(CborConformanceMode mode, long input) @@ -178,7 +178,7 @@ _ when (length < ushort.MaxValue) => 1 + sizeof(ushort), } [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] - public static void PropertyTest_Roundtrip(CborPropertyTestContext input) + public static void CborDocument_Roundtrip(CborPropertyTestContext input) { byte[] encoding = CborDocumentSerializer.encode(input); @@ -188,7 +188,7 @@ public static void PropertyTest_Roundtrip(CborPropertyTestContext input) } [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] - public static void PropertyTest_SkipValue(CborPropertyTestContext input) + public static void CborDocument_SkipValue(CborPropertyTestContext input) { int length = input.RootDocuments.Length; input.RootDocuments = new[] { CborDocument.NewArray(_isDefiniteLength: true, input.RootDocuments) }; @@ -205,7 +205,7 @@ public static void PropertyTest_SkipValue(CborPropertyTestContext input) } [Property(Replay = ReplaySeed, MaxTest = MaxTests, Arbitrary = new[] { typeof(CborRandomGenerators) })] - public static void PropertyTest_SkipToParent(CborPropertyTestContext input) + public static void CborDocument_SkipToParent(CborPropertyTestContext input) { input.RootDocuments = new[] { CborDocument.NewArray(_isDefiniteLength: true, input.RootDocuments) }; byte[] encoding = CborDocumentSerializer.encode(input); diff --git a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj index 71735ea6c7b8..c2211d72e5b1 100644 --- a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj +++ b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj @@ -1,20 +1,16 @@ - + $(NetCoreAppCurrent) enable - false - - - - $(DefineConstants),CBOR_PROPERTY_TESTS CS8002 - CommonTest\System\Security\Cryptography\ByteUtils.cs + + @@ -36,18 +32,11 @@ - - - - - - + - - - + From a0d41ec11310fe43fa2e81040e3e6a1702f18c6c Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Fri, 7 Aug 2020 16:07:56 +0300 Subject: [PATCH 314/755] [mono][interp] Optimize box+unbox to no-op (#40017) --- src/mono/mono/mini/interp/transform.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 1fd13dd4bec3..b81d5f90742c 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -4941,6 +4941,20 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, klass = mini_get_class (method, token, generic_context); CHECK_TYPELOAD (klass); + // Common in generic code: + // box T + unbox.any T -> nop + if ((td->last_ins->opcode == MINT_BOX || td->last_ins->opcode == MINT_BOX_VT) && + (td->sp - 1)->klass == klass && !td->is_bb_start[in_offset]) { + gboolean is_vt = td->last_ins->opcode == MINT_BOX_VT; + interp_clear_ins(td, td->last_ins); + if (is_vt) + PUSH_VT(td, mono_class_value_size(klass, NULL)); + int mt = mint_type(m_class_get_byval_arg(klass)); + SET_TYPE(td->sp - 1, stack_type[mt], klass); + td->ip += 5; + break; + } + if (mini_type_is_reference (m_class_get_byval_arg (klass))) { int mt = mint_type (m_class_get_byval_arg (klass)); interp_handle_isinst (td, klass, FALSE); From d575f10471929f2e2b547fb75f1080a608daa067 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 7 Aug 2020 09:30:15 -0400 Subject: [PATCH 315/755] [Wasm] Ensure monovm_initialize is called on startup and address other startup items (#39446) This PR addresses: - Calling monovm_initialize matches how other mono platforms init themselves (Fixes https://github.com/dotnet/runtime/issues/39074) - Set the entry assembly (Fixes https://github.com/dotnet/runtime/issues/38994) - Make sure the assembly location is set to empty for assemblies that are loaded from memory (Fixes https://github.com/dotnet/runtime/issues/39650) --- .../System/AssemblyPathHelper.cs | 21 ++++++++++++ .../tests/TestUtilities/TestUtilities.csproj | 1 + .../CodeDom/Compiler/CompilerResultsTests.cs | 2 +- .../System/Configuration/ClientConfigPaths.cs | 28 ++++++++++++---- .../tests/StackTraceSymbolsTests.cs | 3 +- ...System.Diagnostics.StackTrace.Tests.csproj | 4 +++ .../Decoding/CustomAttributeDecoderTests.cs | 2 +- .../Decoding/SignatureDecoderTests.cs | 8 ++--- .../TestUtils/CoreMetadataAssemblyResolver.cs | 3 ++ .../src/TestUtils/TestUtils.JittedRuntimes.cs | 23 ++++++++----- .../tests/src/TestUtils/TestUtils.cs | 7 +++- .../PathAssemblyResolver.cs | 9 +---- .../Tests/MetadataLoadContext/Scenarios.cs | 10 +++--- .../Tests/RestrictedApis/RestrictedApis.cs | 2 +- .../tests/src/Tests/Type/TypeTests.cs | 4 +-- .../tests/AssemblyNameTests.cs | 2 +- .../System.Reflection/tests/AssemblyTests.cs | 20 ++++++----- .../tests/RuntimeIdentifierTests.cs | 1 - .../tests/SatelliteAssemblies.cs | 6 ++-- .../tests/System/Reflection/ModuleTests.cs | 10 +++++- src/mono/mono/metadata/appdomain.h | 3 ++ src/mono/mono/metadata/assembly.c | 10 ++++++ src/mono/mono/metadata/domain-internals.h | 3 -- .../src/System/Reflection/RuntimeAssembly.cs | 33 +++++++------------ src/mono/wasm/runtime/driver.c | 12 +++++++ 25 files changed, 148 insertions(+), 79 deletions(-) create mode 100644 src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs diff --git a/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs b/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs new file mode 100644 index 000000000000..10b3ee0cf2e9 --- /dev/null +++ b/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; + +namespace System +{ + public static class AssemblyPathHelper + { + public static string GetAssemblyLocation(Assembly a) + { + // Note, in Browser, assemblies are loaded from memory and in that case, Assembly.Location will return an empty + // string. For these tests, the assemblies will also be available in the VFS, so just specify the assembly name + // plus extension. + return (PlatformDetection.IsNotBrowser) ? + a.Location + : "/" + a.GetName().Name + ".dll"; + } + } +} \ No newline at end of file diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index 564607865138..978aff534fa0 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -22,6 +22,7 @@ + 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 71158faaa22c..aa791baa631a 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 = (PlatformDetection.IsBrowser ? "/" : string.Empty) + typeof(CompilerResultsTests).Assembly.Location }; + var results = new CompilerResults(null) { PathToAssembly = AssemblyPathHelper.GetAssemblyLocation(typeof(CompilerResultsTests).Assembly) }; Assert.NotNull(results.CompiledAssembly); Assert.Equal(typeof(CompilerResultsTests).Assembly.FullName, results.CompiledAssembly.FullName); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs index abb97375d829..087cb3e1f7b6 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs @@ -215,22 +215,38 @@ private static string GetTypeAndHashSuffix(string exePath) AssemblyName assemblyName = assembly.GetName(); Uri codeBase = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.ManifestModule.Name)); - hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName); + try + { + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName); + } + catch (PlatformNotSupportedException) { } + if (hash != null) { typeName = StrongNameDesc; } else { - hash = IdentityHelper.GetNormalizedUriHash(codeBase); - typeName = UrlDesc; + try + { + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetNormalizedUriHash(codeBase); + typeName = UrlDesc; + } + catch (PlatformNotSupportedException) { } } } else if (!string.IsNullOrEmpty(exePath)) { - // Fall back on the exe name - hash = IdentityHelper.GetStrongHashSuitableForObjectName(exePath); - typeName = PathDesc; + try + { + // Fall back on the exe name + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetStrongHashSuitableForObjectName(exePath); + typeName = PathDesc; + } + catch (PlatformNotSupportedException) { } } if (!string.IsNullOrEmpty(hash)) suffix = "_" + typeName + "_" + hash; diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs index 8026935ba5a9..47eb6f07b700 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs @@ -7,13 +7,12 @@ namespace System.Diagnostics.SymbolStore.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39650", TestPlatforms.Browser)] public class StackTraceSymbolsTests { [Fact] public void StackTraceSymbolsDoNotLockFile() { - var asmPath = typeof(StackTraceSymbolsTests).Assembly.Location; + var asmPath = AssemblyPathHelper.GetAssemblyLocation(typeof(StackTraceSymbolsTests).Assembly); var pdbPath = Path.ChangeExtension(asmPath, ".pdb"); Assert.True(File.Exists(pdbPath)); diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj index 0290d8432c8f..b112648c1836 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj +++ b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj @@ -13,4 +13,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs index 9899c0995f7f..6a14d358a08c 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs @@ -15,7 +15,7 @@ public class CustomAttributeDecoderTests [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Type assembly name is different on .NET Framework.")] public void TestCustomAttributeDecoder() { - using (FileStream stream = File.OpenRead(typeof(HasAttributes).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(HasAttributes).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs index 9a83882ff9f1..7669fbcc2ef3 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs @@ -83,7 +83,7 @@ public unsafe void DecodeInvalidMethodSpecificationSignature(byte[] testSignatur [Fact] public void DecodeVarArgsDefAndRef() { - using (FileStream stream = File.OpenRead(typeof(VarArgsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader metadataReader = peReader.GetMetadataReader(); @@ -135,7 +135,7 @@ public static void VarArgsCaller() [Fact] public void SimpleSignatureProviderCoverage() { - using (FileStream stream = File.OpenRead(typeof(SignaturesToDecode<>).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(SignaturesToDecode<>).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); @@ -246,7 +246,7 @@ public event EventHandler Event { add { } remove { } } [Fact] public void PinnedAndUnpinnedLocals() { - using (FileStream stream = File.OpenRead(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); @@ -285,7 +285,7 @@ public static unsafe int DoSomething() [Fact] public void WrongSignatureType() { - using (FileStream stream = File.OpenRead(typeof(VarArgsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs index f5a81d7e4535..70c98068cdd2 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs @@ -1,5 +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; namespace System.Reflection.Tests { @@ -22,7 +23,9 @@ public override Assembly Resolve(MetadataLoadContext context, AssemblyName assem name.Equals("System.Runtime.InteropServices", StringComparison.OrdinalIgnoreCase)) { if (_coreAssembly == null) + { _coreAssembly = context.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); + } return _coreAssembly; } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs index aa98d6ee9390..cdbd7d4f6ec1 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs @@ -18,7 +18,7 @@ public static Type Project(this Type type) Assembly assembly = type.Assembly; string location = assembly.Location; - if (location == null || location == string.Empty) + if (PlatformDetection.IsNotBrowser && (location == null || location == string.Empty)) { throw new Exception("Could not find the IL for assembly " + type.Assembly + " on disk. The most likely cause " + "is that you built the tests for a Jitted runtime but are running them on an AoT runtime."); @@ -30,9 +30,11 @@ public static Type Project(this Type type) // The core assembly we're using might not be the one powering the runtime. Make sure we project to the core assembly the MetataLoadContext // is using. if (a == typeof(object).Assembly) - return TestMetadataLoadContext.LoadFromStream(CreateStreamForCoreAssembly()); + { + TestMetadataLoadContext.LoadFromStream(CreateStreamForCoreAssembly()); + } - return TestMetadataLoadContext.LoadFromAssemblyPath(a.Location); + return TestMetadataLoadContext.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(a)); }); Type projectedType = s_typeDict.GetOrAdd(type, (t) => projectedAssembly.GetType(t.FullName, throwOnError: true, ignoreCase: false)); @@ -50,12 +52,15 @@ public static Stream CreateStreamForCoreAssembly() { // We need a core assembly in IL form. Since this version of this code is for Jitted platforms, the System.Private.Corelib // of the underlying runtime will do just fine. - string assumedLocationOfCoreLibrary = typeof(object).Assembly.Location; - if (assumedLocationOfCoreLibrary == null || assumedLocationOfCoreLibrary == string.Empty) + if (PlatformDetection.IsNotBrowser) { - throw new Exception("Could not find a core assembly to use for tests as 'typeof(object).Assembly.Location` returned " + - "a null or empty value. The most likely cause is that you built the tests for a Jitted runtime but are running them " + - "on an AoT runtime."); + string assumedLocationOfCoreLibrary = typeof(object).Assembly.Location; + if (assumedLocationOfCoreLibrary == null || assumedLocationOfCoreLibrary == string.Empty) + { + throw new Exception("Could not find a core assembly to use for tests as 'typeof(object).Assembly.Location` returned " + + "a null or empty value. The most likely cause is that you built the tests for a Jitted runtime but are running them " + + "on an AoT runtime."); + } } return File.OpenRead(GetPathToCoreAssembly()); @@ -63,7 +68,7 @@ public static Stream CreateStreamForCoreAssembly() public static string GetPathToCoreAssembly() { - return typeof(object).Assembly.Location; + return AssemblyPathHelper.GetAssemblyLocation(typeof(object).Assembly); } public static string GetNameOfCoreAssembly() diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs index c0a4192c3fb2..ac71eddcbaa2 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs @@ -253,7 +253,12 @@ public static void Dump(this CustomAttributeTypedArgument cta, int indent = 0) private static readonly Lazy s_useRuntimeTypesForTests = new Lazy(() => { - if (File.Exists(Path.Combine(Path.GetDirectoryName(typeof(TestUtils).Assembly.Location), "UseRuntimeTypes.txt"))) + if (PlatformDetection.IsBrowser) + return false; + + var loc = AssemblyPathHelper.GetAssemblyLocation(typeof(TestUtils).Assembly); + + if (File.Exists(Path.Combine(loc, "UseRuntimeTypes.txt"))) { // Disable projection so that are Reflection tests run against the runtime types. This is used primarily to verify // the *test* code for correctness. diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs index 501e40c72ecb..464a92559809 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs @@ -60,14 +60,7 @@ public static void PathAssemblyResolverBasicPathWithRunningAssemblies() string coreAssemblyPath = TestUtils.GetPathToCoreAssembly(); // Obtain this test class - string thisAssemblyPath = typeof(MetadataLoadContextTests).Assembly.Location; - - if (PlatformDetection.IsBrowser) - { - // prepends slash as Assembly.Location only contains the file name on browser (https://github.com/dotnet/runtime/issues/39650) - thisAssemblyPath = "/" + thisAssemblyPath; - } - + string thisAssemblyPath = AssemblyPathHelper.GetAssemblyLocation(typeof(MetadataLoadContextTests).Assembly); var resolver = new PathAssemblyResolver(new string[] { coreAssemblyPath, thisAssemblyPath }); using (MetadataLoadContext lc = new MetadataLoadContext(resolver, TestUtils.GetNameOfCoreAssembly())) { diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs index b51651c44273..86561ccad103 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs @@ -16,7 +16,7 @@ public static void Scenario_GetAssemblyName() // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); AssemblyName assemblyName = a.GetName(); Console.WriteLine(assemblyName.FullName); } @@ -28,7 +28,7 @@ public static void Scenario_EnumerateDependencies() // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); foreach (AssemblyName name in a.GetReferencedAssemblies()) { Console.WriteLine(name.FullName); @@ -44,8 +44,8 @@ public static void Scenario_FindACoreAssembly() { Assembly[] candidates = { - lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location), - lc.LoadFromAssemblyPath(typeof(object).Assembly.Location), + lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)), + lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(object).Assembly)), }; foreach (Assembly candidate in candidates) @@ -68,7 +68,7 @@ public static void Scenario_EnumerateTypesAndMembers() // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); foreach (TypeInfo t in a.DefinedTypes) { Console.WriteLine(t.FullName); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs index f154f0987723..28aea79bee9b 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs @@ -12,7 +12,7 @@ public static void TestRestrictions() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(TopLevelType).Assembly)); #pragma warning disable SYSLIB0012 Assert.Throws(() => a.CodeBase); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index 60617d2b4b32..d14c4b849f0a 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -523,7 +523,7 @@ public static void CoreGetTypeCacheCoverage2() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(SampleMetadata.NS0.SameNamedType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(SampleMetadata.NS0.SameNamedType).Assembly)); // Create big hash collisions in GetTypeCoreCache. for (int i = 0; i < 16; i++) { @@ -542,7 +542,7 @@ public static void CoreGetTypeCacheCoverage3() using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { // Make sure the tricky corner case of a null/empty namespace is covered. - Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(TopLevelType).Assembly)); Type t = a.GetType("TopLevelType", throwOnError: true, ignoreCase: false); Assert.Null(t.Namespace); Assert.Equal("TopLevelType", t.Name); diff --git a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs index d33e010aa02a..e64b887f5a3c 100644 --- a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs @@ -240,7 +240,7 @@ public static void GetAssemblyName() } Assembly a = typeof(AssemblyNameTests).Assembly; - Assert.Equal(new AssemblyName(a.FullName).ToString(), AssemblyName.GetAssemblyName(a.Location).ToString()); + Assert.Equal(new AssemblyName(a.FullName).ToString(), AssemblyName.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a)).ToString()); } [Fact] diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index 8f7384f685f6..e1b60d5eacc5 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -158,8 +158,9 @@ 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")); - 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); + + string name = AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly); + Assert.Equal(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll").Name, name); } [Fact] @@ -167,8 +168,9 @@ public void GetFiles() { Assert.NotNull(typeof(AssemblyTests).Assembly.GetFiles()); Assert.Equal(1, typeof(AssemblyTests).Assembly.GetFiles().Length); - if (PlatformDetection.IsNotBrowser) // see https://github.com/dotnet/runtime/issues/39650 - Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, typeof(AssemblyTests).Assembly.Location); + + string name = AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly); + Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, name); } public static IEnumerable GetHashCode_TestData() @@ -387,7 +389,7 @@ public void LoadFrom_SamePath_ReturnsEqualAssemblies() [Fact] public void LoadFrom_SameIdentityAsAssemblyWithDifferentPath_ReturnsEqualAssemblies() { - Assembly assembly1 = Assembly.LoadFrom(typeof(AssemblyTests).Assembly.Location); + Assembly assembly1 = Assembly.LoadFrom(AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly)); Assert.Equal(assembly1, typeof(AssemblyTests).Assembly); Assembly assembly2 = Assembly.LoadFrom(LoadFromTestPath); @@ -659,7 +661,7 @@ public void AssemblyLoadFromStringNeg() public void AssemblyLoadFromBytes() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); Assembly loadedAssembly = Assembly.Load(aBytes); Assert.NotNull(loadedAssembly); @@ -677,8 +679,8 @@ public void AssemblyLoadFromBytesNeg() public void AssemblyLoadFromBytesWithSymbols() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); - byte[] symbols = System.IO.File.ReadAllBytes((System.IO.Path.ChangeExtension(assembly.Location, ".pdb"))); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); + byte[] symbols = System.IO.File.ReadAllBytes((System.IO.Path.ChangeExtension(AssemblyPathHelper.GetAssemblyLocation(assembly), ".pdb"))); Assembly loadedAssembly = Assembly.Load(aBytes, symbols); Assert.NotNull(loadedAssembly); @@ -696,7 +698,7 @@ public void AssemblyReflectionOnlyLoadFromString() public void AssemblyReflectionOnlyLoadFromBytes() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); Assert.Throws(() => Assembly.ReflectionOnlyLoad(aBytes)); } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs index 6747714a6279..d25b747b15fb 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs @@ -11,7 +11,6 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests public class RuntimeIdentifierTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39074", TestPlatforms.Browser)] public void VerifyOSRid() { Assert.NotNull(RuntimeInformation.RuntimeIdentifier); diff --git a/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs b/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs index 658d1f42a128..7851469527bc 100644 --- a/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs +++ b/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs @@ -18,15 +18,15 @@ public class SatelliteAssembliesTestsFixture public SatelliteAssembliesTestsFixture() { AssemblyLoadContext satelliteAssembliesTests = new AssemblyLoadContext("SatelliteAssembliesTests"); - var satelliteAssembliesTestsPath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(SatelliteAssembliesTests).Assembly.Location; + var satelliteAssembliesTestsPath = AssemblyPathHelper.GetAssemblyLocation(typeof(SatelliteAssembliesTests).Assembly); satelliteAssembliesTests.LoadFromAssemblyPath(satelliteAssembliesTestsPath); AssemblyLoadContext referencedClassLib = new AssemblyLoadContext("ReferencedClassLib"); - var referencedClassLibPath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(ReferencedClassLib.Program).Assembly.Location; + var referencedClassLibPath = AssemblyPathHelper.GetAssemblyLocation(typeof(ReferencedClassLib.Program).Assembly); referencedClassLib.LoadFromAssemblyPath(referencedClassLibPath); AssemblyLoadContext referencedClassLibNeutralIsSatellite = new AssemblyLoadContext("ReferencedClassLibNeutralIsSatellite"); - var referencedClassLibNeutralIsSatellitePath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(ReferencedClassLibNeutralIsSatellite.Program).Assembly.Location; + var referencedClassLibNeutralIsSatellitePath = AssemblyPathHelper.GetAssemblyLocation(typeof(ReferencedClassLibNeutralIsSatellite.Program).Assembly); referencedClassLibNeutralIsSatellite.LoadFromAssemblyPath(referencedClassLibNeutralIsSatellitePath); new AssemblyLoadContext("Empty"); diff --git a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs index 8f16d1d6e204..b5494718b7be 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs @@ -81,7 +81,15 @@ public void CustomAttributes() [Fact] public void FullyQualifiedName() { - Assert.Equal(Assembly.GetExecutingAssembly().Location, Module.FullyQualifiedName); + var loc = AssemblyPathHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()); + + // Browser will include the path (/), so strip it + if (PlatformDetection.IsBrowser && loc.Length > 1) + { + loc = loc.Substring(1); + } + + Assert.Equal(loc, Module.FullyQualifiedName); } [Fact] diff --git a/src/mono/mono/metadata/appdomain.h b/src/mono/mono/metadata/appdomain.h index ab260646e900..bc8a1f2de199 100644 --- a/src/mono/mono/metadata/appdomain.h +++ b/src/mono/mono/metadata/appdomain.h @@ -106,6 +106,9 @@ mono_domain_foreach (MonoDomainFunc func, void* user_data); MONO_API MONO_RT_EXTERNAL_ONLY MonoAssembly * mono_domain_assembly_open (MonoDomain *domain, const char *name); +MONO_API void +mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly); + MONO_API mono_bool mono_domain_finalize (MonoDomain *domain, uint32_t timeout); diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index d4ea7f7e53c0..d9a9e7f8c3b5 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -2501,6 +2501,16 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena for (i = 0; !image && bundles [i]; ++i) { if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) { image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name); +#if defined(TARGET_WASM) && defined(ENABLE_NETCORE) + /* + * Since bundled images do not exist on disk, don't give them a legit file name. + * This is the expected behavior for single file exe's. + */ + if (image->filename) + g_free (image->filename); + + image->filename = NULL; +#endif break; } } diff --git a/src/mono/mono/metadata/domain-internals.h b/src/mono/mono/metadata/domain-internals.h index 2acdd85d20d4..0985b671df7f 100644 --- a/src/mono/mono/metadata/domain-internals.h +++ b/src/mono/mono/metadata/domain-internals.h @@ -692,9 +692,6 @@ mono_runtime_install_appctx_properties (void); gboolean mono_domain_set_fast (MonoDomain *domain, gboolean force); -void -mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly); - MonoAssemblyLoadContext * mono_domain_default_alc (MonoDomain *domain); 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 7154236a265e..2c7616bf5955 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 @@ -415,38 +415,29 @@ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version? vers if (name.Length == 0) throw new ArgumentException(SR.Argument_EmptyFileName); - string location = Location; - if (location != null && Path.GetFileName(location) == name) - return new FileStream(location, FileMode.Open, FileAccess.Read); - string filename = (string)GetFilesInternal(name, true); - if (filename != null) - return new FileStream(filename, FileMode.Open, FileAccess.Read); + RuntimeModule? m = (RuntimeModule?)GetModule(name); + + if (m != null) + return new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read); else return null; } public override FileStream[] GetFiles(bool getResourceModules) { - string[] names = (string[])GetFilesInternal(null, getResourceModules); - if (names == null) + Module[] modules = GetModules(getResourceModules); + + if (modules.Length == 0) return Array.Empty(); - string location = Location; + FileStream[] res = new FileStream[modules.Length]; - FileStream[] res; - if (location != string.Empty) - { - res = new FileStream[names.Length + 1]; - res[0] = new FileStream(location, FileMode.Open, FileAccess.Read); - for (int i = 0; i < names.Length; ++i) - res[i + 1] = new FileStream(names[i], FileMode.Open, FileAccess.Read); - } - else + for (int i = 0; i < modules.Length; i++) { - res = new FileStream[names.Length]; - for (int i = 0; i < names.Length; ++i) - res[i] = new FileStream(names[i], FileMode.Open, FileAccess.Read); + RuntimeModule m = (RuntimeModule)modules[i]; + res[i] = new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read); } + return res; } diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 8e68329cb6d0..2d4498c8955a 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -375,6 +375,16 @@ mono_wasm_load_runtime (const char *unused, int debug_level) monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); #endif + const char *appctx_keys[2]; + appctx_keys [0] = "APP_CONTEXT_BASE_DIRECTORY"; + appctx_keys [1] = "RUNTIME_IDENTIFIER"; + + const char *appctx_values[2]; + appctx_values [0] = "/"; + appctx_values [1] = "browser-wasm"; + + monovm_initialize (2, appctx_keys, appctx_values); + mini_parse_debug_option ("top-runtime-invoke-unhandled"); mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL); @@ -514,6 +524,8 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) uint32_t entry = mono_image_get_entry_point (image); if (!entry) return NULL; + + mono_domain_ensure_entry_assembly (root_domain, assembly); return mono_get_method (image, entry, NULL); } From 5620160d496fb7e50691259f5b964de64a67cbdb Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 7 Aug 2020 09:45:17 -0400 Subject: [PATCH 316/755] [Wasm] Rename System.Runtime.InteropServices.JavaScript to System.Private.Runtime.InteropServices.JavaScript (#40478) Fixes https://github.com/dotnet/runtime/issues/39042 --- src/libraries/NetCoreAppLibrary.props | 2 +- .../src/System.Net.Http.csproj | 3 +- .../src/System.Net.WebSockets.Client.csproj | 4 +- .../Directory.Build.props | 0 ...te.Runtime.InteropServices.JavaScript.sln} | 4 +- .../src/ILLinkTrim.xml | 2 +- .../src/Resources/Strings.resx | 2 +- ...Runtime.InteropServices.JavaScript.csproj} | 5 +- .../InteropServices/JavaScript/AnyRef.cs | 0 .../InteropServices/JavaScript/Array.cs | 0 .../InteropServices/JavaScript/ArrayBuffer.cs | 0 .../InteropServices/JavaScript/CoreObject.cs | 0 .../InteropServices/JavaScript/DataView.cs | 0 .../JavaScript/Float32Array.cs | 0 .../JavaScript/Float64Array.cs | 0 .../InteropServices/JavaScript/Function.cs | 0 .../InteropServices/JavaScript/HostObject.cs | 0 .../InteropServices/JavaScript/Int16Array.cs | 0 .../InteropServices/JavaScript/Int32Array.cs | 0 .../InteropServices/JavaScript/Int8Array.cs | 0 .../InteropServices/JavaScript/JSException.cs | 0 .../InteropServices/JavaScript/JSObject.cs | 0 .../Runtime/InteropServices/JavaScript/Map.cs | 0 .../InteropServices/JavaScript/Runtime.cs | 0 .../JavaScript/SharedArrayBuffer.cs | 0 .../InteropServices/JavaScript/TypedArray.cs | 0 .../InteropServices/JavaScript/Uint16Array.cs | 0 .../InteropServices/JavaScript/Uint32Array.cs | 0 .../InteropServices/JavaScript/Uint8Array.cs | 0 .../JavaScript/Uint8ClampedArray.cs | 0 .../tests/AssemblyInfo.cs | 0 ...e.InteropServices.JavaScript.Tests.csproj} | 2 +- .../InteropServices/JavaScript/ArrayTests.cs | 0 .../JavaScript/DataViewTests.cs | 0 .../JavaScript/HelperMarshal.cs | 0 .../JavaScript/Http/HttpRequestMessageTest.cs | 0 .../JavaScript/JavaScriptTests.cs | 0 .../InteropServices/JavaScript/MapTests.cs | 0 .../JavaScript/MarshalTests.cs | 0 .../JavaScript/TypedArrayTests.cs | 0 ...stem.Runtime.InteropServices.JavaScript.cs | 341 ------------------ ....Runtime.InteropServices.JavaScript.csproj | 12 - src/libraries/pkg/baseline/packageIndex.json | 2 +- .../wasm/debugger/tests/debugger-test.csproj | 2 +- src/mono/wasm/runtime-test.js | 2 +- src/mono/wasm/runtime/binding_support.js | 2 +- 46 files changed, 15 insertions(+), 370 deletions(-) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/Directory.Build.props (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln => System.Private.Runtime.InteropServices.JavaScript/System.Private.Runtime.InteropServices.JavaScript.sln} (89%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/ILLinkTrim.xml (60%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/Resources/Strings.resx (98%) rename src/libraries/{System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj => System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj} (90%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/ArrayBuffer.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/CoreObject.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/DataView.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Float32Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Float64Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Function.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/HostObject.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Int16Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Int32Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Int8Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/JSException.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/JSObject.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Map.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Runtime.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/SharedArrayBuffer.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Uint16Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Uint32Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Uint8Array.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/src/System/Runtime/InteropServices/JavaScript/Uint8ClampedArray.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/AssemblyInfo.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj => System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj} (91%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/MapTests.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs (100%) rename src/libraries/{System.Runtime.InteropServices.JavaScript => System.Private.Runtime.InteropServices.JavaScript}/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs (100%) delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj diff --git a/src/libraries/NetCoreAppLibrary.props b/src/libraries/NetCoreAppLibrary.props index 9b52e36fe43e..0fd6812ef3c1 100644 --- a/src/libraries/NetCoreAppLibrary.props +++ b/src/libraries/NetCoreAppLibrary.props @@ -78,6 +78,7 @@ System.Numerics.Vectors; System.ObjectModel; System.Private.DataContractSerialization; + System.Private.Runtime.InteropServices.JavaScript; System.Private.Uri; System.Private.Xml; System.Private.Xml.Linq; @@ -99,7 +100,6 @@ System.Runtime.Extensions; System.Runtime.Handles; System.Runtime.InteropServices; - System.Runtime.InteropServices.JavaScript; System.Runtime.InteropServices.RuntimeInformation; System.Runtime.Intrinsics; System.Runtime.Loader; 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 983e7f9eb96d..1e2ceae09b72 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -694,7 +694,6 @@ - @@ -716,7 +715,7 @@ - + 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 1f44cb148364..b74f3d8962be 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,6 +37,8 @@ - + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/Directory.Build.props similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/Directory.Build.props diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/System.Private.Runtime.InteropServices.JavaScript.sln similarity index 89% rename from src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/System.Private.Runtime.InteropServices.JavaScript.sln index 1a0db563634e..eacf0032df3a 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/System.Private.Runtime.InteropServices.JavaScript.sln @@ -6,12 +6,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1A2F9F4A EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}" EndProject -Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "System.Runtime.InteropServices.JavaScript.Tests", "tests\System.Runtime.InteropServices.JavaScript.Tests.csproj", "{4F753464-0719-4559-9E0F-86175CECA903}" +Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "System.Private.Runtime.InteropServices.JavaScript.Tests", "tests\System.Private.Runtime.InteropServices.JavaScript.Tests.csproj", "{4F753464-0719-4559-9E0F-86175CECA903}" ProjectSection(ProjectDependencies) = postProject {644FCC7F-1478-4D30-BF66-40E0ADF8723C} = {644FCC7F-1478-4D30-BF66-40E0ADF8723C} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.InteropServices.JavaScript", "src\System.Runtime.InteropServices.JavaScript.csproj", "{644FCC7F-1478-4D30-BF66-40E0ADF8723C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Private.Runtime.InteropServices.JavaScript", "src\System.Private.Runtime.InteropServices.JavaScript.csproj", "{644FCC7F-1478-4D30-BF66-40E0ADF8723C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml similarity index 60% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml index 67f100eb7747..7587cdc31bb9 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLinkTrim.xml @@ -1,5 +1,5 @@  - + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx similarity index 98% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx index a7f92bb25150..8d3b3f1694f0 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx @@ -118,6 +118,6 @@ 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. + System.Private.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.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj similarity index 90% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj index 072a1f1766be..778b0ec31bf6 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj @@ -2,12 +2,9 @@ true enable - $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-Browser - - SR.SystemRuntimeInteropServicesJavaScript_PlatformNotSupported - true diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/ArrayBuffer.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/ArrayBuffer.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/ArrayBuffer.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/ArrayBuffer.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/CoreObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/CoreObject.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/CoreObject.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/CoreObject.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/DataView.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/DataView.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/DataView.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/DataView.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float32Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float32Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float32Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float32Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float64Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float64Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float64Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Float64Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Function.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Function.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Function.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Function.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/HostObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/HostObject.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/HostObject.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/HostObject.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int16Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int16Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int16Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int16Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int32Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int32Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int32Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int32Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int8Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int8Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int8Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Int8Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSException.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSException.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSException.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSException.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Map.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Map.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Map.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Map.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/SharedArrayBuffer.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/SharedArrayBuffer.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/SharedArrayBuffer.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/SharedArrayBuffer.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint16Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint16Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint16Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint16Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint32Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint32Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint32Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint32Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8Array.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8Array.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8Array.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8ClampedArray.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8ClampedArray.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8ClampedArray.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Uint8ClampedArray.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/AssemblyInfo.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/AssemblyInfo.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/AssemblyInfo.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/AssemblyInfo.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj similarity index 91% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj index b38835cd91f7..20ae0d4a7215 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj @@ -19,6 +19,6 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MapTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MapTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MapTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MapTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs rename to src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs 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 deleted file mode 100644 index dc2ac4c65c87..000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs +++ /dev/null @@ -1,341 +0,0 @@ -// 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 deleted file mode 100644 index aded6c5d1e51..000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - enable - $(NetCoreAppCurrent) - - - - - - - - \ No newline at end of file diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index cc13c1d2183a..427eb60f15f7 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -5125,7 +5125,7 @@ "4.1.1.0": "4.3.0" } }, - "System.Runtime.InteropServices.JavaScript": { + "System.Private.Runtime.InteropServices.JavaScript": { "InboxOn": { "net5.0": "5.0.0.0" } diff --git a/src/mono/wasm/debugger/tests/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test.csproj index 310ec8138098..27f295c0de4d 100644 --- a/src/mono/wasm/debugger/tests/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test.csproj @@ -42,7 +42,7 @@ MainJS="$(MonoProjectRoot)wasm\runtime-test.js" DebugLevel="1" AssemblySearchPaths="@(AssemblySearchPaths)" - ExtraAssemblies="$(ArtifactsBinDir)\System.Runtime.InteropServices.JavaScript\$(NetCoreAppCurrent)-Browser-$(RuntimeConfiguration)\System.Runtime.InteropServices.JavaScript.dll"/> + ExtraAssemblies="$(ArtifactsBinDir)\System.Private.Runtime.InteropServices.JavaScript\$(NetCoreAppCurrent)-Browser-$(RuntimeConfiguration)\System.Private.Runtime.InteropServices.JavaScript.dll"/> diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 8f4ced5581fc..74f6a664d212 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -340,6 +340,6 @@ var App = { } }, call_test_method: function (method_name, args) { - return BINDING.call_static_method("[System.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name, args); + return BINDING.call_static_method("[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name, args); } }; \ No newline at end of file diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index d3dd31e8c723..b9a1dae6ec1c 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -4,7 +4,7 @@ var BindingSupportLib = { $BINDING__postset: 'BINDING.export_functions (Module);', $BINDING: { - BINDING_ASM: "[System.Runtime.InteropServices.JavaScript]System.Runtime.InteropServices.JavaScript.Runtime", + BINDING_ASM: "[System.Private.Runtime.InteropServices.JavaScript]System.Runtime.InteropServices.JavaScript.Runtime", mono_wasm_object_registry: [], mono_wasm_ref_counter: 0, mono_wasm_free_list: [], From fb6043adf72d8b7687d5b495dc7c888c82eea016 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 7 Aug 2020 15:09:56 +0100 Subject: [PATCH 317/755] fix nullable annotation for ImmutableInterlocked.Update methods (#40459) --- .../ref/System.Collections.Immutable.cs | 4 ++-- .../src/System/Collections/Immutable/ImmutableInterlocked.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index c8daf5a07fd9..5c7729165fc3 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -520,8 +520,8 @@ public static void Push(ref System.Collections.Immutable.ImmutableStack lo public static bool TryPop(ref System.Collections.Immutable.ImmutableStack location, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T value) { throw null; } public static bool TryRemove(ref System.Collections.Immutable.ImmutableDictionary location, TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) where TKey : notnull { throw null; } public static bool TryUpdate(ref System.Collections.Immutable.ImmutableDictionary location, TKey key, TValue newValue, TValue comparisonValue) where TKey : notnull { throw null; } - public static bool Update(ref T location, System.Func transformer) where T : class { throw null; } - public static bool Update(ref T location, System.Func transformer, TArg transformerArgument) where T : class { throw null; } + public static bool Update(ref T location, System.Func transformer) where T : class? { throw null; } + public static bool Update(ref T location, System.Func transformer, TArg transformerArgument) where T : class? { throw null; } public static bool Update(ref System.Collections.Immutable.ImmutableArray location, Func, System.Collections.Immutable.ImmutableArray> transformer) { throw null; } public static bool Update(ref System.Collections.Immutable.ImmutableArray location, Func, TArg, System.Collections.Immutable.ImmutableArray> transformer, TArg transformerArgument) { throw null; } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs index 6d3ba1728e6b..f907de4d8b49 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs @@ -30,7 +30,7 @@ public static class ImmutableInterlocked /// false if the location's value remained the same because the last /// invocation of returned the existing value. /// - public static bool Update(ref T location, Func transformer) where T : class + public static bool Update(ref T location, Func transformer) where T : class? { Requires.NotNull(transformer, nameof(transformer)); @@ -74,7 +74,7 @@ public static bool Update(ref T location, Func transformer) where T : c /// false if the location's value remained the same because the last /// invocation of returned the existing value. /// - public static bool Update(ref T location, Func transformer, TArg transformerArgument) where T : class + public static bool Update(ref T location, Func transformer, TArg transformerArgument) where T : class? { Requires.NotNull(transformer, nameof(transformer)); From ebc57b941320a86fc2b34047e53448c2acbebb98 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 7 Aug 2020 08:18:09 -0700 Subject: [PATCH 318/755] Address additional feedback from #40172 (#40505) --- eng/illink.targets | 5 ++--- src/libraries/illink-sharedframework.targets | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/eng/illink.targets b/eng/illink.targets index 682871ebc72b..d27feb5f4662 100644 --- a/eng/illink.targets +++ b/eng/illink.targets @@ -276,9 +276,8 @@ - <_DotNetHostDirectory>$(NetCoreRoot) - <_DotNetHostFileName>dotnet - <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe + <_DotNetHostDirectory>$(DotNetRoot) + <_DotNetHostFileName>$([System.IO.Path]::GetFileName('$(DotNetTool)')) - <_DotNetHostDirectory>$(RepoRoot).dotnet - <_DotNetHostFileName>dotnet - <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe + <_DotNetHostDirectory>$(DotNetRoot) + <_DotNetHostFileName>$([System.IO.Path]::GetFileName('$(DotNetTool)')) - + From 5ca480ea678ad2ea6c9abe54e32ce80a3970782a Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Fri, 7 Aug 2020 17:19:33 +0200 Subject: [PATCH 319/755] Increase multiple HTTP/2 connections test timeouts again (#40464) Fixes #40115 Fixes #40436 --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index f0964613b0bd..71c9e27bdfa5 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -2167,7 +2167,7 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ Assert.True(connection1.IsInvalid); Assert.False(connection0.IsInvalid); - Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 7, expectedWarpUpTasks:2).ConfigureAwait(false); + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams, readTimeout: 15, expectedWarpUpTasks:2).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); @@ -2204,13 +2204,13 @@ private async Task VerifySendTasks(IReadOnlyList> send private async Task PrepareConnection(Http2LoopbackServer server, HttpClient client, uint maxConcurrentStreams, int readTimeout = 3, int expectedWarpUpTasks = 1) { Task warmUpTask = client.GetAsync(server.Address); - Http2LoopbackConnection connection = await GetConnection(server, maxConcurrentStreams, readTimeout).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Http2LoopbackConnection connection = await GetConnection(server, maxConcurrentStreams, readTimeout).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds * 2).ConfigureAwait(false); // Wait until the client confirms MaxConcurrentStreams setting took into effect. Task settingAckReceived = connection.SettingAckWaiter; while (true) { Task handleRequestTask = HandleAllPendingRequests(connection, expectedWarpUpTasks); - await Task.WhenAll(warmUpTask, handleRequestTask).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + await Task.WhenAll(warmUpTask, handleRequestTask).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds * 2).ConfigureAwait(false); Assert.True(warmUpTask.Result.IsSuccessStatusCode); warmUpTask.Result.Dispose(); if (settingAckReceived.IsCompleted) From e7204f5d6fcaca5e097ec854b3be6055229fc442 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 7 Aug 2020 11:25:42 -0400 Subject: [PATCH 320/755] Use T? for unconstrained nullable types (#40197) * Temporarily upgrade compiler version for T? support * Use T? for unconstrained nullable types --- .../api-guidelines/nullability.md | 1 + eng/Versions.props | 2 + .../System.Private.CoreLib/src/System/GC.cs | 4 +- .../InteropServices/Marshal.CoreCLR.cs | 9 ++- .../ProviderBase/DbReferenceCollection.cs | 3 +- .../Implementations/MsQuic/MsQuicStream.cs | 2 +- .../Threading/Tasks/RendezvousAwaitable.cs | 4 +- ...nsions.DependencyInjection.Abstractions.cs | 3 +- .../src/ServiceProviderServiceExtensions.cs | 5 +- .../ref/Microsoft.VisualBasic.Core.cs | 3 +- .../ref/System.Collections.Concurrent.cs | 12 ++-- .../Concurrent/BlockingCollection.cs | 16 ++--- .../Collections/Concurrent/ConcurrentBag.cs | 4 +- .../Concurrent/ConcurrentDictionary.cs | 4 +- .../ref/System.Collections.Immutable.cs | 63 ++++++------------ .../Immutable/AllocFreeConcurrentStack.cs | 2 +- .../Immutable/IImmutableListQueries.cs | 6 +- .../Immutable/ImmutableDictionary.cs | 3 +- .../ImmutableDictionary_2.Builder.cs | 3 +- .../ImmutableDictionary_2.HashBucket.cs | 4 +- .../Immutable/ImmutableDictionary_2.cs | 2 +- .../Immutable/ImmutableInterlocked.cs | 4 +- .../Immutable/ImmutableList_1.Builder.cs | 6 +- .../Immutable/ImmutableList_1.Node.cs | 10 ++- .../Collections/Immutable/ImmutableList_1.cs | 6 +- .../ImmutableSortedDictionary_2.Builder.cs | 3 +- .../ImmutableSortedDictionary_2.Node.cs | 2 +- .../Immutable/ImmutableSortedSet_1.Builder.cs | 6 +- .../Immutable/ImmutableSortedSet_1.Node.cs | 10 ++- .../Immutable/ImmutableSortedSet_1.cs | 6 +- .../Collections/Immutable/ImmutableStack_1.cs | 3 +- .../Collections/Immutable/SecureObjectPool.cs | 2 +- .../Immutable/SortedInt32KeyNode.cs | 10 ++- .../System/Linq/ImmutableArrayExtensions.cs | 54 +++++++--------- .../ref/System.Collections.cs | 21 +++--- .../Generic/CollectionExtensions.cs | 5 +- .../System/Collections/Generic/LinkedList.cs | 7 +- .../src/System/Collections/Generic/Queue.cs | 4 +- .../Collections/Generic/SortedDictionary.cs | 2 +- .../System/Collections/Generic/SortedList.cs | 42 ++++-------- .../Generic/SortedSet.TreeSubSet.cs | 18 +++--- .../System/Collections/Generic/SortedSet.cs | 24 +++---- .../src/System/Collections/Generic/Stack.cs | 4 +- .../ref/System.ComponentModel.Composition.cs | 12 ++-- .../Composition/CompositionResultOfT.cs | 6 +- .../Composition/Hosting/AtomicComposition.cs | 2 +- .../ExportProvider.GetExportOverrides.cs | 17 ++--- .../Composition/MetadataServices.cs | 16 ++--- .../ReflectionModel/LazyMemberInfo.cs | 2 +- .../ref/System.Data.Common.cs | 31 ++++----- .../Data/Common/DbDataReaderExtensions.cs | 5 +- .../Data/Common/SQLTypes/SQLInt64Storage.cs | 2 +- .../src/System/Data/DataRowExtensions.cs | 32 ++++------ .../System/Data/DataViewSettingCollection.cs | 4 +- .../src/System/Data/RbTree.cs | 22 +++---- .../src/System/Data/SortExpressionBuilder.cs | 2 +- .../System/Data/TypedTableBaseExtensions.cs | 3 +- .../src/System/Data/xmlsaver.cs | 5 +- .../ProviderBase/DbReferenceCollection.cs | 3 +- .../Enumeration/FileSystemEnumerator.Unix.cs | 2 +- .../FileSystemEnumerator.Windows.cs | 2 +- .../IO/Enumeration/FileSystemEnumerator.cs | 2 +- .../src/System/IO/Iterator.cs | 10 +-- .../src/System/Dynamic/Utils/CacheDict.cs | 2 +- .../Expressions/Compiler/LambdaCompiler.cs | 2 +- .../Linq/Expressions/Interpreter/Utilities.cs | 2 +- .../ref/System.Linq.Parallel.cs | 33 ++++------ .../Enumerables/AggregationMinMaxHelpers.cs | 9 +-- .../Parallel/Enumerables/EmptyEnumerable.cs | 2 +- .../src/System/Linq/Parallel/Helpers.cs | 2 +- .../AsynchronousChannelMergeEnumerator.cs | 2 +- .../SynchronousChannelMergeEnumerator.cs | 4 +- .../Binary/ConcatQueryOperator.cs | 6 +- .../Linq/Parallel/Utils/ReverseComparer.cs | 2 +- .../src/System/Linq/ParallelEnumerable.cs | 44 +++++-------- .../ref/System.Linq.Queryable.cs | 33 ++++------ .../src/System/Linq/CachedReflection.cs | 22 +++---- .../src/System/Linq/Queryable.cs | 33 ++++------ src/libraries/System.Linq/ref/System.Linq.cs | 24 +++---- .../src/System/Linq/DefaultIfEmpty.cs | 2 +- .../System.Linq/src/System/Linq/ElementAt.cs | 5 +- .../System.Linq/src/System/Linq/First.cs | 16 ++--- .../System.Linq/src/System/Linq/IPartition.cs | 9 +-- .../System.Linq/src/System/Linq/Last.cs | 16 ++--- .../System.Linq/src/System/Linq/Max.cs | 10 ++- .../System.Linq/src/System/Linq/Min.cs | 10 ++- .../System/Linq/OrderedEnumerable.SpeedOpt.cs | 20 +++--- .../src/System/Linq/OrderedEnumerable.cs | 7 +- .../src/System/Linq/Partition.SpeedOpt.cs | 57 +++++++---------- .../src/System/Linq/Repeat.SpeedOpt.cs | 5 +- .../src/System/Linq/Select.SpeedOpt.cs | 64 ++++++++----------- .../System.Linq/src/System/Linq/Single.cs | 12 ++-- .../src/System/Buffers/ReadOnlySequence.cs | 4 +- .../ref/System.Net.Http.Json.cs | 10 +-- .../Http/Json/HttpClientJsonExtensions.Get.cs | 10 +-- .../Http/Json/HttpContentJsonExtensions.cs | 4 +- .../StressTests/HttpStress/StressClient.cs | 2 +- .../ServiceNameCollection.cs | 3 +- .../ObjectModel/KeyedCollection.cs | 2 +- .../src/System/Action.cs | 5 +- .../src/System/Array.cs | 10 ++- .../Collections/Concurrent/ConcurrentQueue.cs | 4 +- .../Concurrent/ConcurrentQueueSegment.cs | 6 +- .../System/Collections/Generic/Comparer.cs | 11 ++-- .../System/Collections/Generic/Dictionary.cs | 4 +- .../Collections/Generic/EqualityComparer.cs | 6 +- .../System/Collections/Generic/IComparer.cs | 2 +- .../Collections/Generic/IEqualityComparer.cs | 2 +- .../src/System/Collections/Generic/List.cs | 12 ++-- .../Collections/ObjectModel/Collection.cs | 6 +- .../System/Diagnostics/Tracing/EventSource.cs | 4 +- .../src/System/IComparable.cs | 2 +- .../src/System/IEquatable.cs | 2 +- .../System.Private.CoreLib/src/System/Lazy.cs | 12 ++-- .../src/System/Resources/ResourceReader.cs | 4 +- .../src/System/Resources/ResourceSet.cs | 6 +- .../System/Resources/RuntimeResourceSet.cs | 4 +- .../CompilerServices/AsyncTaskCache.cs | 2 +- .../AsyncTaskMethodBuilderT.cs | 5 +- .../AsyncValueTaskMethodBuilderT.cs | 3 +- .../CompilerServices/ConditionalWeakTable.cs | 2 +- .../Runtime/InteropServices/Marshal.NoCom.cs | 7 +- .../System/Runtime/InteropServices/Marshal.cs | 3 +- .../src/System/SpanHelpers.BinarySearch.cs | 2 +- .../src/System/Threading/AsyncLocal.cs | 6 +- .../src/System/Threading/Tasks/Future.cs | 8 +-- .../Threading/Tasks/ProducerConsumerQueues.cs | 2 +- .../Sources/ManualResetValueTaskSourceCore.cs | 4 +- .../src/System/Threading/Tasks/ValueTask.cs | 8 +-- .../src/System/Threading/ThreadLocal.cs | 13 ++-- .../src/System/Type.Helpers.cs | 4 +- .../Utilities/EnumerableExtensions.cs | 5 +- .../System.Runtime.CompilerServices.Unsafe.cs | 3 +- .../ref/System.Runtime.InteropServices.cs | 10 ++- .../Formatters/Binary/BinaryObjectWriter.cs | 4 +- .../System.Runtime/ref/System.Runtime.cs | 16 ++--- .../ref/System.Security.Cryptography.Cng.cs | 1 - .../Win32/SafeHandles/NCryptSafeHandles.cs | 4 +- .../Cryptography/Pal/AnyOS/ManagedPal.cs | 6 +- .../Pal/Windows/PkcsPalWindows.cs | 6 +- .../System.Text.Json/ref/System.Text.Json.cs | 25 +++----- .../JsonConverterOfT.ReadCore.cs | 9 ++- .../Json/Serialization/JsonConverterOfT.cs | 7 +- .../Json/Serialization/JsonPropertyInfoOfT.cs | 2 +- .../JsonResumableConverterOfT.cs | 3 +- .../JsonSerializer.Read.Helpers.cs | 6 +- .../Serialization/JsonSerializer.Read.Span.cs | 3 +- .../JsonSerializer.Read.Stream.cs | 4 +- .../JsonSerializer.Read.String.cs | 6 +- .../JsonSerializer.Read.Utf8JsonReader.cs | 6 +- .../System/Collections/HashtableExtensions.cs | 5 +- .../Threading/Channels/AsyncOperation.cs | 6 +- .../Threading/Channels/BoundedChannel.cs | 2 +- .../Threading/Channels/UnboundedChannel.cs | 2 +- .../ref/System.Threading.Tasks.Dataflow.cs | 21 ++---- .../src/Base/DataflowBlock.cs | 12 ++-- .../src/Base/ISourceBlock.cs | 3 +- .../src/Blocks/BatchBlock.cs | 3 +- .../src/Blocks/BatchedJoinBlock.cs | 6 +- .../src/Blocks/BroadcastBlock.cs | 9 +-- .../src/Blocks/BufferBlock.cs | 3 +- .../src/Blocks/TransformBlock.cs | 3 +- .../src/Blocks/TransformManyBlock.cs | 3 +- .../src/Blocks/WriteOnceBlock.cs | 13 ++-- .../src/Internal/Common.cs | 3 +- .../src/Internal/ReorderingBuffer.cs | 6 +- .../src/Internal/SourceCore.cs | 3 +- .../src/Internal/TargetRegistry.cs | 3 +- .../System.Threading/ref/System.Threading.cs | 6 +- .../src/System/TypeIdentifier.cs | 2 +- .../src/System/WeakReference.T.Mono.cs | 3 +- 171 files changed, 596 insertions(+), 892 deletions(-) diff --git a/docs/coding-guidelines/api-guidelines/nullability.md b/docs/coding-guidelines/api-guidelines/nullability.md index 8c029d01fcce..62e0fe395888 100644 --- a/docs/coding-guidelines/api-guidelines/nullability.md +++ b/docs/coding-guidelines/api-guidelines/nullability.md @@ -99,6 +99,7 @@ The C# compiler respects a set of attributes that impact its flow analysis. We - **DO** add `[NotNullIfNotNull(string)]` if nullable ref argument will be non-`null` upon exit, when an other argument passed evaluated to non-`null`, pass that argument name as string. Example: `public void Exchange([NotNullIfNotNull("value")] ref object? location, object? value);`. - **DO** add `[return: NotNullIfNotNull(string)]` if a method would not return `null` in case an argument passed evaluated to non-`null`, pass that argument name as string. Example: `[return: NotNullIfNotNull("name")] public string? FormatName(string? name);` - **DO** add `[MemberNotNull(string fieldName)]` to a helper method which initializes member field(s), passing in the field name. Example: `[MemberNotNull("_buffer")] private void InitializeBuffer()`. This will help to avoid spurious warnings at call sites that call the initialization method and then proceed to use the specified field. Note that there are two constructors to `MemberNotNull`; one that takes a single `string`, and one that takes a `params string[]`. When the number of fields initialized is small (e.g. <= 3), it's preferable to use multiple `[MemberNotNull(string)]` attributes on the method rather than one `[MemberNotNull(string, string, string, ...)]` attribute, as the latter is not CLS compliant and will likely require `#pragma warning disable` and `#pragma warning restore` around the line to suppress warnings. +- **AVOID** using `[MaybeNull]`, not because it's problematic, but because there's almost always a better option, such as `T?` (as of this writing, in all of the dotnet/runtime there are only 7 occurrences of `[MaybeNull]`). One example of where it's applicable is `AsyncLocal.Value`; `[DisallowNull]` can't be used here, because `null` is valid if `T` is nullable, and `T?` shouldn't be used because `Value` shouldn't be set to `null` if `T` isn't nullable. Another is in the relatively rare case where a public or protected field is exposed, may begin life as null, but shouldn't be explicitly set to null. ## Code Review Guidance diff --git a/eng/Versions.props b/eng/Versions.props index 45e754414804..02bd975b4fa1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -16,6 +16,8 @@ release true + + 3.8.0-2.20379.3 true false true diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs index 1809ea64685d..cb011de2ef2b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs @@ -659,7 +659,7 @@ internal static void UnregisterMemoryLoadChangeNotification(Action notification) /// If pinned is set to true, must not be a reference type or a type that contains object references. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] // forced to ensure no perf drop for small memory buffers (hot path) - public static T[] AllocateUninitializedArray(int length, bool pinned = false) + public static T[] AllocateUninitializedArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior { if (!pinned) { @@ -705,7 +705,7 @@ static T[] AllocateNewUninitializedArray(int length, bool pinned) /// /// If pinned is set to true, must not be a reference type or a type that contains object references. /// - public static T[] AllocateArray(int length, bool pinned = false) + public static T[] AllocateArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior { GC_ALLOC_FLAGS flags = GC_ALLOC_FLAGS.GC_ALLOC_NO_FLAGS; 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 994244c034db..016d9502d694 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 @@ -706,7 +706,7 @@ public static bool SetComObjectData(object obj, object key, object? data) } [SupportedOSPlatform("windows")] - public static TWrapper CreateWrapperOfType([AllowNull] T o) + public static TWrapper CreateWrapperOfType(T? o) { return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!; } @@ -756,7 +756,7 @@ public static unsafe int Release(IntPtr pUnk) public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant); [SupportedOSPlatform("windows")] - public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) + public static void GetNativeVariantForObject(T? obj, IntPtr pDstNativeVariant) { GetNativeVariantForObject((object?)obj, pDstNativeVariant); } @@ -766,10 +766,9 @@ public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNa public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant); [SupportedOSPlatform("windows")] - [return: MaybeNull] - public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) + public static T? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { - return (T)GetObjectForNativeVariant(pSrcNativeVariant)!; + return (T?)GetObjectForNativeVariant(pSrcNativeVariant); } [SupportedOSPlatform("windows")] diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs index 1ccde6673ebc..8d7aa930bcc6 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbReferenceCollection.cs @@ -137,8 +137,7 @@ protected void AddItem(object value, int tag) } } - [return: MaybeNull] - internal T FindItem(int tag, Func filterMethod) where T : class + internal T? FindItem(int tag, Func filterMethod) where T : class { bool lockObtained = false; try diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs index fc451a7630b7..be0e4a8d034a 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -398,7 +398,7 @@ internal override Task FlushAsync(CancellationToken cancellationToken = default) { ThrowIfDisposed(); - return default!; + return Task.CompletedTask; } public override ValueTask DisposeAsync() diff --git a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs index 3b4fd9a3acbb..b6d1b461380f 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs @@ -24,7 +24,7 @@ internal class RendezvousAwaitable : ICriticalNotifyCompletion /// The exception representing the failed async operation, if it failed. private ExceptionDispatchInfo? _error; /// The result of the async operation, if it succeeded. - [AllowNull] private TResult _result = default; + private TResult? _result; #if DEBUG private bool _resultSet; #endif @@ -64,7 +64,7 @@ public TResult GetResult() } // The operation completed successfully. Clear and return the result. - TResult result = _result; + TResult result = _result!; _result = default(TResult); #if DEBUG _resultSet = false; diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs index 5f9137309bb5..dffd433b92de 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs @@ -111,8 +111,7 @@ public static partial class ServiceProviderServiceExtensions public static T GetRequiredService(this System.IServiceProvider provider) where T : notnull { throw null; } public static System.Collections.Generic.IEnumerable GetServices(this System.IServiceProvider provider, System.Type serviceType) { throw null; } public static System.Collections.Generic.IEnumerable GetServices(this System.IServiceProvider provider) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T GetService(this System.IServiceProvider provider) { throw null; } + public static T? GetService(this System.IServiceProvider provider) { throw null; } } } namespace Microsoft.Extensions.DependencyInjection.Extensions diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs index e35fc6546142..29fcd6cef52d 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs @@ -18,15 +18,14 @@ public static class ServiceProviderServiceExtensions /// The type of service object to get. /// The to retrieve the service object from. /// A service object of type or null if there is no such service. - [return: MaybeNull] - public static T GetService(this IServiceProvider provider) + public static T? GetService(this IServiceProvider provider) { if (provider == null) { throw new ArgumentNullException(nameof(provider)); } - return (T)provider.GetService(typeof(T)); + return (T?)provider.GetService(typeof(T)); } /// diff --git a/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs b/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs index 7b0bfbcf12dc..db978528bf99 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs @@ -771,9 +771,8 @@ internal Conversions() { } public static decimal ToDecimal(string? Value) { throw null; } public static double ToDouble(object? Value) { throw null; } public static double ToDouble(string? Value) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("Value")] - public static T ToGenericParameter(object? Value) { throw null; } + public static T? ToGenericParameter(object? Value) { throw null; } public static int ToInteger(object? Value) { throw null; } public static int ToInteger(string? Value) { throw null; } public static long ToLong(object? Value) { throw null; } diff --git a/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs b/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs index cef519b39d5b..c1a477bb048d 100644 --- a/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs +++ b/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs @@ -33,8 +33,8 @@ void System.Collections.ICollection.CopyTo(System.Array array, int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } public T Take() { throw null; } public T Take(System.Threading.CancellationToken cancellationToken) { throw null; } - public static int TakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item) { throw null; } - public static int TakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item, System.Threading.CancellationToken cancellationToken) { throw null; } + public static int TakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item) { throw null; } + public static int TakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item, System.Threading.CancellationToken cancellationToken) { throw null; } public T[] ToArray() { throw null; } public bool TryAdd(T item) { throw null; } public bool TryAdd(T item, int millisecondsTimeout) { throw null; } @@ -48,10 +48,10 @@ void System.Collections.ICollection.CopyTo(System.Array array, int index) { } public bool TryTake([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T item, int millisecondsTimeout) { throw null; } public bool TryTake([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T item, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; } public bool TryTake([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T item, System.TimeSpan timeout) { throw null; } - public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item) { throw null; } - public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item, int millisecondsTimeout) { throw null; } - public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; } - public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] out T item, System.TimeSpan timeout) { throw null; } + public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item) { throw null; } + public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item, int millisecondsTimeout) { throw null; } + public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; } + public static int TryTakeFromAny(System.Collections.Concurrent.BlockingCollection[] collections, out T? item, System.TimeSpan timeout) { throw null; } } public partial class ConcurrentBag : System.Collections.Concurrent.IProducerConsumerCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.ICollection, System.Collections.IEnumerable { diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs index ec80b76e7541..a7a74c66c320 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs @@ -1169,7 +1169,7 @@ private static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTim /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TakeFromAny may block until an item is available to be removed. - public static int TakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item) + public static int TakeFromAny(BlockingCollection[] collections, out T? item) { return TakeFromAny(collections, out item, CancellationToken.None); } @@ -1198,7 +1198,7 @@ public static int TakeFromAny(BlockingCollection[] collections, [MaybeNull] o /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TakeFromAny may block until an item is available to be removed. - public static int TakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item, CancellationToken cancellationToken) + public static int TakeFromAny(BlockingCollection[] collections, out T? item, CancellationToken cancellationToken) { int returnValue = TryTakeFromAnyCore(collections, out item, Timeout.Infinite, true, cancellationToken); Debug.Assert(returnValue >= 0 && returnValue < collections.Length, @@ -1226,7 +1226,7 @@ public static int TakeFromAny(BlockingCollection[] collections, [MaybeNull] o /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TryTakeFromAny may block until an item is available to be removed. - public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item) + public static int TryTakeFromAny(BlockingCollection[] collections, out T? item) { return TryTakeFromAny(collections, out item, 0); } @@ -1257,7 +1257,7 @@ public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TryTakeFromAny may block until an item is available to be removed. - public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item, TimeSpan timeout) + public static int TryTakeFromAny(BlockingCollection[] collections, out T? item, TimeSpan timeout) { ValidateTimeout(timeout); return TryTakeFromAnyCore(collections, out item, (int)timeout.TotalMilliseconds, false, CancellationToken.None); @@ -1287,7 +1287,7 @@ public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TryTakeFromAny may block until an item is available to be removed. - public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item, int millisecondsTimeout) + public static int TryTakeFromAny(BlockingCollection[] collections, out T? item, int millisecondsTimeout) { ValidateMillisecondsTimeout(millisecondsTimeout); return TryTakeFromAnyCore(collections, out item, millisecondsTimeout, false, CancellationToken.None); @@ -1321,7 +1321,7 @@ public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull /// The count of is greater than the maximum size of /// 62 for STA and 63 for MTA. /// A call to TryTakeFromAny may block until an item is available to be removed. - public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull] out T item, int millisecondsTimeout, CancellationToken cancellationToken) + public static int TryTakeFromAny(BlockingCollection[] collections, out T? item, int millisecondsTimeout, CancellationToken cancellationToken) { ValidateMillisecondsTimeout(millisecondsTimeout); return TryTakeFromAnyCore(collections, out item, millisecondsTimeout, false, cancellationToken); @@ -1344,7 +1344,7 @@ public static int TryTakeFromAny(BlockingCollection[] collections, [MaybeNull /// If the collections argument is a 0-length array or contains a /// null element. Also, if at least one of the collections has been marked complete for adds. /// If at least one of the collections has been disposed. - private static int TryTakeFromAnyCore(BlockingCollection[] collections, [MaybeNull] out T item, int millisecondsTimeout, bool isTakeOperation, CancellationToken externalCancellationToken) + private static int TryTakeFromAnyCore(BlockingCollection[] collections, out T? item, int millisecondsTimeout, bool isTakeOperation, CancellationToken externalCancellationToken) { ValidateCollectionsArray(collections, false); @@ -1378,7 +1378,7 @@ private static int TryTakeFromAnyCore(BlockingCollection[] collections, [Mayb /// If the collections argument is a 0-length array or contains a /// null element. Also, if at least one of the collections has been marked complete for adds. /// If at least one of the collections has been disposed. - private static int TryTakeFromAnyCoreSlow(BlockingCollection[] collections, [MaybeNull] out T item, int millisecondsTimeout, bool isTakeOperation, CancellationToken externalCancellationToken) + private static int TryTakeFromAnyCoreSlow(BlockingCollection[] collections, out T? item, int millisecondsTimeout, bool isTakeOperation, CancellationToken externalCancellationToken) { const int OPERATION_FAILED = -1; diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs index e2253548c46a..2ac047da2584 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs @@ -1089,7 +1089,7 @@ internal enum Operation private sealed class Enumerator : IEnumerator { private readonly T[] _array; - [AllowNull] private T _current = default; + private T? _current; private int _index; public Enumerator(T[] array) @@ -1110,7 +1110,7 @@ public bool MoveNext() return false; } - public T Current => _current; + public T Current => _current!; object? IEnumerator.Current { diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs index 6b06c592e385..affa3bfaa30b 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs @@ -344,7 +344,7 @@ public bool TryRemove(KeyValuePair item) /// The variable into which the removed value, if found, is stored. /// Whether removal of the key is conditional on its value. /// The conditional value to compare against if is true - private bool TryRemoveInternal(TKey key, [MaybeNullWhen(false)] out TValue value, bool matchValue, [AllowNull] TValue oldValue) + private bool TryRemoveInternal(TKey key, [MaybeNullWhen(false)] out TValue value, bool matchValue, TValue? oldValue) { IEqualityComparer? comparer = _comparer; int hashcode = comparer is null ? key.GetHashCode() : comparer.GetHashCode(key); @@ -375,7 +375,7 @@ private bool TryRemoveInternal(TKey key, [MaybeNullWhen(false)] out TValue value bool valuesMatch = EqualityComparer.Default.Equals(oldValue, curr._value); if (!valuesMatch) { - value = default!; + value = default; return false; } } diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index 5c7729165fc3..b24217cca9ce 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -268,8 +268,7 @@ public static partial class ImmutableDictionary public static System.Collections.Immutable.ImmutableDictionary Create() where TKey : notnull { throw null; } public static System.Collections.Immutable.ImmutableDictionary Create(System.Collections.Generic.IEqualityComparer? keyComparer) where TKey : notnull { throw null; } public static System.Collections.Immutable.ImmutableDictionary Create(System.Collections.Generic.IEqualityComparer? keyComparer, System.Collections.Generic.IEqualityComparer? valueComparer) where TKey : notnull { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue GetValueOrDefault(this System.Collections.Immutable.IImmutableDictionary dictionary, TKey key) where TKey : notnull { throw null; } + public static TValue? GetValueOrDefault(this System.Collections.Immutable.IImmutableDictionary dictionary, TKey key) where TKey : notnull { throw null; } public static TValue GetValueOrDefault(this System.Collections.Immutable.IImmutableDictionary dictionary, TKey key, TValue defaultValue) where TKey : notnull { throw null; } public static System.Collections.Immutable.ImmutableDictionary ToImmutableDictionary(this System.Collections.Generic.IEnumerable> source) where TKey : notnull { throw null; } public static System.Collections.Immutable.ImmutableDictionary ToImmutableDictionary(this System.Collections.Generic.IEnumerable> source, System.Collections.Generic.IEqualityComparer? keyComparer) where TKey : notnull { throw null; } @@ -367,8 +366,7 @@ public void Clear() { } public bool ContainsKey(TKey key) { throw null; } public bool ContainsValue(TValue value) { throw null; } public System.Collections.Immutable.ImmutableDictionary.Enumerator GetEnumerator() { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public TValue GetValueOrDefault(TKey key) { throw null; } + public TValue? GetValueOrDefault(TKey key) { throw null; } public TValue GetValueOrDefault(TKey key, TValue defaultValue) { throw null; } public bool Remove(System.Collections.Generic.KeyValuePair item) { throw null; } public bool Remove(TKey key) { throw null; } @@ -572,14 +570,12 @@ public void CopyTo(int index, T[] array, int arrayIndex, int count) { } public void CopyTo(T[] array) { } public void CopyTo(T[] array, int arrayIndex) { } public bool Exists(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Find(System.Predicate match) { throw null; } + public T? Find(System.Predicate match) { throw null; } public System.Collections.Immutable.ImmutableList FindAll(System.Predicate match) { throw null; } public int FindIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindIndex(int startIndex, System.Predicate match) { throw null; } public int FindIndex(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T FindLast(System.Predicate match) { throw null; } + public T? FindLast(System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, System.Predicate match) { throw null; } public int FindLastIndex(System.Predicate match) { throw null; } @@ -662,14 +658,12 @@ public void CopyTo(int index, T[] array, int arrayIndex, int count) { } public void CopyTo(T[] array) { } public void CopyTo(T[] array, int arrayIndex) { } public bool Exists(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Find(System.Predicate match) { throw null; } + public T? Find(System.Predicate match) { throw null; } public System.Collections.Immutable.ImmutableList FindAll(System.Predicate match) { throw null; } public int FindIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindIndex(int startIndex, System.Predicate match) { throw null; } public int FindIndex(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T FindLast(System.Predicate match) { throw null; } + public T? FindLast(System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, System.Predicate match) { throw null; } public int FindLastIndex(System.Predicate match) { throw null; } @@ -866,8 +860,7 @@ public void Clear() { } public bool ContainsKey(TKey key) { throw null; } public bool ContainsValue(TValue value) { throw null; } public System.Collections.Immutable.ImmutableSortedDictionary.Enumerator GetEnumerator() { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public TValue GetValueOrDefault(TKey key) { throw null; } + public TValue? GetValueOrDefault(TKey key) { throw null; } public TValue GetValueOrDefault(TKey key, TValue defaultValue) { throw null; } public bool Remove(System.Collections.Generic.KeyValuePair item) { throw null; } public bool Remove(TKey key) { throw null; } @@ -928,10 +921,8 @@ internal ImmutableSortedSet() { } public bool IsEmpty { get { throw null; } } public T this[int index] { get { throw null; } } public System.Collections.Generic.IComparer KeyComparer { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Max { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Min { get { throw null; } } + public T? Max { get { throw null; } } + public T? Min { get { throw null; } } bool System.Collections.Generic.ICollection.IsReadOnly { get { throw null; } } T System.Collections.Generic.IList.this[int index] { get { throw null; } set { } } bool System.Collections.ICollection.IsSynchronized { get { throw null; } } @@ -996,10 +987,8 @@ internal Builder() { } public int Count { get { throw null; } } public T this[int index] { get { throw null; } } public System.Collections.Generic.IComparer KeyComparer { get { throw null; } set { } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Max { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Min { get { throw null; } } + public T? Max { get { throw null; } } + public T? Min { get { throw null; } } bool System.Collections.Generic.ICollection.IsReadOnly { get { throw null; } } bool System.Collections.ICollection.IsSynchronized { get { throw null; } } object System.Collections.ICollection.SyncRoot { get { throw null; } } @@ -1083,32 +1072,24 @@ namespace System.Linq { public static partial class ImmutableArrayExtensions { - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Aggregate(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func func) { throw null; } + public static T? Aggregate(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func func) { throw null; } public static TAccumulate Aggregate(this System.Collections.Immutable.ImmutableArray immutableArray, TAccumulate seed, System.Func func) { throw null; } public static TResult Aggregate(this System.Collections.Immutable.ImmutableArray immutableArray, TAccumulate seed, System.Func func, System.Func resultSelector) { throw null; } public static bool All(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static bool Any(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } public static bool Any(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static bool Any(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T ElementAtOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, int index) { throw null; } + public static T? ElementAtOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, int index) { throw null; } public static T ElementAt(this System.Collections.Immutable.ImmutableArray immutableArray, int index) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T FirstOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T FirstOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T FirstOrDefault(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } + public static T? FirstOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } + public static T? FirstOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } + public static T? FirstOrDefault(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } public static T First(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } public static T First(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static T First(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T LastOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T LastOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T LastOrDefault(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } + public static T? LastOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } + public static T? LastOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } + public static T? LastOrDefault(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } public static T Last(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } public static T Last(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static T Last(this System.Collections.Immutable.ImmutableArray.Builder builder) { throw null; } @@ -1117,10 +1098,8 @@ public static partial class ImmutableArrayExtensions public static bool SequenceEqual(this System.Collections.Immutable.ImmutableArray immutableArray, System.Collections.Generic.IEnumerable items, System.Collections.Generic.IEqualityComparer? comparer = null) where TDerived : TBase { throw null; } public static bool SequenceEqual(this System.Collections.Immutable.ImmutableArray immutableArray, System.Collections.Immutable.ImmutableArray items, System.Collections.Generic.IEqualityComparer? comparer = null) where TDerived : TBase { throw null; } public static bool SequenceEqual(this System.Collections.Immutable.ImmutableArray immutableArray, System.Collections.Immutable.ImmutableArray items, System.Func predicate) where TDerived : TBase { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T SingleOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T SingleOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } + public static T? SingleOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } + public static T? SingleOrDefault(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static T Single(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } public static T Single(this System.Collections.Immutable.ImmutableArray immutableArray, System.Func predicate) { throw null; } public static T[] ToArray(this System.Collections.Immutable.ImmutableArray immutableArray) { throw null; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs index 3188fce8fe3b..e44135512ed8 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs @@ -31,7 +31,7 @@ public static bool TryTake([MaybeNullWhen(false)] out T item) return true; } - item = default(T)!; + item = default; return false; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/IImmutableListQueries.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/IImmutableListQueries.cs index d5decd80e654..cb19d1869609 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/IImmutableListQueries.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/IImmutableListQueries.cs @@ -120,8 +120,7 @@ internal interface IImmutableListQueries : IReadOnlyList /// The first element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - T Find(Predicate match); + T? Find(Predicate match); /// /// Retrieves all the elements that match the conditions defined by the specified @@ -194,8 +193,7 @@ internal interface IImmutableListQueries : IReadOnlyList /// The last element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - T FindLast(Predicate match); + T? FindLast(Predicate match); /// /// Searches for an element that matches the conditions defined by the specified diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary.cs index 80d99d4d207a..53e6a030761e 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary.cs @@ -290,8 +290,7 @@ public static bool Contains(this IImmutableDictionaryThe dictionary to retrieve the value from. /// The key to search for. /// The value for the key, or the default value of type if no matching key was found. - [return: MaybeNull] - public static TValue GetValueOrDefault(this IImmutableDictionary dictionary, TKey key) where TKey : notnull + public static TValue? GetValueOrDefault(this IImmutableDictionary dictionary, TKey key) where TKey : notnull { return GetValueOrDefault(dictionary, key, default(TValue)!); } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs index a3c766227771..eb94a5bfd27c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs @@ -466,8 +466,7 @@ public Enumerator GetEnumerator() /// /// The key to search for. /// The value for the key, or the default value of type if no matching key was found. - [return: MaybeNull] - public TValue GetValueOrDefault(TKey key) + public TValue? GetValueOrDefault(TKey key) { return this.GetValueOrDefault(key, default(TValue)!); } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.HashBucket.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.HashBucket.cs index 0f8e7cede690..77e65ecf25dd 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.HashBucket.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.HashBucket.cs @@ -263,7 +263,7 @@ internal bool TryGetValue(TKey key, Comparers comparers, [MaybeNullWhen(false)] { if (this.IsEmpty) { - value = default(TValue)!; + value = default; return false; } @@ -277,7 +277,7 @@ internal bool TryGetValue(TKey key, Comparers comparers, [MaybeNullWhen(false)] var index = _additionalElements.IndexOf(kv, comparers.KeyOnlyComparer); if (index < 0) { - value = default(TValue)!; + value = default; return false; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.cs index 504d1202d075..346fdc1d1160 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.cs @@ -912,7 +912,7 @@ private static bool TryGetValue(TKey key, MutationInput origin, [MaybeNullWhen(f return bucket.TryGetValue(key, origin.Comparers, out value!); } - value = default(TValue)!; + value = default; return false; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs index f907de4d8b49..5f99c0624b49 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs @@ -525,7 +525,7 @@ public static bool TryPop(ref ImmutableStack location, [MaybeNullWhen(fals if (priorCollection.IsEmpty) { - value = default(T)!; + value = default; return false; } @@ -580,7 +580,7 @@ public static bool TryDequeue(ref ImmutableQueue location, [MaybeNullWhen( if (priorCollection.IsEmpty) { - value = default(T)!; + value = default; return false; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs index 7d5577d8f2ec..ee6b888241d2 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs @@ -395,8 +395,7 @@ public ImmutableList ConvertAll(Func converter) /// The first element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type T. /// - [return: MaybeNull] - public T Find(Predicate match) => _root.Find(match); + public T? Find(Predicate match) => _root.Find(match); /// /// Retrieves all the elements that match the conditions defined by the specified @@ -469,8 +468,7 @@ public ImmutableList ConvertAll(Func converter) /// The last element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type T. /// - [return: MaybeNull] - public T FindLast(Predicate match) => _root.FindLast(match); + public T? FindLast(Predicate match) => _root.FindLast(match); /// /// Searches for an element that matches the conditions defined by the specified diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs index 9c30a67a6d90..ef0381384f29 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs @@ -998,8 +998,7 @@ internal bool Exists(Predicate match) /// The first element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - internal T Find(Predicate match) + internal T? Find(Predicate match) { Requires.NotNull(match, nameof(match)); @@ -1011,7 +1010,7 @@ internal T Find(Predicate match) } } - return default(T)!; + return default; } /// @@ -1144,8 +1143,7 @@ internal int FindIndex(int startIndex, int count, Predicate match) /// The last element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - internal T FindLast(Predicate match) + internal T? FindLast(Predicate match) { Requires.NotNull(match, nameof(match)); @@ -1160,7 +1158,7 @@ internal T FindLast(Predicate match) } } - return default(T)!; + return default; } /// diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs index e252d3c56198..9597b0a98b6a 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.cs @@ -593,8 +593,7 @@ public ImmutableList ConvertAll(Func converter) /// The first element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - public T Find(Predicate match) => _root.Find(match); + public T? Find(Predicate match) => _root.Find(match); /// /// Retrieves all the elements that match the conditions defined by the specified @@ -667,8 +666,7 @@ public ImmutableList ConvertAll(Func converter) /// The last element that matches the conditions defined by the specified predicate, /// if found; otherwise, the default value for type . /// - [return: MaybeNull] - public T FindLast(Predicate match) => _root.FindLast(match); + public T? FindLast(Predicate match) => _root.FindLast(match); /// /// Searches for an element that matches the conditions defined by the specified diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs index 47da5f071d9b..2f8fafe67b29 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs @@ -603,8 +603,7 @@ public void RemoveRange(IEnumerable keys) /// /// The key to search for. /// The value for the key, or the default value for type if no matching key was found. - [return: MaybeNull] - public TValue GetValueOrDefault(TKey key) + public TValue? GetValueOrDefault(TKey key) { return this.GetValueOrDefault(key, default(TValue)!); } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Node.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Node.cs index 353fb9211368..99173a5b2715 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Node.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Node.cs @@ -362,7 +362,7 @@ internal bool TryGetValue(TKey key, IComparer keyComparer, [MaybeNullWhen( var match = this.Search(key, keyComparer); if (match.IsEmpty) { - value = default(TValue)!; + value = default; return false; } else diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs index 35169818def2..2a1c606d12aa 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs @@ -123,8 +123,7 @@ public ref readonly T ItemRef(int index) /// Gets the maximum value in the collection, as defined by the comparer. /// /// The maximum value in the set. - [MaybeNull] - public T Max + public T? Max { get { return _root.Max; } } @@ -133,8 +132,7 @@ public T Max /// Gets the minimum value in the collection, as defined by the comparer. /// /// The minimum value in the set. - [MaybeNull] - public T Min + public T? Min { get { return _root.Min; } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Node.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Node.cs index 9ff2099a9714..89b044c0ce97 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Node.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Node.cs @@ -184,14 +184,13 @@ internal T Key /// Gets the maximum value in the collection, as defined by the comparer. /// /// The maximum value in the set. - [MaybeNull] - internal T Max + internal T? Max { get { if (this.IsEmpty) { - return default(T)!; + return default; } Node n = this; @@ -208,14 +207,13 @@ internal T Max /// Gets the minimum value in the collection, as defined by the comparer. /// /// The minimum value in the set. - [MaybeNull] - internal T Min + internal T? Min { get { if (this.IsEmpty) { - return default(T)!; + return default; } Node n = this; diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs index c6b8a281f98a..b74674d8e271 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs @@ -84,8 +84,7 @@ public ImmutableSortedSet Clear() /// Gets the maximum value in the collection, as defined by the comparer. /// /// The maximum value in the set. - [MaybeNull] - public T Max + public T? Max { get { return _root.Max; } } @@ -94,8 +93,7 @@ public T Max /// Gets the minimum value in the collection, as defined by the comparer. /// /// The minimum value in the set. - [MaybeNull] - public T Min + public T? Min { get { return _root.Min; } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack_1.cs index 15b5fbdd68ee..f8b70a0a230d 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack_1.cs @@ -27,8 +27,7 @@ public sealed partial class ImmutableStack : IImmutableStack /// /// The element on the top of the stack. /// - [MaybeNull] - private readonly T _head = default!; + private readonly T? _head; /// /// A stack that contains the rest of the elements (under the top element). diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SecureObjectPool.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SecureObjectPool.cs index 8d3664fe9554..6d194da50e5d 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SecureObjectPool.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SecureObjectPool.cs @@ -124,7 +124,7 @@ internal bool TryUse(ref TCaller caller, [MaybeNullWhen(false)] out T v } else { - value = default(T)!; + value = default; return false; } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SortedInt32KeyNode.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SortedInt32KeyNode.cs index 96ba5622790e..25cc0638f62f 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SortedInt32KeyNode.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/SortedInt32KeyNode.cs @@ -34,8 +34,7 @@ internal sealed partial class SortedInt32KeyNode : IBinaryTree /// /// The value associated with this node. /// - [MaybeNull] - private readonly TValue _value = default!; + private readonly TValue? _value; /// /// A value indicating whether this node has been frozen (made immutable). @@ -197,15 +196,14 @@ internal SortedInt32KeyNode Remove(int key, out bool mutated) /// /// The key. /// The value. - [return: MaybeNull] - internal TValue GetValueOrDefault(int key) + internal TValue? GetValueOrDefault(int key) { SortedInt32KeyNode node = this; while (true) { if (node.IsEmpty) { - return default(TValue)!; + return default; } if (key == node._key) @@ -237,7 +235,7 @@ internal bool TryGetValue(int key, [MaybeNullWhen(false)] out TValue value) { if (node.IsEmpty) { - value = default(TValue)!; + value = default; return false; } diff --git a/src/libraries/System.Collections.Immutable/src/System/Linq/ImmutableArrayExtensions.cs b/src/libraries/System.Collections.Immutable/src/System/Linq/ImmutableArrayExtensions.cs index 13109d4c1143..2850cc5c1c36 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Linq/ImmutableArrayExtensions.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Linq/ImmutableArrayExtensions.cs @@ -253,14 +253,13 @@ public static bool SequenceEqual(this ImmutableArray imm /// Applies an accumulator function over a sequence. /// /// The type of element contained by the collection. - [return: MaybeNull] - public static T Aggregate(this ImmutableArray immutableArray, Func func) + public static T? Aggregate(this ImmutableArray immutableArray, Func func) { Requires.NotNull(func, nameof(func)); if (immutableArray.Length == 0) { - return default(T)!; + return default; } var result = immutableArray[0]; @@ -316,12 +315,11 @@ public static T ElementAt(this ImmutableArray immutableArray, int index) /// Returns the element at a specified index in a sequence or a default value if the index is out of range. /// /// The type of element contained by the collection. - [return: MaybeNull] - public static T ElementAtOrDefault(this ImmutableArray immutableArray, int index) + public static T? ElementAtOrDefault(this ImmutableArray immutableArray, int index) { if (index < 0 || index >= immutableArray.Length) { - return default(T)!; + return default; } return immutableArray[index]; @@ -367,18 +365,16 @@ public static T First(this ImmutableArray immutableArray) /// /// The type of element contained by the collection. /// - [return: MaybeNull] - public static T FirstOrDefault(this ImmutableArray immutableArray) + public static T? FirstOrDefault(this ImmutableArray immutableArray) { - return immutableArray.array!.Length > 0 ? immutableArray.array[0] : default(T)!; + return immutableArray.array!.Length > 0 ? immutableArray.array[0] : default; } /// /// Returns the first element of the sequence that satisfies a condition or a default value if no such element is found. /// /// The type of element contained by the collection. - [return: MaybeNull] - public static T FirstOrDefault(this ImmutableArray immutableArray, Func predicate) + public static T? FirstOrDefault(this ImmutableArray immutableArray, Func predicate) { Requires.NotNull(predicate, nameof(predicate)); @@ -390,7 +386,7 @@ public static T FirstOrDefault(this ImmutableArray immutableArray, Func @@ -432,8 +428,7 @@ public static T Last(this ImmutableArray immutableArray, Func pre /// /// The type of element contained by the collection. /// - [return: MaybeNull] - public static T LastOrDefault(this ImmutableArray immutableArray) + public static T? LastOrDefault(this ImmutableArray immutableArray) { immutableArray.ThrowNullRefIfNotInitialized(); return immutableArray.array!.LastOrDefault()!; @@ -443,8 +438,7 @@ public static T LastOrDefault(this ImmutableArray immutableArray) /// Returns the last element of a sequence that satisfies a condition or a default value if no such element is found. /// /// The type of element contained by the collection. - [return: MaybeNull] - public static T LastOrDefault(this ImmutableArray immutableArray, Func predicate) + public static T? LastOrDefault(this ImmutableArray immutableArray, Func predicate) { Requires.NotNull(predicate, nameof(predicate)); @@ -456,7 +450,7 @@ public static T LastOrDefault(this ImmutableArray immutableArray, Func @@ -478,8 +472,8 @@ public static T Single(this ImmutableArray immutableArray, Func p { Requires.NotNull(predicate, nameof(predicate)); - var first = true; - var result = default(T)!; + bool first = true; + T? result = default; foreach (var v in immutableArray.array!) { if (predicate(v)) @@ -499,7 +493,7 @@ public static T Single(this ImmutableArray immutableArray, Func p Enumerable.Empty().Single(); // throw the same exception as LINQ would } - return result; + return result!; } /// @@ -507,8 +501,7 @@ public static T Single(this ImmutableArray immutableArray, Func p /// /// The type of element contained by the collection. /// - [return: MaybeNull] - public static T SingleOrDefault(this ImmutableArray immutableArray) + public static T? SingleOrDefault(this ImmutableArray immutableArray) { immutableArray.ThrowNullRefIfNotInitialized(); return immutableArray.array!.SingleOrDefault()!; @@ -518,13 +511,12 @@ public static T SingleOrDefault(this ImmutableArray immutableArray) /// Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. /// /// The type of element contained by the collection. - [return: MaybeNull] - public static T SingleOrDefault(this ImmutableArray immutableArray, Func predicate) + public static T? SingleOrDefault(this ImmutableArray immutableArray, Func predicate) { Requires.NotNull(predicate, nameof(predicate)); - var first = true; - var result = default(T)!; + bool first = true; + T? result = default; foreach (var v in immutableArray.array!) { if (predicate(v)) @@ -657,12 +649,11 @@ public static T First(this ImmutableArray.Builder builder) /// /// Returns the first element in the collection, or the default value if the collection is empty. /// - [return: MaybeNull] - public static T FirstOrDefault(this ImmutableArray.Builder builder) + public static T? FirstOrDefault(this ImmutableArray.Builder builder) { Requires.NotNull(builder, nameof(builder)); - return builder.Any() ? builder[0] : default(T)!; + return builder.Any() ? builder[0] : default; } /// @@ -684,12 +675,11 @@ public static T Last(this ImmutableArray.Builder builder) /// /// Returns the last element in the collection, or the default value if the collection is empty. /// - [return: MaybeNull] - public static T LastOrDefault(this ImmutableArray.Builder builder) + public static T? LastOrDefault(this ImmutableArray.Builder builder) { Requires.NotNull(builder, nameof(builder)); - return builder.Any() ? builder[builder.Count - 1] : default(T)!; + return builder.Any() ? builder[builder.Count - 1] : default; } /// diff --git a/src/libraries/System.Collections/ref/System.Collections.cs b/src/libraries/System.Collections/ref/System.Collections.cs index b0505e823849..334a67afad23 100644 --- a/src/libraries/System.Collections/ref/System.Collections.cs +++ b/src/libraries/System.Collections/ref/System.Collections.cs @@ -43,8 +43,7 @@ namespace System.Collections.Generic { public static partial class CollectionExtensions { - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue GetValueOrDefault(this System.Collections.Generic.IReadOnlyDictionary dictionary, TKey key) { throw null; } + public static TValue? GetValueOrDefault(this System.Collections.Generic.IReadOnlyDictionary dictionary, TKey key) { throw null; } public static TValue GetValueOrDefault(this System.Collections.Generic.IReadOnlyDictionary dictionary, TKey key, TValue defaultValue) { throw null; } public static bool Remove(this System.Collections.Generic.IDictionary dictionary, TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) { throw null; } public static bool TryAdd(this System.Collections.Generic.IDictionary dictionary, TKey key, TValue value) { throw null; } @@ -53,7 +52,7 @@ public abstract partial class Comparer : System.Collections.Generic.IComparer { protected Comparer() { } public static System.Collections.Generic.Comparer Default { get { throw null; } } - public abstract int Compare([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); + public abstract int Compare(T? x, T? y); public static System.Collections.Generic.Comparer Create(System.Comparison comparison) { throw null; } int System.Collections.IComparer.Compare(object? x, object? y) { throw null; } } @@ -184,7 +183,7 @@ public abstract partial class EqualityComparer : System.Collections.Generic.I { protected EqualityComparer() { } public static System.Collections.Generic.EqualityComparer Default { get { throw null; } } - public abstract bool Equals([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); + public abstract bool Equals(T? x, T? y); public abstract int GetHashCode([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T obj); bool System.Collections.IEqualityComparer.Equals(object? x, object? y) { throw null; } int System.Collections.IEqualityComparer.GetHashCode(object obj) { throw null; } @@ -326,14 +325,12 @@ public void CopyTo(int index, T[] array, int arrayIndex, int count) { } public void CopyTo(T[] array) { } public void CopyTo(T[] array, int arrayIndex) { } public bool Exists(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Find(System.Predicate match) { throw null; } + public T? Find(System.Predicate match) { throw null; } public System.Collections.Generic.List FindAll(System.Predicate match) { throw null; } public int FindIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindIndex(int startIndex, System.Predicate match) { throw null; } public int FindIndex(System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T FindLast(System.Predicate match) { throw null; } + public T? FindLast(System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, int count, System.Predicate match) { throw null; } public int FindLastIndex(int startIndex, System.Predicate match) { throw null; } public int FindLastIndex(System.Predicate match) { throw null; } @@ -589,10 +586,8 @@ public SortedSet(System.Collections.Generic.IEnumerable collection, System.Co protected SortedSet(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.Collections.Generic.IComparer Comparer { get { throw null; } } public int Count { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Max { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T Min { get { throw null; } } + public T? Max { get { throw null; } } + public T? Min { get { throw null; } } bool System.Collections.Generic.ICollection.IsReadOnly { get { throw null; } } bool System.Collections.ICollection.IsSynchronized { get { throw null; } } object System.Collections.ICollection.SyncRoot { get { throw null; } } @@ -607,7 +602,7 @@ public void CopyTo(T[] array, int index, int count) { } public void ExceptWith(System.Collections.Generic.IEnumerable other) { } public System.Collections.Generic.SortedSet.Enumerator GetEnumerator() { throw null; } protected virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public virtual System.Collections.Generic.SortedSet GetViewBetween(T lowerValue, T upperValue) { throw null; } + public virtual System.Collections.Generic.SortedSet GetViewBetween(T? lowerValue, T? upperValue) { throw null; } public virtual void IntersectWith(System.Collections.Generic.IEnumerable other) { } public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable other) { throw null; } public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable other) { throw null; } diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs b/src/libraries/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs index 47de3ec036e7..39158f2e18cd 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs @@ -7,8 +7,7 @@ namespace System.Collections.Generic { public static class CollectionExtensions { - [return: MaybeNull] - public static TValue GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key) + public static TValue? GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key) { return dictionary.GetValueOrDefault(key, default!); } @@ -53,7 +52,7 @@ public static bool Remove(this IDictionary dictionar return true; } - value = default(TValue)!; + value = default; return false; } } diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs b/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs index 1694a7cbf651..cd2718696213 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs @@ -530,7 +530,7 @@ public struct Enumerator : IEnumerator, IEnumerator, ISerializable, IDeserial private readonly LinkedList _list; private LinkedListNode? _node; private readonly int _version; - [AllowNull] private T _current; + private T? _current; private int _index; internal Enumerator(LinkedList list) @@ -542,10 +542,7 @@ internal Enumerator(LinkedList list) _index = 0; } - public T Current - { - get { return _current; } - } + public T Current => _current!; object? IEnumerator.Current { diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs b/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs index efd2b1e9a72c..c468d1663c45 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs @@ -395,7 +395,7 @@ public struct Enumerator : IEnumerator, private readonly Queue _q; private readonly int _version; private int _index; // -1 = not started, -2 = ended/disposed - [AllowNull] private T _currentElement; + private T? _currentElement; internal Enumerator(Queue q) { @@ -457,7 +457,7 @@ public T Current { if (_index < 0) ThrowEnumerationNotStartedOrEnded(); - return _currentElement; + return _currentElement!; } } diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs index 8bca75b21f7c..fd649d52ca34 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs @@ -288,7 +288,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) TreeSet>.Node? node = _set.FindNode(new KeyValuePair(key, default(TValue)!)); if (node == null) { - value = default(TValue)!; + value = default; return false; } value = node.Item.Value; 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 1ce3cd9cd19e..220de76fca16 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs @@ -685,7 +685,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) return true; } - value = default(TValue)!; + value = default; return false; } @@ -761,8 +761,8 @@ private static bool IsCompatibleKey(object key) private struct Enumerator : IEnumerator>, IDictionaryEnumerator { private readonly SortedList _sortedList; - [AllowNull] private TKey _key; - [AllowNull] private TValue _value; + private TKey? _key; + private TValue? _value; private int _index; private readonly int _version; private readonly int _getEnumeratorRetType; // What should Enumerator.Current return? @@ -796,7 +796,7 @@ object IDictionaryEnumerator.Key throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); } - return _key; + return _key!; } } @@ -827,17 +827,11 @@ DictionaryEntry IDictionaryEnumerator.Entry throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); } - return new DictionaryEntry(_key, _value); + return new DictionaryEntry(_key!, _value); } } - public KeyValuePair Current - { - get - { - return new KeyValuePair(_key, _value); - } - } + public KeyValuePair Current => new KeyValuePair(_key!, _value!); object? IEnumerator.Current { @@ -850,11 +844,11 @@ public KeyValuePair Current if (_getEnumeratorRetType == DictEntry) { - return new DictionaryEntry(_key, _value); + return new DictionaryEntry(_key!, _value); } else { - return new KeyValuePair(_key, _value); + return new KeyValuePair(_key!, _value!); } } } @@ -890,7 +884,7 @@ private sealed class SortedListKeyEnumerator : IEnumerator, IEnumerator private readonly SortedList _sortedList; private int _index; private readonly int _version; - [AllowNull] private TKey _currentKey = default!; + private TKey? _currentKey; internal SortedListKeyEnumerator(SortedList sortedList) { @@ -923,13 +917,7 @@ public bool MoveNext() return false; } - public TKey Current - { - get - { - return _currentKey; - } - } + public TKey Current => _currentKey!; object? IEnumerator.Current { @@ -960,7 +948,7 @@ private sealed class SortedListValueEnumerator : IEnumerator, IEnumerato private readonly SortedList _sortedList; private int _index; private readonly int _version; - [AllowNull] private TValue _currentValue = default!; + private TValue? _currentValue; internal SortedListValueEnumerator(SortedList sortedList) { @@ -993,13 +981,7 @@ public bool MoveNext() return false; } - public TValue Current - { - get - { - return _currentValue; - } - } + public TValue Current => _currentValue!; object? IEnumerator.Current { diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs index eb116ac0eb45..91745e21d058 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs @@ -16,10 +16,8 @@ public partial class SortedSet internal sealed class TreeSubSet : SortedSet, ISerializable, IDeserializationCallback { private readonly SortedSet _underlying; - [MaybeNull, AllowNull] - private readonly T _min; - [MaybeNull, AllowNull] - private readonly T _max; + private readonly T? _min; + private readonly T? _max; // keeps track of whether the count variable is up to date // up to date -> _countVersion = _underlying.version // not up to date -> _countVersion < _underlying.version @@ -38,7 +36,7 @@ internal override bool versionUpToDate() } #endif - public TreeSubSet(SortedSet Underlying, [AllowNull] T Min, [AllowNull] T Max, bool lowerBoundActive, bool upperBoundActive) + public TreeSubSet(SortedSet Underlying, T? Min, T? Max, bool lowerBoundActive, bool upperBoundActive) : base(Underlying.Comparer) { _underlying = Underlying; @@ -129,7 +127,7 @@ internal override T MinInternal get { Node? current = root; - T result = default(T)!; + T? result = default; while (current != null) { @@ -150,7 +148,7 @@ internal override T MinInternal } } - return result; + return result!; } } @@ -159,7 +157,7 @@ internal override T MaxInternal get { Node? current = root; - T result = default(T)!; + T? result = default; while (current != null) { @@ -179,7 +177,7 @@ internal override T MaxInternal } } - return result; + return result!; } } @@ -340,7 +338,7 @@ internal override int TotalCount() // This passes functionality down to the underlying tree, clipping edges if necessary // There's nothing gained by having a nested subset. May as well draw it from the base // Cannot increase the bounds of the subset, can only decrease it - public override SortedSet GetViewBetween([AllowNull] T lowerValue, [AllowNull] T upperValue) + public override SortedSet GetViewBetween(T? lowerValue, T? upperValue) { if (_lBoundActive && Comparer.Compare(_min, lowerValue) > 0) { diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs index 3cc375c47834..3d2989a86c8b 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs @@ -755,9 +755,9 @@ internal virtual int InternalIndexOf(T item) return -1; } - internal Node? FindRange([AllowNull] T from, [AllowNull] T to) => FindRange(from, to, lowerBoundActive: true, upperBoundActive: true); + internal Node? FindRange(T? from, T? to) => FindRange(from, to, lowerBoundActive: true, upperBoundActive: true); - internal Node? FindRange([AllowNull] T from, [AllowNull] T to, bool lowerBoundActive, bool upperBoundActive) + internal Node? FindRange(T? from, T? to, bool lowerBoundActive, bool upperBoundActive) { Node? current = root; while (current != null) @@ -1504,17 +1504,15 @@ public int RemoveWhere(Predicate match) #region ISorted members - [MaybeNull] - public T Min => MinInternal; + public T? Min => MinInternal; - [MaybeNull] - internal virtual T MinInternal + internal virtual T? MinInternal { get { if (root == null) { - return default(T)!; + return default; } Node current = root; @@ -1527,17 +1525,15 @@ internal virtual T MinInternal } } - [MaybeNull] - public T Max => MaxInternal; + public T? Max => MaxInternal; - [MaybeNull] - internal virtual T MaxInternal + internal virtual T? MaxInternal { get { if (root == null) { - return default(T)!; + return default; } Node current = root; @@ -1559,7 +1555,7 @@ public IEnumerable Reverse() } } - public virtual SortedSet GetViewBetween([AllowNull] T lowerValue, [AllowNull] T upperValue) + public virtual SortedSet GetViewBetween(T? lowerValue, T? upperValue) { if (Comparer.Compare(lowerValue, upperValue) > 0) { @@ -2074,7 +2070,7 @@ public bool TryGetValue(T equalValue, [MaybeNullWhen(false)] out T actualValue) actualValue = node.Item; return true; } - actualValue = default(T)!; + actualValue = default; return false; } diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs b/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs index dbb41578cade..8f191eed51e4 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs @@ -315,7 +315,7 @@ public struct Enumerator : IEnumerator, System.Collections.IEnumerator private readonly Stack _stack; private readonly int _version; private int _index; - [AllowNull] private T _currentElement; + private T? _currentElement; internal Enumerator(Stack stack) { @@ -361,7 +361,7 @@ public T Current { if (_index < 0) ThrowEnumerationNotStartedOrEnded(); - return _currentElement; + return _currentElement!; } } diff --git a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs index 2b30949c522f..f55f6b216d37 100644 --- a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs +++ b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs @@ -415,16 +415,12 @@ public abstract partial class ExportProvider protected ExportProvider() { } public event System.EventHandler? ExportsChanged { add { } remove { } } public event System.EventHandler? ExportsChanging { add { } remove { } } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T GetExportedValueOrDefault() { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T GetExportedValueOrDefault(string? contractName) { throw null; } + public T? GetExportedValueOrDefault() { throw null; } + public T? GetExportedValueOrDefault(string? contractName) { throw null; } public System.Collections.Generic.IEnumerable GetExportedValues() { throw null; } public System.Collections.Generic.IEnumerable GetExportedValues(string? contractName) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T GetExportedValue() { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T GetExportedValue(string? contractName) { throw null; } + public T? GetExportedValue() { throw null; } + public T? GetExportedValue(string? contractName) { throw null; } public System.Collections.Generic.IEnumerable GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition definition) { throw null; } public System.Collections.Generic.IEnumerable GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition definition, System.ComponentModel.Composition.Hosting.AtomicComposition? atomicComposition) { throw null; } public System.Collections.Generic.IEnumerable> GetExports(System.Type type, System.Type? metadataViewType, string? contractName) { throw null; } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResultOfT.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResultOfT.cs index 380d2029e1d5..9c66e1817b89 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResultOfT.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionResultOfT.cs @@ -11,7 +11,7 @@ namespace System.ComponentModel.Composition internal struct CompositionResult { private readonly IEnumerable? _errors; - [AllowNull] private readonly T _value; + private readonly T? _value; public CompositionResult(T value) : this(value, null) @@ -28,7 +28,7 @@ public CompositionResult(IEnumerable? errors) { } - internal CompositionResult([AllowNull] T value, IEnumerable? errors) + internal CompositionResult(T? value, IEnumerable? errors) { _errors = errors; _value = value; @@ -53,7 +53,7 @@ public T Value { ThrowOnErrors(); - return _value; + return _value!; } } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AtomicComposition.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AtomicComposition.cs index d20dac119020..752d817a0507 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AtomicComposition.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AtomicComposition.cs @@ -295,7 +295,7 @@ private bool TryGetValueInternal(object key, bool localAtomicCompositionOnly, return _outerAtomicComposition.TryGetValueInternal(key, localAtomicCompositionOnly, out value); } - value = default(T)!; + value = default; return false; } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs index 12f0a6a3e418..8ddbd6c53689 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs @@ -473,8 +473,7 @@ public IEnumerable> GetExports(string? /// An error occurred during composition. will /// contain a collection of errors that occurred. /// - [return: MaybeNull] - public T GetExportedValue() + public T? GetExportedValue() { return GetExportedValue((string?)null); } @@ -524,8 +523,7 @@ public T GetExportedValue() /// An error occurred during composition. will /// contain a collection of errors that occurred. /// - [return: MaybeNull] - public T GetExportedValue(string? contractName) + public T? GetExportedValue(string? contractName) { return GetExportedValueCore(contractName, ImportCardinality.ExactlyOne); } @@ -575,8 +573,7 @@ public T GetExportedValue(string? contractName) /// An error occurred during composition. will /// contain a collection of errors that occurred. /// - [return: MaybeNull] - public T GetExportedValueOrDefault() + public T? GetExportedValueOrDefault() { return GetExportedValueOrDefault((string?)null); } @@ -626,8 +623,7 @@ public T GetExportedValueOrDefault() /// An error occurred during composition. will /// contain a collection of errors that occurred. /// - [return: MaybeNull] - public T GetExportedValueOrDefault(string? contractName) + public T? GetExportedValueOrDefault(string? contractName) { return GetExportedValueCore(contractName, ImportCardinality.ZeroOrOne); } @@ -724,8 +720,7 @@ private IEnumerable GetExportedValuesCore(string? contractName) return result; } - [return: MaybeNull] - private T GetExportedValueCore(string? contractName, ImportCardinality cardinality) + private T? GetExportedValueCore(string? contractName, ImportCardinality cardinality) { if (!cardinality.IsAtMostOne()) { @@ -734,7 +729,7 @@ private T GetExportedValueCore(string? contractName, ImportCardinality cardin Export? export = GetExportsCore(typeof(T), (Type?)null, contractName, cardinality).SingleOrDefault(); - return (export != null) ? ExportServices.GetCastedExportedValue(export) : default(T)!; + return (export != null) ? ExportServices.GetCastedExportedValue(export) : default; } private IEnumerable> GetExportsCore(string? contractName) diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/MetadataServices.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/MetadataServices.cs index b64f990f7950..25d362e457d7 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/MetadataServices.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/MetadataServices.cs @@ -26,27 +26,19 @@ internal static class MetadataServices return new ReadOnlyDictionary(metadata); } - [return: MaybeNull] - public static T GetValue(this IDictionary metadata, string key) + public static T? GetValue(this IDictionary metadata, string key) { if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } - if (!metadata.TryGetValue(key, out object? untypedValue)) + if (metadata.TryGetValue(key, out object? untypedValue) && untypedValue is T t) { - return default(T)!; + return t; } - if (untypedValue is T) - { - return (T)untypedValue; - } - else - { - return default(T)!; - } + return default; } } } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs index 983f25d9efc9..14124ff46f5c 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs @@ -103,7 +103,7 @@ public override int GetHashCode() { throw new Exception(SR.Diagnostic_InternalExceptionMessage); } - return MemberType.GetHashCode() ^ _accessors[0]!.GetHashCode(); // TODO-NULLABLE https://github.com/dotnet/roslyn/issues/34644 + return MemberType.GetHashCode() ^ _accessors[0]!.GetHashCode(); // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) } } diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index 24cdb3d274eb..d9df3c027077 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -403,21 +403,15 @@ internal DataRowComparer() { } } public static partial class DataRowExtensions { - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, System.Data.DataColumn column) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, System.Data.DataColumn column, System.Data.DataRowVersion version) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, int columnIndex) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, int columnIndex, System.Data.DataRowVersion version) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, string columnName) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Field(this System.Data.DataRow row, string columnName, System.Data.DataRowVersion version) { throw null; } - public static void SetField(this System.Data.DataRow row, System.Data.DataColumn column, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T value) { } - public static void SetField(this System.Data.DataRow row, int columnIndex, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T value) { } - public static void SetField(this System.Data.DataRow row, string columnName, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T value) { } + public static T? Field(this System.Data.DataRow row, System.Data.DataColumn column) { throw null; } + public static T? Field(this System.Data.DataRow row, System.Data.DataColumn column, System.Data.DataRowVersion version) { throw null; } + public static T? Field(this System.Data.DataRow row, int columnIndex) { throw null; } + public static T? Field(this System.Data.DataRow row, int columnIndex, System.Data.DataRowVersion version) { throw null; } + public static T? Field(this System.Data.DataRow row, string columnName) { throw null; } + public static T? Field(this System.Data.DataRow row, string columnName, System.Data.DataRowVersion version) { throw null; } + public static void SetField(this System.Data.DataRow row, System.Data.DataColumn column, T? value) { } + public static void SetField(this System.Data.DataRow row, int columnIndex, T? value) { } + public static void SetField(this System.Data.DataRow row, string columnName, T? value) { } } [System.FlagsAttribute] public enum DataRowState @@ -1057,8 +1051,8 @@ internal DataViewSettingCollection() { } [System.ComponentModel.BrowsableAttribute(false)] public bool IsSynchronized { get { throw null; } } public virtual System.Data.DataViewSetting this[System.Data.DataTable table] { get { throw null; } set { } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public virtual System.Data.DataViewSetting this[int index] { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public virtual System.Data.DataViewSetting? this[int index] { get { throw null; } set { } } public virtual System.Data.DataViewSetting? this[string tableName] { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] public object SyncRoot { get { throw null; } } @@ -1563,8 +1557,7 @@ public SyntaxErrorException(string? message, System.Exception? innerException) { public static partial class TypedTableBaseExtensions { public static System.Data.EnumerableRowCollection AsEnumerable(this System.Data.TypedTableBase source) where TRow : System.Data.DataRow { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TRow ElementAtOrDefault(this System.Data.TypedTableBase source, int index) where TRow : System.Data.DataRow { throw null; } + public static TRow? ElementAtOrDefault(this System.Data.TypedTableBase source, int index) where TRow : System.Data.DataRow { throw null; } public static System.Data.OrderedEnumerableRowCollection OrderByDescending(this System.Data.TypedTableBase source, System.Func keySelector) where TRow : System.Data.DataRow { throw null; } public static System.Data.OrderedEnumerableRowCollection OrderByDescending(this System.Data.TypedTableBase source, System.Func keySelector, System.Collections.Generic.IComparer comparer) where TRow : System.Data.DataRow { throw null; } public static System.Data.OrderedEnumerableRowCollection OrderBy(this System.Data.TypedTableBase source, System.Func keySelector) where TRow : System.Data.DataRow { throw null; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataReaderExtensions.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataReaderExtensions.cs index 97e0fafbff1a..8b851446d44d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataReaderExtensions.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataReaderExtensions.cs @@ -30,7 +30,7 @@ private void PopulateFields() BaseSchemaName = GetDbColumnValue(SchemaTableColumn.BaseSchemaName); BaseServerName = GetDbColumnValue(SchemaTableOptionalColumn.BaseServerName); BaseTableName = GetDbColumnValue(SchemaTableColumn.BaseTableName); - ColumnName = GetDbColumnValue(SchemaTableColumn.ColumnName); + ColumnName = GetDbColumnValue(SchemaTableColumn.ColumnName)!; ColumnOrdinal = GetDbColumnValue(SchemaTableColumn.ColumnOrdinal); ColumnSize = GetDbColumnValue(SchemaTableColumn.ColumnSize); IsAliased = GetDbColumnValue(SchemaTableColumn.IsAliased); @@ -49,8 +49,7 @@ private void PopulateFields() DataTypeName = GetDbColumnValue("DataTypeName"); } - // The following may return null, but local methods can't be annotated for that yet ([MaybeNull]) - private T GetDbColumnValue(string columnName) => _schemaColumns.Contains(columnName) && _schemaRow[columnName] is T value ? value : default!; + private T? GetDbColumnValue(string columnName) => _schemaColumns.Contains(columnName) && _schemaRow[columnName] is T value ? value : default; } public static ReadOnlyCollection GetColumnSchema(this DbDataReader reader) diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs index 2c9fa58f854d..e469f3218b5b 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs @@ -12,7 +12,7 @@ namespace System.Data.Common { internal sealed class SqlInt64Storage : DataStorage { - private SqlInt64[] _values = default!; + private SqlInt64[] _values = default!; // Late-initialized public SqlInt64Storage(DataColumn column) : base(column, typeof(SqlInt64), SqlInt64.Null, SqlInt64.Null, StorageType.SqlInt64) diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRowExtensions.cs b/src/libraries/System.Data.Common/src/System/Data/DataRowExtensions.cs index afa65a31f7ee..3ebbdc113527 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRowExtensions.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRowExtensions.cs @@ -19,8 +19,7 @@ public static class DataRowExtensions /// The input DataRow /// The input column name specifying which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, string columnName) + public static T? Field(this DataRow row, string columnName) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[columnName]); @@ -35,8 +34,7 @@ public static T Field(this DataRow row, string columnName) /// The input DataRow /// The input DataColumn specifying which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, DataColumn column) + public static T? Field(this DataRow row, DataColumn column) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[column]); @@ -51,8 +49,7 @@ public static T Field(this DataRow row, DataColumn column) /// The input DataRow /// The input ordinal specifying which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, int columnIndex) + public static T? Field(this DataRow row, int columnIndex) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[columnIndex]); @@ -68,8 +65,7 @@ public static T Field(this DataRow row, int columnIndex) /// The input ordinal specifying which row value to retrieve. /// The DataRow version for which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, int columnIndex, DataRowVersion version) + public static T? Field(this DataRow row, int columnIndex, DataRowVersion version) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[columnIndex, version]); @@ -85,8 +81,7 @@ public static T Field(this DataRow row, int columnIndex, DataRowVersion versi /// The input column name specifying which row value to retrieve. /// The DataRow version for which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, string columnName, DataRowVersion version) + public static T? Field(this DataRow row, string columnName, DataRowVersion version) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[columnName, version]); @@ -102,8 +97,7 @@ public static T Field(this DataRow row, string columnName, DataRowVersion ver /// The input DataColumn specifying which row value to retrieve. /// The DataRow version for which row value to retrieve. /// The DataRow value for the column specified. - [return: MaybeNull] - public static T Field(this DataRow row, DataColumn column, DataRowVersion version) + public static T? Field(this DataRow row, DataColumn column, DataRowVersion version) { DataSetUtil.CheckArgumentNull(row, nameof(row)); return UnboxT.s_unbox(row[column, version]); @@ -115,7 +109,7 @@ public static T Field(this DataRow row, DataColumn column, DataRowVersion ver /// The input DataRow. /// The input ordinal specifying which row value to set. /// The new row value for the specified column. - public static void SetField(this DataRow row, int columnIndex, [AllowNull] T value) + public static void SetField(this DataRow row, int columnIndex, T? value) { DataSetUtil.CheckArgumentNull(row, nameof(row)); row[columnIndex] = (object?)value ?? DBNull.Value; @@ -127,7 +121,7 @@ public static void SetField(this DataRow row, int columnIndex, [AllowNull] T /// The input DataRow. /// The input column name specifying which row value to retrieve. /// The new row value for the specified column. - public static void SetField(this DataRow row, string columnName, [AllowNull] T value) + public static void SetField(this DataRow row, string columnName, T? value) { DataSetUtil.CheckArgumentNull(row, nameof(row)); row[columnName] = (object?)value ?? DBNull.Value; @@ -139,7 +133,7 @@ public static void SetField(this DataRow row, string columnName, [AllowNull] /// The input DataRow. /// The input DataColumn specifying which row value to retrieve. /// The new row value for the specified column. - public static void SetField(this DataRow row, DataColumn column, [AllowNull] T value) + public static void SetField(this DataRow row, DataColumn column, T? value) { DataSetUtil.CheckArgumentNull(row, nameof(row)); row[column] = (object?)value ?? DBNull.Value; @@ -147,9 +141,9 @@ public static void SetField(this DataRow row, DataColumn column, [AllowNull] private static class UnboxT { - internal static readonly Converter s_unbox = Create(); + internal static readonly Converter s_unbox = Create(); - private static Converter Create() + private static Converter Create() { if (typeof(T).IsValueType) { @@ -165,8 +159,7 @@ private static Converter Create() return ReferenceField; } - [return: MaybeNull] - private static T ReferenceField(object value) + private static T? ReferenceField(object value) => value == DBNull.Value ? default : (T)value; private static T ValueField(object value) @@ -174,7 +167,6 @@ private static T ValueField(object value) ? throw DataSetUtil.InvalidCast(SR.Format(SR.DataSetLinq_NonNullableCast, typeof(T))) : (T)value; - [return: MaybeNull] private static Nullable NullableField(object value) where TElem : struct => value == DBNull.Value ? default : new Nullable((TElem)value); } diff --git a/src/libraries/System.Data.Common/src/System/Data/DataViewSettingCollection.cs b/src/libraries/System.Data.Common/src/System/Data/DataViewSettingCollection.cs index dc059c1a3e3b..62b9fb6e470c 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataViewSettingCollection.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataViewSettingCollection.cs @@ -84,8 +84,8 @@ public virtual DataViewSetting? this[string tableName] } } - [MaybeNull] - public virtual DataViewSetting this[int index] + [DisallowNull] + public virtual DataViewSetting? this[int index] { get { diff --git a/src/libraries/System.Data.Common/src/System/Data/RbTree.cs b/src/libraries/System.Data.Common/src/System/Data/RbTree.cs index 4c40476ca385..a5f75b089899 100644 --- a/src/libraries/System.Data.Common/src/System/Data/RbTree.cs +++ b/src/libraries/System.Data.Common/src/System/Data/RbTree.cs @@ -96,8 +96,8 @@ internal abstract class RBTree : IEnumerable internal const int DefaultPageSize = 32; /* 512 = 2^9 32 million nodes*/ internal const int NIL = 0; // 0th page, 0th slot for each tree till CLR static & generics issue is fixed - private TreePage?[] _pageTable = default!; // initial size 4, then doubles (grows) - it never shrinks. Late-initialized to non-null in InitTree. - private int[] _pageTableMap = default!; // Late-initialized to non-null in InitTree + private TreePage?[] _pageTable; // initial size 4, then doubles (grows) - it never shrinks. + private int[] _pageTableMap; private int _inUsePageCount; // contains count of allocated pages per tree, its <= the capacity of pageTable private int _nextFreePageLine; // used for keeping track of position of last used free page in pageTable public int root; @@ -107,8 +107,8 @@ internal abstract class RBTree : IEnumerable private int _inUseSatelliteTreeCount; // total number of satellite associated with this tree. private readonly TreeAccessMethod _accessMethod; - protected abstract int CompareNode([AllowNull] K record1, [AllowNull] K record2); - protected abstract int CompareSateliteTreeNode([AllowNull] K record1, [AllowNull] K record2); + protected abstract int CompareNode(K? record1, K? record2); + protected abstract int CompareSateliteTreeNode(K? record1, K? record2); protected RBTree(TreeAccessMethod accessMethod) { @@ -116,6 +116,8 @@ protected RBTree(TreeAccessMethod accessMethod) InitTree(); } + [MemberNotNull(nameof(_pageTable))] + [MemberNotNull(nameof(_pageTableMap))] private void InitTree() { root = NIL; @@ -337,7 +339,7 @@ public bool HasDuplicates * Use bitmap associated with page to allocate a slot. * mark the slot as used and return its index. */ - private int GetNewNode([AllowNull] K key) + private int GetNewNode(K? key) { // find page with free slots, if none, allocate a new page TreePage? page = null; @@ -1205,7 +1207,7 @@ private int RBDeleteFixup(int root_id, int x_id, int px_id /* px is parent of x return root_id; } - private int SearchSubTree(int root_id, [AllowNull] K key) + private int SearchSubTree(int root_id, K? key) { if (root_id != NIL && _accessMethod != TreeAccessMethod.KEY_SEARCH_AND_INDEX) { @@ -1556,7 +1558,7 @@ public int Insert(K item) // Begin: List of methods for making it easy to work with ArrayList - public int Add([AllowNull] K item) //Insert (int record) + public int Add(K? item) //Insert (int record) { int nodeId = GetNewNode(item); RBInsert(NIL, nodeId, NIL, -1, false); @@ -1875,8 +1877,7 @@ private struct Node internal int _parentId; internal int _nextId; // multiple records associated with same key internal int _subTreeSize; // number of nodes in subtree rooted at the current node - [AllowNull, MaybeNull] - internal K _keyOfNode; + internal K? _keyOfNode; internal NodeColor _nodeColor; } @@ -2042,8 +2043,7 @@ internal struct RBTreeEnumerator : IEnumerator, IEnumerator private readonly RBTree _tree; private readonly int _version; private int _index, _mainTreeNodeId; - [AllowNull, MaybeNull] - private K _current; + private K? _current; internal RBTreeEnumerator(RBTree tree) { diff --git a/src/libraries/System.Data.Common/src/System/Data/SortExpressionBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/SortExpressionBuilder.cs index 2889e2445b9c..c5304d94ef34 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SortExpressionBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SortExpressionBuilder.cs @@ -92,7 +92,7 @@ public List Select(T row) /// Note: Comparison is done in the order it was Added. /// /// Comparison result of the combined Sort comparer expression - public int Compare([AllowNull] List a, [AllowNull] List b) + public int Compare(List? a, List? b) { Debug.Assert(a != null && b != null && a.Count == Count); diff --git a/src/libraries/System.Data.Common/src/System/Data/TypedTableBaseExtensions.cs b/src/libraries/System.Data.Common/src/System/Data/TypedTableBaseExtensions.cs index 91535113670d..ccdd59352c9f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/TypedTableBaseExtensions.cs +++ b/src/libraries/System.Data.Common/src/System/Data/TypedTableBaseExtensions.cs @@ -92,8 +92,7 @@ public static EnumerableRowCollection AsEnumerable(this TypedTableBa return new EnumerableRowCollection(source as DataTable); } - [return: MaybeNull] - public static TRow ElementAtOrDefault(this TypedTableBase source, int index) where TRow : DataRow + public static TRow? ElementAtOrDefault(this TypedTableBase source, int index) where TRow : DataRow { if ((index >= 0) && (index < source.Rows.Count)) { diff --git a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs index 959cebbcfc51..0d5f4952a277 100644 --- a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs +++ b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs @@ -6,6 +6,7 @@ using System.Data.SqlTypes; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; @@ -2250,7 +2251,7 @@ internal sealed class NewDiffgramGen internal XmlWriter _xmlw = default!; // Late-initialized private bool _fBefore; private bool _fErrors; - internal Hashtable _rowsOrder = default!; // Always initialized in DoAssignments + internal Hashtable _rowsOrder; private readonly ArrayList _tables = new ArrayList(); private readonly bool _writeHierarchy; @@ -2297,7 +2298,7 @@ private void CreateTableHierarchy(DataTable dt) } } - + [MemberNotNull(nameof(_rowsOrder))] private void DoAssignments(ArrayList tables) { int rows = 0; diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs index 8cf24c84ed2f..02e526676ca3 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbReferenceCollection.cs @@ -133,8 +133,7 @@ protected void AddItem(object value, int tag) } } - [return: MaybeNull] - internal T FindItem(int tag, Func filterMethod) where T : class + internal T? FindItem(int tag, Func filterMethod) where T : class { bool lockObtained = false; try diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs index 029f9cd89536..95bb53f43ba8 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs @@ -25,7 +25,7 @@ public unsafe abstract partial class FileSystemEnumerator : CriticalFin private Queue? _pending; private Interop.Sys.DirectoryEntry _entry; - private TResult _current = default!; + private TResult? _current; // Used for creating full paths private char[]? _pathBuffer; diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs index 69084acc3d6b..32fd206ea897 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs @@ -31,7 +31,7 @@ public unsafe abstract partial class FileSystemEnumerator : CriticalFin private readonly object _lock = new object(); private Interop.NtDll.FILE_FULL_DIR_INFORMATION* _entry; - private TResult _current = default!; + private TResult? _current; private IntPtr _buffer; private int _bufferLength; diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.cs b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.cs index c3d4a978066c..b5168eb1ab05 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.cs @@ -69,7 +69,7 @@ protected virtual void OnDirectoryFinished(ReadOnlySpan directory) { } /// The native error code. protected virtual bool ContinueOnError(int error) => false; - public TResult Current => _current; + public TResult Current => _current!; object? IEnumerator.Current => Current; diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/Iterator.cs b/src/libraries/System.IO.FileSystem/src/System/IO/Iterator.cs index 49c4b4cfd378..09bf15d98a47 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/Iterator.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/Iterator.cs @@ -14,18 +14,14 @@ internal abstract class Iterator : IEnumerable, IEnumerator current!; protected abstract Iterator Clone(); @@ -37,7 +33,7 @@ public void Dispose() protected virtual void Dispose(bool disposing) { - current = default(TSource)!; + current = default; state = -1; } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs index 50b6cf2e1e30..9c9a3bddcc73 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs @@ -77,7 +77,7 @@ internal bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) return true; } - value = default(TValue)!; + value = default; return false; } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.cs index 7365e1025b29..c647214c170d 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.cs @@ -286,7 +286,7 @@ private MemberExpression CreateLazyInitializedField(string name) Debug.Assert(_method is DynamicMethod); #endif { - return Expression.Field(Expression.Constant(new StrongBox(default(T)!)), "Value"); + return Expression.Field(Expression.Constant(new StrongBox()), "Value"); } #if FEATURE_COMPILE_TO_METHODBUILDER else diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Utilities.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Utilities.cs index 618557728ce1..7b757e955d23 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Utilities.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Utilities.cs @@ -192,7 +192,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) } } } - value = default(TValue)!; + value = default; return false; } diff --git a/src/libraries/System.Linq.Parallel/ref/System.Linq.Parallel.cs b/src/libraries/System.Linq.Parallel/ref/System.Linq.Parallel.cs index 837bf534b8ba..e8ab5c078ef0 100644 --- a/src/libraries/System.Linq.Parallel/ref/System.Linq.Parallel.cs +++ b/src/libraries/System.Linq.Parallel/ref/System.Linq.Parallel.cs @@ -61,8 +61,7 @@ public static partial class ParallelEnumerable public static System.Linq.ParallelQuery DefaultIfEmpty(this System.Linq.ParallelQuery source, TSource defaultValue) { throw null; } public static System.Linq.ParallelQuery Distinct(this System.Linq.ParallelQuery source) { throw null; } public static System.Linq.ParallelQuery Distinct(this System.Linq.ParallelQuery source, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource ElementAtOrDefault(this System.Linq.ParallelQuery source, int index) { throw null; } + public static TSource? ElementAtOrDefault(this System.Linq.ParallelQuery source, int index) { throw null; } public static TSource ElementAt(this System.Linq.ParallelQuery source, int index) { throw null; } public static System.Linq.ParallelQuery Empty() { throw null; } [System.ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() extension method to convert the right data source to System.Linq.ParallelQuery.")] @@ -71,10 +70,8 @@ public static partial class ParallelEnumerable public static System.Linq.ParallelQuery Except(this System.Linq.ParallelQuery first, System.Collections.Generic.IEnumerable second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static System.Linq.ParallelQuery Except(this System.Linq.ParallelQuery first, System.Linq.ParallelQuery second) { throw null; } public static System.Linq.ParallelQuery Except(this System.Linq.ParallelQuery first, System.Linq.ParallelQuery second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource FirstOrDefault(this System.Linq.ParallelQuery source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource FirstOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } + public static TSource? FirstOrDefault(this System.Linq.ParallelQuery source) { throw null; } + public static TSource? FirstOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static TSource First(this System.Linq.ParallelQuery source) { throw null; } public static TSource First(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static void ForAll(this System.Linq.ParallelQuery source, System.Action action) { } @@ -104,10 +101,8 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static System.Linq.ParallelQuery Join(this System.Linq.ParallelQuery outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static System.Linq.ParallelQuery Join(this System.Linq.ParallelQuery outer, System.Linq.ParallelQuery inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector) { throw null; } public static System.Linq.ParallelQuery Join(this System.Linq.ParallelQuery outer, System.Linq.ParallelQuery inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource LastOrDefault(this System.Linq.ParallelQuery source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource LastOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } + public static TSource? LastOrDefault(this System.Linq.ParallelQuery source) { throw null; } + public static TSource? LastOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static TSource Last(this System.Linq.ParallelQuery source) { throw null; } public static TSource Last(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static long LongCount(this System.Linq.ParallelQuery source) { throw null; } @@ -122,8 +117,7 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static long? Max(this System.Linq.ParallelQuery source) { throw null; } public static float? Max(this System.Linq.ParallelQuery source) { throw null; } public static float Max(this System.Linq.ParallelQuery source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource Max(this System.Linq.ParallelQuery source) { throw null; } + public static TSource? Max(this System.Linq.ParallelQuery source) { throw null; } public static decimal Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static double Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static int Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } @@ -134,8 +128,7 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static long? Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static float? Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static float Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TResult Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } + public static TResult? Max(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static decimal Min(this System.Linq.ParallelQuery source) { throw null; } public static double Min(this System.Linq.ParallelQuery source) { throw null; } public static int Min(this System.Linq.ParallelQuery source) { throw null; } @@ -146,8 +139,7 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static long? Min(this System.Linq.ParallelQuery source) { throw null; } public static float? Min(this System.Linq.ParallelQuery source) { throw null; } public static float Min(this System.Linq.ParallelQuery source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource Min(this System.Linq.ParallelQuery source) { throw null; } + public static TSource? Min(this System.Linq.ParallelQuery source) { throw null; } public static decimal Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static double Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static int Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } @@ -158,8 +150,7 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static long? Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static float? Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static float Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TResult Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } + public static TResult? Min(this System.Linq.ParallelQuery source, System.Func selector) { throw null; } public static System.Linq.ParallelQuery OfType(this System.Linq.ParallelQuery source) { throw null; } public static System.Linq.OrderedParallelQuery OrderByDescending(this System.Linq.ParallelQuery source, System.Func keySelector) { throw null; } public static System.Linq.OrderedParallelQuery OrderByDescending(this System.Linq.ParallelQuery source, System.Func keySelector, System.Collections.Generic.IComparer? comparer) { throw null; } @@ -180,10 +171,8 @@ public static void ForAll(this System.Linq.ParallelQuery sourc public static bool SequenceEqual(this System.Linq.ParallelQuery first, System.Collections.Generic.IEnumerable second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static bool SequenceEqual(this System.Linq.ParallelQuery first, System.Linq.ParallelQuery second) { throw null; } public static bool SequenceEqual(this System.Linq.ParallelQuery first, System.Linq.ParallelQuery second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource SingleOrDefault(this System.Linq.ParallelQuery source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource SingleOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } + public static TSource? SingleOrDefault(this System.Linq.ParallelQuery source) { throw null; } + public static TSource? SingleOrDefault(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static TSource Single(this System.Linq.ParallelQuery source) { throw null; } public static TSource Single(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } public static System.Linq.ParallelQuery SkipWhile(this System.Linq.ParallelQuery source, System.Func predicate) { throw null; } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs index 7a5fa88fdeeb..746c1a5b7496 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs @@ -20,8 +20,7 @@ internal static class AggregationMinMaxHelpers // Helper method to find the minimum or maximum element in the source. // - [return: MaybeNull] - private static T Reduce(IEnumerable source, int sign) + private static T? Reduce(IEnumerable source, int sign) { Debug.Assert(source != null); Debug.Assert(sign == -1 || sign == 1); @@ -41,8 +40,7 @@ private static T Reduce(IEnumerable source, int sign) // Helper method to find the minimum element in the source. // - [return: MaybeNull] - internal static T ReduceMin(IEnumerable source) + internal static T? ReduceMin(IEnumerable source) { return Reduce(source, -1); } @@ -51,8 +49,7 @@ internal static T ReduceMin(IEnumerable source) // Helper method to find the maximum element in the source. // - [return: MaybeNull] - internal static T ReduceMax(IEnumerable source) + internal static T? ReduceMax(IEnumerable source) { return Reduce(source, 1); } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs index 4ad52acb8060..d4e21e184902 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs @@ -56,7 +56,7 @@ public override IEnumerator GetEnumerator() } } - internal class EmptyEnumerator : QueryOperatorEnumerator, IEnumerator + internal sealed class EmptyEnumerator : QueryOperatorEnumerator, IEnumerator { internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref T currentElement, ref int currentKey) { diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Helpers.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Helpers.cs index 746887d4965e..54494258c2ed 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Helpers.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Helpers.cs @@ -133,7 +133,7 @@ internal struct Slot { internal int hashCode; internal int next; - [MaybeNull, AllowNull] internal TElement value; + internal TElement? value; } } } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs index e741ac506b35..3432a14aef67 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs @@ -32,7 +32,7 @@ internal sealed class AsynchronousChannelMergeEnumerator : MergeEnumerator private IntValueEvent? _consumerEvent; // The consumer event. private readonly bool[] _done; // Tracks which channels are done. private int _channelIndex; // The next channel from which we'll dequeue. - [MaybeNull, AllowNull] private T _currentElement = default; // The remembered element from the previous MoveNext. + private T? _currentElement; // The remembered element from the previous MoveNext. //----------------------------------------------------------------------------------- // Allocates a new enumerator over a set of one-to-one channels. diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs index bb0c023d9554..ba10ef686462 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs @@ -24,7 +24,7 @@ internal sealed class SynchronousChannelMergeEnumerator : MergeEnumerator { private readonly SynchronousChannel[] _channels; // The channel array we will enumerate, from left-to-right. private int _channelIndex; // The current channel index. This moves through the array as we enumerate. - private T _currentElement = default!; // The last element remembered during enumeration. + private T? _currentElement; // The last element remembered during enumeration. //----------------------------------------------------------------------------------- // Instantiates a new enumerator for a set of channels. @@ -61,7 +61,7 @@ public override T Current throw new InvalidOperationException(SR.PLINQ_CommonEnumerator_Current_NotStarted); } - return _currentElement; + return _currentElement!; } } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Binary/ConcatQueryOperator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Binary/ConcatQueryOperator.cs index faa7e1afb76d..f6b4b72099dc 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Binary/ConcatQueryOperator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Binary/ConcatQueryOperator.cs @@ -296,10 +296,8 @@ internal override TSource GetElement(int index) internal struct ConcatKey { - [MaybeNull, AllowNull] - private readonly TLeftKey _leftKey; - [MaybeNull, AllowNull] - private readonly TRightKey _rightKey; + private readonly TLeftKey? _leftKey; + private readonly TRightKey? _rightKey; private readonly bool _isLeft; private ConcatKey([AllowNull] TLeftKey leftKey, [AllowNull] TRightKey rightKey, bool isLeft) diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Utils/ReverseComparer.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Utils/ReverseComparer.cs index f949814c9c59..229b5244acb1 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Utils/ReverseComparer.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Utils/ReverseComparer.cs @@ -26,7 +26,7 @@ internal ReverseComparer(IComparer comparer) _comparer = comparer; } - public int Compare([AllowNull] T x, [AllowNull] T y) + public int Compare(T? x, T? y) { return _comparer.Compare(y, x); } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs index 17a378e80377..f4f870c31642 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs @@ -2659,8 +2659,7 @@ public static decimal Min(this ParallelQuery source) /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource Min(this ParallelQuery source) + public static TSource? Min(this ParallelQuery source) { if (source == null) throw new ArgumentNullException(nameof(source)); return AggregationMinMaxHelpers.ReduceMin(source); @@ -2922,8 +2921,7 @@ public static decimal Min(this ParallelQuery source, Func /// The query was canceled. /// - [return: MaybeNull] - public static TResult Min(this ParallelQuery source, Func selector) + public static TResult? Min(this ParallelQuery source, Func selector) { return source.Select(selector).Min(); } @@ -3164,8 +3162,7 @@ public static decimal Max(this ParallelQuery source) /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource Max(this ParallelQuery source) + public static TSource? Max(this ParallelQuery source) { if (source == null) throw new ArgumentNullException(nameof(source)); return AggregationMinMaxHelpers.ReduceMax(source); @@ -3427,8 +3424,7 @@ public static decimal Max(this ParallelQuery source, Func /// The query was canceled. /// - [return: MaybeNull] - public static TResult Max(this ParallelQuery source, Func selector) + public static TResult? Max(this ParallelQuery source, Func selector) { return source.Select(selector).Max(); } @@ -5289,8 +5285,7 @@ public static ParallelQuery Cast(this ParallelQuery source) // defaultIfEmpty - whether to return a default value (true) or throw an // exception if the output of the query operator is empty // - [return: MaybeNull] - private static TSource GetOneWithPossibleDefault( + private static TSource? GetOneWithPossibleDefault( QueryOperator queryOp, bool throwIfTwo, bool defaultIfEmpty) { Debug.Assert(queryOp != null, "expected query operator"); @@ -5321,7 +5316,7 @@ private static TSource GetOneWithPossibleDefault( if (defaultIfEmpty) { - return default(TSource)!; + return default; } else { @@ -5436,8 +5431,7 @@ public static TSource First(this ParallelQuery source, Func /// The query was canceled. /// - [return: MaybeNull] - public static TSource FirstOrDefault(this ParallelQuery source) + public static TSource? FirstOrDefault(this ParallelQuery source) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -5483,8 +5477,7 @@ public static TSource FirstOrDefault(this ParallelQuery source /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource FirstOrDefault(this ParallelQuery source, Func predicate) + public static TSource? FirstOrDefault(this ParallelQuery source, Func predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); @@ -5616,8 +5609,7 @@ public static TSource Last(this ParallelQuery source, Func /// The query was canceled. /// - [return: MaybeNull] - public static TSource LastOrDefault(this ParallelQuery source) + public static TSource? LastOrDefault(this ParallelQuery source) { // @PERF: optimize for seekable data sources. E.g. if an array, we can // seek directly to the last element. @@ -5659,8 +5651,7 @@ public static TSource LastOrDefault(this ParallelQuery source) /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource LastOrDefault(this ParallelQuery source, Func predicate) + public static TSource? LastOrDefault(this ParallelQuery source, Func predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); @@ -5764,8 +5755,7 @@ public static TSource Single(this ParallelQuery source, Func /// The query was canceled. /// - [return: MaybeNull] - public static TSource SingleOrDefault(this ParallelQuery source) + public static TSource? SingleOrDefault(this ParallelQuery source) { // @PERF: optimize for ICollection-typed data sources, i.e. we can just // check the Count property and avoid costly fork/join/synchronization. @@ -5795,8 +5785,7 @@ public static TSource SingleOrDefault(this ParallelQuery sourc /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource SingleOrDefault(this ParallelQuery source, Func predicate) + public static TSource? SingleOrDefault(this ParallelQuery source, Func predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); @@ -5821,9 +5810,9 @@ public static TSource SingleOrDefault(this ParallelQuery sourc /// /// is a null reference (Nothing in Visual Basic). /// - public static ParallelQuery DefaultIfEmpty(this ParallelQuery source) + public static ParallelQuery DefaultIfEmpty(this ParallelQuery source) { - return DefaultIfEmpty(source, default!); + return DefaultIfEmpty(source, default!)!; } /// @@ -5909,8 +5898,7 @@ public static TSource ElementAt(this ParallelQuery source, int /// /// The query was canceled. /// - [return: MaybeNull] - public static TSource ElementAtOrDefault(this ParallelQuery source, int index) + public static TSource? ElementAtOrDefault(this ParallelQuery source, int index) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -5928,7 +5916,7 @@ public static TSource ElementAtOrDefault(this ParallelQuery so } } - return default(TSource)!; + return default; } } } diff --git a/src/libraries/System.Linq.Queryable/ref/System.Linq.Queryable.cs b/src/libraries/System.Linq.Queryable/ref/System.Linq.Queryable.cs index 91d264afdb8b..c3253aada63a 100644 --- a/src/libraries/System.Linq.Queryable/ref/System.Linq.Queryable.cs +++ b/src/libraries/System.Linq.Queryable/ref/System.Linq.Queryable.cs @@ -74,15 +74,12 @@ public static partial class Queryable public static System.Linq.IQueryable DefaultIfEmpty(this System.Linq.IQueryable source, TSource defaultValue) { throw null; } public static System.Linq.IQueryable Distinct(this System.Linq.IQueryable source) { throw null; } public static System.Linq.IQueryable Distinct(this System.Linq.IQueryable source, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource ElementAtOrDefault(this System.Linq.IQueryable source, int index) { throw null; } + public static TSource? ElementAtOrDefault(this System.Linq.IQueryable source, int index) { throw null; } public static TSource ElementAt(this System.Linq.IQueryable source, int index) { throw null; } public static System.Linq.IQueryable Except(this System.Linq.IQueryable source1, System.Collections.Generic.IEnumerable source2) { throw null; } public static System.Linq.IQueryable Except(this System.Linq.IQueryable source1, System.Collections.Generic.IEnumerable source2, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource FirstOrDefault(this System.Linq.IQueryable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource FirstOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } + public static TSource? FirstOrDefault(this System.Linq.IQueryable source) { throw null; } + public static TSource? FirstOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static TSource First(this System.Linq.IQueryable source) { throw null; } public static TSource First(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static System.Linq.IQueryable> GroupBy(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> keySelector) { throw null; } @@ -99,22 +96,16 @@ public static partial class Queryable public static System.Linq.IQueryable Intersect(this System.Linq.IQueryable source1, System.Collections.Generic.IEnumerable source2, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static System.Linq.IQueryable Join(this System.Linq.IQueryable outer, System.Collections.Generic.IEnumerable inner, System.Linq.Expressions.Expression> outerKeySelector, System.Linq.Expressions.Expression> innerKeySelector, System.Linq.Expressions.Expression> resultSelector) { throw null; } public static System.Linq.IQueryable Join(this System.Linq.IQueryable outer, System.Collections.Generic.IEnumerable inner, System.Linq.Expressions.Expression> outerKeySelector, System.Linq.Expressions.Expression> innerKeySelector, System.Linq.Expressions.Expression> resultSelector, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource LastOrDefault(this System.Linq.IQueryable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource LastOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } + public static TSource? LastOrDefault(this System.Linq.IQueryable source) { throw null; } + public static TSource? LastOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static TSource Last(this System.Linq.IQueryable source) { throw null; } public static TSource Last(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static long LongCount(this System.Linq.IQueryable source) { throw null; } public static long LongCount(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource Max(this System.Linq.IQueryable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TResult Max(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> selector) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource Min(this System.Linq.IQueryable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TResult Min(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> selector) { throw null; } + public static TSource? Max(this System.Linq.IQueryable source) { throw null; } + public static TResult? Max(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> selector) { throw null; } + public static TSource? Min(this System.Linq.IQueryable source) { throw null; } + public static TResult? Min(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> selector) { throw null; } public static System.Linq.IQueryable OfType(this System.Linq.IQueryable source) { throw null; } public static System.Linq.IOrderedQueryable OrderByDescending(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> keySelector) { throw null; } public static System.Linq.IOrderedQueryable OrderByDescending(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> keySelector, System.Collections.Generic.IComparer? comparer) { throw null; } @@ -130,10 +121,8 @@ public static partial class Queryable public static System.Linq.IQueryable Select(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> selector) { throw null; } public static bool SequenceEqual(this System.Linq.IQueryable source1, System.Collections.Generic.IEnumerable source2) { throw null; } public static bool SequenceEqual(this System.Linq.IQueryable source1, System.Collections.Generic.IEnumerable source2, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource SingleOrDefault(this System.Linq.IQueryable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TSource SingleOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } + public static TSource? SingleOrDefault(this System.Linq.IQueryable source) { throw null; } + public static TSource? SingleOrDefault(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static TSource Single(this System.Linq.IQueryable source) { throw null; } public static TSource Single(this System.Linq.IQueryable source, System.Linq.Expressions.Expression> predicate) { throw null; } public static System.Linq.IQueryable SkipLast(this System.Linq.IQueryable source, int count) { throw null; } diff --git a/src/libraries/System.Linq.Queryable/src/System/Linq/CachedReflection.cs b/src/libraries/System.Linq.Queryable/src/System/Linq/CachedReflection.cs index 91e37ff906b2..8f345d0a86bb 100644 --- a/src/libraries/System.Linq.Queryable/src/System/Linq/CachedReflection.cs +++ b/src/libraries/System.Linq.Queryable/src/System/Linq/CachedReflection.cs @@ -262,7 +262,7 @@ public static MethodInfo ElementAt_TSource_2(Type TSource) => public static MethodInfo ElementAtOrDefault_TSource_2(Type TSource) => (s_ElementAtOrDefault_TSource_2 ?? - (s_ElementAtOrDefault_TSource_2 = new Func, int, object>(Queryable.ElementAtOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_ElementAtOrDefault_TSource_2 = new Func, int, object?>(Queryable.ElementAtOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_Except_TSource_2; @@ -297,14 +297,14 @@ public static MethodInfo First_TSource_2(Type TSource) => public static MethodInfo FirstOrDefault_TSource_1(Type TSource) => (s_FirstOrDefault_TSource_1 ?? - (s_FirstOrDefault_TSource_1 = new Func, object>(Queryable.FirstOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_FirstOrDefault_TSource_1 = new Func, object?>(Queryable.FirstOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_FirstOrDefault_TSource_2; public static MethodInfo FirstOrDefault_TSource_2(Type TSource) => (s_FirstOrDefault_TSource_2 ?? - (s_FirstOrDefault_TSource_2 = new Func, Expression>, object>(Queryable.FirstOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_FirstOrDefault_TSource_2 = new Func, Expression>, object?>(Queryable.FirstOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_GroupBy_TSource_TKey_2; @@ -423,14 +423,14 @@ public static MethodInfo Last_TSource_2(Type TSource) => public static MethodInfo LastOrDefault_TSource_1(Type TSource) => (s_LastOrDefault_TSource_1 ?? - (s_LastOrDefault_TSource_1 = new Func, object>(Queryable.LastOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_LastOrDefault_TSource_1 = new Func, object?>(Queryable.LastOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_LastOrDefault_TSource_2; public static MethodInfo LastOrDefault_TSource_2(Type TSource) => (s_LastOrDefault_TSource_2 ?? - (s_LastOrDefault_TSource_2 = new Func, Expression>, object>(Queryable.LastOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_LastOrDefault_TSource_2 = new Func, Expression>, object?>(Queryable.LastOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_LongCount_TSource_1; @@ -451,28 +451,28 @@ public static MethodInfo LongCount_TSource_2(Type TSource) => public static MethodInfo Max_TSource_1(Type TSource) => (s_Max_TSource_1 ?? - (s_Max_TSource_1 = new Func, object>(Queryable.Max).GetMethodInfo().GetGenericMethodDefinition())) + (s_Max_TSource_1 = new Func, object?>(Queryable.Max).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_Max_TSource_TResult_2; public static MethodInfo Max_TSource_TResult_2(Type TSource, Type TResult) => (s_Max_TSource_TResult_2 ?? - (s_Max_TSource_TResult_2 = new Func, Expression>, object>(Queryable.Max).GetMethodInfo().GetGenericMethodDefinition())) + (s_Max_TSource_TResult_2 = new Func, Expression>, object?>(Queryable.Max).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource, TResult); private static MethodInfo? s_Min_TSource_1; public static MethodInfo Min_TSource_1(Type TSource) => (s_Min_TSource_1 ?? - (s_Min_TSource_1 = new Func, object>(Queryable.Min).GetMethodInfo().GetGenericMethodDefinition())) + (s_Min_TSource_1 = new Func, object?>(Queryable.Min).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_Min_TSource_TResult_2; public static MethodInfo Min_TSource_TResult_2(Type TSource, Type TResult) => (s_Min_TSource_TResult_2 ?? - (s_Min_TSource_TResult_2 = new Func, Expression>, object>(Queryable.Min).GetMethodInfo().GetGenericMethodDefinition())) + (s_Min_TSource_TResult_2 = new Func, Expression>, object?>(Queryable.Min).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource, TResult); private static MethodInfo? s_OfType_TResult_1; @@ -591,14 +591,14 @@ public static MethodInfo Single_TSource_2(Type TSource) => public static MethodInfo SingleOrDefault_TSource_1(Type TSource) => (s_SingleOrDefault_TSource_1 ?? - (s_SingleOrDefault_TSource_1 = new Func, object>(Queryable.SingleOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_SingleOrDefault_TSource_1 = new Func, object?>(Queryable.SingleOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_SingleOrDefault_TSource_2; public static MethodInfo SingleOrDefault_TSource_2(Type TSource) => (s_SingleOrDefault_TSource_2 ?? - (s_SingleOrDefault_TSource_2 = new Func, Expression>, object>(Queryable.SingleOrDefault).GetMethodInfo().GetGenericMethodDefinition())) + (s_SingleOrDefault_TSource_2 = new Func, Expression>, object?>(Queryable.SingleOrDefault).GetMethodInfo().GetGenericMethodDefinition())) .MakeGenericMethod(TSource); private static MethodInfo? s_Skip_TSource_2; diff --git a/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs b/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs index e3ed64c4f191..902474b9eedf 100644 --- a/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs +++ b/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs @@ -740,8 +740,7 @@ public static TSource First(this IQueryable source, Expression )); } - [return: MaybeNull] - public static TSource FirstOrDefault(this IQueryable source) + public static TSource? FirstOrDefault(this IQueryable source) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -751,8 +750,7 @@ public static TSource FirstOrDefault(this IQueryable source) CachedReflectionInfo.FirstOrDefault_TSource_1(typeof(TSource)), source.Expression)); } - [return: MaybeNull] - public static TSource FirstOrDefault(this IQueryable source, Expression> predicate) + public static TSource? FirstOrDefault(this IQueryable source, Expression> predicate) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -790,8 +788,7 @@ public static TSource Last(this IQueryable source, Expression< )); } - [return: MaybeNull] - public static TSource LastOrDefault(this IQueryable source) + public static TSource? LastOrDefault(this IQueryable source) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -801,8 +798,7 @@ public static TSource LastOrDefault(this IQueryable source) CachedReflectionInfo.LastOrDefault_TSource_1(typeof(TSource)), source.Expression)); } - [return: MaybeNull] - public static TSource LastOrDefault(this IQueryable source, Expression> predicate) + public static TSource? LastOrDefault(this IQueryable source, Expression> predicate) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -840,8 +836,7 @@ public static TSource Single(this IQueryable source, Expressio )); } - [return: MaybeNull] - public static TSource SingleOrDefault(this IQueryable source) + public static TSource? SingleOrDefault(this IQueryable source) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -851,8 +846,7 @@ public static TSource SingleOrDefault(this IQueryable source) CachedReflectionInfo.SingleOrDefault_TSource_1(typeof(TSource)), source.Expression)); } - [return: MaybeNull] - public static TSource SingleOrDefault(this IQueryable source, Expression> predicate) + public static TSource? SingleOrDefault(this IQueryable source, Expression> predicate) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -880,8 +874,7 @@ public static TSource ElementAt(this IQueryable source, int in )); } - [return: MaybeNull] - public static TSource ElementAtOrDefault(this IQueryable source, int index) + public static TSource? ElementAtOrDefault(this IQueryable source, int index) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -1065,8 +1058,7 @@ public static long LongCount(this IQueryable source, Expressio )); } - [return: MaybeNull] - public static TSource Min(this IQueryable source) + public static TSource? Min(this IQueryable source) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -1076,8 +1068,7 @@ public static TSource Min(this IQueryable source) CachedReflectionInfo.Min_TSource_1(typeof(TSource)), source.Expression)); } - [return: MaybeNull] - public static TResult Min(this IQueryable source, Expression> selector) + public static TResult? Min(this IQueryable source, Expression> selector) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -1091,8 +1082,7 @@ public static TResult Min(this IQueryable source, Exp )); } - [return: MaybeNull] - public static TSource Max(this IQueryable source) + public static TSource? Max(this IQueryable source) { if (source == null) throw Error.ArgumentNull(nameof(source)); @@ -1102,8 +1092,7 @@ public static TSource Max(this IQueryable source) CachedReflectionInfo.Max_TSource_1(typeof(TSource)), source.Expression)); } - [return: MaybeNull] - public static TResult Max(this IQueryable source, Expression> selector) + public static TResult? Max(this IQueryable source, Expression> selector) { if (source == null) throw Error.ArgumentNull(nameof(source)); diff --git a/src/libraries/System.Linq/ref/System.Linq.cs b/src/libraries/System.Linq/ref/System.Linq.cs index bf41a28033ca..91d5432e2b5a 100644 --- a/src/libraries/System.Linq/ref/System.Linq.cs +++ b/src/libraries/System.Linq/ref/System.Linq.cs @@ -42,17 +42,17 @@ public static partial class Enumerable public static bool Contains(this System.Collections.Generic.IEnumerable source, TSource value, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static int Count(this System.Collections.Generic.IEnumerable source) { throw null; } public static int Count(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } - public static System.Collections.Generic.IEnumerable DefaultIfEmpty(this System.Collections.Generic.IEnumerable source) { throw null; } + public static System.Collections.Generic.IEnumerable DefaultIfEmpty(this System.Collections.Generic.IEnumerable source) { throw null; } public static System.Collections.Generic.IEnumerable DefaultIfEmpty(this System.Collections.Generic.IEnumerable source, TSource defaultValue) { throw null; } public static System.Collections.Generic.IEnumerable Distinct(this System.Collections.Generic.IEnumerable source) { throw null; } public static System.Collections.Generic.IEnumerable Distinct(this System.Collections.Generic.IEnumerable source, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource ElementAtOrDefault(this System.Collections.Generic.IEnumerable source, int index) { throw null; } + public static TSource? ElementAtOrDefault(this System.Collections.Generic.IEnumerable source, int index) { throw null; } public static TSource ElementAt(this System.Collections.Generic.IEnumerable source, int index) { throw null; } public static System.Collections.Generic.IEnumerable Empty() { throw null; } public static System.Collections.Generic.IEnumerable Except(this System.Collections.Generic.IEnumerable first, System.Collections.Generic.IEnumerable second) { throw null; } public static System.Collections.Generic.IEnumerable Except(this System.Collections.Generic.IEnumerable first, System.Collections.Generic.IEnumerable second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource FirstOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource FirstOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } + public static TSource? FirstOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } + public static TSource? FirstOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static TSource First(this System.Collections.Generic.IEnumerable source) { throw null; } public static TSource First(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static System.Collections.Generic.IEnumerable> GroupBy(this System.Collections.Generic.IEnumerable source, System.Func keySelector) { throw null; } @@ -69,8 +69,8 @@ public static partial class Enumerable public static System.Collections.Generic.IEnumerable Intersect(this System.Collections.Generic.IEnumerable first, System.Collections.Generic.IEnumerable second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } public static System.Collections.Generic.IEnumerable Join(this System.Collections.Generic.IEnumerable outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector) { throw null; } public static System.Collections.Generic.IEnumerable Join(this System.Collections.Generic.IEnumerable outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource LastOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource LastOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } + public static TSource? LastOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } + public static TSource? LastOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static TSource Last(this System.Collections.Generic.IEnumerable source) { throw null; } public static TSource Last(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static long LongCount(this System.Collections.Generic.IEnumerable source) { throw null; } @@ -85,7 +85,7 @@ public static partial class Enumerable public static long? Max(this System.Collections.Generic.IEnumerable source) { throw null; } public static float? Max(this System.Collections.Generic.IEnumerable source) { throw null; } public static float Max(this System.Collections.Generic.IEnumerable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource Max(this System.Collections.Generic.IEnumerable source) { throw null; } + public static TSource? Max(this System.Collections.Generic.IEnumerable source) { throw null; } public static decimal Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static double Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static int Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } @@ -96,7 +96,7 @@ public static partial class Enumerable public static long? Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static float? Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static float Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TResult Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } + public static TResult? Max(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static decimal Min(this System.Collections.Generic.IEnumerable source) { throw null; } public static double Min(this System.Collections.Generic.IEnumerable source) { throw null; } public static int Min(this System.Collections.Generic.IEnumerable source) { throw null; } @@ -107,7 +107,7 @@ public static partial class Enumerable public static long? Min(this System.Collections.Generic.IEnumerable source) { throw null; } public static float? Min(this System.Collections.Generic.IEnumerable source) { throw null; } public static float Min(this System.Collections.Generic.IEnumerable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource Min(this System.Collections.Generic.IEnumerable source) { throw null; } + public static TSource? Min(this System.Collections.Generic.IEnumerable source) { throw null; } public static decimal Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static double Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static int Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } @@ -118,7 +118,7 @@ public static partial class Enumerable public static long? Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static float? Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static float Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TResult Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } + public static TResult? Min(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static System.Collections.Generic.IEnumerable OfType(this System.Collections.IEnumerable source) { throw null; } public static System.Linq.IOrderedEnumerable OrderByDescending(this System.Collections.Generic.IEnumerable source, System.Func keySelector) { throw null; } public static System.Linq.IOrderedEnumerable OrderByDescending(this System.Collections.Generic.IEnumerable source, System.Func keySelector, System.Collections.Generic.IComparer? comparer) { throw null; } @@ -136,8 +136,8 @@ public static partial class Enumerable public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) { throw null; } public static bool SequenceEqual(this System.Collections.Generic.IEnumerable first, System.Collections.Generic.IEnumerable second) { throw null; } public static bool SequenceEqual(this System.Collections.Generic.IEnumerable first, System.Collections.Generic.IEnumerable second, System.Collections.Generic.IEqualityComparer? comparer) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource SingleOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public static TSource SingleOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } + public static TSource? SingleOrDefault(this System.Collections.Generic.IEnumerable source) { throw null; } + public static TSource? SingleOrDefault(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static TSource Single(this System.Collections.Generic.IEnumerable source) { throw null; } public static TSource Single(this System.Collections.Generic.IEnumerable source, System.Func predicate) { throw null; } public static System.Collections.Generic.IEnumerable SkipLast(this System.Collections.Generic.IEnumerable source, int count) { throw null; } diff --git a/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs b/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs index e358538081c0..a513a6eb7fe3 100644 --- a/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs +++ b/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs @@ -8,7 +8,7 @@ namespace System.Linq { public static partial class Enumerable { - public static IEnumerable DefaultIfEmpty(this IEnumerable source) => + public static IEnumerable DefaultIfEmpty(this IEnumerable source) => DefaultIfEmpty(source, default!); public static IEnumerable DefaultIfEmpty(this IEnumerable source, TSource defaultValue) diff --git a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs index a857819b290d..da8dc8f92876 100644 --- a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs +++ b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs @@ -51,8 +51,7 @@ public static TSource ElementAt(this IEnumerable source, int i return default; } - [return: MaybeNull] - public static TSource ElementAtOrDefault(this IEnumerable source, int index) + public static TSource? ElementAtOrDefault(this IEnumerable source, int index) { if (source == null) { @@ -90,7 +89,7 @@ public static TSource ElementAtOrDefault(this IEnumerable sour } } - return default!; + return default; } } } diff --git a/src/libraries/System.Linq/src/System/Linq/First.cs b/src/libraries/System.Linq/src/System/Linq/First.cs index 6ebeb804463f..295acb5e4d41 100644 --- a/src/libraries/System.Linq/src/System/Linq/First.cs +++ b/src/libraries/System.Linq/src/System/Linq/First.cs @@ -30,16 +30,13 @@ public static TSource First(this IEnumerable source, Func(this IEnumerable source) => + public static TSource? FirstOrDefault(this IEnumerable source) => source.TryGetFirst(out bool _); - [return: MaybeNull] - public static TSource FirstOrDefault(this IEnumerable source, Func predicate) => + public static TSource? FirstOrDefault(this IEnumerable source, Func predicate) => source.TryGetFirst(predicate, out bool _); - [return: MaybeNull] - private static TSource TryGetFirst(this IEnumerable source, out bool found) + private static TSource? TryGetFirst(this IEnumerable source, out bool found) { if (source == null) { @@ -72,11 +69,10 @@ private static TSource TryGetFirst(this IEnumerable source, ou } found = false; - return default!; + return default; } - [return: MaybeNull] - private static TSource TryGetFirst(this IEnumerable source, Func predicate, out bool found) + private static TSource? TryGetFirst(this IEnumerable source, Func predicate, out bool found) { if (source == null) { @@ -98,7 +94,7 @@ private static TSource TryGetFirst(this IEnumerable source, Fu } found = false; - return default!; + return default; } } } diff --git a/src/libraries/System.Linq/src/System/Linq/IPartition.cs b/src/libraries/System.Linq/src/System/Linq/IPartition.cs index d1c5e2e102b7..68b676f0948f 100644 --- a/src/libraries/System.Linq/src/System/Linq/IPartition.cs +++ b/src/libraries/System.Linq/src/System/Linq/IPartition.cs @@ -30,23 +30,20 @@ internal interface IPartition : IIListProvider /// The 0-based index to access. /// true if the sequence contains an element at that index, false otherwise. /// The element if is true, otherwise, the default value of . - [return: MaybeNull] - TElement TryGetElementAt(int index, out bool found); + TElement? TryGetElementAt(int index, out bool found); /// /// Gets the first item in this sequence. /// /// true if the sequence contains an element, false otherwise. /// The element if is true, otherwise, the default value of . - [return: MaybeNull] - TElement TryGetFirst(out bool found); + TElement? TryGetFirst(out bool found); /// /// Gets the last item in this sequence. /// /// true if the sequence contains an element, false otherwise. /// The element if is true, otherwise, the default value of . - [return: MaybeNull] - TElement TryGetLast(out bool found); + TElement? TryGetLast(out bool found); } } diff --git a/src/libraries/System.Linq/src/System/Linq/Last.cs b/src/libraries/System.Linq/src/System/Linq/Last.cs index d08bbf96682f..d7819614ab07 100644 --- a/src/libraries/System.Linq/src/System/Linq/Last.cs +++ b/src/libraries/System.Linq/src/System/Linq/Last.cs @@ -30,16 +30,13 @@ public static TSource Last(this IEnumerable source, Func(this IEnumerable source) => + public static TSource? LastOrDefault(this IEnumerable source) => source.TryGetLast(out bool _); - [return: MaybeNull] - public static TSource LastOrDefault(this IEnumerable source, Func predicate) => + public static TSource? LastOrDefault(this IEnumerable source, Func predicate) => source.TryGetLast(predicate, out bool _); - [return: MaybeNull] - private static TSource TryGetLast(this IEnumerable source, out bool found) + private static TSource? TryGetLast(this IEnumerable source, out bool found) { if (source == null) { @@ -80,11 +77,10 @@ private static TSource TryGetLast(this IEnumerable source, out } found = false; - return default!; + return default; } - [return: MaybeNull] - private static TSource TryGetLast(this IEnumerable source, Func predicate, out bool found) + private static TSource? TryGetLast(this IEnumerable source, Func predicate, out bool found) { if (source == null) { @@ -139,7 +135,7 @@ private static TSource TryGetLast(this IEnumerable source, Fun } found = false; - return default!; + return default; } } } diff --git a/src/libraries/System.Linq/src/System/Linq/Max.cs b/src/libraries/System.Linq/src/System/Linq/Max.cs index 21e1f8d890bf..9dc4c92cd1f8 100644 --- a/src/libraries/System.Linq/src/System/Linq/Max.cs +++ b/src/libraries/System.Linq/src/System/Linq/Max.cs @@ -441,8 +441,7 @@ public static decimal Max(this IEnumerable source) return value; } - [return: MaybeNull] - public static TSource Max(this IEnumerable source) + public static TSource? Max(this IEnumerable source) { if (source == null) { @@ -450,7 +449,7 @@ public static TSource Max(this IEnumerable source) } Comparer comparer = Comparer.Default; - TSource value = default!; + TSource? value = default; if (value == null) { using (IEnumerator e = source.GetEnumerator()) @@ -983,8 +982,7 @@ public static decimal Max(this IEnumerable source, Func(this IEnumerable source, Func selector) + public static TResult? Max(this IEnumerable source, Func selector) { if (source == null) { @@ -997,7 +995,7 @@ public static TResult Max(this IEnumerable source, Fu } Comparer comparer = Comparer.Default; - TResult value = default!; + TResult? value = default; if (value == null) { using (IEnumerator e = source.GetEnumerator()) diff --git a/src/libraries/System.Linq/src/System/Linq/Min.cs b/src/libraries/System.Linq/src/System/Linq/Min.cs index b3a7e62d5b7f..9958c8468bec 100644 --- a/src/libraries/System.Linq/src/System/Linq/Min.cs +++ b/src/libraries/System.Linq/src/System/Linq/Min.cs @@ -399,8 +399,7 @@ public static decimal Min(this IEnumerable source) return value; } - [return: MaybeNull] - public static TSource Min(this IEnumerable source) + public static TSource? Min(this IEnumerable source) { if (source == null) { @@ -408,7 +407,7 @@ public static TSource Min(this IEnumerable source) } Comparer comparer = Comparer.Default; - TSource value = default!; + TSource? value = default; if (value == null) { using (IEnumerator e = source.GetEnumerator()) @@ -899,8 +898,7 @@ public static decimal Min(this IEnumerable source, Func(this IEnumerable source, Func selector) + public static TResult? Min(this IEnumerable source, Func selector) { if (source == null) { @@ -913,7 +911,7 @@ public static TResult Min(this IEnumerable source, Fu } Comparer comparer = Comparer.Default; - TResult value = default!; + TResult? value = default; if (value == null) { using (IEnumerator e = source.GetEnumerator()) diff --git a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs index 5d3946e14299..b90dbf28a953 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs @@ -138,8 +138,7 @@ internal int GetCount(int minIdx, int maxIdx, bool onlyIfCheap) public IPartition Take(int count) => new OrderedPartition(this, 0, count - 1); - [return: MaybeNull] - public TElement TryGetElementAt(int index, out bool found) + public TElement? TryGetElementAt(int index, out bool found) { if (index == 0) { @@ -158,11 +157,10 @@ public TElement TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TElement TryGetFirst(out bool found) + public TElement? TryGetFirst(out bool found) { CachingComparer comparer = GetComparer(); using (IEnumerator e = _source.GetEnumerator()) @@ -170,7 +168,7 @@ public TElement TryGetFirst(out bool found) if (!e.MoveNext()) { found = false; - return default!; + return default; } TElement value = e.Current; @@ -189,15 +187,14 @@ public TElement TryGetFirst(out bool found) } } - [return: MaybeNull] - public TElement TryGetLast(out bool found) + public TElement? TryGetLast(out bool found) { using (IEnumerator e = _source.GetEnumerator()) { if (!e.MoveNext()) { found = false; - return default!; + return default; } CachingComparer comparer = GetComparer(); @@ -217,15 +214,14 @@ public TElement TryGetLast(out bool found) } } - [return: MaybeNull] - public TElement TryGetLast(int minIdx, int maxIdx, out bool found) + public TElement? TryGetLast(int minIdx, int maxIdx, out bool found) { Buffer buffer = new Buffer(_source); int count = buffer._count; if (minIdx >= count) { found = false; - return default!; + return default; } found = true; diff --git a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs index 8f985a4469fb..2c8cf01f941d 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs @@ -72,8 +72,7 @@ internal IEnumerator GetEnumerator(int minIdx, int maxIdx) IOrderedEnumerable IOrderedEnumerable.CreateOrderedEnumerable(Func keySelector, IComparer? comparer, bool descending) => new OrderedEnumerable(_source, keySelector, comparer, @descending, this); - [return: MaybeNull] - public TElement TryGetLast(Func predicate, out bool found) + public TElement? TryGetLast(Func predicate, out bool found) { CachingComparer comparer = GetComparer(); using (IEnumerator e = _source.GetEnumerator()) @@ -84,7 +83,7 @@ public TElement TryGetLast(Func predicate, out bool found) if (!e.MoveNext()) { found = false; - return default!; + return default; } value = e.Current; @@ -176,7 +175,7 @@ internal class CachingComparer : CachingComparer protected readonly Func _keySelector; protected readonly IComparer _comparer; protected readonly bool _descending; - [MaybeNull] protected TKey _lastKey = default!; + protected TKey? _lastKey; public CachingComparer(Func keySelector, IComparer comparer, bool descending) { diff --git a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs index f2f39c02bead..c46465f82547 100644 --- a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs @@ -38,7 +38,6 @@ private EmptyPartition() public TElement Current => default!; [ExcludeFromCodeCoverage(Justification = "Shouldn't be called, and as undefined can return or throw anything anyway")] - [MaybeNull] object IEnumerator.Current => default!; void IEnumerator.Reset() @@ -55,25 +54,22 @@ void IDisposable.Dispose() public IPartition Take(int count) => this; - [return: MaybeNull] - public TElement TryGetElementAt(int index, out bool found) + public TElement? TryGetElementAt(int index, out bool found) { found = false; - return default!; + return default; } - [return: MaybeNull] - public TElement TryGetFirst(out bool found) + public TElement? TryGetFirst(out bool found) { found = false; - return default!; + return default; } - [return: MaybeNull] - public TElement TryGetLast(out bool found) + public TElement? TryGetLast(out bool found) { found = false; - return default!; + return default; } public TElement[] ToArray() => Array.Empty(); @@ -117,8 +113,7 @@ public IPartition Take(int count) return new OrderedPartition(_source, _minIndexInclusive, maxIndex); } - [return: MaybeNull] - public TElement TryGetElementAt(int index, out bool found) + public TElement? TryGetElementAt(int index, out bool found) { if (unchecked((uint)index <= (uint)(_maxIndexInclusive - _minIndexInclusive))) { @@ -126,14 +121,12 @@ public TElement TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TElement TryGetFirst(out bool found) => _source.TryGetElementAt(_minIndexInclusive, out found); + public TElement? TryGetFirst(out bool found) => _source.TryGetElementAt(_minIndexInclusive, out found); - [return: MaybeNull] - public TElement TryGetLast(out bool found) => + public TElement? TryGetLast(out bool found) => _source.TryGetLast(_minIndexInclusive, _maxIndexInclusive, out found); public TElement[] ToArray() => _source.ToArray(_minIndexInclusive, _maxIndexInclusive); @@ -201,8 +194,7 @@ public IPartition Take(int count) return unchecked((uint)maxIndex >= (uint)_maxIndexInclusive) ? this : new ListPartition(_source, _minIndexInclusive, maxIndex); } - [return: MaybeNull] - public TSource TryGetElementAt(int index, out bool found) + public TSource? TryGetElementAt(int index, out bool found) { if (unchecked((uint)index <= (uint)(_maxIndexInclusive - _minIndexInclusive) && index < _source.Count - _minIndexInclusive)) { @@ -211,11 +203,10 @@ public TSource TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TSource TryGetFirst(out bool found) + public TSource? TryGetFirst(out bool found) { if (_source.Count > _minIndexInclusive) { @@ -224,11 +215,10 @@ public TSource TryGetFirst(out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TSource TryGetLast(out bool found) + public TSource? TryGetLast(out bool found) { int lastIndex = _source.Count - 1; if (lastIndex >= _minIndexInclusive) @@ -238,7 +228,7 @@ public TSource TryGetLast(out bool found) } found = false; - return default!; + return default; } private int Count @@ -480,8 +470,7 @@ public IPartition Take(int count) return new EnumerablePartition(_source, _minIndexInclusive, maxIndex); } - [return: MaybeNull] - public TSource TryGetElementAt(int index, out bool found) + public TSource? TryGetElementAt(int index, out bool found) { // If the index is negative or >= our max count, return early. if (index >= 0 && (!HasLimit || index < Limit)) @@ -499,11 +488,10 @@ public TSource TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TSource TryGetFirst(out bool found) + public TSource? TryGetFirst(out bool found) { using (IEnumerator en = _source.GetEnumerator()) { @@ -515,11 +503,10 @@ public TSource TryGetFirst(out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TSource TryGetLast(out bool found) + public TSource? TryGetLast(out bool found) { using (IEnumerator en = _source.GetEnumerator()) { @@ -542,7 +529,7 @@ public TSource TryGetLast(out bool found) } found = false; - return default!; + return default; } public TSource[] ToArray() diff --git a/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs index 7cc12d6678e0..3840acd81340 100644 --- a/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Repeat.SpeedOpt.cs @@ -62,8 +62,7 @@ public IPartition Take(int count) return new RepeatIterator(_current, count); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if ((uint)index < (uint)_count) { @@ -72,7 +71,7 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } public TResult TryGetFirst(out bool found) diff --git a/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs index 530f92b0b1fb..e23cbd49f322 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs @@ -133,8 +133,7 @@ public IPartition Take(int count) new SelectListPartitionIterator(_source, _selector, 0, count - 1); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if (unchecked((uint)index < (uint)_source.Length)) { @@ -143,7 +142,7 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } public TResult TryGetFirst(out bool found) @@ -262,8 +261,7 @@ public IPartition Take(int count) return new SelectRangeIterator(_start, _start + count, _selector); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if ((uint)index < (uint)(_end - _start)) { @@ -272,7 +270,7 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } public TResult TryGetFirst(out bool found) @@ -351,8 +349,7 @@ public IPartition Take(int count) return new SelectListPartitionIterator(_source, _selector, 0, count - 1); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if (unchecked((uint)index < (uint)_source.Count)) { @@ -361,11 +358,10 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetFirst(out bool found) + public TResult? TryGetFirst(out bool found) { if (_source.Count != 0) { @@ -374,11 +370,10 @@ public TResult TryGetFirst(out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetLast(out bool found) + public TResult? TryGetLast(out bool found) { int len = _source.Count; if (len != 0) @@ -388,7 +383,7 @@ public TResult TryGetLast(out bool found) } found = false; - return default!; + return default; } } @@ -453,8 +448,7 @@ public IPartition Take(int count) return new SelectListPartitionIterator(_source, _selector, 0, count - 1); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if (unchecked((uint)index < (uint)_source.Count)) { @@ -463,11 +457,10 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetFirst(out bool found) + public TResult? TryGetFirst(out bool found) { if (_source.Count != 0) { @@ -476,11 +469,10 @@ public TResult TryGetFirst(out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetLast(out bool found) + public TResult? TryGetLast(out bool found) { int len = _source.Count; if (len != 0) @@ -490,7 +482,7 @@ public TResult TryGetLast(out bool found) } found = false; - return default!; + return default; } } @@ -565,8 +557,7 @@ public IPartition Take(int count) return new SelectIPartitionIterator(_source.Take(count), _selector); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { bool sourceFound; TSource input = _source.TryGetElementAt(index, out sourceFound); @@ -574,8 +565,7 @@ public TResult TryGetElementAt(int index, out bool found) return sourceFound ? _selector(input!) : default!; } - [return: MaybeNull] - public TResult TryGetFirst(out bool found) + public TResult? TryGetFirst(out bool found) { bool sourceFound; TSource input = _source.TryGetFirst(out sourceFound); @@ -583,8 +573,7 @@ public TResult TryGetFirst(out bool found) return sourceFound ? _selector(input!) : default!; } - [return: MaybeNull] - public TResult TryGetLast(out bool found) + public TResult? TryGetLast(out bool found) { bool sourceFound; TSource input = _source.TryGetLast(out sourceFound); @@ -739,8 +728,7 @@ public IPartition Take(int count) return (uint)maxIndex >= (uint)_maxIndexInclusive ? this : new SelectListPartitionIterator(_source, _selector, _minIndexInclusive, maxIndex); } - [return: MaybeNull] - public TResult TryGetElementAt(int index, out bool found) + public TResult? TryGetElementAt(int index, out bool found) { if ((uint)index <= (uint)(_maxIndexInclusive - _minIndexInclusive) && index < _source.Count - _minIndexInclusive) { @@ -749,11 +737,10 @@ public TResult TryGetElementAt(int index, out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetFirst(out bool found) + public TResult? TryGetFirst(out bool found) { if (_source.Count > _minIndexInclusive) { @@ -762,11 +749,10 @@ public TResult TryGetFirst(out bool found) } found = false; - return default!; + return default; } - [return: MaybeNull] - public TResult TryGetLast(out bool found) + public TResult? TryGetLast(out bool found) { int lastIndex = _source.Count - 1; if (lastIndex >= _minIndexInclusive) @@ -776,7 +762,7 @@ public TResult TryGetLast(out bool found) } found = false; - return default!; + return default; } private int Count diff --git a/src/libraries/System.Linq/src/System/Linq/Single.cs b/src/libraries/System.Linq/src/System/Linq/Single.cs index 7640bc7c8646..913405d502c2 100644 --- a/src/libraries/System.Linq/src/System/Linq/Single.cs +++ b/src/libraries/System.Linq/src/System/Linq/Single.cs @@ -83,8 +83,7 @@ public static TSource Single(this IEnumerable source, Func(this IEnumerable source) + public static TSource? SingleOrDefault(this IEnumerable source) { if (source == null) { @@ -96,7 +95,7 @@ public static TSource SingleOrDefault(this IEnumerable source) switch (list.Count) { case 0: - return default!; + return default; case 1: return list[0]; } @@ -107,7 +106,7 @@ public static TSource SingleOrDefault(this IEnumerable source) { if (!e.MoveNext()) { - return default!; + return default; } TSource result = e.Current; @@ -122,8 +121,7 @@ public static TSource SingleOrDefault(this IEnumerable source) return default; } - [return: MaybeNull] - public static TSource SingleOrDefault(this IEnumerable source, Func predicate) + public static TSource? SingleOrDefault(this IEnumerable source, Func predicate) { if (source == null) { @@ -155,7 +153,7 @@ public static TSource SingleOrDefault(this IEnumerable source, } } - return default!; + return default; } } } diff --git a/src/libraries/System.Memory/src/System/Buffers/ReadOnlySequence.cs b/src/libraries/System.Memory/src/System/Buffers/ReadOnlySequence.cs index 273a9702c8ca..7fd6b1372c12 100644 --- a/src/libraries/System.Memory/src/System/Buffers/ReadOnlySequence.cs +++ b/src/libraries/System.Memory/src/System/Buffers/ReadOnlySequence.cs @@ -17,8 +17,8 @@ namespace System.Buffers public readonly partial struct ReadOnlySequence { // The data is essentially two SequencePositions, however the Start and End SequencePositions are deconstructed to improve packing. - [AllowNull] private readonly object? _startObject; - [AllowNull] private readonly object? _endObject; + private readonly object? _startObject; + private readonly object? _endObject; private readonly int _startInteger; private readonly int _endInteger; diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs index c8d7a3c7c9b4..34e35f788339 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs @@ -12,10 +12,10 @@ public static partial class HttpClientJsonExtensions public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -28,7 +28,7 @@ public static partial class HttpClientJsonExtensions public static partial class HttpContentJsonExtensions { public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Type type, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } public sealed partial class JsonContent : System.Net.Http.HttpContent { diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs index dd50490e26d3..908b5bc15667 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs @@ -34,7 +34,7 @@ public static partial class HttpClientJsonExtensions return GetFromJsonAsyncCore(taskResponse, type, options, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -45,7 +45,7 @@ public static Task GetFromJsonAsync(this HttpClient client, stri return GetFromJsonAsyncCore(taskResponse, options, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -62,10 +62,10 @@ public static Task GetFromJsonAsync(this HttpClient client, Uri? public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, type, options: null, cancellationToken); - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, CancellationToken cancellationToken = default) + public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, options: null, cancellationToken); - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, CancellationToken cancellationToken = default) + public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, options: null, cancellationToken); private static async Task GetFromJsonAsyncCore(Task taskResponse, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken) @@ -80,7 +80,7 @@ public static Task GetFromJsonAsync(this HttpClient client, Uri? } } - private static async Task GetFromJsonAsyncCore(Task taskResponse, JsonSerializerOptions? options, CancellationToken cancellationToken) + private static async Task GetFromJsonAsyncCore(Task taskResponse, JsonSerializerOptions? options, CancellationToken cancellationToken) { using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) { diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs index 753c0315583c..e73c6fb49d73 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs @@ -21,7 +21,7 @@ public static partial class HttpContentJsonExtensions return ReadFromJsonAsyncCore(content, type, sourceEncoding, options, cancellationToken); } - public static Task ReadFromJsonAsync(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + public static Task ReadFromJsonAsync(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { ValidateContent(content); Debug.Assert(content.Headers.ContentType != null); @@ -46,7 +46,7 @@ public static Task ReadFromJsonAsync(this HttpContent content, JsonSeriali } } - private static async Task ReadFromJsonAsyncCore(HttpContent content, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) + private static async Task ReadFromJsonAsyncCore(HttpContent content, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) { Stream contentStream = await ReadHttpContentStreamAsync(content, cancellationToken).ConfigureAwait(false); diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs index 415ccbdc5145..9e1b3a3b18a7 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs @@ -452,7 +452,7 @@ public void PrintFailureTypes() private class StructuralEqualityComparer : IEqualityComparer where T : IStructuralEquatable { - public bool Equals([AllowNull] T left, [AllowNull] T right) => left != null && left.Equals(right, StructuralComparisons.StructuralEqualityComparer); + public bool Equals(T? left, T? right) => left != null && left.Equals(right, StructuralComparisons.StructuralEqualityComparer); public int GetHashCode(T value) => value.GetHashCode(StructuralComparisons.StructuralEqualityComparer); } } diff --git a/src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ServiceNameCollection.cs b/src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ServiceNameCollection.cs index 7bfa4f7863ed..8797f31cf589 100644 --- a/src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ServiceNameCollection.cs +++ b/src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ServiceNameCollection.cs @@ -133,7 +133,7 @@ private void AddIfNew(IList serviceNames) /// /// Normalize, check for duplicates, and add if the value is unique. /// - private void AddIfNew([MaybeNull]string serviceName) + private void AddIfNew(string serviceName) { if (string.IsNullOrEmpty(serviceName)) { @@ -164,6 +164,7 @@ private static int GetCountOrOne(IEnumerable collection) // prefix/host:port // prefix/host/DistinguishedName // prefix/host:port/DistinguishedName + [return: NotNullIfNotNull("inputServiceName")] private static string? NormalizeServiceName(string? inputServiceName) { if (string.IsNullOrWhiteSpace(inputServiceName)) diff --git a/src/libraries/System.ObjectModel/src/System/Collections/ObjectModel/KeyedCollection.cs b/src/libraries/System.ObjectModel/src/System/Collections/ObjectModel/KeyedCollection.cs index 93cd10b6ffd0..3c0c0a4068a7 100644 --- a/src/libraries/System.ObjectModel/src/System/Collections/ObjectModel/KeyedCollection.cs +++ b/src/libraries/System.ObjectModel/src/System/Collections/ObjectModel/KeyedCollection.cs @@ -114,7 +114,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TItem item) } } - item = default(TItem)!; + item = default; return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Action.cs b/src/libraries/System.Private.CoreLib/src/System/Action.cs index 539e5fd9ce58..dacc4fa7cc5b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Action.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Action.cs @@ -23,7 +23,10 @@ namespace System public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); - public delegate int Comparison([AllowNull] T x, [AllowNull] T y); + // This should probably technically be T? rather than T to match `IComparer`. However, the use cases are generally different, + // with Comparison typically being used via a lambda, with the T inferred from the type of the collection being sorted, + // and forcing nullable warnings onto all such usage leads to many spurious warnings. + public delegate int Comparison(T x, T y); public delegate TOutput Converter(TInput input); diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index 030e8e23d658..1e0fca689b40 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -752,8 +752,7 @@ public static void Fill(T[] array, T value, int startIndex, int count) } } - [return: MaybeNull] - public static T Find(T[] array, Predicate match) + public static T? Find(T[] array, Predicate match) { if (array == null) { @@ -772,7 +771,7 @@ public static T Find(T[] array, Predicate match) return array[i]; } } - return default!; + return default; } public static T[] FindAll(T[] array, Predicate match) @@ -849,8 +848,7 @@ public static int FindIndex(T[] array, int startIndex, int count, Predicate(T[] array, Predicate match) + public static T? FindLast(T[] array, Predicate match) { if (array == null) { @@ -869,7 +867,7 @@ public static T FindLast(T[] array, Predicate match) return array[i]; } } - return default!; + return default; } public static int FindLastIndex(T[] array, Predicate match) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs index 76f0ea247553..08eb093d54f9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs @@ -689,7 +689,7 @@ private bool TryDequeueSlow([MaybeNullWhen(false)] out T item) // check and this check, another item could have arrived). if (head._nextSegment == null) { - item = default!; + item = default; return false; } @@ -783,7 +783,7 @@ private bool TryPeek([MaybeNullWhen(false)] out T result, bool resultUsed) // and we'll traverse to that segment. } - result = default!; + result = default; return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs index 56a758e2cf9b..1cd82352ae17 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs @@ -173,7 +173,7 @@ public bool TryDequeue([MaybeNullWhen(false)] out T item) int currentTail = Volatile.Read(ref _headAndTail.Tail); if (currentTail - currentHead <= 0 || (frozen && (currentTail - FreezeOffset - currentHead <= 0))) { - item = default!; + item = default; return false; } @@ -234,7 +234,7 @@ public bool TryPeek([MaybeNullWhen(false)] out T result, bool resultUsed) int currentTail = Volatile.Read(ref _headAndTail.Tail); if (currentTail - currentHead <= 0 || (frozen && (currentTail - FreezeOffset - currentHead <= 0))) { - result = default!; + result = default; return false; } @@ -311,7 +311,7 @@ public bool TryEnqueue(T item) internal struct Slot { /// The item. - [AllowNull, MaybeNull] public T Item; // SOS's ThreadPool command depends on this being at the beginning of the struct when T is a reference type + public T? Item; // SOS's ThreadPool command depends on this being at the beginning of the struct when T is a reference type /// The sequence number for this slot, used to synchronize between enqueuers and dequeuers. public int SequenceNumber; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs index 0b4f12d9e038..2ee414aa6279 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs @@ -21,7 +21,7 @@ public static Comparer Create(Comparison comparison) return new ComparisonComparer(comparison); } - public abstract int Compare([AllowNull] T x, [AllowNull] T y); + public abstract int Compare(T? x, T? y); int IComparer.Compare(object? x, object? y) { @@ -42,10 +42,7 @@ public ComparisonComparer(Comparison comparison) _comparison = comparison; } - public override int Compare([AllowNull] T x, [AllowNull] T y) - { - return _comparison(x, y); - } + public override int Compare(T? x, T? y) => _comparison(x!, y!); } // Note: although there is a lot of shared code in the following @@ -58,7 +55,7 @@ public override int Compare([AllowNull] T x, [AllowNull] T y) // Needs to be public to support binary serialization compatibility public sealed partial class GenericComparer : Comparer where T : IComparable { - public override int Compare([AllowNull] T x, [AllowNull] T y) + public override int Compare(T? x, T? y) { if (x != null) { @@ -106,7 +103,7 @@ public override int GetHashCode() => // Needs to be public to support binary serialization compatibility public sealed partial class ObjectComparer : Comparer { - public override int Compare([AllowNull] T x, [AllowNull] T y) + public override int Compare(T? x, T? y) { return System.Collections.Comparer.Default.Compare(x, y); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index 6c5682e613b6..39245df47cce 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -1461,7 +1461,7 @@ public struct Enumerator : IEnumerator, IEnumerator private readonly Dictionary _dictionary; private int _index; private readonly int _version; - [AllowNull, MaybeNull] private TKey _currentKey; + private TKey? _currentKey; internal Enumerator(Dictionary dictionary) { @@ -1653,7 +1653,7 @@ public struct Enumerator : IEnumerator, IEnumerator private readonly Dictionary _dictionary; private int _index; private readonly int _version; - [AllowNull, MaybeNull] private TValue _currentValue; + private TValue? _currentValue; internal Enumerator(Dictionary dictionary) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs index 6b6830e6425d..180bea6ddf9d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs @@ -13,7 +13,7 @@ public abstract partial class EqualityComparer : IEqualityComparer, IEquality { // public static EqualityComparer Default is runtime-specific - public abstract bool Equals([AllowNull] T x, [AllowNull] T y); + public abstract bool Equals(T? x, T? y); public abstract int GetHashCode([DisallowNull] T obj); int IEqualityComparer.GetHashCode(object? obj) @@ -42,7 +42,7 @@ bool IEqualityComparer.Equals(object? x, object? y) public sealed partial class GenericEqualityComparer : EqualityComparer where T : IEquatable { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals([AllowNull] T x, [AllowNull] T y) + public override bool Equals(T? x, T? y) { if (x != null) { @@ -100,7 +100,7 @@ public override int GetHashCode() => public sealed partial class ObjectEqualityComparer : EqualityComparer { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals([AllowNull] T x, [AllowNull] T y) + public override bool Equals(T? x, T? y) { if (x != null) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IComparer.cs index 82394ef20b9e..59a9b90d9f53 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IComparer.cs @@ -14,6 +14,6 @@ public interface IComparer // value less than zero if x is less than y, zero if x is equal to y, or a // value greater than zero if x is greater than y. // - int Compare([AllowNull] T x, [AllowNull] T y); + int Compare(T? x, T? y); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IEqualityComparer.cs index b83b54ee749f..19545c6bbdd4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IEqualityComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IEqualityComparer.cs @@ -10,7 +10,7 @@ namespace System.Collections.Generic // It is used in Dictionary class. public interface IEqualityComparer { - bool Equals([AllowNull] T x, [AllowNull] T y); + bool Equals(T? x, T? y); int GetHashCode([DisallowNull] T obj); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs index 13ab166e8d32..6da36e0f57bf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs @@ -412,8 +412,7 @@ private void EnsureCapacity(int min) public bool Exists(Predicate match) => FindIndex(match) != -1; - [return: MaybeNull] - public T Find(Predicate match) + public T? Find(Predicate match) { if (match == null) { @@ -427,7 +426,7 @@ public T Find(Predicate match) return _items[i]; } } - return default!; + return default; } public List FindAll(Predicate match) @@ -479,8 +478,7 @@ public int FindIndex(int startIndex, int count, Predicate match) return -1; } - [return: MaybeNull] - public T FindLast(Predicate match) + public T? FindLast(Predicate match) { if (match == null) { @@ -494,7 +492,7 @@ public T FindLast(Predicate match) return _items[i]; } } - return default!; + return default; } public int FindLastIndex(Predicate match) @@ -1077,7 +1075,7 @@ public struct Enumerator : IEnumerator, IEnumerator private readonly List _list; private int _index; private readonly int _version; - [AllowNull, MaybeNull] private T _current; + private T? _current; internal Enumerator(List list) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/Collection.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/Collection.cs index 2f2676a2cbaa..fcafafed633f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/Collection.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/Collection.cs @@ -244,7 +244,7 @@ void ICollection.CopyTo(Array array, int index) { ThrowHelper.IfNullAndNullsAreIllegalThenThrow(value, ExceptionArgument.value); - T item = default!; + T? item = default; try { @@ -285,7 +285,7 @@ int IList.Add(object? value) } ThrowHelper.IfNullAndNullsAreIllegalThenThrow(value, ExceptionArgument.value); - T item = default!; + T? item = default; try { @@ -327,7 +327,7 @@ void IList.Insert(int index, object? value) } ThrowHelper.IfNullAndNullsAreIllegalThenThrow(value, ExceptionArgument.value); - T item = default!; + T? item = default; try { diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 6c6e22bb2760..6085322e18d3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1363,14 +1363,14 @@ protected virtual void Dispose(bool disposing) if (m_etwProvider != null) { m_etwProvider.Dispose(); - m_etwProvider = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + m_etwProvider = null!; } #endif #if FEATURE_PERFTRACING if (m_eventPipeProvider != null) { m_eventPipeProvider.Dispose(); - m_eventPipeProvider = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + m_eventPipeProvider = null!; } #endif } diff --git a/src/libraries/System.Private.CoreLib/src/System/IComparable.cs b/src/libraries/System.Private.CoreLib/src/System/IComparable.cs index 3c0f50b23fa9..3599bbdf9ded 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IComparable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IComparable.cs @@ -33,6 +33,6 @@ public interface IComparable // if this is equal to object, or a value greater than zero // if this is greater than object. // - int CompareTo([AllowNull] T other); + int CompareTo(T? other); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IEquatable.cs b/src/libraries/System.Private.CoreLib/src/System/IEquatable.cs index 1edba4472c91..89f0771802a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IEquatable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IEquatable.cs @@ -7,6 +7,6 @@ namespace System { public interface IEquatable // invariant due to questionable semantics around equality and inheritance { - bool Equals([AllowNull] T other); + bool Equals(T? other); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Lazy.cs b/src/libraries/System.Private.CoreLib/src/System/Lazy.cs index 4fcfbc9070bf..ac676de6c4c5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Lazy.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Lazy.cs @@ -195,7 +195,7 @@ public class Lazy<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Pub private Func? _factory; // _value eventually stores the lazily created value. It is valid when _state = null. - private T _value = default!; + private T? _value; /// /// Initializes a new instance of the class that @@ -447,14 +447,13 @@ private T CreateValue() } /// Gets the value of the Lazy<T> for debugging display purposes. - [MaybeNull] - internal T ValueForDebugDisplay + internal T? ValueForDebugDisplay { get { if (!IsValueCreated) { - return default!; + return default; } return _value; } @@ -503,7 +502,7 @@ internal T ValueForDebugDisplay /// from initialization delegate. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] - public T Value => _state == null ? _value : CreateValue(); + public T Value => _state == null ? _value! : CreateValue(); } /// A debugger view of the Lazy<T> to surface additional debugging properties and @@ -524,8 +523,7 @@ public LazyDebugView(Lazy lazy) public bool IsValueCreated => _lazy.IsValueCreated; /// Returns the value of the Lazy object. - [MaybeNull] - public T Value => _lazy.ValueForDebugDisplay; + public T? Value => _lazy.ValueForDebugDisplay; /// Returns the execution mode of the Lazy object public LazyThreadSafetyMode? Mode => _lazy.Mode; diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs index baf733b3678b..c43899c52431 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs @@ -157,11 +157,11 @@ private unsafe void Dispose(bool disposing) // Close the stream in a thread-safe way. This fix means // that we may call Close n times, but that's safe. BinaryReader copyOfStore = _store; - _store = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + _store = null!; if (copyOfStore != null) copyOfStore.Close(); } - _store = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + _store = null!; _namePositions = null; _nameHashes = null; _ums = null; 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 dbb3342b94f0..6ad05b686929 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs @@ -29,7 +29,7 @@ namespace System.Resources public class ResourceSet : IDisposable, IEnumerable { protected IResourceReader Reader = null!; - internal Hashtable? Table; // TODO-NULLABLE: Avoid nulling out in Dispose + internal Hashtable? Table; private Hashtable? _caseInsensitiveTable; // For case-insensitive lookups. @@ -90,11 +90,11 @@ protected virtual void Dispose(bool disposing) { // Close the Reader in a thread-safe way. IResourceReader? copyOfReader = Reader; - Reader = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + Reader = null!; if (copyOfReader != null) copyOfReader.Close(); } - Reader = null!; // TODO-NULLABLE: Avoid nulling out in Dispose + Reader = null!; _caseInsensitiveTable = null; Table = null; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/RuntimeResourceSet.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/RuntimeResourceSet.cs index c00ebb2b04a4..f6de75e7e3e9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/RuntimeResourceSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/RuntimeResourceSet.cs @@ -175,12 +175,12 @@ sealed class RuntimeResourceSet : ResourceSet, IEnumerable // for arbitrarily long times, since the object is usually a string // literal that will live for the lifetime of the appdomain. The // value is a ResourceLocator instance, which might cache the object. - private Dictionary? _resCache; // TODO-NULLABLE: Avoid nulling out in Dispose + private Dictionary? _resCache; // For our special load-on-demand reader, cache the cast. The // RuntimeResourceSet's implementation knows how to treat this reader specially. - private ResourceReader? _defaultReader; // TODO-NULLABLE: Avoid nulling out in Dispose + private ResourceReader? _defaultReader; // This is a lookup table for case-insensitive lookups, and may be null. // Consider always using a case-insensitive resource cache, as we don't diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskCache.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskCache.cs index 363371f7e7b7..1c654cd79c37 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskCache.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskCache.cs @@ -45,7 +45,7 @@ private static int GetPoolAsyncValueTasksLimitValue() => /// Specifies the result type. /// The result for the task. /// The cacheable task. - internal static Task CreateCacheableTask([AllowNull] TResult result) => + internal static Task CreateCacheableTask(TResult? result) => new Task(false, result, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default); /// Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX). diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs index 4a3d1dfed13b..70ac433630de 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs @@ -292,8 +292,7 @@ private static void ExecutionContextCallback(object? s) /// A delegate to the method. private Action? _moveNextAction; /// The state machine itself. - [AllowNull, MaybeNull] - public TStateMachine StateMachine = default; // mutable struct; do not make this readonly. SOS DumpAsync command depends on this name. + public TStateMachine? StateMachine; // mutable struct; do not make this readonly. SOS DumpAsync command depends on this name. /// Captured ExecutionContext with which to invoke ; may be null. public ExecutionContext? Context; @@ -428,7 +427,7 @@ public void SetResult(TResult result) /// Completes the already initialized task with the specified result. /// The result to use to complete the task. /// The task to complete. - internal static void SetExistingTaskResult(Task task, [AllowNull] TResult result) + internal static void SetExistingTaskResult(Task task, TResult? result) { Debug.Assert(task != null, "Expected non-null task"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs index 1c88475eae7d..846c64999c30 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs @@ -364,8 +364,7 @@ private sealed class StateMachineBox : /// If this box is stored in the cache, the next box in the cache. private StateMachineBox? _next; /// The state machine itself. - [AllowNull, MaybeNull] - public TStateMachine StateMachine = default; + public TStateMachine? StateMachine; /// Gets a box object to use for an operation. This may be a reused, pooled object, or it may be new. [MethodImpl(MethodImplOptions.AggressiveInlining)] // only one caller diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs index 8d3b9adb0f3b..d5caca5098f0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs @@ -552,7 +552,7 @@ internal bool TryGetEntry(int index, [NotNullWhen(true)] out TKey? key, [MaybeNu } key = default; - value = default!; + value = default; return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs index 477717e9cb21..ed7d4928c250 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NoCom.cs @@ -52,7 +52,7 @@ public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : not } [SupportedOSPlatform("windows")] - public static TWrapper CreateWrapperOfType([AllowNull] T o) + public static TWrapper CreateWrapperOfType(T? o) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } @@ -122,7 +122,7 @@ public static void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVaria } [SupportedOSPlatform("windows")] - public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant) + public static void GetNativeVariantForObject(T? obj, IntPtr pDstNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } @@ -146,8 +146,7 @@ public static object GetObjectForIUnknown(IntPtr pUnk) } [SupportedOSPlatform("windows")] - [return: MaybeNull] - public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant) + public static T? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index 40c0396c2ac0..7a2e976c92af 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -572,8 +572,7 @@ public static void PtrToStructure(IntPtr ptr, [DisallowNull] T structure) PtrToStructure(ptr, (object)structure!); } - [return: MaybeNull] - public static T PtrToStructure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T))!; + public static T? PtrToStructure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T))!; public static void DestroyStructure(IntPtr ptr) => DestroyStructure(ptr, typeof(T)); diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.BinarySearch.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.BinarySearch.cs index 2da00f975d23..4b8c9127cd23 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.BinarySearch.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.BinarySearch.cs @@ -75,7 +75,7 @@ public ComparerComparable(T value, TComparer comparer) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo([AllowNull] T other) => _comparer.Compare(_value, other); + public int CompareTo(T? other) => _comparer.Compare(_value, other); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/AsyncLocal.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/AsyncLocal.cs index 1a81b1dbc422..288ffbd32e69 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/AsyncLocal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/AsyncLocal.cs @@ -86,8 +86,8 @@ internal interface IAsyncLocal public readonly struct AsyncLocalValueChangedArgs { - [MaybeNull] public T PreviousValue { get; } - [MaybeNull] public T CurrentValue { get; } + public T? PreviousValue { get; } + public T? CurrentValue { get; } // // If the value changed because we changed to a different ExecutionContext, this is true. If it changed @@ -95,7 +95,7 @@ public readonly struct AsyncLocalValueChangedArgs // public bool ThreadContextChanged { get; } - internal AsyncLocalValueChangedArgs([AllowNull] T previousValue, [AllowNull] T currentValue, bool contextChanged) + internal AsyncLocalValueChangedArgs(T? previousValue, T? currentValue, bool contextChanged) { PreviousValue = previousValue!; CurrentValue = currentValue!; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs index b993f263cc28..32dceb94def7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs @@ -59,7 +59,7 @@ namespace System.Threading.Tasks public class Task : Task { // The value itself, if set. - [MaybeNull, AllowNull] internal TResult m_result = default!; + internal TResult? m_result; private static readonly TaskFactory s_Factory = new TaskFactory(); @@ -93,7 +93,7 @@ internal Task(TResult result) : m_result = result; } - internal Task(bool canceled, [AllowNull] TResult result, TaskCreationOptions creationOptions, CancellationToken ct) + internal Task(bool canceled, TResult? result, TaskCreationOptions creationOptions, CancellationToken ct) : base(canceled, creationOptions, ct) { if (!canceled) @@ -364,7 +364,7 @@ internal static Task StartNew(Task? parent, Func func // internal helper function breaks out logic used by TaskCompletionSource - internal bool TrySetResult([AllowNull] TResult result) + internal bool TrySetResult(TResult? result) { Debug.Assert(m_action == null, "Task.TrySetResult(): non-null m_action"); @@ -1357,7 +1357,7 @@ public SystemThreadingTasks_FutureDebugView(Task task) m_task = task; } - [MaybeNull] public TResult Result => m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default!; + public TResult? Result => m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default; public object? AsyncState => m_task.AsyncState; public TaskCreationOptions CreationOptions => m_task.CreationOptions; public Exception? Exception => m_task.Exception; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs index f067ffd44eb2..b1ef1c1b0339 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ProducerConsumerQueues.cs @@ -239,7 +239,7 @@ private bool TryDequeueSlow(ref Segment segment, ref T[] array, [MaybeNullWhen(f if (first == segment.m_state.m_last) { - result = default!; + result = default; return false; } 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 8a4a2db85314..b9caa5392bce 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 @@ -31,7 +31,7 @@ public struct ManualResetValueTaskSourceCore /// Whether the current operation has completed. private bool _completed; /// The result with which the operation succeeded, or the default value if it hasn't yet completed or failed. - [AllowNull, MaybeNull] private TResult _result; + private TResult? _result; /// The exception with which the operation failed, or null if it hasn't yet completed or completed successfully. private ExceptionDispatchInfo? _error; /// The current version of this value, used to help prevent misuse. @@ -98,7 +98,7 @@ public TResult GetResult(short token) } _error?.Throw(); - return _result; + return _result!; } /// Schedules the continuation action for this operation. 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 7a04c041d653..afc8f5a00f3a 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 @@ -445,7 +445,7 @@ public ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContex /// null if has the result, otherwise a or a . internal readonly object? _obj; /// The result to be used if the operation completed successfully synchronously. - [AllowNull] internal readonly TResult _result; + internal readonly TResult? _result; /// Opaque value passed through to the . internal readonly short _token; /// true to continue on the captured context; otherwise, false. @@ -508,7 +508,7 @@ public ValueTask(IValueTaskSource source, short token) /// The token. /// true to continue on captured context; otherwise, false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ValueTask(object? obj, TResult result, short token, bool continueOnCapturedContext) + private ValueTask(object? obj, TResult? result, short token, bool continueOnCapturedContext) { _obj = obj; _result = result; @@ -556,7 +556,7 @@ public Task AsTask() if (obj == null) { - return AsyncTaskMethodBuilder.GetTaskForResult(_result); + return AsyncTaskMethodBuilder.GetTaskForResult(_result!); } if (obj is Task t) @@ -781,7 +781,7 @@ public TResult Result if (obj == null) { - return _result; + return _result!; } if (obj is Task t) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs index 2d0c67cc605e..4d7188e85806 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs @@ -305,8 +305,7 @@ public T Value } } - [return: MaybeNull] - private T GetValueSlow() + private T? GetValueSlow() { // If the object has been disposed, the id will be -1. int id = ~_idComplement; @@ -538,8 +537,7 @@ public bool IsValueCreated /// Gets the value of the ThreadLocal<T> for debugging display purposes. It takes care of getting /// the value for the current thread in the ThreadLocal mode. - [MaybeNull] - internal T ValueForDebugDisplay + internal T? ValueForDebugDisplay { get { @@ -548,7 +546,7 @@ internal T ValueForDebugDisplay LinkedSlot? slot; if (slotArray == null || id >= slotArray.Length || (slot = slotArray[id].Value) == null || !_initialized) - return default!; + return default; return slot._value; } } @@ -672,7 +670,7 @@ internal LinkedSlot(LinkedSlotVolatile[]? slotArray) internal volatile LinkedSlotVolatile[]? _slotArray; // The value for this slot. - [AllowNull, MaybeNull] internal T _value = default; + internal T? _value; } /// @@ -804,8 +802,7 @@ public SystemThreading_ThreadLocalDebugView(ThreadLocal tlocal) public bool IsValueCreated => _tlocal.IsValueCreated; /// Returns the value of the ThreadLocal object. - [MaybeNull] - public T Value => _tlocal.ValueForDebugDisplay; + public T? Value => _tlocal.ValueForDebugDisplay; /// Return all values for all threads that have accessed this instance. public List? Values => _tlocal.ValuesForDebugDisplay; diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs b/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs index 491f7ac437cf..d28dcd8b0b07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs @@ -304,7 +304,7 @@ public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bin { for (i = 0; i < e.Length; i++) if (e[i] != null) - ret[cnt++] = e[i]!; // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) + ret[cnt++] = e[i]!; // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) } // Copy the Types @@ -312,7 +312,7 @@ public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bin { for (i = 0; i < t.Length; i++) if (t[i] != null) - ret[cnt++] = t[i]!; // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) + ret[cnt++] = t[i]!; // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) } return ret; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EnumerableExtensions.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EnumerableExtensions.cs index aaec6063a4b9..99545a020291 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EnumerableExtensions.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EnumerableExtensions.cs @@ -13,8 +13,7 @@ namespace System.Reflection.Internal /// internal static class EnumerableExtensions { - [return: MaybeNull] - public static T FirstOrDefault(this ImmutableArray collection, Func predicate) + public static T? FirstOrDefault(this ImmutableArray collection, Func predicate) { foreach (var item in collection) { @@ -24,7 +23,7 @@ public static T FirstOrDefault(this ImmutableArray collection, Func(void* source) { throw null; } public static ref T AsRef(in T source) { throw null; } #if NETSTANDARD2_1 - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("o")] #endif - public static T As(object? o) where T : class? { throw null; } + public static T? As(object? o) where T : class? { throw null; } public static ref TTo As(ref TFrom source) { throw null; } public static System.IntPtr ByteOffset(ref T origin, ref T target) { throw null; } public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { } 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 67b487cb971b..7bc7065a9f01 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -500,7 +500,7 @@ public static void Copy(float[] source, int startIndex, System.IntPtr destinatio [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("o")] public static object? CreateWrapperOfType(object? o, System.Type t) { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public static TWrapper CreateWrapperOfType([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T o) { throw null; } + public static TWrapper CreateWrapperOfType(T? o) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static void DestroyStructure(System.IntPtr ptr, System.Type structuretype) { } public static void DestroyStructure(System.IntPtr ptr) { } @@ -548,7 +548,7 @@ public static void FreeHGlobal(System.IntPtr hglobal) { } public static void GetNativeVariantForObject(object? obj, System.IntPtr pDstNativeVariant) { } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public static void GetNativeVariantForObject([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T obj, System.IntPtr pDstNativeVariant) { } + public static void GetNativeVariantForObject(T? obj, System.IntPtr pDstNativeVariant) { } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object GetObjectForIUnknown(System.IntPtr pUnk) { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] @@ -556,8 +556,7 @@ public static void GetNativeVariantForObject([System.Diagnostics.CodeAnalysis public static object? GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } + public static T? GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object?[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; } @@ -594,8 +593,7 @@ public static void PrelinkAll(System.Type c) { } public static void PtrToStructure(System.IntPtr ptr, object structure) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static object? PtrToStructure(System.IntPtr ptr, System.Type structureType) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T PtrToStructure(System.IntPtr ptr) { throw null; } + public static T? PtrToStructure(System.IntPtr ptr) { throw null; } public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T structure) { } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { throw null; } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs index 8ecc28256629..d4207fbfa68e 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs @@ -159,7 +159,7 @@ private void Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo { Type type = memberTypes[i] != null ? memberTypes[i] : - memberData[i] != null ? GetType(memberData[i]!) : // TODO-NULLABLE https://github.com/dotnet/roslyn/issues/34644 + memberData[i] != null ? GetType(memberData[i]!) : // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) Converter.s_typeofObject; InternalPrimitiveTypeE code = ToCode(type); @@ -170,7 +170,7 @@ private void Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo if (memberData[i] != null) { memberObjectInfos[i] = WriteObjectInfo.Serialize( - memberData[i]!, // TODO-NULLABLE https://github.com/dotnet/roslyn/issues/34644 + memberData[i]!, // TODO-NULLABLE: Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) _surrogates, _context, _serObjectInfoInit, diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index aaaf4da863d9..8ebce34c3dbf 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -343,10 +343,8 @@ public static void Fill(T[] array, T value, int startIndex, int count) { } public static int FindLastIndex(T[] array, int startIndex, int count, System.Predicate match) { throw null; } public static int FindLastIndex(T[] array, int startIndex, System.Predicate match) { throw null; } public static int FindLastIndex(T[] array, System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T FindLast(T[] array, System.Predicate match) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static T Find(T[] array, System.Predicate match) { throw null; } + public static T? FindLast(T[] array, System.Predicate match) { throw null; } + public static T? Find(T[] array, System.Predicate match) { throw null; } public static void ForEach(T[] array, System.Action action) { } public System.Collections.IEnumerator GetEnumerator() { throw null; } public int GetLength(int dimension) { throw null; } @@ -816,7 +814,7 @@ public sealed partial class CLSCompliantAttribute : System.Attribute public CLSCompliantAttribute(bool isCompliant) { } public bool IsCompliant { get { throw null; } } } - public delegate int Comparison([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); + public delegate int Comparison(T x, T y); public abstract partial class ContextBoundObject : System.MarshalByRefObject { protected ContextBoundObject() { } @@ -2298,7 +2296,7 @@ public partial interface IComparable } public partial interface IComparable { - int CompareTo([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T other); + int CompareTo(T? other); } [System.CLSCompliantAttribute(false)] public partial interface IConvertible @@ -2331,7 +2329,7 @@ public partial interface IDisposable } public partial interface IEquatable { - bool Equals([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T other); + bool Equals(T? other); } public partial interface IFormatProvider { @@ -5375,7 +5373,7 @@ public partial interface ICollection : System.Collections.Generic.IEnumerable } public partial interface IComparer { - int Compare([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); + int Compare(T? x, T? y); } public partial interface IDictionary : System.Collections.Generic.ICollection>, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { @@ -5397,7 +5395,7 @@ public partial interface IEnumerator : System.Collections.IEnumerator, Sy } public partial interface IEqualityComparer { - bool Equals([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); + bool Equals(T? x, T? y); int GetHashCode([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T obj); } public partial interface IList : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable diff --git a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs index 9fb5beead82c..97fbd6c4efbb 100644 --- a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs +++ b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs @@ -169,7 +169,6 @@ public CngKeyCreationParameters() { } public System.Security.Cryptography.CngKeyUsages? KeyUsage { get { throw null; } set { } } public System.Security.Cryptography.CngPropertyCollection Parameters { get { throw null; } } public System.IntPtr ParentWindowHandle { get { throw null; } set { } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] public System.Security.Cryptography.CngProvider Provider { get { throw null; } set { } } public System.Security.Cryptography.CngUIPolicy? UIPolicy { get { throw null; } set { } } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs b/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs index 13c292f6d7f1..28508857bc2b 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs @@ -98,8 +98,8 @@ protected SafeNCryptHandle(IntPtr handle, SafeHandle parentHandle) /// /// Wrapper for the _holder field which ensures that we're in a consistent state /// - [MaybeNull] - private SafeNCryptHandle Holder + [DisallowNull] + private SafeNCryptHandle? Holder { get { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs index d9c9f46693c8..94e8c460e4ce 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs @@ -67,14 +67,12 @@ public override byte[] GetSubjectKeyIdentifier(X509Certificate2 certificate) } } - [return: MaybeNull] - public override T GetPrivateKeyForSigning(X509Certificate2 certificate, bool silent) + public override T? GetPrivateKeyForSigning(X509Certificate2 certificate, bool silent) where T : class { return GetPrivateKey(certificate); } - [return: MaybeNull] - public override T GetPrivateKeyForDecryption(X509Certificate2 certificate, bool silent) + public override T? GetPrivateKeyForDecryption(X509Certificate2 certificate, bool silent) where T : class { return GetPrivateKey(certificate); } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs index 414f2228d6a5..a720ce02fd72 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs @@ -91,14 +91,12 @@ public sealed override byte[] GetSubjectKeyIdentifier(X509Certificate2 certifica } } - [return: MaybeNull] - public override T GetPrivateKeyForSigning(X509Certificate2 certificate, bool silent) + public override T? GetPrivateKeyForSigning(X509Certificate2 certificate, bool silent) where T : class { return GetPrivateKey(certificate, silent, preferNCrypt: true); } - [return: MaybeNull] - public override T GetPrivateKeyForDecryption(X509Certificate2 certificate, bool silent) + public override T? GetPrivateKeyForDecryption(X509Certificate2 certificate, bool silent) where T : class { return GetPrivateKey(certificate, silent, preferNCrypt: false); } 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 533f4f4a7513..4184827a8025 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -191,13 +191,10 @@ public static partial class JsonSerializer public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -211,13 +208,10 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val public static object? Deserialize(string json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static TValue? Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue? Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -533,8 +527,7 @@ public abstract partial class JsonConverter : System.Text.Json.Serialization. protected internal JsonConverter() { } public override bool CanConvert(System.Type typeToConvert) { throw null; } public virtual bool HandleNull { get { throw null; } } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public abstract T Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); + 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)] diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs index cd6c39c47a27..57dfef601c88 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs @@ -15,8 +15,7 @@ public partial class JsonConverter return ReadCore(ref reader, options, ref state); } - [return: MaybeNull] - internal T ReadCore( + internal T? ReadCore( ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state) @@ -35,7 +34,7 @@ internal T ReadCore( if (state.Current.ReturnValue == null) { // Avoid returning null for value types. - return default!; + return default; } return (T)state.Current.ReturnValue!; @@ -44,7 +43,7 @@ internal T ReadCore( { // Read more data until we have the full element. state.BytesConsumed += reader.BytesConsumed; - return default!; + return default; } } } @@ -55,7 +54,7 @@ internal T ReadCore( if (!SingleValueReadWithReadAhead(ClassType.Value, ref reader, ref state)) { state.BytesConsumed += reader.BytesConsumed; - return default!; + return default; } } 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 dfd81ffd871b..e6f7d84d3ea7 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 @@ -83,7 +83,7 @@ internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerO } // Provide a default implementation for value converters. - internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNull] out T value) + internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, out T? value) { value = Read(ref reader, typeToConvert, options); return true; @@ -99,10 +99,9 @@ internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, J /// The being converted. /// The being used. /// The value that was converted. - [return: MaybeNull] - public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); + public abstract T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); - internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNull] out T value) + internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, out T? value) { if (ClassType == ClassType.Value) { 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 85962cdb0bf5..9e24e2595422 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 @@ -249,7 +249,7 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Converter.TypeToConvert); } - value = default(T)!; + value = default(T); success = true; } else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs index fc0ce662715a..fbe746d6b128 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs @@ -12,8 +12,7 @@ namespace System.Text.Json.Serialization /// internal abstract class JsonResumableConverter : JsonConverter { - [return: MaybeNull] - public sealed override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public sealed override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // Bridge from resumable to value converters. if (options == null) 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 4e7946872454..76dd25b38278 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 @@ -12,8 +12,7 @@ public static partial class JsonSerializer // Members accessed by the serializer when deserializing. private const DynamicallyAccessedMemberTypes MembersAccessedOnRead = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties; - [return: MaybeNull] - private static TValue ReadCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) + private static TValue? ReadCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) { ReadStack state = default; state.Initialize(returnType, options, supportContinuation: false); @@ -21,8 +20,7 @@ private static TValue ReadCore(ref Utf8JsonReader reader, Type returnTyp return ReadCore(jsonConverter, ref reader, options, ref state); } - [return: MaybeNull] - private static TValue ReadCore(JsonConverter jsonConverter, ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state) + private static TValue? ReadCore(JsonConverter jsonConverter, ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state) { if (jsonConverter is JsonConverter converter) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs index 974ed2a0ca75..af9dd0e819c1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs @@ -22,8 +22,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - [return: MaybeNull] - public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) + public static TValue? Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) { if (options == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 24d1421aa387..b0c471cfcbd0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -35,7 +35,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - public static ValueTask DeserializeAsync<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>( + public static ValueTask DeserializeAsync<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>( Stream utf8Json, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) @@ -86,7 +86,7 @@ public static partial class JsonSerializer return ReadAsync(utf8Json, returnType, options, cancellationToken); } - private static async ValueTask ReadAsync( + private static async ValueTask ReadAsync( Stream utf8Json, Type returnType, JsonSerializerOptions? options, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs index bd9edb83e68f..af1f35da2214 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs @@ -34,8 +34,7 @@ public static partial class JsonSerializer /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// - [return: MaybeNull] - public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(string json, JsonSerializerOptions? options = null) + public static TValue? Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(string json, JsonSerializerOptions? options = null) { if (json == null) { @@ -84,8 +83,7 @@ public static partial class JsonSerializer return value; } - [return: MaybeNull] - private static TValue Deserialize(string json, Type returnType, JsonSerializerOptions? options) + private static TValue? Deserialize(string json, Type returnType, JsonSerializerOptions? options) { const long ArrayPoolMaxSizeBeforeUsingNormalAlloc = 1024 * 1024; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs index 9daac01bd1b3..4b424581307e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs @@ -52,8 +52,7 @@ public static partial class JsonSerializer /// Hence, , , are used while reading. /// /// - [return: MaybeNull] - public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) + public static TValue? Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) { if (options == null) { @@ -137,8 +136,7 @@ private static void CheckSupportedOptions(JsonReaderOptions readerOptions, strin } } - [return: MaybeNull] - private static TValue ReadValueCore(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state) + private static TValue? ReadValueCore(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state) { JsonReaderState readerState = reader.CurrentState; CheckSupportedOptions(readerState.Options, nameof(reader)); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Collections/HashtableExtensions.cs b/src/libraries/System.Text.RegularExpressions/src/System/Collections/HashtableExtensions.cs index e45e58460671..0df0e573b239 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Collections/HashtableExtensions.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Collections/HashtableExtensions.cs @@ -7,14 +7,15 @@ namespace System.Collections { internal static class HashtableExtensions { - public static bool TryGetValue(this Hashtable table, object key, [MaybeNull] out T value) + public static bool TryGetValue(this Hashtable table, object key, out T? value) { if (table.ContainsKey(key)) { value = (T)table[key]!; return true; } - value = default!; + + value = default; return false; } } 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 67106d328e80..9412cc28abfa 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 @@ -51,8 +51,7 @@ internal partial class AsyncOperation : AsyncOperation, IValueTaskSourc /// Only relevant to cancelable operations; 0 if the operation hasn't had completion reserved, 1 if it has. private volatile int _completionReserved; /// The result of the operation. - [MaybeNull, AllowNull] - private TResult _result = default; + private TResult? _result; /// Any error that occurred during the operation. private ExceptionDispatchInfo? _error; /// The continuation callback. @@ -454,7 +453,6 @@ public VoidAsyncOperationWithData(bool runContinuationsAsynchronously, Cancellat } /// The item being written. - [MaybeNull, AllowNull] - public TData Item { get; set; } = default!; + public TData? Item { get; set; } } } diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs index be088c5291b1..cec397b78bc3 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs @@ -105,7 +105,7 @@ public override bool TryRead([MaybeNullWhen(false)] out T item) } } - item = default!; + item = default; return false; } diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs index 6ac25fb99857..612d6b50f8f3 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs @@ -119,7 +119,7 @@ public override bool TryRead([MaybeNullWhen(false)] out T item) return true; } - item = default!; + item = default; return false; } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.cs b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.cs index e860e697ac7d..4931e851d6d3 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.cs @@ -30,8 +30,7 @@ public BatchBlock(int batchSize, System.Threading.Tasks.Dataflow.GroupingDataflo public void Complete() { } public System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - T[] System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + T[]? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, T messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } @@ -88,8 +87,7 @@ public void Complete() { } public System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } bool System.Threading.Tasks.Dataflow.IReceivableSourceBlock.TryReceiveAll([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList? items) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - T System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + T? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, T messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } @@ -105,8 +103,7 @@ public BufferBlock(System.Threading.Tasks.Dataflow.DataflowBlockOptions dataflow public void Complete() { } public System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - T System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + T? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, T messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } @@ -208,8 +205,7 @@ public partial interface IReceivableSourceBlock : System.Threading.Task } public partial interface ISourceBlock : System.Threading.Tasks.Dataflow.IDataflowBlock { - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - TOutput ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed); + TOutput? ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed); System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions); void ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target); bool ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target); @@ -267,8 +263,7 @@ public TransformBlock(System.Func transform, System.Threading.T public void Complete() { } public System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - TOutput System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + TOutput? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, TInput messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } @@ -288,8 +283,7 @@ public TransformManyBlock(System.Func target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - TOutput System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + TOutput? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, TInput messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } @@ -306,8 +300,7 @@ public void Complete() { } public System.IDisposable LinkTo(System.Threading.Tasks.Dataflow.ITargetBlock target, System.Threading.Tasks.Dataflow.DataflowLinkOptions linkOptions) { throw null; } void System.Threading.Tasks.Dataflow.IDataflowBlock.Fault(System.Exception exception) { } bool System.Threading.Tasks.Dataflow.IReceivableSourceBlock.TryReceiveAll([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList? items) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - T System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } + T? System.Threading.Tasks.Dataflow.ISourceBlock.ConsumeMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target, out bool messageConsumed) { throw null; } void System.Threading.Tasks.Dataflow.ISourceBlock.ReleaseReservation(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { } bool System.Threading.Tasks.Dataflow.ISourceBlock.ReserveMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, System.Threading.Tasks.Dataflow.ITargetBlock target) { throw null; } System.Threading.Tasks.Dataflow.DataflowMessageStatus System.Threading.Tasks.Dataflow.ITargetBlock.OfferMessage(System.Threading.Tasks.Dataflow.DataflowMessageHeader messageHeader, T messageValue, System.Threading.Tasks.Dataflow.ISourceBlock? source, bool consumeToAccept) { throw null; } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs index 45d7c5c4c033..2785f3ea4d4a 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs @@ -154,8 +154,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader message } /// - [return: MaybeNull] - T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { // This message should have only made it to the target if it passes the filter, so we shouldn't need to check again. // The real source will also be doing verifications, so we don't need to validate args here. @@ -621,8 +620,7 @@ internal void OfferToTarget() } /// Called by the target to consume the buffered message. - [return: MaybeNull] - TOutput ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + TOutput? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { // Validate arguments if (!messageHeader.IsValid) throw new ArgumentException(SR.Argument_InvalidMessageHeader, nameof(messageHeader)); @@ -1129,8 +1127,7 @@ private sealed class ReceiveTarget : TaskCompletionSource, ITargetBlock }; /// The received value if we accepted a value from the source. - [AllowNull, MaybeNull] - private T _receivedValue = default!; + private T? _receivedValue; /// The cancellation token source representing both external and internal cancellation. internal readonly CancellationTokenSource _cts = new CancellationTokenSource(); @@ -1664,8 +1661,7 @@ public bool TryReceiveAll([NotNullWhen(true)] out IList? items) } /// - [return: MaybeNull] - public TOutput ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + public TOutput? ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/ISourceBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/ISourceBlock.cs index 518f8fb02663..8e4d27af8bf9 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/ISourceBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/ISourceBlock.cs @@ -27,8 +27,7 @@ public interface ISourceBlock : IDataflowBlock // IMPLEMENT EXPLICITLY /// - [return: MaybeNull] - TOutput ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed); + TOutput? ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed); /// bool ReserveMessage(DataflowMessageHeader messageHeader, ITargetBlock target); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchBlock.cs index df9bb9c980f3..af2775e9031f 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchBlock.cs @@ -154,8 +154,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader message } /// - [return: MaybeNull] - T[] ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T[]? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchedJoinBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchedJoinBlock.cs index 054eaa3bc19e..8099f49cae70 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchedJoinBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BatchedJoinBlock.cs @@ -172,8 +172,7 @@ void IDataflowBlock.Fault(Exception exception) } /// - [return: MaybeNull] - Tuple, IList> ISourceBlock, IList>>.ConsumeMessage( + Tuple, IList>? ISourceBlock, IList>>.ConsumeMessage( DataflowMessageHeader messageHeader, ITargetBlock, IList>> target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); @@ -436,8 +435,7 @@ void IDataflowBlock.Fault(Exception exception) } /// - [return: MaybeNull] - Tuple, IList, IList> ISourceBlock, IList, IList>>.ConsumeMessage( + Tuple, IList, IList>? ISourceBlock, IList, IList>>.ConsumeMessage( DataflowMessageHeader messageHeader, ITargetBlock, IList, IList>> target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs index 508d151b0431..9f9b93298f86 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs @@ -417,8 +417,7 @@ private void CompleteTargetIfPossible() } /// - [return: MaybeNull] - T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } @@ -531,8 +530,7 @@ private sealed class BroadcastingSourceCore /// An indicator whether _currentMessage has a value. private bool _currentMessageIsValid; /// The message currently being broadcast. - [AllowNull, MaybeNull] - private TOutput _currentMessage = default; + private TOutput? _currentMessage; /// The target that the next message is reserved for, or null if nothing is reserved. private ITargetBlock? _nextMessageReservedFor; /// Whether this block should again attempt to offer messages to targets. @@ -1049,8 +1047,7 @@ internal IDisposable LinkTo(ITargetBlock target, DataflowLinkOptions li } /// - [return: MaybeNull] - internal TOutput ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + internal TOutput? ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { // Validate arguments if (!messageHeader.IsValid) throw new ArgumentException(SR.Argument_InvalidMessageHeader, nameof(messageHeader)); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BufferBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BufferBlock.cs index dc7b45d96499..6d5e702bb7f0 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BufferBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BufferBlock.cs @@ -197,8 +197,7 @@ private void CompleteCore(Exception? exception, bool storeExceptionEvenIfAlready public Task Completion { get { return _source.Completion; } } /// - [return: MaybeNull] - T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformBlock.cs index cbaff49b6c82..b5267ca25681 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformBlock.cs @@ -368,8 +368,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader me } /// - [return: MaybeNull] - TOutput ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + TOutput? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.cs index a1d7dcc1e0aa..0e6ddfab1412 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.cs @@ -601,8 +601,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader me } /// - [return: MaybeNull] - TOutput ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + TOutput? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _source.ConsumeMessage(messageHeader, target, out messageConsumed); } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/WriteOnceBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/WriteOnceBlock.cs index 22d052a15364..244703a9d895 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/WriteOnceBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/WriteOnceBlock.cs @@ -39,8 +39,7 @@ public sealed class WriteOnceBlock : IPropagatorBlock, IReceivableSourc /// The header of the singly-assigned value. private DataflowMessageHeader _header; /// The singly-assigned value. - [AllowNull, MaybeNull] - private T _value = default; + private T? _value; /// Gets the object used as the value lock. private object ValueLock { get { return _targetRegistry; } } @@ -381,7 +380,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader message } /// - T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { // Validate arguments if (!messageHeader.IsValid) throw new ArgumentException(SR.Argument_InvalidMessageHeader, nameof(messageHeader)); @@ -397,7 +396,7 @@ T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlo else { messageConsumed = false; - return default(T)!; + return default; } } @@ -506,8 +505,7 @@ private TaskCompletionSource CompletionTaskSource /// Gets whether the block is storing a value. private bool HasValue { get { return _header.IsValid; } } /// Gets the value being stored by the block. - [MaybeNull] - private T Value { get { return _header.IsValid ? _value : default(T); } } + private T? Value { get { return _header.IsValid ? _value : default(T); } } /// public override string ToString() { return Common.GetNameForDebugger(this, _dataflowBlockOptions); } @@ -546,8 +544,7 @@ public DebugView(WriteOnceBlock writeOnceBlock) /// Gets whether the WriteOnceBlock has a value. public bool HasValue { get { return _writeOnceBlock.HasValue; } } /// Gets the WriteOnceBlock's value if it has one, or default(T) if it doesn't. - [MaybeNull] - public T Value { get { return _writeOnceBlock.Value; } } + public T? Value { get { return _writeOnceBlock.Value; } } /// Gets the DataflowBlockOptions used to configure this block. public DataflowBlockOptions DataflowBlockOptions { get { return _writeOnceBlock._dataflowBlockOptions; } } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs index 275b2931a408..0022621f04d8 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs @@ -93,8 +93,7 @@ internal static bool TryKeepAliveUntil(KeepAlivePredicateThe type of the data to be unwrapped. /// The weak reference. /// The T instance. - [return: MaybeNull] - internal static T UnwrapWeakReference(object state) where T : class + internal static T? UnwrapWeakReference(object state) where T : class { var wr = state as WeakReference; Debug.Assert(wr != null, "Expected a WeakReference as the state argument"); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/ReorderingBuffer.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/ReorderingBuffer.cs index e69865bfd7aa..80513f6eae2e 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/ReorderingBuffer.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/ReorderingBuffer.cs @@ -66,7 +66,7 @@ internal ReorderingBuffer(object owningSource, Action outputAct /// The ID of the item. /// The completed item. /// Specifies whether the item is valid (true) or just a placeholder (false). - internal void AddItem(long id, [AllowNull] TOutput item, bool itemIsValid) + internal void AddItem(long id, TOutput? item, bool itemIsValid) { Debug.Assert(id != Common.INVALID_REORDERING_ID, "This ID should never have been handed out."); Common.ContractAssertMonitorStatus(ValueLock, held: false); @@ -104,7 +104,7 @@ internal void AddItem(long id, [AllowNull] TOutput item, bool itemIsValid) /// true if the item was not added but is next in line. /// false if the item was not added and is not next in line. /// - internal bool? AddItemIfNextAndTrusted(long id, [AllowNull] TOutput item, bool isTrusted) + internal bool? AddItemIfNextAndTrusted(long id, TOutput? item, bool isTrusted) { Debug.Assert(id != Common.INVALID_REORDERING_ID, "This ID should never have been handed out."); Common.ContractAssertMonitorStatus(ValueLock, held: false); @@ -138,7 +138,7 @@ public void IgnoreItem(long id) /// Outputs the item. The item must have already been confirmed to have the next ID. /// The item to output. /// Whether the item is valid. - private void OutputNextItem([AllowNull] TOutput theNextItem, bool itemIsValid) + private void OutputNextItem(TOutput? theNextItem, bool itemIsValid) { Common.ContractAssertMonitorStatus(ValueLock, held: true); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs index 99d772c1ad66..a9e86e683c28 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs @@ -155,8 +155,7 @@ internal IDisposable LinkTo(ITargetBlock target, DataflowLinkOptions li } /// - [return: MaybeNull] - internal TOutput ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + internal TOutput? ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { // Validate arguments if (!messageHeader.IsValid) throw new ArgumentException(SR.Argument_InvalidMessageHeader, nameof(messageHeader)); diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/TargetRegistry.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/TargetRegistry.cs index 9420fc8854a2..6cc23ec53986 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/TargetRegistry.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/TargetRegistry.cs @@ -331,8 +331,7 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader message } /// - [return: MaybeNull] - T ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) + T? ISourceBlock.ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock target, out bool messageConsumed) { return _owningSource.ConsumeMessage(messageHeader, this, out messageConsumed); } diff --git a/src/libraries/System.Threading/ref/System.Threading.cs b/src/libraries/System.Threading/ref/System.Threading.cs index d5fceaafaf60..888abda4af76 100644 --- a/src/libraries/System.Threading/ref/System.Threading.cs +++ b/src/libraries/System.Threading/ref/System.Threading.cs @@ -35,10 +35,8 @@ public readonly partial struct AsyncLocalValueChangedArgs private readonly T _PreviousValue_k__BackingField; private readonly T _CurrentValue_k__BackingField; private readonly int _dummyPrimitive; - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T CurrentValue { get { throw null; } } - [System.Diagnostics.CodeAnalysis.MaybeNullAttribute] - public T PreviousValue { get { throw null; } } + public T? CurrentValue { get { throw null; } } + public T? PreviousValue { get { throw null; } } public bool ThreadContextChanged { get { throw null; } } } public sealed partial class AsyncLocal diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/TypeIdentifier.cs b/src/mono/netcore/System.Private.CoreLib/src/System/TypeIdentifier.cs index a4bc5ace9b7b..e54fecd7df3c 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/TypeIdentifier.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/TypeIdentifier.cs @@ -74,7 +74,7 @@ internal abstract class ATypeName : ITypeName public abstract ITypeName NestedName(ITypeIdentifier innerName); - public bool Equals([AllowNull] ITypeName other) + public bool Equals(ITypeName? other) { return other != null && DisplayName == other.DisplayName; } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/WeakReference.T.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/WeakReference.T.Mono.cs index 8ab12b5977a8..e4c4b0af7bea 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/WeakReference.T.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/WeakReference.T.Mono.cs @@ -11,8 +11,7 @@ public partial class WeakReference private GCHandle handle; private bool trackResurrection; - [MaybeNull] - private T Target + private T? Target { get { From 03022564c9e5e9a18330432c2d7fa8316256b599 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 7 Aug 2020 08:36:19 -0700 Subject: [PATCH 321/755] [JsonSerializer] Verify null can't be assigned to non-nullable structs (#40446) --- .../tests/Serialization/Array.ReadTests.cs | 7 +++++-- .../tests/Serialization/Null.ReadTests.cs | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs index 780c8c1e4a40..6f917532323b 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs @@ -616,8 +616,7 @@ static void TestRoundTrip(ClassWithNonNullEnumerableGetters obj) Assert.Equal(0, obj.MyImmutableList.Count); TestRoundTrip(obj); - // TODO: Skip ImmutableArray due to https://github.com/dotnet/runtime/issues/1037. - const string inputJsonWithNullCollections = + string inputJsonWithNullCollections = @"{ ""Array"":null, ""List"":null, @@ -627,6 +626,10 @@ static void TestRoundTrip(ClassWithNonNullEnumerableGetters obj) obj = JsonSerializer.Deserialize(inputJsonWithNullCollections); TestRoundTrip(obj); + + // ImmutableArray is a struct and cannot be null. + inputJsonWithNullCollections = @"{""MyImmutableArray"":null}"; + Assert.Throws(() => JsonSerializer.Deserialize(inputJsonWithNullCollections)); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs index df8715e54c5d..0f32389207a5 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs @@ -168,25 +168,33 @@ public static void NullReadTestChar() Assert.Equal('Y', JsonSerializer.Deserialize("\"\u0059\"")); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/1037")] [Fact] public static void ParseNullStringToStructShouldThrowJsonException() { string nullString = "null"; - Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(nullString)); + byte[] nullStringAsBytes = Encoding.UTF8.GetBytes(nullString); + + Utf8JsonReader reader = new Utf8JsonReader(nullStringAsBytes); JsonTestHelper.AssertThrows(reader, (reader) => JsonSerializer.Deserialize(ref reader)); - Assert.Throws(() => JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(nullString))); + Assert.Throws(() => JsonSerializer.Deserialize(nullStringAsBytes)); Assert.Throws(() => JsonSerializer.Deserialize(nullString)); + + // null can be assigned to nullable structs. + Assert.Null(JsonSerializer.Deserialize(nullStringAsBytes)); + Assert.Null(JsonSerializer.Deserialize(nullString)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/1037")] [Fact] public static async Task ParseNullStringShouldThrowJsonExceptionAsync() { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("null"))) { await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(stream)); + + // null can be assigned to nullable structs. + stream.Position = 0; + Assert.Null(await JsonSerializer.DeserializeAsync(stream)); } } From aa02ca29fa41a56dcd2676187d056e2ed771e61d Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 7 Aug 2020 08:44:54 -0700 Subject: [PATCH 322/755] Add code to preserve public fields of input types to JsonSerializer (#40508) --- .../JsonSerializer.Read.Helpers.cs | 3 ++- .../JsonSerializer.Write.Helpers.cs | 2 +- .../tests/TrimmingTests/Helper.cs | 20 ++++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) 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 76dd25b38278..8b4909ad4ca1 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 @@ -10,7 +10,8 @@ namespace System.Text.Json public static partial class JsonSerializer { // Members accessed by the serializer when deserializing. - private const DynamicallyAccessedMemberTypes MembersAccessedOnRead = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties; + private const DynamicallyAccessedMemberTypes MembersAccessedOnRead = + DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields; private static TValue? ReadCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs index 96c33a06255a..d23528f786f8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs @@ -10,7 +10,7 @@ namespace System.Text.Json public static partial class JsonSerializer { // Members accessed by the serializer when serializing. - private const DynamicallyAccessedMemberTypes MembersAccessedOnWrite = DynamicallyAccessedMemberTypes.PublicProperties; + private const DynamicallyAccessedMemberTypes MembersAccessedOnWrite = DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields; private static void WriteCore( Utf8JsonWriter writer, diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs index a9593b9f3ab1..b99a5a895624 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs @@ -90,16 +90,18 @@ public static bool AssertCollectionAndSerialize(object obj, string json) } } - internal class MyClass + public class MyClass { public int X { get; set; } - public int Y { get; set; } + [JsonInclude] + public int Y; } internal struct MyStruct { public int X { get; } - public int Y { get; } + [JsonInclude] + public int Y; [JsonConstructor] public MyStruct(int x, int y) => (X, Y) = (x, y); @@ -108,7 +110,8 @@ internal struct MyStruct internal class MyClassWithParameterizedCtor { public int X { get; set; } - public int Y { get; set; } + [JsonInclude] + public int Y; public MyClassWithParameterizedCtor(int x, int y) => (X, Y) = (x, y); } @@ -116,11 +119,14 @@ internal class MyClassWithParameterizedCtor internal class MyBigClass { public string A { get; } - public string B { get; } + [JsonInclude] + public string B; public string C { get; } - public int One { get; } + [JsonInclude] + public int One; public int Two { get; } - public int Three { get; } + [JsonInclude] + public int Three; public MyBigClass(string a, string b, string c, int one, int two, int three) { From 16ad2eab13df7d8c16ac8e8b83bd8dc87791b95b Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 7 Aug 2020 08:56:52 -0700 Subject: [PATCH 323/755] Disable formatting for outerloop. (#40517) --- eng/pipelines/coreclr/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index 7e72c87e16b8..c58c4804174b 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -164,4 +164,5 @@ jobs: jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml platforms: - Linux_x64 - - Windows_NT_x64 + # Isssue: https://github.com/dotnet/runtime/issues/40034 + #- Windows_NT_x64 From 9b3434ae2e25e4beb985e403d7abf67921aaa57e Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Fri, 7 Aug 2020 09:05:39 -0700 Subject: [PATCH 324/755] Handle 16 byte HFA fields in arm64 profiler (#40482) Fixes #40277. --- src/coreclr/src/vm/arm64/profiler.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/vm/arm64/profiler.cpp b/src/coreclr/src/vm/arm64/profiler.cpp index ba35eb103eec..2b6a2e69ea51 100644 --- a/src/coreclr/src/vm/arm64/profiler.cpp +++ b/src/coreclr/src/vm/arm64/profiler.cpp @@ -260,12 +260,17 @@ LPVOID ProfileArgIterator::GetReturnBufferAddr(void) *(UINT32*)dest = *(UINT32*)&pData->floatArgumentRegisters.q[floatRegIdx]; dest += 4; } - else + else if (hfaFieldSize == 8) { - _ASSERTE(hfaFieldSize == 8); *(UINT64*)dest = *(UINT64*)&pData->floatArgumentRegisters.q[floatRegIdx]; dest += 8; } + else + { + _ASSERTE(hfaFieldSize == 16); + *(NEON128*)dest = pData->floatArgumentRegisters.q[floatRegIdx]; + dest += 16; + } if (floatRegIdx > 8) { From 98bf6ddc5941a77e67eea84a698ceab849705a6a Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Fri, 7 Aug 2020 09:16:38 -0700 Subject: [PATCH 325/755] Add -y to apt-get install commands (#40492) --- eng/pipelines/coreclr/templates/run-performance-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 7b7cf524758a..c38d33405cca 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -53,7 +53,7 @@ jobs: - IsInternal: '' - HelixApiAccessToken: '' - HelixPreCommandStemWindows: 'py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install --user azure.storage.blob==12.0.0 --force-reinstall;py -3 -m pip install --user azure.storage.queue==12.0.0 --force-reinstall;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get install nodejs;sudo apt-get install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get -y install nodejs;sudo apt-get -y install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"' - ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"' - HelixPreCommand: '' From 2b93f831736a44998b9b58a249dfd57d08ef319f Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Fri, 7 Aug 2020 09:18:40 -0700 Subject: [PATCH 326/755] Fix Japanese Abbreviated Era Names (#40300) --- .../DateTimeFormatInfoTests.cs | 22 +++++++++++ .../System/Globalization/GregorianCalendar.cs | 2 +- .../Globalization/JapaneseCalendar.Icu.cs | 37 +++++++++++++++---- .../System/Globalization/JapaneseCalendar.cs | 8 ++-- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs index 52cda26a787a..90c94defe96a 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs @@ -187,5 +187,27 @@ public void TestFirstYearOfJapaneseEra() $"Parsing '{formattedDateWithGannen}' result should match if '{formattedDate}' has Gan-nen symbol" ); } + + [Fact] + public void JapaneseAbbreviatedEnglishEraNamesTest() + { + string [] eraNames = { "M", "T", "S", "H", "R" }; + + var ci = new CultureInfo("ja-JP") { DateTimeFormat = { Calendar = new JapaneseCalendar() }}; + + int eraNumber = ci.DateTimeFormat.GetEra("Q"); + if (eraNumber == 4 || eraNumber == 5) + { + // Skip the test on Windows versions which have wrong Japanese Era information. + // Windows at some point used "Q" as fake era name before getting the official name. + return; + } + + int numberOfErasToTest = Math.Min(eraNames.Length, ci.DateTimeFormat.Calendar.Eras.Length); + for (int i = 0; i < numberOfErasToTest; i++) + { + Assert.Equal(i + 1, ci.DateTimeFormat.GetEra(eraNames[i])); + } + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs index 1aa2b0247a56..4f7bf1c3184d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs @@ -35,7 +35,7 @@ public class GregorianCalendar : Calendar public override CalendarAlgorithmType AlgorithmType => CalendarAlgorithmType.SolarCalendar; /// - /// Internal method to provide a default intance of GregorianCalendar. + /// Internal method to provide a default instance of GregorianCalendar. /// Used by NLS+ implementation /// internal static Calendar GetDefaultInstance() => s_defaultInstance ??= new GregorianCalendar(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs index cfc47d72da67..5ac43a99e56c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs @@ -8,6 +8,8 @@ namespace System.Globalization { public partial class JapaneseCalendar : Calendar { + private static readonly string [] s_abbreviatedEnglishEraNames = { "M", "T", "S", "H", "R" }; + private static EraInfo[]? IcuGetJapaneseEras() { if (GlobalizationMode.Invariant) @@ -23,16 +25,11 @@ public partial class JapaneseCalendar : Calendar return null; } - string[]? abbrevEnglishEraNames; - if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames)) - { - return null; - } - List eras = new List(); int lastMaxYear = GregorianCalendar.MaxYear; int latestEra = Interop.Globalization.GetLatestJapaneseEra(); + for (int i = latestEra; i >= 0; i--) { DateTime dt; @@ -47,16 +44,40 @@ public partial class JapaneseCalendar : Calendar break; } - eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1, - eraNames![i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames![i])); + eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1, eraNames![i], GetAbbreviatedEraName(eraNames, i), "")); lastMaxYear = dt.Year; } + string[] abbrevEnglishEraNames; + if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames!)) + { + // Failed to get English names. fallback to hardcoded data. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + + // Check if we are getting the English Name at the end of the returned list. + // ICU usually return long list including all Era names written in Japanese characters except the recent eras which actually we support will be returned in English. + // We have the following check as older ICU versions doesn't carry the English names (e.g. ICU version 50). + if (abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1].Length == 0 || abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1][0] > '\u007F') + { + // Couldn't get English names. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + + int startIndex = abbrevEnglishEraNames == s_abbreviatedEnglishEraNames ? eras.Count - 1 : abbrevEnglishEraNames.Length - 1; + + Debug.Assert(abbrevEnglishEraNames == s_abbreviatedEnglishEraNames || eras.Count <= abbrevEnglishEraNames.Length); + // remap the Era numbers, now that we know how many there will be for (int i = 0; i < eras.Count; i++) { eras[i].era = eras.Count - i; + if (startIndex < abbrevEnglishEraNames.Length) + { + eras[i].englishEraName = abbrevEnglishEraNames[startIndex]; + } + startIndex--; } return eras.ToArray(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs index b147247faf32..ba6b3087cd82 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs @@ -5,17 +5,17 @@ namespace System.Globalization { /// /// JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as - /// Gregorian calendar. However, the year value is an offset to the Gregorian + /// Gregorian calendar. However, the year value is an offset to the Gregorian /// year based on the era. /// /// This system is adopted by Emperor Meiji in 1868. The year value is counted based on the reign of an emperor, /// and the era begins on the day an emperor ascends the throne and continues until his death. /// The era changes at 12:00AM. /// - /// For example, the current era is Reiwa. It started on 2019/5/1 A.D. Therefore, Gregorian year 2019 is also Reiwa 1st. + /// For example, the current era is Reiwa. It started on 2019/5/1 A.D. Therefore, Gregorian year 2019 is also Reiwa 1st. /// 2019/5/1 A.D. is also Reiwa 1st 5/1. /// - /// Any date in the year during which era is changed can be reckoned in either era. For example, + /// Any date in the year during which era is changed can be reckoned in either era. For example, /// 2019/1/1 can be 1/1 Reiwa 1st year or 1/1 Heisei 31st year. /// /// Note: @@ -50,7 +50,7 @@ public partial class JapaneseCalendar : Calendar // // We know about 4 built-in eras, however users may add additional era(s) from the // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras - // we don't read the registry and instead we call WinRT to get the needed informatio + // we don't read the registry and instead we call WinRT to get the needed information // // Registry values look like: // yyyy.mm.dd=era_abbrev_english_englishabbrev From 4b593940ee884ad4c1dd0712ced488e3127be4c6 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Fri, 7 Aug 2020 09:52:30 -0700 Subject: [PATCH 327/755] add NetworkException (#40344) * add NetworkException --- .../src/System/Net/NetworkErrorHelper.cs | 26 +++++ .../src/System.Net.Http.csproj | 2 + .../Connections/SocketConnection.cs | 48 ++-------- .../SocketsHttpConnectionFactory.cs | 5 + .../FunctionalTests/SocketsHttpHandlerTest.cs | 4 +- .../ref/System.Net.Primitives.cs | 17 ++++ .../src/Resources/Strings.resx | 21 ++++ .../src/System.Net.Primitives.csproj | 2 + .../src/System/Net/NetworkError.cs | 30 ++++++ .../src/System/Net/NetworkException.cs | 52 ++++++++++ .../FunctionalTests/NetworkExceptionTest.cs | 34 +++++++ ...tem.Net.Primitives.Functional.Tests.csproj | 1 + .../src/System.Net.Sockets.csproj | 2 + .../src/System/Net/Sockets/NetworkStream.cs | 95 ++++++++++++------- .../src/System/Net/Sockets/Socket.Tasks.cs | 12 +-- .../FunctionalTests/NetworkStreamTest.cs | 38 ++++---- 16 files changed, 289 insertions(+), 100 deletions(-) create mode 100644 src/libraries/Common/src/System/Net/NetworkErrorHelper.cs create mode 100644 src/libraries/System.Net.Primitives/src/System/Net/NetworkError.cs create mode 100644 src/libraries/System.Net.Primitives/src/System/Net/NetworkException.cs create mode 100644 src/libraries/System.Net.Primitives/tests/FunctionalTests/NetworkExceptionTest.cs diff --git a/src/libraries/Common/src/System/Net/NetworkErrorHelper.cs b/src/libraries/Common/src/System/Net/NetworkErrorHelper.cs new file mode 100644 index 000000000000..e305163ed8fe --- /dev/null +++ b/src/libraries/Common/src/System/Net/NetworkErrorHelper.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.Net.Sockets; + +namespace System.Net +{ + internal static class NetworkErrorHelper + { + internal static NetworkException MapSocketException(SocketException socketException) + { + NetworkError error = socketException.SocketErrorCode switch + { + SocketError.AddressAlreadyInUse => NetworkError.EndPointInUse, + SocketError.HostNotFound => NetworkError.HostNotFound, + SocketError.ConnectionRefused => NetworkError.ConnectionRefused, + SocketError.OperationAborted => NetworkError.OperationAborted, + SocketError.ConnectionAborted => NetworkError.ConnectionAborted, + SocketError.ConnectionReset => NetworkError.ConnectionReset, + _ => NetworkError.Unknown + }; + + return new NetworkException(error, socketException); + } + } +} 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 1e2ceae09b72..420af9b298b7 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -109,6 +109,8 @@ Link="Common\System\IO\StreamHelpers.CopyValidation.cs" /> + _stream.Socket.RemoteEndPoint; public override EndPoint? LocalEndPoint => _stream.Socket.LocalEndPoint; @@ -19,7 +21,7 @@ internal sealed class SocketConnection : Connection, IConnectionProperties public SocketConnection(Socket socket) { - _stream = new SocketConnectionNetworkStream(socket, this); + _stream = new NetworkStream(socket, ownsSocket: true); } protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) @@ -38,7 +40,11 @@ protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, Cancel _stream.Socket.Dispose(); } - _stream.DisposeWithoutClosingConnection(); + _stream.Dispose(); + } + catch (SocketException socketException) + { + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException))); } catch (Exception ex) { @@ -61,41 +67,5 @@ bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out obje property = null; return false; } - - // This is done to couple disposal of the SocketConnection and the NetworkStream. - private sealed class SocketConnectionNetworkStream : NetworkStream - { - private readonly SocketConnection _connection; - - public SocketConnectionNetworkStream(Socket socket, SocketConnection connection) : base(socket, ownsSocket: true) - { - _connection = connection; - } - - public void DisposeWithoutClosingConnection() - { - base.Dispose(true); - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - // This will call base.Dispose(). - _connection.Dispose(); - } - else - { - base.Dispose(disposing); - } - } - - public override ValueTask DisposeAsync() - { - // This will call base.Dispose(). - Dispose(true); - return default; - } - } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs index e224616c9e3f..34018a14170a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs @@ -79,6 +79,11 @@ public virtual async ValueTask EstablishConnectionAsync(HttpRequestM socket.NoDelay = true; return new SocketConnection(socket); } + catch (SocketException socketException) + { + socket.Dispose(); + throw NetworkErrorHelper.MapSocketException(socketException); + } catch { socket.Dispose(); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 71c9e27bdfa5..551ce4e96b63 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -160,7 +160,9 @@ public async Task CustomConnectionFactory_SyncRequest_Fails() using HttpClient client = CreateHttpClient(handler); - await Assert.ThrowsAnyAsync(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo")); + HttpRequestException e = await Assert.ThrowsAnyAsync(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo")); + NetworkException networkException = Assert.IsType(e.InnerException); + Assert.Equal(NetworkError.HostNotFound, networkException.NetworkError); } } diff --git a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs index 899fa7d7d68e..9127d1bf3ca5 100644 --- a/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs +++ b/src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs @@ -322,6 +322,23 @@ public abstract partial class TransportContext protected TransportContext() { } public abstract System.Security.Authentication.ExtendedProtection.ChannelBinding? GetChannelBinding(System.Security.Authentication.ExtendedProtection.ChannelBindingKind kind); } + public enum NetworkError : int + { + Unknown = 0, + EndPointInUse, + HostNotFound, + ConnectionRefused, + OperationAborted, + ConnectionAborted, + ConnectionReset, + } + public class NetworkException : System.IO.IOException + { + public NetworkException(NetworkError error, Exception? innerException = null) { } + public NetworkException(string message, NetworkError error, Exception? innerException = null) { } + protected NetworkException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } + public NetworkError NetworkError { get { throw null; } } + } } namespace System.Net.Cache { diff --git a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx index d95ea7484aac..d0dbe85701a4 100644 --- a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx @@ -114,4 +114,25 @@ An invalid IPEndPoint was specified. + + An unknown network error occurred. + + + The requested EndPoint is already in use. + + + No connection could be made because the remote host actively refused it. + + + No such host is known. + + + The operation was aborted by the user. + + + The connection was aborted by the local host. + + + The connection was forcibly closed by the remote host. + diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index 07f176ab3ad6..413d76f6925c 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -34,6 +34,8 @@ + + diff --git a/src/libraries/System.Net.Primitives/src/System/Net/NetworkError.cs b/src/libraries/System.Net.Primitives/src/System/Net/NetworkError.cs new file mode 100644 index 000000000000..44bcac8678a2 --- /dev/null +++ b/src/libraries/System.Net.Primitives/src/System/Net/NetworkError.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.Net +{ + /// Defines a set of error codes for use with . + public enum NetworkError : int + { + /// An unknown network error occurred. + Unknown = 0, + + /// The requested EndPoint is already in use. + EndPointInUse, + + /// No such host is known. + HostNotFound, + + /// No connection could be made because the remote host actively refused it. + ConnectionRefused, + + /// The operation was aborted by the user. + OperationAborted, + + /// The connection was aborted by the local host. + ConnectionAborted, + + /// The connection was forcibly closed by the remote host. + ConnectionReset, + } +} diff --git a/src/libraries/System.Net.Primitives/src/System/Net/NetworkException.cs b/src/libraries/System.Net.Primitives/src/System/Net/NetworkException.cs new file mode 100644 index 000000000000..7b1b48f93791 --- /dev/null +++ b/src/libraries/System.Net.Primitives/src/System/Net/NetworkException.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Runtime.Serialization; + +namespace System.Net +{ + /// Provides socket exceptions to the application. + [Serializable] + public class NetworkException : IOException + { + /// Creates a new instance of the class with the specified error code. + public NetworkException(NetworkError error, Exception? innerException = null) + : this(GetExceptionMessage(error), error, innerException) {} + + /// Creates a new instance of the class with the specified error code and message. + public NetworkException(string message, NetworkError error, Exception? innerException = null) + : base(message, innerException) + { + NetworkError = error; + } + + /// Creates a new instance of the from serialized data. + protected NetworkException(SerializationInfo serializationInfo, StreamingContext streamingContext) + : base(serializationInfo, streamingContext) + { + NetworkError = (NetworkError)serializationInfo.GetInt32("NetworkError"); + } + + /// Populates the serialization data for this object. + public override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + base.GetObjectData(serializationInfo, streamingContext); + serializationInfo.AddValue("NetworkError", (int)NetworkError); + } + + /// Returns the specific kind of error. + public NetworkError NetworkError { get; } + + private static string GetExceptionMessage(NetworkError error) => error switch + { + NetworkError.EndPointInUse => SR.networkerror_addressinuse, + NetworkError.HostNotFound => SR.networkerror_hostnotfound, + NetworkError.ConnectionRefused => SR.networkerror_connectionrefused, + NetworkError.ConnectionAborted => SR.networkerror_connectionaborted, + NetworkError.ConnectionReset => SR.networkerror_connectionreset, + NetworkError.OperationAborted => SR.networkerror_operationaborted, + _ => SR.networkerror_unknown + }; + } +} diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/NetworkExceptionTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/NetworkExceptionTest.cs new file mode 100644 index 000000000000..a7f60c9de162 --- /dev/null +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/NetworkExceptionTest.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Net.Primitives.Functional.Tests +{ + public static class NetworkExceptionTest + { + [Fact] + public static void Create_AllErrorCodes_Success() + { + foreach (NetworkError error in Enum.GetValues(typeof(NetworkError))) + { + NetworkException e = new NetworkException(error); + Assert.Equal(error, e.NetworkError); + Assert.Null(e.InnerException); + Assert.NotNull(e.Message); + } + } + + [Fact] + public static void Create_InnerExceptionAndMessage_Success() + { + const string Message = "Hello"; + Exception inner = new Exception(); + + NetworkException e = new NetworkException(Message, NetworkError.Unknown, inner); + + Assert.Equal(inner, e.InnerException); + Assert.Equal(Message, e.Message); + } + } +} diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj b/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj index 26cd2568e157..215b3411c287 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj @@ -20,6 +20,7 @@ + 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 ae0f96d5351e..4d39c2d94a77 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -95,6 +95,8 @@ Link="Common\System\Net\Sockets\ProtocolType.cs" /> + diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index d6fa0458bdc5..e2a3ac6fff45 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -50,15 +50,15 @@ public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) // allowing non-blocking sockets could result in non-deterministic failures from those // operations. A developer that requires using NetworkStream with a non-blocking socket can // temporarily flip Socket.Blocking as a workaround. - throw new IOException(SR.net_sockets_blocking); + throw GetCustomNetworkException(SR.net_sockets_blocking); } if (!socket.Connected) { - throw new IOException(SR.net_notconnected); + throw GetCustomNetworkException(SR.net_notconnected); } if (socket.SocketType != SocketType.Stream) { - throw new IOException(SR.net_notstream); + throw GetCustomNetworkException(SR.net_notstream); } _streamSocket = socket; @@ -241,11 +241,13 @@ public override int Read(byte[] buffer, int offset, int size) { return _streamSocket.Receive(buffer, offset, size, 0); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } } @@ -266,7 +268,7 @@ public override int Read(Span buffer) if (errorCode != SocketError.Success) { var exception = new SocketException((int)errorCode); - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw NetworkErrorHelper.MapSocketException(exception); } return bytesRead; } @@ -322,11 +324,13 @@ public override void Write(byte[] buffer, int offset, int size) // after ALL the requested number of bytes was transferred. _streamSocket.Send(buffer, offset, size, SocketFlags.None); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } } @@ -348,7 +352,7 @@ public override void Write(ReadOnlySpan buffer) if (errorCode != SocketError.Success) { var exception = new SocketException((int)errorCode); - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw NetworkErrorHelper.MapSocketException(exception); } } @@ -443,11 +447,13 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, Asyn callback, state); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } } @@ -473,11 +479,13 @@ public override int EndRead(IAsyncResult asyncResult) { return _streamSocket.EndReceive(asyncResult); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } } @@ -529,11 +537,13 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, Asy callback, state); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } } @@ -555,11 +565,13 @@ public override void EndWrite(IAsyncResult asyncResult) { _streamSocket.EndSend(asyncResult); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } } @@ -609,11 +621,13 @@ public override Task ReadAsync(byte[] buffer, int offset, int size, Cancell fromNetworkStream: true, cancellationToken).AsTask(); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } } @@ -634,11 +648,13 @@ public override ValueTask ReadAsync(Memory buffer, CancellationToken fromNetworkStream: true, cancellationToken: cancellationToken); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } } @@ -687,11 +703,13 @@ public override Task WriteAsync(byte[] buffer, int offset, int size, Cancellatio SocketFlags.None, cancellationToken).AsTask(); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } } @@ -711,11 +729,13 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo SocketFlags.None, cancellationToken); } + catch (SocketException socketException) + { + throw NetworkErrorHelper.MapSocketException(socketException); + } catch (Exception exception) when (!(exception is OutOfMemoryException)) { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); + throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } } @@ -772,5 +792,10 @@ private void ThrowIfDisposed() void ThrowObjectDisposedException() => throw new ObjectDisposedException(GetType().FullName); } + + private static NetworkException GetCustomNetworkException(string message, Exception? innerException = null) + { + return new NetworkException(message, NetworkError.Unknown, innerException); + } } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs index 7e995116b877..75a226949d93 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs @@ -154,7 +154,7 @@ internal ValueTask ReceiveAsync(Memory buffer, SocketFlags socketFlag Debug.Assert(saea.BufferList == null); saea.SetBuffer(buffer); saea.SocketFlags = socketFlags; - saea.WrapExceptionsInIOExceptions = fromNetworkStream; + saea.WrapExceptionsInNetworkExceptions = fromNetworkStream; return saea.ReceiveAsync(this, cancellationToken); } @@ -237,7 +237,7 @@ internal ValueTask SendAsync(ReadOnlyMemory buffer, SocketFlags socke Debug.Assert(saea.BufferList == null); saea.SetBuffer(MemoryMarshal.AsMemory(buffer)); saea.SocketFlags = socketFlags; - saea.WrapExceptionsInIOExceptions = false; + saea.WrapExceptionsInNetworkExceptions = false; return saea.SendAsync(this, cancellationToken); } @@ -255,7 +255,7 @@ internal ValueTask SendAsyncForNetworkStream(ReadOnlyMemory buffer, Socket Debug.Assert(saea.BufferList == null); saea.SetBuffer(MemoryMarshal.AsMemory(buffer)); saea.SocketFlags = socketFlags; - saea.WrapExceptionsInIOExceptions = true; + saea.WrapExceptionsInNetworkExceptions = true; return saea.SendAsyncForNetworkStream(this, cancellationToken); } @@ -577,7 +577,7 @@ public AwaitableSocketAsyncEventArgs(Socket owner, bool isReceiveForCaching) : _isReadForCaching = isReceiveForCaching; } - public bool WrapExceptionsInIOExceptions { get; set; } + public bool WrapExceptionsInNetworkExceptions { get; set; } private void Release() { @@ -885,8 +885,8 @@ private Exception CreateException(SocketError error, bool forAsyncThrow = true) e = ExceptionDispatchInfo.SetCurrentStackTrace(e); } - return WrapExceptionsInIOExceptions ? - new IOException(SR.Format(SR.net_io_readfailure, e.Message), e) : + return WrapExceptionsInNetworkExceptions ? + NetworkErrorHelper.MapSocketException((SocketException)e) : e; } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs index f7b0e83e44a7..fb2938598541 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs @@ -25,25 +25,25 @@ public void Ctor_NullSocket_ThrowsArgumentNullExceptions() } [Fact] - public void Ctor_NotConnected_ThrowsIOException() + public void Ctor_NotConnected_ThrowsNetworkException() { - Assert.Throws(() => new NetworkStream(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))); + Assert.Throws(() => new NetworkStream(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))); } [Fact] - public async Task Ctor_NotStream_ThrowsIOException() + public async Task Ctor_NotStream_ThrowsNetworkException() { using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndPoint).Port)); - Assert.Throws(() => new NetworkStream(client)); + Assert.Throws(() => new NetworkStream(client)); } } [Fact] - public async Task Ctor_NonBlockingSocket_ThrowsIOException() + public async Task Ctor_NonBlockingSocket_ThrowsNetworkException() { using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) @@ -56,7 +56,7 @@ public async Task Ctor_NonBlockingSocket_ThrowsIOException() using (Socket server = await acceptTask) { server.Blocking = false; - Assert.Throws(() => new NetworkStream(server)); + Assert.Throws(() => new NetworkStream(server)); } } } @@ -186,7 +186,7 @@ public async Task Ctor_SocketBool_CanReadAndWrite(bool ownsSocket) } else if (ownsSocket) { - Assert.IsType(e); + Assert.IsType(e); } else { @@ -302,7 +302,7 @@ await RunWithConnectedNetworkStreamsAsync((server, _) => } [Fact] - public async Task DisposeSocketDirectly_ReadWriteThrowIOException() + public async Task DisposeSocketDirectly_ReadWriteThrowNetworkException() { using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) @@ -317,14 +317,14 @@ public async Task DisposeSocketDirectly_ReadWriteThrowIOException() { serverSocket.Dispose(); - Assert.Throws(() => server.Read(new byte[1], 0, 1)); - Assert.Throws(() => server.Write(new byte[1], 0, 1)); + Assert.Throws(() => server.Read(new byte[1], 0, 1)); + Assert.Throws(() => server.Write(new byte[1], 0, 1)); - Assert.Throws(() => server.BeginRead(new byte[1], 0, 1, null, null)); - Assert.Throws(() => server.BeginWrite(new byte[1], 0, 1, null, null)); + Assert.Throws(() => server.BeginRead(new byte[1], 0, 1, null, null)); + Assert.Throws(() => server.BeginWrite(new byte[1], 0, 1, null, null)); - Assert.Throws(() => { server.ReadAsync(new byte[1], 0, 1); }); - Assert.Throws(() => { server.WriteAsync(new byte[1], 0, 1); }); + Assert.Throws(() => { server.ReadAsync(new byte[1], 0, 1); }); + Assert.Throws(() => { server.WriteAsync(new byte[1], 0, 1); }); } } } @@ -334,8 +334,8 @@ public async Task InvalidIAsyncResult_EndReadWriteThrows() { await RunWithConnectedNetworkStreamsAsync((server, _) => { - Assert.Throws(() => server.EndRead(Task.CompletedTask)); - Assert.Throws(() => server.EndWrite(Task.CompletedTask)); + Assert.Throws(() => server.EndRead(Task.CompletedTask)); + Assert.Throws(() => server.EndWrite(Task.CompletedTask)); return Task.CompletedTask; }); } @@ -586,7 +586,7 @@ await RunWithConnectedNetworkStreamsAsync((server, client) => Assert.Equal(-1, server.ReadTimeout); server.ReadTimeout = 1; - Assert.ThrowsAny(() => server.Read(new byte[1], 0, 1)); + Assert.ThrowsAny(() => server.Read(new byte[1], 0, 1)); return Task.CompletedTask; }); @@ -713,8 +713,8 @@ await RunWithConnectedNetworkStreamsAsync(async (stream, _) => // before that takes effect, it may also complete as aborted. bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); Assert.True( - (isWindows && e is IOException) || - (!isWindows && (e == null || e is IOException)), + (isWindows && e is NetworkException) || + (!isWindows && (e == null || e is NetworkException)), $"Got unexpected exception: {e?.ToString() ?? "(null)"}"); // Copying after disposing the stream From ffa06471f6e5fac939533c7541ad31321089cf0a Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 7 Aug 2020 10:52:37 -0700 Subject: [PATCH 328/755] [JsonSerializer] Prevent arbitrary properties from being cached when deserializing with parameterized ctors (#40495) * [JsonSerializer] Prevent arbitrary properties from being cached when deserializing with parameterized ctors * Address review feedback * Correct check on when to grow property pool in sync code paths --- ...ctWithParameterizedConstructorConverter.cs | 107 ++++++++++-------- .../ConstructorTests.ParameterMatching.cs | 4 +- 2 files changed, 61 insertions(+), 50 deletions(-) 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 f001c86198ed..6e2f251ac62e 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 @@ -7,8 +7,8 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -using FoundProperties = System.ValueTuple; -using FoundPropertiesAsync = System.ValueTuple; +using FoundProperty = System.ValueTuple; +using FoundPropertyAsync = System.ValueTuple; namespace System.Text.Json.Serialization.Converters { @@ -21,6 +21,7 @@ internal abstract partial class ObjectWithParameterizedConstructorConverter : internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj; + ArgumentState argumentState = state.Current.CtorArgumentState!; if (state.UseFastPath) { @@ -32,21 +33,24 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo obj = CreateObject(ref state.Current); - if (state.Current.PropertyIndex > 0) + if (argumentState.FoundPropertyCount > 0) { Utf8JsonReader tempReader; - for (int i = 0; i < state.Current.PropertyIndex; i++) + FoundProperty[]? properties = argumentState.FoundProperties; + Debug.Assert(properties != null); + + for (int i = 0; i < argumentState.FoundPropertyCount; i++) { - JsonPropertyInfo jsonPropertyInfo = state.Current.CtorArgumentState!.FoundProperties![i].Item1; - long resumptionByteIndex = state.Current.CtorArgumentState.FoundProperties[i].Item3; - byte[]? propertyNameArray = state.Current.CtorArgumentState.FoundProperties[i].Item4; - string? dataExtKey = state.Current.CtorArgumentState.FoundProperties[i].Item5; + JsonPropertyInfo jsonPropertyInfo = properties[i].Item1; + long resumptionByteIndex = properties[i].Item3; + byte[]? propertyNameArray = properties[i].Item4; + string? dataExtKey = properties[i].Item5; tempReader = new Utf8JsonReader( originalSpan.Slice(checked((int)resumptionByteIndex)), isFinalBlock: true, - state: state.Current.CtorArgumentState.FoundProperties[i].Item2); + state: properties[i].Item2); Debug.Assert(tempReader.TokenType == JsonTokenType.PropertyName); @@ -65,7 +69,8 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo ReadPropertyValue(obj, ref state, ref tempReader, jsonPropertyInfo, useExtensionProperty); } - ArrayPool.Shared.Return(state.Current.CtorArgumentState!.FoundProperties!, clearArray: true); + ArrayPool.Shared.Return(argumentState.FoundProperties!, clearArray: true); + argumentState.FoundProperties = null; } } else @@ -86,14 +91,13 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo obj = CreateObject(ref state.Current); - if (state.Current.CtorArgumentState!.FoundPropertyCount > 0) + if (argumentState.FoundPropertyCount > 0) { - // Set the properties we've parsed so far. - for (int i = 0; i < state.Current.CtorArgumentState!.FoundPropertyCount; i++) + for (int i = 0; i < argumentState.FoundPropertyCount; i++) { - JsonPropertyInfo jsonPropertyInfo = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item1; - object? propValue = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item2; - string? dataExtKey = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item3; + JsonPropertyInfo jsonPropertyInfo = argumentState.FoundPropertiesAsync![i].Item1; + object? propValue = argumentState.FoundPropertiesAsync![i].Item2; + string? dataExtKey = argumentState.FoundPropertiesAsync![i].Item3; if (dataExtKey == null) { @@ -117,7 +121,8 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo } } - ArrayPool.Shared.Return(state.Current.CtorArgumentState!.FoundPropertiesAsync!, clearArray: true); + ArrayPool.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true); + argumentState.FoundPropertiesAsync = null; } } @@ -128,7 +133,7 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo } // Check if we are trying to build the sorted parameter cache. - if (state.Current.CtorArgumentState!.ParameterRefCache != null) + if (argumentState.ParameterRefCache != null) { state.Current.JsonClassInfo.UpdateSortedParameterCache(ref state.Current); } @@ -195,31 +200,36 @@ private void ReadConstructorArguments(ref ReadStack state, ref Utf8JsonReader re out _, createExtensionProperty: false); - if (state.Current.CtorArgumentState!.FoundProperties == null) - { - state.Current.CtorArgumentState.FoundProperties = - ArrayPool.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count)); - } - else if (state.Current.PropertyIndex - 1 == state.Current.CtorArgumentState.FoundProperties!.Length) + if (jsonPropertyInfo.ShouldDeserialize) { - // Rare case where we can't fit all the JSON properties in the rented pool; we have to grow. - // This could happen if there are duplicate properties in the JSON. + ArgumentState argumentState = state.Current.CtorArgumentState!; + + if (argumentState.FoundProperties == null) + { + argumentState.FoundProperties = + ArrayPool.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count)); + } + else if (argumentState.FoundPropertyCount == argumentState.FoundProperties.Length) + { + // Rare case where we can't fit all the JSON properties in the rented pool; we have to grow. + // This could happen if there are duplicate properties in the JSON. - var newCache = ArrayPool.Shared.Rent(state.Current.CtorArgumentState.FoundProperties!.Length * 2); + var newCache = ArrayPool.Shared.Rent(argumentState.FoundProperties.Length * 2); - state.Current.CtorArgumentState.FoundProperties!.CopyTo(newCache, 0); + argumentState.FoundProperties.CopyTo(newCache, 0); - ArrayPool.Shared.Return(state.Current.CtorArgumentState.FoundProperties!, clearArray: true); + ArrayPool.Shared.Return(argumentState.FoundProperties, clearArray: true); - state.Current.CtorArgumentState.FoundProperties = newCache!; - } + argumentState.FoundProperties = newCache!; + } - state.Current.CtorArgumentState!.FoundProperties![state.Current.PropertyIndex - 1] = ( - jsonPropertyInfo, - reader.CurrentState, - reader.BytesConsumed, - state.Current.JsonPropertyName, - state.Current.JsonPropertyNameAsString); + argumentState.FoundProperties[argumentState.FoundPropertyCount++] = ( + jsonPropertyInfo, + reader.CurrentState, + reader.BytesConsumed, + state.Current.JsonPropertyName, + state.Current.JsonPropertyNameAsString); + } reader.Skip(); @@ -387,30 +397,31 @@ private bool HandlePropertyWithContinuation( } } + Debug.Assert(jsonPropertyInfo.ShouldDeserialize); + // Ensure that the cache has enough capacity to add this property. - if (state.Current.CtorArgumentState!.FoundPropertiesAsync == null) + ArgumentState argumentState = state.Current.CtorArgumentState!; + + if (argumentState.FoundPropertiesAsync == null) { - state.Current.CtorArgumentState.FoundPropertiesAsync = - ArrayPool.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count)); + argumentState.FoundPropertiesAsync = ArrayPool.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count)); } - else if (state.Current.CtorArgumentState.FoundPropertyCount == state.Current.CtorArgumentState.FoundPropertiesAsync!.Length) + else if (argumentState.FoundPropertyCount == argumentState.FoundPropertiesAsync!.Length) { // Rare case where we can't fit all the JSON properties in the rented pool; we have to grow. // This could happen if there are duplicate properties in the JSON. - var newCache = ArrayPool.Shared.Rent( - state.Current.CtorArgumentState.FoundPropertiesAsync!.Length * 2); + var newCache = ArrayPool.Shared.Rent(argumentState.FoundPropertiesAsync!.Length * 2); - state.Current.CtorArgumentState.FoundPropertiesAsync!.CopyTo(newCache, 0); + argumentState.FoundPropertiesAsync!.CopyTo(newCache, 0); - ArrayPool.Shared.Return( - state.Current.CtorArgumentState.FoundPropertiesAsync!, clearArray: true); + ArrayPool.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true); - state.Current.CtorArgumentState.FoundPropertiesAsync = newCache!; + argumentState.FoundPropertiesAsync = newCache!; } // Cache the property name and value. - state.Current.CtorArgumentState.FoundPropertiesAsync[state.Current.CtorArgumentState.FoundPropertyCount++] = ( + argumentState.FoundPropertiesAsync![argumentState.FoundPropertyCount++] = ( jsonPropertyInfo, propValue, state.Current.JsonPropertyNameAsString); diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs index b3315fc88711..91c224d5a8eb 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -779,7 +779,7 @@ public async Task Escaped_ParameterNames_Work() } [Fact] - public async Task FirstParameterWins() + public async Task LastParameterWins() { Point_2D point = await Serializer.DeserializeWrapper(@"{""X"":1,""Y"":2,""X"":4}"); Assert.Equal(4, point.X); // Not 1. @@ -787,7 +787,7 @@ public async Task FirstParameterWins() } [Fact] - public async Task SubsequentParameter_GoesToExtensionData() + public async Task LastParameterWins_DoesNotGoToExtensionData() { string json = @"{ ""FirstName"":""Jet"", From 5ebf5867c29f3d053b74561e119853b33dfeea9a Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Fri, 7 Aug 2020 11:08:34 -0700 Subject: [PATCH 329/755] Fix Issue #877 - Use GT_OBJ when copying a struct (#40483) --- src/coreclr/src/jit/morph.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 61ad9937b048..81342722a380 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -5742,7 +5742,9 @@ GenTree* Compiler::fgMorphStackArgForVarArgs(unsigned lclNum, var_types varType, GenTree* tree; if (varTypeIsStruct(varType)) { - tree = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, ptrArg, typGetBlkLayout(varDsc->lvExactSize)); + CORINFO_CLASS_HANDLE typeHnd = varDsc->lvVerTypeInfo.GetClassHandle(); + assert(typeHnd != nullptr); + tree = gtNewObjNode(typeHnd, ptrArg); } else { From 89af52b01bb3b24e2b7b97bd6343ceb7d330c4e3 Mon Sep 17 00:00:00 2001 From: Eddy Nakamura Date: Fri, 7 Aug 2020 15:58:32 -0300 Subject: [PATCH 330/755] Update Equals method from ActivityContext (#40465) --- .../src/System/Diagnostics/ActivityContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs index d94640ad23fa..0522cbfb7dce 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs @@ -93,7 +93,7 @@ public static ActivityContext Parse(string traceParent, string? traceState) return context; } - public bool Equals(ActivityContext value) => SpanId.Equals(value.SpanId) && TraceId.Equals(value.TraceId) && TraceFlags == value.TraceFlags && TraceState == value.TraceState; + public bool Equals(ActivityContext value) => SpanId.Equals(value.SpanId) && TraceId.Equals(value.TraceId) && TraceFlags == value.TraceFlags && TraceState == value.TraceState && IsRemote == value.IsRemote; public override bool Equals(object? obj) => (obj is ActivityContext context) ? Equals(context) : false; public static bool operator ==(ActivityContext left, ActivityContext right) => left.Equals(right); From 254ef0f7f7f429ec238735fe6132805e3c38a19f Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 7 Aug 2020 14:35:53 -0500 Subject: [PATCH 331/755] Make Extensions linker friendly. (#40431) * Make Extensions linker friendly. Annotating the rest of the Microsoft.Extensions libraries. Fix #40396 * Disable parallelism in trimming tests to fix race condition. --- .../ProviderAliasUtilities.cs | 16 +++-- ...oft.Extensions.Hosting.Abstractions.csproj | 7 ++- ...erviceCollectionHostedServiceExtensions.cs | 3 +- .../TrimmingTests/AddHostedServiceTests.cs | 34 +++++++++++ ...soft.Extensions.Hosting.TrimmingTests.proj | 13 +++++ .../Microsoft.Extensions.Http.sln | 14 ++--- .../src/DefaultTypedHttpClientFactory.cs | 4 +- .../HttpClientBuilderExtensions.cs | 13 +++-- ...lientFactoryServiceCollectionExtensions.cs | 37 ++++++++---- .../src/ITypedHttpClientFactory.cs | 3 +- .../src/Microsoft.Extensions.Http.csproj | 2 + .../DefaultHttpClientFactoryTest.cs | 0 .../DefaultHttpMessageHandlerBuilderTest.cs | 0 ...tFactoryServiceCollectionExtensionsTest.cs | 0 .../DependencyInjection/OtherTestOptions.cs | 0 .../HttpMessageHandlerBuilderTest.cs | 0 .../ITestTypedClient.cs | 0 .../Logging/HttpHeadersLogValueTest.cs | 0 .../RedactedLogValueIntegrationTest.cs | 0 .../Microsoft.Extensions.Http.Tests.csproj | 4 +- .../TestTypedClient.cs | 0 .../TrimmingTests/AddTypedClientTests.cs | 58 +++++++++++++++++++ ...crosoft.Extensions.Http.TrimmingTests.proj | 13 +++++ .../Microsoft.Extensions.Logging.Console.sln | 12 ++-- .../src/ConsoleLoggerExtensions.cs | 5 +- .../src/FormatterOptionsMonitor.cs | 5 +- ...icrosoft.Extensions.Logging.Console.csproj | 5 ++ .../AnsiParserTests.cs | 0 .../Console/ConsoleContext.cs | 0 .../Console/ConsoleSink.cs | 0 .../Console/TestConsole.cs | 0 .../ConsoleFormatterTests.cs | 0 .../ConsoleLoggerExtensionsTests.cs | 0 .../ConsoleLoggerTest.cs | 0 .../JsonConsoleFormatterTests.cs | 0 ...ft.Extensions.Logging.Console.Tests.csproj | 2 +- .../SimpleConsoleFormatterTests.cs | 0 .../TestFormatterOptionsMonitor.cs | 0 .../TextWriterExtensionsTests.cs | 0 .../TrimmingTests/AddConsoleFormatterTests.cs | 51 ++++++++++++++++ ...ensions.Logging.Console.TrimmingTests.proj | 13 +++++ src/libraries/tests.proj | 2 + 42 files changed, 268 insertions(+), 48 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/AddHostedServiceTests.cs create mode 100644 src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/Microsoft.Extensions.Hosting.TrimmingTests.proj rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/DefaultHttpClientFactoryTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/DefaultHttpMessageHandlerBuilderTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/DependencyInjection/OtherTestOptions.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/HttpMessageHandlerBuilderTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/ITestTypedClient.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/Logging/HttpHeadersLogValueTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/Logging/RedactedLogValueIntegrationTest.cs (100%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/Microsoft.Extensions.Http.Tests.csproj (90%) rename src/libraries/Microsoft.Extensions.Http/tests/{ => Microsoft.Extensions.Http.Tests}/TestTypedClient.cs (100%) create mode 100644 src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/AddTypedClientTests.cs create mode 100644 src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/Microsoft.Extensions.Http.TrimmingTests.proj rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/AnsiParserTests.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/Console/ConsoleContext.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/Console/ConsoleSink.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/Console/TestConsole.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/ConsoleFormatterTests.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/ConsoleLoggerExtensionsTests.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/ConsoleLoggerTest.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/JsonConsoleFormatterTests.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/Microsoft.Extensions.Logging.Console.Tests.csproj (60%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/SimpleConsoleFormatterTests.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/TestFormatterOptionsMonitor.cs (100%) rename src/libraries/Microsoft.Extensions.Logging.Console/tests/{ => Microsoft.Extensions.Logging.Console.Tests}/TextWriterExtensionsTests.cs (100%) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/AddConsoleFormatterTests.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/Microsoft.Extensions.Logging.Console.TrimmingTests.proj diff --git a/src/libraries/Common/src/Extensions/ProviderAliasUtilities/ProviderAliasUtilities.cs b/src/libraries/Common/src/Extensions/ProviderAliasUtilities/ProviderAliasUtilities.cs index 4fb6f86ba23e..40e80be64476 100644 --- a/src/libraries/Common/src/Extensions/ProviderAliasUtilities/ProviderAliasUtilities.cs +++ b/src/libraries/Common/src/Extensions/ProviderAliasUtilities/ProviderAliasUtilities.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; using System.Reflection; namespace Microsoft.Extensions.Logging @@ -9,21 +10,18 @@ namespace Microsoft.Extensions.Logging internal static class ProviderAliasUtilities { private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; - private const string AliasAttibuteAliasProperty = "Alias"; internal static string GetAlias(Type providerType) { - foreach (object attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) + foreach (CustomAttributeData attributeData in CustomAttributeData.GetCustomAttributes(providerType)) { - if (attribute.GetType().FullName == AliasAttibuteTypeFullName) + if (attributeData.AttributeType.FullName == AliasAttibuteTypeFullName) { - PropertyInfo valueProperty = attribute - .GetType() - .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); - - if (valueProperty != null) + foreach (CustomAttributeTypedArgument arg in attributeData.ConstructorArguments) { - return valueProperty.GetValue(attribute) as string; + Debug.Assert(arg.ArgumentType == typeof(string)); + + return arg.Value?.ToString(); } } } diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index 1b488e022839..d0f3cc26369a 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -1,4 +1,4 @@ - + netstandard2.1;netstandard2.0;net461 @@ -6,6 +6,11 @@ true + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/ServiceCollectionHostedServiceExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/ServiceCollectionHostedServiceExtensions.cs index f1c39b352794..5b8092edbd1f 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/ServiceCollectionHostedServiceExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/ServiceCollectionHostedServiceExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -15,7 +16,7 @@ public static class ServiceCollectionHostedServiceExtensions /// An to register. /// The to register with. /// The original . - public static IServiceCollection AddHostedService(this IServiceCollection services) + public static IServiceCollection AddHostedService<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] THostedService>(this IServiceCollection services) where THostedService : class, IHostedService { services.TryAddEnumerable(ServiceDescriptor.Singleton()); diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/AddHostedServiceTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/AddHostedServiceTests.cs new file mode 100644 index 000000000000..585eea0a6a07 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/AddHostedServiceTests.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System.Threading; +using System.Threading.Tasks; + +class Program +{ + static int Main(string[] args) + { + IServiceCollection descriptors = new ServiceCollection(); + descriptors.AddHostedService(); + + ServiceProvider provider = descriptors.BuildServiceProvider(); + + foreach (IHostedService h in provider.GetServices()) + { + if (!(h is MyHost)) + { + return -1; + } + } + + return 100; + } + + private class MyHost : IHostedService + { + public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + } +} diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/Microsoft.Extensions.Hosting.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/Microsoft.Extensions.Hosting.TrimmingTests.proj new file mode 100644 index 000000000000..61e8e1a75966 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/TrimmingTests/Microsoft.Extensions.Hosting.TrimmingTests.proj @@ -0,0 +1,13 @@ + + + + + Microsoft.Extensions.Hosting.Abstractions;Microsoft.Extensions.DependencyInjection + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.sln b/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.sln index 15ace04ecb75..ab21d6dff380 100644 --- a/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.sln +++ b/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.sln @@ -13,10 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Http", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Http", "src\Microsoft.Extensions.Http.csproj", "{A50C941B-09D7-4AB4-85AF-D02E6F96885A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Http.Tests", "tests\Microsoft.Extensions.Http.Tests.csproj", "{C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{92E18BB1-B630-4B03-9B05-47F31D1BF94A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Http.Tests", "tests\Microsoft.Extensions.Http.Tests\Microsoft.Extensions.Http.Tests.csproj", "{7DADD323-891C-4EA7-8906-6BC4009FA083}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,14 +31,14 @@ Global {A50C941B-09D7-4AB4-85AF-D02E6F96885A}.Debug|Any CPU.Build.0 = Debug|Any CPU {A50C941B-09D7-4AB4-85AF-D02E6F96885A}.Release|Any CPU.ActiveCfg = Release|Any CPU {A50C941B-09D7-4AB4-85AF-D02E6F96885A}.Release|Any CPU.Build.0 = Release|Any CPU - {C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7}.Release|Any CPU.Build.0 = Release|Any CPU {92E18BB1-B630-4B03-9B05-47F31D1BF94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {92E18BB1-B630-4B03-9B05-47F31D1BF94A}.Debug|Any CPU.Build.0 = Debug|Any CPU {92E18BB1-B630-4B03-9B05-47F31D1BF94A}.Release|Any CPU.ActiveCfg = Release|Any CPU {92E18BB1-B630-4B03-9B05-47F31D1BF94A}.Release|Any CPU.Build.0 = Release|Any CPU + {7DADD323-891C-4EA7-8906-6BC4009FA083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DADD323-891C-4EA7-8906-6BC4009FA083}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DADD323-891C-4EA7-8906-6BC4009FA083}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DADD323-891C-4EA7-8906-6BC4009FA083}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -46,8 +46,8 @@ Global GlobalSection(NestedProjects) = preSolution {183E40F1-33A4-461D-AADF-4CF59FB93CCA} = {B51DC955-13A6-41ED-A6C7-DDAB98911513} {A50C941B-09D7-4AB4-85AF-D02E6F96885A} = {0517D0EB-1ED7-420A-A7D7-9A167C102ED2} - {C9FE0B1E-35F6-4AFE-A9A6-DA6C1B88C1E7} = {9DE482AA-076A-4EB1-821F-EE2A4A230B4A} {92E18BB1-B630-4B03-9B05-47F31D1BF94A} = {9DE482AA-076A-4EB1-821F-EE2A4A230B4A} + {7DADD323-891C-4EA7-8906-6BC4009FA083} = {9DE482AA-076A-4EB1-821F-EE2A4A230B4A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F300086C-E02A-417C-8659-59AA5139E68A} diff --git a/src/libraries/Microsoft.Extensions.Http/src/DefaultTypedHttpClientFactory.cs b/src/libraries/Microsoft.Extensions.Http/src/DefaultTypedHttpClientFactory.cs index b5d75b0d9ca4..1b0f442d6091 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DefaultTypedHttpClientFactory.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DefaultTypedHttpClientFactory.cs @@ -2,13 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using System.Threading; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.Extensions.Http { - internal class DefaultTypedHttpClientFactory : ITypedHttpClientFactory + internal class DefaultTypedHttpClientFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient> : + ITypedHttpClientFactory { private readonly Cache _cache; private readonly IServiceProvider _services; diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs index f1509da93d16..8d6ffb703f15 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net.Http; using System.Threading; @@ -316,7 +317,8 @@ public static IHttpClientBuilder ConfigureHttpMessageHandlerBuilder(this IHttpCl /// scope bound to the message handler, which is managed independently. /// /// - public static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder builder) + public static IHttpClientBuilder AddTypedClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IHttpClientBuilder builder) where TClient : class { if (builder == null) @@ -327,7 +329,8 @@ public static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder return AddTypedClientCore(builder, validateSingleType: false); } - internal static IHttpClientBuilder AddTypedClientCore(this IHttpClientBuilder builder, bool validateSingleType) + internal static IHttpClientBuilder AddTypedClientCore<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IHttpClientBuilder builder, bool validateSingleType) where TClient : class { ReserveClient(builder, typeof(TClient), builder.Name, validateSingleType); @@ -375,7 +378,8 @@ internal static IHttpClientBuilder AddTypedClientCore(this IHttpClientB /// scope bound to the message handler, which is managed independently. /// /// - public static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder builder) + public static IHttpClientBuilder AddTypedClient( + this IHttpClientBuilder builder) where TClient : class where TImplementation : class, TClient { @@ -387,7 +391,8 @@ public static IHttpClientBuilder AddTypedClient(this I return AddTypedClientCore(builder, validateSingleType: false); } - internal static IHttpClientBuilder AddTypedClientCore(this IHttpClientBuilder builder, bool validateSingleType) + internal static IHttpClientBuilder AddTypedClientCore( + this IHttpClientBuilder builder, bool validateSingleType) where TClient : class where TImplementation : class, TClient { diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs index d0f90cf3e1ca..b0a34b788e43 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Http; @@ -198,7 +199,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services) where TClient : class { if (services == null) @@ -240,7 +242,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services) where TClient : class where TImplementation : class, TClient { @@ -282,7 +285,8 @@ public static IHttpClientBuilder AddHttpClient(this IS /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services, string name) where TClient : class { if (services == null) @@ -332,7 +336,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services, string name) where TClient : class where TImplementation : class, TClient { @@ -376,7 +381,8 @@ public static IHttpClientBuilder AddHttpClient(this IS /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, Action configureClient) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services, Action configureClient) where TClient : class { if (services == null) @@ -421,7 +427,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, Action configureClient) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services, Action configureClient) where TClient : class { if (services == null) @@ -470,7 +477,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, Action configureClient) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services, Action configureClient) where TClient : class where TImplementation : class, TClient { @@ -520,7 +528,8 @@ public static IHttpClientBuilder AddHttpClient(this IS /// as the service type. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, Action configureClient) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services, Action configureClient) where TClient : class where TImplementation : class, TClient { @@ -569,7 +578,8 @@ public static IHttpClientBuilder AddHttpClient(this IS /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action configureClient) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services, string name, Action configureClient) where TClient : class { if (services == null) @@ -621,7 +631,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action configureClient) + public static IHttpClientBuilder AddHttpClient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>( + this IServiceCollection services, string name, Action configureClient) where TClient : class { if (services == null) @@ -677,7 +688,8 @@ public static IHttpClientBuilder AddHttpClient(this IServiceCollection /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action configureClient) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services, string name, Action configureClient) where TClient : class where TImplementation : class, TClient { @@ -734,7 +746,8 @@ public static IHttpClientBuilder AddHttpClient(this IS /// Use as the name to configure the default client. /// /// - public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action configureClient) + public static IHttpClientBuilder AddHttpClient( + this IServiceCollection services, string name, Action configureClient) where TClient : class where TImplementation : class, TClient { diff --git a/src/libraries/Microsoft.Extensions.Http/src/ITypedHttpClientFactory.cs b/src/libraries/Microsoft.Extensions.Http/src/ITypedHttpClientFactory.cs index 67ac64c23012..979f99a43a65 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/ITypedHttpClientFactory.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/ITypedHttpClientFactory.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Microsoft.Extensions.DependencyInjection; @@ -96,7 +97,7 @@ namespace Microsoft.Extensions.Http /// } /// /// - public interface ITypedHttpClientFactory + public interface ITypedHttpClientFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient> { /// /// Creates a typed client given an associated . diff --git a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj index e27e847e380f..6de909a45f7e 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj @@ -12,6 +12,8 @@ Link="Common\src\Extensions\TypeNameHelper\TypeNameHelper.cs" /> + + diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DefaultHttpClientFactoryTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpClientFactoryTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DefaultHttpClientFactoryTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpMessageHandlerBuilderTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DefaultHttpMessageHandlerBuilderTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/DefaultHttpMessageHandlerBuilderTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DefaultHttpMessageHandlerBuilderTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DependencyInjection/HttpClientFactoryServiceCollectionExtensionsTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/OtherTestOptions.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DependencyInjection/OtherTestOptions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/DependencyInjection/OtherTestOptions.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/DependencyInjection/OtherTestOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/HttpMessageHandlerBuilderTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/HttpMessageHandlerBuilderTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/HttpMessageHandlerBuilderTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/HttpMessageHandlerBuilderTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/ITestTypedClient.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/ITestTypedClient.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/ITestTypedClient.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/ITestTypedClient.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Logging/HttpHeadersLogValueTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpHeadersLogValueTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/Logging/HttpHeadersLogValueTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpHeadersLogValueTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Microsoft.Extensions.Http.Tests.csproj similarity index 90% rename from src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Microsoft.Extensions.Http.Tests.csproj index 3c192f903d02..76700604db85 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Microsoft.Extensions.Http.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);net461 @@ -24,7 +24,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Http/tests/TestTypedClient.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestTypedClient.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Http/tests/TestTypedClient.cs rename to src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestTypedClient.cs diff --git a/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/AddTypedClientTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/AddTypedClientTests.cs new file mode 100644 index 000000000000..17bcf13fc5a6 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/AddTypedClientTests.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; +using System.Net.Http; + +class Program +{ + static int Main(string[] args) + { + IServiceCollection descriptors = new ServiceCollection(); + descriptors.AddHttpClient("test1") + .AddTypedClient() + .AddTypedClient(); + + descriptors.AddHttpClient("test2"); + descriptors.AddHttpClient("test3"); + + ServiceProvider provider = descriptors.BuildServiceProvider(); + + TypedClientA clientA = provider.GetRequiredService(); + ITypedClientB clientB = provider.GetRequiredService(); + TypedClientC clientC = provider.GetRequiredService(); + ITypedClientD clientD = provider.GetRequiredService(); + + if (clientA == null || + !(clientB is TypedClientB) || + clientC == null || + !(clientD is TypedClientD)) + { + return -1; + } + + return 100; + } + + class TypedClientA + { + public TypedClientA(HttpClient httpClient) { } + } + + interface ITypedClientB { } + class TypedClientB : ITypedClientB + { + public TypedClientB(HttpClient httpClient) { } + } + + class TypedClientC + { + public TypedClientC(HttpClient httpClient) { } + } + + interface ITypedClientD { } + class TypedClientD : ITypedClientD + { + public TypedClientD(HttpClient httpClient) { } + } +} diff --git a/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/Microsoft.Extensions.Http.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/Microsoft.Extensions.Http.TrimmingTests.proj new file mode 100644 index 000000000000..4d7101977090 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Http/tests/TrimmingTests/Microsoft.Extensions.Http.TrimmingTests.proj @@ -0,0 +1,13 @@ + + + + + Microsoft.Extensions.Http + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.sln b/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.sln index a7cab36d8df3..24a098f8e6b3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.sln +++ b/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.sln @@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Loggin EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{56A299FB-3733-4AF5-AE10-66AB73D6FC13}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Console.Tests", "tests\Microsoft.Extensions.Logging.Console.Tests.csproj", "{9B344154-013F-4D6B-99A5-77DFA1CB8CC0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Console.Tests", "tests\Microsoft.Extensions.Logging.Console.Tests\Microsoft.Extensions.Logging.Console.Tests.csproj", "{A2CFB82A-F553-44CD-8765-97409380EED9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -29,10 +29,10 @@ Global {CDEDF61A-4D74-4EAA-B31E-AF5CAAA7B974}.Debug|Any CPU.Build.0 = Debug|Any CPU {CDEDF61A-4D74-4EAA-B31E-AF5CAAA7B974}.Release|Any CPU.ActiveCfg = Release|Any CPU {CDEDF61A-4D74-4EAA-B31E-AF5CAAA7B974}.Release|Any CPU.Build.0 = Release|Any CPU - {9B344154-013F-4D6B-99A5-77DFA1CB8CC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9B344154-013F-4D6B-99A5-77DFA1CB8CC0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9B344154-013F-4D6B-99A5-77DFA1CB8CC0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9B344154-013F-4D6B-99A5-77DFA1CB8CC0}.Release|Any CPU.Build.0 = Release|Any CPU + {A2CFB82A-F553-44CD-8765-97409380EED9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2CFB82A-F553-44CD-8765-97409380EED9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2CFB82A-F553-44CD-8765-97409380EED9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2CFB82A-F553-44CD-8765-97409380EED9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -40,7 +40,7 @@ Global GlobalSection(NestedProjects) = preSolution {6D191D5A-572C-4BFA-B73B-C24AF80E8016} = {A12B6049-11A7-4E2B-857B-620B917B4A46} {CDEDF61A-4D74-4EAA-B31E-AF5CAAA7B974} = {A1F1D16A-5787-45E5-AF85-617702C216C6} - {9B344154-013F-4D6B-99A5-77DFA1CB8CC0} = {56A299FB-3733-4AF5-AE10-66AB73D6FC13} + {A2CFB82A-F553-44CD-8765-97409380EED9} = {56A299FB-3733-4AF5-AE10-66AB73D6FC13} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E75E4D9D-8919-409F-8FF1-67DD9C346EA7} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs index 2e591ec819fc..8cd8a594e359 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -120,7 +121,7 @@ private static ILoggingBuilder AddFormatterWithName(this ILoggingBuilder builder /// Adds a custom console logger formatter 'TFormatter' to be configured with options 'TOptions'. /// /// The to use. - public static ILoggingBuilder AddConsoleFormatter(this ILoggingBuilder builder) + public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this ILoggingBuilder builder) where TOptions : ConsoleFormatterOptions where TFormatter : ConsoleFormatter { @@ -138,7 +139,7 @@ public static ILoggingBuilder AddConsoleFormatter(this ILo /// /// The to use. /// A delegate to configure options 'TOptions' for custom formatter 'TFormatter'. - public static ILoggingBuilder AddConsoleFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this ILoggingBuilder builder, Action configure) where TOptions : ConsoleFormatterOptions where TFormatter : ConsoleFormatter { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/FormatterOptionsMonitor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/FormatterOptionsMonitor.cs index d29376cb9b84..00adb44b4b61 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/FormatterOptionsMonitor.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/FormatterOptionsMonitor.cs @@ -2,11 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console { - internal class FormatterOptionsMonitor : IOptionsMonitor where TOptions : ConsoleFormatterOptions + internal class FormatterOptionsMonitor<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : + IOptionsMonitor + where TOptions : ConsoleFormatterOptions { private TOptions _options; public FormatterOptionsMonitor(TOptions options) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 29bfc3f99068..1e8e0f43fa4b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -28,6 +28,11 @@ Link="Common\Interop\Windows\Interop.GetStdHandle.cs" /> + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/AnsiParserTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/AnsiParserTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/AnsiParserTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/AnsiParserTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/ConsoleContext.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/ConsoleContext.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/ConsoleContext.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/ConsoleContext.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/ConsoleSink.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/ConsoleSink.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/ConsoleSink.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/ConsoleSink.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/TestConsole.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/TestConsole.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/Console/TestConsole.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Console/TestConsole.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleFormatterTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleFormatterTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleFormatterTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerTest.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/JsonConsoleFormatterTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Microsoft.Extensions.Logging.Console.Tests.csproj similarity index 60% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Microsoft.Extensions.Logging.Console.Tests.csproj index 6d1c916ab02d..6caa09d4a5fa 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/Microsoft.Extensions.Logging.Console.Tests.csproj @@ -7,7 +7,7 @@ - + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/SimpleConsoleFormatterTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/SimpleConsoleFormatterTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/SimpleConsoleFormatterTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/TestFormatterOptionsMonitor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/TestFormatterOptionsMonitor.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/TestFormatterOptionsMonitor.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/TestFormatterOptionsMonitor.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/TextWriterExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/TextWriterExtensionsTests.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Console/tests/TextWriterExtensionsTests.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/TextWriterExtensionsTests.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/AddConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/AddConsoleFormatterTests.cs new file mode 100644 index 000000000000..e12c7d779778 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/AddConsoleFormatterTests.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Console; +using System.IO; + +class Program +{ + private static int ConstructorCallCount = 0; + private static int WriteCallCount = 0; + + static int Main(string[] args) + { + IServiceCollection descriptors = new ServiceCollection(); + descriptors.AddLogging(builder => + { + builder.AddConsoleFormatter(); + builder.AddConsole(o => { o.FormatterName = "custom"; }); + }); + + ServiceProvider provider = descriptors.BuildServiceProvider(); + + ILoggerProvider logger = provider.GetRequiredService(); + logger.CreateLogger("log").LogError("Hello"); + + if (ConstructorCallCount != 1 || + WriteCallCount != 1) + { + return -1; + } + + return 100; + } + + private class CustomFormatter : ConsoleFormatter + { + public CustomFormatter() : base("Custom") + { + ConstructorCallCount++; + } + public override void Write(in LogEntry logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter) + { + WriteCallCount++; + } + } + + private class CustomOptions : ConsoleFormatterOptions { } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/Microsoft.Extensions.Logging.Console.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/Microsoft.Extensions.Logging.Console.TrimmingTests.proj new file mode 100644 index 000000000000..353b9d16635a --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/TrimmingTests/Microsoft.Extensions.Logging.Console.TrimmingTests.proj @@ -0,0 +1,13 @@ + + + + + Microsoft.Extensions.Logging.Console + + + + + + + + diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 75ce0856c06d..9ba9856ed656 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -11,6 +11,7 @@ true false false + true @@ -38,6 +39,7 @@ Condition="'$(TestPackages)' == 'true'" /> From 64c25fd2b1182b513d0859418c472a6a2c4f26fb Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 7 Aug 2020 15:46:47 -0400 Subject: [PATCH 332/755] [Wasm] Add simple browser sample (#40460) --- src/mono/netcore/sample/wasm/browser/Makefile | 16 ++++++ .../netcore/sample/wasm/browser/Program.cs | 21 +++++++ .../sample/wasm/browser/WasmSample.csproj | 57 +++++++++++++++++++ .../netcore/sample/wasm/browser/index.html | 28 +++++++++ .../netcore/sample/wasm/browser/runtime.js | 15 +++++ .../netcore/sample/wasm/browser/server.py | 37 ++++++++++++ .../sample/wasm/{ => console}/Makefile | 2 +- .../sample/wasm/{ => console}/Program.cs | 0 .../wasm/{ => console}/WasmSample.csproj | 0 9 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/mono/netcore/sample/wasm/browser/Makefile create mode 100644 src/mono/netcore/sample/wasm/browser/Program.cs create mode 100644 src/mono/netcore/sample/wasm/browser/WasmSample.csproj create mode 100644 src/mono/netcore/sample/wasm/browser/index.html create mode 100644 src/mono/netcore/sample/wasm/browser/runtime.js create mode 100644 src/mono/netcore/sample/wasm/browser/server.py rename src/mono/netcore/sample/wasm/{ => console}/Makefile (95%) rename src/mono/netcore/sample/wasm/{ => console}/Program.cs (100%) rename src/mono/netcore/sample/wasm/{ => console}/WasmSample.csproj (100%) diff --git a/src/mono/netcore/sample/wasm/browser/Makefile b/src/mono/netcore/sample/wasm/browser/Makefile new file mode 100644 index 000000000000..d5227aca5c34 --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/Makefile @@ -0,0 +1,16 @@ +TOP=../../../../../.. + +DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary + +CONFIG?=Release + +all: build + +build: + $(TOP)/.dotnet/dotnet build $(DOTNET_Q_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) WasmSample.csproj + +clean: + rm -rf bin + +run: + cd bin/$(CONFIG)/publish && python server.py \ No newline at end of file diff --git a/src/mono/netcore/sample/wasm/browser/Program.cs b/src/mono/netcore/sample/wasm/browser/Program.cs new file mode 100644 index 000000000000..36e09e414a70 --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/Program.cs @@ -0,0 +1,21 @@ +// -*- indent-tabs-mode: nil -*- +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Sample +{ + public class Test + { + public static void Main(String[] args) + { + Console.WriteLine ("Hello, World!"); + } + + public static int TestMeaning() + { + return 42; + } + } +} diff --git a/src/mono/netcore/sample/wasm/browser/WasmSample.csproj b/src/mono/netcore/sample/wasm/browser/WasmSample.csproj new file mode 100644 index 000000000000..e268098b6654 --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/WasmSample.csproj @@ -0,0 +1,57 @@ + + + Exe + bin + false + $(NetCoreAppCurrent) + wasm + Browser + $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(Configuration)\runtimes\browser-wasm\ + $(MSBuildThisFileDirectory)obj\$(Configuration)\wasm + $(MSBuildThisFileDirectory)bin\$(Configuration)\publish + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + diff --git a/src/mono/netcore/sample/wasm/browser/index.html b/src/mono/netcore/sample/wasm/browser/index.html new file mode 100644 index 000000000000..4cf3a1ef1b1d --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/index.html @@ -0,0 +1,28 @@ + + + + + + TESTS + + + + + + Result from Sample.Test.TestMeaaning: + + + + + + + + \ No newline at end of file diff --git a/src/mono/netcore/sample/wasm/browser/runtime.js b/src/mono/netcore/sample/wasm/browser/runtime.js new file mode 100644 index 000000000000..7db3cb4fc70e --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/runtime.js @@ -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. + +var Module = { + onRuntimeInitialized: function () { + config.loaded_cb = function () { + App.init (); + }; + config.fetch_file_cb = function (asset) { + return fetch (asset, { credentials: 'same-origin' }); + } + + MONO.mono_load_runtime_and_bcl_args (config); + }, +}; diff --git a/src/mono/netcore/sample/wasm/browser/server.py b/src/mono/netcore/sample/wasm/browser/server.py new file mode 100644 index 000000000000..ab1e3edd8151 --- /dev/null +++ b/src/mono/netcore/sample/wasm/browser/server.py @@ -0,0 +1,37 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. + +import sys + +if sys.version_info[0] == 2: + + import SimpleHTTPServer + import SocketServer + + PORT = 8000 + + class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): + pass + + Handler.extensions_map['.wasm'] = 'application/wasm' + + httpd = SocketServer.TCPServer(("", PORT), Handler) + + print ("python 2 serving at port", PORT) + httpd.serve_forever() + + +if sys.version_info[0] == 3: + + import http.server + import socketserver + + PORT = 8000 + + Handler = http.server.SimpleHTTPRequestHandler + Handler.extensions_map['.wasm'] = 'application/wasm' + + with socketserver.TCPServer(("", PORT), Handler) as httpd: + print("python 3 serving at port", PORT) + httpd.serve_forever() + diff --git a/src/mono/netcore/sample/wasm/Makefile b/src/mono/netcore/sample/wasm/console/Makefile similarity index 95% rename from src/mono/netcore/sample/wasm/Makefile rename to src/mono/netcore/sample/wasm/console/Makefile index 16d37d41f4cb..40cbf04ed407 100644 --- a/src/mono/netcore/sample/wasm/Makefile +++ b/src/mono/netcore/sample/wasm/console/Makefile @@ -1,4 +1,4 @@ -TOP=../../../../.. +TOP=../../../../../.. DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary diff --git a/src/mono/netcore/sample/wasm/Program.cs b/src/mono/netcore/sample/wasm/console/Program.cs similarity index 100% rename from src/mono/netcore/sample/wasm/Program.cs rename to src/mono/netcore/sample/wasm/console/Program.cs diff --git a/src/mono/netcore/sample/wasm/WasmSample.csproj b/src/mono/netcore/sample/wasm/console/WasmSample.csproj similarity index 100% rename from src/mono/netcore/sample/wasm/WasmSample.csproj rename to src/mono/netcore/sample/wasm/console/WasmSample.csproj From 55ed5cda016f1dd3d730e81165c40d45327e1ba4 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 7 Aug 2020 13:26:55 -0700 Subject: [PATCH 333/755] Fix covariant override disassembly (#40502) - This introduces a new path where ildasm must generate a full token description instead of relying on ilasm to produce the signature from the method body --- src/coreclr/src/ildasm/dasm.cpp | 104 ++++++++++++++++-- .../UnitTest/CompatibleWithTest.ilproj | 2 - 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/coreclr/src/ildasm/dasm.cpp b/src/coreclr/src/ildasm/dasm.cpp index da3d12f0f336..eecd1edbf263 100644 --- a/src/coreclr/src/ildasm/dasm.cpp +++ b/src/coreclr/src/ildasm/dasm.cpp @@ -3300,7 +3300,9 @@ void DumpGenericParsCA(mdToken tok, void* GUICookie/*=NULL*/) } //end if(g_fShowCA) } -// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec. +// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec or +// if the method has a signature which does not exactly match between the overrider and overridee. +// That case is commonly caused by covariant overrides. // In that case the syntax is slightly different (there are additional 'method' keywords). // Refer to Expert .NET 2.0 IL Assembler page 242. void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, void* GUICookie, mdToken tkOverrider, @@ -3320,6 +3322,11 @@ void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, v if(g_pImport->IsValidToken(tkDecl)) { + bool needsFullTokenPrint = false; + bool hasTkDeclParent = false; + + // Determine if the decl is a typespec method, in which case the "method" syntax + full token print + // must be used to generate the disassembly. if(SUCCEEDED(g_pImport->GetParentToken(tkDecl,&tkDeclParent))) { if(g_pImport->IsValidToken(tkDeclParent)) @@ -3334,20 +3341,99 @@ void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, v { if(TypeFromToken(tkDeclParent)==mdtTypeSpec) { - szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method")); - PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider); - - *pbOverridingTypeSpec = TRUE; - return; + needsFullTokenPrint = true; } - PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider); - strcat_s(szString, SZSTRING_SIZE,"::"); - szptr = &szString[strlen(szString)]; + hasTkDeclParent = true; } } else szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID OVERRIDDEN METHOD'S PARENT TOKEN")); } + + // Determine if the sig of the decl does not match the sig of the body + // In that case the full "method" syntax must be used + if ((TypeFromToken(tkOverrider) == mdtMethodDef) && !needsFullTokenPrint) + { + PCCOR_SIGNATURE pComSigDecl; + ULONG cComSigDecl; + mdToken tkDeclSigTok = tkDecl; + bool successfullyGotDeclSig = false; + bool successfullyGotBodySig = false; + + if (TypeFromToken(tkDeclSigTok) == mdtMethodSpec) + { + mdToken meth=0; + if (SUCCEEDED(g_pImport->GetMethodSpecProps(tkDeclSigTok, &meth, NULL, NULL))) + { + tkDeclSigTok = meth; + } + } + + if (TypeFromToken(tkDeclSigTok) == mdtMethodDef) + { + if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkDeclSigTok, &cComSigDecl, &pComSigDecl))) + { + successfullyGotDeclSig = true; + } + } + else if (TypeFromToken(tkDeclSigTok) == mdtMemberRef) + { + const char *pszMemberNameUnused; + if (SUCCEEDED(g_pImport->GetNameAndSigOfMemberRef( + tkDeclSigTok, + &pComSigDecl, + &cComSigDecl, + &pszMemberNameUnused))) + { + successfullyGotDeclSig = true; + } + } + + PCCOR_SIGNATURE pComSigBody; + ULONG cComSigBody; + if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkOverrider, &cComSigBody, &pComSigBody))) + { + successfullyGotBodySig = true; + } + + if (successfullyGotDeclSig && successfullyGotBodySig) + { + if (cComSigBody != cComSigDecl) + { + needsFullTokenPrint = true; + } + else if (memcmp(pComSigBody, pComSigDecl, cComSigBody) != 0) + { + needsFullTokenPrint = true; + } + + // Signature are binary identical, full sig printing not needed + } + else + { + szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID BODY OR DECL SIG")); + } + } + + if (needsFullTokenPrint) + { + // In this case, the shortcut syntax cannot be used, and a full token must be printed. + // Print the full token and return. + szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method")); + PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider); + + *pbOverridingTypeSpec = TRUE; + return; + } + + if (hasTkDeclParent) + { + // If the tkDeclParent was successfully retrieved during parent discovery print it here. + PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider); + strcat_s(szString, SZSTRING_SIZE,"::"); + szptr = &szString[strlen(szString)]; + } + if(TypeFromToken(tkDecl) == mdtMethodSpec) { mdToken meth=0; diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj index 78d81b01d73e..2a6c4198b627 100644 --- a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj @@ -3,8 +3,6 @@ Exe BuildAndRun 0 - - true From c5e4fd71a8fe52026213d098b966b778dde60201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 7 Aug 2020 22:52:31 +0200 Subject: [PATCH 334/755] WASM: Add pkgproj for the browser debug proxy/host transport package (#40494) * WASM: Add pkgproj for the browser debug proxy/host transport package * Update src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs Co-authored-by: Larry Ewing Co-authored-by: Larry Ewing --- eng/Subsets.props | 7 +++- src/mono/netcore/nuget/Directory.Build.props | 41 +++++++++++++++++++ .../netcore/nuget/Directory.Build.targets | 8 ++++ ...NETCore.BrowserDebugHost.Transport.pkgproj | 26 ++++++++++++ src/mono/netcore/nuget/descriptions.json | 12 ++++++ src/mono/netcore/nuget/mono-packages.proj | 13 ++++++ src/mono/netcore/nuget/packageIndex.json | 2 + .../BrowserDebugHost/BrowserDebugHost.csproj | 2 + .../debugger/BrowserDebugProxy/MonoProxy.cs | 6 +-- 9 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 src/mono/netcore/nuget/Directory.Build.props create mode 100644 src/mono/netcore/nuget/Directory.Build.targets create mode 100644 src/mono/netcore/nuget/Microsoft.NETCore.BrowserDebugHost.Transport/Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj create mode 100644 src/mono/netcore/nuget/descriptions.json create mode 100644 src/mono/netcore/nuget/mono-packages.proj create mode 100644 src/mono/netcore/nuget/packageIndex.json diff --git a/eng/Subsets.props b/eng/Subsets.props index 2c52c183a2ce..293b59187ccf 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -57,7 +57,7 @@ clr.runtime+linuxdac+clr.corelib+clr.nativecorelib+clr.tools+clr.packages mono.llvm+ - $(DefaultMonoSubsets)mono.runtime+mono.corelib + $(DefaultMonoSubsets)mono.runtime+mono.corelib+mono.packages libs.native+libs.ref+libs.src+libs.pretest+libs.packages @@ -92,6 +92,7 @@ + @@ -167,6 +168,10 @@ + + + + diff --git a/src/mono/netcore/nuget/Directory.Build.props b/src/mono/netcore/nuget/Directory.Build.props new file mode 100644 index 000000000000..dc82034199d6 --- /dev/null +++ b/src/mono/netcore/nuget/Directory.Build.props @@ -0,0 +1,41 @@ + + + + + + + + + + $(MSBuildThisFileDirectory)/descriptions.json + $(CoreclrDir)/LICENSE.TXT + + https://go.microsoft.com/fwlink/?LinkID=799421 + + https://dot.net + + $(MSBuildThisFileDirectory)/packageIndex.json + AnyCPU + + + true + + $(ArtifactsObjDir)version.txt + + + + + + true + + + + + + true + + + + diff --git a/src/mono/netcore/nuget/Directory.Build.targets b/src/mono/netcore/nuget/Directory.Build.targets new file mode 100644 index 000000000000..568d3d34aedc --- /dev/null +++ b/src/mono/netcore/nuget/Directory.Build.targets @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/mono/netcore/nuget/Microsoft.NETCore.BrowserDebugHost.Transport/Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj b/src/mono/netcore/nuget/Microsoft.NETCore.BrowserDebugHost.Transport/Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj new file mode 100644 index 000000000000..f361ca5eb294 --- /dev/null +++ b/src/mono/netcore/nuget/Microsoft.NETCore.BrowserDebugHost.Transport/Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj @@ -0,0 +1,26 @@ + + + + + + false + + + + + + + + + tools\$(NetCoreAppCurrent)\BrowserDebugProxy.dll + + + tools\$(NetCoreAppCurrent)\BrowserDebugHost.dll + + + tools\$(NetCoreAppCurrent)\BrowserDebugHost.runtimeconfig.json + + + + + diff --git a/src/mono/netcore/nuget/descriptions.json b/src/mono/netcore/nuget/descriptions.json new file mode 100644 index 000000000000..5fb2e801ce68 --- /dev/null +++ b/src/mono/netcore/nuget/descriptions.json @@ -0,0 +1,12 @@ +[ + { + "Name": "NuGet3MinVersion", + "Description": "When using NuGet 3.x this package requires at least version {0}.", + "CommonTypes": [ ] + }, + { + "Name": "Microsoft.NETCore.BrowserDebugHost.Transport", + "Description": "Internal package for sharing BrowserDebugHost.", + "CommonTypes": [ ] + } +] diff --git a/src/mono/netcore/nuget/mono-packages.proj b/src/mono/netcore/nuget/mono-packages.proj new file mode 100644 index 000000000000..0f2794e1ebd2 --- /dev/null +++ b/src/mono/netcore/nuget/mono-packages.proj @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/mono/netcore/nuget/packageIndex.json b/src/mono/netcore/nuget/packageIndex.json new file mode 100644 index 000000000000..7a73a41bfdf7 --- /dev/null +++ b/src/mono/netcore/nuget/packageIndex.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj index 9a038a02e4bc..aee852c016ed 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj +++ b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj @@ -8,4 +8,6 @@ + + diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 197d499cb897..61707ae185c8 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -20,7 +20,7 @@ internal class MonoProxy : DevToolsProxy HashSet sessions = new HashSet(); Dictionary contexts = new Dictionary(); - public MonoProxy(ILoggerFactory loggerFactory, bool hideWebDriver = true) : base(loggerFactory) { hideWebDriver = true; } + public MonoProxy(ILoggerFactory loggerFactory, bool hideWebDriver = true) : base(loggerFactory) { this.hideWebDriver = hideWebDriver; } readonly bool hideWebDriver; @@ -149,8 +149,6 @@ async Task IsRuntimeAlreadyReadyAlready(SessionId sessionId, CancellationT return res.Value?["result"] ? ["value"]?.Value() ?? false; } - static int bpIdGenerator; - protected override async Task AcceptCommand(MessageId id, string method, JObject args, CancellationToken token) { // Inspector doesn't use the Target domain or sessions @@ -995,4 +993,4 @@ async Task DeleteWebDriver(SessionId sessionId, CancellationToken token) } } } -} \ No newline at end of file +} From 2f13c5fac55105a28869a37a4105d81f6320c97a Mon Sep 17 00:00:00 2001 From: imhameed Date: Fri, 7 Aug 2020 14:55:57 -0700 Subject: [PATCH 335/755] [mono] Allow creating `TypedReference *` and `TypedReference &` via reflection. (#40472) CoreCLR gained support for creating`TypedReference *` and `TypedReference &` via `MakePointerType` and `MakeByRefType` in https://github.com/dotnet/coreclr/pull/25817. Reenable byref System.Void-related reflection tests. Fixes https://github.com/dotnet/runtime/issues/31713. Fixes https://github.com/dotnet/runtime/issues/37489. --- .../tests/System/Type/TypePropertyTests.cs | 1 - .../tests/System/Type/TypeTests.cs | 2 -- src/mono/mono/metadata/icall.c | 18 ++++++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs index 75935d27bb0d..026c53d1bc46 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs @@ -224,7 +224,6 @@ public void IsArray_Get_ReturnsExpected() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/31713", TestRuntimes.Mono)] public void IsByRef_Get_ReturnsExpected() { Type t = CreateType(); diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs index 40df667733da..d801b567140a 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs @@ -391,7 +391,6 @@ public static IEnumerable MakeByRefType_TestData() [Theory] [MemberData(nameof(MakeByRefType_TestData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/37489", TestRuntimes.Mono)] public void MakeByRefType_Invoke_ReturnsExpected(Type t) { Type tPointer = t.MakeByRefType(); @@ -474,7 +473,6 @@ public static IEnumerable MakePointerType_TestData() [Theory] [MemberData(nameof(MakePointerType_TestData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/37489", TestRuntimes.Mono)] public void MakePointerType_Invoke_ReturnsExpected(Type t) { Type tPointer = t.MakePointerType(); diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 479ba5e95cbc..fa991bc72e57 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -7230,7 +7230,7 @@ ves_icall_System_Reflection_RuntimeModule_ResolveSignature (MonoImage *image, gu } static void -check_for_invalid_type (MonoClass *klass, MonoError *error) +check_for_invalid_array_type (MonoClass *klass, MonoError *error) { char *name; @@ -7243,13 +7243,23 @@ check_for_invalid_type (MonoClass *klass, MonoError *error) mono_error_set_type_load_name (error, name, g_strdup (""), ""); } +static void +check_for_invalid_byref_or_pointer_type (MonoClass *klass, MonoError *error) +{ +#ifdef ENABLE_NETCORE + return; +#else + check_for_invalid_array_type (klass, error); +#endif +} + MonoReflectionTypeHandle ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int rank, MonoError *error) { MonoType *type = MONO_HANDLE_GETVAL (ref_type, type); MonoClass *klass = mono_class_from_mono_type_internal (type); - check_for_invalid_type (klass, error); + check_for_invalid_array_type (klass, error); return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE)); MonoClass *aklass; @@ -7276,7 +7286,7 @@ ves_icall_RuntimeType_make_byref_type (MonoReflectionTypeHandle ref_type, MonoEr mono_class_init_checked (klass, error); return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE)); - check_for_invalid_type (klass, error); + check_for_invalid_byref_or_pointer_type (klass, error); return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE)); MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type); @@ -7292,7 +7302,7 @@ ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type, MonoEr mono_class_init_checked (klass, error); return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE)); - check_for_invalid_type (klass, error); + check_for_invalid_byref_or_pointer_type (klass, error); return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE)); MonoClass *pklass = mono_class_create_ptr (type); From 83ee84a7d62af9beac1999092c75c3a09d0d887d Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sat, 8 Aug 2020 01:18:28 +0300 Subject: [PATCH 336/755] Reduced code size and optimized name key creation for JSON properties and parameters (#40136) --- .../Json/Serialization/JsonClassInfo.Cache.cs | 87 ++++++------------- 1 file changed, 25 insertions(+), 62 deletions(-) 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 7b01b16fb477..0de7ed3ea231 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 @@ -446,84 +446,47 @@ private static bool IsParameterRefEqual(in ParameterRef parameterRef, ReadOnlySp /// // AggressiveInlining used since this method is only called from two locations and is on a hot path. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong GetKey(ReadOnlySpan propertyName) + public static ulong GetKey(ReadOnlySpan name) { - const int BitsInByte = 8; ulong key; - int length = propertyName.Length; + + ref byte reference = ref MemoryMarshal.GetReference(name); + int length = name.Length; if (length > 7) { - key = MemoryMarshal.Read(propertyName) - & 0x00FFFFFFFFFFFFFF - // Include the length with a max of 0xFF. - | ((ulong)Math.Min(length, 0xFF)) << (7 * BitsInByte); - } - else if (length > 3) - { - key = MemoryMarshal.Read(propertyName); - - if (length == 7) - { - key |= (ulong)propertyName[6] << (6 * BitsInByte) - | (ulong)propertyName[5] << (5 * BitsInByte) - | (ulong)propertyName[4] << (4 * BitsInByte) - | (ulong)7 << (7 * BitsInByte); - } - else if (length == 6) - { - key |= (ulong)propertyName[5] << (5 * BitsInByte) - | (ulong)propertyName[4] << (4 * BitsInByte) - | (ulong)6 << (7 * BitsInByte); - } - else if (length == 5) - { - key |= (ulong)propertyName[4] << (4 * BitsInByte) - | (ulong)5 << (7 * BitsInByte); - } - else - { - key |= (ulong)4 << (7 * BitsInByte); - } + key = Unsafe.ReadUnaligned(ref reference) & 0x00ffffffffffffffL; + key |= (ulong)Math.Min(length, 0xff) << 56; } - else if (length > 1) + else { - key = MemoryMarshal.Read(propertyName); + key = + length > 5 ? Unsafe.ReadUnaligned(ref reference) | (ulong)Unsafe.ReadUnaligned(ref Unsafe.Add(ref reference, 4)) << 32 : + length > 3 ? Unsafe.ReadUnaligned(ref reference) : + length > 1 ? Unsafe.ReadUnaligned(ref reference) : 0UL; + key |= (ulong)length << 56; - if (length == 3) - { - key |= (ulong)propertyName[2] << (2 * BitsInByte) - | (ulong)3 << (7 * BitsInByte); - } - else + if ((length & 1) != 0) { - key |= (ulong)2 << (7 * BitsInByte); + var offset = length - 1; + key |= (ulong)Unsafe.Add(ref reference, offset) << (offset * 8); } } - else if (length == 1) - { - key = propertyName[0] - | (ulong)1 << (7 * BitsInByte); - } - else - { - // An empty name is valid. - key = 0; - } // Verify key contains the embedded bytes as expected. + const int BitsInByte = 8; Debug.Assert( // Verify embedded property name. - (length < 1 || propertyName[0] == ((key & ((ulong)0xFF << BitsInByte * 0)) >> BitsInByte * 0)) && - (length < 2 || propertyName[1] == ((key & ((ulong)0xFF << BitsInByte * 1)) >> BitsInByte * 1)) && - (length < 3 || propertyName[2] == ((key & ((ulong)0xFF << BitsInByte * 2)) >> BitsInByte * 2)) && - (length < 4 || propertyName[3] == ((key & ((ulong)0xFF << BitsInByte * 3)) >> BitsInByte * 3)) && - (length < 5 || propertyName[4] == ((key & ((ulong)0xFF << BitsInByte * 4)) >> BitsInByte * 4)) && - (length < 6 || propertyName[5] == ((key & ((ulong)0xFF << BitsInByte * 5)) >> BitsInByte * 5)) && - (length < 7 || propertyName[6] == ((key & ((ulong)0xFF << BitsInByte * 6)) >> BitsInByte * 6)) && + (name.Length < 1 || name[0] == ((key & ((ulong)0xFF << BitsInByte * 0)) >> BitsInByte * 0)) && + (name.Length < 2 || name[1] == ((key & ((ulong)0xFF << BitsInByte * 1)) >> BitsInByte * 1)) && + (name.Length < 3 || name[2] == ((key & ((ulong)0xFF << BitsInByte * 2)) >> BitsInByte * 2)) && + (name.Length < 4 || name[3] == ((key & ((ulong)0xFF << BitsInByte * 3)) >> BitsInByte * 3)) && + (name.Length < 5 || name[4] == ((key & ((ulong)0xFF << BitsInByte * 4)) >> BitsInByte * 4)) && + (name.Length < 6 || name[5] == ((key & ((ulong)0xFF << BitsInByte * 5)) >> BitsInByte * 5)) && + (name.Length < 7 || name[6] == ((key & ((ulong)0xFF << BitsInByte * 6)) >> BitsInByte * 6)) && // Verify embedded length. - (length >= 0xFF || (key & ((ulong)0xFF << BitsInByte * 7)) >> BitsInByte * 7 == (ulong)length) && - (length < 0xFF || (key & ((ulong)0xFF << BitsInByte * 7)) >> BitsInByte * 7 == 0xFF)); + (name.Length >= 0xFF || (key & ((ulong)0xFF << BitsInByte * 7)) >> BitsInByte * 7 == (ulong)name.Length) && + (name.Length < 0xFF || (key & ((ulong)0xFF << BitsInByte * 7)) >> BitsInByte * 7 == 0xFF)); return key; } From 57678512d214af368ff055f358c5106f1aa19ac4 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 7 Aug 2020 15:21:30 -0700 Subject: [PATCH 337/755] Sign and add entitlements to createdump and host binaries (#40485) Sign and add entitlements to createdump and host binaries Enables createdump on MacOS. Part of issue #https://github.com/dotnet/runtime/issues/34916. Don't attempt to sign in a public PR job --- eng/Subsets.props | 2 + .../common/createdump-entitlements.plist | 12 ++++ eng/pipelines/common/entitlements.plist | 18 +++++ .../common/macos-sign-with-entitlements.yml | 65 +++++++++++++++++++ eng/pipelines/coreclr/templates/build-job.yml | 22 +++++++ eng/pipelines/installer/jobs/base-job.yml | 27 +++++++- 6 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 eng/pipelines/common/createdump-entitlements.plist create mode 100644 eng/pipelines/common/entitlements.plist create mode 100644 eng/pipelines/common/macos-sign-with-entitlements.yml diff --git a/eng/Subsets.props b/eng/Subsets.props index 293b59187ccf..f7f61f98f6e9 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -70,6 +70,7 @@ <_subset>$(_subset.Replace('+mono+', '+$(DefaultMonoSubsets)+')) <_subset>$(_subset.Replace('+libs+', '+$(DefaultLibrariesSubsets)+')) <_subset>$(_subset.Replace('+installer+', '+$(DefaultInstallerSubsets)+')) + <_subset>$(_subset.Replace('+installer.nocorehost+', '+$(DefaultInstallerSubsets.Replace('corehost+', ''))+')) <_subset>+$(_subset.Trim('+'))+ @@ -106,6 +107,7 @@ + diff --git a/eng/pipelines/common/createdump-entitlements.plist b/eng/pipelines/common/createdump-entitlements.plist new file mode 100644 index 000000000000..1f2d3798ee2f --- /dev/null +++ b/eng/pipelines/common/createdump-entitlements.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.debugger + + + diff --git a/eng/pipelines/common/entitlements.plist b/eng/pipelines/common/entitlements.plist new file mode 100644 index 000000000000..f4ea418fb45a --- /dev/null +++ b/eng/pipelines/common/entitlements.plist @@ -0,0 +1,18 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.debugger + + com.apple.security.get-task-allow + + + diff --git a/eng/pipelines/common/macos-sign-with-entitlements.yml b/eng/pipelines/common/macos-sign-with-entitlements.yml new file mode 100644 index 000000000000..6c65193845d7 --- /dev/null +++ b/eng/pipelines/common/macos-sign-with-entitlements.yml @@ -0,0 +1,65 @@ +parameters: + filesToSign: [] + +steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core SDK 2.1.808' + inputs: + packageType: sdk + version: 2.1.808 + + - ${{ each file in parameters.filesToSign }}: + - script: codesign -s - -f --entitlements ${{ file.entitlementsFile }} ${{ file.path }}/${{ file.name }} + displayName: 'Add entitlements to ${{ file.name }}' + + - task: CopyFiles@2 + displayName: 'Copy entitled file ${{ file.name }}' + inputs: + contents: '${{ file.path }}/${{ file.name }}' + targetFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled' + overWrite: true + + - task: ArchiveFiles@2 + displayName: 'Zip MacOS files for signing' + inputs: + rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/mac_entitled' + archiveFile: '$(Build.ArtifactStagingDirectory)/mac_entitled_to_sign.zip' + archiveType: zip + includeRootFolder: true + replaceExistingArchive: true + + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 + displayName: 'ESRP CodeSigning' + inputs: + ConnectedServiceName: 'ESRP CodeSigning' + FolderPath: '$(Build.ArtifactStagingDirectory)/' + Pattern: 'mac_entitled_to_sign.zip' + UseMinimatch: true + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-401337-Apple", + "operationCode": "MacAppDeveloperSign", + "parameters" : { + "hardening": "Enable" + }, + "toolName": "sign", + "toolVersion": "1.0" + } + ] + + - task: ExtractFiles@1 + displayName: 'Extract MacOS after signing' + inputs: + archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/mac_entitled_to_sign.zip' + destinationFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled_signed' + + - ${{ each file in parameters.filesToSign }}: + - task: CopyFiles@2 + displayName: 'Copy ${{ file.name }} to destination' + inputs: + contents: ${{ file.name }} + sourceFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled_signed' + targetFolder: '${{ file.path }}' + overWrite: true diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index f2b45e8072cc..f56c06f56ad6 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -167,6 +167,28 @@ jobs: - script: $(coreClrRepoRootDir)build-test$(scriptExt) skipstressdependencies skipmanaged skipgeneratelayout $(buildConfig) $(archType) $(crossArg) $(osArg) $(priorityArg) $(compilerArg) displayName: Build native test components + # Sign and add entitlements to these MacOS binaries + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.osGroup, 'OSX') }}: + + - template: /eng/pipelines/common/macos-sign-with-entitlements.yml + parameters: + filesToSign: + - name: createdump + path: $(buildProductRootFolderPath) + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/createdump-entitlements.plist + - name: corerun + path: $(buildProductRootFolderPath) + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + + - task: CopyFiles@2 + displayName: 'Copy signed createdump to sharedFramework' + inputs: + contents: createdump + sourceFolder: $(buildProductRootFolderPath) + targetFolder: $(buildProductRootFolderPath)/sharedFramework + overWrite: true + # Sign on Windows - ${{ if and(eq(parameters.osGroup, 'Windows_NT'), eq(parameters.signBinaries, 'true'), ne(parameters.testGroup, 'clrTools')) }}: - powershell: eng\common\build.ps1 -ci -sign -restore -configuration:$(buildConfig) -warnaserror:0 /p:ArcadeBuild=true /p:OfficialBuild=true /p:TargetOS=$(osGroup) /p:TargetArchitecture=$(archType) /p:Configuration=$(_BuildConfig) /p:DotNetSignType=$env:_SignType -projects $(Build.SourcesDirectory)\eng\empty.csproj diff --git a/eng/pipelines/installer/jobs/base-job.yml b/eng/pipelines/installer/jobs/base-job.yml index b74bf18fb60c..9ad565067c74 100644 --- a/eng/pipelines/installer/jobs/base-job.yml +++ b/eng/pipelines/installer/jobs/base-job.yml @@ -132,7 +132,7 @@ jobs: - name: BaseJobBuildCommand value: >- - $(Build.SourcesDirectory)/build.sh -subset installer -ci + $(Build.SourcesDirectory)/build.sh -ci $(BuildAction) -configuration $(_BuildConfig) $(LiveOverridePathArgs) @@ -456,8 +456,29 @@ jobs: df -h displayName: Disk Usage before Build - - script: $(BaseJobBuildCommand) - displayName: Build + # Build the default subset non-MacOS platforms + - ${{ if ne(parameters.osGroup, 'OSX') }}: + - script: $(BaseJobBuildCommand) + displayName: Build + + # Build corehost, sign and add entitlements to MacOS binaries + - ${{ if eq(parameters.osGroup, 'OSX') }}: + - script: $(BaseJobBuildCommand) -subset corehost + displayName: Build CoreHost + + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/pipelines/common/macos-sign-with-entitlements.yml + parameters: + filesToSign: + - name: dotnet + path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + - name: apphost + path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + + - script: $(BaseJobBuildCommand) -subset installer.nocorehost + displayName: Build and Package - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: - script: | From 39b9607807f29e48cae4652cd74735182b31182e Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Fri, 7 Aug 2020 15:23:13 -0700 Subject: [PATCH 338/755] Remove perf CI runs (#40540) --- eng/pipelines/coreclr/perf.yml | 83 ++++++++++++++-------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index 0cb8d81f925c..dd120af2255e 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -17,25 +17,8 @@ trigger: - README.md - SECURITY.md - THIRD-PARTY-NOTICES.TXT - - -pr: - branches: - include: - - master - paths: - include: - - '*' - - src/libraries/System.Private.CoreLib/* - exclude: - - docs/* - - CODE-OF-CONDUCT.md - - CONTRIBUTING.md - - LICENSE.TXT - - PATENTS.TXT - - README.md - - SECURITY.md - - THIRD-PARTY-NOTICES.TXT + +pr: none jobs: # @@ -94,38 +77,38 @@ jobs: projectFile: microbenchmarks.proj runKind: micro_mono -# run mono interpreter job (private CI only) -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml - buildConfig: release - runtimeFlavor: mono - platforms: - - Linux_x64 - jobParameters: - testGroup: perf - liveLibrariesBuildConfig: Release - runtimeType: mono - codeGenType: 'Interpreter' - projectFile: microbenchmarks.proj - runKind: micro_mono +# run mono interpreter job +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: mono + platforms: + - Linux_x64 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + runtimeType: mono + codeGenType: 'Interpreter' + projectFile: microbenchmarks.proj + runKind: micro_mono - # run mono wasm microbenchmarks perf job - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml - buildConfig: release - runtimeFlavor: wasm - platforms: - - Linux_x64 - jobParameters: - testGroup: perf - liveLibrariesBuildConfig: Release - runtimeType: wasm - codeGenType: 'wasm' - projectFile: microbenchmarks.proj - runKind: micro +# run mono wasm microbenchmarks perf job +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: wasm + platforms: + - Linux_x64 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + runtimeType: wasm + codeGenType: 'wasm' + projectFile: microbenchmarks.proj + runKind: micro + # run coreclr microbenchmarks perf job - template: /eng/pipelines/common/platform-matrix.yml parameters: From 20e481843bfbead4987045a5cca5c1aaf9124517 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Fri, 7 Aug 2020 20:07:48 -0300 Subject: [PATCH 339/755] [wasm] [debugger] Support Exception Break on Debugger (handled and unhandled) (#40480) * Support Exception Break on Debugger (handled and unhandled) Co-authored-by: Ankit Jain --- src/mono/mono/mini/mini-wasm-debugger.c | 81 ++++-- .../BrowserDebugHost/BrowserDebugHost.csproj | 2 +- .../BrowserDebugProxy/AssemblyInfo.cs | 4 - .../BrowserDebugProxy.csproj | 2 +- .../BrowserDebugProxy/DevToolsHelper.cs | 4 + .../debugger/BrowserDebugProxy/MonoProxy.cs | 37 ++- .../DebuggerTestSuite/ExceptionTests.cs | 264 ++++++++++++++++++ .../debugger/DebuggerTestSuite/Support.cs | 6 + .../debugger/tests/debugger-exception-test.cs | 55 ++++ src/mono/wasm/debugger/tests/other.js | 19 ++ src/mono/wasm/runtime/library_mono.js | 10 + 11 files changed, 456 insertions(+), 28 deletions(-) delete mode 100644 src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-exception-test.cs diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index dc1f5d38f3d2..90855b582859 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -24,6 +24,12 @@ static int log_level = 1; #define DEBUG_PRINTF(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { fprintf (stdout, __VA_ARGS__); } } while (0) +enum { + EXCEPTION_MODE_NONE, + EXCEPTION_MODE_UNCAUGHT, + EXCEPTION_MODE_ALL +}; + //functions exported to be used by JS G_BEGIN_DECLS @@ -34,6 +40,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_enum_frames (void); EMSCRIPTEN_KEEPALIVE void mono_wasm_get_var_info (int scope, int* pos, int len); EMSCRIPTEN_KEEPALIVE void mono_wasm_clear_all_breakpoints (void); EMSCRIPTEN_KEEPALIVE int mono_wasm_setup_single_step (int kind); +EMSCRIPTEN_KEEPALIVE int mono_wasm_pause_on_exceptions (int state); EMSCRIPTEN_KEEPALIVE void mono_wasm_get_object_properties (int object_id, gboolean expand_value_types); EMSCRIPTEN_KEEPALIVE void mono_wasm_get_array_values (int object_id); EMSCRIPTEN_KEEPALIVE void mono_wasm_get_array_value_expanded (int object_id, int idx); @@ -43,6 +50,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_get_deref_ptr_value (void *value_addr, MonoC //JS functions imported that we use extern void mono_wasm_add_frame (int il_offset, int method_token, const char *assembly_name, const char *method_name); extern void mono_wasm_fire_bp (void); +extern void mono_wasm_fire_exception (int exception_obj_id, const char* message, const char* class_name, gboolean uncaught); extern void mono_wasm_add_obj_var (const char*, const char*, guint64); extern void mono_wasm_add_value_type_unexpanded_var (const char*, const char*); extern void mono_wasm_begin_value_type_var (const char*, const char*); @@ -57,6 +65,7 @@ extern void mono_wasm_add_typed_value (const char *type, const char *str_value, G_END_DECLS static void describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAsyncLocalThis, gboolean expandValueType); +static void handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame); //FIXME move all of those fields to the profiler object static gboolean debugger_enabled; @@ -65,6 +74,7 @@ static int event_request_id; static GHashTable *objrefs; static GHashTable *obj_to_objref; static int objref_id = 0; +static int pause_on_exc = EXCEPTION_MODE_NONE; static const char* all_getters_allowed_class_names[] = { @@ -363,6 +373,8 @@ mono_wasm_debugger_init (void) obj_to_objref = g_hash_table_new (NULL, NULL); objrefs = g_hash_table_new_full (NULL, NULL, NULL, mono_debugger_free_objref); + + mini_get_dbg_callbacks ()->handle_exception = handle_exception; } MONO_API void @@ -373,6 +385,14 @@ mono_wasm_enable_debugging (int debug_level) log_level = debug_level; } +EMSCRIPTEN_KEEPALIVE int +mono_wasm_pause_on_exceptions (int state) +{ + pause_on_exc = state; + DEBUG_PRINTF (1, "setting pause on exception: %d\n", pause_on_exc); + return 1; +} + EMSCRIPTEN_KEEPALIVE int mono_wasm_setup_single_step (int kind) { @@ -428,6 +448,50 @@ mono_wasm_setup_single_step (int kind) return isBPOnNativeCode; } +static int +get_object_id(MonoObject *obj) +{ + ObjRef *ref; + if (!obj) + return 0; + + ref = (ObjRef *)g_hash_table_lookup (obj_to_objref, GINT_TO_POINTER (~((gsize)obj))); + if (ref) + return ref->id; + ref = g_new0 (ObjRef, 1); + ref->id = mono_atomic_inc_i32 (&objref_id); + ref->handle = mono_gchandle_new_weakref_internal (obj, FALSE); + g_hash_table_insert (objrefs, GINT_TO_POINTER (ref->id), ref); + g_hash_table_insert (obj_to_objref, GINT_TO_POINTER (~((gsize)obj)), ref); + return ref->id; +} + +static void +handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame) +{ + ERROR_DECL (error); + DEBUG_PRINTF (1, "handle exception - %d - %p - %p - %p\n", pause_on_exc, exc, throw_ctx, catch_ctx); + + if (pause_on_exc == EXCEPTION_MODE_NONE) + return; + if (pause_on_exc == EXCEPTION_MODE_UNCAUGHT && catch_ctx != NULL) + return; + + int obj_id = get_object_id ((MonoObject *)exc); + const char *error_message = mono_string_to_utf8_checked_internal (exc->message, error); + + if (!is_ok (error)) + error_message = "Failed to get exception message."; + + const char *class_name = mono_class_full_name (mono_object_class (exc)); + DEBUG_PRINTF (2, "handle exception - calling mono_wasm_fire_exc(): %d - message - %s, class_name: %s\n", obj_id, error_message, class_name); + + mono_wasm_fire_exception (obj_id, error_message, class_name, !catch_ctx); + + DEBUG_PRINTF (2, "handle exception - done\n"); +} + + EMSCRIPTEN_KEEPALIVE void mono_wasm_clear_all_breakpoints (void) { @@ -567,23 +631,6 @@ mono_wasm_current_bp_id (void) return evt->id; } -static int get_object_id(MonoObject *obj) -{ - ObjRef *ref; - if (!obj) - return 0; - - ref = (ObjRef *)g_hash_table_lookup (obj_to_objref, GINT_TO_POINTER (~((gsize)obj))); - if (ref) - return ref->id; - ref = g_new0 (ObjRef, 1); - ref->id = mono_atomic_inc_i32 (&objref_id); - ref->handle = mono_gchandle_new_weakref_internal (obj, FALSE); - g_hash_table_insert (objrefs, GINT_TO_POINTER (ref->id), ref); - g_hash_table_insert (obj_to_objref, GINT_TO_POINTER (~((gsize)obj)), ref); - return ref->id; -} - static gboolean list_frames (MonoStackFrameInfo *info, MonoContext *ctx, gpointer data) { diff --git a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj index aee852c016ed..9650dc835663 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj +++ b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + $(NetCoreAppCurrent) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs b/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs deleted file mode 100644 index 5d9d173c2446..000000000000 --- a/src/mono/wasm/debugger/BrowserDebugProxy/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; \ No newline at end of file diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj index 4063416ceb07..7da1586b7fb3 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj +++ b/src/mono/wasm/debugger/BrowserDebugProxy/BrowserDebugProxy.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + $(NetCoreAppCurrent) true diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index 45edb968a549..d17c9e739130 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -175,6 +175,8 @@ internal class MonoCommands public static MonoCommands GetCallStack() => new MonoCommands("MONO.mono_wasm_get_call_stack()"); + public static MonoCommands GetExceptionObject () => new MonoCommands ("MONO.mono_wasm_get_exception_object()"); + public static MonoCommands IsRuntimeReady() => new MonoCommands("MONO.mono_wasm_runtime_is_ready"); public static MonoCommands StartSingleStepping(StepKind kind) => new MonoCommands($"MONO.mono_wasm_start_single_stepping ({(int)kind})"); @@ -200,6 +202,8 @@ public static MonoCommands GetScopeVariables(int scopeId, params VarInfo[] vars) public static MonoCommands CallFunctionOn(JToken args) => new MonoCommands($"MONO.mono_wasm_call_function_on ({args.ToString ()})"); public static MonoCommands Resume() => new MonoCommands($"MONO.mono_wasm_debugger_resume ()"); + + public static MonoCommands SetPauseOnExceptions (string state) => new MonoCommands ($"MONO.mono_wasm_set_pause_on_exceptions(\"{state}\")"); } internal enum MonoErrorCodes diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 61707ae185c8..1f1079f8c0c7 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -99,9 +99,9 @@ protected override async Task AcceptEvent(SessionId sessionId, string meth //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack var top_func = args?["callFrames"] ? [0] ? ["functionName"]?.Value(); - if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") + if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_exception") { - return await OnBreakpointHit(sessionId, args, token); + return await OnPause(sessionId, args, token); } break; } @@ -329,6 +329,14 @@ protected override async Task AcceptCommand(MessageId id, string method, J return true; } + case "Debugger.setPauseOnExceptions": + { + string state = args["state"].Value (); + await SendMonoCommand(id, MonoCommands.SetPauseOnExceptions (state), token); + // Pass this on to JS too + return false; + } + // Protocol extensions case "DotnetDebugger.getMethodLocation": { @@ -449,12 +457,14 @@ async Task RuntimeGetProperties(MessageId id, DotnetObjectId objectId, J } //static int frame_id=0; - async Task OnBreakpointHit(SessionId sessionId, JObject args, CancellationToken token) + async Task OnPause(SessionId sessionId, JObject args, CancellationToken token) { //FIXME we should send release objects every now and then? Or intercept those we inject and deal in the runtime var res = await SendMonoCommand(sessionId, MonoCommands.GetCallStack(), token); var orig_callframes = args?["callFrames"]?.Values(); var context = GetContext(sessionId); + JObject data = null; + var reason = "other";//other means breakpoint if (res.IsErr) { @@ -486,8 +496,24 @@ async Task OnBreakpointHit(SessionId sessionId, JObject args, Cancellation { var function_name = frame["functionName"]?.Value(); var url = frame["url"]?.Value(); - if ("mono_wasm_fire_bp" == function_name ||"_mono_wasm_fire_bp" == function_name) + if ("mono_wasm_fire_bp" == function_name ||"_mono_wasm_fire_bp" == function_name || + "_mono_wasm_fire_exception" == function_name) { + if ("_mono_wasm_fire_exception" == function_name) { + var exception_obj_id = await SendMonoCommand(sessionId, MonoCommands.GetExceptionObject (), token); + var res_val = exception_obj_id.Value? ["result"]? ["value"]; + var exception_dotnet_obj_id = new DotnetObjectId("object", res_val?["exception_id"]?.Value ()); + data = JObject.FromObject (new { + type = "object", + subtype = "error", + className = res_val? ["class_name"]?.Value(), + uncaught = res_val? ["uncaught"]?.Value(), + description = res_val? ["message"]?.Value() + "\n", + objectId = exception_dotnet_obj_id.ToString() + }); + reason = "exception"; + } + var frames = new List(); int frame_id = 0; var the_mono_frames = res.Value?["result"] ? ["value"] ? ["frames"]?.Values(); @@ -580,7 +606,8 @@ async Task OnBreakpointHit(SessionId sessionId, JObject args, Cancellation var o = JObject.FromObject(new { callFrames, - reason = "other", //other means breakpoint + reason, + data, hitBreakpoints = bp_list, }); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs new file mode 100644 index 000000000000..301c4227cf48 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs @@ -0,0 +1,264 @@ +// 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.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Microsoft.WebAssembly.Diagnostics; +using Xunit; + +namespace DebuggerTests +{ + + public class ExceptionTests : DebuggerTestBase + { + [Fact] + public async Task ExceptionTestAll() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + int line = 15; + int col = 20; + string entry_method_name = "[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions"; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-exception-test.cs"; + + await SetPauseOnException("all"); + + var eval_expr = "window.setTimeout(function() { invoke_static_method (" + + $"'{entry_method_name}'" + + "); }, 1);"; + + var pause_location = await EvaluateAndCheck(eval_expr, null, 0, 0, null); + //stop in the managed caught exception + pause_location = await WaitForManagedException(pause_location); + + AssertEqual("run", pause_location["callFrames"] ? [0] ? ["functionName"]?.Value(), "pause0"); + + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "DebuggerTests.CustomException", + uncaught = false + }), "exception0.data"); + + var exception_members = await GetProperties(pause_location["data"]["objectId"]?.Value()); + CheckString(exception_members, "message", "not implemented caught"); + + pause_location = await WaitForManagedException(null); + AssertEqual("run", pause_location["callFrames"] ? [0] ? ["functionName"]?.Value(), "pause1"); + + //stop in the uncaught exception + CheckLocation(debugger_test_loc, 28, 16, scripts, pause_location["callFrames"][0]["location"]); + + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "DebuggerTests.CustomException", + uncaught = true + }), "exception1.data"); + + exception_members = await GetProperties(pause_location["data"]["objectId"]?.Value()); + CheckString(exception_members, "message", "not implemented uncaught"); + }); + } + + [Fact] + public async Task JSExceptionTestAll() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetPauseOnException("all"); + + var eval_expr = "window.setTimeout(function () { exceptions_test (); }, 1)"; + var pause_location = await EvaluateAndCheck(eval_expr, null, 0, 0, "exception_caught_test", null, null); + + Assert.Equal("exception", pause_location["reason"]); + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "TypeError", + uncaught = false + }), "exception0.data"); + + var exception_members = await GetProperties(pause_location["data"]["objectId"]?.Value()); + CheckString(exception_members, "message", "exception caught"); + + pause_location = await SendCommandAndCheck(null, "Debugger.resume", null, 0, 0, "exception_uncaught_test"); + + Assert.Equal("exception", pause_location["reason"]); + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "RangeError", + uncaught = true + }), "exception1.data"); + + exception_members = await GetProperties(pause_location["data"]["objectId"]?.Value()); + CheckString(exception_members, "message", "exception uncaught"); + }); + } + + // FIXME? BUG? We seem to get the stack trace for Runtime.exceptionThrown at `call_method`, + // but JS shows the original error type, and original trace + [Fact] + public async Task ExceptionTestNone() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + string entry_method_name = "[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions"; + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetPauseOnException("none"); + + var eval_expr = "window.setTimeout(function() { invoke_static_method (" + + $"'{entry_method_name}'" + + "); }, 1);"; + + try + { + await EvaluateAndCheck(eval_expr, null, 0, 0, "", null, null); + } + catch (ArgumentException ae) + { + var eo = JObject.Parse(ae.Message); + + // AssertEqual (line, eo ["exceptionDetails"]?["lineNumber"]?.Value (), "lineNumber"); + AssertEqual("Uncaught", eo["exceptionDetails"] ? ["text"]?.Value(), "text"); + + await CheckValue(eo["exceptionDetails"] ? ["exception"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "Error" // BUG?: "DebuggerTests.CustomException" + }), "exception"); + + return; + } + + Assert.True(false, "Expected to get an ArgumentException from the uncaught user exception"); + }); + } + + [Fact] + public async Task JSExceptionTestNone() + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetPauseOnException("none"); + + var eval_expr = "window.setTimeout(function () { exceptions_test (); }, 1)"; + + int line = 44; + try + { + await EvaluateAndCheck(eval_expr, null, 0, 0, "", null, null); + } + catch (ArgumentException ae) + { + Console.WriteLine($"{ae}"); + var eo = JObject.Parse(ae.Message); + + AssertEqual(line, eo["exceptionDetails"] ? ["lineNumber"]?.Value(), "lineNumber"); + AssertEqual("Uncaught", eo["exceptionDetails"] ? ["text"]?.Value(), "text"); + + await CheckValue(eo["exceptionDetails"] ? ["exception"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "RangeError" + }), "exception"); + + return; + } + + Assert.True(false, "Expected to get an ArgumentException from the uncaught user exception"); + }); + } + + [Theory] + [InlineData("function () { exceptions_test (); }", null, 0, 0, "exception_uncaught_test", "RangeError", "exception uncaught")] + [InlineData("function () { invoke_static_method ('[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions'); }", + "dotnet://debugger-test.dll/debugger-exception-test.cs", 28, 16, "run", + "DebuggerTests.CustomException", "not implemented uncaught")] + public async Task ExceptionTestUncaught(string eval_fn, string loc, int line, int col, string fn_name, + string exception_type, string exception_message) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + + await SetPauseOnException("uncaught"); + + var eval_expr = $"window.setTimeout({eval_fn}, 1);"; + var pause_location = await EvaluateAndCheck(eval_expr, loc, line, col, fn_name); + + Assert.Equal("exception", pause_location["reason"]); + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = exception_type, + uncaught = true + }), "exception.data"); + + var exception_members = await GetProperties(pause_location["data"]["objectId"]?.Value()); + CheckString(exception_members, "message", exception_message); + }); + } + + async Task WaitForManagedException(JObject pause_location) + { + while (true) + { + if (pause_location != null) + { + AssertEqual("exception", pause_location ["reason"]?.Value (), $"Expected to only pause because of an exception. {pause_location}"); + + // return in case of a managed exception, and ignore JS ones + if (pause_location["data"]?["objectId"]?.Value ()?.StartsWith("dotnet:object:") == true) + { + break; + } + } + + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); + } + + return pause_location; + } + } +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs index b038d2cd8385..cac5e736b3a0 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs @@ -869,6 +869,12 @@ internal async Task SetBreakpoint(string url_key, int line, int column, return bp1_res; } + internal async Task SetPauseOnException(string state) + { + var exc_res = await ctx.cli.SendCommand("Debugger.setPauseOnExceptions", JObject.FromObject(new { state = state }), ctx.token); + return exc_res; + } + internal async Task SetBreakpointInMethod(string assembly, string type, string method, int lineOffset = 0, int col = 0) { var req = JObject.FromObject(new { assemblyName = assembly, typeName = type, methodName = method, lineOffset = lineOffset }); diff --git a/src/mono/wasm/debugger/tests/debugger-exception-test.cs b/src/mono/wasm/debugger/tests/debugger-exception-test.cs new file mode 100644 index 000000000000..3eb253569422 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-exception-test.cs @@ -0,0 +1,55 @@ +// 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.Threading.Tasks; +namespace DebuggerTests +{ + public class ExceptionTestsClass + { + public class TestCaughtException + { + public void run() + { + try + { + throw new CustomException ("not implemented caught"); + } + catch + { + Console.WriteLine("caught exception"); + } + } + } + + public class TestUncaughtException + { + public void run() + { + throw new CustomException ("not implemented uncaught"); + } + } + + public static void TestExceptions() + { + TestCaughtException f = new TestCaughtException(); + f.run(); + + TestUncaughtException g = new TestUncaughtException(); + g.run(); + } + + } + + public class CustomException : Exception + { + // Using this name to match with what js has. + // helps with the tests + public string message; + public CustomException (string message) + : base (message) + { + this.message = message; + } + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/other.js b/src/mono/wasm/debugger/tests/other.js index 7ba8e66c8fa5..a1b121ee32bf 100644 --- a/src/mono/wasm/debugger/tests/other.js +++ b/src/mono/wasm/debugger/tests/other.js @@ -31,3 +31,22 @@ function getters_js_test () { console.log (`break here`); return ptd; } + +function exception_caught_test () { + try { + throw new TypeError ('exception caught'); + } catch (e) { + console.log(e); + } +} + +function exception_uncaught_test () { + console.log('uncaught test'); + throw new RangeError ('exception uncaught'); +} + +function exceptions_test () { + exception_caught_test (); + exception_uncaught_test (); +} + diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 0692c65b3624..5e1a1770897b 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1588,6 +1588,16 @@ var MonoSupportLib = { console.log ("mono_wasm_fire_bp"); debugger; }, + + mono_wasm_fire_exception: function (exception_id, message, class_name, uncaught) { + MONO.active_exception = { + exception_id: exception_id, + message : Module.UTF8ToString (message), + class_name : Module.UTF8ToString (class_name), + uncaught : uncaught + }; + debugger; + }, }; autoAddDeps(MonoSupportLib, '$MONO') From de6380e65a8d201900e7983a30a5c870d229ca3d Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 7 Aug 2020 16:10:58 -0700 Subject: [PATCH 340/755] Fix StringBuilder AV (#40500) * Fix StringBuilder AV * OOME --- .../src/System/Text/StringBuilder.cs | 6 ++---- .../tests/System/Text/StringBuilderTests.cs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs index 9e368e45e76f..dfdf689194d0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs @@ -795,7 +795,6 @@ public StringBuilder Append(char[]? value, int startIndex, int charCount) } } - /// /// Appends a string to the end of this builder. /// @@ -808,9 +807,8 @@ public StringBuilder Append(string? value) char[] chunkChars = m_ChunkChars; int chunkLength = m_ChunkLength; int valueLen = value.Length; - int newCurrentIndex = chunkLength + valueLen; - if (newCurrentIndex < chunkChars.Length) // Use strictly < to avoid issues if count == 0, newIndex == length + if (((uint)chunkLength + (uint)valueLen) < (uint)chunkChars.Length) // Use strictly < to avoid issues if count == 0, newIndex == length { if (valueLen <= 2) { @@ -835,7 +833,7 @@ public StringBuilder Append(string? value) } } - m_ChunkLength = newCurrentIndex; + m_ChunkLength = chunkLength + valueLen; } else { diff --git a/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs b/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs index 66d04633d01a..0d2489c2030a 100644 --- a/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs @@ -2230,5 +2230,23 @@ public static void EqualsIgnoresMaxCapacity() Assert.True(sb1.Equals(sb2)); } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static unsafe void FailureOnLargeString() + { + RemoteExecutor.Invoke(() => // Uses lots of memory + { + AssertExtensions.ThrowsAny(() => + { + StringBuilder sb = new StringBuilder(); + sb.Append(new char[2_000_000_000]); + sb.Length--; + string s = new string('x', 500_000_000); + sb.Append(s); // This should throw, not AV + }); + + return RemoteExecutor.SuccessExitCode; // workaround https://github.com/dotnet/arcade/issues/5865 + }).Dispose(); + } } } From d1c7946bb0892005a58ec647e3a6d8f3514cdc6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Sat, 8 Aug 2020 01:17:32 +0200 Subject: [PATCH 341/755] Continue updating previous generic dictionaries after expansion (#40355) Fix perf regression after introduction of expandable generic dictionaries. When we expand a generic dictionary, we should back propagate the change to previously allocated shorter versions of the same dictionary, otherwise already running JITted code may continue referring to the "old version" of the dictionary implying repeated slow path generic lookups. Thanks Tomas --- src/coreclr/src/jit/importer.cpp | 12 ++- src/coreclr/src/vm/genericdict.cpp | 89 ++++++++++++++++++----- src/coreclr/src/vm/genericdict.h | 16 +++- src/coreclr/src/vm/generics.cpp | 7 +- src/coreclr/src/vm/genmeth.cpp | 10 ++- src/coreclr/src/vm/method.cpp | 7 +- src/coreclr/src/vm/methodtable.cpp | 11 ++- src/coreclr/src/vm/methodtable.h | 6 +- src/coreclr/src/vm/methodtable.inl | 6 +- src/coreclr/src/vm/methodtablebuilder.cpp | 14 ++-- 10 files changed, 127 insertions(+), 51 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 5e575d1f2f49..463054b9b989 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -2117,11 +2117,18 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken nullptr DEBUGARG("impRuntimeLookup indirectOffset")); } + // The last indirection could be subject to a size check (dynamic dictionary expansion) + bool isLastIndirectionWithSizeCheck = + ((i == pRuntimeLookup->indirections - 1) && (pRuntimeLookup->sizeOffset != CORINFO_NO_SIZE_CHECK)); + if (i != 0) { slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree); slotPtrTree->gtFlags |= GTF_IND_NONFAULTING; - slotPtrTree->gtFlags |= GTF_IND_INVARIANT; + if (!isLastIndirectionWithSizeCheck) + { + slotPtrTree->gtFlags |= GTF_IND_INVARIANT; + } } if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset)) @@ -2131,8 +2138,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken if (pRuntimeLookup->offsets[i] != 0) { - // The last indirection could be subject to a size check (dynamic dictionary expansion) - if (i == pRuntimeLookup->indirections - 1 && pRuntimeLookup->sizeOffset != CORINFO_NO_SIZE_CHECK) + if (isLastIndirectionWithSizeCheck) { lastIndOfTree = impCloneExpr(slotPtrTree, &slotPtrTree, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL, nullptr DEBUGARG("impRuntimeLookup indirectOffset")); diff --git a/src/coreclr/src/vm/genericdict.cpp b/src/coreclr/src/vm/genericdict.cpp index 1fb05846c3c4..37044ef1d8c4 100644 --- a/src/coreclr/src/vm/genericdict.cpp +++ b/src/coreclr/src/vm/genericdict.cpp @@ -71,26 +71,39 @@ DictionaryLayout* DictionaryLayout::Allocate(WORD numSlots, //--------------------------------------------------------------------------------------- // -// Count the number of bytes that are required in a dictionary with the specified layout +// Total number of bytes for a dictionary with the specified layout (including optional back pointer +// used by expanded dictionaries). The pSlotSize argument is used to return the size +// to be stored in the size slot of the dictionary (not including the optional back pointer). // //static DWORD DictionaryLayout::GetDictionarySizeFromLayout( DWORD numGenericArgs, - PTR_DictionaryLayout pDictLayout) + PTR_DictionaryLayout pDictLayout, + DWORD* pSlotSize) { LIMITED_METHOD_DAC_CONTRACT; PRECONDITION(numGenericArgs > 0); PRECONDITION(CheckPointer(pDictLayout, NULL_OK)); + PRECONDITION(CheckPointer(pSlotSize)); - DWORD bytes = numGenericArgs * sizeof(TypeHandle); // Slots for instantiation arguments + DWORD slotBytes = numGenericArgs * sizeof(TypeHandle); // Slots for instantiation arguments + DWORD extraAllocBytes = 0; if (pDictLayout != NULL) { - bytes += sizeof(TADDR); // Slot for dictionary size - bytes += pDictLayout->m_numSlots * sizeof(TADDR); // Slots for dictionary slots based on a dictionary layout + DWORD numSlots = VolatileLoadWithoutBarrier(&pDictLayout->m_numSlots); + + slotBytes += sizeof(TADDR); // Slot for dictionary size + slotBytes += numSlots * sizeof(TADDR); // Slots for dictionary slots based on a dictionary layout + + if (numSlots > pDictLayout->m_numInitialSlots) + { + extraAllocBytes = sizeof(PTR_Dictionary); // Slot for the back-pointer in expanded dictionaries + } } - return bytes; + *pSlotSize = slotBytes; + return slotBytes + extraAllocBytes; } #ifndef DACCESS_COMPILE @@ -800,10 +813,11 @@ Dictionary* Dictionary::GetMethodDictionaryWithSizeCheck(MethodDesc* pMD, ULONG InstantiatedMethodDesc* pIMD = pMD->AsInstantiatedMethodDesc(); _ASSERTE(pDictLayout != NULL && pDictLayout->GetMaxSlots() > 0); - DWORD expectedDictionarySize = DictionaryLayout::GetDictionarySizeFromLayout(numGenericArgs, pDictLayout); - _ASSERT(currentDictionarySize < expectedDictionarySize); + DWORD expectedDictionarySlotSize; + DWORD expectedDictionaryAllocSize = DictionaryLayout::GetDictionarySizeFromLayout(numGenericArgs, pDictLayout, &expectedDictionarySlotSize); + _ASSERT(currentDictionarySize < expectedDictionarySlotSize); - Dictionary* pNewDictionary = (Dictionary*)(void*)pIMD->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(expectedDictionarySize)); + Dictionary* pNewDictionary = (Dictionary*)(void*)pIMD->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(expectedDictionaryAllocSize)); // Copy old dictionary entry contents for (DWORD i = 0; i < currentDictionarySize / sizeof(DictionaryEntry); i++) @@ -813,7 +827,8 @@ Dictionary* Dictionary::GetMethodDictionaryWithSizeCheck(MethodDesc* pMD, ULONG } DWORD* pSizeSlot = (DWORD*)(pNewDictionary + numGenericArgs); - *pSizeSlot = expectedDictionarySize; + *pSizeSlot = expectedDictionarySlotSize; + *pNewDictionary->GetBackPointerSlot(numGenericArgs) = pDictionary; // Publish the new dictionary slots to the type. FastInterlockExchangePointer(pIMD->m_pPerInstInfo.GetValuePtr(), pNewDictionary); @@ -855,11 +870,12 @@ Dictionary* Dictionary::GetTypeDictionaryWithSizeCheck(MethodTable* pMT, ULONG s DictionaryLayout* pDictLayout = pMT->GetClass()->GetDictionaryLayout(); _ASSERTE(pDictLayout != NULL && pDictLayout->GetMaxSlots() > 0); - DWORD expectedDictionarySize = DictionaryLayout::GetDictionarySizeFromLayout(numGenericArgs, pDictLayout); - _ASSERT(currentDictionarySize < expectedDictionarySize); + DWORD expectedDictionarySlotSize; + DWORD expectedDictionaryAllocSize = DictionaryLayout::GetDictionarySizeFromLayout(numGenericArgs, pDictLayout, &expectedDictionarySlotSize); + _ASSERT(currentDictionarySize < expectedDictionarySlotSize); // Expand type dictionary - Dictionary* pNewDictionary = (Dictionary*)(void*)pMT->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(expectedDictionarySize)); + Dictionary* pNewDictionary = (Dictionary*)(void*)pMT->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(expectedDictionaryAllocSize)); // Copy old dictionary entry contents for (DWORD i = 0; i < currentDictionarySize / sizeof(DictionaryEntry); i++) @@ -869,7 +885,8 @@ Dictionary* Dictionary::GetTypeDictionaryWithSizeCheck(MethodTable* pMT, ULONG s } DWORD* pSizeSlot = (DWORD*)(pNewDictionary + numGenericArgs); - *pSizeSlot = expectedDictionarySize; + *pSizeSlot = expectedDictionarySlotSize; + *pNewDictionary->GetBackPointerSlot(numGenericArgs) = pDictionary; // Publish the new dictionary slots to the type. ULONG dictionaryIndex = pMT->GetNumDicts() - 1; @@ -1490,12 +1507,46 @@ Dictionary::PopulateEntry( #if !defined(CROSSGEN_COMPILE) if (slotIndex != 0) { - Dictionary* pDictionary = (pMT != NULL) ? - GetTypeDictionaryWithSizeCheck(pMT, slotIndex) : - GetMethodDictionaryWithSizeCheck(pMD, slotIndex); + Dictionary* pDictionary; + DWORD numGenericArgs; + DictionaryLayout * pDictLayout; + if (pMT != NULL) + { + pDictionary = GetTypeDictionaryWithSizeCheck(pMT, slotIndex); + numGenericArgs = pMT->GetNumGenericArgs(); + pDictLayout = pMT->GetClass()->GetDictionaryLayout(); + } + else + { + pDictionary = GetMethodDictionaryWithSizeCheck(pMD, slotIndex); + numGenericArgs = pMD->GetNumGenericMethodArgs(); + pDictLayout = pMD->GetDictionaryLayout(); + } + DWORD minimumSizeOfDictionaryToPatch = (slotIndex + 1) * sizeof(DictionaryEntry *); + DWORD sizeOfInitialDictionary = (numGenericArgs + 1 + pDictLayout->GetNumInitialSlots()) * sizeof(DictionaryEntry *); + + DictionaryEntry *slot = pDictionary->GetSlotAddr(0, slotIndex); + VolatileStoreWithoutBarrier(slot, (DictionaryEntry)result); + *ppSlot = slot; - VolatileStoreWithoutBarrier(pDictionary->GetSlotAddr(0, slotIndex), (DictionaryEntry)result); - *ppSlot = pDictionary->GetSlotAddr(0, slotIndex); + // Backpatch previous versions of the generic dictionary + DWORD dictionarySize = pDictionary->GetDictionarySlotsSize(numGenericArgs); + while (dictionarySize > sizeOfInitialDictionary) + { + pDictionary = *pDictionary->GetBackPointerSlot(numGenericArgs); + if (pDictionary == nullptr) + { + // Initial dictionary allocated with higher number of slots than the initial layout slot count + break; + } + dictionarySize = pDictionary->GetDictionarySlotsSize(numGenericArgs); + if (dictionarySize < minimumSizeOfDictionaryToPatch) + { + // Previous dictionary is too short to patch, end iteration + break; + } + VolatileStoreWithoutBarrier(pDictionary->GetSlotAddr(0, slotIndex), (DictionaryEntry)result); + } } #endif // !CROSSGEN_COMPILE } diff --git a/src/coreclr/src/vm/genericdict.h b/src/coreclr/src/vm/genericdict.h index 8637144466d6..43df31078a2b 100644 --- a/src/coreclr/src/vm/genericdict.h +++ b/src/coreclr/src/vm/genericdict.h @@ -146,9 +146,11 @@ class DictionaryLayout // Create an initial dictionary layout containing numSlots slots static DictionaryLayout* Allocate(WORD numSlots, LoaderAllocator *pAllocator, AllocMemTracker *pamTracker); - // Bytes used for this dictionary, which might be stored inline in - // another structure (e.g. MethodTable) - static DWORD GetDictionarySizeFromLayout(DWORD numGenericArgs, PTR_DictionaryLayout pDictLayout); + // Total number of bytes used for this dictionary, which might be stored inline in + // another structure (e.g. MethodTable). This may include the final back-pointer + // to previous dictionaries after dictionary expansion; pSlotSize is used to return + // the size to be stored in the "size slot" of the dictionary. + static DWORD GetDictionarySizeFromLayout(DWORD numGenericArgs, PTR_DictionaryLayout pDictLayout, DWORD *pSlotSize); static BOOL FindToken(MethodTable* pMT, LoaderAllocator* pAllocator, @@ -171,7 +173,7 @@ class DictionaryLayout DWORD GetMaxSlots(); DWORD GetNumInitialSlots(); DWORD GetNumUsedSlots(); - + PTR_DictionaryEntryLayout GetEntryLayout(DWORD i) { LIMITED_METHOD_CONTRACT; @@ -300,6 +302,12 @@ class Dictionary LIMITED_METHOD_CONTRACT; return VolatileLoadWithoutBarrier((DWORD*)GetSlotAddr(numGenericArgs, 0)); } + + inline Dictionary **GetBackPointerSlot(DWORD numGenericArgs) + { + LIMITED_METHOD_CONTRACT; + return (Dictionary **)((uint8_t *)m_pEntries + GetDictionarySlotsSize(numGenericArgs)); + } #endif // #ifndef DACCESS_COMPILE public: diff --git a/src/coreclr/src/vm/generics.cpp b/src/coreclr/src/vm/generics.cpp index 4e95b52f009e..b616b84099c3 100644 --- a/src/coreclr/src/vm/generics.cpp +++ b/src/coreclr/src/vm/generics.cpp @@ -266,14 +266,15 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( // creating this type. In other words: this type will have a smaller dictionary that its layout. This is not a // problem however because whenever we need to load a value from the dictionary of this type beyond its size, we // will expand the dictionary at that point. - DWORD cbInstAndDict = pOldMT->GetInstAndDictSize(); + DWORD cbInstAndDictSlotSize; + DWORD cbInstAndDictAllocSize = pOldMT->GetInstAndDictSize(&cbInstAndDictSlotSize); // Allocate from the high frequence heap of the correct domain S_SIZE_T allocSize = safe_cbMT; allocSize += cbOptional; allocSize += cbIMap; allocSize += cbPerInst; - allocSize += cbInstAndDict; + allocSize += cbInstAndDictAllocSize; if (allocSize.IsOverflow()) { @@ -474,7 +475,7 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( _ASSERTE(pLayout->GetMaxSlots() > 0); PTR_Dictionary pDictionarySlots = pMT->GetPerInstInfo()[pOldMT->GetNumDicts() - 1].GetValue(); DWORD* pSizeSlot = (DWORD*)(pDictionarySlots + ntypars); - *pSizeSlot = cbInstAndDict; + *pSizeSlot = cbInstAndDictSlotSize; } // Copy interface map across diff --git a/src/coreclr/src/vm/genmeth.cpp b/src/coreclr/src/vm/genmeth.cpp index 80ffce4f34e9..3b67c67e4946 100644 --- a/src/coreclr/src/vm/genmeth.cpp +++ b/src/coreclr/src/vm/genmeth.cpp @@ -386,15 +386,17 @@ InstantiatedMethodDesc::NewInstantiatedMethodDesc(MethodTable *pExactMT, { SString name; TypeString::AppendMethodDebug(name, pGenericMDescInRepMT); - LOG((LF_JIT, LL_INFO1000, "GENERICS: Created new dictionary layout for dictionary of size %d for %S\n", - DictionaryLayout::GetDictionarySizeFromLayout(pGenericMDescInRepMT->GetNumGenericMethodArgs(), pDL), name.GetUnicode())); + DWORD dictionarySlotSize; + DWORD dictionaryAllocSize = DictionaryLayout::GetDictionarySizeFromLayout(pGenericMDescInRepMT->GetNumGenericMethodArgs(), pDL, &dictionarySlotSize); + LOG((LF_JIT, LL_INFO1000, "GENERICS: Created new dictionary layout for dictionary of slot size %d / alloc size %d for %S\n", + dictionarySlotSize, dictionaryAllocSize, name.GetUnicode())); } #endif // _DEBUG } // Allocate space for the instantiation and dictionary - infoSize = DictionaryLayout::GetDictionarySizeFromLayout(methodInst.GetNumArgs(), pDL); - pInstOrPerInstInfo = (TypeHandle*)(void*)amt.Track(pAllocator->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(infoSize))); + DWORD allocSize = DictionaryLayout::GetDictionarySizeFromLayout(methodInst.GetNumArgs(), pDL, &infoSize); + pInstOrPerInstInfo = (TypeHandle*)(void*)amt.Track(pAllocator->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(allocSize))); for (DWORD i = 0; i < methodInst.GetNumArgs(); i++) pInstOrPerInstInfo[i] = methodInst[i]; diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index 3fa602804b54..ed6f44e7426c 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -2664,11 +2664,12 @@ void MethodDesc::Save(DataImage *image) if (GetMethodDictionary()) { - DWORD cBytes = DictionaryLayout::GetDictionarySizeFromLayout(GetNumGenericMethodArgs(), GetDictionaryLayout()); + DWORD cSlotBytes; + DWORD cAllocBytes = DictionaryLayout::GetDictionarySizeFromLayout(GetNumGenericMethodArgs(), GetDictionaryLayout(), &cSlotBytes); void* pBytes = GetMethodDictionary()->AsPtr(); - LOG((LF_ZAP, LL_INFO10000, " MethodDesc::Save dictionary size %d\n", cBytes)); - image->StoreStructure(pBytes, cBytes, + LOG((LF_ZAP, LL_INFO10000, " MethodDesc::Save dictionary size %d\n", cSlotBytes)); + image->StoreStructure(pBytes, cSlotBytes, DataImage::ITEM_DICTIONARY_WRITEABLE); } diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 485b82674311..437162fa98f7 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -4109,14 +4109,15 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags) fIsWriteable = FALSE; } - + DWORD slotSize; + DWORD allocSize = GetInstAndDictSize(&slotSize); if (!fIsWriteable) { - image->StoreInternedStructure(pDictionary, GetInstAndDictSize(), DataImage::ITEM_DICTIONARY); + image->StoreInternedStructure(pDictionary, slotSize, DataImage::ITEM_DICTIONARY); } else { - image->StoreStructure(pDictionary, GetInstAndDictSize(), DataImage::ITEM_DICTIONARY_WRITEABLE); + image->StoreStructure(pDictionary, slotSize, DataImage::ITEM_DICTIONARY_WRITEABLE); } } @@ -8888,7 +8889,9 @@ MethodTable::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) if (GetDictionary() != NULL) { - DacEnumMemoryRegion(dac_cast(GetDictionary()), GetInstAndDictSize()); + DWORD slotSize; + DWORD allocSize = GetInstAndDictSize(&slotSize); + DacEnumMemoryRegion(dac_cast(GetDictionary()), slotSize); } VtableIndirectionSlotIterator it = IterateVtableIndirectionSlots(); diff --git a/src/coreclr/src/vm/methodtable.h b/src/coreclr/src/vm/methodtable.h index 16f8d7dbc593..6018c24f0d01 100644 --- a/src/coreclr/src/vm/methodtable.h +++ b/src/coreclr/src/vm/methodtable.h @@ -3929,8 +3929,10 @@ public : inline DWORD GetInterfaceMapSize(); // The instantiation/dictionary comes at the end of the MethodTable after - // the interface map. - inline DWORD GetInstAndDictSize(); + // the interface map. This is the total number of bytes used by the dictionary. + // The pSlotSize argument is used to return the size occupied by slots (not including + // the optional back pointer used when expanding dictionaries). + inline DWORD GetInstAndDictSize(DWORD *pSlotSize); private: // Helper template to compute the offsets at compile time diff --git a/src/coreclr/src/vm/methodtable.inl b/src/coreclr/src/vm/methodtable.inl index a20e1b4ca495..07b2c3c361ed 100644 --- a/src/coreclr/src/vm/methodtable.inl +++ b/src/coreclr/src/vm/methodtable.inl @@ -1092,14 +1092,14 @@ inline DWORD MethodTable::GetInterfaceMapSize() //========================================================================================== // These are the generic dictionaries themselves and are come after // the interface map. In principle they need not be inline in the method table. -inline DWORD MethodTable::GetInstAndDictSize() +inline DWORD MethodTable::GetInstAndDictSize(DWORD *pSlotSize) { LIMITED_METHOD_DAC_CONTRACT; if (!HasInstantiation()) - return 0; + return *pSlotSize = 0; else - return DictionaryLayout::GetDictionarySizeFromLayout(GetNumGenericArgs(), GetClass()->GetDictionaryLayout()); + return DictionaryLayout::GetDictionarySizeFromLayout(GetNumGenericArgs(), GetClass()->GetDictionaryLayout(), pSlotSize); } //========================================================================================== diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index fc14d39be565..666bb3bf2526 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -10114,10 +10114,12 @@ MethodTableBuilder::SetupMethodTable2( EEClass *pClass = GetHalfBakedClass(); - DWORD cbDict = bmtGenerics->HasInstantiation() - ? DictionaryLayout::GetDictionarySizeFromLayout( - bmtGenerics->GetNumGenericArgs(), pClass->GetDictionaryLayout()) - : 0; + DWORD cbDictSlotSize = 0; + DWORD cbDictAllocSize = 0; + if (bmtGenerics->HasInstantiation()) + { + cbDictAllocSize = DictionaryLayout::GetDictionarySizeFromLayout(bmtGenerics->GetNumGenericArgs(), pClass->GetDictionaryLayout(), &cbDictSlotSize); + } #ifdef FEATURE_COLLECTIBLE_TYPES BOOL fCollectible = pLoaderModule->IsCollectible(); @@ -10150,7 +10152,7 @@ MethodTableBuilder::SetupMethodTable2( dwGCSize, bmtInterface->dwInterfaceMapSize, bmtGenerics->numDicts, - cbDict, + cbDictAllocSize, GetParentMethodTable(), GetClassLoader(), bmtAllocator, @@ -10370,7 +10372,7 @@ MethodTableBuilder::SetupMethodTable2( PTR_Dictionary pDictionarySlots = pMT->GetPerInstInfo()[bmtGenerics->numDicts - 1].GetValue(); DWORD* pSizeSlot = (DWORD*)(pDictionarySlots + bmtGenerics->GetNumGenericArgs()); - *pSizeSlot = cbDict; + *pSizeSlot = cbDictSlotSize; } } From 82ba676b709644c45defc2d92dbbbf7a02b2b805 Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Fri, 7 Aug 2020 16:50:22 -0700 Subject: [PATCH 342/755] Update using-dotnet-cli.md (#40504) * Update using-dotnet-cli.md Update the First Run section for .NET 5. * more renames * typo Co-authored-by: danmosemsft --- docs/workflow/testing/using-your-build.md | 6 +- docs/workflow/using-dotnet-cli.md | 87 ++++++++++++----------- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/docs/workflow/testing/using-your-build.md b/docs/workflow/testing/using-your-build.md index 31a7f6bc8d3f..33e5ef19e174 100644 --- a/docs/workflow/testing/using-your-build.md +++ b/docs/workflow/testing/using-your-build.md @@ -1,7 +1,7 @@ # Using your .NET Runtime Build -We assume that you have successfully built CoreCLR repository and thus have files of the form +We assume that you have successfully built the repository and thus have files of the form ``` ~/runtime/artifacts/bin/coreclr/../ ``` @@ -11,7 +11,7 @@ a 'host' program that will load the Runtime as well as all the other .NET librar code that your application needs. The easiest way to get all this other stuff is to simply use the standard 'dotnet' host that installs with .NET SDK. -The released version of 'dotnet' tool may not be compatible with the live CoreCLR repository. The following steps +The released version of 'dotnet' tool may not be compatible with the live repository. The following steps assume use of a dogfood build of the .NET SDK. ## Acquire the latest nightly .NET SDK @@ -157,7 +157,7 @@ Assert failure(PID 13452 [0x0000348c], Thread: 10784 [0x2a20]): Consistency chec ## Using .NET SDK to run your .NET Application If you don't like the idea of copying files manually you can follow [these instructions](../using-dotnet-cli.md) to use dotnet cli to do this for you. -However the steps described here are the simplest and most commonly used by CoreCLR developers for ad-hoc testing. +However the steps described here are the simplest and most commonly used by runtime developers for ad-hoc testing. ## Using CoreRun to run your .NET Application diff --git a/docs/workflow/using-dotnet-cli.md b/docs/workflow/using-dotnet-cli.md index 7c9efa28c829..68cadd5bf4f8 100644 --- a/docs/workflow/using-dotnet-cli.md +++ b/docs/workflow/using-dotnet-cli.md @@ -1,23 +1,23 @@ # Using your .NET Runtime build with .NET SDK -This walkthrough explains how to run against your local CoreCLR build using .NET SDK only. +This walkthrough explains how to run your own app against your local build using only the .NET SDK. For other walkthroughs see: -- [Using Your Build - Update CoreCLR from raw binary output](./testing/using-your-build.md) +- [Using Your Build - Update from raw build output](./testing/using-your-build.md) - [Using CoreRun To Run .NET Application](./testing/using-corerun.md) - [Dogfooding .NET SDK](https://github.com/dotnet/runtime/blob/master/docs/project/dogfooding.md). ## Prerequisites -1. Successfully built CoreCLR repository and thus have files of the form shown below. From now on we call this folder NuGet package folder. +1. Successfully built this repository and thus have files of the form shown below. From now on we call this folder NuGet package folder. ``` - artifacts\bin\coreclr\..\.nuget\pkg\runtime.-.Microsoft.NETCore.Runtime.CoreCLR..nupkg + artifacts\packages\\Shipping\ ``` -2. Acquired the latest nightly .NET SDK from [here](https://github.com/dotnet/cli/blob/master/README.md#installers-and-binaries) and added it's root folder to your [path](requirements/windows-requirements.md#adding-to-the-default-path-variable) +2. Acquired the latest nightly .NET SDK from [here](https://github.com/dotnet/installer) and added its root folder to your [path](requirements/windows-requirements.md#adding-to-the-default-path-variable) ## First Run @@ -29,13 +29,11 @@ From now on all instructions relate to this folder as "app folder". ### 2. Create NuGet.Config file -The build script creates NuGet packages and puts them to `artifacts\bin\coreclr\..\.nuget\pkg\`. .NET SDK has no idea about its existence and we need to tell it where to search for the packages. +The build script creates NuGet packages and puts them to `artifacts\packages\\Shipping\`. .NET SDK has no idea about its existence and we need to tell it where to search for the packages. Please run `dotnet new nugetconfig` in the app folder and update the created `NuGet.Config` file: -* **set path to local CoreCLR NuGet folder!!** -* add address to dotnet core tools NuGet feed - +* ** adjust path below to point to your in-repo NuGet folder** ```xml @@ -44,11 +42,9 @@ Please run `dotnet new nugetconfig` in the app folder and update the created `Nu - - + - ``` ### 3. Create and update the Project file @@ -60,39 +56,34 @@ Please run `dotnet new console` in the app folder and update the created `.cspro Exe - netcoreapp3.0 + net5.0 win-x64 - 3.0.0-preview1-26210-0 + 5.0.0-dev - - - - - ``` **You have to set the correct values for `RuntimeIdentifier` (RI), `RuntimeFrameworkVersion` and versions of both packages.** You can generally figure that out by looking at the packages you found in your output. -In our example you will see there is a package with the name `runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR.3.0.0-preview1-26210-0.nupkg` +In our example you will see there is a package with the name `Microsoft.NETCore.App.Runtime.win-x64.5.0.0-dev.nupkg` ``` -runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR.3.0.0-preview1-26210-0.nupkg - ^--RI---^ ^--------version-------^ +Microsoft.NETCore.App.Runtime.win-x64.5.0.0-dev.nupkg + ^-RI--^ ^version^ ``` ### 4. Change Program.cs -To make sure that you run against your local coreclr build please change your `Main` method in `Program.cs` file to: +To make sure that you run against your local build of this repo please change your `Main` method in `Program.cs` file to: ```cs static void Main(string[] args) { - var coreAssemblyInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location); - Console.WriteLine($"Hello World from Core {coreAssemblyInfo.ProductVersion}"); - Console.WriteLine($"The location is {typeof(object).Assembly.Location}"); + var coreAssemblyInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location); + Console.WriteLine($"Hello World from .NET {coreAssemblyInfo.ProductVersion}"); + Console.WriteLine($"The location is {typeof(object).Assembly.Location}"); } ``` @@ -108,40 +99,56 @@ dotnet publish Make sure that restoring done by `dotnet publish` installed the explicit version of the Runtime that you have specified: ``` -PS C:\coreclr\helloWorld> dotnet publish - Restoring packages for C:\coreclr\helloWorld\helloWorld.csproj... - Installing runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview1-26210- +c:\runtime\helloworld>dotnet publish +Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET +Copyright (C) Microsoft Corporation. All rights reserved. + + Determining projects to restore... + Restored c:\runtime\helloworld\helloworld.csproj (in 114 ms). + You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview + helloworld -> c:\runtime\helloworld\bin\Debug\net5.0\win-x64\helloworld.dll + helloworld -> c:\runtime\helloworld\bin\Debug\net5.0\win-x64\publish\ ``` If you see something like the message below it means that it has failed to restore your local runtime packages. In such case double check your `NuGet.config` file and paths used in it. ``` -C:\coreclr\helloWorld\helloWorld.csproj : warning NU1603: helloWorld depends on runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR (>= 3.0.0-preview1-26210-0) but runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview1-26210-0 was not found. An approximate best match of runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview2-25501-02 was resolved. +c:\runtime\helloworld>dotnet publish +Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET +Copyright (C) Microsoft Corporation. All rights reserved. + + Determining projects to restore... +c:\runtime\helloworld\helloworld.csproj : error NU1102: Unable to find package Microsoft.NETCore.App.Runtime.win-x64 with version (= 5.0.0-does-not-exist) +c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 25 version(s) in nuget [ Nearest version: 5.0.0-preview.1.20120.5 ] +c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 1 version(s) in local runtime [ Nearest version: 5.0.0-dev ] +c:\runtime\helloworld\helloworld.csproj : error NU1102: Unable to find package Microsoft.NETCore.App.Host.win-x64 with version (= 5.0.0-does-not-exist) +c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 27 version(s) in nuget [ Nearest version: 5.0.0-preview.1.20120.5 ] +c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 1 version(s) in local runtime [ Nearest version: 5.0.0-dev ] + Failed to restore c:\runtime\helloworld\helloworld.csproj (in 519 ms). ``` ### 6. Run the app -After you publish you will find all the binaries needed to run your application under `bin\Debug\netcoreapp3.0\win-x64\publish\`. +After you publish you will find all the binaries needed to run your application under `bin\Debug\net5.0\win-x64\publish\`. To run the application simply run the EXE that is in this publish directory (it is the name of the app, or specified in the project file). ``` -.\bin\Debug\netcoreapp3.0\win-x64\publish\HelloWorld.exe +.\bin\Debug\net5.0\win-x64\publish\HelloWorld.exe ``` -Running the app should tell you the version and which user and machine build the assembly as well as the commit hash of the code -at the time of building: +Running the app should tell you the version and where the location of System.Private.CoreLib in the publish directory: ``` -Hello World from Core 4.6.26210.0 @BuiltBy: adsitnik-MININT-O513E3V @SrcCode: https://github.com/dotnet/runtime/tree/3d6da797d1f7dc47d5934189787a4e8006ab3a04 -The location is C:\coreclr\helloWorld\bin\Debug\netcoreapp3.0\win-x64\publish\System.Private.CoreLib.dll +Hello World from .NET 5.0.0-dev +The location is c:\runtime\helloworld\bin\Debug\net5.0\win-x64\publish\System.Private.CoreLib.dll ``` -**Congratulations! You have just run your first app against local CoreCLR build!** +**Congratulations! You have just run your first app against your local build of this repo** -## Update CoreCLR using runtime nuget package +## Update using runtime nuget package -Updating CoreCLR from raw binary output is easier for quick one-off testing but using the nuget package is better -for referencing your CoreCLR build in your actual application because of it does not require manual copying of files +Updating the runtime from raw binary output is easier for quick one-off testing but using the nuget package is better +for referencing your build in your actual application because of it does not require manual copying of files around each time the application is built and plugs into the rest of the tool chain. This set of instructions will cover the further steps needed to consume the runtime nuget package. From 85d2bbc2ddb28164ea15e0e152bc44afdbc04ab3 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 7 Aug 2020 17:28:41 -0700 Subject: [PATCH 343/755] When returning a SIMD value use v0 register as the candidate for source operand of GT_RETURN in case when it is a single-register local variable --- src/coreclr/src/jit/lsrabuild.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/lsrabuild.cpp b/src/coreclr/src/jit/lsrabuild.cpp index d902b3a1ab4e..e2f8775f2bae 100644 --- a/src/coreclr/src/jit/lsrabuild.cpp +++ b/src/coreclr/src/jit/lsrabuild.cpp @@ -3443,10 +3443,15 @@ int LinearScan::BuildReturn(GenTree* tree) if (varTypeIsSIMD(tree) && !op1->IsMultiRegLclVar()) { useCandidates = allSIMDRegs(); + if (op1->OperGet() == GT_LCL_VAR) + { + assert(op1->TypeGet() != TYP_SIMD32); + useCandidates = RBM_DOUBLERET; + } BuildUse(op1, useCandidates); return 1; } -#endif // !TARGET_ARM64 +#endif // TARGET_ARM64 if (varTypeIsStruct(tree)) { From 1db5808a3033e4a7125a7311c02cbaaf332d1179 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 7 Aug 2020 17:51:23 -0700 Subject: [PATCH 344/755] [Arm64] Treat methods of non-generic Vector64 and Vector128 classes as intrinsics (#40441) --- src/coreclr/src/zap/zapinfo.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index e997efa396b1..ff12d9631621 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -2171,8 +2171,11 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF fTreatAsRegularMethodCall = fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic; #if defined(TARGET_ARM64) - // On Arm64 AdvSimd ISA is required by CoreCLR, so we can expand Vector64 and Vector128 methods. - fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic && (strcmp(className, "Vector64`1") != 0) && (strcmp(className, "Vector128`1") != 0); + // On Arm64 AdvSimd ISA is required by CoreCLR, so we can expand Vector64 and Vector128 generic methods (e.g. Vector64.get_Zero) + // as well as Vector64 and Vector128 methods (e.g. Vector128.CreateScalarUnsafe). + fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic + && (strncmp(className, "Vector64", _countof("Vector64") - 1) != 0) + && (strncmp(className, "Vector128", _countof("Vector128") - 1) != 0); #else fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic; #endif From 7ab3163c9e173d4cd78c197d330d73cc6f5f7468 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 7 Aug 2020 20:53:35 -0500 Subject: [PATCH 345/755] Disable EOL Target Frameworks check in newer SDKs (#40552) --- Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Directory.Build.props b/Directory.Build.props index c4bcb9a62558..ff2883becc68 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -101,6 +101,9 @@ Properties $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) + + + false From 51ad8e451c354c8e0d6cd271b49e519de05ec9cd Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 7 Aug 2020 21:24:05 -0700 Subject: [PATCH 346/755] Reenable the test. (#40515) --- src/coreclr/tests/issues.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index edfe25e42021..246f85c958f8 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -672,9 +672,6 @@ https://github.com/dotnet/runtime/issues/10001 - - https://github.com/dotnet/runtime/issues/38799 - From 110c7dcb1d19694907641e5040acddef39e4fedd Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Sat, 8 Aug 2020 08:08:42 -0700 Subject: [PATCH 347/755] Superpmi: adjust relocations (#40563) Fix #39908 --- .../ToolBox/superpmi/superpmi-shared/compileresult.cpp | 10 ++++++++++ src/coreclr/src/jit/emit.cpp | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/compileresult.cpp index e27491bbd5ee..75d8ab5d079b 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -796,6 +796,16 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; if ((section_begin <= address) && (address < section_end)) // A reloc for our section? { +#if defined(TARGET_AMD64) + // During an actual compile, recordRelocation() will be called before the compile + // is actually finished, and it will write the relative offset into the fixupLocation. + // Then, emitEndCodeGen() will patch forward jumps by subtracting any adjustment due + // to overestimation of instruction sizes. Because we're applying the relocs after the + // compile has finished, we need to reverse that: i.e. add in the (negative) adjustment + // that's now in the fixupLocation. + INT32 adjustment = *(INT32*)address; + delta += adjustment; +#endif LogDebug(" fixupLoc-%016llX (@%p) : %08X => %08X", fixupLocation, address, *(DWORD*)address, delta); *(DWORD*)address = (DWORD)delta; diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index ab1c281ea5eb..7a957b17f91e 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -3867,7 +3867,7 @@ void emitter::emitJumpDistBind() { if (tgtIG) { - printf("to G_M%03u_IG%02u\n", emitComp->compMethodID, tgtIG->igNum); + printf(" to G_M%03u_IG%02u\n", emitComp->compMethodID, tgtIG->igNum); } else { From e1494e8e4c631f51754b613048e9e680ec0ce16b Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Sat, 8 Aug 2020 09:50:41 -0700 Subject: [PATCH 348/755] Minimal fix for Issue 620 (#40535) * Minimal fix for Issue 620 Added test case: Runtime_620.cs Added lvForceLoadNormalize * Changed conditional to "else if" --- src/coreclr/src/jit/compiler.h | 6 +- src/coreclr/src/jit/morph.cpp | 27 +- .../JitBlue/Runtime_620/Runtime_620.cs | 405 ++++++++++++++++++ .../JitBlue/Runtime_620/Runtime_620.csproj | 11 + 4 files changed, 444 insertions(+), 5 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.csproj diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 9924c5ffe1db..22ceceea5ae0 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -476,6 +476,8 @@ class LclVarDsc unsigned char lvContainsHoles : 1; // True when we have a promoted struct that contains holes unsigned char lvCustomLayout : 1; // True when this struct has "CustomLayout" + unsigned char lvForceLoadNormalize : 1; // True when this local had a cast on the LHS of an assignment + unsigned char lvIsMultiRegArg : 1; // true if this is a multireg LclVar struct used in an argument context unsigned char lvIsMultiRegRet : 1; // true if this is a multireg LclVar struct assigned from a multireg call @@ -884,14 +886,14 @@ class LclVarDsc { return varTypeIsSmall(TypeGet()) && // lvIsStructField is treated the same as the aliased local, see fgDoNormalizeOnStore. - (lvIsParam || lvAddrExposed || lvIsStructField); + (lvIsParam || lvAddrExposed || lvIsStructField || lvForceLoadNormalize); } bool lvNormalizeOnStore() const { return varTypeIsSmall(TypeGet()) && // lvIsStructField is treated the same as the aliased local, see fgDoNormalizeOnStore. - !(lvIsParam || lvAddrExposed || lvIsStructField); + !(lvIsParam || lvAddrExposed || lvIsStructField || lvForceLoadNormalize); } void incRefCnts(BasicBlock::weight_t weight, diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 81342722a380..6ec078e450fc 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -13683,6 +13683,11 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) unsigned lclNum = temp->AsLclVarCommon()->GetLclNum(); LclVarDsc* varDsc = &lvaTable[lclNum]; + // Note that fgMorph uses GTF_DONT_CSE to mark the left side of an assignment + // Thus stores have this flag and load do not have this flag + // + bool isLoad = (tree->gtFlags & GTF_DONT_CSE) == 0; + // We will try to optimize when we have a promoted struct promoted with a zero lvFldOffset if (varDsc->lvPromoted && (varDsc->lvFldOffset == 0)) { @@ -13709,15 +13714,31 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) } // If the type of the IND (typ) is a "small int", and the type of the local has the // same width, then we can reduce to just the local variable -- it will be - // correctly normalized, and signed/unsigned differences won't matter. + // correctly normalized. // // The below transformation cannot be applied if the local var needs to be normalized on load. else if (varTypeIsSmall(typ) && (genTypeSize(lvaTable[lclNum].lvType) == genTypeSize(typ)) && !lvaTable[lclNum].lvNormalizeOnLoad()) { - tree->gtType = typ = temp->TypeGet(); - foldAndReturnTemp = true; + // For any stores of small types, we will force loads to be normalized + // this is necessary as we need to zero/sign extend any load + // after this kind of store. + // + if (!isLoad) + { + varDsc->lvForceLoadNormalize = true; + } + // otherwise we have a load operation + // + // And for loads signed/unsigned differences do matter. + // + else if (varTypeIsUnsigned(lvaTable[lclNum].lvType) == varTypeIsUnsigned(typ)) + { + tree->gtType = typ = temp->TypeGet(); + foldAndReturnTemp = true; + } } + // For matching types we can fold else if (!varTypeIsStruct(typ) && (lvaTable[lclNum].lvType == typ) && !lvaTable[lclNum].lvNormalizeOnLoad()) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.cs b/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.cs new file mode 100644 index 000000000000..4178337d4d03 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.cs @@ -0,0 +1,405 @@ +// 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.Runtime.CompilerServices; + +namespace NormalizeTest +{ + class Program + { + static int testResult = 100; + static bool s_print = false; + + //////////////////////////////////////////////////////////// + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ByteTest1(sbyte a, int b) + { + sbyte c = (sbyte)(a * 2); + byte t = *((byte*)&c); + if (s_print) + { + Console.WriteLine(t); + } + int d = ((int) t) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe sbyte ByteTest2(sbyte a, int b) + { + sbyte c = (sbyte)(b * 2); + *((byte*)&c) = (byte)(a * b); + return c; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ByteTest3(byte a, int b) + { + byte c = (byte)(a * 2); + int d = *((sbyte*)&c) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe byte ByteTest4(byte a, int b) + { + byte c = (byte)(b * 2); + *((sbyte*)&c) = (sbyte)(a * b); + return c; + } + + struct S1 { + public long l64; + public sbyte s8; + public byte u8; + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ByteTestField1(sbyte a, int b) + { + S1 s; + s.l64 = 0; + s.s8 = (sbyte)(a * 2); + int d = *((byte*)&s.s8) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe sbyte ByteTestField2(sbyte a, int b) + { + S1 s; + s.s8 = (sbyte)(b * 2); + *((byte*)&s.s8) = (byte)(a * b); + return s.s8; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ByteTestField3(byte a, int b) + { + S1 s; + s.u8 = (byte)(a * 2); + int d = *((sbyte*)&s.u8) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe byte ByteTestField4(byte a, int b) + { + S1 s; + s.u8 = (byte)(b * 2); + *((sbyte*)&s.u8) = (sbyte)(a * b); + return s.u8; + } + + //////////////////////////////////////////////////////////// + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ShortTest1(short a, int b) + { + short c = (short)(a * 2); + ushort t = *((ushort*)&c); + if (s_print) + { + Console.WriteLine(t); + } + int d = ((int) t) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe short ShortTest2(short a, int b) + { + short c = (short)(b * 2); + *((ushort*)&c) = (ushort)(a * b); + return c; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ShortTest3(ushort a, int b) + { + ushort c = (ushort)(a * 2); + int d = *((short*)&c) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe ushort ShortTest4(ushort a, int b) + { + ushort c = (ushort)(b * 2); + *((short*)&c) = (short)(a * b); + return c; + } + + struct S2 { + public long l64; + public short s16; + public ushort u16; + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ShortTestField1(short a, int b) + { + S2 s; + s.l64 = 0; + s.s16 = (short)(a * 2); + int d = *((ushort*)&s.s16) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe short ShortTestField2(short a, int b) + { + S2 s; + s.s16 = (short)(b * 2); + *((ushort*)&s.s16) = (ushort)(a * b); + return s.s16; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int ShortTestField3(ushort a, int b) + { + S2 s; + s.u16 = (ushort)(a * 2); + int d = *((short*)&s.u16) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe ushort ShortTestField4(ushort a, int b) + { + S2 s; + s.u16 = (ushort)(b * 2); + *((short*)&s.u16) = (short)(a * b); + return s.u16; + } + + //////////////////////////////////////////////////////////// + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe long IntTest1(int a, long b) + { + int c = (int)(a * 2); + uint t = *((uint*)&c); + if (s_print) + { + Console.WriteLine(t); + } + long d = ((long) t) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int IntTest2(int a, long b) + { + int c = (int)(b * 2); + *((uint*)&c) = (uint)(a * b); + return c; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe long IntTest3(uint a, long b) + { + uint c = (uint)(a * 2); + long d = *((int*)&c) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe uint IntTest4(uint a, long b) + { + uint c = (uint)(b * 2); + *((int*)&c) = (int)(a * b); + return c; + } + + struct S3 { + public long l64; + public int s32; + public uint u32; + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe long IntTestField1(int a, long b) + { + S3 s; + s.l64 = 0; + s.s32 = (int)(a * 2); + long d = *((uint*)&s.s32) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int IntTestField2(int a, long b) + { + S3 s; + s.s32 = (int)(b * 2); + *((uint*)&s.s32) = (uint)(a * b); + return s.s32; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe long IntTestField3(uint a, long b) + { + S3 s; + s.u32 = (uint)(a * 2); + long d = *((int*)&s.u32) / b; + return d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe uint IntTestField4(uint a, long b) + { + S3 s; + s.u32 = (uint)(b * 2); + *((int*)&s.u32) = (int)(a * b); + return s.u32; + } + + //////////////////////////////////////////////////////////// + + static void CheckInt(String id, int result, int expected) + { + if (result != expected) + { + Console.WriteLine("CheckInt - FAILED: {0} -- result {1}, expected {2}", id, result, expected); + testResult = -1; + } + } + + static void CheckLong(String id, long result, long expected) + { + if (result != expected) + { + Console.WriteLine("CheckLong - FAILED: {0} -- result {1}, expected {2}", id, result, expected); + testResult = -1; + } + } + + static int Main() + { + { + int result1a = ByteTest1(-1,1); + CheckInt("ByteTest1a", result1a, 0xFE); + + int result1b = ByteTest1(-1,-1); + CheckInt("ByteTest1b", result1b, -0xFE); + + sbyte result2a = ByteTest2(-1,1); + CheckInt("ByteTest2a", (int) result2a, -1); + + sbyte result2b = ByteTest2(-1,-1); + CheckInt("ByteTest2b", (int) result2b, 1); + + int result3 = ByteTest3(0x7F,-1); + CheckInt("ByteTest3", result3, 2); + + byte result4 = ByteTest4(0x7F,-1); + CheckInt("ByteTest4", (int) result4, 0x81); + + int resultF1a = ByteTestField1(-1,1); + CheckInt("ByteTestField1a", resultF1a, 0xFE); + + int resultF1b = ByteTestField1(-1,-1); + CheckInt("ByteTestField1b", resultF1b, -0xFE); + + sbyte resultF2a = ByteTestField2(-1,1); + CheckInt("ByteTestField2a", (int) resultF2a, -1); + + sbyte resultF2b = ByteTestField2(-1,-1); + CheckInt("ByteTestField2b", (int) resultF2b, 1); + + int resultF3 = ByteTestField3(0x7F,-1); + CheckInt("ByteTestField3", resultF3, 2); + + byte resultF4 = ByteTestField4(0x7F,-1); + CheckInt("ByteTestField4", (int) resultF4, 0x81); + } + //////////////////////////////////////////////////////////// + { + int result1a = ShortTest1(-1,1); + CheckInt("ShortTest1a", result1a, 0xFFFE); + + int result1b = ShortTest1(-1,-1); + CheckInt("ShortTest1b", result1b, -0xFFFE); + + short result2a = ShortTest2(-1,1); + CheckInt("ShortTest2a", (int) result2a, -1); + + short result2b = ShortTest2(-1,-1); + CheckInt("ShortTest2b", (int) result2b, 1); + + int result3 = ShortTest3(0x7FFF,-1); + CheckInt("ShortTest3", result3, 2); + + ushort result4 = ShortTest4(0x7FFF,-1); + CheckInt("ShortTest4", (int) result4, 0x8001); + + int resultF1a = ShortTestField1(-1,1); + CheckInt("ShortTestField1a", resultF1a, 0xFFFE); + + int resultF1b = ShortTestField1(-1,-1); + CheckInt("ShortTestField1b", resultF1b, -0xFFFE); + + short resultF2a = ShortTestField2(-1,1); + CheckInt("ShortTestField2a", (int) resultF2a, -1); + + short resultF2b = ShortTestField2(-1,-1); + CheckInt("ShortTestField2b", (int) resultF2b, 1); + + int resultF3 = ShortTestField3(0x7FFF,-1); + CheckInt("ShortTestField3", resultF3, 2); + + ushort resultF4 = ShortTestField4(0x7FFF,-1); + CheckInt("ShortTestField4", (int) resultF4, 0x8001); + } + //////////////////////////////////////////////////////////// + { + long result1a = IntTest1(-1,1); + CheckLong("IntTest1a", result1a, 0xFFFFFFFE); + + long result1b = IntTest1(-1,-1); + CheckLong("IntTest1b", result1b, -0xFFFFFFFE); + + int result2a = IntTest2(-1,1); + CheckLong("IntTest2a", (long) result2a, -1); + + int result2b = IntTest2(-1,-1); + CheckLong("IntTest2b", (long) result2b, 1); + + long result3 = IntTest3(0x7FFFFFFF,-1); + CheckLong("IntTest3", result3, 2); + + uint result4 = IntTest4(0x7FFFFFFF,-1); + CheckLong("IntTest4", (long) result4, 0x80000001); + + long resultF1a = IntTestField1(-1,1); + CheckLong("IntTestField1a", resultF1a, 0xFFFFFFFE); + + long resultF1b = IntTestField1(-1,-1); + CheckLong("IntTestField1b", resultF1b, -0xFFFFFFFE); + + int resultF2a = IntTestField2(-1,1); + CheckLong("IntTestField2a", (long) resultF2a, -1); + + int resultF2b = IntTestField2(-1,-1); + CheckLong("IntTestField2b", (long) resultF2b, 1); + + long resultF3 = IntTestField3(0x7FFFFFFF,-1); + CheckLong("IntTestField3", resultF3, 2); + + uint resultF4 = IntTestField4(0x7FFFFFFF,-1); + CheckLong("IntTestField4", (long) resultF4, 0x80000001); + } + //////////////////////////////////////////////////////////// + + if (testResult == 100) + { + Console.WriteLine("Test Passed"); + } + return testResult; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.csproj new file mode 100644 index 000000000000..e5292cce5876 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_620/Runtime_620.csproj @@ -0,0 +1,11 @@ + + + Exe + None + True + True + + + + + From 00d4741b496336b399f5e5920113e26143b55f38 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sat, 8 Aug 2020 10:36:52 -0700 Subject: [PATCH 349/755] include more details in exception if remote certificate validation fails (#40110) * include more details in exception if remote certificate validation fails * fix unit test linking * feedback from review * update exception message --- .../src/Resources/Strings.resx | 11 +-- .../src/System/Net/Security/SecureChannel.cs | 69 +++++++++++++------ .../Net/Security/SslAuthenticationOptions.cs | 17 ++++- .../Net/Security/SslStream.Implementation.cs | 26 +++++-- .../src/System/Net/Security/SslStream.cs | 44 ++---------- .../ServerAsyncAuthenticateTest.cs | 63 +++++++++++++++++ .../SslStreamNetworkStreamTest.cs | 41 +++++++---- .../Fakes/FakeSslStream.Implementation.cs | 3 +- 8 files changed, 186 insertions(+), 88 deletions(-) diff --git a/src/libraries/System.Net.Security/src/Resources/Strings.resx b/src/libraries/System.Net.Security/src/Resources/Strings.resx index 1270f6bb3be8..e518415c15b2 100644 --- a/src/libraries/System.Net.Security/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Security/src/Resources/Strings.resx @@ -164,9 +164,6 @@ Received an unexpected EOF or 0 bytes from the transport stream. - - The parameter: {0} is not valid. Use the object returned from corresponding Begin async call. - The handshake failed due to an unexpected packet format. @@ -174,7 +171,13 @@ The remote party requested renegotiation when AllowRenegotiation was set to false. - The remote certificate is invalid according to the validation procedure. + The remote certificate is invalid according to the validation procedure: {0} + + + The remote certificate is invalid because of errors in the certificate chain: {0} + + + The remote certificate was rejected by the provided RemoteCertificateValidationCallback. The server mode SSL must use a certificate with the associated private key. diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs index b0af7167142e..4d20cea9c251 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -25,7 +25,8 @@ internal class SecureChannel private SslConnectionInfo? _connectionInfo; private X509Certificate? _selectedClientCertificate; - private bool _isRemoteCertificateAvailable; + private X509Certificate2? _remoteCertificate; + private bool _remoteCertificateExposed; // These are the MAX encrypt buffer output sizes, not the actual sizes. private int _headerSize = 5; //ATTN must be set to at least 5 by default @@ -39,6 +40,7 @@ internal class SecureChannel private static readonly Oid s_serverAuthOid = new Oid("1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.1"); private static readonly Oid s_clientAuthOid = new Oid("1.3.6.1.5.5.7.3.2", "1.3.6.1.5.5.7.3.2"); + private SslStream? _ssl; internal SecureChannel(SslAuthenticationOptions sslAuthenticationOptions, SslStream sslStream) { @@ -54,6 +56,7 @@ internal SecureChannel(SslAuthenticationOptions sslAuthenticationOptions, SslStr _securityContext = null; _refreshCredentialNeeded = true; _sslAuthenticationOptions = sslAuthenticationOptions; + _ssl = sslStream; } // @@ -85,7 +88,16 @@ internal bool IsRemoteCertificateAvailable { get { - return _isRemoteCertificateAvailable; + return _remoteCertificate != null; + } + } + + internal X509Certificate? RemoteCertificate + { + get + { + _remoteCertificateExposed = true; + return _remoteCertificate; } } @@ -164,8 +176,15 @@ internal void SetRefreshCredentialNeeded() internal void Close() { + if (!_remoteCertificateExposed) + { + _remoteCertificate?.Dispose(); + _remoteCertificate = null; + } + _securityContext?.Dispose(); _credentialsHandle?.Dispose(); + _ssl = null; GC.SuppressFinalize(this); } @@ -585,7 +604,6 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint) else { _credentialsHandle = SslStreamPal.AcquireCredentialsHandle(selectedCert!, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.EncryptionPolicy, _sslAuthenticationOptions.IsServer); - thumbPrint = guessedThumbPrint; // Delay until here in case something above threw. _selectedClientCertificate = clientCertificate; } @@ -911,22 +929,21 @@ internal SecurityStatusPal Decrypt(byte[]? payload, ref int offset, ref int coun --*/ //This method validates a remote certificate. - internal bool VerifyRemoteCertificate(RemoteCertValidationCallback? remoteCertValidationCallback, ref ProtocolToken? alertToken) + internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remoteCertValidationCallback, ref ProtocolToken? alertToken, out SslPolicyErrors sslPolicyErrors, out X509ChainStatusFlags chainStatus) { - SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; + sslPolicyErrors = SslPolicyErrors.None; + chainStatus = X509ChainStatusFlags.NoError; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain? chain = null; - X509Certificate2? remoteCertificateEx = null; X509Certificate2Collection? remoteCertificateStore = null; try { - remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore); - _isRemoteCertificateAvailable = remoteCertificateEx != null; + _remoteCertificate = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore); - if (remoteCertificateEx == null) + if (_remoteCertificate == null) { if (NetEventSource.Log.IsEnabled() && RemoteCertRequired) NetEventSource.Error(this, $"Remote certificate required, but no remote certificate received"); sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; @@ -948,7 +965,7 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback? remoteCertVa sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties( _securityContext!, chain, - remoteCertificateEx, + _remoteCertificate, _sslAuthenticationOptions.CheckCertName, _sslAuthenticationOptions.IsServer, _sslAuthenticationOptions.TargetHost); @@ -956,30 +973,40 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback? remoteCertVa if (remoteCertValidationCallback != null) { - success = remoteCertValidationCallback(_sslAuthenticationOptions.TargetHost, remoteCertificateEx, chain, sslPolicyErrors); + object? sender = _ssl; + if (sender == null) + { + throw new ObjectDisposedException(nameof(SslStream)); + } + + success = remoteCertValidationCallback(sender, _remoteCertificate, chain, sslPolicyErrors); } else { - if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_sslAuthenticationOptions.RemoteCertRequired) - { - success = true; - } - else + if (!RemoteCertRequired) { - success = (sslPolicyErrors == SslPolicyErrors.None); + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNotAvailable; } + + success = (sslPolicyErrors == SslPolicyErrors.None); } if (NetEventSource.Log.IsEnabled()) { LogCertificateValidation(remoteCertValidationCallback, sslPolicyErrors, success, chain!); - if (NetEventSource.Log.IsEnabled()) - NetEventSource.Info(this, $"Cert validation, remote cert = {remoteCertificateEx}"); + NetEventSource.Info(this, $"Cert validation, remote cert = {_remoteCertificate}"); } if (!success) { alertToken = CreateFatalHandshakeAlertToken(sslPolicyErrors, chain!); + if (chain != null) + { + foreach (X509ChainStatus status in chain.ChainStatus) + { + chainStatus |= status.Status; + } + } } } finally @@ -1006,8 +1033,6 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback? remoteCertVa remoteCertificateStore[i].Dispose(); } } - - remoteCertificateEx?.Dispose(); } return success; @@ -1133,7 +1158,7 @@ private static TlsAlertMessage GetAlertMessageFromChain(X509Chain chain) return TlsAlertMessage.BadCertificate; } - private void LogCertificateValidation(RemoteCertValidationCallback? remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain) + private void LogCertificateValidation(RemoteCertificateValidationCallback? remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain) { if (!NetEventSource.Log.IsEnabled()) return; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs index e229ddd0e72e..d3f99e6e9b41 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs @@ -10,7 +10,7 @@ namespace System.Net.Security { internal class SslAuthenticationOptions { - internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback? localCallback) + internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback? remoteCallback, LocalCertSelectionCallback? localCallback) { Debug.Assert(sslClientAuthenticationOptions.TargetHost != null); @@ -78,15 +78,21 @@ internal SslAuthenticationOptions(SslServerAuthenticationOptions sslServerAuthen CertificateContext = SslStreamCertificateContext.Create(certificateWithKey); } } + + if (sslServerAuthenticationOptions.RemoteCertificateValidationCallback != null) + { + CertValidationDelegate = sslServerAuthenticationOptions.RemoteCertificateValidationCallback; + } } - internal SslAuthenticationOptions(ServerOptionsSelectionCallback optionCallback, object? state) + internal SslAuthenticationOptions(ServerOptionsSelectionCallback optionCallback, object? state, RemoteCertificateValidationCallback? remoteCallback) { CheckCertName = false; TargetHost = string.Empty; IsServer = true; UserState = state; ServerOptionDelegate = optionCallback; + CertValidationDelegate = remoteCallback; } internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticationOptions) @@ -108,6 +114,11 @@ internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticati // given cert is X509Certificate2 with key. We can use it directly. CertificateContext = SslStreamCertificateContext.Create(certificateWithKey); } + + if (sslServerAuthenticationOptions.RemoteCertificateValidationCallback != null) + { + CertValidationDelegate = sslServerAuthenticationOptions.RemoteCertificateValidationCallback; + } } private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols protocols) @@ -136,7 +147,7 @@ private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols proto internal EncryptionPolicy EncryptionPolicy { get; set; } internal bool RemoteCertRequired { get; set; } internal bool CheckCertName { get; set; } - internal RemoteCertValidationCallback? CertValidationDelegate { get; set; } + internal RemoteCertificateValidationCallback? CertValidationDelegate { get; set; } internal LocalCertSelectionCallback? CertSelectionDelegate { get; set; } internal ServerCertSelectionCallback? ServerCertSelectionDelegate { get; set; } internal CipherSuitesPolicy? CipherSuitesPolicy { get; set; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 5f3c5cdff31e..5af70ed4cde3 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -4,10 +4,10 @@ using System.Buffers; using System.ComponentModel; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Runtime.ExceptionServices; using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -41,7 +41,7 @@ private enum Framing private const int InitialHandshakeBufferSize = 4096 + FrameOverhead; // try to fit at least 4K ServerCertificate private ArrayBuffer _handshakeBuffer; - private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback? localCallback) + private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback? remoteCallback, LocalCertSelectionCallback? localCallback) { ThrowIfExceptional(); @@ -321,9 +321,23 @@ private async Task ForceAuthenticationAsync(TIOAdapter adapter, bool } ProtocolToken? alertToken = null; - if (!CompleteHandshake(ref alertToken)) + if (!CompleteHandshake(ref alertToken, out SslPolicyErrors sslPolicyErrors, out X509ChainStatusFlags chainStatus)) { - SendAuthResetSignal(alertToken, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.net_ssl_io_cert_validation, null))); + if (_sslAuthenticationOptions!.CertValidationDelegate != null) + { + // there may be some chain errors but the decision was made by custom callback. Details should be tracing if enabled. + SendAuthResetSignal(alertToken, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.net_ssl_io_cert_custom_validation, null))); + } + else if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors && chainStatus != X509ChainStatusFlags.NoError) + { + // We failed only because of chain and we have some insight. + SendAuthResetSignal(alertToken, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.Format(SR.net_ssl_io_cert_chain_validation, chainStatus), null))); + } + else + { + // Simple add sslPolicyErrors as crude info. + SendAuthResetSignal(alertToken, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.Format(SR.net_ssl_io_cert_validation, sslPolicyErrors), null))); + } } } finally @@ -504,11 +518,11 @@ private void SendAuthResetSignal(ProtocolToken? message, ExceptionDispatchInfo e // // - Returns false if failed to verify the Remote Cert // - private bool CompleteHandshake(ref ProtocolToken? alertToken) + private bool CompleteHandshake(ref ProtocolToken? alertToken, out SslPolicyErrors sslPolicyErrors, out X509ChainStatusFlags chainStatus) { _context!.ProcessHandshakeSuccess(); - if (!_context.VerifyRemoteCertificate(_sslAuthenticationOptions!.CertValidationDelegate, ref alertToken)) + if (!_context.VerifyRemoteCertificate(_sslAuthenticationOptions!.CertValidationDelegate, ref alertToken, out sslPolicyErrors, out chainStatus)) { _handshakeCompleted = false; return false; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs index 523935e3533b..f896c0ea0a63 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -37,7 +37,6 @@ public enum EncryptionPolicy public delegate ValueTask ServerOptionsSelectionCallback(SslStream stream, SslClientHelloInfo clientHelloInfo, object? state, CancellationToken cancellationToken); // Internal versions of the above delegates. - internal delegate bool RemoteCertValidationCallback(string? host, X509Certificate2? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors); internal delegate X509Certificate LocalCertSelectionCallback(string targetHost, X509CertificateCollection localCertificates, X509Certificate2? remoteCertificate, string[] acceptableIssuers); internal delegate X509Certificate ServerCertSelectionCallback(string? hostName); @@ -46,13 +45,9 @@ public partial class SslStream : AuthenticatedStream /// Set as the _exception when the instance is disposed. private static readonly ExceptionDispatchInfo s_disposedSentinel = ExceptionDispatchInfo.Capture(new ObjectDisposedException(nameof(SslStream), (string?)null)); - private X509Certificate2? _remoteCertificate; - private bool _remoteCertificateExposed; - internal RemoteCertificateValidationCallback? _userCertificateValidationCallback; internal LocalCertificateSelectionCallback? _userCertificateSelectionCallback; internal ServerCertificateSelectionCallback? _userServerCertificateSelectionCallback; - internal RemoteCertValidationCallback _certValidationDelegate; internal LocalCertSelectionCallback? _certSelectionDelegate; internal EncryptionPolicy _encryptionPolicy; @@ -106,7 +101,6 @@ public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificat _userCertificateValidationCallback = userCertificateValidationCallback; _userCertificateSelectionCallback = userCertificateSelectionCallback; _encryptionPolicy = encryptionPolicy; - _certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper); _certSelectionDelegate = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper); _innerStream = innerStream; @@ -130,7 +124,6 @@ private void SetAndVerifyValidationCallback(RemoteCertificateValidationCallback? if (_userCertificateValidationCallback == null) { _userCertificateValidationCallback = callback; - _certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper); } else if (callback != null && _userCertificateValidationCallback != callback) { @@ -151,24 +144,6 @@ private void SetAndVerifySelectionCallback(LocalCertificateSelectionCallback? ca } } - private bool UserCertValidationCallbackWrapper(string? hostName, X509Certificate2? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) - { - _remoteCertificate = certificate == null ? null : new X509Certificate2(certificate); - if (_userCertificateValidationCallback == null) - { - if (!RemoteCertRequired) - { - sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNotAvailable; - } - - return (sslPolicyErrors == SslPolicyErrors.None); - } - else - { - return _userCertificateValidationCallback(this, certificate, chain, sslPolicyErrors); - } - } - private X509Certificate UserCertSelectionCallbackWrapper(string targetHost, X509CertificateCollection localCertificates, X509Certificate? remoteCertificate, string[] acceptableIssuers) { return _userCertificateSelectionCallback!(this, targetHost, localCertificates, remoteCertificate, acceptableIssuers); @@ -194,7 +169,7 @@ private SslAuthenticationOptions CreateAuthenticationOptions(SslServerAuthentica _userServerCertificateSelectionCallback = sslServerAuthenticationOptions.ServerCertificateSelectionCallback; authOptions.ServerCertSelectionDelegate = _userServerCertificateSelectionCallback == null ? null : new ServerCertSelectionCallback(ServerCertSelectionCallbackWrapper); - authOptions.CertValidationDelegate = _certValidationDelegate; + authOptions.CertValidationDelegate = _userCertificateValidationCallback; authOptions.CertSelectionDelegate = _certSelectionDelegate; return authOptions; @@ -318,7 +293,7 @@ public void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthent SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback); SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback); - ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate); + ValidateCreateContext(sslClientAuthenticationOptions, _userCertificateValidationCallback, _certSelectionDelegate); ProcessAuthentication(); } @@ -389,7 +364,7 @@ public Task AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAu SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback); SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback); - ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate); + ValidateCreateContext(sslClientAuthenticationOptions, _userCertificateValidationCallback, _certSelectionDelegate); return ProcessAuthentication(true, false, cancellationToken)!; } @@ -399,7 +374,7 @@ private Task AuthenticateAsClientApm(SslClientAuthenticationOptions sslClientAut SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback); SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback); - ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate); + ValidateCreateContext(sslClientAuthenticationOptions, _userCertificateValidationCallback, _certSelectionDelegate); return ProcessAuthentication(true, true, cancellationToken)!; } @@ -457,7 +432,7 @@ private Task AuthenticateAsServerApm(SslServerAuthenticationOptions sslServerAut public Task AuthenticateAsServerAsync(ServerOptionsSelectionCallback optionsCallback, object? state, CancellationToken cancellationToken = default) { - ValidateCreateContext(new SslAuthenticationOptions(optionsCallback, state)); + ValidateCreateContext(new SslAuthenticationOptions(optionsCallback, state, _userCertificateValidationCallback)); return ProcessAuthentication(isAsync: true, isApm: false, cancellationToken)!; } @@ -560,8 +535,7 @@ public virtual X509Certificate? RemoteCertificate get { ThrowIfExceptionalOrNotAuthenticated(); - _remoteCertificateExposed = true; - return _remoteCertificate; + return _context?.RemoteCertificate; } } @@ -714,12 +688,6 @@ protected override void Dispose(bool disposing) { try { - if (!_remoteCertificateExposed) - { - _remoteCertificate?.Dispose(); - _remoteCertificate = null; - _remoteCertificateExposed = false; - } CloseInternal(); } finally diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 6695fc966ae5..4682ba35a7ad 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Net.Sockets; using System.Net.Test.Common; using System.Security.Authentication; @@ -193,6 +194,68 @@ public async Task ServerAsyncAuthenticate_FailingOptionCallback_Throws(bool useA } } + [Fact] + public async Task ServerAsyncAuthenticate_VerificationDelegate_Success() + { + bool validationCallbackCalled = false; + var serverOptions = new SslServerAuthenticationOptions() { ServerCertificate = _serverCertificate, ClientCertificateRequired = true, }; + var clientOptions = new SslClientAuthenticationOptions() { TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, false) }; + clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; + serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => + { + validationCallbackCalled = true; + return true; + }; + + (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); + using (client) + using (server) + { + Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); + Task t2 = server.AuthenticateAsServerAsync( + (stream, clientHelloInfo, userState, cancellationToken) => + { + Assert.Equal(server, stream); + Assert.Equal(clientOptions.TargetHost, clientHelloInfo.ServerName); + return new ValueTask(OptionsTask(serverOptions)); + }, + null, CancellationToken.None); + + await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); + Assert.True(validationCallbackCalled); + } + } + + [Fact] + public async Task ServerAsyncAuthenticate_ConstructorVerificationDelegate_Success() + { + bool validationCallbackCalled = false; + var serverOptions = new SslServerAuthenticationOptions() { ServerCertificate = _serverCertificate, ClientCertificateRequired = true, }; + var clientOptions = new SslClientAuthenticationOptions() { TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, false) }; + clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; + + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); + var client = new SslStream(clientStream); + var server = new SslStream(serverStream, false, (sender, certificate, chain, sslPolicyErrors) => { validationCallbackCalled = true; return true;}); + + using (client) + using (server) + { + Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); + Task t2 = server.AuthenticateAsServerAsync( + (stream, clientHelloInfo, userState, cancellationToken) => + { + Assert.Equal(server, stream); + Assert.Equal(clientOptions.TargetHost, clientHelloInfo.ServerName); + return new ValueTask(OptionsTask(serverOptions)); + }, + null, CancellationToken.None); + + await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); + Assert.True(validationCallbackCalled); + } + } + [Theory] [InlineData(true)] [InlineData(false)] diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index 46345ba49d42..3b77a45122b2 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -277,22 +277,34 @@ public async Task SslStream_UntrustedCaWithCustomCallback_OK() } } - [Fact] + [Theory] [PlatformSpecific(TestPlatforms.AnyUnix)] - public async Task SslStream_UntrustedCaWithCustomCallback_Throws() + [InlineData(true)] + [InlineData(false)] + public async Task SslStream_UntrustedCaWithCustomCallback_Throws(bool customCallback) { + string errorMessage; var options = new SslClientAuthenticationOptions() { TargetHost = "localhost" }; - options.RemoteCertificateValidationCallback = - (sender, certificate, chain, sslPolicyErrors) => - { - chain.ChainPolicy.ExtraStore.AddRange(_serverChain); - chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count -1]); - chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - // This should work and we should be able to trust the chain. - Assert.True(chain.Build((X509Certificate2)certificate)); - // Reject it in custom callback to simulate for example pinning. - return false; - }; + if (customCallback) + { + options.RemoteCertificateValidationCallback = + (sender, certificate, chain, sslPolicyErrors) => + { + chain.ChainPolicy.ExtraStore.AddRange(_serverChain); + chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count -1]); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + // This should work and we should be able to trust the chain. + Assert.True(chain.Build((X509Certificate2)certificate)); + // Reject it in custom callback to simulate for example pinning. + return false; + }; + + errorMessage = "RemoteCertificateValidationCallback"; + } + else + { + errorMessage = "PartialChain"; + } (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (clientStream) @@ -303,7 +315,8 @@ public async Task SslStream_UntrustedCaWithCustomCallback_Throws() Task t1 = client.AuthenticateAsClientAsync(options, default); Task t2 = server.AuthenticateAsServerAsync(_serverCert); - await Assert.ThrowsAsync(() => t1); + var e = await Assert.ThrowsAsync(() => t1); + Assert.Contains(errorMessage, e.Message); // Server side should finish since we run custom callback after handshake is done. await t2; } diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs index 66702b6c4688..7139118b9101 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs @@ -17,7 +17,7 @@ private class FakeOptions private FakeOptions? _sslAuthenticationOptions; - private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback? localCallback) + private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback? remoteCallback, LocalCertSelectionCallback? localCallback) { // Without setting (or using) these members you will get a build exception in the unit test project. // The code that normally uses these in the main solution is in the implementation of SslStream. @@ -89,6 +89,7 @@ internal class SecureChannel internal SslConnectionInfo ConnectionInfo => default; internal ChannelBinding GetChannelBinding(ChannelBindingKind kind) => default; internal X509Certificate LocalServerCertificate => default; + internal X509Certificate RemoteCertificate => default; internal bool IsRemoteCertificateAvailable => default; internal SslApplicationProtocol NegotiatedApplicationProtocol => default; internal X509Certificate LocalClientCertificate => default; From 46acbaa5f13b501dc2e750bc2023d4a30eded9c7 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Sat, 8 Aug 2020 11:12:58 -0700 Subject: [PATCH 350/755] fix flaky test (#40565) Co-authored-by: Geoffrey Kizer --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 551ce4e96b63..b58fc6bc788c 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -162,7 +162,6 @@ public async Task CustomConnectionFactory_SyncRequest_Fails() HttpRequestException e = await Assert.ThrowsAnyAsync(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo")); NetworkException networkException = Assert.IsType(e.InnerException); - Assert.Equal(NetworkError.HostNotFound, networkException.NetworkError); } } From 4a58c28b80022311ef6aa982a7c8975af509ef53 Mon Sep 17 00:00:00 2001 From: Key Kim Date: Sun, 9 Aug 2020 10:56:21 +0900 Subject: [PATCH 351/755] Update linux-requirements.md (#40576) append -y option and add ``` around command code --- docs/workflow/requirements/linux-requirements.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/workflow/requirements/linux-requirements.md b/docs/workflow/requirements/linux-requirements.md index 0cdd9cc39978..b6dee2b8baf2 100644 --- a/docs/workflow/requirements/linux-requirements.md +++ b/docs/workflow/requirements/linux-requirements.md @@ -55,8 +55,13 @@ The following dependencies are needed if Mono Runtime is enabled (default behavi - autoconf - automake -- libtool +- libtool - ~$ sudo apt-get install cmake llvm-9 clang-9 autoconf automake libtool build-essential python curl git lldb-6.0 liblldb-6.0-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libssl-dev libnuma-dev libkrb5-dev zlib1g-dev +``` +sudo apt-get install -y cmake llvm-9 clang-9 autoconf automake \ +libtool build-essential python curl git lldb-6.0 liblldb-6.0-dev \ +libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev \ +libssl-dev libnuma-dev libkrb5-dev zlib1g-dev +``` You now have all the required components. From aa5fdab9654d74bc6274c0b5d820272c8e859621 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sun, 9 Aug 2020 05:32:44 -0400 Subject: [PATCH 352/755] Update Microsoft.CodeAnalysis.NetAnalyzers to 3.3.0-beta3.20407.4 (#40560) --- eng/Analyzers.props | 2 +- eng/CodeAnalysis.ruleset | 14 ++++++++++++++ .../Advapi32/Interop.CreateProcessWithLogon.cs | 2 ++ .../Advapi32/Interop.CryptGetDefaultProvider.cs | 4 +++- .../Windows/Kernel32/Interop.CreateProcess.cs | 2 ++ .../src/Interop/Windows/WinHttp/Interop.winhttp.cs | 4 +++- .../System.Data.Odbc/src/System.Data.Odbc.csproj | 2 +- .../src/System.Diagnostics.EventLog.csproj | 1 + .../src/System/Drawing/Printing/LibcupsNative.cs | 4 +++- .../src/System/Net/Http/WinHttpHandler.cs | 2 +- .../tests/UnitTests/FakeInterop.cs | 2 +- 11 files changed, 32 insertions(+), 7 deletions(-) diff --git a/eng/Analyzers.props b/eng/Analyzers.props index 2c9b1c8bee44..c14a86901948 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -6,7 +6,7 @@ - + diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset index 42ea385a079d..3726904d2fd7 100644 --- a/eng/CodeAnalysis.ruleset +++ b/eng/CodeAnalysis.ruleset @@ -64,6 +64,7 @@ + @@ -112,6 +113,8 @@ + + @@ -174,6 +177,15 @@ + + + + + + + + + @@ -239,6 +251,8 @@ + + diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CreateProcessWithLogon.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CreateProcessWithLogon.cs index 7d4fc64ff1aa..61e28bd616d5 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CreateProcessWithLogon.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CreateProcessWithLogon.cs @@ -18,7 +18,9 @@ internal static extern bool CreateProcessWithLogonW( IntPtr password, LogonFlags logonFlags, string? appName, +#pragma warning disable CA1838 // reasonable use of StringBuilder to build up a command line [In] StringBuilder cmdLine, +#pragma warning restore CA1838 int creationFlags, IntPtr environmentBlock, string lpCurrentDirectory, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetDefaultProvider.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetDefaultProvider.cs index 8b3a702d23aa..3a264330a327 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetDefaultProvider.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetDefaultProvider.cs @@ -20,7 +20,9 @@ public static extern bool CryptGetDefaultProvider( int dwProvType, IntPtr pdwReserved, GetDefaultProviderFlags dwFlags, - StringBuilder? pszProvName, +#pragma warning disable CA1838 // not on a hot path + [Out] StringBuilder? pszProvName, +#pragma warning restore CA1838 ref int pcbProvName); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateProcess.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateProcess.cs index 104bfe0e0e16..95a17f1b5624 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateProcess.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateProcess.cs @@ -15,7 +15,9 @@ internal partial class Kernel32 [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, EntryPoint = "CreateProcessW")] internal static extern bool CreateProcess( string? lpApplicationName, +#pragma warning disable CA1838 // reasonable use of StringBuilder to build up a command line [In] StringBuilder lpCommandLine, +#pragma warning restore CA1838 ref SECURITY_ATTRIBUTES procSecAttrs, ref SECURITY_ATTRIBUTES threadSecAttrs, bool bInheritHandles, diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs index c56d91b3a0a4..ddaaf8a56d09 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs @@ -43,7 +43,9 @@ public static extern SafeWinHttpHandle WinHttpOpenRequest( [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpAddRequestHeaders( SafeWinHttpHandle requestHandle, +#pragma warning disable CA1838 // Uses pooled StringBuilder [In] StringBuilder headers, +#pragma warning restore CA1838 uint headersLength, uint modifiers); @@ -59,7 +61,7 @@ public static extern bool WinHttpAddRequestHeaders( [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSendRequest( SafeWinHttpHandle requestHandle, - [In] StringBuilder headers, + IntPtr headers, uint headersLength, IntPtr optional, uint optionalLength, diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index b9c72520b7ea..e118672a4a0a 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -3,7 +3,7 @@ true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent);netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;netstandard2.0;net461-Windows_NT true - $(NoWarn);CA2249 + $(NoWarn);CA2249;CA1838 enable diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj index 42937d19fb58..a22f890d5bd5 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj @@ -3,6 +3,7 @@ true $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;net461;netstandard2.0 true + $(NoWarn);CA1838 diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs index f741f0ae7795..cc3e39f8a730 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs @@ -33,7 +33,9 @@ internal static IntPtr LoadLibcups() internal static extern void cupsFreeDests(int num_dests, IntPtr dests); [DllImport(LibraryName, ExactSpelling = true, CharSet = CharSet.Ansi)] - internal static extern IntPtr cupsTempFd(StringBuilder sb, int len); +#pragma warning disable CA1838 // not hot-path enough to worry about the overheads of StringBuilder marshaling + internal static extern IntPtr cupsTempFd([Out] StringBuilder sb, int len); +#pragma warning restore CA1838 [DllImport(LibraryName, ExactSpelling = true)] internal static extern IntPtr cupsGetDefault(); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs index c2b405dc3fba..40cd1d553723 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs @@ -1406,7 +1406,7 @@ private RendezvousAwaitable InternalSendRequestAsync(WinHttpRequestState st state.Pin(); if (!Interop.WinHttp.WinHttpSendRequest( state.RequestHandle, - null, + IntPtr.Zero, 0, IntPtr.Zero, 0, diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/FakeInterop.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/FakeInterop.cs index 728aacd3eb27..24e4b717859c 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/FakeInterop.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/FakeInterop.cs @@ -157,7 +157,7 @@ public static SafeWinHttpHandle WinHttpOpenRequest( public static bool WinHttpSendRequest( SafeWinHttpHandle requestHandle, - StringBuilder headers, + IntPtr headers, uint headersLength, IntPtr optional, uint optionalLength, From e13871cb275b9f53fa82285b2a81ada28a859b50 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Sun, 9 Aug 2020 12:36:16 -0400 Subject: [PATCH 353/755] [wasm][debugger] Add support for invoking getters on ValueTypes (#40548) * [wasm][debugger][tests] Fix negative pointer tests * [wasm][debugger][tests] Fix test to correctly check the valuetype local test: `CheckUpdatedValueTypeFieldsOnResume` * [wasm][debugger][tests] Make value checks consistent - In some places we weren't checking for the `description` property - and this hid a bug where sometimes that property wasn't added (eg. for numbers) - Instead, we were working around that by "fixing it up" later - Now, we use the same checks for `Check{Number,String,*}` API, and the `CheckValue/CheckProps` API used with `TNumber` etc. - So, this commit: - fixes the checks, and the tests - and fixes the bug * [wasm][debugger] Add new `id` types, which have associated properties - these are of the form `dotnet:${scheme}:{id-args-object}` - Examples: - `dotnet:valuetype:{ containerId: 4 }` - `dotnet:valuetype:{ num: 2 }` - the `num` field is autogenerated if no id-args are provided. This gets used when valuetypes are expanded. - `this._id_table [id-string]` has associated property objects for every `id` - This might contain, for example, `klass` pointer, and base64 representation of a valuetype * [wasm][debugger] Update valuetype code to use the new `id`s * [wasm][debugger] Simplify array API in `mini-wasm-debugger.c` .. to use a single function to get details of the full array, and individual elements. * [wasm][debugger] library_mono.js: improvements to valuetype code - Allow `_new_id` to update properties for existing objectIds - Extract valuetype id assigment code to a separate function * [wasm][debugger] mini-wasm-debugger.c- extract object id lookup into a function * [wasm][debugger][tests] Rename method param to be self descriptive * [wasm][debugger][tests] Rework cfo test for getters - add some new getters to the test classes - this will become useful in subsequent commits that add support for invoking getters on valuetypes * [wasm][debugger][tests] Improve valuetype locals/method args tests - this also becomes useful in subsequent commits which enable invoking getters on valuetypes * [wasm][debugger] Add support for invoking getters on valuetypes - keep a copy of the value bytes, and the klass pointer - this allows being able to invoke getters on such a valuetype, at a later point - This allows getters like `DateTime.Date`, which has the type `DateTime` * [wasm][debugger] mono.js: fix warnings .. and replace `var` with `let`, or `const`, where appropriate. * [wasm][debugger] mono.js: _split_object_id -> _parse_object_id * [wasm][debugger] Streamline accessing exported debugger.c functions .. especially the ones that return data in `MONO.var_info`. To use: 1. `this._register_c_var_fn ('mono_wasm_get_object_properties', 'bool', [ 'number', 'bool' ]);` 2. Now, this function can be called as `this.mono_wasm_get_object_properties_info (.. )` - returns `res` which has the contents of `MONO.var_info`, after running `_fixup_name_value_objects` on it. * [wasm][debugger] Return errors from debugger.c's details functions - functions like those for getting object/vt properties, can fail, for example, if the objectId is invalid. - We now return that bool result, and that gets surfaced to the caller - This will also help to differentiate the case where the result of such a function was a failure vs just an empty result * [wasm][debugger] Small checks on inputs, and some negative tests - These tests don't actually depend on the error message, and we don't have another to way to differentiate why a command might have failed with an exception. So, right now, they will pass as long as the commands fail as expected. - Future TODO: return `error`, instead of exception details for issues in `mono.js`, like incorrect input, invalid id etc, and update these tests accordingly. * Update src/mono/mono/mini/mini-wasm-debugger.c Co-authored-by: Larry Ewing * Remove description checking from TString Co-authored-by: Larry Ewing --- src/mono/mono/mini/mini-wasm-debugger.c | 217 ++--- .../debugger/DebuggerTestSuite/ArrayTests.cs | 118 ++- .../DebuggerTestSuite/CallFunctionOnTests.cs | 274 +++++-- .../DebuggerTestSuite/PointerTests.cs | 6 +- .../debugger/DebuggerTestSuite/Support.cs | 193 +++-- .../wasm/debugger/DebuggerTestSuite/Tests.cs | 222 +++-- .../wasm/debugger/tests/debugger-cfo-test.cs | 27 +- .../tests/debugger-valuetypes-test.cs | 1 + src/mono/wasm/debugger/tests/other.js | 13 + src/mono/wasm/runtime/library_mono.js | 776 +++++++++++------- 10 files changed, 1179 insertions(+), 668 deletions(-) diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 90855b582859..66608a7a56bc 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -37,24 +37,21 @@ EMSCRIPTEN_KEEPALIVE int mono_wasm_set_breakpoint (const char *assembly_name, in EMSCRIPTEN_KEEPALIVE int mono_wasm_remove_breakpoint (int bp_id); EMSCRIPTEN_KEEPALIVE int mono_wasm_current_bp_id (void); EMSCRIPTEN_KEEPALIVE void mono_wasm_enum_frames (void); -EMSCRIPTEN_KEEPALIVE void mono_wasm_get_var_info (int scope, int* pos, int len); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_local_vars (int scope, int* pos, int len); EMSCRIPTEN_KEEPALIVE void mono_wasm_clear_all_breakpoints (void); EMSCRIPTEN_KEEPALIVE int mono_wasm_setup_single_step (int kind); EMSCRIPTEN_KEEPALIVE int mono_wasm_pause_on_exceptions (int state); -EMSCRIPTEN_KEEPALIVE void mono_wasm_get_object_properties (int object_id, gboolean expand_value_types); -EMSCRIPTEN_KEEPALIVE void mono_wasm_get_array_values (int object_id); -EMSCRIPTEN_KEEPALIVE void mono_wasm_get_array_value_expanded (int object_id, int idx); -EMSCRIPTEN_KEEPALIVE void mono_wasm_invoke_getter_on_object (int object_id, const char* name); -EMSCRIPTEN_KEEPALIVE void mono_wasm_get_deref_ptr_value (void *value_addr, MonoClass *klass); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_object_properties (int object_id, gboolean expand_value_types); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_array_values (int object_id, int start_idx, int count, gboolean expand_value_types); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_invoke_getter_on_object (int object_id, const char* name); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_invoke_getter_on_value (void *value, MonoClass *klass, const char *name); +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_deref_ptr_value (void *value_addr, MonoClass *klass); //JS functions imported that we use extern void mono_wasm_add_frame (int il_offset, int method_token, const char *assembly_name, const char *method_name); extern void mono_wasm_fire_bp (void); extern void mono_wasm_fire_exception (int exception_obj_id, const char* message, const char* class_name, gboolean uncaught); extern void mono_wasm_add_obj_var (const char*, const char*, guint64); -extern void mono_wasm_add_value_type_unexpanded_var (const char*, const char*); -extern void mono_wasm_begin_value_type_var (const char*, const char*); -extern void mono_wasm_end_value_type_var (void); extern void mono_wasm_add_enum_var (const char*, const char*, guint64); extern void mono_wasm_add_func_var (const char*, const char*, guint64); extern void mono_wasm_add_properties_var (const char*, gint32); @@ -631,6 +628,22 @@ mono_wasm_current_bp_id (void) return evt->id; } +static MonoObject* +get_object_from_id (int objectId) +{ + ObjRef *ref = (ObjRef *)g_hash_table_lookup (objrefs, GINT_TO_POINTER (objectId)); + if (!ref) { + DEBUG_PRINTF (2, "get_object_from_id !ref: %d\n", objectId); + return NULL; + } + + MonoObject *obj = mono_gchandle_get_target_internal (ref->handle); + if (!obj) + DEBUG_PRINTF (2, "get_object_from_id !obj: %d\n", objectId); + + return obj; +} + static gboolean list_frames (MonoStackFrameInfo *info, MonoContext *ctx, gpointer data) { @@ -968,17 +981,28 @@ static gboolean describe_value(MonoType * type, gpointer addr, gboolean expandVa mono_wasm_add_enum_var (class_name, enum_members->str, value__); g_string_free (enum_members, TRUE); - } else if (expandValueType) { - char *to_string_val = get_to_string_description (class_name, klass, addr); - mono_wasm_begin_value_type_var (class_name, to_string_val); - g_free (to_string_val); - - // FIXME: isAsyncLocalThis - describe_object_properties_for_klass ((MonoObject*)addr, klass, FALSE, expandValueType); - mono_wasm_end_value_type_var (); } else { char *to_string_val = get_to_string_description (class_name, klass, addr); - mono_wasm_add_value_type_unexpanded_var (class_name, to_string_val); + + if (expandValueType) { + int32_t size = mono_class_value_size (klass, NULL); + void *value_buf = g_malloc0 (size); + mono_value_copy_internal (value_buf, addr, klass); + + EM_ASM ({ + MONO.mono_wasm_add_typed_value ($0, $1, { toString: $2, value_addr: $3, value_size: $4, klass: $5 }); + }, "begin_vt", class_name, to_string_val, value_buf, size, klass); + + g_free (value_buf); + + // FIXME: isAsyncLocalThis + describe_object_properties_for_klass (addr, klass, FALSE, expandValueType); + mono_wasm_add_typed_value ("end_vt", NULL, 0); + } else { + EM_ASM ({ + MONO.mono_wasm_add_typed_value ($0, $1, { toString: $2 }); + }, "unexpanded_vt", class_name, to_string_val); + } g_free (to_string_val); } g_free (class_name); @@ -1036,7 +1060,7 @@ describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAs gboolean is_valuetype; int pnum; char *klass_name; - gboolean getters_allowed; + gboolean auto_invoke_getters; g_assert (klass); is_valuetype = m_class_is_valuetype(klass); @@ -1069,7 +1093,7 @@ describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAs } klass_name = mono_class_full_name (klass); - getters_allowed = are_getters_allowed (klass_name); + auto_invoke_getters = are_getters_allowed (klass_name); iter = NULL; pnum = 0; @@ -1081,29 +1105,24 @@ describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAs mono_wasm_add_properties_var (p->name, pnum); sig = mono_method_signature_internal (p->get); - // automatic properties will get skipped - if (!getters_allowed) { + gboolean vt_self_type_getter = is_valuetype && mono_class_from_mono_type_internal (sig->ret) == klass; + if (auto_invoke_getters && !vt_self_type_getter) { + invoke_and_describe_getter_value (obj, p); + } else { // not allowed to call the getter here char *ret_class_name = mono_class_full_name (mono_class_from_mono_type_internal (sig->ret)); - // getters not supported for valuetypes, yet - gboolean invokable = !is_valuetype && sig->param_count == 0; + gboolean invokable = sig->param_count == 0; mono_wasm_add_typed_value ("getter", ret_class_name, invokable); g_free (ret_class_name); continue; } - - if (is_valuetype && mono_class_from_mono_type_internal (sig->ret) == klass) { - // Property of the same valuetype, avoid endlessly recursion! - mono_wasm_add_typed_value ("getter", klass_name, 0); - continue; - } - - invoke_and_describe_getter_value (obj, p); } pnum ++; } + + g_free (klass_name); } /* @@ -1132,17 +1151,10 @@ static gboolean describe_object_properties (guint64 objectId, gboolean isAsyncLocalThis, gboolean expandValueType) { DEBUG_PRINTF (2, "describe_object_properties %llu\n", objectId); - ObjRef *ref = (ObjRef *)g_hash_table_lookup (objrefs, GINT_TO_POINTER (objectId)); - if (!ref) { - DEBUG_PRINTF (2, "describe_object_properties !ref\n"); - return FALSE; - } - MonoObject *obj = mono_gchandle_get_target_internal (ref->handle); - if (!obj) { - DEBUG_PRINTF (2, "describe_object_properties !obj\n"); + MonoObject *obj = get_object_from_id (objectId); + if (!obj) return FALSE; - } if (m_class_is_delegate (mono_object_class (obj))) { // delegates get the same id format as regular objects @@ -1155,21 +1167,13 @@ describe_object_properties (guint64 objectId, gboolean isAsyncLocalThis, gboolea } static gboolean -invoke_getter_on_object (guint64 objectId, const char *name) +invoke_getter (void *obj_or_value, MonoClass *klass, const char *name) { - ObjRef *ref = (ObjRef *)g_hash_table_lookup (objrefs, GINT_TO_POINTER (objectId)); - if (!ref) { - DEBUG_PRINTF (1, "invoke_getter_on_object no objRef found for id %llu\n", objectId); - return FALSE; - } - - MonoObject *obj = mono_gchandle_get_target_internal (ref->handle); - if (!obj) { - DEBUG_PRINTF (1, "invoke_getter_on_object !obj\n"); + if (!obj_or_value || !klass || !name) { + DEBUG_PRINTF (2, "invoke_getter: none of the arguments can be null"); return FALSE; } - MonoClass *klass = mono_object_class (obj); gpointer iter = NULL; MonoProperty *p; while ((p = mono_class_get_properties (klass, &iter))) { @@ -1177,7 +1181,7 @@ invoke_getter_on_object (guint64 objectId, const char *name) if (!p->get->name || strcasecmp (p->name, name) != 0) continue; - invoke_and_describe_getter_value (obj, p); + invoke_and_describe_getter_value (obj_or_value, p); return TRUE; } @@ -1185,50 +1189,48 @@ invoke_getter_on_object (guint64 objectId, const char *name) } static gboolean -describe_array_values (guint64 objectId) +describe_array_values (guint64 objectId, int startIdx, int count, gboolean expandValueType) { + if (count == 0) + return TRUE; + int esize; gpointer elem; - ObjRef *ref = (ObjRef *)g_hash_table_lookup (objrefs, GINT_TO_POINTER (objectId)); - if (!ref) { + MonoArray *arr = (MonoArray*) get_object_from_id (objectId); + if (!arr) return FALSE; - } - MonoArray *arr = (MonoArray *)mono_gchandle_get_target_internal (ref->handle); - MonoObject *obj = &arr->obj; - if (!obj) { + + MonoClass *klass = mono_object_class (arr); + MonoTypeEnum type = m_class_get_byval_arg (klass)->type; + if (type != MONO_TYPE_SZARRAY && type != MONO_TYPE_ARRAY) { + DEBUG_PRINTF (1, "describe_array_values: object is not an array. type: 0x%x\n", type); return FALSE; } - esize = mono_array_element_size (obj->vtable->klass); - for (int i = 0; i < arr->max_length; i++) { - mono_wasm_add_array_item(i); - elem = (gpointer*)((char*)arr->vector + (i * esize)); - describe_value (m_class_get_byval_arg (m_class_get_element_class (arr->obj.vtable->klass)), elem, FALSE); + + int len = arr->max_length; + if (len == 0 && startIdx == 0 && count <= 0) { + // Nothing to do + return TRUE; } - return TRUE; -} -/* Expands valuetypes */ -static gboolean -describe_array_value_expanded (guint64 objectId, guint64 idx) -{ - int esize; - gpointer elem; - ObjRef *ref = (ObjRef *)g_hash_table_lookup (objrefs, GINT_TO_POINTER (objectId)); - if (!ref) { + if (startIdx < 0 || (len > 0 && startIdx >= len)) { + DEBUG_PRINTF (1, "describe_array_values: invalid startIdx (%d) for array of length %d\n", startIdx, len); return FALSE; } - MonoArray *arr = (MonoArray *)mono_gchandle_get_target_internal (ref->handle); - MonoObject *obj = &arr->obj; - if (!obj) { + + if (count > 0 && (startIdx + count) > len) { + DEBUG_PRINTF (1, "describe_array_values: invalid count (%d) for startIdx: %d, and array of length %d\n", count, startIdx, len); return FALSE; } - if (idx >= arr->max_length) - return FALSE; - esize = mono_array_element_size (obj->vtable->klass); - elem = (gpointer*)((char*)arr->vector + (idx * esize)); - describe_value (m_class_get_byval_arg (m_class_get_element_class (arr->obj.vtable->klass)), elem, TRUE); + esize = mono_array_element_size (klass); + int endIdx = count < 0 ? len : startIdx + count; + for (int i = startIdx; i < endIdx; i ++) { + mono_wasm_add_array_item(i); + elem = (gpointer*)((char*)arr->vector + (i * esize)); + describe_value (m_class_get_byval_arg (m_class_get_element_class (klass)), elem, expandValueType); + } return TRUE; } @@ -1331,22 +1333,23 @@ describe_variables_on_frame (MonoStackFrameInfo *info, MonoContext *ctx, gpointe return TRUE; } -EMSCRIPTEN_KEEPALIVE void +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_deref_ptr_value (void *value_addr, MonoClass *klass) { MonoType *type = m_class_get_byval_arg (klass); if (type->type != MONO_TYPE_PTR && type->type != MONO_TYPE_FNPTR) { DEBUG_PRINTF (2, "BUG: mono_wasm_get_deref_ptr_value: Expected to get a ptr type, but got 0x%x\n", type->type); - return; + return FALSE; } mono_wasm_add_properties_var ("deref", -1); describe_value (type->data.type, value_addr, TRUE); + return TRUE; } //FIXME this doesn't support getting the return value pseudo-var -EMSCRIPTEN_KEEPALIVE void -mono_wasm_get_var_info (int scope, int* pos, int len) +EMSCRIPTEN_KEEPALIVE gboolean +mono_wasm_get_local_vars (int scope, int* pos, int len) { FrameDescData data; data.target_frame = scope; @@ -1355,37 +1358,51 @@ mono_wasm_get_var_info (int scope, int* pos, int len) data.pos = pos; mono_walk_stack_with_ctx (describe_variables_on_frame, NULL, MONO_UNWIND_NONE, &data); + + return TRUE; } -EMSCRIPTEN_KEEPALIVE void +EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_object_properties (int object_id, gboolean expand_value_types) { DEBUG_PRINTF (2, "getting properties of object %d\n", object_id); - describe_object_properties (object_id, FALSE, expand_value_types); + return describe_object_properties (object_id, FALSE, expand_value_types); } -EMSCRIPTEN_KEEPALIVE void -mono_wasm_get_array_values (int object_id) +EMSCRIPTEN_KEEPALIVE gboolean +mono_wasm_get_array_values (int object_id, int start_idx, int count, gboolean expand_value_types) { - DEBUG_PRINTF (2, "getting array values %d\n", object_id); + DEBUG_PRINTF (2, "getting array values %d, startIdx: %d, count: %d, expandValueType: %d\n", object_id, start_idx, count, expand_value_types); - describe_array_values(object_id); + return describe_array_values (object_id, start_idx, count, expand_value_types); } -EMSCRIPTEN_KEEPALIVE void -mono_wasm_get_array_value_expanded (int object_id, int idx) +EMSCRIPTEN_KEEPALIVE gboolean +mono_wasm_invoke_getter_on_object (int object_id, const char* name) { - DEBUG_PRINTF (2, "getting array value %d for idx %d\n", object_id, idx); + MonoObject *obj = get_object_from_id (object_id); + if (!obj) + return FALSE; - describe_array_value_expanded (object_id, idx); + return invoke_getter (obj, mono_object_class (obj), name); } -EMSCRIPTEN_KEEPALIVE void -mono_wasm_invoke_getter_on_object (int object_id, const char* name) +EMSCRIPTEN_KEEPALIVE gboolean +mono_wasm_invoke_getter_on_value (void *value, MonoClass *klass, const char *name) { - invoke_getter_on_object (object_id, name); + DEBUG_PRINTF (2, "mono_wasm_invoke_getter_on_value: v: %p klass: %p, name: %s\n", value, klass, name); + if (!klass || !value) + return FALSE; + + if (!m_class_is_valuetype (klass)) { + DEBUG_PRINTF (2, "mono_wasm_invoke_getter_on_value: klass is not a valuetype. name: %s\n", mono_class_full_name (klass)); + return FALSE; + } + + return invoke_getter (value, klass, name); } + // Functions required by debugger-state-machine. gsize mono_debugger_tls_thread_id (DebuggerTlsData *debuggerTlsData) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index 022e41cc042c..f9319a7b491f 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -26,7 +26,7 @@ public async Task InspectPrimitiveTypeArrayLocals(int line, int col, string meth etype_name: "int", local_var_name_prefix: "int", array : new [] { TNumber(4), TNumber(70), TNumber(1) }, - array_elements : null, + array_elem_props: null, test_prev_frame : test_prev_frame, frame_idx : frame_idx, use_cfo : use_cfo); @@ -47,7 +47,7 @@ public async Task InspectValueTypeArrayLocals(int line, int col, string method_n TValueType("DebuggerTests.Point"), TValueType("DebuggerTests.Point"), }, - array_elements : new [] + array_elem_props: new [] { TPoint(5, -2, "point_arr#Id#0", "Green"), TPoint(123, 0, "point_arr#Id#1", "Blue") @@ -73,7 +73,7 @@ public async Task InspectObjectArrayLocals(int line, int col, string method_name TObject("DebuggerTests.SimpleClass", is_null : true), TObject("DebuggerTests.SimpleClass") }, - array_elements : new [] + array_elem_props: new [] { TSimpleClass(5, -2, "class_arr#Id#0", "Green"), null, // Element is null @@ -100,7 +100,7 @@ public async Task InspectGenericTypeArrayLocals(int line, int col, string method TObject("DebuggerTests.GenericClass"), TObject("DebuggerTests.GenericClass") }, - array_elements : new [] + array_elem_props : new [] { null, // Element is null new @@ -136,7 +136,7 @@ public async Task InspectGenericValueTypeArrayLocals(int line, int col, string m TValueType("DebuggerTests.SimpleGenericStruct"), TValueType("DebuggerTests.SimpleGenericStruct") }, - array_elements : new [] + array_elem_props : new [] { new { @@ -171,7 +171,7 @@ public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string TValueType("DebuggerTests.SimpleGenericStruct"), TValueType("DebuggerTests.SimpleGenericStruct") }, - array_elements : new [] + array_elem_props : new [] { new { @@ -199,7 +199,7 @@ public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string use_cfo : use_cfo); async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, string method_name, string etype_name, - string local_var_name_prefix, object[] array, object[] array_elements, + string local_var_name_prefix, object[] array, object[] array_elem_props, bool test_prev_frame = false, int frame_idx = 0, bool use_cfo = false) { var insp = new Inspector(); @@ -223,8 +223,8 @@ await insp.Ready(async(cli, token) => var locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); Assert.Equal(4, locals.Count()); - CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]"); - CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]"); + CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]", array?.Length ?? 0); + CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]", 0); CheckObject(locals, $"{local_var_name_prefix}_arr_null", $"{etype_name}[]", is_null : true); CheckBool(locals, "call_other", test_prev_frame); @@ -250,13 +250,13 @@ await insp.Ready(async(cli, token) => await CheckProps(prefix_arr, array, local_arr_name); - if (array_elements?.Length > 0) + if (array_elem_props?.Length > 0) { - for (int i = 0; i < array_elements.Length; i++) + for (int i = 0; i < array_elem_props.Length; i++) { var i_str = i.ToString(); var label = $"{local_var_name_prefix}_arr[{i}]"; - if (array_elements[i] == null) + if (array_elem_props[i] == null) { var act_i = prefix_arr.FirstOrDefault(jt => jt["name"]?.Value() == i_str); Assert.True(act_i != null, $"[{label}] Couldn't find array element [{i_str}]"); @@ -265,7 +265,7 @@ await insp.Ready(async(cli, token) => } else { - await CompareObjectPropertiesFor(prefix_arr, i_str, array_elements[i], label : label); + await CompareObjectPropertiesFor(prefix_arr, i_str, array_elem_props[i], label : label); } } } @@ -601,5 +601,95 @@ await CompareObjectPropertiesFor(frame_locals, "this", }); } + [Fact] + public async Task InvalidArrayId() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", + wait_for_event_fn : async(pause_location) => + { + + int frame_idx = 1; + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + var c_obj = GetAndAssertObjectWithName(frame_locals, "c"); + var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); + Assert.NotNull(c_obj_id); + + // Invalid format + await GetProperties("dotnet:array:4123", expect_ok : false); + + // Invalid object id + await GetProperties("dotnet:array:{ \"arrayId\": 234980 }", expect_ok : false); + + // Trying to access object as an array + if (!DotnetObjectId.TryParse (c_obj_id, out var id) || id.Scheme != "object") + Assert.True(false, "Unexpected object id format. Maybe this test is out of sync with the object id format in library_mono.js?"); + + if (!int.TryParse(id.Value, out var idNum)) + Assert.True(false, "Expected a numeric value part of the object id: {c_obj_id}"); + await GetProperties($"dotnet:array:{{\"arrayId\":{idNum}}}", expect_ok : false); + }); + + [Fact] + public async Task InvalidValueTypeArrayIndex() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", + locals_fn : async(locals) => + { + var this_obj = GetAndAssertObjectWithName(locals, "this"); + var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); + var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); + Assert.NotNull(c_obj_id); + + var c_props = await GetProperties(c_obj_id); + + var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); + var pf_arr_elems = await GetProperties(pf_arr["value"]["objectId"].Value()); + + if (!DotnetObjectId.TryParse(pf_arr_elems[0]["value"] ? ["objectId"]?.Value(), out var id)) + Assert.True(false, "Couldn't parse objectId for PointsFields' elements"); + + AssertEqual("valuetype", id.Scheme, "Expected a valuetype id"); + var id_args = id.ValueAsJson; + Assert.True(id_args["arrayId"] != null, "ObjectId format for array seems to have changed. Expected to find 'arrayId' in the value. Update this test"); + Assert.True(id_args != null, "Expected to get a json as the value part of {id}"); + + // Try one valid query, to confirm that the id format hasn't changed! + id_args["arrayIdx"] = 0; + await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : true); + + id_args["arrayIdx"] = 12399; + await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); + + id_args["arrayIdx"] = -1; + await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); + + id_args["arrayIdx"] = "qwe"; + await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); + }); + + [Fact] + public async Task InvalidAccessors() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", + locals_fn : async(locals) => + { + var this_obj = GetAndAssertObjectWithName(locals, "this"); + var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); + var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); + Assert.NotNull(c_obj_id); + + var c_props = await GetProperties(c_obj_id); + + var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); + + var invalid_accessors = new object[] { "NonExistant", "10000", "-2", 10000, -2, null, String.Empty }; + foreach (var invalid_accessor in invalid_accessors) + { + // var res = await InvokeGetter (JObject.FromObject (new { value = new { objectId = obj_id } }), invalid_accessor, expect_ok: true); + var res = await InvokeGetter(pf_arr, invalid_accessor, expect_ok : true); + AssertEqual("undefined", res.Value["result"] ? ["type"]?.ToString(), "Expected to get undefined result for non-existant accessor"); + } + }); + } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs index 5c66bb2fb259..3014c6cc5e83 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs @@ -481,6 +481,36 @@ await insp.Ready(async(cli, token) => // callFunctionOn result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); await CheckValue(result.Value["result"], TNumber(5), "cfo-res"); + + cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return 'test value'; }", + objectId = obj_id + }); + + // value of @returnByValue doesn't matter, as the returned value + // is a primitive + if (return_by_val) + cfo_args["returnByValue"] = return_by_val; + + // callFunctionOn + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + await CheckValue(result.Value["result"], JObject.FromObject(new { type = "string", value = "test value" }), "cfo-res"); + + cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return null; }", + objectId = obj_id + }); + + // value of @returnByValue doesn't matter, as the returned value + // is a primitive + if (return_by_val) + cfo_args["returnByValue"] = return_by_val; + + // callFunctionOn + result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + await CheckValue(result.Value["result"], JObject.Parse("{ type: 'object', subtype: 'null', value: null }"), "cfo-res"); }); } @@ -536,7 +566,7 @@ await insp.Ready(async(cli, token) => }); } - public static TheoryData, bool> GettersTestData(bool use_cfo) => new TheoryData, bool> + public static TheoryData, string, bool> GettersTestData(string local_name, bool use_cfo) => new TheoryData, string, bool> { // Chrome sends this one { @@ -546,6 +576,7 @@ await insp.Ready(async(cli, token) => 12, "function invokeGetter(arrayStr){ let result=this; const properties=JSON.parse(arrayStr); for(let i=0,n=properties.length;i JArray.FromObject(arg_strs).ToString(), + local_name, use_cfo }, { @@ -555,6 +586,7 @@ await insp.Ready(async(cli, token) => 12, "function invokeGetter(arrayStr){ let result=this; const properties=JSON.parse(arrayStr); for(let i=0,n=properties.length;i JArray.FromObject(arg_strs).ToString(), + local_name, use_cfo }, @@ -566,6 +598,7 @@ await insp.Ready(async(cli, token) => 12, "function(e){return this[e]}", (args_str) => args_str?.Length > 0 ? args_str[0] : String.Empty, + local_name, use_cfo }, { @@ -575,14 +608,17 @@ await insp.Ready(async(cli, token) => 12, "function(e){return this[e]}", (args_str) => args_str?.Length > 0 ? args_str[0] : String.Empty, + local_name, use_cfo } }; [Theory] - [MemberData(nameof(GettersTestData), parameters : false)] - [MemberData(nameof(GettersTestData), parameters : true)] - public async Task PropertyGettersOnObjectsTest(string eval_fn, string method_name, int line, int col, string cfo_fn, Func get_args_fn, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( + [MemberData(nameof(GettersTestData), "ptd", false)] + [MemberData(nameof(GettersTestData), "ptd", true)] + [MemberData(nameof (GettersTestData), "swp", false)] + [MemberData(nameof (GettersTestData), "swp", true)] + public async Task PropertyGettersTest(string eval_fn, string method_name, int line, int col, string cfo_fn, Func get_args_fn, string local_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-cfo-test.cs", line, col, method_name, $"window.setTimeout(function() {{ {eval_fn} }}, 1);", @@ -590,55 +626,56 @@ public async Task PropertyGettersOnObjectsTest(string eval_fn, string method_nam wait_for_event_fn : async(pause_location) => { var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var dt = new DateTime(10, 9, 8, 7, 6, 5); await CheckProps(frame_locals, new { ptd = TObject("DebuggerTests.ClassWithProperties"), - swp = TObject("DebuggerTests.StructWithProperties"), + swp = TObject("DebuggerTests.StructWithProperties") }, "locals#0"); - var ptd = GetAndAssertObjectWithName(frame_locals, "ptd"); + var obj = GetAndAssertObjectWithName(frame_locals, local_name); - var ptd_props = await GetProperties(ptd?["value"] ? ["objectId"]?.Value()); - await CheckProps(ptd_props, new + var dt = new DateTime(4, 5, 6, 7, 8, 9); + var obj_props = await GetProperties(obj?["value"] ? ["objectId"]?.Value()); + await CheckProps(obj_props, new { - Int = TGetter("Int"), - String = TGetter("String"), - DT = TGetter("DT"), - IntArray = TGetter("IntArray"), - DTArray = TGetter("DTArray") - }, "ptd", num_fields : 7); + V = TNumber(0xDEADBEEF), + Int = TGetter("Int"), + String = TGetter("String"), + DT = TGetter("DT"), + IntArray = TGetter("IntArray"), + DTArray = TGetter("DTArray"), + StringField = TString(null), + + // Auto properties show w/o getters, because they have + // a backing field + DTAutoProperty = TValueType("System.DateTime", dt.ToString()) + }, local_name); // Automatic properties don't have invokable getters, because we can get their // value from the backing field directly { - dt = new DateTime(4, 5, 6, 7, 8, 9); - var dt_auto_props = await GetObjectOnLocals(ptd_props, "DTAutoProperty"); - await CheckDateTime(ptd_props, "DTAutoProperty", dt); + var dt_auto_props = await GetObjectOnLocals(obj_props, "DTAutoProperty"); + await CheckDateTime(obj_props, "DTAutoProperty", dt); } // Invoke getters, and check values - var res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "Int" })); - Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); - await CheckValue(res.Value["result"], JObject.FromObject(new { type = "number", value = 5 }), "ptd.Int"); + dt = new DateTime(3, 4, 5, 6, 7, 8); + var res = await InvokeGetter(obj, get_args_fn(new [] { "Int" }), cfo_fn); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "number", value = (0xDEADBEEF + (uint) dt.Month) }), $"{local_name}.Int"); - res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "String" })); - Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); - await CheckValue(res.Value["result"], JObject.FromObject(new { type = "string", value = "foobar" }), "ptd.String"); + res = await InvokeGetter(obj, get_args_fn(new [] { "String" }), cfo_fn); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "string", value = $"String property, V: 0xDEADBEEF" }), $"{local_name}.String"); - dt = new DateTime(3, 4, 5, 6, 7, 8); - res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "DT" })); - Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); - await CheckValue(res.Value["result"], TValueType("System.DateTime", dt.ToString()), "ptd.DT"); + res = await InvokeGetter(obj, get_args_fn(new [] { "DT" }), cfo_fn); + await CheckValue(res.Value["result"], TValueType("System.DateTime", dt.ToString()), $"{local_name}.DT"); await CheckDateTimeValue(res.Value["result"], dt); // Check arrays through getters - res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "IntArray" })); - Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); - await CheckValue(res.Value["result"], TArray("int[]", 2), "ptd.IntArray"); + res = await InvokeGetter(obj, get_args_fn(new [] { "IntArray" }), cfo_fn); + await CheckValue(res.Value["result"], TArray("int[]", 2), $"{local_name}.IntArray"); { var arr_elems = await GetProperties(res.Value["result"] ? ["objectId"]?.Value()); var exp_elems = new [] @@ -647,12 +684,11 @@ public async Task PropertyGettersOnObjectsTest(string eval_fn, string method_nam TNumber(20) }; - await CheckProps(arr_elems, exp_elems, "ptd.IntArray"); + await CheckProps(arr_elems, exp_elems, $"{local_name}.IntArray"); } - res = await InvokeGetter(ptd, cfo_fn, get_args_fn(new [] { "DTArray" })); - Assert.True(res.IsOk, $"InvokeGetter failed with : {res}"); - await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), "ptd.DTArray"); + res = await InvokeGetter(obj, get_args_fn(new [] { "DTArray" }), cfo_fn); + await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), $"{local_name}.DTArray"); { var dt0 = new DateTime(6, 7, 8, 9, 10, 11); var dt1 = new DateTime(1, 2, 3, 4, 5, 6); @@ -664,44 +700,20 @@ public async Task PropertyGettersOnObjectsTest(string eval_fn, string method_nam TValueType("System.DateTime", dt1.ToString()), }; - await CheckProps(arr_elems, exp_elems, "ptd.DTArray"); - } - }); + await CheckProps(arr_elems, exp_elems, $"{local_name}.DTArray"); - [Theory] - [InlineData("invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", "MoveNext", 38, 12)] - [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "PropertyGettersTest", 30, 12)] - public async Task PropertyGettersOnStructsTest(string eval_fn, string method_name, int line, int col) => await CheckInspectLocalsAtBreakpointSite( - "dotnet://debugger-test.dll/debugger-cfo-test.cs", line, col, - method_name, - $"window.setTimeout(function() {{ {eval_fn} }}, 1);", - wait_for_event_fn : async(pause_location) => - { - var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - await CheckProps(frame_locals, new - { - ptd = TObject("DebuggerTests.ClassWithProperties"), - swp = TObject("DebuggerTests.StructWithProperties"), - }, "locals#0"); - - var swp = GetAndAssertObjectWithName(frame_locals, "swp"); - - var swp_props = await GetProperties(swp?["value"] ? ["objectId"]?.Value()); - await CheckProps(swp_props, new - { - Int = TSymbol("int { get; }"), - String = TSymbol("string { get; }"), - DT = TSymbol("System.DateTime { get; }"), - IntArray = TSymbol("int[] { get; }"), - DTArray = TSymbol("System.DateTime[] { get; }") - }, "swp"); + res = await InvokeGetter(arr_elems[0], "Date"); + await CheckDateTimeValue(res.Value["result"], dt0.Date); + } }); [Theory] - [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 30, 12, false)] + [InlineData("invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 38, 12, true)] + [InlineData("invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 38, 12, false)] [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 30, 12, true)] - [InlineData("invoke_getters_js_test ();", "/other.js", 29, 1, false)] - [InlineData("invoke_getters_js_test ();", "/other.js", 29, 1, true)] + [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTest');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 30, 12, false)] + [InlineData("invoke_getters_js_test ();", "/other.js", 30, 1, false)] + [InlineData("invoke_getters_js_test ();", "/other.js", 30, 1, true)] public async Task CheckAccessorsOnObjectsWithCFO(string eval_fn, string bp_loc, int line, int col, bool roundtrip) { await RunCallFunctionOn( @@ -754,14 +766,126 @@ async Task GetPropertiesAndCheckAccessors(JObject get_prop_req, int num_ } } - async Task InvokeGetter(JToken obj, string fn, object arguments) => await ctx.cli.SendCommand( - "Runtime.callFunctionOn", - JObject.FromObject(new + public static TheoryData NegativeTestsData(bool use_cfo = false) => new TheoryData + { { "invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:MethodForNegativeTests', null);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 45, 12, use_cfo }, + { "negative_cfo_test ();", "/other.js", 62, 1, use_cfo } + }; + + [Theory] + [MemberData(nameof(NegativeTestsData), false)] + public async Task RunOnInvalidCfoId(string eval_fn, string bp_loc, int line, int col, bool use_cfo) => await RunCallFunctionOn( + eval_fn, "function() { return this; }", "ptd", + bp_loc, line, col, + test_fn : async(cfo_result) => + { + var ptd_id = cfo_result.Value?["result"] ? ["objectId"]?.Value(); + + var cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return 0; }", + objectId = ptd_id + "_invalid" + }); + + var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + Assert.True(res.IsErr); + }); + + [Theory] + [MemberData(nameof(NegativeTestsData), false)] + public async Task RunOnInvalidThirdSegmentOfObjectId(string eval_fn, string bp_loc, int line, int col, bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + await SetBreakpoint(bp_loc, line, col); + + // callFunctionOn + var eval_expr = $"window.setTimeout(function() {{ {eval_fn} }}, 1);"; + var result = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr }), ctx.token); + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + var frame_locals = await GetProperties(pause_location["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value()); + var ptd = GetAndAssertObjectWithName(frame_locals, "ptd"); + var ptd_id = ptd["value"]["objectId"].Value(); + + var cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return 0; }", + objectId = ptd_id + "_invalid" + }); + + var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + Assert.True(res.IsErr); + }); + } + + [Theory] + [MemberData(nameof(NegativeTestsData), false)] + [MemberData(nameof(NegativeTestsData), true)] + public async Task InvalidPropertyGetters(string eval_fn, string bp_loc, int line, int col, bool use_cfo) + { + var insp = new Inspector(); + //Collect events + var scripts = SubscribeToScripts(insp); + + await Ready(); + await insp.Ready(async(cli, token) => + { + ctx = new DebugTestContext(cli, insp, token, scripts); + await SetBreakpoint(bp_loc, line, col); + ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; + + // callFunctionOn + var eval_expr = $"window.setTimeout(function() {{ {eval_fn} }}, 1);"; + await SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr })); + var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); + + var frame_locals = await GetProperties(pause_location["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value()); + var ptd = GetAndAssertObjectWithName(frame_locals, "ptd"); + var ptd_id = ptd["value"]["objectId"].Value(); + + var invalid_args = new object[] { "NonExistant", String.Empty, null, 12310 }; + foreach (var invalid_arg in invalid_args) + { + var getter_res = await InvokeGetter(JObject.FromObject(new { value = new { objectId = ptd_id } }), invalid_arg); + AssertEqual("undefined", getter_res.Value["result"] ? ["type"]?.ToString(), $"Expected to get undefined result for non-existant accessor - {invalid_arg}"); + } + }); + } + + [Theory] + [MemberData(nameof(NegativeTestsData), false)] + public async Task ReturnNullFromCFO(string eval_fn, string bp_loc, int line, int col, bool use_cfo) => await RunCallFunctionOn( + eval_fn, "function() { return this; }", "ptd", + bp_loc, line, col, + test_fn : async(result) => { - functionDeclaration = fn, - objectId = obj["value"] ? ["objectId"]?.Value(), - arguments = new [] { new { value = arguments } } - }), ctx.token); + var is_js = bp_loc.EndsWith(".js"); + var ptd = JObject.FromObject(new { value = new { objectId = result.Value?["result"] ? ["objectId"]?.Value() } }); + + var null_value_json = JObject.Parse("{ 'type': 'object', 'subtype': 'null', 'value': null }"); + foreach (var returnByValue in new bool?[] { null, false, true }) + { + var res = await InvokeGetter(ptd, "StringField", returnByValue : returnByValue); + if (is_js) + { + // In js case, it doesn't know the className, so the result looks slightly different + Assert.True( + JObject.DeepEquals(res.Value["result"], null_value_json), + $"[StringField#returnByValue = {returnByValue}] Json didn't match. Actual: {res.Value ["result"]} vs {null_value_json}"); + } + else + { + await CheckValue(res.Value["result"], TString(null), "StringField"); + } + } + }); /* * 1. runs `Runtime.callFunctionOn` on the objectId, diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs index e121870d3192..2a62a67422c4 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs @@ -534,12 +534,10 @@ public async Task DerefNonPointerObject(string eval_fn, string type, string meth var complex = GetAndAssertObjectWithName(locals, "complex"); // try to deref the non-pointer object, as a pointer - var props = await GetProperties(complex["value"]["objectId"].Value().Replace(":object:", ":pointer:")); - Assert.Empty(props.Values()); + await GetProperties(complex["value"]["objectId"].Value().Replace(":object:", ":pointer:"), expect_ok: false); // try to deref an invalid pointer id - props = await GetProperties("dotnet:pointer:123897"); - Assert.Empty(props.Values()); + await GetProperties("dotnet:pointer:123897", expect_ok: false); }); async Task CheckArrayElements(JToken array, JToken[] exp_elems) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs index cac5e736b3a0..ac8570978353 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; using Xunit; @@ -301,6 +302,7 @@ internal void CheckNumber(JToken locals, string name, T value) var val = l["value"]; Assert.Equal("number", val["type"]?.Value()); Assert.Equal(value, val["value"].Value()); + Assert.Equal(value.ToString(), val["description"].Value().ToString()); return; } Assert.True(false, $"Could not find variable '{name}'"); @@ -308,32 +310,14 @@ internal void CheckNumber(JToken locals, string name, T value) internal void CheckString(JToken locals, string name, string value) { - foreach (var l in locals) - { - if (name != l["name"]?.Value()) - continue; - var val = l["value"]; - if (value == null) - { - Assert.Equal("object", val["type"]?.Value()); - Assert.Equal("null", val["subtype"]?.Value()); - } - else - { - Assert.Equal("string", val["type"]?.Value()); - Assert.Equal(value, val["value"]?.Value()); - } - return; - } - Assert.True(false, $"Could not find variable '{name}'"); + var l = GetAndAssertObjectWithName(locals, name); + CheckValue(l["value"], TString(value), name).Wait(); } internal JToken CheckSymbol(JToken locals, string name, string value) { var l = GetAndAssertObjectWithName(locals, name); - var val = l["value"]; - Assert.Equal("symbol", val["type"]?.Value()); - Assert.Equal(value, val["value"]?.Value()); + CheckValue(l["value"], TSymbol(value), name).Wait(); return l; } @@ -341,14 +325,8 @@ internal JToken CheckObject(JToken locals, string name, string class_name, strin { var l = GetAndAssertObjectWithName(locals, name); var val = l["value"]; - Assert.Equal("object", val["type"]?.Value()); + CheckValue(val, TObject(class_name, is_null: is_null), name).Wait(); Assert.True(val["isValueType"] == null || !val["isValueType"].Value()); - Assert.Equal(class_name, val["className"]?.Value()); - - var has_null_subtype = val["subtype"] != null && val["subtype"]?.Value() == "null"; - Assert.Equal(is_null, has_null_subtype); - if (subtype != null) - Assert.Equal(subtype, val["subtype"]?.Value()); return l; } @@ -368,31 +346,34 @@ internal async Task CheckDateTime(JToken locals, string name, DateTime expected) internal async Task CheckDateTimeValue(JToken value, DateTime expected) { - AssertEqual("System.DateTime", value["className"]?.Value(), "className"); - AssertEqual(expected.ToString(), value["description"]?.Value(), "description"); - - var members = await GetProperties(value["objectId"]?.Value()); + await CheckDateTimeMembers(value, expected); - // not checking everything - CheckNumber(members, "Year", expected.Year); - CheckNumber(members, "Month", expected.Month); - CheckNumber(members, "Day", expected.Day); - CheckNumber(members, "Hour", expected.Hour); - CheckNumber(members, "Minute", expected.Minute); - CheckNumber(members, "Second", expected.Second); + var res = await InvokeGetter(JObject.FromObject(new { value = value }), "Date"); + await CheckDateTimeMembers(res.Value["result"], expected.Date); // FIXME: check some float properties too + + async Task CheckDateTimeMembers(JToken v, DateTime exp_dt) + { + AssertEqual("System.DateTime", v["className"]?.Value(), "className"); + AssertEqual(exp_dt.ToString(), v["description"]?.Value(), "description"); + + var members = await GetProperties(v["objectId"]?.Value()); + + // not checking everything + CheckNumber(members, "Year", exp_dt.Year); + CheckNumber(members, "Month", exp_dt.Month); + CheckNumber(members, "Day", exp_dt.Day); + CheckNumber(members, "Hour", exp_dt.Hour); + CheckNumber(members, "Minute", exp_dt.Minute); + CheckNumber(members, "Second", exp_dt.Second); + } } internal JToken CheckBool(JToken locals, string name, bool expected) { var l = GetAndAssertObjectWithName(locals, name); - var val = l["value"]; - Assert.Equal("boolean", val["type"]?.Value()); - if (val["value"] == null) - Assert.True(false, "expected bool value not found for variable named {name}"); - Assert.Equal(expected, val["value"]?.Value()); - + CheckValue(l["value"], TBool(expected), name).Wait(); return l; } @@ -405,41 +386,21 @@ internal void CheckContentValue(JToken token, string value) internal JToken CheckValueType(JToken locals, string name, string class_name) { var l = GetAndAssertObjectWithName(locals, name); - var val = l["value"]; - Assert.Equal("object", val["type"]?.Value()); - Assert.True(val["isValueType"] != null && val["isValueType"].Value()); - Assert.Equal(class_name, val["className"]?.Value()); + CheckValue(l["value"], TValueType(class_name), name).Wait(); return l; } internal JToken CheckEnum(JToken locals, string name, string class_name, string descr) { var l = GetAndAssertObjectWithName(locals, name); - var val = l["value"]; - Assert.Equal("object", val["type"]?.Value()); - Assert.True(val["isEnum"] != null && val["isEnum"].Value()); - Assert.Equal(class_name, val["className"]?.Value()); - Assert.Equal(descr, val["description"]?.Value()); + CheckValue(l["value"], TEnum(class_name, descr), name).Wait(); return l; } - internal void CheckArray(JToken locals, string name, string class_name) - { - foreach (var l in locals) - { - if (name != l["name"]?.Value()) - continue; - - var val = l["value"]; - Assert.Equal("object", val["type"]?.Value()); - Assert.Equal("array", val["subtype"]?.Value()); - Assert.Equal(class_name, val["className"]?.Value()); - - //FIXME: elements? - return; - } - Assert.True(false, $"Could not find variable '{name}'"); - } + internal void CheckArray(JToken locals, string name, string class_name, int length) + => CheckValue( + GetAndAssertObjectWithName(locals, name)["value"], + TArray(class_name, length), name).Wait(); internal JToken GetAndAssertObjectWithName(JToken obj, string name) { @@ -482,6 +443,23 @@ internal async Task RunUntil(string methodName) return wait_res; } + internal async Task InvokeGetter(JToken obj, object arguments, string fn = "function(e){return this[e]}", bool expect_ok = true, bool? returnByValue = null) + { + var req = JObject.FromObject(new + { + functionDeclaration = fn, + objectId = obj["value"]?["objectId"]?.Value(), + arguments = new[] { new { value = arguments } } + }); + if (returnByValue != null) + req["returnByValue"] = returnByValue.Value; + + var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", req, ctx.token); + Assert.True(expect_ok == res.IsOk, $"InvokeGetter failed for {req} with {res}"); + + return res; + } + internal async Task StepAndCheck(StepKind kind, string script_loc, int line, int column, string function_name, Func wait_for_event_fn = null, Action locals_fn = null, int times = 1) { @@ -796,7 +774,7 @@ internal async Task GetObjectOnLocals(JToken locals, string name) } /* @fn_args is for use with `Runtime.callFunctionOn` only */ - internal async Task GetProperties(string id, JToken fn_args = null) + internal async Task GetProperties(string id, JToken fn_args = null, bool expect_ok = true) { if (ctx.UseCallFunctionOnBeforeGetProperties && !id.StartsWith("dotnet:scope:")) { @@ -810,7 +788,9 @@ internal async Task GetProperties(string id, JToken fn_args = null) cfo_args["arguments"] = fn_args; var result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); - AssertEqual(true, result.IsOk, $"Runtime.getProperties failed for {cfo_args.ToString ()}, with Result: {result}"); + AssertEqual(expect_ok, result.IsOk, $"Runtime.getProperties returned {result.IsOk} instead of {expect_ok}, for {cfo_args.ToString ()}, with Result: {result}"); + if (!result.IsOk) + return null; id = result.Value["result"] ? ["objectId"]?.Value(); } @@ -820,8 +800,9 @@ internal async Task GetProperties(string id, JToken fn_args = null) }); var frame_props = await ctx.cli.SendCommand("Runtime.getProperties", get_prop_req, ctx.token); + AssertEqual(expect_ok, frame_props.IsOk, $"Runtime.getProperties returned {frame_props.IsOk} instead of {expect_ok}, for {get_prop_req}, with Result: {frame_props}"); if (!frame_props.IsOk) - Assert.True(false, $"Runtime.getProperties failed for {get_prop_req.ToString ()}, with Result: {frame_props}"); + return null; var locals = frame_props.Value["result"]; // FIXME: Should be done when generating the list in library_mono.js, but not sure yet @@ -927,11 +908,14 @@ internal void AssertEqual(object expected, object actual, string label) => Asser internal static JObject TString(string value) => value == null ? TObject("string", is_null : true) : - JObject.FromObject(new { type = "string", value = @value, description = @value }); + JObject.FromObject(new { type = "string", value = @value }); internal static JObject TNumber(int value) => JObject.FromObject(new { type = "number", value = @value.ToString(), description = value.ToString() }); + internal static JObject TNumber(uint value) => + JObject.FromObject(new { type = "number", value = @value.ToString(), description = value.ToString() }); + internal static JObject TValueType(string className, string description = null, object members = null) => JObject.FromObject(new { type = "object", isValueType = true, className = className, description = description ?? className }); @@ -987,6 +971,65 @@ public DebugTestContext(InspectorClient cli, Inspector insp, CancellationToken t } } + class DotnetObjectId + { + public string Scheme { get; } + public string Value { get; } + + JObject value_json; + public JObject ValueAsJson + { + get + { + if (value_json == null) + { + try + { + value_json = JObject.Parse(Value); + } + catch (JsonReaderException) { } + } + + return value_json; + } + } + + public static bool TryParse(JToken jToken, out DotnetObjectId objectId) => TryParse(jToken?.Value(), out objectId); + + public static bool TryParse(string id, out DotnetObjectId objectId) + { + objectId = null; + if (id == null) + { + return false; + } + + if (!id.StartsWith("dotnet:")) + { + return false; + } + + var parts = id.Split(":", 3); + + if (parts.Length < 3) + { + return false; + } + + objectId = new DotnetObjectId(parts[1], parts[2]); + + return true; + } + + public DotnetObjectId(string scheme, string value) + { + Scheme = scheme; + Value = value; + } + + public override string ToString() => $"dotnet:{Scheme}:{Value}"; + } + enum StepKind { Into, diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 03964dd207d0..5ba31d8c3701 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -372,14 +372,14 @@ await CheckInspectLocalsAtBreakpointSite( CheckObject(locals, "list", "System.Collections.Generic.Dictionary"); CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null : true); - CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]"); + CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]", 1); CheckObject(locals, "list_arr_null", "System.Collections.Generic.Dictionary[]", is_null : true); // Unused locals CheckObject(locals, "list_unused", "System.Collections.Generic.Dictionary"); CheckObject(locals, "list_null_unused", "System.Collections.Generic.Dictionary", is_null : true); - CheckObject(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]"); + CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]", 1); CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null : true); } ); @@ -638,9 +638,11 @@ await insp.Ready(async(cli, token) => CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct"); var ss_props = await GetObjectOnLocals(this_props, "SimpleStructProperty"); - Assert.Equal(2, ss_props.Count()); - CheckValueType(ss_props, "dt", "System.DateTime"); - CheckValueType(ss_props, "gs", "Math.GenericStruct"); + var dt = new DateTime(2020, 1, 2, 3, 4, 5); + await CheckProps(ss_props, new { + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("Math.GenericStruct") + }, "ss_props"); await CheckDateTime(ss_props, "dt", new DateTime(2020, 1, 2, 3, 4, 5)); @@ -829,7 +831,7 @@ await insp.Ready(async(cli, token) => CheckObject(locals, "this", "Math.NestedInMath"); //FIXME: check fields CheckValueType(locals, "ss", "Math.SimpleStruct"); - CheckArray(locals, "ss_arr", "Math.SimpleStruct[]"); + CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", 0); // TODO: struct fields } ); @@ -863,29 +865,40 @@ await insp.Ready(async(cli, token) => var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_method_with_structs(); }, 1);", - debugger_test_loc, 22, 8, "MethodWithLocalStructs", - locals_fn: (locals) => - { - Assert.Equal(3, locals.Count()); + debugger_test_loc, 22, 8, "MethodWithLocalStructs"); - CheckValueType(locals, "ss_local", "DebuggerTests.ValueTypesTest.SimpleStruct"); - CheckValueType(locals, "gs_local", "DebuggerTests.ValueTypesTest.GenericStruct"); - CheckObject(locals, "vt_local", "DebuggerTests.ValueTypesTest"); - } - ); + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + await CheckProps(locals, new + { + ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"), + gs_local = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + vt_local = TObject("DebuggerTests.ValueTypesTest") + }, "locals"); var dt = new DateTime(2021, 2, 3, 4, 6, 7); + var vt_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "vt_local"); + Assert.Equal(5, vt_local_props.Count()); + + CheckString(vt_local_props, "StringField", "string#0"); + CheckValueType(vt_local_props, "SimpleStructField", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckValueType(vt_local_props, "SimpleStructProperty", "DebuggerTests.ValueTypesTest.SimpleStruct"); + await CheckDateTime(vt_local_props, "DT", new DateTime(2020, 1, 2, 3, 4, 5)); + CheckEnum(vt_local_props, "RGB", "DebuggerTests.RGB", "Blue"); + // Check ss_local's properties var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); await CheckProps(ss_local_props, new { + V = TGetter("V"), str_member = TString("set in MethodWithLocalStructs#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Utc") + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") }, "ss_local"); { + var gres = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_local"), "V"); + await CheckValue(gres.Value["result"], TNumber(0xDEADBEEF + 2), $"ss_local#V"); // Check ss_local.dt await CheckDateTime(ss_local_props, "dt", dt); @@ -905,43 +918,30 @@ await insp.Ready(async(cli, token) => }, "gs_local"); // Check vt_local's properties - var vt_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "vt_local"); - Assert.Equal(5, vt_local_props.Count()); - CheckString(vt_local_props, "StringField", "string#0"); - CheckValueType(vt_local_props, "SimpleStructField", "DebuggerTests.ValueTypesTest.SimpleStruct"); - CheckValueType(vt_local_props, "SimpleStructProperty", "DebuggerTests.ValueTypesTest.SimpleStruct"); - await CheckDateTime(vt_local_props, "DT", new DateTime(2020, 1, 2, 3, 4, 5)); - CheckEnum(vt_local_props, "RGB", "DebuggerTests.RGB", "Blue"); + var exp = new[] + { + ("SimpleStructProperty", 2, "Utc"), + ("SimpleStructField", 5, "Local") + }; + foreach (var (name, bias, dt_kind) in exp) { - // SimpleStructProperty - dt = new DateTime(2022, 3, 4, 5, 7, 8); - var ssp_props = await CompareObjectPropertiesFor(vt_local_props, "SimpleStructProperty", + dt = new DateTime(2020 + bias, 1 + bias, 2 + bias, 3 + bias, 5 + bias, 6 + bias); + var ssp_props = await CompareObjectPropertiesFor(vt_local_props, name, new { - str_member = TString("SimpleStructProperty#string#0#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Utc") + V = TGetter("V"), + str_member = TString($"{name}#string#0#SimpleStruct#str_member"), + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", dt_kind) }, - label: "vt_local_props.SimpleStructProperty"); + label: $"vt_local_props.{name}"); await CheckDateTime(ssp_props, "dt", dt); - - // SimpleStructField - dt = new DateTime(2025, 6, 7, 8, 10, 11); - var ssf_props = await CompareObjectPropertiesFor(vt_local_props, "SimpleStructField", - new - { - str_member = TString("SimpleStructField#string#0#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Local") - }, - label: "vt_local_props.SimpleStructField"); - - await CheckDateTime(ssf_props, "dt", dt); + var gres = await InvokeGetter(GetAndAssertObjectWithName(vt_local_props, name), "V"); + await CheckValue(gres.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), $"{name}#V"); } // FIXME: check ss_local.gs.List's members @@ -968,20 +968,19 @@ await insp.Ready(async(cli, token) => var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:TestStructsAsMethodArgs'); }, 1);", - debugger_test_loc, 34, 12, "MethodWithStructArgs", - locals_fn: (locals) => - { - Assert.Equal(3, locals.Count()); - - CheckString(locals, "label", "TestStructsAsMethodArgs#label"); - CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); - CheckNumber(locals, "x", 3); - } - ); + debugger_test_loc, 34, 12, "MethodWithStructArgs"); + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + { + Assert.Equal(3, locals.Count()); + CheckString(locals, "label", "TestStructsAsMethodArgs#label"); + CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckNumber(locals, "x", 3); + } var dt = new DateTime(2025, 6, 7, 8, 10, 11); var ss_local_as_ss_arg = new { + V = TGetter("V"), str_member = TString("ss_local#SimpleStruct#string#0#SimpleStruct#str_member"), dt = TValueType("System.DateTime", dt.ToString()), gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), @@ -998,6 +997,9 @@ await insp.Ready(async(cli, token) => var ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg"); await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_arg"); + var res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V"); + await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), "ss_arg#V"); + { // Check ss_local.dt await CheckDateTime(ss_arg_props, "dt", dt); @@ -1007,19 +1009,19 @@ await insp.Ready(async(cli, token) => } pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 38, 8, "MethodWithStructArgs", times : 4, - locals_fn: (locals) => - { - Assert.Equal(3, locals.Count()); - - CheckString(locals, "label", "TestStructsAsMethodArgs#label"); - CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); - CheckNumber(locals, "x", 3); + locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); + locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + { + Assert.Equal(3, locals.Count()); - } - ); + CheckString(locals, "label", "TestStructsAsMethodArgs#label"); + CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct"); + CheckNumber(locals, "x", 3); + } var ss_arg_updated = new { + V = TGetter("V"), str_member = TString("ValueTypesTest#MethodWithStructArgs#updated#ss_arg#str_member"), dt = TValueType("System.DateTime", dt.ToString()), gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), @@ -1027,7 +1029,10 @@ await insp.Ready(async(cli, token) => }; ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg"); - await CheckProps(ss_arg_props, ss_arg_updated, "ss_ar"); + await CheckProps(ss_arg_props, ss_arg_updated, "ss_arg"); + + res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V"); + await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), "ss_arg#V"); { // Check ss_local.gs @@ -1059,7 +1064,7 @@ await insp.Ready(async(cli, token) => pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 28, 12, "TestStructsAsMethodArgs", times : 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new { ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"), @@ -1092,7 +1097,7 @@ await insp.Ready(async(cli, token) => ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 202, 205 }; + var lines = new [] { 203, 206 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1100,16 +1105,14 @@ await insp.Ready(async(cli, token) => "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeMembers'); }, 1);", debugger_test_loc, lines[0], 12, "MethodUpdatingValueTypeMembers"); - var dt = new DateTime(1, 2, 3, 4, 5, 6); - await CheckLocals(pause_location, dt); + await CheckLocals(pause_location, new DateTime(1, 2, 3, 4, 5, 6), new DateTime(4, 5, 6, 7, 8, 9)); // Resume - dt = new DateTime(9, 8, 7, 6, 5, 4); pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingValueTypeMembers"); - await CheckLocals(pause_location, dt); + await CheckLocals(pause_location, new DateTime(9, 8, 7, 6, 5, 4), new DateTime(5, 1, 3, 7, 9, 10)); }); - async Task CheckLocals(JToken pause_location, DateTime dt) + async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt) { var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new @@ -1122,20 +1125,20 @@ async Task CheckLocals(JToken pause_location, DateTime dt) { await CheckProps(obj_props, new { - DT = TValueType("System.DateTime", dt.ToString()) + DT = TValueType("System.DateTime", obj_dt.ToString()) }, "locals#obj.DT", num_fields : 5); - await CheckDateTime(obj_props, "DT", dt); + await CheckDateTime(obj_props, "DT", obj_dt); } - var vt_props = await GetObjectOnLocals(locals, "obj"); + var vt_props = await GetObjectOnLocals(locals, "vt"); { await CheckProps(vt_props, new { - DT = TValueType("System.DateTime", dt.ToString()) + DT = TValueType("System.DateTime", vt_dt.ToString()) }, "locals#obj.DT", num_fields : 5); - await CheckDateTime(vt_props, "DT", dt); + await CheckDateTime(vt_props, "DT", vt_dt); } } } @@ -1153,7 +1156,7 @@ await insp.Ready(async(cli, token) => ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 211, 213 }; + var lines = new [] { 212, 214 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1186,7 +1189,7 @@ await insp.Ready(async(cli, token) => ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 222, 224 }; + var lines = new [] { 223, 225 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1259,13 +1262,17 @@ await insp.Ready(async(cli, token) => var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); await CheckProps(ss_local_props, new { + V = TGetter("V"), str_member = TString("set in MethodWithLocalStructsStaticAsync#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Utc") + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") }, "ss_local"); { + var gres = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_local"), "V"); + await CheckValue(gres.Value["result"], TNumber(0xDEADBEEF + 2), $"ss_local#V"); + // Check ss_local.dt await CheckDateTime(ss_local_props, "dt", dt); @@ -1294,10 +1301,10 @@ await CompareObjectPropertiesFor(ss_local_props, "gs", } [Theory] - [InlineData(134, 12, "MethodWithLocalsForToStringTest", false, false)] - [InlineData(144, 12, "MethodWithArgumentsForToStringTest", true, false)] - [InlineData(189, 12, "MethodWithArgumentsForToStringTestAsync", true, true)] - [InlineData(179, 12, "MethodWithArgumentsForToStringTestAsync", false, true)] + [InlineData(135, 12, "MethodWithLocalsForToStringTest", false, false)] + [InlineData(145, 12, "MethodWithArgumentsForToStringTest", true, false)] + [InlineData(190, 12, "MethodWithArgumentsForToStringTestAsync", true, true)] + [InlineData(180, 12, "MethodWithArgumentsForToStringTestAsync", false, true)] public async Task InspectLocalsForToStringDescriptions(int line, int col, string method_name, bool call_other, bool invoke_async) { var insp = new Inspector(); @@ -1478,6 +1485,43 @@ await insp.Ready(async(cli, token) => }); } + [Fact] + public async Task InvalidValueTypeData() + { + await CheckInspectLocalsAtBreakpointSite( + "dotnet://debugger-test.dll/debugger-test.cs", 85, 8, + "OuterMethod", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:OuterMethod'); })", + wait_for_event_fn : async(pause_location) => + { + var new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 4 }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok : false); + + new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3 }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok : false); + + new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 'AA' }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok : false); + }); + + async Task CreateNewId(string expr) + { + var res = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = expr }), ctx.token); + Assert.True(res.IsOk, "Expected Runtime.evaluate to succeed"); + AssertEqual("string", res.Value["result"] ? ["type"]?.Value(), "Expected Runtime.evaluate to return a string type result"); + return res.Value["result"] ? ["value"]?.Value(); + } + + async Task _invoke_getter(string obj_id, string property_name, bool expect_ok) + { + var expr = $"MONO._invoke_getter ('{obj_id}', '{property_name}')"; + var res = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = expr }), ctx.token); + AssertEqual(expect_ok, res.IsOk, "Runtime.evaluate result not as expected for {expr}"); + + return res; + } + } + //TODO add tests covering basic stepping behavior as step in/out/over } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/tests/debugger-cfo-test.cs b/src/mono/wasm/debugger/tests/debugger-cfo-test.cs index ad3b12cf6c8f..6e885646bf00 100644 --- a/src/mono/wasm/debugger/tests/debugger-cfo-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-cfo-test.cs @@ -26,24 +26,32 @@ public static void LocalsTest(int len) public static void PropertyGettersTest() { - var ptd = new ClassWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9) }; - var swp = new StructWithProperties(); + var ptd = new ClassWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9), V = 0xDEADBEEF }; + var swp = new StructWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9), V = 0xDEADBEEF }; System.Console.WriteLine("break here"); } public static async System.Threading.Tasks.Task PropertyGettersTestAsync() { - var ptd = new ClassWithProperties { DTAutoProperty = new DateTime(4, 5, 6, 7, 8, 9) }; - var swp = new StructWithProperties(); + var ptd = new ClassWithProperties { DTAutoProperty = new DateTime (4, 5, 6, 7, 8, 9), V = 0xDEADBEEF }; + var swp = new StructWithProperties { DTAutoProperty = new DateTime (4, 5, 6, 7, 8, 9), V = 0xDEADBEEF }; System.Console.WriteLine("break here"); await System.Threading.Tasks.Task.CompletedTask; } + + public static void MethodForNegativeTests (string value = null) + { + var ptd = new ClassWithProperties { StringField = value }; + var swp = new StructWithProperties { StringField = value }; + Console.WriteLine("break here"); + } } class ClassWithProperties { - public int Int { get { return 5; } } - public string String { get { return "foobar"; } } + public uint V; + public uint Int { get { return V + (uint)DT.Month; } } + public string String { get { return $"String property, V: 0x{V:X}"; } } public DateTime DT { get { return new DateTime(3, 4, 5, 6, 7, 8); } } public int[] IntArray { get { return new int[] { 10, 20 }; } } @@ -54,11 +62,14 @@ class ClassWithProperties struct StructWithProperties { - public int Int { get { return 5; } } - public string String { get { return "foobar"; } } + public uint V; + public uint Int { get { return V + (uint)DT.Month; } } + public string String { get { return $"String property, V: 0x{V:X}"; } } public DateTime DT { get { return new DateTime(3, 4, 5, 6, 7, 8); } } public int[] IntArray { get { return new int[] { 10, 20 }; } } public DateTime[] DTArray { get { return new DateTime[] { new DateTime(6, 7, 8, 9, 10, 11), new DateTime(1, 2, 3, 4, 5, 6) }; } } + public DateTime DTAutoProperty { get; set; } + public string StringField; } } \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs b/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs index 3a4ceeaa48b8..7c372871eae1 100644 --- a/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-valuetypes-test.cs @@ -61,6 +61,7 @@ public static async Task MethodWithLocalStructsStaticAsync() public struct SimpleStruct { + public uint V { get { return 0xDEADBEEF + (uint)dt.Month; } set { } } public string str_member; public DateTime dt; public GenericStruct gs; diff --git a/src/mono/wasm/debugger/tests/other.js b/src/mono/wasm/debugger/tests/other.js index a1b121ee32bf..93532686914e 100644 --- a/src/mono/wasm/debugger/tests/other.js +++ b/src/mono/wasm/debugger/tests/other.js @@ -50,3 +50,16 @@ function exceptions_test () { exception_uncaught_test (); } +function negative_cfo_test (str_value = null) { + var ptd = { + get Int () { return 5; }, + get String () { return "foobar"; }, + get DT () { return "dt"; }, + get IntArray () { return [1,2,3]; }, + get DTArray () { return ["dt0", "dt1"]; }, + DTAutoProperty: "dt", + StringField: str_value + }; + console.log (`break here`); + return ptd; +} diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 5e1a1770897b..14e191e79cd1 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1,6 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +/** + * @typedef WasmId + * @type {object} + * @property {string} idStr - full object id string + * @property {string} scheme - eg, object, valuetype, array .. + * @property {string} value - string part after `dotnet:scheme:` of the id string + * @property {object} o - value parsed as JSON + */ + var MonoSupportLib = { $MONO__postset: 'MONO.export_functions (Module);', $MONO: { @@ -9,6 +18,10 @@ var MonoSupportLib = { _vt_stack: [], mono_wasm_runtime_is_ready : false, mono_wasm_ignore_pdb_load_errors: true, + + /** @type {object.} */ + _id_table: {}, + pump_message: function () { if (!this.mono_background_exec) this.mono_background_exec = Module.cwrap ("mono_background_exec", null); @@ -98,30 +111,19 @@ var MonoSupportLib = { }, _fixup_name_value_objects: function (var_list) { - var out_list = []; - - var _fixup_value = function (value) { - if (value != null && value != undefined) { - var descr = value.description; - if (descr == null || descr == undefined) - value.description = '' + value.value; - } - return value; - }; + let out_list = []; var i = 0; while (i < var_list.length) { - var o = var_list [i]; - var name = o.name; + let o = var_list [i]; + const name = o.name; if (name == null || name == undefined) { i ++; - o.value = _fixup_value(o.value); out_list.push (o); continue; } if (i + 1 < var_list.length) { - _fixup_value(var_list[i + 1].value); o = Object.assign (o, var_list [i + 1]); } @@ -133,8 +135,8 @@ var MonoSupportLib = { }, _filter_automatic_properties: function (props) { - var names_found = {}; - var final_var_list = []; + let names_found = {}; + let final_var_list = []; for (var i in props) { var p = props [i]; @@ -153,46 +155,116 @@ var MonoSupportLib = { return final_var_list; }, - // Given `dotnet:object:foo:bar`, - // returns [ 'dotnet', 'object', 'foo:bar'] - _split_object_id: function (id, delimiter = ':', count = 3) { - if (id === undefined || id == "") - return []; + /** Given `dotnet:object:foo:bar`, + * returns { scheme:'object', value: 'foo:bar' } + * + * Given `dotnet:pointer:{ b: 3 }` + * returns { scheme:'object', value: '{b:3}`, o: {b:3} + * + * @param {string} idStr + * @param {boolean} [throwOnError=false] + * + * @returns {WasmId} + */ + _parse_object_id: function (idStr, throwOnError = false) { + if (idStr === undefined || idStr == "" || !idStr.startsWith ('dotnet:')) { + if (throwOnError) + throw new Error (`Invalid id: ${idStr}`); + + return undefined; + } + + const [, scheme, ...rest] = idStr.split(':'); + let res = { + scheme, + value: rest.join (':'), + idStr, + o: {} + }; + + try { + res.o = JSON.parse(res.value); + // eslint-disable-next-line no-empty + } catch (e) {} - if (delimiter === undefined) delimiter = ':'; - if (count === undefined) count = 3; + return res; + }, + + /** + * @param {WasmId} id + * @returns {object[]} + */ + _get_vt_properties: function (id) { + let entry = this._id_table [id.idStr]; + if (entry !== undefined && entry.members !== undefined) + return entry.members; + + if (!isNaN (id.o.containerId)) + this._get_object_properties (id.o.containerId, true); + else if (!isNaN (id.o.arrayId)) + this._get_array_values (id, Number (id.o.arrayIdx), 1, true); + else + throw new Error (`Invalid valuetype id (${id.idStr}). Can't get properties for it.`); - var var_arr = id.split (delimiter); - var result = var_arr.splice (0, count - 1); + entry = this._get_id_props (id.idStr); + if (entry !== undefined && entry.members !== undefined) + return entry.members; - if (var_arr.length > 0) - result.push (var_arr.join (delimiter)); - return result; + throw new Error (`Unknown valuetype id: ${id.idStr}`); + }, + + /** + * + * @callback GetIdArgsCallback + * @param {object} var + * @param {number} idx + * @returns {object} + */ + + /** + * @param {object[]} vars + * @param {GetIdArgsCallback} getIdArgs + * @returns {object} + */ + _assign_vt_ids: function (vars, getIdArgs) + { + vars.forEach ((v, i) => { + // we might not have a `.value`, like in case of getters which have a `.get` instead + const value = v.value; + if (value === undefined || !value.isValueType) + return; + + if (value.objectId !== undefined) + throw new Error (`Bug: Trying to assign valuetype id, but the var already has one: ${v}`); + + value.objectId = this._new_or_add_id_props ({ scheme: 'valuetype', idArgs: getIdArgs (v, i), props: value._props }); + delete value._props; + }); + + return vars; }, // // @var_list: [ { index: , name: }, .. ] mono_wasm_get_variables: function(scope, var_list) { - if (!this.mono_wasm_get_var_info) - this.mono_wasm_get_var_info = Module.cwrap ("mono_wasm_get_var_info", null, [ 'number', 'number', 'number']); - - this.var_info = []; - var numBytes = var_list.length * Int32Array.BYTES_PER_ELEMENT; - var ptr = Module._malloc(numBytes); - var heapBytes = new Int32Array(Module.HEAP32.buffer, ptr, numBytes); + const numBytes = var_list.length * Int32Array.BYTES_PER_ELEMENT; + const ptr = Module._malloc(numBytes); + let heapBytes = new Int32Array(Module.HEAP32.buffer, ptr, numBytes); for (let i=0; i ({ containerId: this._async_method_objectId, fieldOffset: v.fieldOffset })); - var value = res[i].value; + for (let i in res) { + const res_name = res [i].name; if (this._async_method_objectId != 0) { //Async methods are special in the way that local variables can be lifted to generated class fields //value of "this" comes here either @@ -201,9 +273,6 @@ var MonoSupportLib = { // ALTHOUGH, the name wouldn't have `<>` for method args res [i].name = res_name.substring (1, res_name.indexOf ('>')); } - - if (value.isValueType) - value.objectId = `dotnet:valuetype:${this._async_method_objectId}:${res [i].fieldOffset}`; } else if (res_name === undefined && var_list [i] !== undefined) { // For non-async methods, we just have the var id, but we have the name // from the caller @@ -212,70 +281,49 @@ var MonoSupportLib = { } this._post_process_details(res); - this.var_info = [] - return res; }, - - mono_wasm_get_object_properties: function(objId, expandValueTypes) { - if (!this.mono_wasm_get_object_properties_info) - this.mono_wasm_get_object_properties_info = Module.cwrap ("mono_wasm_get_object_properties", null, [ 'number', 'bool' ]); - - this.var_info = []; - this.mono_wasm_get_object_properties_info (objId, expandValueTypes); - - var res = MONO._filter_automatic_properties (MONO._fixup_name_value_objects (this.var_info)); - for (var i = 0; i < res.length; i++) { - var res_val = res [i].value; - // we might not have a `.value`, like in case of getters which have a `.get` instead - if (res_val !== undefined && res_val.isValueType != undefined && res_val.isValueType) - res_val.objectId = `dotnet:valuetype:${objId}:${res [i].fieldOffset}`; - } - - this.var_info = []; + /** + * @param {number} idNum + * @param {boolean} expandValueTypes + * @returns {object} + */ + _get_object_properties: function(idNum, expandValueTypes) { + let { res_ok, res } = this.mono_wasm_get_object_properties_info (idNum, expandValueTypes); + if (!res_ok) + throw new Error (`Failed to get properties for ${idNum}`); + + res = MONO._filter_automatic_properties (res); + res = this._assign_vt_ids (res, v => ({ containerId: idNum, fieldOffset: v.fieldOffset })); + res = this._post_process_details (res); return res; }, - mono_wasm_get_array_values: function(objId) { - if (!this.mono_wasm_get_array_values_info) - this.mono_wasm_get_array_values_info = Module.cwrap ("mono_wasm_get_array_values", null, [ 'number' ]); - - this.var_info = []; - this.mono_wasm_get_array_values_info (objId); - - var res = MONO._fixup_name_value_objects (this.var_info); - for (var i = 0; i < res.length; i++) { - var prop_value = res [i].value; - if (prop_value.isValueType) { - res [i].value.objectId = `dotnet:array:${objId}:${i}`; - } else if (prop_value.objectId !== undefined && prop_value.objectId.startsWith("dotnet:pointer")) { - prop_value.objectId = this._get_updated_ptr_id (prop_value.objectId, { - varName: `[${i}]` - }); - } + /** + * @param {WasmId} id + * @param {number} [startIdx=0] + * @param {number} [count=-1] + * @param {boolean} [expandValueTypes=false] + * @returns {object[]} + */ + _get_array_values: function (id, startIdx = 0, count = -1, expandValueTypes = false) { + if (isNaN (id.o.arrayId) || isNaN (startIdx)) + throw new Error (`Invalid array id: ${id.idStr}`); + + let { res_ok, res } = this.mono_wasm_get_array_values_info (id.o.arrayId, startIdx, count, expandValueTypes); + if (!res_ok) + throw new Error (`Failed to get properties for array id ${id.idStr}`); + + res = this._assign_vt_ids (res, (_, i) => ({ arrayId: id.o.arrayId, arrayIdx: Number (startIdx) + i})); + + for (let i = 0; i < res.length; i ++) { + let value = res [i].value; + if (value.objectId !== undefined && value.objectId.startsWith("dotnet:pointer")) + this._new_or_add_id_props ({ objectId: value.objectId, props: { varName: `[${i}]` } }); } - - this.var_info = []; - - return res; - }, - - mono_wasm_get_array_value_expanded: function(objId, idx) { - if (!this.mono_wasm_get_array_value_expanded_info) - this.mono_wasm_get_array_value_expanded_info = Module.cwrap ("mono_wasm_get_array_value_expanded", null, [ 'number', 'number' ]); - - this.var_info = []; - this.mono_wasm_get_array_value_expanded_info (objId, idx); - - var res = MONO._fixup_name_value_objects (this.var_info); - // length should be exactly one! - if (res [0].value.isValueType != undefined && res [0].value.isValueType) - res [0].value.objectId = `dotnet:array:${objId}:${idx}`; - - this.var_info = []; - + res = this._post_process_details (res); return res; }, @@ -289,8 +337,13 @@ var MonoSupportLib = { return details; }, - _next_value_type_id: function () { - return ++this._next_value_type_id_var; + /** + * Gets the next id number to use for generating ids + * + * @returns {number} + */ + _next_id: function () { + return ++this._next_id_var; }, _extract_and_cache_value_types: function (var_list) { @@ -298,82 +351,46 @@ var MonoSupportLib = { return var_list; for (let i in var_list) { - var value = var_list [i].value; + let value = var_list [i].value; if (value === undefined) continue; if (value.objectId !== undefined && value.objectId.startsWith ("dotnet:pointer:")) { - var ptr_args = this._get_ptr_args (value.objectId); - if (ptr_args.varName === undefined) { - // It might have been already set in some cases, like arrays - // where the name would be `0`, but we want `[0]` for pointers, - // so the deref would look like `*[0]` - value.objectId = this._get_updated_ptr_id (value.objectId, { - varName: var_list [i].name - }); - } + let ptr_args = this._get_id_props (value.objectId); + if (ptr_args === undefined) + throw new Error (`Bug: Expected to find an entry for pointer id: ${value.objectId}`); + + // It might have been already set in some cases, like arrays + // where the name would be `0`, but we want `[0]` for pointers, + // so the deref would look like `*[0]` + ptr_args.varName = ptr_args.varName || var_list [i].name; } if (value.type != "object" || value.isValueType != true || value.expanded != true) // undefined would also give us false continue; // Generate objectId for expanded valuetypes - - var objectId = value.objectId; - if (objectId == undefined) - objectId = `dotnet:valuetype:${this._next_value_type_id ()}`; - value.objectId = objectId; + value.objectId = value.objectId || this._new_or_add_id_props ({ scheme: 'valuetype' }); this._extract_and_cache_value_types (value.members); - this._value_types_cache [objectId] = value.members; + const new_props = Object.assign ({ members: value.members }, value.__extra_vt_props); + + this._new_or_add_id_props ({ objectId: value.objectId, props: new_props }); delete value.members; + delete value.__extra_vt_props; } return var_list; }, - _get_details_for_value_type: function (objectId, fetchDetailsFn) { - if (objectId in this._value_types_cache) - return this._value_types_cache[objectId]; - - this._post_process_details (fetchDetailsFn()); - if (objectId in this._value_types_cache) - return this._value_types_cache[objectId]; - - // return error - throw new Error (`Could not get details for ${objectId}`); - }, - - _is_object_id_array: function (objectId) { - // Keep this in sync with `_get_array_details` - return (objectId.startsWith ('dotnet:array:') && objectId.split (':').length == 3); - }, - - _get_array_details: function (objectId, objectIdParts) { - // Keep this in sync with `_is_object_id_array` - switch (objectIdParts.length) { - case 3: - return this._post_process_details (this.mono_wasm_get_array_values(objectIdParts[2])); - - case 4: - var arrayObjectId = objectIdParts[2]; - var arrayIdx = objectIdParts[3]; - return this._get_details_for_value_type( - objectId, () => this.mono_wasm_get_array_value_expanded(arrayObjectId, arrayIdx)); - - default: - throw new Error (`object id format not supported : ${objectId}`); - } - }, - _get_cfo_res_details: function (objectId, args) { if (!(objectId in this._call_function_res_cache)) throw new Error(`Could not find any object with id ${objectId}`); - var real_obj = this._call_function_res_cache [objectId]; + const real_obj = this._call_function_res_cache [objectId]; - var descriptors = Object.getOwnPropertyDescriptors (real_obj); + const descriptors = Object.getOwnPropertyDescriptors (real_obj); if (args.accessorPropertiesOnly) { Object.keys (descriptors).forEach (k => { if (descriptors [k].get === undefined) @@ -381,10 +398,10 @@ var MonoSupportLib = { }); } - var res_details = []; + let res_details = []; Object.keys (descriptors).forEach (k => { - var new_obj; - var prop_desc = descriptors [k]; + let new_obj; + let prop_desc = descriptors [k]; if (typeof prop_desc.value == "object") { // convert `{value: { type='object', ... }}` // to `{ name: 'foo', value: { type='object', ... }} @@ -425,34 +442,77 @@ var MonoSupportLib = { return { __value_as_json_string__: JSON.stringify (res_details) }; }, - _get_ptr_args: function (objectId) { - var parts = this._split_object_id (objectId); - if (parts.length != 3) - throw new Error (`Bug: Unexpected objectId format for a pointer, expected 3 parts: ${objectId}`); - return JSON.parse (parts [2]); - }, + /** + * Generates a new id, and a corresponding entry for associated properties + * like `dotnet:pointer:{ a: 4 }` + * The third segment of that `{a:4}` is the idArgs parameter + * + * Only `scheme` or `objectId` can be set. + * if `scheme`, then a new id is generated, and it's properties set + * if `objectId`, then it's properties are updated + * + * @param {object} args + * @param {string} [args.scheme=undefined] scheme second part of `dotnet:pointer:..` + * @param {string} [args.objectId=undefined] objectId + * @param {object} [args.idArgs={}] The third segment of the objectId + * @param {object} [args.props={}] Properties for the generated id + * + * @returns {string} generated/updated id string + */ + _new_or_add_id_props: function ({ scheme = undefined, objectId = undefined, idArgs = {}, props = {} }) { + if (scheme === undefined && objectId === undefined) + throw new Error (`Either scheme or objectId must be given`); + + if (scheme !== undefined && objectId !== undefined) + throw new Error (`Both scheme, and objectId cannot be given`); + + if (objectId !== undefined && Object.entries (idArgs).length > 0) + throw new Error (`Both objectId, and idArgs cannot be given`); + + if (Object.entries (idArgs).length == 0) { + // We want to generate a new id, only if it doesn't have other + // attributes that it can use to uniquely identify. + // Eg, we don't do this for `dotnet:valuetype:{containerId:4, fieldOffset: 24}` + idArgs.num = this._next_id (); + } - _get_updated_ptr_id: function (objectId, new_args) { - var old_args = {}; - if (typeof (objectId) === 'string' && objectId.length) - old_args = this._get_ptr_args (objectId); + let idStr; + if (objectId !== undefined) { + idStr = objectId; + const old_props = this._id_table [idStr]; + if (old_props === undefined) + throw new Error (`ObjectId not found in the id table: ${idStr}`); - return `dotnet:pointer:${JSON.stringify ( Object.assign (old_args, new_args) )}`; + this._id_table [idStr] = Object.assign (old_props, props); + } else { + idStr = `dotnet:${scheme}:${JSON.stringify (idArgs)}`; + this._id_table [idStr] = props; + } + + return idStr; + }, + + /** + * @param {string} objectId + * @returns {object} + */ + _get_id_props: function (objectId) { + return this._id_table [objectId]; }, _get_deref_ptr_value: function (objectId) { - if (!this.mono_wasm_get_deref_ptr_value_info) - this.mono_wasm_get_deref_ptr_value_info = Module.cwrap("mono_wasm_get_deref_ptr_value", null, ['number', 'number']); + const ptr_args = this._get_id_props (objectId); + if (ptr_args === undefined) + throw new Error (`Unknown pointer id: ${objectId}`); - var ptr_args = this._get_ptr_args (objectId); if (ptr_args.ptr_addr == 0 || ptr_args.klass_addr == 0) throw new Error (`Both ptr_addr and klass_addr need to be non-zero, to dereference a pointer. objectId: ${objectId}`); - this.var_info = []; - var value_addr = new DataView (Module.HEAPU8.buffer).getUint32 (ptr_args.ptr_addr, /* littleEndian */ true); - this.mono_wasm_get_deref_ptr_value_info (value_addr, ptr_args.klass_addr); + const value_addr = new DataView (Module.HEAPU8.buffer).getUint32 (ptr_args.ptr_addr, /* littleEndian */ true); + let { res_ok, res } = this.mono_wasm_get_deref_ptr_value_info (value_addr, ptr_args.klass_addr); + if (!res_ok) + throw new Error (`Failed to dereference pointer ${objectId}`); - var res = MONO._fixup_name_value_objects(this.var_info); if (res.length > 0) { if (ptr_args.varName === undefined) throw new Error (`Bug: no varName found for the pointer. objectId: ${objectId}`); @@ -461,34 +521,25 @@ var MonoSupportLib = { } res = this._post_process_details (res); - this.var_info = []; return res; }, mono_wasm_get_details: function (objectId, args) { - var parts = objectId.split(":"); - if (parts[0] != "dotnet") - throw new Error ("Can't handle non-dotnet object ids. ObjectId: " + objectId); + let id = this._parse_object_id (objectId, true); - switch (parts[1]) { - case "object": - if (parts.length != 3) - throw new Error(`exception this time: Invalid object id format: ${objectId}`); + switch (id.scheme) { + case "object": { + if (isNaN (id.value)) + throw new Error (`Invalid objectId: ${objectId}. Expected a numeric id.`); - return this._post_process_details(this.mono_wasm_get_object_properties(parts[2], false)); + return this._get_object_properties(id.value, false); + } case "array": - return this._get_array_details(objectId, parts); + return this._get_array_values (id); case "valuetype": - if (parts.length != 3 && parts.length != 4) { - // dotnet:valuetype:vtid - // dotnet:valuetype:containerObjectId:vtId - throw new Error(`Invalid object id format: ${objectId}`); - } - - var containerObjectId = parts[2]; - return this._get_details_for_value_type(objectId, () => this.mono_wasm_get_object_properties(containerObjectId, true)); + return this._get_vt_properties(id); case "cfo_res": return this._get_cfo_res_details (objectId, args); @@ -503,7 +554,7 @@ var MonoSupportLib = { }, _cache_call_function_res: function (obj) { - var id = `dotnet:cfo_res:${this._next_call_function_res_id++}`; + const id = `dotnet:cfo_res:${this._next_call_function_res_id++}`; this._call_function_res_cache[id] = obj; return id; }, @@ -513,44 +564,69 @@ var MonoSupportLib = { delete this._cache_call_function_res[objectId]; }, - _invoke_getter_on_object: function (objectId, name) { - if (!this.mono_wasm_invoke_getter_on_object) - this.mono_wasm_invoke_getter_on_object = Module.cwrap ("mono_wasm_invoke_getter_on_object", 'void', [ 'number', 'string' ]); - - if (objectId < 0) { - // invalid id - return []; + /** + * @param {string} objectIdStr objectId + * @param {string} name property name + * @returns {object} return value + */ + _invoke_getter: function (objectIdStr, name) { + const id = this._parse_object_id (objectIdStr); + if (id === undefined) + throw new Error (`Invalid object id: ${objectIdStr}`); + + let getter_res; + if (id.scheme == 'object') { + if (isNaN (id.o) || id.o < 0) + throw new Error (`Invalid object id: ${objectIdStr}`); + + let { res_ok, res } = this.mono_wasm_invoke_getter_on_object_info (id.o, name); + if (!res_ok) + throw new Error (`Invoking getter on ${objectIdStr} failed`); + + getter_res = res; + } else if (id.scheme == 'valuetype') { + const id_props = this._get_id_props (objectIdStr); + if (id_props === undefined) + throw new Error (`Unknown valuetype id: ${objectIdStr}`); + + if (typeof id_props.value64 !== 'string' || isNaN (id_props.klass)) + throw new Error (`Bug: Cannot invoke getter on ${objectIdStr}, because of missing or invalid klass/value64 fields. idProps: ${JSON.stringify (id_props)}`); + + const dataPtr = Module._malloc (id_props.value64.length); + const dataHeap = new Uint8Array (Module.HEAPU8.buffer, dataPtr, id_props.value64.length); + dataHeap.set (new Uint8Array (this._base64_to_uint8 (id_props.value64))); + + let { res_ok, res } = this.mono_wasm_invoke_getter_on_value_info (dataHeap.byteOffset, id_props.klass, name); + Module._free (dataHeap.byteOffset); + + if (!res_ok) { + console.debug (`Invoking getter on valuetype ${objectIdStr}, with props: ${JSON.stringify (id_props)} failed`); + throw new Error (`Invoking getter on valuetype ${objectIdStr} failed`); + } + getter_res = res; + } else { + throw new Error (`Only object, and valuetypes supported for getters, id: ${objectIdStr}`); } - this.mono_wasm_invoke_getter_on_object (objectId, name); - var getter_res = MONO._post_process_details (MONO.var_info); - - MONO.var_info = []; - return getter_res [0]; + getter_res = MONO._post_process_details (getter_res); + return getter_res.length > 0 ? getter_res [0] : {}; }, _create_proxy_from_object_id: function (objectId) { - var details = this.mono_wasm_get_details(objectId); + const details = this.mono_wasm_get_details(objectId); - if (this._is_object_id_array (objectId)) + if (objectId.startsWith ('dotnet:array:')) return details.map (p => p.value); - var objIdParts = objectId.split (':'); - var objIdNum = -1; - if (objectId.startsWith ("dotnet:object:")) - objIdNum = objIdParts [2]; - - var proxy = {}; + let proxy = {}; Object.keys (details).forEach (p => { var prop = details [p]; if (prop.get !== undefined) { // TODO: `set` - // We don't add a `get` for non-object types right now, - // so, we shouldn't get here with objIdNum==-1 Object.defineProperty (proxy, prop.name, - { get () { return MONO._invoke_getter_on_object (objIdNum, prop.name); } } + { get () { return MONO._invoke_getter (objectId, prop.name); } } ); } else { proxy [prop.name] = prop.value; @@ -564,21 +640,27 @@ var MonoSupportLib = { if (request.arguments != undefined && !Array.isArray (request.arguments)) throw new Error (`"arguments" should be an array, but was ${request.arguments}`); - var objId = request.objectId; - var proxy; + const objId = request.objectId; + let proxy; - if (objId in this._call_function_res_cache) { - proxy = this._call_function_res_cache [objId]; - } else if (!objId.startsWith ('dotnet:cfo_res:')) { + if (objId.startsWith ('dotnet:cfo_res:')) { + if (objId in this._call_function_res_cache) + proxy = this._call_function_res_cache [objId]; + else + throw new Error (`Unknown object id ${objId}`); + } else { proxy = this._create_proxy_from_object_id (objId); } - var fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : []; - var fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`; + const fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : []; + const fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`; - var fn_res = eval (fn_eval_str); - if (fn_res == undefined) // should we just return undefined? - throw Error ('Function returned undefined result'); + const fn_res = eval (fn_eval_str); + if (fn_res === undefined) + return { type: "undefined" }; + + if (fn_res === null || (fn_res.subtype === 'null' && fn_res.value === undefined)) + return fn_res; // primitive type if (Object (fn_res) !== fn_res) @@ -591,7 +673,7 @@ var MonoSupportLib = { if (request.returnByValue) return {type: "object", value: fn_res}; - var fn_res_id = this._cache_call_function_res (fn_res); + const fn_res_id = this._cache_call_function_res (fn_res); if (Object.getPrototypeOf (fn_res) == Array.prototype) { return { type: "object", @@ -606,14 +688,14 @@ var MonoSupportLib = { }, _clear_per_step_state: function () { - this._next_value_type_id_var = 0; - this._value_types_cache = {}; + this._next_id_var = 0; + this._id_table = {}; }, mono_wasm_debugger_resume: function () { this._clear_per_step_state (); }, - + mono_wasm_start_single_stepping: function (kind) { console.log (">> mono_wasm_start_single_stepping " + kind); if (!this.mono_wasm_setup_single_step) @@ -639,6 +721,42 @@ var MonoSupportLib = { return this.mono_wasm_pause_on_exceptions (state_enum); }, + _register_c_fn: function (name, ...args) { + Object.defineProperty (this._c_fn_table, name + '_wrapper', { value: Module.cwrap (name, ...args) }); + }, + + /** + * Calls `Module.cwrap` for the function name, + * and creates a wrapper around it that returns + * `{ bool result, object var_info } + * + * @param {string} name C function name + * @param {string} ret_type + * @param {string[]} params + * + * @returns {void} + */ + _register_c_var_fn: function (name, ret_type, params) { + if (ret_type !== 'bool') + throw new Error (`Bug: Expected a C function signature that returns bool`); + + this._register_c_fn (name, ret_type, params); + Object.defineProperty (this, name + '_info', { + value: function (...args) { + MONO.var_info = []; + const res_ok = MONO._c_fn_table [name + '_wrapper'] (...args); + let res = MONO.var_info; + MONO.var_info = []; + if (res_ok) { + res = this._fixup_name_value_objects (res); + return { res_ok, res }; + } + + return { res_ok, res: undefined }; + } + }); + }, + mono_wasm_runtime_ready: function () { this.mono_wasm_runtime_is_ready = true; // DO NOT REMOVE - magic debugger init function @@ -649,6 +767,14 @@ var MonoSupportLib = { // FIXME: where should this go? this._next_call_function_res_id = 0; this._call_function_res_cache = {}; + + this._c_fn_table = {}; + this._register_c_var_fn ('mono_wasm_get_object_properties', 'bool', [ 'number', 'bool' ]); + this._register_c_var_fn ('mono_wasm_get_array_values', 'bool', [ 'number', 'number', 'number', 'bool' ]); + this._register_c_var_fn ('mono_wasm_invoke_getter_on_object', 'bool', [ 'number', 'string' ]); + this._register_c_var_fn ('mono_wasm_invoke_getter_on_value', 'bool', [ 'number', 'number', 'string' ]); + this._register_c_var_fn ('mono_wasm_get_local_vars', 'bool', [ 'number', 'number', 'number']); + this._register_c_var_fn ('mono_wasm_get_deref_ptr_value', 'bool', [ 'number', 'number']); }, mono_wasm_set_breakpoint: function (assembly, method_token, il_offset) { @@ -666,7 +792,7 @@ var MonoSupportLib = { }, // Set environment variable NAME to VALUE - // Should be called before mono_load_runtime_and_bcl () in most cases + // Should be called before mono_load_runtime_and_bcl () in most cases mono_wasm_setenv: function (name, value) { if (!this.wasm_setenv) this.wasm_setenv = Module.cwrap ('mono_wasm_setenv', null, ['string', 'string']); @@ -678,7 +804,7 @@ var MonoSupportLib = { this.wasm_parse_runtime_options = Module.cwrap ('mono_wasm_parse_runtime_options', null, ['number', 'number']); var argv = Module._malloc (options.length * 4); var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); - aindex = 0; + let aindex = 0; for (var i = 0; i < options.length; ++i) { Module.setValue (argv + (aindex * 4), wasm_strdup (options [i]), "i32"); aindex += 1; @@ -1155,7 +1281,7 @@ var MonoSupportLib = { mono_wasm_add_null_var: function(className) { - fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + let fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); if (!fixed_class_name) { // Eg, when a @className is passed from js itself, like // mono_wasm_add_null_var ("string") @@ -1179,12 +1305,13 @@ var MonoSupportLib = { value: { type: "string", value: var_value, + description: var_value } }); }, _mono_wasm_add_getter_var: function(className, invokable) { - fixed_class_name = MONO._mono_csharp_fixup_class_name (className); + const fixed_class_name = MONO._mono_csharp_fixup_class_name (className); if (invokable != 0) { var name; if (MONO.var_info.length > 0) @@ -1211,7 +1338,7 @@ var MonoSupportLib = { }, _mono_wasm_add_array_var: function(className, objectId, length) { - fixed_class_name = MONO._mono_csharp_fixup_class_name(className); + const fixed_class_name = MONO._mono_csharp_fixup_class_name(className); if (objectId == 0) { MONO.mono_wasm_add_null_var (fixed_class_name); return; @@ -1223,42 +1350,121 @@ var MonoSupportLib = { subtype: "array", className: fixed_class_name, description: `${fixed_class_name}(${length})`, - objectId: "dotnet:array:"+ objectId, + objectId: this._new_or_add_id_props ({ scheme: 'array', idArgs: { arrayId: objectId } }) } }); }, + // FIXME: improve + _base64_to_uint8: function (base64String) { + const byteCharacters = atob (base64String); + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + + return new Uint8Array (byteNumbers); + }, + + _begin_value_type_var: function(className, args) { + if (args === undefined || (typeof args !== 'object')) { + console.debug (`_begin_value_type_var: Expected an args object`); + return; + } + + const fixed_class_name = MONO._mono_csharp_fixup_class_name(className); + const toString = args.toString; + const base64String = btoa (String.fromCharCode (...new Uint8Array (Module.HEAPU8.buffer, args.value_addr, args.value_size))); + const vt_obj = { + value: { + type : "object", + className : fixed_class_name, + description : (toString == 0 ? fixed_class_name: Module.UTF8ToString (toString)), + expanded : true, + isValueType : true, + __extra_vt_props: { klass: args.klass, value64: base64String }, + members : [] + } + }; + if (MONO._vt_stack.length == 0) + MONO._old_var_info = MONO.var_info; + + MONO.var_info = vt_obj.value.members; + MONO._vt_stack.push (vt_obj); + }, + + _end_value_type_var: function() { + let top_vt_obj_popped = MONO._vt_stack.pop (); + top_vt_obj_popped.value.members = MONO._filter_automatic_properties ( + MONO._fixup_name_value_objects (top_vt_obj_popped.value.members)); + + if (MONO._vt_stack.length == 0) { + MONO.var_info = MONO._old_var_info; + MONO.var_info.push(top_vt_obj_popped); + } else { + var top_obj = MONO._vt_stack [MONO._vt_stack.length - 1]; + top_obj.value.members.push (top_vt_obj_popped); + MONO.var_info = top_obj.value.members; + } + }, + + _add_valuetype_unexpanded_var: function(className, args) { + if (args === undefined || (typeof args !== 'object')) { + console.debug (`_add_valuetype_unexpanded_var: Expected an args object`); + return; + } + + const fixed_class_name = MONO._mono_csharp_fixup_class_name (className); + const toString = args.toString; + + MONO.var_info.push ({ + value: { + type: "object", + className: fixed_class_name, + description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + isValueType: true + } + }); + }, + + mono_wasm_add_typed_value: function (type, str_value, value) { - var type_str = type; + let type_str = type; if (typeof type != 'string') type_str = Module.UTF8ToString (type); - if (typeof str_value != 'string') str_value = Module.UTF8ToString (str_value); switch (type_str) { - case "bool": + case "bool": { + const v = value != 0; MONO.var_info.push ({ value: { type: "boolean", - value: value != 0 + value: v, + description: v.toString () } }); break; + } - case "char": + case "char": { + const v = `${value} '${String.fromCharCode (value)}'`; MONO.var_info.push ({ value: { type: "symbol", - value: `${value} '${String.fromCharCode (value)}'` + value: v, + description: v } }); break; + } case "number": MONO.var_info.push ({ value: { type: "number", - value: value + value: value, + description: '' + value } }); break; @@ -1275,8 +1481,20 @@ var MonoSupportLib = { MONO._mono_wasm_add_array_var (str_value, value.objectId, value.length); break; + case "begin_vt": + MONO._begin_value_type_var (str_value, value); + break; + + case "end_vt": + MONO._end_value_type_var (); + break; + + case "unexpanded_vt": + MONO._add_valuetype_unexpanded_var (str_value, value); + break; + case "pointer": { - var fixed_value_str = MONO._mono_csharp_fixup_class_name (str_value); + const fixed_value_str = MONO._mono_csharp_fixup_class_name (str_value); if (value.klass_addr == 0 || value.ptr_addr == 0 || fixed_value_str.startsWith ('(void*')) { // null or void*, which we can't deref MONO.var_info.push({ @@ -1292,7 +1510,7 @@ var MonoSupportLib = { type: "object", className: fixed_value_str, description: fixed_value_str, - objectId: this._get_updated_ptr_id ('', value) + objectId: this._new_or_add_id_props ({ scheme: 'pointer', props: value }) } }); } @@ -1300,7 +1518,7 @@ var MonoSupportLib = { break; default: { - var msg = `'${str_value}' ${value}`; + const msg = `'${str_value}' ${value}`; MONO.var_info.push ({ value: { @@ -1390,55 +1608,6 @@ var MonoSupportLib = { MONO._async_method_objectId = objectId; }, - mono_wasm_begin_value_type_var: function(className, toString) { - fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); - var vt_obj = { - value: { - type: "object", - className: fixed_class_name, - description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), - // objectId will be generated by MonoProxy - expanded: true, - isValueType: true, - members: [] - } - }; - if (MONO._vt_stack.length == 0) - MONO._old_var_info = MONO.var_info; - - MONO.var_info = vt_obj.value.members; - MONO._vt_stack.push (vt_obj); - }, - - mono_wasm_end_value_type_var: function() { - var top_vt_obj_popped = MONO._vt_stack.pop (); - top_vt_obj_popped.value.members = MONO._filter_automatic_properties ( - MONO._fixup_name_value_objects (top_vt_obj_popped.value.members)); - - if (MONO._vt_stack.length == 0) { - MONO.var_info = MONO._old_var_info; - MONO.var_info.push(top_vt_obj_popped); - } else { - var top_obj = MONO._vt_stack [MONO._vt_stack.length - 1]; - top_obj.value.members.push (top_vt_obj_popped); - MONO.var_info = top_obj.value.members; - } - }, - - mono_wasm_add_value_type_unexpanded_var: function (className, toString) { - fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); - MONO.var_info.push({ - value: { - type: "object", - className: fixed_class_name, - description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), - // objectId added when enumerating object's properties - expanded: false, - isValueType: true - } - }); - }, - mono_wasm_add_enum_var: function(className, members, value) { // FIXME: flags // @@ -1446,13 +1615,13 @@ var MonoSupportLib = { // group0: Monday:0 // group1: Monday // group2: 0 - var re = new RegExp (`[,]?([^,:]+):(${value}(?=,)|${value}$)`, 'g') - var members_str = Module.UTF8ToString (members); + const re = new RegExp (`[,]?([^,:]+):(${value}(?=,)|${value}$)`, 'g') + const members_str = Module.UTF8ToString (members); - var match = re.exec(members_str); - var member_name = match == null ? ('' + value) : match [1]; + const match = re.exec(members_str); + const member_name = match == null ? ('' + value) : match [1]; - fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + const fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); MONO.var_info.push({ value: { type: "object", @@ -1475,7 +1644,7 @@ var MonoSupportLib = { return; } - fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + const fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); MONO.var_info.push({ value: { type: "object", @@ -1512,11 +1681,11 @@ var MonoSupportLib = { return `${ret_sig} ${method_name} (${args_sig})`; } - var tgt_sig; + let tgt_sig; if (targetName != 0) tgt_sig = args_to_sig (Module.UTF8ToString (targetName)); - var type_name = MONO._mono_csharp_fixup_class_name (Module.UTF8ToString (className)); + const type_name = MONO._mono_csharp_fixup_class_name (Module.UTF8ToString (className)); if (objectId == -1) { // Target property @@ -1586,6 +1755,7 @@ var MonoSupportLib = { mono_wasm_fire_bp: function () { console.log ("mono_wasm_fire_bp"); + // eslint-disable-next-line no-debugger debugger; }, From ff01831094128fb9df0be61fd0e352bbcaeddf02 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sun, 9 Aug 2020 18:46:16 -0700 Subject: [PATCH 354/755] make ssl tests more portable (#40303) * make ssl tests more portable * feedback from review * fix build * fix http broken by one previous commits * feedback from review * fix tests with old ssl versions.S * more ssl fixes --- .../HttpClientHandlerTest.SslProtocols.cs | 38 +++++-------- .../tests/System/Net/SslProtocolSupport.cs | 26 +++++++-- .../TestUtilities/System/PlatformDetection.cs | 2 + ...ttp.WinHttpHandler.Functional.Tests.csproj | 4 +- .../System.Net.Http.Functional.Tests.csproj | 4 +- .../SslStreamNetworkStreamTest.cs | 28 ++++++++-- .../SslStreamSystemDefaultsTest.cs | 54 ++++++++++++++----- .../FunctionalTests/TransportContextTest.cs | 2 +- 8 files changed, 110 insertions(+), 48 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index 92845c1a4747..65342bf3d631 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -80,33 +80,19 @@ public static IEnumerable GetAsync_AllowedSSLVersion_Succeeds_MemberDa { // These protocols are all enabled by default, so we can connect with them both when // explicitly specifying it in the client and when not. - foreach (SslProtocols protocol in new[] { SslProtocols.Tls, SslProtocols.Tls11, SslProtocols.Tls12 }) + foreach (SslProtocols protocol in Enum.GetValues(typeof(SslProtocols))) { - yield return new object[] { protocol, false }; - yield return new object[] { protocol, true }; - } - - // These protocols are disabled by default, so we can only connect with them explicitly. - // On certain platforms these are completely disabled and cannot be used at all. -#pragma warning disable 0618 - if (PlatformDetection.SupportsSsl3) - { -#if !NETFRAMEWORK - yield return new object[] { SslProtocols.Ssl3, true }; -#endif - } - if (PlatformDetection.IsWindows && !PlatformDetection.IsWindows10Version1607OrGreater) - { - yield return new object[] { SslProtocols.Ssl2, true }; - } + if (protocol != SslProtocols.None && (protocol & SslProtocolSupport.SupportedSslProtocols) == protocol) + { + yield return new object[] { protocol, true }; +#pragma warning disable 0618 // SSL2/3 are deprecated + // On certain platforms these are completely disabled and cannot be used at all. + if (protocol != SslProtocols.Ssl2 && protocol != SslProtocols.Ssl3) + { + yield return new object[] { protocol, false }; + } #pragma warning restore 0618 - // These protocols are new, and might not be enabled everywhere yet - if (PlatformDetection.IsUbuntu1810OrHigher) - { -#if !NETFRAMEWORK - yield return new object[] { SslProtocols.Tls13, false }; - yield return new object[] { SslProtocols.Tls13, true }; -#endif + } } } @@ -129,11 +115,13 @@ public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProto // restrictions on minimum TLS/SSL version // We currently know that some platforms like Debian 10 OpenSSL // will by default block < TLS 1.2 +#pragma warning disable 0618 // SSL2/3 are deprecated #if !NETFRAMEWORK handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13; #else handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; #endif +#pragma warning restore 0618 } var options = new LoopbackServer.Options { UseSsl = true, SslProtocols = acceptedProtocol }; diff --git a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs index de9f3818e11e..78ae108471dd 100644 --- a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs +++ b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Authentication; @@ -16,24 +17,41 @@ public class SslProtocolSupport #endif SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; + public const SslProtocols NonTls13Protocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; + public static SslProtocols SupportedSslProtocols { get { - SslProtocols supported = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; + SslProtocols supported = SslProtocols.None; #pragma warning disable 0618 // SSL2/3 are deprecated if (PlatformDetection.SupportsSsl3) { supported |= SslProtocols.Ssl3; } #pragma warning restore 0618 + if (PlatformDetection.SupportsTls10) + { + supported |= SslProtocols.Tls; + } + + if (PlatformDetection.SupportsTls11) + { + supported |= SslProtocols.Tls11; + } + + if (PlatformDetection.SupportsTls12) + { + supported |= SslProtocols.Tls12; + } #if !NETSTANDARD2_0 - // TLS 1.3 is new - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion >= new Version(1, 1, 1)) + if (PlatformDetection.SupportsTls13) { supported |= SslProtocols.Tls13; } #endif + Debug.Assert(SslProtocols.None != supported); + return supported; } } @@ -44,7 +62,7 @@ public IEnumerator GetEnumerator() { foreach (SslProtocols protocol in Enum.GetValues(typeof(SslProtocols))) { - if (protocol != 0 && (protocol & SupportedSslProtocols) == protocol) + if (protocol != SslProtocols.None && (protocol & SupportedSslProtocols) == protocol) { yield return new object[] { protocol }; } diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 6d5811e10140..3db016a56c9c 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -127,6 +127,8 @@ 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 SupportsTls10 => !IsDebian10; public static bool SupportsTls11 => !IsWindows7 && !IsDebian10; public static bool SupportsTls12 => !IsWindows7; // OpenSSL 1.1.1 and above. diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj index 1d0dceca18b3..48ed90347107 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj @@ -117,6 +117,8 @@ Link="Common\System\Net\Http\LoopbackServer.cs" /> + - \ No newline at end of file + diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index 2c97dd43097e..9a5928a025eb 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -132,6 +132,8 @@ Link="Common\System\Net\Http\GenericLoopbackServer.cs" /> + - \ No newline at end of file + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index 3b77a45122b2..28cb9233b638 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -8,6 +8,7 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Net.Security.Tests @@ -83,10 +84,31 @@ public async Task SslStream_SendReceiveOverNetworkStream_Ok() listener.Stop(); } - [Fact] + [ConditionalFact] [PlatformSpecific(TestPlatforms.Linux)] // This only applies where OpenSsl is used. public async Task SslStream_SendReceiveOverNetworkStream_AuthenticationException() { + SslProtocols clientProtocol; + SslProtocols serverProtocol; + + // Try to find protocol mismatch. + if (PlatformDetection.SupportsTls12 && (PlatformDetection.SupportsTls10 || PlatformDetection.SupportsTls11)) + { + // OpenSSL 1.0 where new is Tls12 + clientProtocol = SslProtocols.Tls | SslProtocols.Tls11; + serverProtocol = SslProtocols.Tls12; + } + else if (PlatformDetection.SupportsTls12 && PlatformDetection.SupportsTls13) + { + // OpenSSl 1.1 where new is 1.3 and legacy is 1.2 + clientProtocol = SslProtocols.Tls13; + serverProtocol = SslProtocols.Tls12; + } + else + { + throw new SkipTestException("Did not find disjoined sets"); + } + TcpListener listener = new TcpListener(IPAddress.Loopback, 0); using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate()) @@ -117,13 +139,13 @@ public async Task SslStream_SendReceiveOverNetworkStream_AuthenticationException Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync( serverCertificate.GetNameInfo(X509NameType.SimpleName, false), null, - SslProtocols.Tls11, + clientProtocol, false); AuthenticationException e = await Assert.ThrowsAsync(() => serverStream.AuthenticateAsServerAsync( serverCertificate, false, - SslProtocols.Tls12, + serverProtocol, false)); Assert.NotNull(e.InnerException); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs index 58f54b9ecc3b..4136320067cd 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.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.Collections.Generic; using System.IO; using System.Net.Http; using System.Net.Test.Common; @@ -31,21 +32,48 @@ public SslStreamSystemDefaultTest() protected abstract Task AuthenticateClientAsync(string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation, SslProtocols? protocols = null); protected abstract Task AuthenticateServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation, SslProtocols? protocols = null); - [ConditionalTheory(nameof(IsNotWindows7))] - [InlineData(null, null)] - [InlineData(SslProtocols.None, null)] - [InlineData(null, SslProtocols.None)] - [InlineData(SslProtocols.None, SslProtocols.None)] - [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Tls11)] - [InlineData(SslProtocols.Tls11, NegotiatedCipherSuiteTest.NonTls13Protocols)] - [InlineData(null, SslProtocols.Tls12)] - [InlineData(SslProtocols.Tls12, null)] - [InlineData(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, null)] - [InlineData(null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12)] + public static IEnumerable OneOrBothUseDefaulData() + { + yield return new object[] { null, null }; + yield return new object[] { SslProtocols.None, null }; + yield return new object[] { null, SslProtocols.None }; + yield return new object[] { SslProtocols.None, SslProtocols.None }; #pragma warning disable 0618 - [InlineData(SslProtocols.Default, NegotiatedCipherSuiteTest.NonTls13Protocols)] - [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Default)] + if (PlatformDetection.SupportsTls10) + { + // Default only has Ssl3 and Tls1.0 for legacy reasons. + yield return new object[] { SslProtocols.Default, SslProtocolSupport.NonTls13Protocols }; + yield return new object[] { SslProtocolSupport.NonTls13Protocols, SslProtocols.Default }; + } + #pragma warning restore 0618 + if (PlatformDetection.SupportsTls11) + { + yield return new object[] { SslProtocolSupport.NonTls13Protocols, SslProtocols.Tls11 }; + yield return new object[] { SslProtocols.Tls11, SslProtocolSupport.NonTls13Protocols }; + } + + if (PlatformDetection.SupportsTls12) + { + yield return new object[] { null, SslProtocols.Tls12 }; + yield return new object[] { SslProtocols.Tls12, null }; + } + + if (PlatformDetection.SupportsTls13) + { + yield return new object[] { null, SslProtocols.Tls13 }; + yield return new object[] { SslProtocols.Tls13, null }; + } + + if ((SslProtocolSupport.SupportedSslProtocols & SslProtocolSupport.NonTls13Protocols) != 0) + { + yield return new object[] { SslProtocolSupport.NonTls13Protocols, null }; + yield return new object[] { null, SslProtocolSupport.NonTls13Protocols }; + } + } + + [ConditionalTheory] + [MemberData(nameof(OneOrBothUseDefaulData))] public async Task ClientAndServer_OneOrBothUseDefault_Ok(SslProtocols? clientProtocols, SslProtocols? serverProtocols) { using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate()) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs index fb0fc5ab18c8..17b91a5cd73d 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs @@ -35,7 +35,7 @@ public async Task TransportContext_ConnectToServerWithSsl_GetExpectedChannelBind using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls, false); + await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false); TransportContext context = sslStream.TransportContext; CheckTransportContext(context); From 7e097944639c8a791453751bc4f09153c286c964 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Sun, 9 Aug 2020 20:00:59 -0700 Subject: [PATCH 355/755] check for Null returned from Assembly.GetEntryAssembly (#40598) Fixes 40588 --- .../src/System/Xml/Serialization/Compilation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs index fe7d84f63bd4..67ce05acdec2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs @@ -163,7 +163,7 @@ internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespac serializerPath = Path.Combine(Path.GetDirectoryName(type.Assembly.Location), serializerName + ".dll"); } - if ((string.IsNullOrEmpty(serializerPath) || !File.Exists(serializerPath)) && !string.IsNullOrEmpty(Assembly.GetEntryAssembly().Location)) + if ((string.IsNullOrEmpty(serializerPath) || !File.Exists(serializerPath)) && !string.IsNullOrEmpty(Assembly.GetEntryAssembly()?.Location)) { serializerPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), serializerName + ".dll"); } From 3b4f708fe2e6ddd2f6bc38ccd81c6c4a98f13fbc Mon Sep 17 00:00:00 2001 From: SUN Guoyun <40024232+sunny868@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:20:04 +0800 Subject: [PATCH 356/755] Redefine signal for architecture mips (#40513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit define SIGSTOP 19 is just ok for architecture x86、arm、s390、powerpc and so on. but others architecture has different values. Co-authored-by: Sunguoyun Co-authored-by: hev Co-authored-by: Jan Kotas --- src/libraries/Native/Unix/CMakeLists.txt | 3 +++ .../Native/Unix/System.Native/pal_process.c | 22 +++++++++++++++++-- .../Native/Unix/System.Native/pal_process.h | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 3168c7e55c83..a4f8970239d1 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -64,6 +64,9 @@ elseif (CLR_CMAKE_TARGET_ARCH_WASM) elseif (CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DTARGET_64BIT=1) add_definitions(-DTARGET_ARM64) +elseif (CLR_CMAKE_TARGET_ARCH_MIPS64) + add_definitions(-DTARGET_64BIT=1) + add_definitions(-DTARGET_MIPS64) elseif (CLR_CMAKE_TARGET_ARCH_ARM) add_definitions(-DTARGET_32BIT=1) add_definitions(-DTARGET_ARM) diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index 6d86efe48190..44cb59d4c1a2 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -28,8 +28,6 @@ #include #endif -// Validate that our Signals enum values are correct for the platform -c_static_assert(PAL_SIGKILL == SIGKILL); // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); @@ -653,6 +651,26 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit int32_t SystemNative_Kill(int32_t pid, int32_t signal) { + switch (signal) + { + case PAL_NONE: + signal = 0; + break; + + case PAL_SIGKILL: + signal = SIGKILL; + break; + + case PAL_SIGSTOP: + signal = SIGSTOP; + break; + + default: + assert_msg(false, "Unknown signal", signal); + errno = EINVAL; + return -1; + } + return kill(pid, signal); } diff --git a/src/libraries/Native/Unix/System.Native/pal_process.h b/src/libraries/Native/Unix/System.Native/pal_process.h index 92eaf66e1dbc..49d5b85553c5 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.h +++ b/src/libraries/Native/Unix/System.Native/pal_process.h @@ -72,7 +72,9 @@ typedef enum typedef enum { + PAL_NONE = 0, PAL_SIGKILL = 9, /* kill the specified process */ + PAL_SIGSTOP = 19, } Signals; /** From 4ec3a25cfa9555d5ec07ec6ab2c8db98ad0489c8 Mon Sep 17 00:00:00 2001 From: Key Kim Date: Mon, 10 Aug 2020 12:40:09 +0900 Subject: [PATCH 357/755] Fix typo in docs/workflow/building/libraries (#40600) build command does not exist, it should be build.cmd --- docs/workflow/building/libraries/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md index ec0f52388e69..84daa4a51462 100644 --- a/docs/workflow/building/libraries/README.md +++ b/docs/workflow/building/libraries/README.md @@ -9,11 +9,11 @@ Here is one example of a daily workflow for a developer working mainly on the li git clean -xdf git pull upstream master & git push origin master :: Build Debug libraries on top of Release runtime: -build clr+libs -rc Release +build.cmd clr+libs -rc Release :: The above you may only perform once in a day, or when you pull down significant new changes. :: If you use Visual Studio, you might open System.Text.RegularExpressions.sln here. -build -vs System.Text.RegularExpressions +build.cmd -vs System.Text.RegularExpressions :: Switch to working on a given library (RegularExpressions in this case) cd src\libraries\System.Text.RegularExpressions From fb18a11af37209018899ed31470bd639fb9fc9b6 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Mon, 10 Aug 2020 13:05:30 +0200 Subject: [PATCH 358/755] Use new OS checks in src (#40520) * use new OperatingSystem APIs in System.Net.Ping and remove dependency from System.Runtime.InteropServices.RuntimeInformation * use new OperatingSystem APIs in System.Security.Cryptography.Algorithms * use new OperatingSystem APIs in System.ComponentModel.Composition and improve perf.. * use new OperatingSystem APIs in System.Net.Http and remove dependency from System.Runtime.InteropServices.RuntimeInformation * Apply suggestions from code review * there is no need to cache the results anymore --- .../CommandLineUtils/Utilities/DotNetMuxer.cs | 3 +-- .../Quic/Interop/MsQuicStatusCodes.cs | 14 ++++---------- .../Quic/Interop/MsQuicStatusHelper.cs | 6 ++---- .../NetworkInformation/UnixCommandLinePing.cs | 11 ++++------- .../Composition/Hosting/DirectoryCatalog.cs | 17 +++++++++++++++-- .../System.Net.Http/src/System.Net.Http.csproj | 1 - .../System.Net.Ping/src/System.Net.Ping.csproj | 1 - .../System/Net/NetworkInformation/Ping.Unix.cs | 12 ++++++------ .../Security/Cryptography/CryptoConfig.cs | 2 +- 9 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/libraries/Common/src/Extensions/CommandLineUtils/Utilities/DotNetMuxer.cs b/src/libraries/Common/src/Extensions/CommandLineUtils/Utilities/DotNetMuxer.cs index 1d13ec2d3ed2..8892852e17bc 100644 --- a/src/libraries/Common/src/Extensions/CommandLineUtils/Utilities/DotNetMuxer.cs +++ b/src/libraries/Common/src/Extensions/CommandLineUtils/Utilities/DotNetMuxer.cs @@ -7,7 +7,6 @@ using System; using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; namespace Microsoft.Extensions.CommandLineUtils { @@ -39,7 +38,7 @@ public static string MuxerPathOrDefault() private static string TryFindMuxerPath() { var fileName = MuxerName; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { fileName += ".exe"; } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusCodes.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusCodes.cs index face87e41f91..af7fd3030064 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusCodes.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusCodes.cs @@ -1,22 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; - namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class MsQuicStatusCodes { - internal static readonly uint Success = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.Success : Linux.Success; - internal static readonly uint Pending = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.Pending : Linux.Pending; - internal static readonly uint InternalError = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.InternalError : Linux.InternalError; + internal static uint Success => OperatingSystem.IsWindows() ? Windows.Success : Linux.Success; + internal static uint Pending => OperatingSystem.IsWindows() ? Windows.Pending : Linux.Pending; + internal static uint InternalError => OperatingSystem.IsWindows() ? Windows.InternalError : Linux.InternalError; // TODO return better error messages here. - public static string GetError(uint status) - { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? Windows.GetError(status) : Linux.GetError(status); - } + public static string GetError(uint status) => OperatingSystem.IsWindows() ? Windows.GetError(status) : Linux.GetError(status); private static class Windows { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusHelper.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusHelper.cs index 726a548c59e8..2f64fa241582 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusHelper.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicStatusHelper.cs @@ -1,20 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; - namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class MsQuicStatusHelper { internal static bool SuccessfulStatusCode(uint status) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { return status < 0x80000000; } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (OperatingSystem.IsLinux()) { return (int)status <= 0; } diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs index 24063dccb005..98db97f3106e 100644 --- a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs +++ b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs @@ -4,7 +4,6 @@ #nullable enable using System.Globalization; using System.IO; -using System.Runtime.InteropServices; using System.Text; namespace System.Net.NetworkInformation @@ -18,8 +17,6 @@ internal static class UnixCommandLinePing private static readonly string? s_discoveredPing4UtilityPath = GetPingUtilityPath(ipv4: true); private static readonly string? s_discoveredPing6UtilityPath = GetPingUtilityPath(ipv4: false); - private static readonly bool s_isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - private static readonly bool s_isBSD = RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD); private static readonly Lazy s_isBusybox = new Lazy(() => IsBusyboxPing(s_discoveredPing4UtilityPath)); // We don't want to pick up an arbitrary or malicious ping @@ -92,7 +89,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad // FreeBSD: ping requires -W flag which accepts timeout in MILLISECONDS; // ping6 requires -x which accepts timeout in MILLISECONDS // OSX: ping requires -W flag which accepts timeout in MILLISECONDS; ping6 doesn't support timeout - if (s_isBSD) + if (OperatingSystem.IsFreeBSD()) { if (ipv4) { @@ -103,7 +100,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad sb.Append(" -x "); } } - else if (s_isOSX) + else if (OperatingSystem.IsMacOS()) { if (ipv4) { @@ -136,7 +133,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad if (ttl > 0) { - if (s_isBSD | s_isOSX) + if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS()) { // OSX and FreeBSD use -h to set hop limit for IPv6 and -m ttl for IPv4 if (ipv4) @@ -159,7 +156,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad if (fragmentOption != PingFragmentOptions.Default) { - if (s_isBSD | s_isOSX) + if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS()) { // The bit is off by default on OSX & FreeBSD if (fragmentOption == PingFragmentOptions.Dont) { diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs index 0b9c5d24aad2..7088f00aba17 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs @@ -21,6 +21,13 @@ namespace System.ComponentModel.Composition.Hosting [DebuggerTypeProxy(typeof(DirectoryCatalogDebuggerProxy))] public partial class DirectoryCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged, ICompositionElement { + private static bool IsWindows => +#if NETSTANDARD || NETCOREAPP2_0 + RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#else + OperatingSystem.IsWindows(); +#endif + private readonly Lock _thisLock = new Lock(); private readonly ICompositionElement? _definitionOrigin; private ComposablePartCatalogCollection _catalogCollection; @@ -736,13 +743,19 @@ private string GetDisplayName() private string[] GetFiles() { string[] files = Directory.GetFiles(_fullPath, _searchPattern); - return Array.ConvertAll(files, (file) => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? file.ToUpperInvariant() : file); + + if (!IsWindows) + { + return files; + } + + return Array.ConvertAll(files, (file) => file.ToUpperInvariant()); } private static string GetFullPath(string path) { var fullPath = IOPath.GetFullPath(path); - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? fullPath.ToUpperInvariant() : fullPath; + return IsWindows ? fullPath.ToUpperInvariant() : fullPath; } [MemberNotNull(nameof(_path))] 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 420af9b298b7..9e69e1186bc4 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -695,7 +695,6 @@ - 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 b817ebac3ef9..fa5e3e72a7b6 100644 --- a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj +++ b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj @@ -104,6 +104,5 @@ - diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs index 0086acc03f3e..44ac5729415f 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs @@ -18,8 +18,8 @@ public partial class Ping private const int IcmpHeaderLengthInBytes = 8; private const int MinIpHeaderLengthInBytes = 20; private const int MaxIpHeaderLengthInBytes = 60; - private static readonly bool _sendIpHeader = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - private static readonly bool _needsConnect = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + private static bool SendIpHeader => OperatingSystem.IsMacOS(); + private static bool NeedsConnect => OperatingSystem.IsLinux(); [ThreadStatic] private static Random? t_idGenerator; @@ -56,7 +56,7 @@ private unsafe SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, in IpHeader iph = default; bool ipv4 = address.AddressFamily == AddressFamily.InterNetwork; - bool sendIpHeader = ipv4 && options != null && _sendIpHeader; + bool sendIpHeader = ipv4 && options != null && SendIpHeader; if (sendIpHeader) { @@ -91,7 +91,7 @@ private Socket GetRawSocket(SocketConfig socketConfig) Socket socket = new Socket(addrFamily, SocketType.Raw, socketConfig.ProtocolType); socket.ReceiveTimeout = socketConfig.Timeout; socket.SendTimeout = socketConfig.Timeout; - if (addrFamily == AddressFamily.InterNetworkV6 && RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (addrFamily == AddressFamily.InterNetworkV6 && OperatingSystem.IsMacOS()) { socket.DualMode = false; } @@ -103,7 +103,7 @@ private Socket GetRawSocket(SocketConfig socketConfig) if (socketConfig.Options != null && addrFamily == AddressFamily.InterNetwork) { - if (_sendIpHeader) + if (SendIpHeader) { // some platforms like OSX don't support DontFragment so we construct IP header instead. socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1); @@ -117,7 +117,7 @@ private Socket GetRawSocket(SocketConfig socketConfig) #pragma warning disable 618 // Disable warning about obsolete property. We could use GetAddressBytes but that allocates. // IPv4 multicast address starts with 1110 bits so mask rest and test if we get correct value e.g. 0xe0. - if (_needsConnect && !ep.Address.IsIPv6Multicast && !(addrFamily == AddressFamily.InterNetwork && (ep.Address.Address & 0xf0) == 0xe0)) + if (NeedsConnect && !ep.Address.IsIPv6Multicast && !(addrFamily == AddressFamily.InterNetwork && (ep.Address.Address & 0xf0) == 0xe0)) { // If it is not multicast, use Connect to scope responses only to the target address. socket.Connect(socketConfig.EndPoint); diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs index f82f7828b481..a1aea6e932dd 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs @@ -188,7 +188,7 @@ private static Dictionary DefaultNameHT ht.Add("System.Security.Cryptography.DSA", DSACryptoServiceProviderType); // Windows will register the public ECDsaCng type. Non-Windows gets a special handler. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { ht.Add(ECDsaIdentifier, ECDsaCngType); } From 7281349206c09e0098ae0e4184f2b46225f85b1e Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 10 Aug 2020 08:31:04 -0400 Subject: [PATCH 359/755] [aot] Fix the handling of r4/r8 parameter types with attributes during generic sharing. (#40498) The attributes need to be ignored as with the other types, otherwise gsharedvt wrappers for signatures with parameters like double f = default will not be found. Fixes https://github.com/mono/mono/issues/20195. Co-authored-by: vargaz --- src/mono/mono/mini/mini-generic-sharing.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 5fb8bbb39c96..86f7066ec59d 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1276,6 +1276,10 @@ get_wrapper_shared_type_full (MonoType *t, gboolean is_field) #else return m_class_get_byval_arg (mono_defaults.uint32_class); #endif + case MONO_TYPE_R4: + return m_class_get_byval_arg (mono_defaults.single_class); + case MONO_TYPE_R8: + return m_class_get_byval_arg (mono_defaults.double_class); case MONO_TYPE_OBJECT: case MONO_TYPE_CLASS: case MONO_TYPE_SZARRAY: From 1ec6939facb0fc51b989f368816d0df29be285ed Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Mon, 10 Aug 2020 09:43:39 -0400 Subject: [PATCH 360/755] Support extra compiler flags during building (#39191) Many Linux distributions like to use an extra set of compiler flags (via `CFLAGS`, `CXXFLAGS` and `LDFLAGS`) to produce builds that are hardened against vulnerabilities and exploits. The flags sometimes also enable extra warnings to inform packagers about potential memory issues. This pach adds support for that to dotnet/runtime. The obvious method to make this work is to just export the `CFLAGS`, `CXXFLAGS`, and `LDFLAGS` directly. This, however, enables those flags during configure-time (aka `cmake` without `--build` too). That means several cmake configure tests get executed with unexpected compiler flags. These configure tests can then report incorrect results. For example, https://bugzilla.redhat.com/show_bug.cgi?id=1712158 demonstrates an issue where the check for `strerror_r` in the runtime comes to the wrong conclusion because `-Wall` is enabled and a variable is unused. A slightly longer fix is to support another set of environment variables, and use them to set `CFLAGS`, `CXXFLAGS`, `LDFLAGS`, but only for the invocation of `cmake --build`/`make`. See #35727 for the complete details. Fixes #35727 --- docs/workflow/building/coreclr/README.md | 2 ++ eng/build.sh | 3 +++ eng/native/build-commons.sh | 15 +++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/docs/workflow/building/coreclr/README.md b/docs/workflow/building/coreclr/README.md index c00d90a9799a..520ecd98a4fc 100644 --- a/docs/workflow/building/coreclr/README.md +++ b/docs/workflow/building/coreclr/README.md @@ -22,6 +22,8 @@ CoreCLR also supports a 'checked' build type which has asserts enabled like 'deb ./build.sh -subset clr -configuration checked ``` +To pass extra compiler/linker flags to the coreclr build, set the environment variables `EXTRA_CFLAGS`, `EXTRA_CXXFLAGS` and `EXTRA_LDFLAGS` as needed. Don't set `CFLAGS`/`CXXFLAGS`/`LDFLAGS` directly as that might lead to configure-time tests failing. + This will produce outputs as follows: - Product binaries will be dropped in `artifacts\bin\coreclr\..` folder. diff --git a/eng/build.sh b/eng/build.sh index da8e3770f595..afa16a69447a 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -97,6 +97,9 @@ usage() echo "* Build CoreCLR for Linux x64 on Debug configuration using GCC 8.4." echo "./build.sh clr -gcc8.4" echo "" + echo "* Build CoreCLR for Linux x64 using extra compiler flags (-fstack-clash-protection)." + echo "EXTRA_CFLAGS=-fstack-clash-protection EXTRA_CXXFLAGS=-fstack-clash-protection ./build.sh clr" + echo "" echo "* Cross-compile CoreCLR runtime for Linux ARM64 on Release configuration." echo "./build.sh clr.runtime -arch arm64 -c release -cross" echo "" diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 29c29a194e61..7315e43f2761 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -158,6 +158,17 @@ EOF return fi + SAVED_CFLAGS="${CFLAGS}" + SAVED_CXXFLAGS="${CXXFLAGS}" + SAVED_LDFLAGS="${LDFLAGS}" + + # Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS. + # If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly. + # See https://github.com/dotnet/runtime/issues/35727 for more information. + export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}" + export CXXFLAGS="${CXXFLAGS} ${EXTRA_CXXFLAGS}" + export LDFLAGS="${LDFLAGS} ${EXTRA_LDFLAGS}" + if [[ "$__StaticAnalyzer" == 1 ]]; then pushd "$intermediatesDir" @@ -176,6 +187,10 @@ EOF $cmake_command --build "$intermediatesDir" --target install -- -j "$__NumProc" fi + CFLAGS="${SAVED_CFLAGS}" + CXXFLAGS="${SAVED_CXXFLAGS}" + LDFLAGS="${SAVED_LDFLAGS}" + local exit_code="$?" if [[ "$exit_code" != 0 ]]; then echo "${__ErrMsgPrefix}Failed to build \"$message\"." From efafca9bd8ba5a746634820596f8144d0d98fde1 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Mon, 10 Aug 2020 17:50:42 +0200 Subject: [PATCH 361/755] use new OperatingSystem APIs in test projects that target NetCoreAppCurrent only (#40522) * use new OperatingSystem APIs in test projects that target NetCoreAppCurrent only * use `||` instead of `|` --- .../tests/System/Net/SslProtocolSupport.cs | 1 - .../tests/ManualTests/ManualTests.cs | 3 +-- .../tests/WindowAndCursorProps.cs | 11 ++++---- .../tests/ProcessStandardConsoleTests.cs | 3 +-- .../tests/ProcessStartInfoTests.cs | 8 +++--- .../tests/ProcessTests.Unix.cs | 10 +++---- .../tests/ProcessTests.cs | 19 +++++++------- .../tests/ProcessThreadTests.Unix.cs | 3 +-- .../tests/ProcessThreadTests.cs | 3 +-- .../IdnMapping/IdnMappingGetAsciiTests.cs | 9 +++---- ...ileSystemWatcher.Directory.NotifyFilter.cs | 22 ++++++++-------- .../FileSystemWatcher.File.NotifyFilter.cs | 26 +++++++++---------- .../tests/FileSystemWatcher.unit.cs | 5 ++-- .../tests/Utility/FileSystemWatcherTest.cs | 3 +-- .../tests/Directory/Delete.cs | 3 +-- .../tests/Directory/Exists.cs | 7 +++-- .../tests/Directory/GetDirectories.cs | 3 +-- .../tests/Directory/SetCurrentDirectory.cs | 7 +++-- .../tests/DirectoryInfo/Exists.cs | 3 +-- .../System.IO.FileSystem/tests/File/Delete.cs | 3 +-- .../tests/File/ReadWriteAllBytes.cs | 3 +-- .../tests/File/ReadWriteAllBytesAsync.cs | 3 +-- .../tests/File/ReadWriteAllLines.cs | 5 ++-- .../tests/File/ReadWriteAllLinesAsync.cs | 3 +-- .../tests/File/ReadWriteAllText.cs | 3 +-- .../tests/File/ReadWriteAllTextAsync.cs | 3 +-- .../tests/FileInfo/Length.cs | 3 +-- .../tests/FileStream/SafeFileHandle.cs | 3 +-- .../tests/FileStream/WriteAsync.cs | 5 ++-- .../FileStream/ctor_str_fm_fa_fs.delete.cs | 5 ++-- .../tests/PortedCommon/IOInputs.cs | 9 +++---- .../PortedCommon/ReparsePointUtilities.cs | 2 +- .../IO/IsolatedStorage/IsoStorageTest.cs | 3 +-- .../System/IO/IsolatedStorage/TestHelper.cs | 3 +-- .../MemoryMappedFile.CreateFromFile.Tests.cs | 5 ++-- .../tests/MemoryMappedFilesTestsBase.Unix.cs | 4 +-- .../MemoryMappedFilesTestsBase.Windows.cs | 2 +- .../tests/MemoryMappedFilesTestsBase.cs | 3 +-- .../tests/MemoryMappedViewAccessor.Tests.cs | 5 ++-- .../tests/MemoryMappedViewStream.Tests.cs | 5 ++-- .../NamedPipeTests/NamedPipeTest.Simple.cs | 15 +++++------ .../NamedPipeTests/NamedPipeTest.Specific.cs | 5 ++-- .../System.IO.Pipes/tests/PipeTest.Read.cs | 3 +-- .../System.IO.Pipes/tests/PipeTest.Write.cs | 5 ++-- .../tests/PalTests/NameResolutionPalTests.cs | 3 +-- .../FunctionalTests/IPGlobalPropertiesTest.cs | 3 +-- .../FunctionalTests/SslStreamAlpnTests.cs | 3 +-- .../tests/FunctionalTests/SslStreamEKUTest.cs | 3 +-- .../FunctionalTests/TestConfiguration.cs | 9 +++---- .../FunctionalTests/TransportContextTest.cs | 2 +- .../StressTests/SslStress/SslServerBase.cs | 3 +-- .../System.Net.WebProxy/tests/WebProxyTest.cs | 3 +-- .../tests/Misc/XmlUrlResolverTests.cs | 3 +-- .../Environment.GetEnvironmentVariable.cs | 4 +-- .../Environment.SetEnvironmentVariable.cs | 2 +- .../tests/System/EnvironmentTests.cs | 6 ++--- .../InteropServices/Marshal/OffsetOfTests.cs | 8 +++--- .../tests/System/TimeZoneInfoTests.cs | 5 ++-- .../tests/CryptoConfigTests.cs | 3 +-- .../tests/Oid.cs | 5 ++-- .../tests/CertLoader.cs | 5 ++-- .../tests/Cert.cs | 4 +-- .../tests/ChainTests.cs | 11 ++++---- .../tests/CollectionImportTests.cs | 3 +-- .../tests/CtorTests.cs | 5 ++-- .../tests/DynamicChainTests.cs | 5 ++-- .../tests/FindTests.cs | 3 +-- .../PfxFormatTests.SingleCertGenerator.cs | 3 +-- .../tests/PfxFormatTests.cs | 9 +++---- .../tests/PfxFormatTests_Collection.cs | 2 +- .../tests/PfxFormatTests_SingleCert.cs | 3 +-- .../tests/PfxTests.cs | 7 +++-- .../RevocationTests/DynamicRevocationTests.cs | 5 ++-- .../X500DistinguishedNameEncodingTests.cs | 3 +-- 74 files changed, 164 insertions(+), 226 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs index 78ae108471dd..e6ac1884c358 100644 --- a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs +++ b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; using System.Security.Authentication; namespace System.Net.Test.Common diff --git a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs index 43688d799eba..9bbec557dbb7 100644 --- a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs +++ b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -96,7 +95,7 @@ public static IEnumerable GetKeyChords() yield return MkConsoleKeyInfo('\x01', ConsoleKey.A, ConsoleModifiers.Control | ConsoleModifiers.Alt); yield return MkConsoleKeyInfo('\r', ConsoleKey.Enter, (ConsoleModifiers)0); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // windows will report '\n' as 'Ctrl+Enter', which is typically not picked up by Unix terminals yield return MkConsoleKeyInfo('\n', ConsoleKey.Enter, ConsoleModifiers.Control); diff --git a/src/libraries/System.Console/tests/WindowAndCursorProps.cs b/src/libraries/System.Console/tests/WindowAndCursorProps.cs index 0e63417f0aa1..aed9ef028916 100644 --- a/src/libraries/System.Console/tests/WindowAndCursorProps.cs +++ b/src/libraries/System.Console/tests/WindowAndCursorProps.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; using Microsoft.DotNet.RemoteExecutor; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -323,7 +322,7 @@ public void BeepWithFrequency_Unix_ThrowsPlatformNotSupportedException() [OuterLoop] // clears the screen, not very inner-loop friendly public static void Clear_Invoke_Success() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (!Console.IsInputRedirected && !Console.IsOutputRedirected)) + if (!OperatingSystem.IsWindows() || (!Console.IsInputRedirected && !Console.IsOutputRedirected)) { // Nothing to verify; just run the code. Console.Clear(); @@ -341,7 +340,7 @@ public static void SetCursorPosition_Throws_PlatformNotSupportedException() [PlatformSpecific(~TestPlatforms.Browser)] public static void SetCursorPosition_Invoke_Success() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (!Console.IsInputRedirected && !Console.IsOutputRedirected)) + if (!OperatingSystem.IsWindows() || (!Console.IsInputRedirected && !Console.IsOutputRedirected)) { int origLeft = Console.CursorLeft; int origTop = Console.CursorTop; @@ -383,7 +382,7 @@ public static void GetCursorPosition_Invoke_ReturnsExpected() Assert.Equal(origTop, Console.CursorTop); Assert.Equal(origTuple, Console.GetCursorPosition()); } - else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + else if (!OperatingSystem.IsWindows()) { Assert.Equal(0, Console.CursorLeft); Assert.Equal(0, Console.CursorTop); @@ -405,7 +404,7 @@ public void CursorLeft_Set_GetReturnsExpected() Console.CursorLeft = origLeft; Assert.Equal(origLeft, Console.CursorLeft); } - else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + else if (!OperatingSystem.IsWindows()) { Assert.Equal(0, Console.CursorLeft); } @@ -448,7 +447,7 @@ public void CursorTop_Set_GetReturnsExpected() Console.CursorTop = origTop; Assert.Equal(origTop, Console.CursorTop); } - else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + else if (!OperatingSystem.IsWindows()) { Assert.Equal(0, Console.CursorTop); } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStandardConsoleTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStandardConsoleTests.cs index 6e9bd497e20c..dd41c0e1dbec 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStandardConsoleTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStandardConsoleTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; -using System.Runtime.InteropServices; using System.Text; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -32,7 +31,7 @@ public void TestChangesInConsoleEncoding() Assert.True(p.WaitForExit(WaitInMS)); }; - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!OperatingSystem.IsWindows()) { run(Encoding.UTF8.CodePage); return; diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs index ced27b832ab3..3d946ade10e2 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs @@ -57,7 +57,7 @@ public void TestEnvironmentProperty() environment.Add("NewKey2", "NewValue2"); Assert.True(environment.ContainsKey("NewKey")); - Assert.Equal(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), environment.ContainsKey("newkey")); + Assert.Equal(OperatingSystem.IsWindows(), environment.ContainsKey("newkey")); Assert.False(environment.ContainsKey("NewKey99")); //Iterating @@ -93,7 +93,7 @@ public void TestEnvironmentProperty() //Contains Assert.True(environment.Contains(new KeyValuePair("NewKey", "NewValue"))); - Assert.Equal(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), environment.Contains(new KeyValuePair("nEwKeY", "NewValue"))); + Assert.Equal(OperatingSystem.IsWindows(), environment.Contains(new KeyValuePair("nEwKeY", "NewValue"))); Assert.False(environment.Contains(new KeyValuePair("NewKey99", "NewValue99"))); //Exception not thrown with invalid key @@ -110,7 +110,7 @@ public void TestEnvironmentProperty() Assert.True(environment.TryGetValue("NewKey", out stringout)); Assert.Equal("NewValue", stringout); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.True(environment.TryGetValue("NeWkEy", out stringout)); Assert.Equal("NewValue", stringout); @@ -144,7 +144,7 @@ public void TestEnvironmentProperty() Assert.Throws(() => environment["1bB"]); Assert.True(environment.Contains(new KeyValuePair("NewKey2", "NewValue2OverriddenAgain"))); - Assert.Equal(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), environment.Contains(new KeyValuePair("NEWKeY2", "NewValue2OverriddenAgain"))); + Assert.Equal(OperatingSystem.IsWindows(), environment.Contains(new KeyValuePair("NEWKeY2", "NewValue2OverriddenAgain"))); Assert.False(environment.Contains(new KeyValuePair("NewKey2", "newvalue2Overriddenagain"))); Assert.False(environment.Contains(new KeyValuePair("newkey2", "newvalue2Overriddenagain"))); diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs index 6aca35f46032..9097dd7672a5 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs @@ -108,7 +108,7 @@ public void ProcessStart_DirectoryNameInCurDirectorySameAsFileNameInExecDirector [OuterLoop] public void ProcessStart_UseShellExecute_OnUnix_OpenMissingFile_DoesNotThrow() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && + if (OperatingSystem.IsLinux() && s_allowedProgramsToRun.FirstOrDefault(program => IsProgramInstalled(program)) == null) { return; @@ -139,12 +139,12 @@ public void ProcessStart_UseShellExecute_OnUnix_SuccessWhenProgramInstalled(bool File.WriteAllText(fileToOpen, $"{nameof(ProcessStart_UseShellExecute_OnUnix_SuccessWhenProgramInstalled)}"); } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || programToOpen != null) + if (OperatingSystem.IsMacOS() || programToOpen != null) { using (var px = Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = fileToOpen })) { Assert.NotNull(px); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) // on OSX, process name is dotnet for some reason. Refer to https://github.com/dotnet/runtime/issues/23525 + if (!OperatingSystem.IsMacOS()) // on OSX, process name is dotnet for some reason. Refer to https://github.com/dotnet/runtime/issues/23525 { Assert.Equal(programToOpen, px.ProcessName); } @@ -558,7 +558,7 @@ public unsafe void TestCheckChildProcessUserAndGroupIds() // If this test runs as the user, we expect to be able to match the user groups exactly. // Except on OSX, where getgrouplist may return a list of groups truncated to NGROUPS_MAX. bool checkGroupsExact = userId == geteuid().ToString() && - !RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + !OperatingSystem.IsMacOS(); // Start as username var invokeOptions = new RemoteInvokeOptions(); @@ -600,7 +600,7 @@ public unsafe void TestCheckChildProcessUserAndGroupIdsElevated(bool useRootGrou // On systems with a low value of NGROUPS_MAX (e.g 16 on OSX), the groups may be truncated. // On Linux NGROUPS_MAX is 65536, so we expect to see every group. - bool checkGroupsExact = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + bool checkGroupsExact = OperatingSystem.IsLinux(); // Start as username var invokeOptions = new RemoteInvokeOptions(); diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index ca9a3f6dbace..fa6503b81d48 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -8,7 +8,6 @@ using System.IO.Pipes; using System.Linq; using System.Net; -using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading; @@ -52,7 +51,7 @@ private void SetAndCheckBasePriority(ProcessPriorityClass exPriorityClass, int p private void AssertNonZeroWindowsZeroUnix(long value) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.NotEqual(0, value); } @@ -64,7 +63,7 @@ private void AssertNonZeroWindowsZeroUnix(long value) private void AssertNonZeroAllZeroDarwin(long value) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { Assert.Equal(0, value); } @@ -422,7 +421,7 @@ public void TestId() Assert.NotEqual(Environment.ProcessId, _process.Id); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(_process.Id, Interop.GetProcessId(_process.SafeHandle)); } @@ -517,14 +516,14 @@ public void TestMaxWorkingSet() Assert.InRange((long)p.MinWorkingSet, 0, long.MaxValue); } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"))) { + if (OperatingSystem.IsMacOS() || OperatingSystem.IsFreeBSD()) { return; // doesn't support getting/setting working set for other processes } long curValue = (long)_process.MaxWorkingSet; Assert.InRange(curValue, 0, long.MaxValue); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { try { @@ -572,14 +571,14 @@ public void TestMinWorkingSet() Assert.InRange((long)p.MinWorkingSet, 0, long.MaxValue); } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"))) { + if (OperatingSystem.IsMacOS() || OperatingSystem.IsFreeBSD()) { return; // doesn't support getting/setting working set for other processes } long curValue = (long)_process.MinWorkingSet; Assert.InRange(curValue, 0, long.MaxValue); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { try { @@ -758,7 +757,7 @@ public void TestWorkingSet64() { CreateDefaultProcess(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { // resident memory can be 0 on OSX. Assert.InRange(_process.WorkingSet64, 0, long.MaxValue); @@ -1815,7 +1814,7 @@ public void TestWorkingSet() { CreateDefaultProcess(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { // resident memory can be 0 on OSX. #pragma warning disable 0618 diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs index b6bd36a625bc..2a0f26c1a7a3 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; -using System.Runtime.InteropServices; using System.Threading; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -20,7 +19,7 @@ public void TestPriorityLevelProperty_Unix() ProcessThread thread = _process.Threads[0]; ThreadPriorityLevel level = ThreadPriorityLevel.Normal; - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { Assert.Throws(() => thread.PriorityLevel); } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 57e0ec56af08..fe648a0b796b 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; -using System.Runtime.InteropServices; using System.Threading; using System.Linq; using Microsoft.DotNet.RemoteExecutor; @@ -28,7 +27,7 @@ public void TestCommonPriorityAndTimeProperties() // On OSX, thread id is a 64bit unsigned value. We truncate the ulong to int // due to .NET API surface area. Hence, on overflow id can be negative while // casting the ulong to int. - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (!OperatingSystem.IsMacOS()) { Assert.InRange(thread.Id, 0, int.MaxValue); } diff --git a/src/libraries/System.Globalization.Extensions/tests/IdnMapping/IdnMappingGetAsciiTests.cs b/src/libraries/System.Globalization.Extensions/tests/IdnMapping/IdnMappingGetAsciiTests.cs index 756edf8b7a91..26acb30de581 100644 --- a/src/libraries/System.Globalization.Extensions/tests/IdnMapping/IdnMappingGetAsciiTests.cs +++ b/src/libraries/System.Globalization.Extensions/tests/IdnMapping/IdnMappingGetAsciiTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using Xunit; namespace System.Globalization.Tests @@ -92,8 +91,8 @@ public void TestGetAsciiWithDot() if (ex == null) { // Windows and OSX always throw exception. some versions of Linux succeed and others throw exception - Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)); + Assert.False(OperatingSystem.IsWindows()); + Assert.False(OperatingSystem.IsMacOS()); Assert.Equal(".", result); } else @@ -122,9 +121,9 @@ public static IEnumerable GetAscii_Invalid_TestData() yield return new object[] { "\u0061\u0062\u0063.\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067.\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0", 3, 9, typeof(ArgumentException) }; yield return new object[] { "\u0061\u0062\u0063.\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067.\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0", 11, 10, typeof(ArgumentException) }; - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // expected platform differences, see https://github.com/dotnet/runtime/issues/17190 + if (!OperatingSystem.IsWindows()) // expected platform differences, see https://github.com/dotnet/runtime/issues/17190 { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { yield return new object[] { ".", 0, 1, typeof(ArgumentException) }; } diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.NotifyFilter.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.NotifyFilter.cs index 80bb9b13e94d..51cce8f30b2f 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.NotifyFilter.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.NotifyFilter.cs @@ -36,11 +36,11 @@ public void FileSystemWatcher_Directory_NotifyFilter_Attributes(NotifyFilters fi WatcherChangeTypes expected = 0; if (filter == NotifyFilters.Attributes) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & NotifyFilters.Security) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & NotifyFilters.Security) > 0)) expected |= WatcherChangeTypes.Changed; // Attribute change on OSX is a ChangeOwner operation which passes the Security NotifyFilter. ExpectEvent(watcher, expected, action, cleanup, dir.Path); } @@ -60,9 +60,9 @@ public void FileSystemWatcher_Directory_NotifyFilter_CreationTime(NotifyFilters WatcherChangeTypes expected = 0; if (filter == NotifyFilters.CreationTime) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: dir.Path); @@ -106,9 +106,9 @@ public void FileSystemWatcher_Directory_NotifyFilter_LastAccessTime(NotifyFilter WatcherChangeTypes expected = 0; if (filter == NotifyFilters.LastAccess) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: dir.Path); @@ -129,9 +129,9 @@ public void FileSystemWatcher_Directory_NotifyFilter_LastWriteTime(NotifyFilters WatcherChangeTypes expected = 0; if (filter == NotifyFilters.LastWrite) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: dir.Path); @@ -156,9 +156,9 @@ public void FileSystemWatcher_Directory_NotifyFilter_LastWriteTime_TwoFilters(No WatcherChangeTypes expected = 0; if ((filter & NotifyFilters.LastWrite) > 0) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: dir.Path); } diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.NotifyFilter.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.NotifyFilter.cs index 2b8675a03a38..92bd0b62728c 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.NotifyFilter.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.NotifyFilter.cs @@ -38,11 +38,11 @@ public void FileSystemWatcher_File_NotifyFilter_Attributes(NotifyFilters filter) WatcherChangeTypes expected = 0; if (filter == NotifyFilters.Attributes) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & NotifyFilters.Security) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & NotifyFilters.Security) > 0)) expected |= WatcherChangeTypes.Changed; // Attribute change on OSX is a ChangeOwner operation which passes the Security NotifyFilter. ExpectEvent(watcher, expected, action, cleanup, file.Path); @@ -63,9 +63,9 @@ public void FileSystemWatcher_File_NotifyFilter_CreationTime(NotifyFilters filte WatcherChangeTypes expected = 0; if (filter == NotifyFilters.CreationTime) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: file.Path); @@ -109,9 +109,9 @@ public void FileSystemWatcher_File_NotifyFilter_LastAccessTime(NotifyFilters fil WatcherChangeTypes expected = 0; if (filter == NotifyFilters.LastAccess) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: file.Path); } @@ -131,9 +131,9 @@ public void FileSystemWatcher_File_NotifyFilter_LastWriteTime(NotifyFilters filt WatcherChangeTypes expected = 0; if (filter == NotifyFilters.LastWrite) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForAttribute) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForAttribute) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; ExpectEvent(watcher, expected, action, expectedPath: file.Path); } @@ -154,9 +154,9 @@ public void FileSystemWatcher_File_NotifyFilter_Size(NotifyFilters filter) WatcherChangeTypes expected = 0; if (filter == NotifyFilters.Size || filter == NotifyFilters.LastWrite) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForModify) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; else if (PlatformDetection.IsWindows7 && filter == NotifyFilters.Attributes) // win7 FSW Size change passes the Attribute filter expected |= WatcherChangeTypes.Changed; @@ -183,9 +183,9 @@ public void FileSystemWatcher_File_NotifyFilter_Size_TwoFilters(NotifyFilters fi WatcherChangeTypes expected = 0; if (((filter & NotifyFilters.Size) > 0) || ((filter & NotifyFilters.LastWrite) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ((filter & LinuxFiltersForModify) > 0)) + else if (OperatingSystem.IsLinux() && ((filter & LinuxFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && ((filter & OSXFiltersForModify) > 0)) + else if (OperatingSystem.IsMacOS() && ((filter & OSXFiltersForModify) > 0)) expected |= WatcherChangeTypes.Changed; else if (PlatformDetection.IsWindows7 && ((filter & NotifyFilters.Attributes) > 0)) // win7 FSW Size change passes the Attribute filter expected |= WatcherChangeTypes.Changed; diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs index 4da782fce588..100aa445578b 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs @@ -3,7 +3,6 @@ using System.Collections.ObjectModel; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -507,8 +506,8 @@ public void FileSystemWatcher_Path() watcher.Path = currentDir; Assert.Equal(currentDir, watcher.Path); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || // expect no change for OrdinalIgnoreCase-equal strings - RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsWindows() || // expect no change for OrdinalIgnoreCase-equal strings + OperatingSystem.IsMacOS()) { watcher.Path = currentDir.ToUpperInvariant(); Assert.Equal(currentDir, watcher.Path); diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs index 6ebc03a64a90..0d6ea8b040bc 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; using System.Threading; using Xunit; using Xunit.Sdk; @@ -463,7 +462,7 @@ protected static bool CanCreateSymbolicLinks public static bool CreateSymLink(string targetPath, string linkPath, bool isDirectory) { Process symLinkProcess = new Process(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { symLinkProcess.StartInfo.FileName = "cmd"; symLinkProcess.StartInfo.Arguments = string.Format("/c mklink{0} \"{1}\" \"{2}\"", isDirectory ? " /D" : "", Path.GetFullPath(linkPath), Path.GetFullPath(targetPath)); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs index 3648f97ef4b8..386b847728eb 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Text; using Xunit; using Microsoft.DotNet.XUnitExtensions; @@ -10,7 +9,7 @@ namespace System.IO.Tests { public class Directory_Delete_str : FileSystemTest { - static bool IsBindMountSupported => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && !PlatformDetection.IsInContainer; + static bool IsBindMountSupported => OperatingSystem.IsLinux() && !PlatformDetection.IsInContainer; #region Utilities diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs index cfe5834f53d3..04b1411fca3a 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; -using System.Runtime.InteropServices; using Xunit; namespace System.IO.Tests @@ -125,7 +124,7 @@ public void SymLinksMayExistIndependentlyOfTarget() // considered a file (since it's broken and we don't know what it'll eventually point to). Directory.Delete(path); Assert.False(Directory.Exists(path), "path should now not exist"); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.True(Directory.Exists(linkPath), "linkPath should still exist as a directory"); Assert.False(File.Exists(linkPath), "linkPath should not be a file"); @@ -142,11 +141,11 @@ public void SymLinksMayExistIndependentlyOfTarget() try { Directory.Delete(linkPath); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Should only succeed on Windows"); + Assert.True(OperatingSystem.IsWindows(), "Should only succeed on Windows"); } catch (IOException) { - Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Should only fail on Unix"); + Assert.False(OperatingSystem.IsWindows(), "Should only fail on Unix"); File.Delete(linkPath); } diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/GetDirectories.cs b/src/libraries/System.IO.FileSystem/tests/Directory/GetDirectories.cs index bbc069f341b9..3e4c0aaf9f32 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/GetDirectories.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/GetDirectories.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; -using System.Runtime.InteropServices; using Xunit; namespace System.IO.Tests @@ -34,7 +33,7 @@ public void EnumerateWithSymLinkToDirectory() } targetDir.Delete(recursive: true); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(1, GetEntries(containingFolder.FullName).Count()); Assert.Equal(0, Directory.GetFiles(containingFolder.FullName).Count()); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs b/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs index 16287ef7b3f4..60544b0fd09e 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.InteropServices; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -37,7 +36,7 @@ public void SetToValidOtherDirectory() // On OSX, the temp directory /tmp/ is a symlink to /private/tmp, so setting the current // directory to a symlinked path will result in GetCurrentDirectory returning the absolute // path that followed the symlink. - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (!OperatingSystem.IsMacOS()) { Assert.Equal(TestDirectory, Directory.GetCurrentDirectory()); } @@ -65,11 +64,11 @@ public void SetToPathContainingSymLink() // Set Current Directory to symlink Directory.SetCurrentDirectory(linkPath); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(linkPath, Directory.GetCurrentDirectory()); } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + else if (OperatingSystem.IsMacOS()) { Assert.Equal("/private" + path, Directory.GetCurrentDirectory()); } diff --git a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs index 9438d2ab3875..615bd4c1b1db 100644 --- a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using Xunit; namespace System.IO.Tests @@ -157,7 +156,7 @@ public void SymLinksMayExistIndependentlyOfTarget() pathFI.Refresh(); Assert.False(pathFI.Exists, "path should now not exist"); linkPathFI.Refresh(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.True(linkPathFI.Exists, "linkPath directory should still exist"); Assert.False(File.Exists(linkPath), "linkPath file should not exist"); diff --git a/src/libraries/System.IO.FileSystem/tests/File/Delete.cs b/src/libraries/System.IO.FileSystem/tests/File/Delete.cs index aee2e32ddee5..b696838619b0 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Delete.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Delete.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using Xunit; using Microsoft.DotNet.XUnitExtensions; @@ -9,7 +8,7 @@ namespace System.IO.Tests { public class File_Delete : FileSystemTest { - static bool IsBindMountSupported => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && !PlatformDetection.IsInContainer; + static bool IsBindMountSupported => OperatingSystem.IsLinux() && !PlatformDetection.IsInContainer; protected virtual void Delete(string path) { diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index 33c10d40b847..b6b47961363b 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using Xunit; @@ -106,7 +105,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { File.WriteAllBytes(path, Encoding.UTF8.GetBytes("text")); Assert.Equal(Encoding.UTF8.GetBytes("text"), File.ReadAllBytes(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs index 30fc35e97b1e..598fc0184871 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -120,7 +119,7 @@ public async Task WriteToReadOnlyFileAsync() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { await File.WriteAllBytesAsync(path, Encoding.UTF8.GetBytes("text")); Assert.Equal(Encoding.UTF8.GetBytes("text"), await File.ReadAllBytesAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs index 89ede8680ce5..d5ef0eed9cee 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Text; using Xunit; @@ -112,7 +111,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { Write(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, Read(path)); @@ -300,7 +299,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { Write(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, Read(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs index 9a22ccc2c36c..87b3ad7df7cb 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -107,7 +106,7 @@ public async Task WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { await WriteAsync(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, await ReadAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs index 152858cc9238..e511b69540c7 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Text; using Xunit; @@ -119,7 +118,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { Write(path, "text"); Assert.Equal("text", Read(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs index 3d2f1d9d8da6..33813987cd10 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; -using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -115,7 +114,7 @@ public async Task WriteToReadOnlyFileAsync() try { // Operation succeeds when being run by the Unix superuser - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && geteuid() == 0) + if (!OperatingSystem.IsWindows() && geteuid() == 0) { await WriteAsync(path, "text"); Assert.Equal("text", await ReadAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/FileInfo/Length.cs b/src/libraries/System.IO.FileSystem/tests/FileInfo/Length.cs index 87648f245ff1..b7c3bbe81a2a 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileInfo/Length.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileInfo/Length.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using Xunit; namespace System.IO.Tests @@ -79,7 +78,7 @@ public void SymLinkLength() Assert.Equal(FileSize, info.Length); var linkInfo = new FileInfo(linkPath); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // On Windows, symlinks have length 0. Assert.Equal(0, linkInfo.Length); diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs index 03b335393172..209ddf0c4a58 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs @@ -4,7 +4,6 @@ using Microsoft.Win32.SafeHandles; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -105,7 +104,7 @@ private async Task ThrowWhenHandlePositionIsChanged(bool useAsync) fs.WriteByte(0); fsr.Position++; - if (useAsync && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // Async I/O behaviors differ due to kernel-based implementation on Windows + if (useAsync && OperatingSystem.IsWindows()) // Async I/O behaviors differ due to kernel-based implementation on Windows { Assert.Throws(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 1))); } diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs index 2710edcbf310..5f606907dcb2 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -257,7 +256,7 @@ public static IEnumerable MemberData_FileStreamAsyncWriting() { foreach (bool useAsync in new[] { true, false }) { - if (useAsync && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (useAsync && !OperatingSystem.IsWindows()) { // We don't have a special async I/O implementation in FileStream on Unix. continue; @@ -282,7 +281,7 @@ public Task ManyConcurrentWriteAsyncs() { // For inner loop, just test one case return ManyConcurrentWriteAsyncs_OuterLoop( - useAsync: RuntimeInformation.IsOSPlatform(OSPlatform.Windows), + useAsync: OperatingSystem.IsWindows(), presize: false, exposeHandle: false, cancelable: true, diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.delete.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.delete.cs index 49237f0eb713..5a1022dd68bd 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.delete.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.delete.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using System.Runtime.InteropServices; using Xunit; namespace System.IO.Tests @@ -18,7 +17,7 @@ public void FileShareDeleteNew() { Assert.True(File.Exists(fileName)); File.Delete(fileName); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // Prior to 1903 Windows would not delete the filename until the last file handle is closed. Assert.Equal(PlatformDetection.IsWindows10Version1903OrGreater, !File.Exists(fileName)); @@ -56,7 +55,7 @@ public void FileShareDeleteExisting() using (FileStream fs = CreateFileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete)) { File.Delete(fileName); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // Prior to 1903 Windows would not delete the filename until the last file handle is closed. Assert.Equal(PlatformDetection.IsWindows10Version1903OrGreater, !File.Exists(fileName)); diff --git a/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs b/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs index 0f62c53ad1ed..d6516795762c 100644 --- a/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs +++ b/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs @@ -5,21 +5,20 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.InteropServices; internal static class IOInputs { - public static bool SupportsSettingCreationTime { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } } - public static bool SupportsGettingCreationTime { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) | RuntimeInformation.IsOSPlatform(OSPlatform.OSX); } } + public static bool SupportsSettingCreationTime => OperatingSystem.IsWindows(); + public static bool SupportsGettingCreationTime => OperatingSystem.IsWindows() || OperatingSystem.IsMacOS(); // Max path length (minus trailing \0). Unix values vary system to system; just using really long values here likely to be more than on the average system. - public static readonly int MaxPath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 259 : 10000; + public static readonly int MaxPath = OperatingSystem.IsWindows() ? 259 : 10000; // Windows specific, this is the maximum length that can be passed using extended syntax. Does not include the trailing \0. public static readonly int MaxExtendedPath = short.MaxValue - 1; // Same as MaxPath on Unix - public static readonly int MaxLongPath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? MaxExtendedPath : MaxPath; + public static readonly int MaxLongPath = OperatingSystem.IsWindows() ? MaxExtendedPath : MaxPath; // Windows specific, this is the maximum length that can be passed to APIs taking directory names, such as Directory.CreateDirectory & Directory.Move. // Does not include the trailing \0. diff --git a/src/libraries/System.IO.FileSystem/tests/PortedCommon/ReparsePointUtilities.cs b/src/libraries/System.IO.FileSystem/tests/PortedCommon/ReparsePointUtilities.cs index c0c93059a1ac..d2304e1213fa 100644 --- a/src/libraries/System.IO.FileSystem/tests/PortedCommon/ReparsePointUtilities.cs +++ b/src/libraries/System.IO.FileSystem/tests/PortedCommon/ReparsePointUtilities.cs @@ -34,7 +34,7 @@ public static class MountHelper public static bool CreateSymbolicLink(string linkPath, string targetPath, bool isDirectory) { Process symLinkProcess = new Process(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { symLinkProcess.StartInfo.FileName = "cmd"; symLinkProcess.StartInfo.Arguments = string.Format("/c mklink{0} \"{1}\" \"{2}\"", isDirectory ? " /D" : "", linkPath, targetPath); diff --git a/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/IsoStorageTest.cs b/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/IsoStorageTest.cs index 3b0428c20ba8..9af2e8bb30bb 100644 --- a/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/IsoStorageTest.cs +++ b/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/IsoStorageTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using Xunit; namespace System.IO.IsolatedStorage @@ -78,7 +77,7 @@ public static IEnumerable ValidStores }; // https://github.com/dotnet/runtime/issues/2092 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + if (OperatingSystem.IsWindows() && !PlatformDetection.IsInAppContainer) { validScopes.Add(PresetScopes.MachineStoreForApplication); diff --git a/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/TestHelper.cs b/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/TestHelper.cs index 64f228c3c5f2..e3e7f423a7b7 100644 --- a/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/TestHelper.cs +++ b/src/libraries/System.IO.IsolatedStorage/tests/System/IO/IsolatedStorage/TestHelper.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Reflection; -using System.Runtime.InteropServices; using System.Text; namespace System.IO.IsolatedStorage @@ -33,7 +32,7 @@ static TestHelper() // https://github.com/dotnet/runtime/issues/2092 // https://github.com/dotnet/runtime/issues/21742 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + if (OperatingSystem.IsWindows() && !PlatformDetection.IsInAppContainer) { s_roots.Add(Helper.GetDataDirectory(IsolatedStorageScope.Machine)); diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs index d5edbbc05b29..f23da731a67e 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs @@ -3,7 +3,6 @@ using Microsoft.Win32.SafeHandles; using System.Collections.Generic; -using System.Runtime.InteropServices; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -697,13 +696,13 @@ private void WriteToReadOnlyFile(MemoryMappedFileAccess access, bool succeeds) public void WriteToReadOnlyFile_ReadWrite(MemoryMappedFileAccess access) { WriteToReadOnlyFile(access, access == MemoryMappedFileAccess.Read || - (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && PlatformDetection.IsSuperUser)); + (!OperatingSystem.IsWindows() && PlatformDetection.IsSuperUser)); } [Fact] public void WriteToReadOnlyFile_CopyOnWrite() { - WriteToReadOnlyFile(MemoryMappedFileAccess.CopyOnWrite, (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && PlatformDetection.IsSuperUser)); + WriteToReadOnlyFile(MemoryMappedFileAccess.CopyOnWrite, (!OperatingSystem.IsWindows() && PlatformDetection.IsSuperUser)); } /// diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs index 86cc494976bb..670aa4d70aa0 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Unix.cs @@ -23,8 +23,8 @@ public abstract partial class MemoryMappedFilesTestBase : FileCleanupTestBase const int _SC_PAGESIZE_NetBSD = 28; const int _SC_PAGESIZE_OSX = 29; pageSize = sysconf( - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? _SC_PAGESIZE_OSX : - RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")) ? _SC_PAGESIZE_FreeBSD : + OperatingSystem.IsMacOS() ? _SC_PAGESIZE_OSX : + OperatingSystem.IsFreeBSD() ? _SC_PAGESIZE_FreeBSD : RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")) ? _SC_PAGESIZE_NetBSD : _SC_PAGESIZE_Linux); Assert.InRange(pageSize, 1, int.MaxValue); diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Windows.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Windows.cs index 052e0ab778f9..9473abe2e052 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Windows.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.Windows.cs @@ -51,7 +51,7 @@ protected static int geteuid() /// Asserts that the handle's inheritability matches the specified value. protected static void AssertInheritability(SafeHandle handle, HandleInheritability inheritability) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { uint flags; Assert.True(GetHandleInformation(handle.DangerousGetHandle(), out flags)); diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.cs index f86b39bce7ad..86f00bc40308 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFilesTestsBase.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using Xunit; namespace System.IO.MemoryMappedFiles.Tests @@ -12,7 +11,7 @@ namespace System.IO.MemoryMappedFiles.Tests public abstract partial class MemoryMappedFilesTestBase : FileCleanupTestBase { /// Gets whether named maps are supported by the current platform. - protected static bool MapNamesSupported { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } } + protected static bool MapNamesSupported => OperatingSystem.IsWindows(); /// Creates a map name guaranteed to be unique. protected static string CreateUniqueMapName() { return Guid.NewGuid().ToString("N"); } diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs index f96e00479ae3..0be6027d6d58 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs @@ -3,7 +3,6 @@ using Microsoft.Win32.SafeHandles; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -90,7 +89,7 @@ public void ValidAccessLevelCombinations(MemoryMappedFileAccess mapAccess, Memor } catch (UnauthorizedAccessException) { - if ((RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || PlatformDetection.IsInContainer) && + if ((OperatingSystem.IsMacOS() || PlatformDetection.IsInContainer) && (viewAccess == MemoryMappedFileAccess.ReadExecute || viewAccess == MemoryMappedFileAccess.ReadWriteExecute)) { // Containers and OSX with SIP enabled do not have execute permissions by default. @@ -170,7 +169,7 @@ public void PointerOffsetMatchesViewStart() using (MemoryMappedViewAccessor acc = mmf.CreateViewAccessor(MapLength, 0)) { Assert.Equal( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? MapLength : 0, + OperatingSystem.IsWindows() ? MapLength : 0, acc.PointerOffset); } } diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs index 5f98409f3fe2..a9cf5dbddaee 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs @@ -3,7 +3,6 @@ using Microsoft.Win32.SafeHandles; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -90,7 +89,7 @@ public void ValidAccessLevelCombinations(MemoryMappedFileAccess mapAccess, Memor } catch (UnauthorizedAccessException) { - if ((RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || PlatformDetection.IsInContainer) && + if ((OperatingSystem.IsMacOS() || PlatformDetection.IsInContainer) && (viewAccess == MemoryMappedFileAccess.ReadExecute || viewAccess == MemoryMappedFileAccess.ReadWriteExecute)) { // Containers and OSX with SIP enabled do not have execute permissions by default. @@ -186,7 +185,7 @@ public void PointerOffsetMatchesViewStart() using (MemoryMappedViewStream s = mmf.CreateViewStream(MapLength, 0)) { Assert.Equal( - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? MapLength : 0, + OperatingSystem.IsWindows() ? MapLength : 0, s.PointerOffset); } } diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Simple.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Simple.cs index e576630e038f..d89887dbe0a0 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Simple.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Simple.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -117,7 +116,7 @@ public async Task ClonedServer_ActsAsOriginalServer() Task clientTask = client.ReadAsync(received1, 0, received1.Length); using (NamedPipeServerStream server = new NamedPipeServerStream(PipeDirection.Out, false, true, serverBase.SafePipeHandle)) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(1, client.NumberOfServerInstances); } @@ -155,7 +154,7 @@ public async Task ClonedClient_ActsAsOriginalClient() { using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.In, false, true, pair.clientStream.SafePipeHandle)) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(1, client.NumberOfServerInstances); } @@ -224,7 +223,7 @@ public async Task CancelTokenOn_ServerWaitForConnectionAsync_Throws_OperationCan NamedPipeServerStream server = pair.serverStream; var ctx = new CancellationTokenSource(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // cancellation token after the operation has been initiated + if (OperatingSystem.IsWindows()) // cancellation token after the operation has been initiated { Task serverWaitTimeout = server.WaitForConnectionAsync(ctx.Token); ctx.Cancel(); @@ -322,7 +321,7 @@ public virtual async Task OperationsOnDisconnectedClient() if (!pair.writeToServer) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // writes on Unix may still succeed after other end disconnects, due to socket being used + if (OperatingSystem.IsWindows()) // writes on Unix may still succeed after other end disconnects, due to socket being used { // Pipe is broken Assert.Throws(() => client.Write(buffer, 0, buffer.Length)); @@ -338,7 +337,7 @@ public virtual async Task OperationsOnDisconnectedClient() Assert.Equal(0, client.Read(buffer, 0, buffer.Length)); Assert.Equal(-1, client.ReadByte()); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // NumberOfServerInstances not supported on Unix + if (!OperatingSystem.IsWindows()) // NumberOfServerInstances not supported on Unix { Assert.Throws(() => client.NumberOfServerInstances); } @@ -547,7 +546,7 @@ public async Task Server_ReadWriteCancelledToken_Throws_OperationCanceledExcepti if (server.CanWrite) { var ctx1 = new CancellationTokenSource(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // On Unix WriteAsync's aren't cancelable once initiated + if (OperatingSystem.IsWindows()) // On Unix WriteAsync's aren't cancelable once initiated { Task serverWriteToken = server.WriteAsync(buffer, 0, buffer.Length, ctx1.Token); ctx1.Cancel(); @@ -643,7 +642,7 @@ public async Task Client_ReadWriteCancelledToken_Throws_OperationCanceledExcepti if (client.CanWrite) { var ctx1 = new CancellationTokenSource(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // On Unix WriteAsync's aren't cancelable once initiated + if (OperatingSystem.IsWindows()) // On Unix WriteAsync's aren't cancelable once initiated { Task serverWriteToken = client.WriteAsync(buffer, 0, buffer.Length, ctx1.Token); ctx1.Cancel(); diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index 16714db0fee4..ff2644d3a34e 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; @@ -578,11 +577,11 @@ public void NameTooLong_MaxLengthPerPlatform() // Validate the length was expected string path = (string)e.ActualValue; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (OperatingSystem.IsLinux()) { Assert.Equal(108, path.Length); } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + else if (OperatingSystem.IsMacOS()) { Assert.Equal(104, path.Length); } diff --git a/src/libraries/System.IO.Pipes/tests/PipeTest.Read.cs b/src/libraries/System.IO.Pipes/tests/PipeTest.Read.cs index d762f74d30bd..b3ebf7f17200 100644 --- a/src/libraries/System.IO.Pipes/tests/PipeTest.Read.cs +++ b/src/libraries/System.IO.Pipes/tests/PipeTest.Read.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -264,7 +263,7 @@ public void ValidWrite_ValidRead() Task.Run(() => { pair.writeablePipe.Write(sent, 0, sent.Length); }); Assert.Equal(sent.Length, pair.readablePipe.Read(received, 0, sent.Length)); Assert.Equal(sent, received); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // WaitForPipeDrain isn't supported on Unix + if (OperatingSystem.IsWindows()) // WaitForPipeDrain isn't supported on Unix pair.writeablePipe.WaitForPipeDrain(); } } diff --git a/src/libraries/System.IO.Pipes/tests/PipeTest.Write.cs b/src/libraries/System.IO.Pipes/tests/PipeTest.Write.cs index 3ef6b55c2852..69ab803cd7dd 100644 --- a/src/libraries/System.IO.Pipes/tests/PipeTest.Write.cs +++ b/src/libraries/System.IO.Pipes/tests/PipeTest.Write.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -199,7 +198,7 @@ public virtual void WriteToPipeWithClosedPartner_Throws_IOException() { using (ServerClientPair pair = CreateServerClientPair()) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && + if (!OperatingSystem.IsWindows() && (pair.readablePipe is NamedPipeClientStream || pair.writeablePipe is NamedPipeClientStream)) { // On Unix, NamedPipe*Stream is implemented in term of sockets, where information @@ -281,7 +280,7 @@ public virtual void WriteToPipeWithClosedPartner_Span_Throws_IOException() { using (ServerClientPair pair = CreateServerClientPair()) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && + if (!OperatingSystem.IsWindows() && (pair.readablePipe is NamedPipeClientStream || pair.writeablePipe is NamedPipeClientStream)) { // On Unix, NamedPipe*Stream is implemented in term of sockets, where information diff --git a/src/libraries/System.Net.NameResolution/tests/PalTests/NameResolutionPalTests.cs b/src/libraries/System.Net.NameResolution/tests/PalTests/NameResolutionPalTests.cs index 2e5681031006..f88cd14644d3 100644 --- a/src/libraries/System.Net.NameResolution/tests/PalTests/NameResolutionPalTests.cs +++ b/src/libraries/System.Net.NameResolution/tests/PalTests/NameResolutionPalTests.cs @@ -3,7 +3,6 @@ using System.IO; using System.Net.Sockets; -using System.Runtime.InteropServices; using Xunit; using Xunit.Abstractions; @@ -59,7 +58,7 @@ public void TryGetAddrInfo_HostName(bool justAddresses) Assert.NotNull(hostName); SocketError error = NameResolutionPal.TryGetAddrInfo(hostName, justAddresses, out hostName, out string[] aliases, out IPAddress[] addresses, out int nativeErrorCode); - if (error == SocketError.HostNotFound && (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))) + if (error == SocketError.HostNotFound && (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())) { // On Unix, we are not guaranteed to be able to resove the local host. The ability to do so depends on the // machine configurations, which varies by distro and is often inconsistent. diff --git a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs index e202bf585acf..fd7cf08a881c 100644 --- a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs +++ b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs @@ -4,7 +4,6 @@ using System.Net; using System.Net.Sockets; using System.Net.Test.Common; -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -36,7 +35,7 @@ public void IPGlobalProperties_AccessAllMethods_NoErrors() Assert.NotNull(gp.GetActiveUdpListeners()); Assert.NotNull(gp.GetIPv4GlobalStatistics()); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && !RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"))) + if (!OperatingSystem.IsMacOS() && !OperatingSystem.IsFreeBSD()) { // OSX and FreeBSD do not provide IPv6 stats. Assert.NotNull(gp.GetIPv6GlobalStatistics()); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs index 32ec1127b5d5..6bea47f3c4b1 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Net.Sockets; using System.Net.Test.Common; -using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -226,7 +225,7 @@ public async Task SslStream_Http2_Alpn_Success(Uri server) public static IEnumerable Alpn_TestData() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { yield return new object[] { new List { SslApplicationProtocol.Http11, SslApplicationProtocol.Http2 }, new List { SslApplicationProtocol.Http2 }, null }; yield return new object[] { new List { SslApplicationProtocol.Http11 }, new List { SslApplicationProtocol.Http11, SslApplicationProtocol.Http2 }, null }; diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamEKUTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamEKUTest.cs index a79ce8a8e29a..e9c47fc988e9 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamEKUTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamEKUTest.cs @@ -3,7 +3,6 @@ using System.IO; using System.Net.Test.Common; -using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -122,7 +121,7 @@ public async Task SslStream_ServerEKUClientAuth_Fails() await Assert.ThrowsAsync(() => tasks[0]); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // IOException is thrown when trying to read from a disconnected socket. await Assert.ThrowsAsync(() => tasks[1]); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 4843d8121adf..a8c7b1b5e0fc 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -28,9 +27,9 @@ internal static class TestConfiguration public static bool SupportsNullEncryption { get { return s_supportsNullEncryption.Value; } } - public static bool SupportsHandshakeAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } } + public static bool SupportsHandshakeAlerts { get { return OperatingSystem.IsLinux() || OperatingSystem.IsWindows(); } } - public static bool SupportsAlpnAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,0,2)) >= 0); } } + public static bool SupportsAlpnAlerts { get { return OperatingSystem.IsWindows() || (OperatingSystem.IsLinux() && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,0,2)) >= 0); } } public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) => tasks.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); @@ -38,13 +37,13 @@ public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) private static Lazy s_supportsNullEncryption = new Lazy(() => { // On Windows, null ciphers (no encryption) are supported. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { return true; } // On macOS, the null cipher (no encryption) is not supported. - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { return false; } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs index 17b91a5cd73d..5d43c02643b5 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs @@ -55,7 +55,7 @@ private static void CheckTransportContext(TransportContext context) Assert.True(cbt1 != null, "ChannelBindingKind.Endpoint token data should be returned."); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { Assert.True(cbt2 == null, "ChannelBindingKind.Unique token data is not expected on OSX platform."); } diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslServerBase.cs b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslServerBase.cs index 2fd0b360a0d0..dc3dd8c78526 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslServerBase.cs +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslServerBase.cs @@ -12,7 +12,6 @@ using System.Threading; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; -using System.Runtime.InteropServices; namespace SslStress { @@ -158,7 +157,7 @@ protected virtual X509Certificate2 CreateSelfSignedCertificate() certReq.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false)); certReq.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, false)); X509Certificate2 cert = certReq.CreateSelfSigned(DateTimeOffset.UtcNow.AddMonths(-1), DateTimeOffset.UtcNow.AddMonths(1)); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { cert = new X509Certificate2(cert.Export(X509ContentType.Pfx)); } diff --git a/src/libraries/System.Net.WebProxy/tests/WebProxyTest.cs b/src/libraries/System.Net.WebProxy/tests/WebProxyTest.cs index 92061fba0d7f..564a3dc1b347 100644 --- a/src/libraries/System.Net.WebProxy/tests/WebProxyTest.cs +++ b/src/libraries/System.Net.WebProxy/tests/WebProxyTest.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Net.NetworkInformation; using System.Net.Sockets; -using System.Runtime.InteropServices; using Xunit; namespace System.Net.Tests @@ -196,7 +195,7 @@ public static void WebProxy_BypassOnLocal_MatchesExpected(Uri destination, bool // is turned off. Hence dns lookup for it's own hostname fails. Assert.Equal(SocketError.HostNotFound, exception.SocketErrorCode); Assert.Throws(() => Dns.GetHostEntryAsync(Dns.GetHostName()).GetAwaiter().GetResult()); - Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)); + Assert.True(OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()); } } diff --git a/src/libraries/System.Private.Xml/tests/Misc/XmlUrlResolverTests.cs b/src/libraries/System.Private.Xml/tests/Misc/XmlUrlResolverTests.cs index 4e395222ce4c..aa7ed27beb6b 100644 --- a/src/libraries/System.Private.Xml/tests/Misc/XmlUrlResolverTests.cs +++ b/src/libraries/System.Private.Xml/tests/Misc/XmlUrlResolverTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; -using System.Runtime.InteropServices; using Xunit; namespace System.Xml.Tests @@ -45,7 +44,7 @@ public static IEnumerable GetBaseUriAndPath() // Base URI as null is the default for internal Xml operation. var baseUris = new List { null }; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // The case below does not work on Unix, the '#' ends up treated as a fragment and the path is cut there. var currDirWithDirSeparator = Environment.CurrentDirectory + Path.DirectorySeparatorChar; diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.GetEnvironmentVariable.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.GetEnvironmentVariable.cs index 1c757b85a7ea..2f8a5a4800e1 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.GetEnvironmentVariable.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.GetEnvironmentVariable.cs @@ -25,7 +25,7 @@ public void InvalidArguments_ThrowsExceptions() AssertExtensions.Throws("target", null, () => Environment.GetEnvironmentVariable("test", (EnvironmentVariableTarget)42)); AssertExtensions.Throws("target", null, () => Environment.SetEnvironmentVariable("test", "test", (EnvironmentVariableTarget)(-1))); AssertExtensions.Throws("target", null, () => Environment.GetEnvironmentVariables((EnvironmentVariableTarget)(3))); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && System.Tests.SetEnvironmentVariable.IsSupportedTarget(EnvironmentVariableTarget.User)) + if (OperatingSystem.IsWindows() && System.Tests.SetEnvironmentVariable.IsSupportedTarget(EnvironmentVariableTarget.User)) { AssertExtensions.Throws("variable", null, () => Environment.SetEnvironmentVariable(new string('s', 256), "value", EnvironmentVariableTarget.User)); } @@ -84,7 +84,7 @@ public void VariableNamesAreCaseInsensitiveAsAppropriate() Assert.Equal(value, Environment.GetEnvironmentVariable("ThisIsATestEnvironmentVariable")); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!OperatingSystem.IsWindows()) { value = null; } diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.SetEnvironmentVariable.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.SetEnvironmentVariable.cs index aad0ba7e04fb..2d43aed654f8 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.SetEnvironmentVariable.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.SetEnvironmentVariable.cs @@ -22,7 +22,7 @@ internal static bool IsSupportedTarget(EnvironmentVariableTarget target) return false; } - return target == EnvironmentVariableTarget.Process || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + return target == EnvironmentVariableTarget.Process || OperatingSystem.IsWindows(); } [Fact] diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index 9b6574036d61..ec2a052d827d 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -44,7 +44,7 @@ public void CurrentDirectory_SetToValidOtherDirectory() Environment.CurrentDirectory = TestDirectory; Assert.Equal(Directory.GetCurrentDirectory(), Environment.CurrentDirectory); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (!OperatingSystem.IsMacOS()) { // On OSX, the temp directory /tmp/ is a symlink to /private/tmp, so setting the current // directory to a symlinked path will result in GetCurrentDirectory returning the absolute @@ -127,7 +127,7 @@ public void OSVersion_Idempotent() public void OSVersion_MatchesPlatform() { PlatformID id = Environment.OSVersion.Platform; - PlatformID expected = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PlatformID.Win32NT : OperatingSystem.IsBrowser() ? PlatformID.Other : PlatformID.Unix; + PlatformID expected = OperatingSystem.IsWindows() ? PlatformID.Win32NT : OperatingSystem.IsBrowser() ? PlatformID.Other : PlatformID.Unix; Assert.Equal(expected, id); } @@ -142,7 +142,7 @@ public void OSVersion_ValidVersion() Assert.Contains(version.ToString(2), versionString); - string expectedOS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Windows " : OperatingSystem.IsBrowser() ? "Other " : "Unix "; + string expectedOS = OperatingSystem.IsWindows() ? "Windows " : OperatingSystem.IsBrowser() ? "Other " : "Unix "; Assert.Contains(expectedOS, versionString); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/OffsetOfTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/OffsetOfTests.cs index 5ed3fd5313c6..f299734d5a9a 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/OffsetOfTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/OffsetOfTests.cs @@ -62,7 +62,7 @@ public void OffsetOf_ExplicitLayout_ReturnsExpected() public void OffsetOf_ValidField_ReturnsExpected() { Type t = typeof(FieldAlignmentTest); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.ProcessArchitecture != Architecture.X86)) + if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86)) { Assert.Equal(80, Marshal.SizeOf(t)); } @@ -78,7 +78,7 @@ public void OffsetOf_ValidField_ReturnsExpected() Assert.Equal(new IntPtr(12), Marshal.OffsetOf(t, nameof(FieldAlignmentTest.m_byte2))); Assert.Equal(new IntPtr(16), Marshal.OffsetOf(t, nameof(FieldAlignmentTest.m_int2))); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.ProcessArchitecture != Architecture.X86)) + if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86)) { Assert.Equal(new IntPtr(24), Marshal.OffsetOf(t, nameof(FieldAlignmentTest.m_double1))); Assert.Equal(new IntPtr(32), Marshal.OffsetOf(t, nameof(FieldAlignmentTest.m_char1))); @@ -109,7 +109,7 @@ public void OffsetOf_Decimal_ReturnsExpected() { Type t = typeof(FieldAlignmentTest_Decimal); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm)) + if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm)) { Assert.Equal(96, Marshal.SizeOf(t)); } @@ -121,7 +121,7 @@ public void OffsetOf_Decimal_ReturnsExpected() Assert.Equal(new IntPtr(0), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.b))); Assert.Equal(new IntPtr(8), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.p))); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm)) + if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm)) { Assert.Equal(new IntPtr(88), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.s))); } diff --git a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs index ebe6a600e0d2..ce0e53e93cb5 100644 --- a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs @@ -6,7 +6,6 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Text.RegularExpressions; using Microsoft.DotNet.RemoteExecutor; @@ -16,8 +15,8 @@ namespace System.Tests { public static partial class TimeZoneInfoTests { - private static readonly bool s_isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - private static readonly bool s_isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + private static readonly bool s_isWindows = OperatingSystem.IsWindows(); + private static readonly bool s_isOSX = OperatingSystem.IsMacOS(); private static string s_strPacific = s_isWindows ? "Pacific Standard Time" : "America/Los_Angeles"; private static string s_strSydney = s_isWindows ? "AUS Eastern Standard Time" : "Australia/Sydney"; diff --git a/src/libraries/System.Security.Cryptography.Algorithms/tests/CryptoConfigTests.cs b/src/libraries/System.Security.Cryptography.Algorithms/tests/CryptoConfigTests.cs index a9e70c0aa48a..74d475b237ab 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/tests/CryptoConfigTests.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/tests/CryptoConfigTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Reflection; -using System.Runtime.InteropServices; using System.Text; using Test.Cryptography; using Xunit; @@ -255,7 +254,7 @@ public static IEnumerable AllValidNames [Theory, MemberData(nameof(AllValidNames))] public static void CreateFromName_AllValidNames(string name, string typeName, bool supportsUnixMac) { - bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + bool isWindows = OperatingSystem.IsWindows(); if (supportsUnixMac || isWindows) { diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs index a72697e65193..69b109213903 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using Xunit; namespace System.Security.Cryptography.Encoding.Tests @@ -315,7 +314,7 @@ public static void LookupOidByValue_Method_UnixOnly() } catch (CryptographicException) { - bool isMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + bool isMac = OperatingSystem.IsMacOS(); Assert.True(isMac, "Exception is only raised on macOS"); @@ -348,7 +347,7 @@ public static void LookupOidByFriendlyName_Method_UnixOnly() } catch (CryptographicException) { - bool isMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + bool isMac = OperatingSystem.IsMacOS(); Assert.True(isMac, "Exception is only raised on macOS"); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs index f9a260a7c3a5..be71f91529a1 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; @@ -16,7 +15,7 @@ internal abstract partial class CertLoader private static X509KeyStorageFlags GetBestKeyStorageFlags() { #if NETCOREAPP - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // On Windows 7 ephemeral keys with a key usage embedded in the PFX // are treated differently than Windows 8. So just use the default @@ -28,7 +27,7 @@ private static X509KeyStorageFlags GetBestKeyStorageFlags() return X509KeyStorageFlags.EphemeralKeySet; } } - else if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + else if (!OperatingSystem.IsMacOS()) { // OSX doesn't allow ephemeral, but every other Unix does. return X509KeyStorageFlags.EphemeralKeySet; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/Cert.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/Cert.cs index c18541a8010f..8e385dc95898 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/Cert.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/Cert.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.Runtime.InteropServices; - namespace System.Security.Cryptography.X509Certificates.Tests { // @@ -17,7 +15,7 @@ internal static class Cert // netcoreapp-other: EphemeralKeySet internal static readonly X509KeyStorageFlags EphemeralIfPossible = #if !NO_EPHEMERALKEYSET_AVAILABLE - !RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? X509KeyStorageFlags.EphemeralKeySet : + !OperatingSystem.IsMacOS() ? X509KeyStorageFlags.EphemeralKeySet : #endif X509KeyStorageFlags.DefaultKeySet; // diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ChainTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ChainTests.cs index 77143fd0326d..af0c0a9de2bf 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ChainTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ChainTests.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Text; using System.Threading; using Test.Cryptography; @@ -249,7 +248,7 @@ public static void SystemTrustCertificateWithCustomRootTrust(bool addCertificate Assert.False(chain.Build(microsoftDotCom)); // Linux and Windows do not search the default system root stores when CustomRootTrust is enabled - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { Assert.Equal(3, chain.ChainElements.Count); Assert.Equal(X509ChainStatusFlags.UntrustedRoot, chain.AllStatusFlags()); @@ -843,11 +842,11 @@ public static void InvalidSelfSignedSignature() { X509ChainStatusFlags expectedFlags; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { expectedFlags = X509ChainStatusFlags.NotSignatureValid; } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + else if (OperatingSystem.IsMacOS()) { // For OSX alone expectedFlags here means OR instead of AND. // Because the error code changed in 10.13.4 from UntrustedRoot to PartialChain @@ -879,7 +878,7 @@ public static void InvalidSelfSignedSignature() X509ChainStatusFlags allFlags = chain.AllStatusFlags(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { // If we're on 10.13.3 or older we get UntrustedRoot. // If we're on 10.13.4 or newer we get PartialChain. @@ -1023,7 +1022,7 @@ void CheckChain() bool valid = chain.Build(cert); X509ChainStatusFlags allFlags = chain.AllStatusFlags(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { // OSX considers this to be valid because it doesn't report NotSignatureValid, // just PartialChain ("I couldn't find an issuer that made the signature work"), diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CollectionImportTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CollectionImportTests.cs index 13ab67f9cc45..4690f502db23 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CollectionImportTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CollectionImportTests.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using Xunit; namespace System.Security.Cryptography.X509Certificates.Tests @@ -436,7 +435,7 @@ public static IEnumerable StorageFlags yield return new object[] { X509KeyStorageFlags.DefaultKeySet }; #if !NO_EPHEMERALKEYSET_AVAILABLE - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (!OperatingSystem.IsMacOS()) yield return new object[] { X509KeyStorageFlags.EphemeralKeySet }; #endif } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CtorTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CtorTests.cs index ddcce5fe1d67..2a25bec4e8bc 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/CtorTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/CtorTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using Xunit; namespace System.Security.Cryptography.X509Certificates.Tests @@ -354,13 +353,13 @@ public static void InvalidCertificateBlob() CryptographicException defaultException = new CryptographicException(); Assert.NotEqual(defaultException.Message, ex.Message); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { Assert.Equal(unchecked((int)0x80092009), ex.HResult); // TODO (3233): Test that Message is also set correctly //Assert.Equal("Cannot find the requested object.", ex.Message); } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + else if (OperatingSystem.IsMacOS()) { Assert.Equal(-25257, ex.HResult); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs index 9d88ca710143..b71d2555c794 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; -using System.Runtime.InteropServices; using Test.Cryptography; using Xunit; @@ -97,7 +96,7 @@ DateTime RewindIfNeeded(DateTime input, X509Certificate2 cert, X509ChainStatusFl intermediateCert = TamperIfNeeded(intermediateCert, intermediateErrors); rootCert = TamperIfNeeded(rootCert, rootErrors); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { // For the lower levels, turn NotSignatureValid into PartialChain, // and clear all errors at higher levels. @@ -129,7 +128,7 @@ DateTime RewindIfNeeded(DateTime input, X509Certificate2 cert, X509ChainStatusFl } } } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + else if (OperatingSystem.IsWindows()) { // Windows only reports NotTimeValid on the start-of-chain (end-entity in this case) // If it were possible in this suite to get only a higher-level cert as NotTimeValid diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/FindTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/FindTests.cs index 8a2a60822519..265c345504c7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/FindTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/FindTests.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Text; using Xunit; @@ -94,7 +93,7 @@ private static void EvaluateSingleMatch( Assert.NotSame(expected, match); // FriendlyName is Windows-only. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // Verify that the find result and original are linked, not just equal. match.FriendlyName = "HAHA"; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.SingleCertGenerator.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.SingleCertGenerator.cs index ee9f01d3edd8..de3a5f18004e 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.SingleCertGenerator.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.SingleCertGenerator.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Security.Cryptography.Pkcs; using Xunit; @@ -76,7 +75,7 @@ public void OneCertWithOneKey(SingleCertOptions options) using (var cert = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword, s_exportableImportFlags)) using (RSA key = cert.GetRSAPrivateKey()) { - if (dontShroudKey && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (dontShroudKey && OperatingSystem.IsWindows()) { // CNG keys are only encrypted-exportable, so we need to export them encrypted. // Then we can import it into a new, fully-exportable key. (Sigh.) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.cs index e4c76449ca6a..e1ab045100fd 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; -using System.Runtime.InteropServices; using System.Security.Cryptography.Pkcs; using Test.Cryptography; using Xunit; @@ -39,7 +38,7 @@ public abstract partial class PfxFormatTests // // Our Unix loader matches the current Windows 10 behavior. private static readonly bool s_loaderFailsKeysEarly = - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && + OperatingSystem.IsWindows() && !PlatformDetection.IsWindows10Version1607OrGreater; protected abstract void ReadPfx( @@ -220,7 +219,7 @@ public void OneCert_MismatchedKey() byte[] pfxBytes = builder.Encode(); // On macOS the cert will come back with HasPrivateKey being false. - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (OperatingSystem.IsMacOS()) { using (var publicCert = new X509Certificate2(cert.RawData)) { @@ -282,7 +281,7 @@ public void OneCert_TwoKeys_FirstWins(bool correctKeyFirst) // On macOS the cert will come back with HasPrivateKey being false when the // incorrect key comes first - if (!correctKeyFirst && RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (!correctKeyFirst && OperatingSystem.IsMacOS()) { using (var publicCert = new X509Certificate2(cert.RawData)) { @@ -906,7 +905,7 @@ public void TwoCerts_TwoKeys_ManySafeContentsValues(bool invertCertOrder, bool i // Obviously this hit some sort of weird corner case in the Win7 // loader, but it's not important to the test. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && + if (OperatingSystem.IsWindows() && !PlatformDetection.IsWindows8xOrLater) { followup = null; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_Collection.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_Collection.cs index 35dc1f4f1111..37ca1cc30232 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_Collection.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_Collection.cs @@ -97,7 +97,7 @@ protected override void ReadUnreadablePfx( CryptographicException ex = Assert.ThrowsAny( () => coll.Import(pfxBytes, bestPassword, s_importFlags)); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { if (altWin32Error != 0 && ex.HResult != altWin32Error) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_SingleCert.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_SingleCert.cs index 71382537744d..39f736d259df 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_SingleCert.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxFormatTests_SingleCert.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using Xunit; namespace System.Security.Cryptography.X509Certificates.Tests @@ -69,7 +68,7 @@ protected override void ReadUnreadablePfx( CryptographicException ex = Assert.ThrowsAny( () => new X509Certificate2(pfxBytes, bestPassword, s_importFlags)); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { if (altWin32Error != 0 && ex.HResult != altWin32Error) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs index 195ab0331e9f..e0af53372b30 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.InteropServices; using Test.Cryptography; using Xunit; @@ -222,7 +221,7 @@ private static void Verify_ECDsaPrivateKey_WindowsPfx(ECDsa ecdsa) { Assert.NotNull(ecdsa); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { AssertEccAlgorithm(ecdsa, "ECDSA_P256"); } @@ -239,7 +238,7 @@ public static void ReadECDsaPrivateKey_BrainpoolP160r1_Pfx(byte[] pfxData) { Assert.NotNull(ecdsa); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { AssertEccAlgorithm(ecdsa, "ECDH"); } @@ -263,7 +262,7 @@ public static void ReadECDsaPrivateKey_OpenSslPfx(X509KeyStorageFlags keyStorage { Assert.NotNull(ecdsa); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // If Windows were to start detecting this case as ECDSA that wouldn't be bad, // but this assert is the only proof that this certificate was made with OpenSSL. 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 ac869243d76e..514698aab0b2 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates.Tests.Common; using Xunit; @@ -526,7 +525,7 @@ public static void RevokeIntermediate_PolicyErrors_NotTimeValid(bool policyError // [ActiveIssue("https://github.com/dotnet/runtime/issues/31246")] // Linux reports this code at more levels than Windows does. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (OperatingSystem.IsLinux()) { issuerExtraProblems |= X509ChainStatusFlags.NotValidForUsage; } @@ -610,7 +609,7 @@ public static void RevokeEndEntity_PolicyErrors_NotTimeValid(bool policyErrors, // [ActiveIssue("https://github.com/dotnet/runtime/issues/31246")] // Linux reports this code at more levels than Windows does. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (OperatingSystem.IsLinux()) { issuerExtraProblems |= X509ChainStatusFlags.NotValidForUsage; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/X500DistinguishedNameEncodingTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/X500DistinguishedNameEncodingTests.cs index 482b31786a68..868e75ea994d 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/X500DistinguishedNameEncodingTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/X500DistinguishedNameEncodingTests.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.Runtime.InteropServices; using Test.Cryptography; using Xunit; @@ -135,7 +134,7 @@ private static void ProcessTestCase(SimpleEncoderTestCase testCase, X500Distingu string expectedHex; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { expectedHex = testCase.GetBmpEncoding() ?? testCase.GetPreferredEncoding(); } From 4a61d1083a9d0edd34a5a6624e3f3d7a63bda23e Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Mon, 10 Aug 2020 09:27:24 -0700 Subject: [PATCH 362/755] System.Diagnostics Tracing APIs additions (#40534) --- ...em.Diagnostics.DiagnosticSourceActivity.cs | 11 +- ...System.Diagnostics.DiagnosticSource.csproj | 2 +- .../src/System/Diagnostics/Activity.cs | 46 ++- .../Diagnostics/ActivityCreationOptions.cs | 59 ++++ .../System/Diagnostics/ActivityListener.cs | 14 +- ...taRequest.cs => ActivitySamplingResult.cs} | 2 +- .../src/System/Diagnostics/ActivitySource.cs | 133 ++++----- .../tests/ActivitySourceTests.cs | 277 +++++++++++++++--- 8 files changed, 419 insertions(+), 125 deletions(-) rename src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/{ActivityDataRequest.cs => ActivitySamplingResult.cs} (97%) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs index 8e0f944e09cf..962b663e3a4a 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs @@ -179,7 +179,7 @@ public virtual void OnActivityImport(System.Diagnostics.Activity activity, objec public System.Diagnostics.Activity StartActivity(System.Diagnostics.Activity activity, object? args) { throw null; } public void StopActivity(System.Diagnostics.Activity activity, object? args) { } } - public enum ActivityDataRequest + public enum ActivitySamplingResult { None, PropagationData, @@ -237,17 +237,18 @@ public readonly struct ActivityCreationOptions public T Parent { get { throw null; } } public System.Collections.Generic.IEnumerable> Tags { get { throw null; } } public System.Collections.Generic.IEnumerable Links { get { throw null; } } + public System.Diagnostics.ActivityTagsCollection SamplingTags { get { throw null; } } + public System.Diagnostics.ActivityTraceId TraceId { get { throw null; } } } - public delegate System.Diagnostics.ActivityDataRequest GetRequestedData(ref System.Diagnostics.ActivityCreationOptions options); + public delegate System.Diagnostics.ActivitySamplingResult SampleActivity(ref System.Diagnostics.ActivityCreationOptions options); public sealed class ActivityListener : IDisposable { public ActivityListener() { throw null; } public System.Action? ActivityStarted { get { throw null; } set { throw null; } } public System.Action? ActivityStopped { get { throw null; } set { throw null; } } public System.Func? ShouldListenTo { get { throw null; } set { throw null; } } - public System.Diagnostics.GetRequestedData? GetRequestedDataUsingParentId { get { throw null; } set { throw null; } } - public System.Diagnostics.GetRequestedData? GetRequestedDataUsingContext { get { throw null; } set { throw null; } } - public bool AutoGenerateRootContextTraceId { get { throw null; } set { throw null; } } + public System.Diagnostics.SampleActivity? SampleUsingParentId { get { throw null; } set { throw null; } } + public System.Diagnostics.SampleActivity? Sample { get { throw null; } set { throw null; } } public void Dispose() { throw null; } } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 275bebeb1fec..d8eaff003d81 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -38,7 +38,7 @@ - + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index 23834958a4f4..a97c22223d59 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -929,7 +929,7 @@ public void SetCustomProperty(string propertyName, object? propertyValue) internal static Activity CreateAndStart(ActivitySource source, string name, ActivityKind kind, string? parentId, ActivityContext parentContext, IEnumerable>? tags, IEnumerable? links, - DateTimeOffset startTime, ActivityDataRequest request) + DateTimeOffset startTime, ActivityTagsCollection? samplerTags, ActivitySamplingResult request) { Activity activity = new Activity(name); @@ -994,11 +994,23 @@ internal static Activity CreateAndStart(ActivitySource source, string name, Acti } } + if (samplerTags != null) + { + if (activity._tags == null) + { + activity._tags = new TagsLinkedList(samplerTags!); + } + else + { + activity._tags.Add(samplerTags!); + } + } + activity.StartTimeUtc = startTime == default ? DateTime.UtcNow : startTime.UtcDateTime; - activity.IsAllDataRequested = request == ActivityDataRequest.AllData || request == ActivityDataRequest.AllDataAndRecorded; + activity.IsAllDataRequested = request == ActivitySamplingResult.AllData || request == ActivitySamplingResult.AllDataAndRecorded; - if (request == ActivityDataRequest.AllDataAndRecorded) + if (request == ActivitySamplingResult.AllDataAndRecorded) { activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; } @@ -1295,6 +1307,34 @@ public TagsLinkedList(IEnumerator> e) } } + public TagsLinkedList(IEnumerable> list) => Add(list); + + // Add doesn't take the lock because it is called from the Activity creation before sharing the activity object to the caller. + public void Add(IEnumerable> list) + { + IEnumerator> e = list.GetEnumerator(); + if (!e.MoveNext()) + { + return; + } + + if (_first == null) + { + _last = _first = new LinkedListNode>(e.Current); + } + else + { + _last!.Next = new LinkedListNode>(e.Current); + _last = _last.Next; + } + + while (e.MoveNext()) + { + _last.Next = new LinkedListNode>(e.Current); + _last = _last.Next; + } + } + public void Add(KeyValuePair value) { LinkedListNode> newNode = new LinkedListNode>(value); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityCreationOptions.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityCreationOptions.cs index 5d484594e455..a57854261f41 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityCreationOptions.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityCreationOptions.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.Collections.Generic; +using System.Runtime.CompilerServices; namespace System.Diagnostics { @@ -10,6 +11,9 @@ namespace System.Diagnostics /// public readonly struct ActivityCreationOptions { + private readonly ActivityTagsCollection? _samplerTags; + private readonly ActivityContext _context; + /// /// Construct a new object. /// @@ -27,6 +31,22 @@ internal ActivityCreationOptions(ActivitySource source, string name, T parent, A Parent = parent; Tags = tags; Links = links; + + _samplerTags = null; + + if (parent is ActivityContext ac) + { + _context = ac; + } + else if (parent is string p && p != null) + { + // We don't care about the return value. we care if _context is initialized accordingly. + ActivityContext.TryParse(p, null, out _context); + } + else + { + _context = default; + } } /// @@ -58,5 +78,44 @@ internal ActivityCreationOptions(ActivitySource source, string name, T parent, A /// Retrieve the list of which requested to create the Activity object with. /// public IEnumerable? Links { get; } + + public ActivityTagsCollection SamplingTags + { +#if ALLOW_PARTIALLY_TRUSTED_CALLERS + [System.Security.SecuritySafeCriticalAttribute] +#endif + get + { + if (_samplerTags == null) + { + // Because the struct is readonly, we cannot directly assign _samplerTags. We have to workaround it by calling Unsafe.AsRef + Unsafe.AsRef(in _samplerTags) = new ActivityTagsCollection(); + } + + return _samplerTags!; + } + } + + public ActivityTraceId TraceId + { +#if ALLOW_PARTIALLY_TRUSTED_CALLERS + [System.Security.SecuritySafeCriticalAttribute] +#endif + get + { + if (Parent is ActivityContext && _context == default) + { + // Because the struct is readonly, we cannot directly assign _context. We have to workaround it by calling Unsafe.AsRef + Unsafe.AsRef(in _context) = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None); + } + + return _context.TraceId; + } + } + + // Helper to access the sampling tags. The SamplingTags Getter can allocate when not necessary. + internal ActivityTagsCollection? GetSamplingTags() => _samplerTags; + + internal ActivityContext GetContext() => _context; } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs index 72ff9b29a418..2ad38502fc2b 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs @@ -8,7 +8,7 @@ namespace System.Diagnostics /// /// Define the callback that can be used in to allow deciding to create the Activity objects and with what data state. /// - public delegate ActivityDataRequest GetRequestedData(ref ActivityCreationOptions options); + public delegate ActivitySamplingResult SampleActivity(ref ActivityCreationOptions options); /// /// ActivityListener allows listening to the start and stop Activity events and give the oppertunity to decide creating the Activity for sampling scenarios. @@ -40,20 +40,12 @@ public ActivityListener() /// /// Set or get the callback used to decide allowing creating objects with specific data state. /// - public GetRequestedData? GetRequestedDataUsingParentId { get; set; } + public SampleActivity? SampleUsingParentId { get; set; } /// /// Set or get the callback used to decide allowing creating objects with specific data state. /// - public GetRequestedData? GetRequestedDataUsingContext { get; set; } - - /// - /// Determine if the listener automatically generates a new trace Id before sampling when there is no parent context. - /// - /// - /// If this property is set to true and caused generating a new trace Id, the created object from such call will have the same generated trace Id. - /// - public bool AutoGenerateRootContextTraceId { get; set;} + public SampleActivity? Sample { get; set; } /// /// Dispose will unregister this object from listeneing to events. diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityDataRequest.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySamplingResult.cs similarity index 97% rename from src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityDataRequest.cs rename to src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySamplingResult.cs index a4c03ffa2554..19bee5c8d5d3 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityDataRequest.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySamplingResult.cs @@ -7,7 +7,7 @@ namespace System.Diagnostics /// Used by ActivityListener to indicate what amount of data should be collected for this Activity /// Requesting more data causes greater performance overhead to collect it. /// - public enum ActivityDataRequest + public enum ActivitySamplingResult { /// /// The Activity object doesn't need to be created diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs index ac110fd590e5..d1b4d63d911d 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs @@ -113,96 +113,96 @@ public bool HasListeners() } Activity? activity = null; + ActivityTagsCollection? samplerTags; - ActivityDataRequest dataRequest = ActivityDataRequest.None; - bool? useContext = default; - ActivityCreationOptions optionsWithContext = default; + ActivitySamplingResult samplingResult = ActivitySamplingResult.None; if (parentId != null) { var aco = new ActivityCreationOptions(this, name, parentId, kind, tags, links); - listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions data, ref ActivityDataRequest request, ref bool? canUseContext, ref ActivityCreationOptions dataWithContext) => { - GetRequestedData? getRequestedDataUsingParentId = listener.GetRequestedDataUsingParentId; - if (getRequestedDataUsingParentId != null) + var acoContext = new ActivityCreationOptions(this, name, aco.GetContext(), kind, tags, links); + + listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions data, ref ActivitySamplingResult result, ref ActivityCreationOptions dataWithContext) => { + SampleActivity? sampleUsingParentId = listener.SampleUsingParentId; + if (sampleUsingParentId != null) { - ActivityDataRequest dr = getRequestedDataUsingParentId(ref data); - if (dr > request) + ActivitySamplingResult sr = sampleUsingParentId(ref data); + if (sr > result) { - request = dr; + result = sr; } - - // Stop the enumeration if we get the max value RecordingAndSampling. - return request != ActivityDataRequest.AllDataAndRecorded; } else { - // In case we have a parent Id and the listener not providing the GetRequestedDataUsingParentId, we'll try to find out if the following conditions are true: - // - The listener is providing the GetRequestedDataUsingContext callback - // - Can convert the parent Id to a Context - // Then we can call the listener GetRequestedDataUsingContext callback with the constructed context. - GetRequestedData? getRequestedDataUsingContext = listener.GetRequestedDataUsingContext; - if (getRequestedDataUsingContext != null) + // In case we have a parent Id and the listener not providing the SampleUsingParentId, we'll try to find out if the following conditions are true: + // - The listener is providing the Sample callback + // - Can convert the parent Id to a Context. ActivityCreationOptions.TraceId != default means parent id converted to a valid context. + // Then we can call the listener Sample callback with the constructed context. + SampleActivity? sample = listener.Sample; + if (sample != null && data.GetContext() != default) // data.GetContext() != default means parent Id parsed correctly to a context { - if (!canUseContext.HasValue) + ActivitySamplingResult sr = sample(ref dataWithContext); + if (sr > result) { - canUseContext = Activity.TryConvertIdToContext(parentId, traceState: null, out ActivityContext ctx); - if (canUseContext.Value) - { - dataWithContext = new ActivityCreationOptions(data.Source, data.Name, ctx, data.Kind, data.Tags, data.Links); - } + result = sr; } + } + } + }, ref aco, ref samplingResult, ref acoContext); - if (canUseContext.Value) - { - ActivityDataRequest dr = getRequestedDataUsingContext(ref dataWithContext); - if (dr > request) - { - request = dr; - } - // Stop the enumeration if we get the max value RecordingAndSampling. - return request != ActivityDataRequest.AllDataAndRecorded; - } + if (context == default && aco.GetContext() != default) + { + context = aco.GetContext(); + parentId = null; + } + + samplerTags = aco.GetSamplingTags(); + ActivityTagsCollection? atc = acoContext.GetSamplingTags(); + if (atc != null) + { + if (samplerTags == null) + { + samplerTags = atc; + } + else + { + foreach (KeyValuePair tag in atc) + { + samplerTags.Add(tag); } } - return true; - }, ref aco, ref dataRequest, ref useContext, ref optionsWithContext); + } } else { - ActivityContext initializedContext = context == default && Activity.Current != null ? Activity.Current.Context : context; - optionsWithContext = new ActivityCreationOptions(this, name, initializedContext, kind, tags, links); - listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions data, ref ActivityDataRequest request, ref bool? canUseContext, ref ActivityCreationOptions dataWithContext) => { - GetRequestedData? getRequestedDataUsingContext = listener.GetRequestedDataUsingContext; - if (getRequestedDataUsingContext != null) + bool useCurrentActivityContext = context == default && Activity.Current != null; + var aco = new ActivityCreationOptions(this, name, useCurrentActivityContext ? Activity.Current!.Context : context, kind, tags, links); + listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions data, ref ActivitySamplingResult result, ref ActivityCreationOptions unused) => { + SampleActivity? sample = listener.Sample; + if (sample != null) { - if (listener.AutoGenerateRootContextTraceId && !canUseContext.HasValue && data.Parent == default) - { - ActivityContext ctx = new ActivityContext(ActivityTraceId.CreateRandom(), default, default); - dataWithContext = new ActivityCreationOptions(data.Source, data.Name, ctx, data.Kind, data.Tags, data.Links); - canUseContext = true; - } - ActivityDataRequest dr = getRequestedDataUsingContext(ref data); - if (dr > request) + ActivitySamplingResult dr = sample(ref data); + if (dr > result) { - request = dr; + result = dr; } - - // Stop the enumeration if we get the max value RecordingAndSampling. - return request != ActivityDataRequest.AllDataAndRecorded; } - return true; - }, ref optionsWithContext, ref dataRequest, ref useContext, ref optionsWithContext); - } + }, ref aco, ref samplingResult, ref aco); - if (dataRequest != ActivityDataRequest.None) - { - if (useContext.HasValue && useContext.Value) + if (!useCurrentActivityContext) { - context = optionsWithContext.Parent; - parentId = null; + // We use the context stored inside ActivityCreationOptions as it is possible the trace id get automatically generated during the sampling. + // We don't use the context stored inside ActivityCreationOptions only in case if we used Activity.Current context, the reason is we need to + // create the new child activity with Parent set to Activity.Current. + context = aco.GetContext(); } - activity = Activity.CreateAndStart(this, name, kind, parentId, context, tags, links, startTime, dataRequest); + samplerTags = aco.GetSamplingTags(); + } + + if (samplingResult != ActivitySamplingResult.None) + { + activity = Activity.CreateAndStart(this, name, kind, parentId, context, tags, links, startTime, samplerTags, samplingResult); listeners.EnumWithAction((listener, obj) => listener.ActivityStarted?.Invoke((Activity) obj), activity); } @@ -241,7 +241,7 @@ public static void AddActivityListener(ActivityListener listener) } } - internal delegate bool Function(T item, ref ActivityCreationOptions data, ref ActivityDataRequest dataRequest, ref bool? ctxInitialized, ref ActivityCreationOptions dataWithContext); + internal delegate void Function(T item, ref ActivityCreationOptions data, ref ActivitySamplingResult samplingResult, ref ActivityCreationOptions dataWithContext); internal void AddListener(ActivityListener listener) { @@ -333,7 +333,7 @@ public bool Remove(T item) public int Count => _list.Count; - public void EnumWithFunc(ActivitySource.Function func, ref ActivityCreationOptions data, ref ActivityDataRequest dataRequest, ref bool? ctxInitialized, ref ActivityCreationOptions dataWithContext) + public void EnumWithFunc(ActivitySource.Function func, ref ActivityCreationOptions data, ref ActivitySamplingResult samplingResult, ref ActivityCreationOptions dataWithContext) { uint version = _version; int index = 0; @@ -356,10 +356,7 @@ public void EnumWithFunc(ActivitySource.Function func, ref // Important to call the func outside the lock. // This is the whole point we are having this wrapper class. - if (!func(item, ref data, ref dataRequest, ref ctxInitialized, ref dataWithContext)) - { - break; - } + func(item, ref data, ref samplingResult, ref dataWithContext); } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs index 99bafcd319d5..84d3935b8c84 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs @@ -60,8 +60,8 @@ public void TestActivityWithListenerNoActivityCreate() listener.ActivityStarted = activity => Assert.NotNull(activity); listener.ActivityStopped = activity => Assert.NotNull(activity); listener.ShouldListenTo = (activitySource) => object.ReferenceEquals(aSource, activitySource); - listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.None; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.None; + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.None; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.None; ActivitySource.AddActivityListener(listener); Assert.True(aSource.HasListeners()); @@ -84,8 +84,8 @@ public void TestActivityWithListenerActivityCreateAndAllDataRequested() listener.ActivityStarted = activity => counter++; listener.ActivityStopped = activity => counter--; listener.ShouldListenTo = (activitySource) => object.ReferenceEquals(aSource, activitySource); - listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllDataAndRecorded; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllDataAndRecorded; + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllDataAndRecorded; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllDataAndRecorded; ActivitySource.AddActivityListener(listener); @@ -141,8 +141,8 @@ public void TestActivitySourceAttachedObject() listener.ActivityStarted = activity => Assert.NotNull(activity); listener.ActivityStopped = activity => Assert.NotNull(activity); listener.ShouldListenTo = (activitySource) => object.ReferenceEquals(aSource, activitySource); - listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; ActivitySource.AddActivityListener(listener); @@ -163,8 +163,8 @@ public void TestListeningToConstructedActivityEvents() listener.ActivityStarted = activity => activityStartCount++; listener.ActivityStopped = activity => activityStopCount++; listener.ShouldListenTo = (activitySource) => activitySource.Name == "" && activitySource.Version == ""; - listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; ActivitySource.AddActivityListener(listener); @@ -213,8 +213,8 @@ public void TestExpectedListenersReturnValues() ActivityStarted = (activity) => { activityStartCount++; Assert.NotNull(activity); }, ActivityStopped = (activity) => { activityStopCount++; Assert.NotNull(activity); }, ShouldListenTo = (activitySource) => true, - GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.None, - GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.None + SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.None, + Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.None }; ActivitySource.AddActivityListener(listeners[0]); @@ -228,8 +228,8 @@ public void TestExpectedListenersReturnValues() ActivityStarted = (activity) => { activityStartCount++; Assert.NotNull(activity); }, ActivityStopped = (activity) => { activityStopCount++; Assert.NotNull(activity); }, ShouldListenTo = (activitySource) => true, - GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.PropagationData, - GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.PropagationData + SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.PropagationData, + Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.PropagationData }; ActivitySource.AddActivityListener(listeners[1]); @@ -250,8 +250,8 @@ public void TestExpectedListenersReturnValues() ActivityStarted = (activity) => { activityStartCount++; Assert.NotNull(activity); }, ActivityStopped = (activity) => { activityStopCount++; Assert.NotNull(activity); }, ShouldListenTo = (activitySource) => true, - GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData, - GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData + SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData, + Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData }; ActivitySource.AddActivityListener(listeners[2]); @@ -272,8 +272,8 @@ public void TestExpectedListenersReturnValues() ActivityStarted = (activity) => { activityStartCount++; Assert.NotNull(activity); }, ActivityStopped = (activity) => { activityStopCount++; Assert.NotNull(activity); }, ShouldListenTo = (activitySource) => true, - GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllDataAndRecorded, - GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllDataAndRecorded + SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllDataAndRecorded, + Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllDataAndRecorded }; ActivitySource.AddActivityListener(listeners[3]); @@ -307,8 +307,8 @@ public void TestActivityCreationProperties() listener.ActivityStarted = activity => Assert.NotNull(activity); listener.ActivityStopped = activity => Assert.NotNull(activity); listener.ShouldListenTo = (activitySource) => true; - listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; ActivitySource.AddActivityListener(listener); @@ -363,7 +363,7 @@ public void TestDefaultParentContext() using ActivityListener listener = new ActivityListener(); listener.ShouldListenTo = (activitySource) => activitySource.Name == "ParentContext"; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => + listener.Sample = (ref ActivityCreationOptions activityOptions) => { Activity c = Activity.Current; if (c != null) @@ -371,11 +371,10 @@ public void TestDefaultParentContext() Assert.Equal(c.Context, activityOptions.Parent); } - return ActivityDataRequest.AllData; + return ActivitySamplingResult.AllData; }; ActivitySource.AddActivityListener(listener); - using Activity a = aSource.StartActivity("a", ActivityKind.Server, new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), 0)); using Activity b = aSource.StartActivity("b"); Assert.Equal(a.Context, b.Parent.Context); @@ -426,19 +425,19 @@ public void TestCreatingActivityUsingDifferentParentIds() using ActivityListener listener3 = new ActivityListener(); // will have both context and parent Id callbacks listener1.ShouldListenTo = listener2.ShouldListenTo = listener3.ShouldListenTo = (activitySource) => activitySource.Name == "ParentIdsTest"; - listener1.GetRequestedDataUsingContext = listener3.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => + listener1.Sample = listener3.Sample = (ref ActivityCreationOptions activityOptions) => { callingByContext++; Assert.Equal(new ActivityContext(ActivityTraceId.CreateFromString(w3cId.AsSpan(3, 32)), ActivitySpanId.CreateFromString(w3cId.AsSpan(36, 16)), ActivityTraceFlags.Recorded), activityOptions.Parent); - return ActivityDataRequest.AllData; + return ActivitySamplingResult.AllData; }; - listener2.GetRequestedDataUsingParentId = listener3.GetRequestedDataUsingParentId = (ref ActivityCreationOptions activityOptions) => + listener2.SampleUsingParentId = listener3.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => { callingByParentId++; - return ActivityDataRequest.AllData; + return ActivitySamplingResult.AllData; }; ActivitySource.AddActivityListener(listener1); @@ -476,10 +475,10 @@ public void TestActivityContextIsRemote() using ActivityListener listener = new ActivityListener(); listener.ShouldListenTo = (activitySource) => activitySource.Name == "RemoteContext"; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => + listener.Sample = (ref ActivityCreationOptions activityOptions) => { isRemote = activityOptions.Parent.IsRemote; - return ActivityDataRequest.AllData; + return ActivitySamplingResult.AllData; }; ActivitySource.AddActivityListener(listener); @@ -506,10 +505,12 @@ public void TestTraceIdAutoGeneration() ActivityContext ctx = default; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => + bool forceGenerateTraceId = false; + + listener.Sample = (ref ActivityCreationOptions activityOptions) => { - ctx = activityOptions.Parent; - return ActivityDataRequest.AllData; + ctx = forceGenerateTraceId ? new ActivityContext(activityOptions.TraceId, default, default) : activityOptions.Parent; + return ActivitySamplingResult.AllData; }; ActivitySource.AddActivityListener(listener); @@ -519,7 +520,7 @@ public void TestTraceIdAutoGeneration() Assert.Equal(default, ctx); } - listener.AutoGenerateRootContextTraceId = true; + forceGenerateTraceId = true; Activity activity = aSource.StartActivity("a2", default, ctx); @@ -542,13 +543,12 @@ public void TestTraceIdAutoGenerationWithNullParentId() ActivityContext ctx = default; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => + listener.Sample = (ref ActivityCreationOptions activityOptions) => { - ctx = activityOptions.Parent; - return ActivityDataRequest.AllData; + ctx = new ActivityContext(activityOptions.TraceId, default, default); + return ActivitySamplingResult.AllData; }; - listener.AutoGenerateRootContextTraceId = true; ActivitySource.AddActivityListener(listener); Activity activity = aSource.StartActivity("a2", default, null); @@ -573,7 +573,7 @@ public void TestEventNotificationOrder() using ActivityListener listener = new ActivityListener(); listener.ShouldListenTo = (activitySource) => activitySource.Name == "EventNotificationOrder"; - listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions activityOptions) => ActivityDataRequest.AllData; + listener.Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData; listener.ActivityStopped = a => Assert.Equal(child, Activity.Current); ActivitySource.AddActivityListener(listener); @@ -590,6 +590,211 @@ public void TestEventNotificationOrder() }).Dispose(); } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestAddingSamplerTags() + { + RemoteExecutor.Invoke(() => { + + using ActivitySource aSource = new ActivitySource("SamplerTags1"); + using ActivityListener listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags1"; + + listener.Sample = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("tag1", "value1"); + activityOptions.SamplingTags.Add("tag2", "value2"); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener); + + using Activity activity = aSource.StartActivity("a1"); + + Assert.NotNull(activity); + Assert.Equal(2, activity.TagObjects.Count()); + Assert.Equal(new KeyValuePair("tag1", "value1"), activity.TagObjects.ElementAt(0)); + Assert.Equal(new KeyValuePair("tag2", "value2"), activity.TagObjects.ElementAt(1)); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestAddingSamplerTagsUsingParentId() + { + RemoteExecutor.Invoke(() => { + + using ActivitySource aSource = new ActivitySource("SamplerTags2"); + using ActivityListener listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags2"; + + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("tag1", "value1"); + activityOptions.SamplingTags.Add("tag2", "value2"); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener); + + Activity activity = aSource.StartActivity("a1", ActivityKind.Client, "SomeParent"); + + Assert.NotNull(activity); + Assert.Equal(2, activity.TagObjects.Count()); + Assert.Equal(new KeyValuePair("tag1", "value1"), activity.TagObjects.ElementAt(0)); + Assert.Equal(new KeyValuePair("tag2", "value2"), activity.TagObjects.ElementAt(1)); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestNotAddedSamplerTags() + { + RemoteExecutor.Invoke(() => { + + using ActivitySource aSource = new ActivitySource("SamplerTags3"); + using ActivityListener listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags3"; + + listener.Sample = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("tag1", "value1"); + Assert.False(true, "This callback shouldn't be called at all."); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener); + + // activity should be null as no listener asked for creation. + using Activity activity = aSource.StartActivity("a1", ActivityKind.Client, "NonW3CParentId"); + + Assert.Null(activity); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestDefaultTraceIdWithHierarchicalParentId() + { + RemoteExecutor.Invoke(() => { + + using ActivitySource aSource = new ActivitySource("SamplerTags4"); + using ActivityListener listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags4"; + + listener.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => + { + Assert.Equal(default, activityOptions.TraceId); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener); + + Activity activity = aSource.StartActivity("a1", ActivityKind.Client, "HierarchicalParentId"); + + Assert.NotNull(activity); + // activity has no parent. expected default trace Id. + Assert.Equal(default, activity.TraceId); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestAddingSamplerTagsFromMultipleListeners() + { + RemoteExecutor.Invoke(() => { + using ActivitySource aSource = new ActivitySource("SamplerTags5"); + using ActivityListener listener1 = new ActivityListener(); + using ActivityListener listener2 = new ActivityListener(); + listener1.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags5"; + listener2.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags5"; + + listener1.Sample = listener2.Sample = (ref ActivityCreationOptions activityOptions) => + { + if (activityOptions.SamplingTags.Count == 0) + activityOptions.SamplingTags.Add("tag1", "value1"); + else + activityOptions.SamplingTags.Add("tag2", "value2"); + + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener1); + ActivitySource.AddActivityListener(listener2); + + using Activity activity = aSource.StartActivity("a1"); + + Assert.NotNull(activity); + Assert.Equal(2, activity.TagObjects.Count()); + Assert.Equal(new KeyValuePair("tag1", "value1"), activity.TagObjects.ElementAt(0)); + Assert.Equal(new KeyValuePair("tag2", "value2"), activity.TagObjects.ElementAt(1)); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestSamplerTagsWithMixedListenerModels() + { + RemoteExecutor.Invoke(() => { + const string w3cId = "00-99d43cb30a4cdb4fbeee3a19c29201b0-e82825765f051b47-01"; + + using ActivitySource aSource = new ActivitySource("SamplerTags6"); + using ActivityListener listener1 = new ActivityListener(); + using ActivityListener listener2 = new ActivityListener(); + listener1.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags6"; + listener2.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags6"; + + // listener1 provide SampleUsingParentId callback and doesn't provide Sample + listener1.SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("tag1", "value1"); + return ActivitySamplingResult.AllData; + }; + + // listener2 provide Sample callback and doesn't provide SampleUsingParentId + // Sample should get called as we convert the w3c id to a context. + listener2.Sample = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("tag2", "value2"); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener1); + ActivitySource.AddActivityListener(listener2); + + using Activity activity = aSource.StartActivity("a1", ActivityKind.Client, w3cId); + + Assert.NotNull(activity); + Assert.Equal(2, activity.TagObjects.Count()); + Assert.Equal(new KeyValuePair("tag1", "value1"), activity.TagObjects.ElementAt(0)); + Assert.Equal(new KeyValuePair("tag2", "value2"), activity.TagObjects.ElementAt(1)); + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestAddSamplerAndActivityCreationTags() + { + RemoteExecutor.Invoke(() => { + using ActivitySource aSource = new ActivitySource("SamplerTags7"); + using ActivityListener listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == "SamplerTags7"; + + listener.Sample = (ref ActivityCreationOptions activityOptions) => + { + activityOptions.SamplingTags.Add("SamplerTag1", "SamplerValue1"); + return ActivitySamplingResult.AllData; + }; + + ActivitySource.AddActivityListener(listener); + + ActivityTagsCollection tags = new ActivityTagsCollection(); + tags["tag1"] = "value1"; + tags["tag2"] = "value2"; + + using Activity activity = aSource.StartActivity("a1", ActivityKind.Client, default(ActivityContext), tags); + + Assert.NotNull(activity); + Assert.Equal(3, activity.TagObjects.Count()); + Assert.Equal(new KeyValuePair("tag1", "value1"), activity.TagObjects.ElementAt(0)); + Assert.Equal(new KeyValuePair("tag2", "value2"), activity.TagObjects.ElementAt(1)); + Assert.Equal(new KeyValuePair("SamplerTag1", "SamplerValue1"), activity.TagObjects.ElementAt(2)); + }).Dispose(); + } + public void Dispose() => Activity.Current = null; } } From 93e8e05b45019bae74716cc057abdf2ca44d4149 Mon Sep 17 00:00:00 2001 From: Key Kim Date: Tue, 11 Aug 2020 01:51:35 +0900 Subject: [PATCH 363/755] Remove unused variable assignments in CapiHelper --- .../System/Security/Cryptography/CapiHelper.DSA.Shared.cs | 6 +++--- .../src/System/Security/Cryptography/CapiHelper.Shared.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs index 069813579789..4e6b8e057788 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs @@ -178,7 +178,7 @@ internal static DSAParameters ToDSAParameters(this byte[] cspBlob, bool includeP // BYTE[lenP] Y // BYTE[lenX] X (if private) - int magic = br.ReadInt32(); // Expected to be DSS_PUB_MAGIC_VER3 or DSS_PRIV_MAGIC_VER3 + br.ReadInt32(); // Expected to be DSS_PUB_MAGIC_VER3 or DSS_PRIV_MAGIC_VER3 int lenP = (br.ReadInt32() + 7) / 8; int lenQ = (br.ReadInt32() + 7) / 8; int lenJ = (br.ReadInt32() + 7) / 8; @@ -220,7 +220,7 @@ internal static DSAParameters ToDSAParameters(this byte[] cspBlob, bool includeP // DWORD counter (DSSSEED) // BYTE[20] seed (DSSSEED) - int magic = br.ReadInt32(); // Expected to be DSS_MAGIC or DSS_PRIVATE_MAGIC + br.ReadInt32(); // Expected to be DSS_MAGIC or DSS_PRIVATE_MAGIC int len = (br.ReadInt32() + 7) / 8; dsaParameters.P = br.ReadReversed(len); dsaParameters.Q = br.ReadReversed(DSS_Q_LEN); @@ -279,7 +279,7 @@ private static void ReadKeyBlobHeader(BinaryReader br, out byte bVersion) // WORD reserved // ALG_ID aiKeyAlg - byte bType = br.ReadByte(); // BLOBHEADER.bType: Expected to be 0x6 (PUBLICKEYBLOB) or 0x7 (PRIVATEKEYBLOB), though there's no check for backward compat reasons. + br.ReadByte(); // BLOBHEADER.bType: Expected to be 0x6 (PUBLICKEYBLOB) or 0x7 (PRIVATEKEYBLOB), though there's no check for backward compat reasons. bVersion = br.ReadByte(); // BLOBHEADER.bVersion: Expected to be 0x2 or 0x3, though there's no check for backward compat reasons. br.BaseStream.Position += sizeof(ushort); // BLOBHEADER.wReserved int algId = br.ReadInt32(); // BLOBHEADER.aiKeyAlg diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs index 700d6e48a53f..a75758092ef1 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs @@ -162,14 +162,14 @@ internal static RSAParameters ToRSAParameters(this byte[] cspBlob, bool includeP { BinaryReader br = new BinaryReader(new MemoryStream(cspBlob)); - byte bType = br.ReadByte(); // BLOBHEADER.bType: Expected to be 0x6 (PUBLICKEYBLOB) or 0x7 (PRIVATEKEYBLOB), though there's no check for backward compat reasons. - byte bVersion = br.ReadByte(); // BLOBHEADER.bVersion: Expected to be 0x2, though there's no check for backward compat reasons. + br.ReadByte(); // BLOBHEADER.bType: Expected to be 0x6 (PUBLICKEYBLOB) or 0x7 (PRIVATEKEYBLOB), though there's no check for backward compat reasons. + br.ReadByte(); // BLOBHEADER.bVersion: Expected to be 0x2, though there's no check for backward compat reasons. br.ReadUInt16(); // BLOBHEADER.wReserved int algId = br.ReadInt32(); // BLOBHEADER.aiKeyAlg if (algId != CALG_RSA_KEYX && algId != CALG_RSA_SIGN) throw new PlatformNotSupportedException(); // The FCall this code was ported from supports other algid's but we're only porting what we use. - int magic = br.ReadInt32(); // RSAPubKey.magic: Expected to be 0x31415352 ('RSA1') or 0x32415352 ('RSA2') + br.ReadInt32(); // RSAPubKey.magic: Expected to be 0x31415352 ('RSA1') or 0x32415352 ('RSA2') int bitLen = br.ReadInt32(); // RSAPubKey.bitLen int modulusLength = bitLen / 8; From 64d238d766a861324b404c675258c55e3d298b3d Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Mon, 10 Aug 2020 10:23:11 -0700 Subject: [PATCH 364/755] Update LSRA Doc (#39492) * Update LSRA Doc --- docs/design/coreclr/jit/lsra-detail.md | 353 +++++++++++++++++-------- 1 file changed, 241 insertions(+), 112 deletions(-) diff --git a/docs/design/coreclr/jit/lsra-detail.md b/docs/design/coreclr/jit/lsra-detail.md index 7a35d1947adf..fce0d4d54dff 100644 --- a/docs/design/coreclr/jit/lsra-detail.md +++ b/docs/design/coreclr/jit/lsra-detail.md @@ -3,25 +3,54 @@ Linear Scan Register Allocation: Design and Implementation Notes Table of Contents ----------------- -[Overview](#overview) - -[Preconditions](#preconditions) - -[Post-Conditions](#post-conditions) - -[LSRA Phases](#lsra-phases) - -[Key Data Structures](#key-data-structures) - -[Dumps and Debugging Support](#dumps-and-debugging-support) - -[LSRA Stress Modes](#lsra-stress-modes) - -[Assertions & Validation](#assertions-validation) - -[Future Extensions and Enhancements](#future-extensions-and-enhancements) - -[References](#references) + * [Overview](#overview) + * [Preconditions](#preconditions) + + [Lowered IR Form (LIR)](#lowered-ir-form-lir) + + [Register Requirements](#register-requirements) + * [Post-Conditions](#post-conditions) + * [LSRA Phases](#lsra-phases) + + [Liveness and Candidate Identification](#liveness-and-candidate-identification) + + [Block Ordering](#block-ordering) + + [Building Intervals and RefPositions](#building-intervals-and-refpositions) + + [Register allocation (doLinearScan)](#register-allocation-dolinearscan) + * [Key Data Structures](#key-data-structures) + + [Live In](#live-in) + + [currentLiveVars](#currentlivevars) + + [Referenceable](#referenceable) + + [Interval](#interval) + + [RegRecord](#regrecord) + + [RefPosition](#refposition) + + [GenTree Nodes](#gentree-nodes) + + [VarToRegMap](#vartoregmap) + * [Dumps and Debugging Support](#dumps-and-debugging-support) + * [LSRA Stress Modes](#lsra-stress-modes) + * [Assertions & Validation](#assertions--validation) + * [Future Extensions and Enhancements](#future-extensions-and-enhancements) + * [Feature Enhancements](#feature-enhancements) + + [Support for Allocating Consecutive Registers](#support-for-allocating-consecutive-registers) + * [Code Quality Enhancements](#code-quality-enhancements) + + [Merge Allocation of Free and Busy Registers](#merge-allocation-of-free-and-busy-registers) + + [Auto-tuning of register selection](#auto-tuning-of-register-selection) + + [Pre-allocating high frequency lclVars](#pre-allocating-high-frequency-lclvars) + + [Avoid Splitting Loop Backedges](#avoid-splitting-loop-backedges) + + [Enable EHWriteThru by default](#enable-ehwritethru-by-default) + + [Avoid Spill When Stack Copy is Valid](#avoid-spill-when-stack-copy-is-valid) + + [Rematerialization](#rematerialization) + + [Improving Reg-Optional Support](#improving-reg-optional-support) + - [Reg-Optional Defs](#reg-optional-defs) + - [Don't Pre-determine Reg-Optional Operand](#dont-pre-determine-reg-optional-operand) + - [Don't Mark DelayFree for Duplicate Operands](#dont-mark-delayfree-for-duplicate-operands) + + [Improving Preferencing](#improving-preferencing) + + [Leveraging SSA form](#leveraging-ssa-form) + + [Spanning trees for physical registers](#spanning-trees-for-physical-registers) + + [Improve the handling of def/use conflicts](#improve-the-handling-of-defuse-conflicts) + * [Throughput Enhancements](#throughput-enhancements) + + [Allocation Window for Min-Opts and Tier 0](#allocation-window-for-min-opts-and-tier-0) + + [Distinguish Intra-Block versus Inter-Block Variables](#distinguish-intra-block-versus-inter-block-variables) + + [Improve the VarToRegMap](#improve-the-vartoregmap) + + [Other Throughput Investigations](#other-throughput-investigations) + * [Test and Cleanup Issues](#test-and-cleanup-issues) + * [References](#references) Overview -------- @@ -63,7 +92,7 @@ There are four main phases to LSRA: - Note that the order doesn't affect correctness, as the location of `lclVar`s across block boundaries is fixed up - as necessary by the resolution phase. When not optimizing + as necessary by the resolution phase. When not optimizing, `lclVar`s are not enregistered, so there is no benefit to using a different order. @@ -98,6 +127,12 @@ There are four main phases to LSRA: as both a source and target (where the source is not marked `delayRegFree`. + - An exception is multi-reg local stores of multi-reg sources. + For these, the code generator will read each source register, + and then move it, if needed, to the destination register. + These nodes have 2*N locations where N is the number of registers, + so that the liveness can be reflected accordingly. + - For each node, `RefPosition`s are built to reflect the uses, definitions and kills of any registers involved in the evaluation of the node. @@ -119,7 +154,8 @@ There are four main phases to LSRA: - Splitting or spilling an `Interval` doesn't involve creating a new one. Instead, the `RefPosition` simply gets a new assignment, and is either marked for reload/copy or its location is simply - updated in the incoming map. + updated in the incoming map. This differs from other linear-scan + allocators, where separate intervals are constructed for this case. - The resolution phase has two parts: @@ -246,11 +282,11 @@ Post-Conditions After LSRA, the graph has the following properties: -- The `gtRegNum` of each tree node contains the allocated register, +- The `_gtRegNum` of each tree node (`GetRegNum()`) contains the allocated register, if any. Nodes that produce multiple registers are similarly assigned, via extended register number fields. If the node does not produce a value directly (i.e. it is either of void type, or it is - evaluated as part of its parent) its gtRegNum is set to REG_NA. + evaluated as part of its parent) its `_gtRegNum` is set to `REG_NA`. - In most cases, this register must satisfy the constraints specified for each `RefPosition` by the `BuildNode` methods. @@ -274,19 +310,23 @@ After LSRA, the graph has the following properties: - However, if such a node is constrained to a set of registers, and its current location does not satisfy that requirement, LSRA must insert a `GT_COPY` node between the node and its parent.  - The gtRegNum on the `GT_COPY` node must satisfy the register + The `_gtRegNum` on the `GT_COPY` node must satisfy the register requirement of the parent. -- GenTree::gtRsvdRegs has a set of registers used for internal temps. +- `GenTree::gtRsvdRegs` has a set of registers used for internal temps. These must satisfy the constraints specified by the associated `RefPosition`s. - A tree node is marked `GTF_SPILL` if the tree node must be spilled by the code generator after it has been evaluated. + - Note that a write-thru variable def is always written to the stack, and the `GTF_SPILLED` + flag (not otherwise used for pure defs) to indicate that it also remains live + in the assigned register. + - A tree node is marked `GTF_SPILLED` if it is a lclVar that must be reloaded prior to use. - - The register (gtRegNum) on the node indicates the register to + - The register (`_gtRegNum`) on the node indicates the register to which it must be reloaded. - For lclVar nodes, since the uses and defs are distinct tree @@ -299,18 +339,23 @@ After LSRA, the graph has the following properties: insert a `GT_RELOAD` node to specify the register to which it should be reloaded. +- Note that `GT_COPY` and `GT_RELOAD` nodes are inserted immediately after the + instruction that must be copied or reloaded. However, the reload or copy + isn't actually generated until the code generator is generating code for + the consuming node. + - Local variable table (`LclVarDsc`): - `LclVarDsc::lvRegister` is set to true if a local variable has the same register assignment for its entire lifetime. - - `LclVarDsc::lvRegNum` is initialized to its initial register + - `LclVarDsc::_lvRegNum` is initialized to its initial register assignment. - For incoming parameters, this is the register to which `genFnPrologCalleeRegArgs()` will move it. - - Codegen will set `lvRegNum` to its current value as it processes + - Codegen will set `_lvRegNum` to its current value as it processes the trees, since a variable can be assigned different registers over its lifetimes. @@ -347,7 +392,7 @@ well as supporting components) in more depth. should probably handle them in `Compiler::lvaMarkLocalVars()` when it is called after `Lowering`. - - It sets the ` lvLRACandidate` flag on lclVars that are going + - It sets the `lvLRACandidate` flag on lclVars that are going to be register candidates. ### Block Ordering @@ -364,6 +409,8 @@ that satisfies the following properties: - We use block weight, since edge weight is not tracked in the JIT. +- Blocks that enter EH regions have no predecessor. All live-in vars are on the stack. + The order of the `BasicBlock`s is captured in the `blockSequence` member of `LinearScan`. Other implementations of linear scan register allocation aim to ensure @@ -389,7 +436,8 @@ critical edges. This also captured in the `LsraBlockInfo` and is used by the res `Interval`s are built for lclVars up-front. These are maintained in an array, `localVarIntervals` which is indexed by the `lvVarIndex` (not the `varNum`, since we never allocate registers for non-tracked lclVars). Other intervals (for tree temps and -internal registers) are constructed as the relevant node is encountered. +internal registers) are constructed as the relevant node is encountered. Intervals for +`lclVar`s that are live into an exception region are marked `isWriteThru`. The building of `RefPosition`s is done via a traversal of the nodes, using the `blockSequence` constructed as described above. This traversal invokes `LinearScan::BuildNode()` for each @@ -412,6 +460,7 @@ node, which builds `RefPositions` according to the liveness model described abov - A contained memory operand or addressing mode will cause `RefPosition`s to be created for any (non-contained) base or index registers. + - A single `RefPosition` is created for non-contained nodes. In order to build these uses, we need to find the `Interval` associated with the @@ -420,7 +469,8 @@ node, which builds `RefPositions` according to the liveness model described abov have not yet seen the use. This is a simple list on the assumption that the distance between defs and uses of tree temps is rarely very great. - For x86 and x64, when we have an instruction that will overwrite one of its sources, + When we have an instruction that will overwrite one of its sources, such as RMW + operands common on x86 and x64, we need to ensure that the other source isn't given the same register as the target. For this, we annotate the use `RefPosition` with `delayRegFree`. @@ -428,12 +478,15 @@ node, which builds `RefPositions` according to the liveness model described abov This is cleared before the next instruction is handled. - Next, any registers in the kill set for the instruction are killed. This is performed - by `buildKillPositionsForNode()`, which takes a kill mask that is generally provided - by a `getKillSetForXXX()` method. + by `buildKillPositionsForNode()`, which takes a kill mask that is node-specific and + either provided directly by the `buildXXX()` method for the node, or by a `getKillSetForXXX()` + method. There is a debug-only method, `getKillSetForNode()` which is only used for validation. - Finally, we create `RefTypeDef` `RefPositions` for any registers that are defined by the node. + - For a `STORE_LCL_VAR` of a write-thru `lclVar`, the `RefPosition` is marked `writeThru`. + - A `RefTypeBB` `RefPosition` marks the beginning of a block, at which the incoming live variables are set to their locations at the end of the selected predecessor. @@ -462,13 +515,7 @@ During this phase, preferences are set: (at a previous definition) been assigned a register, and we want to try to use that register again, as well as the case where it has yet to be assigned a register. - This area has room for improvement: - - - A specific case that could be improved is [Issue #25312](https://github.com/dotnet/coreclr/issues/25312) - which involves preferencing for HW intrinsics. - - - Issue [#22374](https://github.com/dotnet/coreclr/issues/22374) also has a pointer - to some methods that could benefit from improved preferencing. + This area has room for improvement, (see [Improving Preferencing](#improving-preferencing)). - Register preferences are set: @@ -528,7 +575,7 @@ LinearScanAllocation(List refPositions) - Currently, parameters may not be allocated a register if their weighted reference count is less than `BB_UNITY_WEIGHT`, however plenty of room remains for improving the allocation of - parameters [Issue \#11356](https://github.com/dotnet/coreclr/issues/11356) + parameters [Issue \#7999](https://github.com/dotnet/runtime/issues/7999) - `TryAllocateFreeReg()` iterates over the registers, attempting to find the best free register (if any) to allocate: @@ -547,17 +594,21 @@ LinearScanAllocation(List refPositions) which is not currently live, but which previously occupied that register). + - Currently it doesn't take encoding size into account. + [Issue \#7996](https://github.com/dotnet/runtime/issues/7996) + tracks this. + - It always uses the same order for iterating over the registers. The jit32 register allocator used a different ordering for tree temps than for lclVars. It's unclear if this matters for LSRA, - but [Issue \#11357](https://github.com/dotnet/coreclr/issues/11357) + but [Issue \#8000](https://github.com/dotnet/runtime/issues/8000) tracks this question. - `AllocateBusyReg()` iterates over all the registers trying to find the best register to spill (it must only be called if `tryAllocateFreeReg()` was unable to find one): - - It takes into account the following: + - It takes into account a number of heuristics including: - The distance to the next use of the `Interval` being spilled @@ -567,16 +618,15 @@ LinearScanAllocation(List refPositions) - Whether the `RefPosition` being allocated, or the one potentially being spilled, is reg-optional + - Both `tryAllocateFreeReg()` and `allocateBusyReg()` currently fully evaluate the "goodness" + of each register. + - It will always spill an `Interval` either at its most recent use, or at the entry to the current block. - - Issues [\#7609](https://github.com/dotnet/coreclr/issues/7609) and - [\#7665](https://github.com/dotnet/coreclr/issues/7665) track improvement of spill - placement. - - - It is quite possible that combining `TryAllocateFreeReg()` and + - It is quite likely that combining `TryAllocateFreeReg()` and `AllocateBusyReg()` would be more effective, see - [Merge Allocation of Free and Busy Registers](#combine) + [Merge Allocation of Free and Busy Registers](#merge-allocation-of-free-and-busy-registers) - Resolution @@ -599,18 +649,10 @@ LinearScanAllocation(List refPositions) - Resolution of exception edges - - This is currently done by ensuring that any variable that's - live in to an exception region is maintained on stack. - - - Issue \#6001 raises the performance issue due to this - implementation. - - - Work is in-progress to support the notion - of "write-thru" variables; for these, all definitions - would write to memory, but uses could use a register - value, if available. + - When `COMPlus_EnableEHWriteThru == 0`, any variable that's + live in to an exception region is always referenced on the stack. - - The value is reloaded at exception boundaries. + - See [Enable EHWriteThru by default](#enable-EHWriteThru-by-default). - Code generation (genGenerateCode) @@ -699,7 +741,7 @@ fixed registers. The representation of `TYP_DOUBLE` registers on 32-bit `Arm` is complicated by the fact that they overlap two `TYP_FLOAT` registers. The handling of this -case could be improved. +case could be improved. See [Support for Allocating Consecutive Registers](#Support-for-Allocating-Consecutive-Registers). ### RefPosition @@ -727,14 +769,11 @@ enregisterable variable or temporary or physical register. It contains - `RefTypeUse` is a pure use of an `Interval` . - `RefTypeKill` is a location at which a physical register is - killed. These only exist on `RegRecord`s, not on `Interval`s - - - Note that this type is probably not needed -- see especially - notes about physical registers in "future" section. + killed. These only exist on `RegRecord`s, not on `Interval`s - `RefTypeBB` is really just a marker in the list of `RefPosition`s, - where the register allocator needs to record the register - locations at block boundaries. It is not associated with an + where the register allocator needs to record the register + locations at block boundaries. It is not associated with an `Interval` or `RegRecord`. - `RefTypeFixedReg` is a `RefPosition` on a `RegRecord` that marks a @@ -807,7 +846,7 @@ The following dumps and debugging modes are provided: - For each incoming arg: its type and incoming location - For each instruction: - - The current contents of the `OperandToLocationInfoMap`. + - The current contents of the `defList`. This corresponds to all the nodes that have defined values that have not yet been consumed. - An abbreviated dump of the GenTree node. @@ -822,8 +861,8 @@ The following dumps and debugging modes are provided: progresses. - After allocation - - A dump of `RefPosition`s, sequentially, and grouped for Var - `Interval` s + - A dump of `RefPosition`s, sequentially, and grouped for `lclVar` + `Interval`s - During resolution - A list of the candidates for resolution at each split, join or @@ -895,18 +934,15 @@ exclusive: - Never allocate a register for a `RefPosition` marked `regOptional` (0x1000). -It may be useful to also have a stress mode that deliberately trashes registers that -are not currently occupied (e.g. at block boundaries). Issue [#18944](https://github.com/dotnet/coreclr/issues/18944). - Assertions & Validation ----------------------- There are many assertions in `LinearScan`. The following are the most effective at identifying issues (i.e. they frequently show up in bugs): -- The node information isn't showing the number of consumed registers - that are expected: - - `assert((consume == 0) || (ComputeAvailableSrcCount(tree) == consume));` +- The def and use counts don't match what's expected: + - See the asserts at the end of the `LinearScan::BuildNode()` method (these are + architecture-specific, and can be found in lsraxarch.cpp, lsraarm64.cpp and lsraarm.cpp). - This usually means that the `BuildXXX` method for this node is not building `RefPosition`s for all of its uses (which is what `consume` has been set to). - The liveness information is incorrect. This assert comes from `LinearScan::checkLastUses()` which @@ -918,19 +954,26 @@ effective at identifying issues (i.e. they frequently show up in bugs): possibly because it is a stress mode, and the instruction hasn't correctly specified its minimum number of registers. -At the end of write-back (`resolveRegisters()`), `verifyFinalAllocation()` runs. It doesn't do a lot of validation, but it - prints the final allocation (including final spill placement), so is useful for tracking down correctness issues. +At the end of write-back (`resolveRegisters()`), `verifyFinalAllocation()` runs. It doesn't do a +lot of validation, but it prints the final allocation (including final spill placement), so is +useful for tracking down correctness issues. Future Extensions and Enhancements ---------------------------------- -The potential enhancements to the JIT, some of which are referenced in this document, can generally be found by [searching for LSRA in open issues](https://github.com/dotnet/coreclr/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+LSRA+in%3Atitle). The ones that are focused on JIT throughput are labeled `JITThroughput`. +The potential enhancements to the JIT, some of which are referenced in this document, can generally be found by [searching for LSRA in open issues](https://github.com/dotnet/runtime/issues?q=is%3Aissue+is%3Aopen+lsra+in%3Atitle). The ones that are focused on JIT throughput are labeled `JITThroughput`. + +## Feature Enhancements + +### Support for Allocating Consecutive Registers + +This is [\#39457](https://github.com/dotnet/runtime/issues/39457). As described there, the challenge is to do this without impacting the common path. This should also include cleaning up the allocating of consecutive registers for `TYP_DOUBLE` for Arm32 [\#8758](https://github.com/dotnet/runtime/issues/8758). ## Code Quality Enhancements -### Merge Allocation of Free and Busy Registers +### Merge Allocation of Free and Busy Registers -This is captured as [\#15408](https://github.com/dotnet/coreclr/issues/15408) +This is captured as [\#9399](https://github.com/dotnet/runtime/issues/9399) Consider merging allocating free & busy regs. Currently the register allocator will always allocate an available register, even if it only meets @@ -943,31 +986,34 @@ The alternative approach under consideration is to combine free and busy registe (`tryAllocateFreeReg()` and `allocateBusyReg()`) such that a busy register will be spilled if there are no suitable free registers, and the current `Interval` has greater weight than the `Interval` occupying the register. This must be accompanied by some improvements in the efficiency of the -checks, so as not to degrade throughput. This is currently a work-in-progress (https://github.com/CarolEidt/coreclr/tree/CombineAlloc) but hasn't yet been ported to the runtime repo, and needs +checks, so as not to degrade throughput. This is currently a work-in-progress (https://github.com/CarolEidt/runtime/tree/CombineAlloc), and needs further work to eliminate diffs and improve throughput. This would make it possible to spill a register for a higher weight `lclVar` rather than "settling" for a register that's a poor fit for its requirements. This is probably the best approach to -address Issues [\#7664](https://github.com/dotnet/coreclr/issues/7664) +address Issues [\#6824](https://github.com/dotnet/runtime/issues/6824): Heuristics for callee saved reg allocation and -[\#13735](https://github.com/dotnet/coreclr/issues/13735) +[\#8846](https://github.com/dotnet/runtime/issues/8846): Let variables within a loop use register first. The following issues are related: -* Both `tryAllocateFreeReg()` and `allocateBusyReg()` currently fully evaluate the "goodness" of each register. - Issue [\#7301](https://github.com/dotnet/coreclr/issues/7301) tracks the possibility of short-circuiting - this evaluation. - Making such an improvement should probably be done in conjunction with this work. +- Issues [\#6806](https://github.com/dotnet/runtime/issues/6806) and + [\#6825](https://github.com/dotnet/runtime/issues/6825) track improvement of spill + placement. + +- Issue [\#6705](https://github.com/dotnet/runtime/issues/6705) tracks the possibility of + short-circuiting this evaluation. + Making such an improvement should probably be done in conjunction with this work. -* Issue [\#26847](https://github.com/dotnet/coreclr/issues/26847) - Heuristics for callee saved reg allocation. +- Issue [\#13466](https://github.com/dotnet/runtime/issues/13466): + Inefficient register allocation in simple method which dereferences a span ### Auto-tuning of register selection This is not yet captured as a GitHub issue. -This would be best done after [Merge Allocation of Free and Busy Registers](#combine). +This would be best done after [Merge Allocation of Free and Busy Registers](#merge-allocation-of-free-and-busy-registers). The idea would be to add support to change the weight given to the various selection heuristics according to a configuration specification, allowing them to be auto-tuned. @@ -980,7 +1026,7 @@ would be added as an alternate path in the register allocator, leaving the defau ### Pre-allocating high frequency lclVars -This is captured as Issue [\#11424](https://github.com/dotnet/coreclr/issues/11424) +This is captured as Issue [\#8019](https://github.com/dotnet/runtime/issues/8019) Consider pre-allocating high-frequency lclVars. The idea here is to ensure that high frequency lclVars aren't forced to use less-than-optimal @@ -1015,7 +1061,7 @@ One strategy would be to do something along the lines of (appropriate hand-wavin ### Avoid Splitting Loop Backedges -This is captured as Issue [\#16857](https://github.com/dotnet/coreclr/issues/16857). +This is captured as Issue [\#9909](https://github.com/dotnet/runtime/issues/9909). When the register allocator performs resolution across block boundaries, it may split critical edges (edges from a block with multiple successors to a block with multiple predecessors). @@ -1029,16 +1075,43 @@ set would ensure that the variable locations match. This would eliminate not jus but all the extra branches currently inserted for resolution. It remains to be seen whether this would outweigh the impact of cases where more resolution moves would be required. +I have an old experimental branch where I started working on this: https://github.com/CarolEidt/coreclr/tree/NoEdgeSplitting (not yet ported to the runtime repo). + +### Enable EHWriteThru by default + +When `COMPlus_EnableEHWriteThru` is set, some performance regressions are observed. When an EH write-thru variable (i.e. one that is live into an exception region) is defined, its value is +always stored, in addition to potentially remaining live in a register. This increases register +pressure which may result in worse code. + +Further investigation is needed, but the following mitigations may be effective (here the +term "EH Var" means a `lclVar` marked `lvLiveInOutOfHndlr`): + +- Adjust the heuristics: + + 1. For determining whether an EH var should be a candidate for register allocation, + e.g. if the defs outweight the uses. + + 2. For determining when a definition of an EH var should be only stored to the stack, + rather than also remaining live in the register. + +- If the weight of the defs exceeds the weight of the blocks with successors in exception + regions, consider spilling the `lclVar` to the stack only at those boundaries. + +The original issue to enable EH WriteThru is [#6212](https://github.com/dotnet/runtime/issues/6212). +It remains open pending the resolution of the performance regressions. + ### Avoid Spill When Stack Copy is Valid The idea here is to avoid spilling at a use if the value on the stack is already the correct value. -Issues that this might address include [\#11344] Spill single-def vars at def, [\#7665] Improve spill placement, -and [\#7465] Avoiding reg spill to memory when reg-value is consistent with memory. +Issues that this might address include: +- [\#7994](https://github.com/dotnet/runtime/issues/7994) Spill single-def vars at def, +- [\#6825](https://github.com/dotnet/runtime/issues/6825) Improve spill placement, and +- [\#6761](https://github.com/dotnet/runtime/issues/6761) Avoiding reg spill to memory when reg-value is consistent with memory. Currently the register allocator doesn't track whether a local variable has the same value on the stack -as in a register. The work-in-progress to support "write-thru" EH variables (variables live across exception -boundaries) adds capability to liveness analysis and code generation (in addition to the register allocator) +as in a register. The support for "write-thru" EH variables (variables live across exception +boundaries) has added the capability to liveness analysis and code generation (in addition to the register allocator) to handle variables that are live in both registers and on the stack. This support could be further leveraged to avoid spilling single-def variables to memory if they have already been spilled at their definition. @@ -1047,19 +1120,29 @@ Extending such support to more generally track whether there is already a valid work. Fully general support would require such information at block boundaries, but it might be worth investigating whether it would be worthwhile and cheaper to simply track this information within a block. -### Support Reg-Optional Defs +### Rematerialization + +This would involve identifying `Interval`s whose values are cheaper to recompute than to spill +and reload. Without SSA form, this would probably be easiest to do when there's a single def. +Issue [\#6264](https://github.com/dotnet/runtime/issues/6264). + +### Improving Reg-Optional Support + +#### Reg-Optional Defs -Issues [\#7752](https://github.com/dotnet/coreclr/issues/7752) and -[\#7753](https://github.com/dotnet/coreclr/issues/7753) track the +Issues [\#6862](https://github.com/dotnet/runtime/issues/6862) and +[\#6863](https://github.com/dotnet/runtime/issues/6863) track the proposal to support "folding" of operations using a tree temp when the defining operation supports read-modify-write (RMW) to memory. This involves supporting the possibility of a def being reg-optional, as well as its use, so that it need never occupy a register. -### Don't Pre-determine Reg-Optional Operand +I have an old experimental branch: https://github.com/CarolEidt/coreclr/tree/RegOptDef where I started working on this. -Issue [\#6361](https://github.com/dotnet/coreclr/issues/6361) +#### Don't Pre-determine Reg-Optional Operand + +Issue [\#6358](https://github.com/dotnet/runtime/issues/6358) tracks the problem that `Lowering` currently has to select a single operand to be reg-optional, even if either operand could be. This requires some additional state because @@ -1067,6 +1150,18 @@ LSRA can't easily navigate from one use to the other to communicate whether the first operand has been assigned a register. +#### Don't Mark DelayFree for Duplicate Operands + +Issue [\#9896](https://github.com/dotnet/runtime/issues/9896). + +### Improving Preferencing + +- Issue [#12945](https://github.com/dotnet/runtime/issues/12945) + involves preferencing for HW intrinsics. + +- Issue [#11959](https://github.com/dotnet/runtime/issues/11959) also has a pointer + to some methods that could benefit from improved preferencing. + ### Leveraging SSA form This has not yet been opened as a github issue. @@ -1083,7 +1178,7 @@ Making SSA form available to LSRA would: This has not yet been opened as a github issue. LLVM has extended their linear scan register allocator with something it -calls "Greedy Register Allocation". This uses a priority queue for the +calls "Greedy Register Allocation"[[6](#6),[7](#7)]. This uses a priority queue for the order of allocation (sorted by decreasing spill cost), and a B+ tree to represent each physical register. I think that using the B+ trees for physical registers would be an improvement over the current PhysRegs, @@ -1091,6 +1186,13 @@ and we may want to experiment with changing the allocation order as well. It would not be necessary to significantly modify the process of creating `Interval`s, nor the resolution phase. +### Improve the handling of def/use conflicts + +Def/use conflicts arise when the producing and conusming nodes each have register requirements, +and they conflict. The current mechanism, in which the register assignment of one of the +`RefPosition`s is changed, can lead to problems because there's then +no associated `RefTypeFixedReg` for that reference. This is Issue [\#10196](https://github.com/dotnet/runtime/issues/10196). + ## Throughput Enhancements ### Allocation Window for Min-Opts and Tier 0 @@ -1111,48 +1213,75 @@ form of a `defList` that holds all of the tree temp values that have been define Once this is empty, the register allocator could process the current list of `RefPosition`s and then start over. +[Issue \#6690](https://github.com/dotnet/runtime/issues/6690) proposes to build `RefPositions` incrementally, which is part of this item. + ### Distinguish Intra-Block versus Inter-Block Variables It is unclear whether it would be beneficial, but if we could keep track of the variables that are only used within a block (presumably true of many introduced temps), we may find that we could continue to limit the number of variables whose liveness is tracked across blocks, keeping an expanded -set only for transient liveness. Issue [\#11339](https://github.com/dotnet/coreclr/issues/11339). +set only for transient liveness. Issue [\#7992](https://github.com/dotnet/runtime/issues/7992). Note that this would only improve JIT throughput for optimized code. ### Improve the VarToRegMap -The `VarToRegMap` incurs non-trivial JIT-time overhead. Issue \#11396 addresses +The `VarToRegMap` incurs non-trivial JIT-time overhead. +Issue [\#8013](https://github.com/dotnet/runtime/issues/8013) addresses the question of whether there is an alternative that would have better performance. This would also improve JIT throughput only for optimized code. +### Other Throughput Investigations + +Issue [\#7998](https://github.com/dotnet/runtime/issues/7998) suggests evluating the throughput cost of updating the preferences at each +kill site. + +## Test and Cleanup Issues + +Issue [\#9767](https://github.com/dotnet/runtime/issues/9767) captures the issue that the +"spill always" stress mode, `LSRA_SPILL_ALWAYS`, `COMPlus_JitStressRegs=0x800` doesn't work properly. + +Issue [\#6261](https://github.com/dotnet/runtime/issues/6261) has to do with `RegOptional` +`RefPositions` that are marked as `copyReg` or `moveReg`. See the notes on this issue; +I don't think such cases should arise, but there may be some cleanup needed here. + +Issue [\#5793](https://github.com/dotnet/runtime/issues/5793) suggests adding a stress mode that +allocates registers forr mullti-reg nodes in the reverse of the ABI requirements. + +Issue [#10691](https://github.com/dotnet/runtime/issues/10691) suggests adding a stress mode that +deliberately trashes registers that are not currently occupied (e.g. at block boundaries). + References ---------- -1. Boissinot, B. et +1. Boissinot, B. et al "Fast liveness checking for ssa-form programs," CGO 2008, pp. 35-44. http://portal.acm.org/citation.cfm?id=1356058.1356064&coll=ACM&dl=ACM&CFID=105967773&CFTOKEN=80545349 -2. Boissinot, B. et al, "Revisiting +2. Boissinot, B. et al, "Revisiting Out-of-SSA Translation for Correctness, Code Quality and Efficiency," CGO 2009, pp. 114-125. -3. Wimmer, C. and Mössenböck, D. "Optimized +3. Wimmer, C. and Mössenböck, D. "Optimized Interval Splitting in a Linear Scan Register Allocator," ACM VEE 2005, pp. 132-141. -4. Wimmer, C. and Franz, M. "Linear Scan +4. Wimmer, C. and Franz, M. "Linear Scan Register Allocation on SSA Form," ACM CGO 2010, pp. 170-179. -5. Traub, O. et al "Quality and Speed in Linear-scan Register +5. Traub, O. et al "Quality and Speed in Linear-scan Register Allocation," SIGPLAN '98, pp. 142-151. -6. Olesen, J. "Greedy Register Allocation in LLVM 3.0," LLVM Project Blog, Sept. 2011. +6. Olesen, J. "Greedy Register Allocation in LLVM 3.0," LLVM Project Blog, Sept. 2011. - (Last retrieved Feb. 2012) + (Last retrieved July 2020) + +7. Yatsina, M. "LLVM Greedy Register Allocator," LLVM Dev Meeting, April 2018. + + (Last retrieved July 2020) \ No newline at end of file From c2711f5ad327c82b66df170d6d2bf7835e8e6774 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 10 Aug 2020 12:23:50 -0500 Subject: [PATCH 365/755] Run dotnet-format on the debugger source (#40618) --- .../wasm/debugger/BrowserDebugHost/Program.cs | 4 +- .../wasm/debugger/BrowserDebugHost/Startup.cs | 10 +- .../BrowserDebugHost/TestHarnessStartup.cs | 26 +- .../debugger/BrowserDebugProxy/DebugStore.cs | 32 +- .../BrowserDebugProxy/DebuggerProxy.cs | 2 +- .../BrowserDebugProxy/DevToolsHelper.cs | 26 +- .../BrowserDebugProxy/DevToolsProxy.cs | 16 +- .../BrowserDebugProxy/EvaluateExpression.cs | 10 +- .../debugger/BrowserDebugProxy/MonoProxy.cs | 86 +- .../debugger/DebuggerTestSuite/ArrayTests.cs | 268 +++---- .../DebuggerTestSuite/CallFunctionOnTests.cs | 740 +++++++++--------- .../DebuggerTestSuite/DateTimeTests.cs | 42 +- .../DebuggerTestSuite/DelegateTests.cs | 346 ++++---- .../DebuggerTestSuite/DevToolsClient.cs | 22 +- .../EvaluateOnCallFrameTests.cs | 258 +++--- .../DebuggerTestSuite/ExceptionTests.cs | 36 +- .../DebuggerTestSuite/InspectorClient.cs | 8 +- .../DebuggerTestSuite/PointerTests.cs | 636 +++++++-------- .../debugger/DebuggerTestSuite/Support.cs | 118 +-- .../wasm/debugger/DebuggerTestSuite/Tests.cs | 351 ++++----- 20 files changed, 1520 insertions(+), 1517 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugHost/Program.cs b/src/mono/wasm/debugger/BrowserDebugHost/Program.cs index c45b9ce0065c..66db8a1ad23c 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/Program.cs +++ b/src/mono/wasm/debugger/BrowserDebugHost/Program.cs @@ -57,7 +57,7 @@ public class TestHarnessProxy public static Task Start(string chromePath, string appPath, string pagePath) { - lock(proxyLock) + lock (proxyLock) { if (host != null) return hostTask; @@ -89,4 +89,4 @@ public static Task Start(string chromePath, string appPath, string pagePath) return hostTask; } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs index 16292f997e6b..81c70187ed07 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs +++ b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs @@ -54,7 +54,7 @@ public static Dictionary MapValues(Dictionary re { case "devtoolsFrontendUrl": var front = response[key]; - filtered[key] = $"{debuggerHost.Scheme}://{debuggerHost.Authority}{front.Replace ($"ws={debuggerHost.Authority}", $"ws={request.Host}")}"; + filtered[key] = $"{debuggerHost.Scheme}://{debuggerHost.Authority}{front.Replace($"ws={debuggerHost.Authority}", $"ws={request.Host}")}"; break; case "webSocketDebuggerUrl": var page = new Uri(response[key]); @@ -97,7 +97,7 @@ string GetEndpoint(HttpContext context) async Task Copy(HttpContext context) { - using(var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }) + using (var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }) { var response = await httpClient.GetAsync(GetEndpoint(context)); context.Response.ContentType = response.Content.Headers.ContentType.ToString(); @@ -133,7 +133,7 @@ async Task ConnectProxy(HttpContext context) return; } - var endpoint = new Uri($"ws://{devToolsHost.Authority}{context.Request.Path.ToString ()}"); + var endpoint = new Uri($"ws://{devToolsHost.Authority}{context.Request.Path.ToString()}"); try { using var loggerFactory = LoggerFactory.Create( @@ -154,11 +154,11 @@ async Task ConnectProxy(HttpContext context) static async Task ProxyGetJsonAsync(string url) { - using(var httpClient = new HttpClient()) + using (var httpClient = new HttpClient()) { var response = await httpClient.GetAsync(url); return await JsonSerializer.DeserializeAsync(await response.Content.ReadAsStreamAsync()); } } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs b/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs index 953eb864f907..265f1a358164 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs +++ b/src/mono/wasm/debugger/BrowserDebugHost/TestHarnessStartup.cs @@ -59,12 +59,12 @@ async Task SendNodeList(HttpContext context) var response = new JArray(JObject.FromObject(new { description = "node.js instance", - devtoolsFrontendUrl = "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4", - faviconUrl = "https://nodejs.org/static/favicon.ico", - id = "91d87807-8a81-4f49-878c-a5604103b0a4", - title = "foo.js", - type = "node", - webSocketDebuggerUrl = "ws://localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4" + devtoolsFrontendUrl = "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4", + faviconUrl = "https://nodejs.org/static/favicon.ico", + id = "91d87807-8a81-4f49-878c-a5604103b0a4", + title = "foo.js", + type = "node", + webSocketDebuggerUrl = "ws://localhost:9300/91d87807-8a81-4f49-878c-a5604103b0a4" })).ToString(); Console.WriteLine($"sending: {response}"); @@ -157,9 +157,9 @@ public void Configure(IApplicationBuilder app, IOptionsMonitor + await LaunchAndServe(psi, context, async (str) => { var start = DateTime.Now; JArray obj = null; @@ -211,7 +211,7 @@ await LaunchAndServe(psi, context, async(str) => } } - var wsURl = obj[0] ? ["webSocketDebuggerUrl"]?.Value(); + var wsURl = obj[0]?["webSocketDebuggerUrl"]?.Value(); Console.WriteLine(">>> {0}", wsURl); return wsURl; @@ -219,7 +219,7 @@ await LaunchAndServe(psi, context, async(str) => } catch (Exception ex) { - Console.WriteLine($"launch-chrome-and-connect failed with {ex.ToString ()}"); + Console.WriteLine($"launch-chrome-and-connect failed with {ex.ToString()}"); } }); }); @@ -252,4 +252,4 @@ await LaunchAndServe(psi, context, async(str) => } } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index aedcfb27a449..9f9c7a6bd080 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -268,7 +268,7 @@ public override bool Equals(object obj) public override int GetHashCode() => assembly.GetHashCode() ^ document.GetHashCode(); - public static bool operator ==(SourceId a, SourceId b) => ((object) a == null) ? (object) b == null : a.Equals(b); + public static bool operator ==(SourceId a, SourceId b) => ((object)a == null) ? (object)b == null : a.Equals(b); public static bool operator !=(SourceId a, SourceId b) => !a.Equals(b); } @@ -486,11 +486,11 @@ private void ProcessSourceLink() if (sourceLinkDebugInfo != null) { - var sourceLinkContent = ((SourceLinkDebugInformation) sourceLinkDebugInfo).Content; + var sourceLinkContent = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content; if (sourceLinkContent != null) { - var jObject = JObject.Parse(sourceLinkContent) ["documents"]; + var jObject = JObject.Parse(sourceLinkContent)["documents"]; sourceLinkMappings = JsonConvert.DeserializeObject>(jObject.ToString()); } } @@ -592,7 +592,7 @@ internal void AddMethod(MethodInfo mi) public string DocUrl => doc.Url; - public(int startLine, int startColumn, int endLine, int endColumn) GetExtents() + public (int startLine, int startColumn, int endLine, int endColumn) GetExtents() { var start = Methods.OrderBy(m => m.StartLocation.Line).ThenBy(m => m.StartLocation.Column).First(); var end = Methods.OrderByDescending(m => m.EndLocation.Line).ThenByDescending(m => m.EndLocation.Column).First(); @@ -606,7 +606,7 @@ async Task GetDataAsync(Uri uri, CancellationToken token) { if (uri.IsFile && File.Exists(uri.LocalPath)) { - using(var file = File.Open(SourceUri.LocalPath, FileMode.Open)) + using (var file = File.Open(SourceUri.LocalPath, FileMode.Open)) { await file.CopyToAsync(mem, token).ConfigureAwait(false); mem.Position = 0; @@ -615,7 +615,7 @@ async Task GetDataAsync(Uri uri, CancellationToken token) else if (uri.Scheme == "http" || uri.Scheme == "https") { var client = new HttpClient(); - using(var stream = await client.GetStreamAsync(uri)) + using (var stream = await client.GetStreamAsync(uri)) { await stream.CopyToAsync(mem, token).ConfigureAwait(false); mem.Position = 0; @@ -659,8 +659,8 @@ byte[] ComputePdbHash(Stream sourceStream) { var algorithm = GetHashAlgorithm(doc.HashAlgorithm); if (algorithm != null) - using(algorithm) - return algorithm.ComputeHash(sourceStream); + using (algorithm) + return algorithm.ComputeHash(sourceStream); return Array.Empty(); } @@ -670,7 +670,7 @@ byte[] ComputePdbHash(Stream sourceStream) if (doc.EmbeddedSource.Length > 0) return new MemoryStream(doc.EmbeddedSource, false); - foreach (var url in new [] { SourceUri, SourceLinkUri }) + foreach (var url in new[] { SourceUri, SourceLinkUri }) { var mem = await GetDataAsync(url, token).ConfigureAwait(false); if (mem != null && (!checkHash || CheckPdbHash(ComputePdbHash(mem)))) @@ -688,11 +688,11 @@ public object ToScriptSource(int executionContextId, object executionContextAuxD return new { scriptId = SourceId.ToString(), - url = Url, - executionContextId, - executionContextAuxData, - //hash: should be the v8 hash algo, managed implementation is pending - dotNetUrl = DotNetUrl, + url = Url, + executionContextId, + executionContextAuxData, + //hash: should be the v8 hash algo, managed implementation is pending + dotNetUrl = DotNetUrl, }; } } @@ -742,7 +742,7 @@ public async IAsyncEnumerable Load(SessionId sessionId, string[] loa new DebugItem { Url = url, - Data = Task.WhenAll(client.GetByteArrayAsync(url), pdb != null ? client.GetByteArrayAsync(pdb) : Task.FromResult(null)) + Data = Task.WhenAll(client.GetByteArrayAsync(url), pdb != null ? client.GetByteArrayAsync(pdb) : Task.FromResult(null)) }); } catch (Exception e) @@ -880,4 +880,4 @@ public IEnumerable FindBreakpointLocations(BreakpointRequest req public string ToUrl(SourceLocation location) => location != null ? GetFileById(location.Id).Url : ""; } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs index 359411196084..08fe836200dc 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebuggerProxy.cs @@ -26,4 +26,4 @@ public Task Run(Uri browserUri, WebSocket ideSocket) return proxy.Run(browserUri, ideSocket); } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index d17c9e739130..a08a62512de9 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -27,7 +27,7 @@ public SessionId(string sessionId) // hashset treats 0 as unset public override int GetHashCode() => sessionId?.GetHashCode() ?? -1; - public override bool Equals(object obj) => (obj is SessionId) ? ((SessionId) obj).sessionId == sessionId : false; + public override bool Equals(object obj) => (obj is SessionId) ? ((SessionId)obj).sessionId == sessionId : false; public static bool operator ==(SessionId a, SessionId b) => a.sessionId == b.sessionId; @@ -55,7 +55,7 @@ public MessageId(string sessionId, int id) public override int GetHashCode() => (sessionId?.GetHashCode() ?? 0) ^ id.GetHashCode(); - public override bool Equals(object obj) => (obj is MessageId) ? ((MessageId) obj).sessionId == sessionId && ((MessageId) obj).id == id : false; + public override bool Equals(object obj) => (obj is MessageId) ? ((MessageId)obj).sessionId == sessionId && ((MessageId)obj).id == id : false; } internal class DotnetObjectId @@ -106,7 +106,7 @@ public struct Result if (result != null && error != null) throw new ArgumentException($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null."); - bool resultHasError = String.Compare((result?["result"] as JObject) ? ["subtype"]?.Value(), "error") == 0; + bool resultHasError = String.Compare((result?["result"] as JObject)?["subtype"]?.Value(), "error") == 0; if (result != null && resultHasError) { this.Value = null; @@ -142,8 +142,8 @@ public JObject ToJObject(MessageId target) return JObject.FromObject(new { target.id, - target.sessionId, - result = Value + target.sessionId, + result = Value }); } else @@ -151,15 +151,15 @@ public JObject ToJObject(MessageId target) return JObject.FromObject(new { target.id, - target.sessionId, - error = Error + target.sessionId, + error = Error }); } } public override string ToString() { - return $"[Result: IsOk: {IsOk}, IsErr: {IsErr}, Value: {Value?.ToString ()}, Error: {Error?.ToString ()} ]"; + return $"[Result: IsOk: {IsOk}, IsErr: {IsErr}, Value: {Value?.ToString()}, Error: {Error?.ToString()} ]"; } } @@ -175,7 +175,7 @@ internal class MonoCommands public static MonoCommands GetCallStack() => new MonoCommands("MONO.mono_wasm_get_call_stack()"); - public static MonoCommands GetExceptionObject () => new MonoCommands ("MONO.mono_wasm_get_exception_object()"); + public static MonoCommands GetExceptionObject() => new MonoCommands("MONO.mono_wasm_get_exception_object()"); public static MonoCommands IsRuntimeReady() => new MonoCommands("MONO.mono_wasm_runtime_is_ready"); @@ -190,7 +190,7 @@ internal class MonoCommands public static MonoCommands GetScopeVariables(int scopeId, params VarInfo[] vars) { var var_ids = vars.Select(v => new { index = v.Index, name = v.Name }).ToArray(); - return new MonoCommands($"MONO.mono_wasm_get_variables({scopeId}, {JsonConvert.SerializeObject (var_ids)})"); + return new MonoCommands($"MONO.mono_wasm_get_variables({scopeId}, {JsonConvert.SerializeObject(var_ids)})"); } public static MonoCommands SetBreakpoint(string assemblyName, uint methodToken, int ilOffset) => new MonoCommands($"MONO.mono_wasm_set_breakpoint (\"{assemblyName}\", {methodToken}, {ilOffset})"); @@ -199,11 +199,11 @@ public static MonoCommands GetScopeVariables(int scopeId, params VarInfo[] vars) public static MonoCommands ReleaseObject(DotnetObjectId objectId) => new MonoCommands($"MONO.mono_wasm_release_object('{objectId}')"); - public static MonoCommands CallFunctionOn(JToken args) => new MonoCommands($"MONO.mono_wasm_call_function_on ({args.ToString ()})"); + public static MonoCommands CallFunctionOn(JToken args) => new MonoCommands($"MONO.mono_wasm_call_function_on ({args.ToString()})"); public static MonoCommands Resume() => new MonoCommands($"MONO.mono_wasm_debugger_resume ()"); - public static MonoCommands SetPauseOnExceptions (string state) => new MonoCommands ($"MONO.mono_wasm_set_pause_on_exceptions(\"{state}\")"); + public static MonoCommands SetPauseOnExceptions(string state) => new MonoCommands($"MONO.mono_wasm_set_pause_on_exceptions(\"{state}\")"); } internal enum MonoErrorCodes @@ -305,4 +305,4 @@ public void ClearState() } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs index 656bd91c5091..dc399dfef38c 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsProxy.cs @@ -112,7 +112,7 @@ async Task ReadOne(WebSocket socket, CancellationToken token) mem.Write(buff, 0, result.Count); if (result.EndOfMessage) - return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int) mem.Length); + return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int)mem.Length); } } @@ -278,11 +278,11 @@ void SendResponseInternal(MessageId id, Result result, CancellationToken token) public async Task Run(Uri browserUri, WebSocket ideSocket) { Log("info", $"DevToolsProxy: Starting on {browserUri}"); - using(this.ide = ideSocket) + using (this.ide = ideSocket) { Log("verbose", $"DevToolsProxy: IDE waiting for connection on {browserUri}"); queues.Add(new DevToolsQueue(this.ide)); - using(this.browser = new ClientWebSocket()) + using (this.browser = new ClientWebSocket()) { this.browser.Options.KeepAliveInterval = Timeout.InfiniteTimeSpan; await this.browser.ConnectAsync(browserUri, CancellationToken.None); @@ -304,7 +304,7 @@ public async Task Run(Uri browserUri, WebSocket ideSocket) //logger.LogTrace ("pump {0} {1}", task, pending_ops.IndexOf (task)); if (task == pending_ops[0]) { - var msg = ((Task) task).Result; + var msg = ((Task)task).Result; if (msg != null) { pending_ops[0] = ReadOne(browser, x.Token); //queue next read @@ -313,7 +313,7 @@ public async Task Run(Uri browserUri, WebSocket ideSocket) } else if (task == pending_ops[1]) { - var msg = ((Task) task).Result; + var msg = ((Task)task).Result; if (msg != null) { pending_ops[1] = ReadOne(ide, x.Token); //queue next read @@ -322,12 +322,12 @@ public async Task Run(Uri browserUri, WebSocket ideSocket) } else if (task == pending_ops[2]) { - var res = ((Task) task).Result; + var res = ((Task)task).Result; throw new Exception("side task must always complete with an exception, what's going on???"); } else if (task == pending_ops[3]) { - var res = ((Task) task).Result; + var res = ((Task)task).Result; Log("verbose", $"DevToolsProxy: Client initiated close from {browserUri}"); x.Cancel(); } @@ -378,4 +378,4 @@ protected void Log(string priority, string msg) } } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs index 982fa87592a6..9f34078b796d 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs @@ -190,10 +190,10 @@ public string Evaluate() CSharpCompilation compilation = CSharpCompilation.Create( "compileAndRunTheExpression", - syntaxTrees : new [] { syntaxTree }, - references : references, - options : new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - using(var ms = new MemoryStream()) + syntaxTrees: new[] { syntaxTree }, + references: references, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + using (var ms = new MemoryStream()) { EmitResult result = compilation.Emit(ms); ms.Seek(0, SeekOrigin.Begin); @@ -210,4 +210,4 @@ public string Evaluate() return retString; } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 1f1079f8c0c7..4166c7ef2366 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -51,8 +51,8 @@ protected override async Task AcceptEvent(SessionId sessionId, string meth if (type == "debug") { var a = args["args"]; - if (a?[0] ? ["value"]?.ToString() == MonoConstants.RUNTIME_IS_READY && - a?[1] ? ["value"]?.ToString() == "fe00e07a-5519-4dfe-b35a-f867dbaf2e28") + if (a?[0]?["value"]?.ToString() == MonoConstants.RUNTIME_IS_READY && + a?[1]?["value"]?.ToString() == "fe00e07a-5519-4dfe-b35a-f867dbaf2e28") { if (a.Count() > 2) { @@ -61,7 +61,7 @@ protected override async Task AcceptEvent(SessionId sessionId, string meth // The optional 3rd argument is the stringified assembly // list so that we don't have to make more round trips var context = GetContext(sessionId); - var loaded = a?[2] ? ["value"]?.ToString(); + var loaded = a?[2]?["value"]?.ToString(); if (loaded != null) context.LoadedFiles = JToken.Parse(loaded).ToObject(); } @@ -97,7 +97,7 @@ protected override async Task AcceptEvent(SessionId sessionId, string meth case "Debugger.paused": { //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack - var top_func = args?["callFrames"] ? [0] ? ["functionName"]?.Value(); + var top_func = args?["callFrames"]?[0]?["functionName"]?.Value(); if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_exception") { @@ -118,7 +118,7 @@ protected override async Task AcceptEvent(SessionId sessionId, string meth switch (url) { case var _ when url == "": - case var _ when url.StartsWith("wasm://", StringComparison.Ordinal): + case var _ when url.StartsWith("wasm://", StringComparison.Ordinal): { Log("verbose", $"ignoring wasm: Debugger.scriptParsed {url}"); return true; @@ -146,7 +146,7 @@ async Task IsRuntimeAlreadyReadyAlready(SessionId sessionId, CancellationT return true; var res = await SendMonoCommand(sessionId, MonoCommands.IsRuntimeReady(), token); - return res.Value?["result"] ? ["value"]?.Value() ?? false; + return res.Value?["result"]?["value"]?.Value() ?? false; } protected override async Task AcceptCommand(MessageId id, string method, JObject args, CancellationToken token) @@ -329,15 +329,15 @@ protected override async Task AcceptCommand(MessageId id, string method, J return true; } - case "Debugger.setPauseOnExceptions": + case "Debugger.setPauseOnExceptions": { - string state = args["state"].Value (); - await SendMonoCommand(id, MonoCommands.SetPauseOnExceptions (state), token); + string state = args["state"].Value(); + await SendMonoCommand(id, MonoCommands.SetPauseOnExceptions(state), token); // Pass this on to JS too return false; } - // Protocol extensions + // Protocol extensions case "DotnetDebugger.getMethodLocation": { Console.WriteLine("set-breakpoint-by-method: " + id + " " + args); @@ -377,7 +377,7 @@ protected override async Task AcceptCommand(MessageId id, string method, J // Maybe this is an async method, in which case the debug info is attached // to the async method implementation, in class named: // `{type_name}/::MoveNext` - methodInfo = assembly.TypesByName.Values.SingleOrDefault(t => t.FullName.StartsWith($"{typeName}/<{methodName}>")) ? + methodInfo = assembly.TypesByName.Values.SingleOrDefault(t => t.FullName.StartsWith($"{typeName}/<{methodName}>"))? .Methods.FirstOrDefault(mi => mi.Name == "MoveNext"); } @@ -410,7 +410,7 @@ protected override async Task AcceptCommand(MessageId id, string method, J } var res = await SendMonoCommand(id, MonoCommands.CallFunctionOn(args), token); - var res_value_type = res.Value?["result"] ? ["value"]?.Type; + var res_value_type = res.Value?["result"]?["value"]?.Type; if (res.IsOk && res_value_type == JTokenType.Object || res_value_type == JTokenType.Object) res = Result.OkFromObject(new { result = res.Value["result"]["value"] }); @@ -435,7 +435,7 @@ async Task RuntimeGetProperties(MessageId id, DotnetObjectId objectId, J if (objectId.Scheme == "cfo_res") { // Runtime.callFunctionOn result object - var value_json_str = res.Value["result"] ? ["value"] ? ["__value_as_json_string__"]?.Value(); + var value_json_str = res.Value["result"]?["value"]?["__value_as_json_string__"]?.Value(); if (value_json_str != null) { res = Result.OkFromObject(new @@ -473,7 +473,7 @@ async Task OnPause(SessionId sessionId, JObject args, CancellationToken to } //step one, figure out where did we hit - var res_value = res.Value?["result"] ? ["value"]; + var res_value = res.Value?["result"]?["value"]; if (res_value == null || res_value is JValue) { //Give up and send the original call stack @@ -496,27 +496,29 @@ async Task OnPause(SessionId sessionId, JObject args, CancellationToken to { var function_name = frame["functionName"]?.Value(); var url = frame["url"]?.Value(); - if ("mono_wasm_fire_bp" == function_name ||"_mono_wasm_fire_bp" == function_name || + if ("mono_wasm_fire_bp" == function_name || "_mono_wasm_fire_bp" == function_name || "_mono_wasm_fire_exception" == function_name) { - if ("_mono_wasm_fire_exception" == function_name) { - var exception_obj_id = await SendMonoCommand(sessionId, MonoCommands.GetExceptionObject (), token); - var res_val = exception_obj_id.Value? ["result"]? ["value"]; - var exception_dotnet_obj_id = new DotnetObjectId("object", res_val?["exception_id"]?.Value ()); - data = JObject.FromObject (new { - type = "object", - subtype = "error", - className = res_val? ["class_name"]?.Value(), - uncaught = res_val? ["uncaught"]?.Value(), - description = res_val? ["message"]?.Value() + "\n", - objectId = exception_dotnet_obj_id.ToString() + if ("_mono_wasm_fire_exception" == function_name) + { + var exception_obj_id = await SendMonoCommand(sessionId, MonoCommands.GetExceptionObject(), token); + var res_val = exception_obj_id.Value?["result"]?["value"]; + var exception_dotnet_obj_id = new DotnetObjectId("object", res_val?["exception_id"]?.Value()); + data = JObject.FromObject(new + { + type = "object", + subtype = "error", + className = res_val?["class_name"]?.Value(), + uncaught = res_val?["uncaught"]?.Value(), + description = res_val?["message"]?.Value() + "\n", + objectId = exception_dotnet_obj_id.ToString() }); reason = "exception"; } var frames = new List(); int frame_id = 0; - var the_mono_frames = res.Value?["result"] ? ["value"] ? ["frames"]?.Values(); + var the_mono_frames = res.Value?["result"]?["value"]?["frames"]?.Values(); foreach (var mono_frame in the_mono_frames) { @@ -562,14 +564,14 @@ async Task OnPause(SessionId sessionId, JObject args, CancellationToken to callFrames.Add(new { functionName = method_name, - callFrameId = $"dotnet:scope:{frame_id-1}", - functionLocation = method.StartLocation.AsLocation(), + callFrameId = $"dotnet:scope:{frame_id - 1}", + functionLocation = method.StartLocation.AsLocation(), - location = location.AsLocation(), + location = location.AsLocation(), - url = store.ToUrl(location), + url = store.ToUrl(location), - scopeChain = new [] + scopeChain = new[] { new { @@ -654,7 +656,7 @@ async Task Step(MessageId msg_id, StepKind kind, CancellationToken token) var res = await SendMonoCommand(msg_id, MonoCommands.StartSingleStepping(kind), token); - var ret_code = res.Value?["result"] ? ["value"]?.Value(); + var ret_code = res.Value?["result"]?["value"]?.Value(); if (ret_code.HasValue && ret_code.Value == 0) { @@ -697,7 +699,7 @@ internal async Task TryGetVariableValue(MessageId msg_id, int scope_id, //get_this var res = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, live_vars), token); - var scope_values = res.Value?["result"] ? ["value"]?.Values()?.ToArray(); + var scope_values = res.Value?["result"]?["value"]?.Values()?.ToArray(); thisValue = scope_values?.FirstOrDefault(v => v["name"]?.Value() == "this"); if (!only_search_on_this) @@ -717,7 +719,7 @@ internal async Task TryGetVariableValue(MessageId msg_id, int scope_id, return null; res = await SendMonoCommand(msg_id, MonoCommands.GetDetails(objectId), token); - scope_values = res.Value?["result"] ? ["value"]?.Values().ToArray(); + scope_values = res.Value?["result"]?["value"]?.Values().ToArray(); var foundValue = scope_values.FirstOrDefault(v => v["name"].Value() == expression); if (foundValue != null) { @@ -781,7 +783,7 @@ async Task GetScopeProperties(MessageId msg_id, int scope_id, Cancellati if (res.IsErr) return res; - var values = res.Value?["result"] ? ["value"]?.Values().ToArray(); + var values = res.Value?["result"]?["value"]?.Values().ToArray(); if (values == null || values.Length == 0) return Result.OkFromObject(new { result = Array.Empty() }); @@ -806,7 +808,7 @@ async Task SetMonoBreakpoint(SessionId sessionId, string reqId, Sour var il_offset = bp.Location.CliLocation.Offset; var res = await SendMonoCommand(sessionId, MonoCommands.SetBreakpoint(asm_name, method_token, il_offset), token); - var ret_code = res.Value?["result"] ? ["value"]?.Value(); + var ret_code = res.Value?["result"]?["value"]?.Value(); if (ret_code.HasValue) { @@ -832,7 +834,7 @@ async Task LoadStore(SessionId sessionId, CancellationToken token) if (loaded_files == null) { var loaded = await SendMonoCommand(sessionId, MonoCommands.GetLoadedFiles(), token); - loaded_files = loaded.Value?["result"] ? ["value"]?.ToObject(); + loaded_files = loaded.Value?["result"]?["value"]?.ToObject(); } await @@ -892,7 +894,7 @@ async Task RemoveBreakpoint(MessageId msg_id, JObject args, CancellationToken to foreach (var bp in breakpointRequest.Locations) { var res = await SendMonoCommand(msg_id, MonoCommands.RemoveBreakpoint(bp.RemoteId), token); - var ret_code = res.Value?["result"] ? ["value"]?.Value(); + var ret_code = res.Value?["result"]?["value"]?.Value(); if (ret_code.HasValue) { @@ -981,13 +983,13 @@ async Task OnGetScriptSource(MessageId msg_id, string script_id, Cancellat var uri = new Uri(src_file.Url); string source = $"// Unable to find document {src_file.SourceUri}"; - using(var data = await src_file.GetSourceAsync(checkHash: false, token: token)) + using (var data = await src_file.GetSourceAsync(checkHash: false, token: token)) { if (data.Length == 0) return false; - using(var reader = new StreamReader(data)) - source = await reader.ReadToEndAsync(); + using (var reader = new StreamReader(data)) + source = await reader.ReadToEndAsync(); } SendResponse(msg_id, Result.OkFromObject(new { scriptSource = source }), token); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index f9319a7b491f..343b3be709d6 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -22,14 +22,14 @@ public class ArrayTests : DebuggerTestBase public async Task InspectPrimitiveTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:PrimitiveTypeLocals", - method_name : method_name, + method_name: method_name, etype_name: "int", local_var_name_prefix: "int", - array : new [] { TNumber(4), TNumber(70), TNumber(1) }, + array: new[] { TNumber(4), TNumber(70), TNumber(1) }, array_elem_props: null, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); [Theory] [InlineData(36, 8, "ValueTypeLocals", false, 0, false)] @@ -39,22 +39,22 @@ public async Task InspectPrimitiveTypeArrayLocals(int line, int col, string meth public async Task InspectValueTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:ValueTypeLocals", - method_name : method_name, + method_name: method_name, etype_name: "DebuggerTests.Point", local_var_name_prefix: "point", - array : new [] + array: new[] { TValueType("DebuggerTests.Point"), TValueType("DebuggerTests.Point"), }, - array_elem_props: new [] + array_elem_props: new[] { TPoint(5, -2, "point_arr#Id#0", "Green"), TPoint(123, 0, "point_arr#Id#1", "Blue") }, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); [Theory] [InlineData(54, 8, "ObjectTypeLocals", false, 0, false)] @@ -64,24 +64,24 @@ public async Task InspectValueTypeArrayLocals(int line, int col, string method_n public async Task InspectObjectArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:ObjectTypeLocals", - method_name : method_name, + method_name: method_name, etype_name: "DebuggerTests.SimpleClass", local_var_name_prefix: "class", - array : new [] + array: new[] { TObject("DebuggerTests.SimpleClass"), TObject("DebuggerTests.SimpleClass", is_null : true), TObject("DebuggerTests.SimpleClass") }, - array_elem_props: new [] + array_elem_props: new[] { TSimpleClass(5, -2, "class_arr#Id#0", "Green"), null, // Element is null TSimpleClass(123, 0, "class_arr#Id#2", "Blue") }, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); [Theory] [InlineData(72, 8, "GenericTypeLocals", false, 0, false)] @@ -91,16 +91,16 @@ public async Task InspectObjectArrayLocals(int line, int col, string method_name public async Task InspectGenericTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericTypeLocals", - method_name : method_name, + method_name: method_name, etype_name: "DebuggerTests.GenericClass", local_var_name_prefix: "gclass", - array : new [] + array: new[] { TObject("DebuggerTests.GenericClass", is_null : true), TObject("DebuggerTests.GenericClass"), TObject("DebuggerTests.GenericClass") }, - array_elem_props : new [] + array_elem_props: new[] { null, // Element is null new @@ -116,9 +116,9 @@ public async Task InspectGenericTypeArrayLocals(int line, int col, string method Value = TNumber(-12) } }, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); [Theory] [InlineData(89, 8, "GenericValueTypeLocals", false, 0, false)] @@ -128,15 +128,15 @@ public async Task InspectGenericTypeArrayLocals(int line, int col, string method public async Task InspectGenericValueTypeArrayLocals(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericValueTypeLocals", - method_name : method_name, + method_name: method_name, etype_name: "DebuggerTests.SimpleGenericStruct", local_var_name_prefix: "gvclass", - array : new [] + array: new[] { TValueType("DebuggerTests.SimpleGenericStruct"), TValueType("DebuggerTests.SimpleGenericStruct") }, - array_elem_props : new [] + array_elem_props: new[] { new { @@ -151,9 +151,9 @@ public async Task InspectGenericValueTypeArrayLocals(int line, int col, string m Value = TPoint(10, 20, "gvclass_arr#2#Value#Id", "Green") } }, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); [Theory] [InlineData(213, 8, "GenericValueTypeLocals2", false, 0, false)] @@ -163,15 +163,15 @@ public async Task InspectGenericValueTypeArrayLocals(int line, int col, string m public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string method_name, bool test_prev_frame, int frame_idx, bool use_cfo) => await TestSimpleArrayLocals( line, col, entry_method_name: "[debugger-test] DebuggerTests.ArrayTestsClass:GenericValueTypeLocals2", - method_name : method_name, + method_name: method_name, etype_name: "DebuggerTests.SimpleGenericStruct", local_var_name_prefix: "gvclass", - array : new [] + array: new[] { TValueType("DebuggerTests.SimpleGenericStruct"), TValueType("DebuggerTests.SimpleGenericStruct") }, - array_elem_props : new [] + array_elem_props: new[] { new { @@ -194,9 +194,9 @@ public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string } } }, - test_prev_frame : test_prev_frame, - frame_idx : frame_idx, - use_cfo : use_cfo); + test_prev_frame: test_prev_frame, + frame_idx: frame_idx, + use_cfo: use_cfo); async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, string method_name, string etype_name, string local_var_name_prefix, object[] array, object[] array_elem_props, @@ -207,7 +207,7 @@ async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, st var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; @@ -225,7 +225,7 @@ await insp.Ready(async(cli, token) => Assert.Equal(4, locals.Count()); CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]", array?.Length ?? 0); CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]", 0); - CheckObject(locals, $"{local_var_name_prefix}_arr_null", $"{etype_name}[]", is_null : true); + CheckObject(locals, $"{local_var_name_prefix}_arr_null", $"{etype_name}[]", is_null: true); CheckBool(locals, "call_other", test_prev_frame); var local_arr_name = $"{local_var_name_prefix}_arr"; @@ -261,11 +261,11 @@ await insp.Ready(async(cli, token) => var act_i = prefix_arr.FirstOrDefault(jt => jt["name"]?.Value() == i_str); Assert.True(act_i != null, $"[{label}] Couldn't find array element [{i_str}]"); - await CheckValue(act_i["value"], TObject(etype_name, is_null : true), label); + await CheckValue(act_i["value"], TObject(etype_name, is_null: true), label); } else { - await CompareObjectPropertiesFor(prefix_arr, i_str, array_elem_props[i], label : label); + await CompareObjectPropertiesFor(prefix_arr, i_str, array_elem_props[i], label: label); } } } @@ -280,7 +280,7 @@ async Task GetObjectWithCFO(string objectId, JObject fn_args = null) var cfo_args = JObject.FromObject(new { functionDeclaration = fn_decl, - objectId = objectId + objectId = objectId }); if (fn_args != null) @@ -308,7 +308,7 @@ public async Task InspectObjectArrayMembers(bool use_cfo) int frame_idx = 1; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -327,18 +327,18 @@ await insp.Ready(async(cli, token) => var c_props = await GetObjectOnFrame(pause_location["callFrames"][frame_idx], "c"); await CheckProps(c_props, new - { - id = TString("c#id"), - ClassArrayProperty = TArray("DebuggerTests.SimpleClass[]", 3), - ClassArrayField = TArray("DebuggerTests.SimpleClass[]", 3), - PointsProperty = TArray("DebuggerTests.Point[]", 2), - PointsField = TArray("DebuggerTests.Point[]", 2) - }, + { + id = TString("c#id"), + ClassArrayProperty = TArray("DebuggerTests.SimpleClass[]", 3), + ClassArrayField = TArray("DebuggerTests.SimpleClass[]", 3), + PointsProperty = TArray("DebuggerTests.Point[]", 2), + PointsField = TArray("DebuggerTests.Point[]", 2) + }, "c" ); await CompareObjectPropertiesFor(c_props, "ClassArrayProperty", - new [] + new[] { TSimpleClass(5, -2, "ClassArrayProperty#Id#0", "Green"), TSimpleClass(30, 1293, "ClassArrayProperty#Id#1", "Green"), @@ -347,7 +347,7 @@ await CompareObjectPropertiesFor(c_props, "ClassArrayProperty", label: "InspectLocalsWithStructsStaticAsync"); await CompareObjectPropertiesFor(c_props, "ClassArrayField", - new [] + new[] { TObject("DebuggerTests.SimpleClass", is_null : true), TSimpleClass(5, -2, "ClassArrayField#Id#1", "Blue"), @@ -356,7 +356,7 @@ await CompareObjectPropertiesFor(c_props, "ClassArrayField", label: "c#ClassArrayField"); await CompareObjectPropertiesFor(c_props, "PointsProperty", - new [] + new[] { TPoint(5, -2, "PointsProperty#Id#0", "Green"), TPoint(123, 0, "PointsProperty#Id#1", "Blue"), @@ -364,7 +364,7 @@ await CompareObjectPropertiesFor(c_props, "PointsProperty", label: "c#PointsProperty"); await CompareObjectPropertiesFor(c_props, "PointsField", - new [] + new[] { TPoint(5, -2, "PointsField#Id#0", "Green"), TPoint(123, 0, "PointsField#Id#1", "Blue"), @@ -388,7 +388,7 @@ public async Task InspectValueTypeArrayLocalsStaticAsync(bool use_cfo) int frame_idx = 0; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -406,24 +406,24 @@ await insp.Ready(async(cli, token) => await CheckProps(frame_locals, new { call_other = TBool(false), - gvclass_arr = TArray("DebuggerTests.SimpleGenericStruct[]", 2), - gvclass_arr_empty = TArray("DebuggerTests.SimpleGenericStruct[]"), - gvclass_arr_null = TObject("DebuggerTests.SimpleGenericStruct[]", is_null : true), - gvclass = TValueType("DebuggerTests.SimpleGenericStruct"), - // BUG: this shouldn't be null! - points = TObject("DebuggerTests.Point[]", is_null : true) + gvclass_arr = TArray("DebuggerTests.SimpleGenericStruct[]", 2), + gvclass_arr_empty = TArray("DebuggerTests.SimpleGenericStruct[]"), + gvclass_arr_null = TObject("DebuggerTests.SimpleGenericStruct[]", is_null: true), + gvclass = TValueType("DebuggerTests.SimpleGenericStruct"), + // BUG: this shouldn't be null! + points = TObject("DebuggerTests.Point[]", is_null: true) }, "ValueTypeLocalsAsync#locals"); var local_var_name_prefix = "gvclass"; await CompareObjectPropertiesFor(frame_locals, local_var_name_prefix, new { Id = TString(null), - Color = TEnum("DebuggerTests.RGB", "Red"), - Value = TPoint(0, 0, null, "Red") + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(0, 0, null, "Red") }); await CompareObjectPropertiesFor(frame_locals, $"{local_var_name_prefix}_arr", - new [] + new[] { new { @@ -459,7 +459,7 @@ public async Task InspectValueTypeArrayLocalsInstanceAsync(bool use_cfo) int frame_idx = 0; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -478,21 +478,21 @@ await insp.Ready(async(cli, token) => await CheckProps(frame_locals, new { t1 = TObject("DebuggerTests.SimpleGenericStruct"), - @this = TObject("DebuggerTests.ArrayTestsClass"), - point_arr = TArray("DebuggerTests.Point[]", 2), - point = TValueType("DebuggerTests.Point") + @this = TObject("DebuggerTests.ArrayTestsClass"), + point_arr = TArray("DebuggerTests.Point[]", 2), + point = TValueType("DebuggerTests.Point") }, "InspectValueTypeArrayLocalsInstanceAsync#locals"); await CompareObjectPropertiesFor(frame_locals, "t1", new { Id = TString("gvclass_arr#1#Id"), - Color = TEnum("DebuggerTests.RGB", "Red"), - Value = TPoint(100, 200, "gvclass_arr#1#Value#Id", "Red") + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TPoint(100, 200, "gvclass_arr#1#Value#Id", "Red") }); await CompareObjectPropertiesFor(frame_locals, "point_arr", - new [] + new[] { TPoint(5, -2, "point_arr#Id#0", "Red"), TPoint(123, 0, "point_arr#Id#1", "Blue"), @@ -518,7 +518,7 @@ public async Task InspectValueTypeArrayLocalsInAsyncStaticStructMethod(bool use_ int frame_idx = 0; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -538,8 +538,8 @@ await insp.Ready(async(cli, token) => await CheckProps(frame_locals, new { call_other = TBool(false), - local_i = TNumber(5), - sc = TSimpleClass(10, 45, "sc#Id", "Blue") + local_i = TNumber(5), + sc = TSimpleClass(10, 45, "sc#Id", "Blue") }, "InspectValueTypeArrayLocalsInAsyncStaticStructMethod#locals"); }); } @@ -558,7 +558,7 @@ public async Task InspectValueTypeArrayLocalsInAsyncInstanceStructMethod(bool us int frame_idx = 0; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -575,19 +575,19 @@ await insp.Ready(async(cli, token) => var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); await CheckProps(frame_locals, new - { - sc_arg = TObject("DebuggerTests.SimpleClass"), - @this = TValueType("DebuggerTests.Point"), - local_gs = TValueType("DebuggerTests.SimpleGenericStruct") - }, + { + sc_arg = TObject("DebuggerTests.SimpleClass"), + @this = TValueType("DebuggerTests.Point"), + local_gs = TValueType("DebuggerTests.SimpleGenericStruct") + }, "locals#0"); await CompareObjectPropertiesFor(frame_locals, "local_gs", new { Id = TString("local_gs#Id"), - Color = TEnum("DebuggerTests.RGB", "Green"), - Value = TNumber(4) + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) }, label: "local_gs#0"); @@ -605,91 +605,91 @@ await CompareObjectPropertiesFor(frame_locals, "this", public async Task InvalidArrayId() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", - wait_for_event_fn : async(pause_location) => - { + wait_for_event_fn: async (pause_location) => + { - int frame_idx = 1; - var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); - var c_obj = GetAndAssertObjectWithName(frame_locals, "c"); - var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); - Assert.NotNull(c_obj_id); + int frame_idx = 1; + var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); + var c_obj = GetAndAssertObjectWithName(frame_locals, "c"); + var c_obj_id = c_obj["value"]?["objectId"]?.Value(); + Assert.NotNull(c_obj_id); // Invalid format - await GetProperties("dotnet:array:4123", expect_ok : false); + await GetProperties("dotnet:array:4123", expect_ok: false); // Invalid object id - await GetProperties("dotnet:array:{ \"arrayId\": 234980 }", expect_ok : false); + await GetProperties("dotnet:array:{ \"arrayId\": 234980 }", expect_ok: false); // Trying to access object as an array - if (!DotnetObjectId.TryParse (c_obj_id, out var id) || id.Scheme != "object") - Assert.True(false, "Unexpected object id format. Maybe this test is out of sync with the object id format in library_mono.js?"); + if (!DotnetObjectId.TryParse(c_obj_id, out var id) || id.Scheme != "object") + Assert.True(false, "Unexpected object id format. Maybe this test is out of sync with the object id format in library_mono.js?"); - if (!int.TryParse(id.Value, out var idNum)) - Assert.True(false, "Expected a numeric value part of the object id: {c_obj_id}"); - await GetProperties($"dotnet:array:{{\"arrayId\":{idNum}}}", expect_ok : false); - }); + if (!int.TryParse(id.Value, out var idNum)) + Assert.True(false, "Expected a numeric value part of the object id: {c_obj_id}"); + await GetProperties($"dotnet:array:{{\"arrayId\":{idNum}}}", expect_ok: false); + }); [Fact] public async Task InvalidValueTypeArrayIndex() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", - locals_fn : async(locals) => - { - var this_obj = GetAndAssertObjectWithName(locals, "this"); - var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); - var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); - Assert.NotNull(c_obj_id); + locals_fn: async (locals) => + { + var this_obj = GetAndAssertObjectWithName(locals, "this"); + var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); + var c_obj_id = c_obj["value"]?["objectId"]?.Value(); + Assert.NotNull(c_obj_id); - var c_props = await GetProperties(c_obj_id); + var c_props = await GetProperties(c_obj_id); - var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); - var pf_arr_elems = await GetProperties(pf_arr["value"]["objectId"].Value()); + var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); + var pf_arr_elems = await GetProperties(pf_arr["value"]["objectId"].Value()); - if (!DotnetObjectId.TryParse(pf_arr_elems[0]["value"] ? ["objectId"]?.Value(), out var id)) - Assert.True(false, "Couldn't parse objectId for PointsFields' elements"); + if (!DotnetObjectId.TryParse(pf_arr_elems[0]["value"]?["objectId"]?.Value(), out var id)) + Assert.True(false, "Couldn't parse objectId for PointsFields' elements"); - AssertEqual("valuetype", id.Scheme, "Expected a valuetype id"); - var id_args = id.ValueAsJson; - Assert.True(id_args["arrayId"] != null, "ObjectId format for array seems to have changed. Expected to find 'arrayId' in the value. Update this test"); - Assert.True(id_args != null, "Expected to get a json as the value part of {id}"); + AssertEqual("valuetype", id.Scheme, "Expected a valuetype id"); + var id_args = id.ValueAsJson; + Assert.True(id_args["arrayId"] != null, "ObjectId format for array seems to have changed. Expected to find 'arrayId' in the value. Update this test"); + Assert.True(id_args != null, "Expected to get a json as the value part of {id}"); // Try one valid query, to confirm that the id format hasn't changed! id_args["arrayIdx"] = 0; - await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : true); + await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: true); - id_args["arrayIdx"] = 12399; - await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); + id_args["arrayIdx"] = 12399; + await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); - id_args["arrayIdx"] = -1; - await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); + id_args["arrayIdx"] = -1; + await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); - id_args["arrayIdx"] = "qwe"; - await GetProperties($"dotnet:valuetype:{id_args.ToString (Newtonsoft.Json.Formatting.None)}", expect_ok : false); - }); + id_args["arrayIdx"] = "qwe"; + await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); + }); [Fact] public async Task InvalidAccessors() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", - locals_fn : async(locals) => - { - var this_obj = GetAndAssertObjectWithName(locals, "this"); - var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); - var c_obj_id = c_obj["value"] ? ["objectId"]?.Value(); - Assert.NotNull(c_obj_id); + locals_fn: async (locals) => + { + var this_obj = GetAndAssertObjectWithName(locals, "this"); + var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); + var c_obj_id = c_obj["value"]?["objectId"]?.Value(); + Assert.NotNull(c_obj_id); - var c_props = await GetProperties(c_obj_id); + var c_props = await GetProperties(c_obj_id); - var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); + var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); - var invalid_accessors = new object[] { "NonExistant", "10000", "-2", 10000, -2, null, String.Empty }; - foreach (var invalid_accessor in invalid_accessors) - { + var invalid_accessors = new object[] { "NonExistant", "10000", "-2", 10000, -2, null, String.Empty }; + foreach (var invalid_accessor in invalid_accessors) + { // var res = await InvokeGetter (JObject.FromObject (new { value = new { objectId = obj_id } }), invalid_accessor, expect_ok: true); - var res = await InvokeGetter(pf_arr, invalid_accessor, expect_ok : true); - AssertEqual("undefined", res.Value["result"] ? ["type"]?.ToString(), "Expected to get undefined result for non-existant accessor"); - } - }); + var res = await InvokeGetter(pf_arr, invalid_accessor, expect_ok: true); + AssertEqual("undefined", res.Value["result"]?["type"]?.ToString(), "Expected to get undefined result for non-existant accessor"); + } + }); } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs index 3014c6cc5e83..a65585103f44 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -25,38 +25,38 @@ public async Task CheckVSCodeTestFunction1(string eval_fn, string bp_loc, int li { string vscode_fn0 = "function(){const e={__proto__:this.__proto__},t=Object.getOwnPropertyNames(this);for(let r=0;r>>0;if(String(i>>>0)===n&&i>>>0!=4294967295)continue;const a=Object.getOwnPropertyDescriptor(this,n);a&&Object.defineProperty(e,n,a)}return e}"; - await RunCallFunctionOn(eval_fn, vscode_fn0, "big", bp_loc, line, col, res_array_len : len, roundtrip : roundtrip, - test_fn : async(result) => - { - - var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); - var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); - if (is_js) - await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); - else - AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + await RunCallFunctionOn(eval_fn, vscode_fn0, "big", bp_loc, line, col, res_array_len: len, roundtrip: roundtrip, + test_fn: async (result) => + { + + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); // Check for a __proto__ object // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - await CheckProps(obj_own.Value["result"], new - { - length = TNumber(len), - // __proto__ = TArray (type, 0) // Is this one really required? - }, $"obj_own", num_fields : is_js ? 2 : 1); - - }); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + await CheckProps(obj_own.Value["result"], new + { + length = TNumber(len), + // __proto__ = TArray (type, 0) // Is this one really required? + }, $"obj_own", num_fields: is_js ? 2 : 1); + + }); } void CheckJFunction(JToken actual, string className, string label) @@ -79,48 +79,48 @@ public async Task CheckVSCodeTestFunction2(string eval_fn, string bp_loc, int li string vscode_fn1 = "function(e,t){const r={},n=-1===e?0:e,i=-1===t?this.length:e+t;for(let e=n;e - { + test_fn: async (result) => + { - var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); // isOwn = false, accessorPropertiesOnly = true var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); - if (is_js) - await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); - else - AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); // Ignoring the __proto__ property // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - var obj_own_val = obj_own.Value["result"]; - var num_elems_recd = len == 0 ? 0 : num_elems_fetch; - AssertEqual(is_js ? num_elems_recd + 1 : num_elems_recd, obj_own_val.Count(), $"obj_own-count"); - - if (is_js) - CheckObject(obj_own_val, "__proto__", "Object"); - - for (int i = fetch_start_idx; i < fetch_start_idx + num_elems_recd; i++) - CheckNumber(obj_own_val, i.ToString(), 1000 + i); - }); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + var num_elems_recd = len == 0 ? 0 : num_elems_fetch; + AssertEqual(is_js ? num_elems_recd + 1 : num_elems_recd, obj_own_val.Count(), $"obj_own-count"); + + if (is_js) + CheckObject(obj_own_val, "__proto__", "Object"); + + for (int i = fetch_start_idx; i < fetch_start_idx + num_elems_recd; i++) + CheckNumber(obj_own_val, i.ToString(), 1000 + i); + }); } [Theory] @@ -135,38 +135,38 @@ public async Task RunOnArrayReturnEmptyArray(string eval_fn, string bp_loc, int await RunCallFunctionOn(eval_fn, "function () { return []; }", "big", bp_loc, line, col, - res_array_len : ret_len, - roundtrip : roundtrip, - test_fn : async(result) => - { - var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); + res_array_len: ret_len, + roundtrip: roundtrip, + test_fn: async (result) => + { + var is_js = bp_loc.EndsWith(".js", StringComparison.Ordinal); // getProperties (isOwn = false, accessorPropertiesOnly = true) var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); - if (is_js) - await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); - else - AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); // getProperties (isOwn = true, accessorPropertiesOnly = false) var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - await CheckProps(obj_own.Value["result"], new - { - length = TNumber(ret_len), - // __proto__ returned by js - }, $"obj_own", num_fields : is_js ? 2 : 1); - }); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + await CheckProps(obj_own.Value["result"], new + { + length = TNumber(ret_len), + // __proto__ returned by js + }, $"obj_own", num_fields: is_js ? 2 : 1); + }); } [Theory] @@ -180,47 +180,47 @@ public async Task RunOnArrayReturnArray(string eval_fn, string bp_loc, int line, await RunCallFunctionOn(eval_fn, "function (m) { return Object.values (this).filter ((k, i) => i%m == 0); }", "big", bp_loc, line, col, - fn_args : JArray.FromObject(new [] { new { value = 2 } }), - res_array_len : ret_len, - roundtrip : roundtrip, - test_fn : async(result) => - { - var is_js = bp_loc.EndsWith(".js"); + fn_args: JArray.FromObject(new[] { new { value = 2 } }), + res_array_len: ret_len, + roundtrip: roundtrip, + test_fn: async (result) => + { + var is_js = bp_loc.EndsWith(".js"); // getProperties (own=false) var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); - if (is_js) - await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); - else - AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + if (is_js) + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + else + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); // getProperties (own=true) // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); // AssertEqual (2, obj_own.Value ["result"].Count (), $"{label}-obj_own.count"); var obj_own_val = obj_own.Value["result"]; - await CheckProps(obj_own_val, new - { - length = TNumber(ret_len), - // __proto__ returned by JS + await CheckProps(obj_own_val, new + { + length = TNumber(ret_len), + // __proto__ returned by JS }, $"obj_own", num_fields: (is_js ? ret_len + 2 : ret_len + 1)); - for (int i = 0; i < ret_len; i++) - CheckNumber(obj_own_val, i.ToString(), i * 2 + 1000); - }); + for (int i = 0; i < ret_len; i++) + CheckNumber(obj_own_val, i.ToString(), i * 2 + 1000); + }); } [Theory] @@ -231,60 +231,60 @@ public async Task RunOnVTArray(bool roundtrip) => await RunCallFunctionOn( "function (m) { return Object.values (this).filter ((k, i) => i%m == 0); }", "ss_arr", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, - fn_args : JArray.FromObject(new [] { new { value = 2 } }), - res_array_len : 5, - roundtrip : roundtrip, - test_fn : async(result) => - { - var ret_len = 5; + fn_args: JArray.FromObject(new[] { new { value = 2 } }), + res_array_len: 5, + roundtrip: roundtrip, + test_fn: async (result) => + { + var ret_len = 5; // getProperties (own=false) var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); - AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); + AssertEqual(0, obj_accessors.Value["result"]?.Count(), "obj_accessors-count"); // getProperties (own=true) // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - var obj_own_val = obj_own.Value["result"]; - await CheckProps(obj_own_val, new - { - length = TNumber(ret_len), - // __proto__ returned by JS - }, "obj_own", num_fields : ret_len + 1); - - for (int i = 0; i < ret_len; i++) - { - var act_i = CheckValueType(obj_own_val, i.ToString(), "Math.SimpleStruct"); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + await CheckProps(obj_own_val, new + { + length = TNumber(ret_len), + // __proto__ returned by JS + }, "obj_own", num_fields: ret_len + 1); + + for (int i = 0; i < ret_len; i++) + { + var act_i = CheckValueType(obj_own_val, i.ToString(), "Math.SimpleStruct"); // Valuetypes can get sent as part of the container's getProperties, so ensure that we can access it var act_i_props = await GetProperties(act_i["value"]["objectId"]?.Value()); - await CheckProps(act_i_props, new - { - dt = TValueType("System.DateTime", new DateTime(2020 + (i * 2), 1, 2, 3, 4, 5).ToString()), - gs = TValueType("Math.GenericStruct") - }, "obj_own ss_arr[{i}]"); - - var gs_props = await GetObjectOnLocals(act_i_props, "gs"); - await CheckProps(gs_props, new - { - List = TObject("System.Collections.Generic.List", is_null : true), - StringField = TString($"ss_arr # {i*2} # gs # StringField") - }, "obj_own ss_arr[{i}].gs"); - - } - }); + await CheckProps(act_i_props, new + { + dt = TValueType("System.DateTime", new DateTime(2020 + (i * 2), 1, 2, 3, 4, 5).ToString()), + gs = TValueType("Math.GenericStruct") + }, "obj_own ss_arr[{i}]"); + + var gs_props = await GetObjectOnLocals(act_i_props, "gs"); + await CheckProps(gs_props, new + { + List = TObject("System.Collections.Generic.List", is_null: true), + StringField = TString($"ss_arr # {i * 2} # gs # StringField") + }, "obj_own ss_arr[{i}].gs"); + + } + }); [Theory] [InlineData(false)] @@ -294,45 +294,45 @@ public async Task RunOnCFOValueTypeResult(bool roundtrip) => await RunCallFuncti fn_decl: "function () { return this; }", local_name: "simple_struct", bp_loc: "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, - roundtrip : roundtrip, - test_fn : async(result) => - { + roundtrip: roundtrip, + test_fn: async (result) => + { // getProperties (own=false) var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); - AssertEqual(0, obj_accessors.Value["result"].Count(), "obj_accessors-count"); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); + AssertEqual(0, obj_accessors.Value["result"].Count(), "obj_accessors-count"); // getProperties (own=true) // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - var obj_own_val = obj_own.Value["result"]; - var dt = new DateTime(2020, 1, 2, 3, 4, 5); - await CheckProps(obj_own_val, new - { - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("Math.GenericStruct") - }, $"obj_own-props"); - - await CheckDateTime(obj_own_val, "dt", dt); - - var gs_props = await GetObjectOnLocals(obj_own_val, "gs"); - await CheckProps(gs_props, new - { - List = TObject("System.Collections.Generic.List", is_null : true), - StringField = TString($"simple_struct # gs # StringField") - }, "simple_struct.gs-props"); - }); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + var dt = new DateTime(2020, 1, 2, 3, 4, 5); + await CheckProps(obj_own_val, new + { + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("Math.GenericStruct") + }, $"obj_own-props"); + + await CheckDateTime(obj_own_val, "dt", dt); + + var gs_props = await GetObjectOnLocals(obj_own_val, "gs"); + await CheckProps(gs_props, new + { + List = TObject("System.Collections.Generic.List", is_null: true), + StringField = TString($"simple_struct # gs # StringField") + }, "simple_struct.gs-props"); + }); [Theory] [InlineData(false)] @@ -341,37 +341,37 @@ public async Task RunOnJSObject(bool roundtrip) => await RunCallFunctionOn( "object_js_test ();", "function () { return this; }", "obj", "/other.js", 17, 1, - fn_args : JArray.FromObject(new [] { new { value = 2 } }), - roundtrip : roundtrip, - test_fn : async(result) => - { + fn_args: JArray.FromObject(new[] { new { value = 2 } }), + roundtrip: roundtrip, + test_fn: async (result) => + { // getProperties (own=false) var obj_accessors = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = true, - ownProperties = false - }), ctx.token); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = true, + ownProperties = false + }), ctx.token); - await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); + await CheckProps(obj_accessors.Value["result"], new { __proto__ = TIgnore() }, "obj_accessors"); // getProperties (own=true) // isOwn = true, accessorPropertiesOnly = false var obj_own = await ctx.cli.SendCommand("Runtime.getProperties", JObject.FromObject(new - { - objectId = result.Value["result"]["objectId"].Value(), - accessorPropertiesOnly = false, - ownProperties = true - }), ctx.token); - - var obj_own_val = obj_own.Value["result"]; - await CheckProps(obj_own_val, new - { - a_obj = TObject("Object"), - b_arr = TArray("Array", 2) - }, "obj_own", num_fields : 3); - }); + { + objectId = result.Value["result"]["objectId"].Value(), + accessorPropertiesOnly = false, + ownProperties = true + }), ctx.token); + + var obj_own_val = obj_own.Value["result"]; + await CheckProps(obj_own_val, new + { + a_obj = TObject("Object"), + b_arr = TArray("Array", 2) + }, "obj_own", num_fields: 3); + }); [Theory] [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] @@ -383,31 +383,31 @@ public async Task RunOnArrayReturnObjectArrayByValue(string eval_fn, string bp_l var ret_len = 5; await RunCallFunctionOn(eval_fn, "function () { return Object.values (this).filter ((k, i) => i%2 == 0); }", - "big", bp_loc, line, col, returnByValue : true, roundtrip : roundtrip, - test_fn : async(result) => - { + "big", bp_loc, line, col, returnByValue: true, roundtrip: roundtrip, + test_fn: async (result) => + { // Check cfo result AssertEqual(JTokenType.Object, result.Value["result"].Type, "cfo-result-jsontype"); - AssertEqual("object", result.Value["result"]["type"]?.Value(), "cfo-res-type"); - - AssertEqual(JTokenType.Array, result.Value["result"]["value"].Type, "cfo-res-value-jsontype"); - var actual = result.Value["result"] ? ["value"].Values().ToArray(); - AssertEqual(ret_len, actual.Length, "cfo-res-value-length"); - - for (int i = 0; i < ret_len; i++) - { - var exp_num = i * 2 + 1000; - if (bp_loc.EndsWith(".js", StringComparison.Ordinal)) - AssertEqual(exp_num, actual[i].Value(), $"[{i}]"); - else - { - AssertEqual("number", actual[i] ? ["type"]?.Value(), $"[{i}]-type"); - AssertEqual(exp_num.ToString(), actual[i] ? ["description"]?.Value(), $"[{i}]-description"); - AssertEqual(exp_num, actual[i] ? ["value"]?.Value(), $"[{i}]-value"); - } - } - await Task.CompletedTask; - }); + AssertEqual("object", result.Value["result"]["type"]?.Value(), "cfo-res-type"); + + AssertEqual(JTokenType.Array, result.Value["result"]["value"].Type, "cfo-res-value-jsontype"); + var actual = result.Value["result"]?["value"].Values().ToArray(); + AssertEqual(ret_len, actual.Length, "cfo-res-value-length"); + + for (int i = 0; i < ret_len; i++) + { + var exp_num = i * 2 + 1000; + if (bp_loc.EndsWith(".js", StringComparison.Ordinal)) + AssertEqual(exp_num, actual[i].Value(), $"[{i}]"); + else + { + AssertEqual("number", actual[i]?["type"]?.Value(), $"[{i}]-type"); + AssertEqual(exp_num.ToString(), actual[i]?["description"]?.Value(), $"[{i}]-description"); + AssertEqual(exp_num, actual[i]?["value"]?.Value(), $"[{i}]-value"); + } + } + await Task.CompletedTask; + }); } [Theory] @@ -417,25 +417,25 @@ await RunCallFunctionOn(eval_fn, [InlineData("invoke_static_method ('[debugger-test] DebuggerTests.CallFunctionOnTest:LocalsTest', 10);", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 23, 12, true)] public async Task RunOnArrayReturnArrayByValue(string eval_fn, string bp_loc, int line, int col, bool roundtrip) => await RunCallFunctionOn(eval_fn, "function () { return Object.getOwnPropertyNames (this); }", - "big", bp_loc, line, col, returnByValue : true, - roundtrip : roundtrip, - test_fn : async(result) => - { + "big", bp_loc, line, col, returnByValue: true, + roundtrip: roundtrip, + test_fn: async (result) => + { // Check cfo result AssertEqual("object", result.Value["result"]["type"]?.Value(), "cfo-res-type"); - var exp = new JArray(); - for (int i = 0; i < 10; i++) - exp.Add(i.ToString()); - exp.Add("length"); + var exp = new JArray(); + for (int i = 0; i < 10; i++) + exp.Add(i.ToString()); + exp.Add("length"); - var actual = result.Value["result"] ? ["value"]; - if (!JObject.DeepEquals(exp, actual)) - { - Assert.True(false, $"Results don't match.\nExpected: {exp}\nActual: {actual}"); - } - await Task.CompletedTask; - }); + var actual = result.Value["result"]?["value"]; + if (!JObject.DeepEquals(exp, actual)) + { + Assert.True(false, $"Results don't match.\nExpected: {exp}\nActual: {actual}"); + } + await Task.CompletedTask; + }); [Theory] [InlineData("big_array_js_test (10);", "/other.js", 8, 1, false)] @@ -449,7 +449,7 @@ public async Task RunOnArrayReturnPrimitive(string eval_fn, string bp_loc, int l var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); await SetBreakpoint(bp_loc, line, col); @@ -470,7 +470,7 @@ await insp.Ready(async(cli, token) => var cfo_args = JObject.FromObject(new { functionDeclaration = "function () { return 5; }", - objectId = obj_id + objectId = obj_id }); // value of @returnByValue doesn't matter, as the returned value @@ -485,7 +485,7 @@ await insp.Ready(async(cli, token) => cfo_args = JObject.FromObject(new { functionDeclaration = "function () { return 'test value'; }", - objectId = obj_id + objectId = obj_id }); // value of @returnByValue doesn't matter, as the returned value @@ -500,7 +500,7 @@ await insp.Ready(async(cli, token) => cfo_args = JObject.FromObject(new { functionDeclaration = "function () { return null; }", - objectId = obj_id + objectId = obj_id }); // value of @returnByValue doesn't matter, as the returned value @@ -530,7 +530,7 @@ public async Task CFOWithSilentReturnsErrors(string eval_fn, string bp_loc, int var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); await SetBreakpoint(bp_loc, line, col); @@ -549,7 +549,7 @@ await insp.Ready(async(cli, token) => var cfo_args = JObject.FromObject(new { functionDeclaration = $"function () {{ throw Error ('{error_msg}'); }}", - objectId = big_obj_id + objectId = big_obj_id }); if (silent.HasValue) @@ -561,7 +561,7 @@ await insp.Ready(async(cli, token) => Assert.False(result.IsOk, "result.IsOk"); Assert.True(result.IsErr, "result.IsErr"); - var hasErrorMessage = result.Error["exceptionDetails"] ? ["exception"] ? ["description"]?.Value()?.Contains(error_msg); + var hasErrorMessage = result.Error["exceptionDetails"]?["exception"]?["description"]?.Value()?.Contains(error_msg); Assert.True((hasErrorMessage ?? false), "Exception message not found"); }); } @@ -616,96 +616,96 @@ await insp.Ready(async(cli, token) => [Theory] [MemberData(nameof(GettersTestData), "ptd", false)] [MemberData(nameof(GettersTestData), "ptd", true)] - [MemberData(nameof (GettersTestData), "swp", false)] - [MemberData(nameof (GettersTestData), "swp", true)] + [MemberData(nameof(GettersTestData), "swp", false)] + [MemberData(nameof(GettersTestData), "swp", true)] public async Task PropertyGettersTest(string eval_fn, string method_name, int line, int col, string cfo_fn, Func get_args_fn, string local_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-cfo-test.cs", line, col, method_name, $"window.setTimeout(function() {{ {eval_fn} }}, 1);", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - await CheckProps(frame_locals, new - { - ptd = TObject("DebuggerTests.ClassWithProperties"), - swp = TObject("DebuggerTests.StructWithProperties") - }, "locals#0"); - - var obj = GetAndAssertObjectWithName(frame_locals, local_name); - - var dt = new DateTime(4, 5, 6, 7, 8, 9); - var obj_props = await GetProperties(obj?["value"] ? ["objectId"]?.Value()); - await CheckProps(obj_props, new - { - V = TNumber(0xDEADBEEF), - Int = TGetter("Int"), - String = TGetter("String"), - DT = TGetter("DT"), - IntArray = TGetter("IntArray"), - DTArray = TGetter("DTArray"), - StringField = TString(null), + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + await CheckProps(frame_locals, new + { + ptd = TObject("DebuggerTests.ClassWithProperties"), + swp = TObject("DebuggerTests.StructWithProperties") + }, "locals#0"); + + var obj = GetAndAssertObjectWithName(frame_locals, local_name); + + var dt = new DateTime(4, 5, 6, 7, 8, 9); + var obj_props = await GetProperties(obj?["value"]?["objectId"]?.Value()); + await CheckProps(obj_props, new + { + V = TNumber(0xDEADBEEF), + Int = TGetter("Int"), + String = TGetter("String"), + DT = TGetter("DT"), + IntArray = TGetter("IntArray"), + DTArray = TGetter("DTArray"), + StringField = TString(null), // Auto properties show w/o getters, because they have // a backing field DTAutoProperty = TValueType("System.DateTime", dt.ToString()) - }, local_name); + }, local_name); // Automatic properties don't have invokable getters, because we can get their // value from the backing field directly { - var dt_auto_props = await GetObjectOnLocals(obj_props, "DTAutoProperty"); - await CheckDateTime(obj_props, "DTAutoProperty", dt); - } + var dt_auto_props = await GetObjectOnLocals(obj_props, "DTAutoProperty"); + await CheckDateTime(obj_props, "DTAutoProperty", dt); + } // Invoke getters, and check values dt = new DateTime(3, 4, 5, 6, 7, 8); - var res = await InvokeGetter(obj, get_args_fn(new [] { "Int" }), cfo_fn); - await CheckValue(res.Value["result"], JObject.FromObject(new { type = "number", value = (0xDEADBEEF + (uint) dt.Month) }), $"{local_name}.Int"); + var res = await InvokeGetter(obj, get_args_fn(new[] { "Int" }), cfo_fn); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "number", value = (0xDEADBEEF + (uint)dt.Month) }), $"{local_name}.Int"); - res = await InvokeGetter(obj, get_args_fn(new [] { "String" }), cfo_fn); - await CheckValue(res.Value["result"], JObject.FromObject(new { type = "string", value = $"String property, V: 0xDEADBEEF" }), $"{local_name}.String"); + res = await InvokeGetter(obj, get_args_fn(new[] { "String" }), cfo_fn); + await CheckValue(res.Value["result"], JObject.FromObject(new { type = "string", value = $"String property, V: 0xDEADBEEF" }), $"{local_name}.String"); - res = await InvokeGetter(obj, get_args_fn(new [] { "DT" }), cfo_fn); - await CheckValue(res.Value["result"], TValueType("System.DateTime", dt.ToString()), $"{local_name}.DT"); - await CheckDateTimeValue(res.Value["result"], dt); + res = await InvokeGetter(obj, get_args_fn(new[] { "DT" }), cfo_fn); + await CheckValue(res.Value["result"], TValueType("System.DateTime", dt.ToString()), $"{local_name}.DT"); + await CheckDateTimeValue(res.Value["result"], dt); // Check arrays through getters - res = await InvokeGetter(obj, get_args_fn(new [] { "IntArray" }), cfo_fn); - await CheckValue(res.Value["result"], TArray("int[]", 2), $"{local_name}.IntArray"); - { - var arr_elems = await GetProperties(res.Value["result"] ? ["objectId"]?.Value()); - var exp_elems = new [] - { + res = await InvokeGetter(obj, get_args_fn(new[] { "IntArray" }), cfo_fn); + await CheckValue(res.Value["result"], TArray("int[]", 2), $"{local_name}.IntArray"); + { + var arr_elems = await GetProperties(res.Value["result"]?["objectId"]?.Value()); + var exp_elems = new[] + { TNumber(10), TNumber(20) - }; + }; - await CheckProps(arr_elems, exp_elems, $"{local_name}.IntArray"); - } + await CheckProps(arr_elems, exp_elems, $"{local_name}.IntArray"); + } - res = await InvokeGetter(obj, get_args_fn(new [] { "DTArray" }), cfo_fn); - await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), $"{local_name}.DTArray"); - { - var dt0 = new DateTime(6, 7, 8, 9, 10, 11); - var dt1 = new DateTime(1, 2, 3, 4, 5, 6); + res = await InvokeGetter(obj, get_args_fn(new[] { "DTArray" }), cfo_fn); + await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), $"{local_name}.DTArray"); + { + var dt0 = new DateTime(6, 7, 8, 9, 10, 11); + var dt1 = new DateTime(1, 2, 3, 4, 5, 6); - var arr_elems = await GetProperties(res.Value["result"] ? ["objectId"]?.Value()); - var exp_elems = new [] - { + var arr_elems = await GetProperties(res.Value["result"]?["objectId"]?.Value()); + var exp_elems = new[] + { TValueType("System.DateTime", dt0.ToString()), TValueType("System.DateTime", dt1.ToString()), - }; + }; - await CheckProps(arr_elems, exp_elems, $"{local_name}.DTArray"); + await CheckProps(arr_elems, exp_elems, $"{local_name}.DTArray"); - res = await InvokeGetter(arr_elems[0], "Date"); - await CheckDateTimeValue(res.Value["result"], dt0.Date); - } - }); + res = await InvokeGetter(arr_elems[0], "Date"); + await CheckDateTimeValue(res.Value["result"], dt0.Date); + } + }); [Theory] [InlineData("invoke_static_method_async ('[debugger-test] DebuggerTests.CallFunctionOnTest:PropertyGettersTestAsync');", "dotnet://debugger-test.dll/debugger-cfo-test.cs", 38, 12, true)] @@ -719,39 +719,39 @@ public async Task CheckAccessorsOnObjectsWithCFO(string eval_fn, string bp_loc, await RunCallFunctionOn( eval_fn, "function() { return this; }", "ptd", bp_loc, line, col, - roundtrip : roundtrip, - test_fn : async(result) => - { + roundtrip: roundtrip, + test_fn: async (result) => + { - var is_js = bp_loc.EndsWith(".js"); + var is_js = bp_loc.EndsWith(".js"); // Check with `accessorPropertiesOnly=true` - var id = result.Value?["result"] ? ["objectId"]?.Value(); - var get_prop_req = JObject.FromObject(new - { - objectId = id, - accessorPropertiesOnly = true - }); + var id = result.Value?["result"]?["objectId"]?.Value(); + var get_prop_req = JObject.FromObject(new + { + objectId = id, + accessorPropertiesOnly = true + }); - var res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 6 : 5); // js returns extra `__proto__` member also + var res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 6 : 5); // js returns extra `__proto__` member also Assert.False(res.Value["result"].Any(jt => jt["name"]?.Value() == "StringField"), "StringField shouldn't be returned for `accessorPropertiesOnly`"); // Check with `accessorPropertiesOnly` unset, == false get_prop_req = JObject.FromObject(new - { - objectId = id, - }); + { + objectId = id, + }); - res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 8 : 7); // js returns a `__proto__` member also + res = await GetPropertiesAndCheckAccessors(get_prop_req, is_js ? 8 : 7); // js returns a `__proto__` member also Assert.True(res.Value["result"].Any(jt => jt["name"]?.Value() == "StringField"), "StringField should be returned for `accessorPropertiesOnly=false`"); - }); + }); async Task GetPropertiesAndCheckAccessors(JObject get_prop_req, int num_fields) { var res = await ctx.cli.SendCommand("Runtime.getProperties", get_prop_req, ctx.token); if (!res.IsOk) - Assert.True(false, $"Runtime.getProperties failed for {get_prop_req.ToString ()}, with Result: {res}"); + Assert.True(false, $"Runtime.getProperties failed for {get_prop_req.ToString()}, with Result: {res}"); var accessors = new string[] { "Int", "String", "DT", "IntArray", "DTArray" }; foreach (var name in accessors) @@ -776,19 +776,19 @@ async Task GetPropertiesAndCheckAccessors(JObject get_prop_req, int num_ public async Task RunOnInvalidCfoId(string eval_fn, string bp_loc, int line, int col, bool use_cfo) => await RunCallFunctionOn( eval_fn, "function() { return this; }", "ptd", bp_loc, line, col, - test_fn : async(cfo_result) => - { - var ptd_id = cfo_result.Value?["result"] ? ["objectId"]?.Value(); + test_fn: async (cfo_result) => + { + var ptd_id = cfo_result.Value?["result"]?["objectId"]?.Value(); - var cfo_args = JObject.FromObject(new - { - functionDeclaration = "function () { return 0; }", - objectId = ptd_id + "_invalid" - }); + var cfo_args = JObject.FromObject(new + { + functionDeclaration = "function () { return 0; }", + objectId = ptd_id + "_invalid" + }); - var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); - Assert.True(res.IsErr); - }); + var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); + Assert.True(res.IsErr); + }); [Theory] [MemberData(nameof(NegativeTestsData), false)] @@ -799,7 +799,7 @@ public async Task RunOnInvalidThirdSegmentOfObjectId(string eval_fn, string bp_l var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -817,7 +817,7 @@ await insp.Ready(async(cli, token) => var cfo_args = JObject.FromObject(new { functionDeclaration = "function () { return 0; }", - objectId = ptd_id + "_invalid" + objectId = ptd_id + "_invalid" }); var res = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); @@ -835,7 +835,7 @@ public async Task InvalidPropertyGetters(string eval_fn, string bp_loc, int line var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); await SetBreakpoint(bp_loc, line, col); @@ -854,7 +854,7 @@ await insp.Ready(async(cli, token) => foreach (var invalid_arg in invalid_args) { var getter_res = await InvokeGetter(JObject.FromObject(new { value = new { objectId = ptd_id } }), invalid_arg); - AssertEqual("undefined", getter_res.Value["result"] ? ["type"]?.ToString(), $"Expected to get undefined result for non-existant accessor - {invalid_arg}"); + AssertEqual("undefined", getter_res.Value["result"]?["type"]?.ToString(), $"Expected to get undefined result for non-existant accessor - {invalid_arg}"); } }); } @@ -864,28 +864,28 @@ await insp.Ready(async(cli, token) => public async Task ReturnNullFromCFO(string eval_fn, string bp_loc, int line, int col, bool use_cfo) => await RunCallFunctionOn( eval_fn, "function() { return this; }", "ptd", bp_loc, line, col, - test_fn : async(result) => - { - var is_js = bp_loc.EndsWith(".js"); - var ptd = JObject.FromObject(new { value = new { objectId = result.Value?["result"] ? ["objectId"]?.Value() } }); - - var null_value_json = JObject.Parse("{ 'type': 'object', 'subtype': 'null', 'value': null }"); - foreach (var returnByValue in new bool?[] { null, false, true }) - { - var res = await InvokeGetter(ptd, "StringField", returnByValue : returnByValue); - if (is_js) - { + test_fn: async (result) => + { + var is_js = bp_loc.EndsWith(".js"); + var ptd = JObject.FromObject(new { value = new { objectId = result.Value?["result"]?["objectId"]?.Value() } }); + + var null_value_json = JObject.Parse("{ 'type': 'object', 'subtype': 'null', 'value': null }"); + foreach (var returnByValue in new bool?[] { null, false, true }) + { + var res = await InvokeGetter(ptd, "StringField", returnByValue: returnByValue); + if (is_js) + { // In js case, it doesn't know the className, so the result looks slightly different Assert.True( - JObject.DeepEquals(res.Value["result"], null_value_json), - $"[StringField#returnByValue = {returnByValue}] Json didn't match. Actual: {res.Value ["result"]} vs {null_value_json}"); - } - else - { - await CheckValue(res.Value["result"], TString(null), "StringField"); - } - } - }); + JObject.DeepEquals(res.Value["result"], null_value_json), + $"[StringField#returnByValue = {returnByValue}] Json didn't match. Actual: {res.Value["result"]} vs {null_value_json}"); + } + else + { + await CheckValue(res.Value["result"], TString(null), "StringField"); + } + } + }); /* * 1. runs `Runtime.callFunctionOn` on the objectId, @@ -905,7 +905,7 @@ async Task RunCallFunctionOn(string eval_fn, string fn_decl, string local_name, var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); await SetBreakpoint(bp_loc, line, col); @@ -926,7 +926,7 @@ await insp.Ready(async(cli, token) => var cfo_args = JObject.FromObject(new { functionDeclaration = fn_decl, - objectId = obj_id + objectId = obj_id }); if (fn_args != null) @@ -948,7 +948,7 @@ await insp.Ready(async(cli, token) => cfo_args = JObject.FromObject(new { functionDeclaration = "function () { return this; }", - objectId = result.Value["result"]["objectId"]?.Value() + objectId = result.Value["result"]["objectId"]?.Value() }); if (fn_args != null) @@ -978,4 +978,4 @@ async Task CheckCFOResult(Result result) } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs index 6b7a5603d2d2..034b0613997e 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs @@ -26,7 +26,7 @@ public async Task CheckDateTimeLocale(string locale) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-datetime-test.cs"; @@ -37,31 +37,31 @@ await insp.Ready(async(cli, token) => "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.DateTimeTest:LocaleTest'," + $"'{locale}'); }}, 1);", debugger_test_loc, 25, 12, "LocaleTest", - locals_fn : async(locals) => - { - DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(locale).DateTimeFormat; - CultureInfo.CurrentCulture = new CultureInfo(locale, false); - DateTime dt = new DateTime(2020, 1, 2, 3, 4, 5); - string dt_str = dt.ToString(); + locals_fn: async (locals) => + { + DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(locale).DateTimeFormat; + CultureInfo.CurrentCulture = new CultureInfo(locale, false); + DateTime dt = new DateTime(2020, 1, 2, 3, 4, 5); + string dt_str = dt.ToString(); - var fdtp = dtfi.FullDateTimePattern; - var ldp = dtfi.LongDatePattern; - var ltp = dtfi.LongTimePattern; - var sdp = dtfi.ShortDatePattern; - var stp = dtfi.ShortTimePattern; + var fdtp = dtfi.FullDateTimePattern; + var ldp = dtfi.LongDatePattern; + var ltp = dtfi.LongTimePattern; + var sdp = dtfi.ShortDatePattern; + var stp = dtfi.ShortTimePattern; - CheckString(locals, "fdtp", fdtp); - CheckString(locals, "ldp", ldp); - CheckString(locals, "ltp", ltp); - CheckString(locals, "sdp", sdp); - CheckString(locals, "stp", stp); - await CheckDateTime(locals, "dt", dt); - CheckString(locals, "dt_str", dt_str); - } + CheckString(locals, "fdtp", fdtp); + CheckString(locals, "ldp", ldp); + CheckString(locals, "ltp", ltp); + CheckString(locals, "sdp", sdp); + CheckString(locals, "stp", stp); + await CheckDateTime(locals, "dt", dt); + CheckString(locals, "dt_str", dt_str); + } ); }); } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs index e186ddc5f71c..a2daecd29d5c 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -23,61 +23,61 @@ public async Task InspectLocalsWithDelegatesAtBreakpointSite(int frame, int line await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test.cs", line, col, method_name, "window.setTimeout(function() { invoke_delegates_test (); }, 1);", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); - - await CheckProps(locals, new - { - fn_func = TDelegate("System.Func", "bool |(Math)"), - fn_func_null = TObject("System.Func", is_null : true), - fn_func_arr = TArray("System.Func[]", 1), - fn_del = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), - fn_del_null = TObject("Math.IsMathNull", is_null : true), - fn_del_arr = TArray("Math.IsMathNull[]", 1), - - // Unused locals - fn_func_unused = TDelegate("System.Func", "bool |(Math)"), - fn_func_null_unused = TObject("System.Func", is_null : true), - fn_func_arr_unused = TArray("System.Func[]", 1), - - fn_del_unused = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), - fn_del_null_unused = TObject("Math.IsMathNull", is_null : true), - fn_del_arr_unused = TArray("Math.IsMathNull[]", 1), - - res = TBool(false), - m_obj = TObject("Math") - }, "locals"); - - await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func", "bool |(Math)"), + fn_func_null = TObject("System.Func", is_null: true), + fn_func_arr = TArray("System.Func[]", 1), + fn_del = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), + fn_del_null = TObject("Math.IsMathNull", is_null: true), + fn_del_arr = TArray("Math.IsMathNull[]", 1), + + // Unused locals + fn_func_unused = TDelegate("System.Func", "bool |(Math)"), + fn_func_null_unused = TObject("System.Func", is_null: true), + fn_func_arr_unused = TArray("System.Func[]", 1), + + fn_del_unused = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), + fn_del_null_unused = TObject("Math.IsMathNull", is_null: true), + fn_del_arr_unused = TArray("Math.IsMathNull[]", 1), + + res = TBool(false), + m_obj = TObject("Math") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new[] + { TDelegate( "System.Func", "bool |(Math)") - }, "locals#fn_func_arr"); + }, "locals#fn_func_arr"); - await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] - { + await CompareObjectPropertiesFor(locals, "fn_del_arr", new[] + { TDelegate( "Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)") - }, "locals#fn_del_arr"); + }, "locals#fn_del_arr"); - await CompareObjectPropertiesFor(locals, "fn_func_arr_unused", new [] - { + await CompareObjectPropertiesFor(locals, "fn_func_arr_unused", new[] + { TDelegate( "System.Func", "bool |(Math)") - }, "locals#fn_func_arr_unused"); + }, "locals#fn_func_arr_unused"); - await CompareObjectPropertiesFor(locals, "fn_del_arr_unused", new [] - { + await CompareObjectPropertiesFor(locals, "fn_del_arr_unused", new[] + { TDelegate( "Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)") - }, "locals#fn_del_arr_unused"); - } + }, "locals#fn_del_arr_unused"); + } ); [Theory] @@ -90,66 +90,66 @@ public async Task InspectDelegateSignaturesWithFunc(int frame, int line, int col line, col, bp_method, "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:DelegatesSignatureTest'); }, 1)", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); - - await CheckProps(locals, new - { - fn_func = TDelegate("System.Func>, Math.GenericStruct>", - "Math.GenericStruct |(Math,Math.GenericStruct>)"), - - fn_func_del = TDelegate("System.Func>, Math.GenericStruct>", - "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), - - fn_func_null = TObject("System.Func>, Math.GenericStruct>", is_null : true), - fn_func_only_ret = TDelegate("System.Func", "bool |()"), - fn_func_arr = TArray("System.Func>, Math.GenericStruct>[]", 1), - - fn_del = TDelegate("Math.DelegateForSignatureTest", - "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), - - fn_del_l = TDelegate("Math.DelegateForSignatureTest", - "Math.GenericStruct |(Math,Math.GenericStruct>)"), - - fn_del_null = TObject("Math.DelegateForSignatureTest", is_null : true), - fn_del_arr = TArray("Math.DelegateForSignatureTest[]", 2), - m_obj = TObject("Math"), - gs_gs = TValueType("Math.GenericStruct>"), - fn_void_del = TDelegate("Math.DelegateWithVoidReturn", - "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), - - fn_void_del_arr = TArray("Math.DelegateWithVoidReturn[]", 1), - fn_void_del_null = TObject("Math.DelegateWithVoidReturn", is_null : true), - gs = TValueType("Math.GenericStruct"), - rets = TArray("Math.GenericStruct[]", 6) - }, "locals"); - - await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func>, Math.GenericStruct>", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + + fn_func_del = TDelegate("System.Func>, Math.GenericStruct>", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + + fn_func_null = TObject("System.Func>, Math.GenericStruct>", is_null: true), + fn_func_only_ret = TDelegate("System.Func", "bool |()"), + fn_func_arr = TArray("System.Func>, Math.GenericStruct>[]", 1), + + fn_del = TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), + + fn_del_l = TDelegate("Math.DelegateForSignatureTest", + "Math.GenericStruct |(Math,Math.GenericStruct>)"), + + fn_del_null = TObject("Math.DelegateForSignatureTest", is_null: true), + fn_del_arr = TArray("Math.DelegateForSignatureTest[]", 2), + m_obj = TObject("Math"), + gs_gs = TValueType("Math.GenericStruct>"), + fn_void_del = TDelegate("Math.DelegateWithVoidReturn", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), + + fn_void_del_arr = TArray("Math.DelegateWithVoidReturn[]", 1), + fn_void_del_null = TObject("Math.DelegateWithVoidReturn", is_null: true), + gs = TValueType("Math.GenericStruct"), + rets = TArray("Math.GenericStruct[]", 6) + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new[] + { TDelegate( "System.Func>, Math.GenericStruct>", "Math.GenericStruct |(Math,Math.GenericStruct>)"), - }, "locals#fn_func_arr"); + }, "locals#fn_func_arr"); - await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] - { + await CompareObjectPropertiesFor(locals, "fn_del_arr", new[] + { TDelegate( "Math.DelegateForSignatureTest", "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), TDelegate( "Math.DelegateForSignatureTest", "Math.GenericStruct |(Math,Math.GenericStruct>)") - }, "locals#fn_del_arr"); + }, "locals#fn_del_arr"); - await CompareObjectPropertiesFor(locals, "fn_void_del_arr", new [] - { + await CompareObjectPropertiesFor(locals, "fn_void_del_arr", new[] + { TDelegate( "Math.DelegateWithVoidReturn", "void DelegateTargetWithVoidReturn (Math.GenericStruct)") - }, "locals#fn_void_del_arr"); - }); + }, "locals#fn_void_del_arr"); + }); [Theory] [InlineData(0, 224, 8, "ActionTSignatureTest", false)] @@ -160,29 +160,29 @@ public async Task ActionTSignatureTest(int frame, int line, int col, string bp_m "dotnet://debugger-test.dll/debugger-test.cs", line, col, bp_method, "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:ActionTSignatureTest'); }, 1)", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); - - await CheckProps(locals, new - { - fn_action = TDelegate("System.Action>", - "void |(Math.GenericStruct)"), - fn_action_del = TDelegate("System.Action>", - "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), - fn_action_bare = TDelegate("System.Action", - "void|()"), + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_action = TDelegate("System.Action>", + "void |(Math.GenericStruct)"), + fn_action_del = TDelegate("System.Action>", + "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), + fn_action_bare = TDelegate("System.Action", + "void|()"), - fn_action_null = TObject("System.Action>", is_null : true), + fn_action_null = TObject("System.Action>", is_null: true), - fn_action_arr = TArray("System.Action>[]", 3), + fn_action_arr = TArray("System.Action>[]", 3), - gs = TValueType("Math.GenericStruct"), - }, "locals"); + gs = TValueType("Math.GenericStruct"), + }, "locals"); - await CompareObjectPropertiesFor(locals, "fn_action_arr", new [] - { + await CompareObjectPropertiesFor(locals, "fn_action_arr", new[] + { TDelegate( "System.Action>", "void |(Math.GenericStruct)"), @@ -190,8 +190,8 @@ public async Task ActionTSignatureTest(int frame, int line, int col, string bp_m "System.Action>", "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), TObject("System.Action>", is_null : true) - }, "locals#fn_action_arr"); - }); + }, "locals#fn_action_arr"); + }); [Theory] [InlineData(0, 242, 8, "NestedDelegatesTest", false)] @@ -202,39 +202,39 @@ public async Task NestedDelegatesTest(int frame, int line, int col, string bp_me "dotnet://debugger-test.dll/debugger-test.cs", line, col, bp_method, "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:NestedDelegatesTest'); }, 1)", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); - - await CheckProps(locals, new - { - fn_func = TDelegate("System.Func, bool>", - "bool |(Func)"), - fn_func_null = TObject("System.Func, bool>", is_null : true), - fn_func_arr = TArray("System.Func, bool>[]", 1), - fn_del_arr = TArray("System.Func, bool>[]", 1), - - m_obj = TObject("Math"), - fn_del_null = TObject("System.Func, bool>", is_null : true), - fs = TDelegate("System.Func", - "bool |(int)") - }, "locals"); - - await CompareObjectPropertiesFor(locals, "fn_func_arr", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + fn_func = TDelegate("System.Func, bool>", + "bool |(Func)"), + fn_func_null = TObject("System.Func, bool>", is_null: true), + fn_func_arr = TArray("System.Func, bool>[]", 1), + fn_del_arr = TArray("System.Func, bool>[]", 1), + + m_obj = TObject("Math"), + fn_del_null = TObject("System.Func, bool>", is_null: true), + fs = TDelegate("System.Func", + "bool |(int)") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "fn_func_arr", new[] + { TDelegate( "System.Func, bool>", "bool |(System.Func)") - }, "locals#fn_func_arr"); + }, "locals#fn_func_arr"); - await CompareObjectPropertiesFor(locals, "fn_del_arr", new [] - { + await CompareObjectPropertiesFor(locals, "fn_del_arr", new[] + { TDelegate( "System.Func, bool>", "bool DelegateTargetForNestedFunc (Func)") - }, "locals#fn_del_arr"); - }); + }, "locals#fn_del_arr"); + }); [Theory] [InlineData(0, 262, 8, "MethodWithDelegateArgs", false)] @@ -245,29 +245,29 @@ public async Task DelegatesAsMethodArgsTest(int frame, int line, int col, string "dotnet://debugger-test.dll/debugger-test.cs", line, col, bp_method, "window.setTimeout (function () { invoke_static_method ('[debugger-test] Math:DelegatesAsMethodArgsTest'); }, 1)", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); - - await CheckProps(locals, new - { - @this = TObject("Math"), - dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), - fn_func = TDelegate("System.Func", - "bool |(char[])"), - fn_action = TDelegate("System.Action[]>", - "void |(Math.GenericStruct[])") - }, "locals"); - - await CompareObjectPropertiesFor(locals, "dst_arr", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][frame]["callFrameId"].Value()); + + await CheckProps(locals, new + { + @this = TObject("Math"), + dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + fn_func = TDelegate("System.Func", + "bool |(char[])"), + fn_action = TDelegate("System.Action[]>", + "void |(Math.GenericStruct[])") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "dst_arr", new[] + { TDelegate("Math.DelegateForSignatureTest", "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), TDelegate("Math.DelegateForSignatureTest", "Math.GenericStruct |(Math,Math.GenericStruct>)"), - }, "locals#dst_arr"); - }); + }, "locals#dst_arr"); + }); [Theory] [InlineData(false)] @@ -276,31 +276,31 @@ public async Task MethodWithDelegatesAsyncTest(bool use_cfo) => await CheckInspe "dotnet://debugger-test.dll/debugger-test.cs", 281, 8, "MoveNext", //"DelegatesAsMethodArgsTestAsync" "window.setTimeout (function () { invoke_static_method_async ('[debugger-test] Math:MethodWithDelegatesAsyncTest'); }, 1)", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - await CheckProps(locals, new - { - @this = TObject("Math"), - _dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), - _fn_func = TDelegate("System.Func", - "bool |(char[])"), - _fn_action = TDelegate("System.Action[]>", - "void |(Math.GenericStruct[])") - }, "locals"); - - await CompareObjectPropertiesFor(locals, "_dst_arr", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + await CheckProps(locals, new + { + @this = TObject("Math"), + _dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + _fn_func = TDelegate("System.Func", + "bool |(char[])"), + _fn_action = TDelegate("System.Action[]>", + "void |(Math.GenericStruct[])") + }, "locals"); + + await CompareObjectPropertiesFor(locals, "_dst_arr", new[] + { TDelegate( "Math.DelegateForSignatureTest", "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), TDelegate( "Math.DelegateForSignatureTest", "Math.GenericStruct |(Math,Math.GenericStruct>)"), - }, "locals#dst_arr"); - }); + }, "locals#dst_arr"); + }); } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs index bedba1310041..5caae92eee1b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DevToolsClient.cs @@ -22,14 +22,14 @@ internal class DevToolsClient : IDisposable readonly ILogger logger; public DevToolsClient(ILogger logger) - { - this.logger = logger; - } + { + this.logger = logger; + } - ~DevToolsClient() - { - Dispose(false); - } + ~DevToolsClient() + { + Dispose(false); + } public void Dispose() { @@ -79,7 +79,7 @@ async Task ReadOne(CancellationToken token) if (result.EndOfMessage) { mem.Write(buff, 0, result.Count); - return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int) mem.Length); + return Encoding.UTF8.GetString(mem.GetBuffer(), 0, (int)mem.Length); } else { @@ -135,7 +135,7 @@ protected async Task ConnectWithMainLoops( var task = await Task.WhenAny(pending_ops); if (task == pending_ops[0]) { //pending_ops[0] is for message reading - var msg = ((Task) task).Result; + var msg = ((Task)task).Result; pending_ops[0] = ReadOne(token); Task tsk = receive(msg, token); if (tsk != null) @@ -143,7 +143,7 @@ protected async Task ConnectWithMainLoops( } else if (task == pending_ops[1]) { - var res = ((Task) task).Result; + var res = ((Task)task).Result; //it might not throw if exiting successfull return res; } @@ -164,4 +164,4 @@ protected virtual void Log(string priority, string msg) // } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index f2836d3bc352..079c9c87f71f 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -19,19 +19,19 @@ public async Task EvaluateThisProperties() => await CheckInspectLocalsAtBreakpoi "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, "run", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); - CheckContentValue(evaluate, "1"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); - CheckContentValue(evaluate, "2"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); - CheckContentValue(evaluate, "3"); - - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dt"); - await CheckDateTimeValue(evaluate, new DateTime(2000, 5, 4, 3, 2, 1)); - }); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); + CheckContentValue(evaluate, "3"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dt"); + await CheckDateTimeValue(evaluate, new DateTime(2000, 5, 4, 3, 2, 1)); + }); [Theory] [InlineData(63, 12, "EvaluateTestsStructInstanceMethod")] @@ -41,53 +41,53 @@ public async Task EvaluateThisPropertiesOnStruct(int line, int col, string metho "dotnet://debugger-test.dll/debugger-evaluate-test.cs", line, col, method_name, "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); - CheckContentValue(evaluate, "1"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); - CheckContentValue(evaluate, "2"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); - CheckContentValue(evaluate, "3"); - - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dateTime"); - await CheckDateTimeValue(evaluate, new DateTime(2020, 1, 2, 3, 4, 5)); - }); + wait_for_event_fn: async (pause_location) => + { + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "c"); + CheckContentValue(evaluate, "3"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "dateTime"); + await CheckDateTimeValue(evaluate, new DateTime(2020, 1, 2, 3, 4, 5)); + }); [Fact] public async Task EvaluateParameters() => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, "run", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "g"); - CheckContentValue(evaluate, "100"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "h"); - CheckContentValue(evaluate, "200"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "valString"); - CheckContentValue(evaluate, "test"); - }); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "g"); + CheckContentValue(evaluate, "100"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "h"); + CheckContentValue(evaluate, "200"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "valString"); + CheckContentValue(evaluate, "test"); + }); [Fact] public async Task EvaluateLocals() => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, "run", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d"); - CheckContentValue(evaluate, "101"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e"); - CheckContentValue(evaluate, "102"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "f"); - CheckContentValue(evaluate, "103"); - - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_dt"); - await CheckDateTimeValue(evaluate, new DateTime(2010, 9, 8, 7, 6, 5)); - }); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d"); + CheckContentValue(evaluate, "101"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e"); + CheckContentValue(evaluate, "102"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "f"); + CheckContentValue(evaluate, "103"); + + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_dt"); + await CheckDateTimeValue(evaluate, new DateTime(2010, 9, 8, 7, 6, 5)); + }); [Fact] public async Task EvaluateLocalsAsync() @@ -100,72 +100,72 @@ await CheckInspectLocalsAtBreakpointSite( bp_loc, line, col, function_name, "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.ArrayTestsClass:EntryPointForStructMethod', true); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); // sc_arg { - var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); - await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#1"); - - var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); - await CheckProps(sc_arg_props, new - { - X = TNumber(10), - Y = TNumber(45), - Id = TString("sc#Id"), - Color = TEnum("DebuggerTests.RGB", "Blue"), - PointWithCustomGetter = TGetter("PointWithCustomGetter") - }, "sc_arg_props#1"); - } + var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); + await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#1"); + + var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); + await CheckProps(sc_arg_props, new + { + X = TNumber(10), + Y = TNumber(45), + Id = TString("sc#Id"), + Color = TEnum("DebuggerTests.RGB", "Blue"), + PointWithCustomGetter = TGetter("PointWithCustomGetter") + }, "sc_arg_props#1"); + } // local_gs { - var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); - await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#1"); - - var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); - await CheckProps(local_gs_props, new - { - Id = TObject("string", is_null : true), - Color = TEnum("DebuggerTests.RGB", "Red"), - Value = TNumber(0) - }, "local_gs_props#1"); - } + var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); + await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#1"); + + var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); + await CheckProps(local_gs_props, new + { + Id = TObject("string", is_null: true), + Color = TEnum("DebuggerTests.RGB", "Red"), + Value = TNumber(0) + }, "local_gs_props#1"); + } // step, check local_gs pause_location = await StepAndCheck(StepKind.Over, bp_loc, line + 1, col, function_name); - { - var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); - await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#2"); - - var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); - await CheckProps(local_gs_props, new - { - Id = TString("local_gs#Id"), - Color = TEnum("DebuggerTests.RGB", "Green"), - Value = TNumber(4) - }, "local_gs_props#2"); - } + { + var local_gs = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "local_gs"); + await CheckValue(local_gs, TValueType("DebuggerTests.SimpleGenericStruct"), "local_gs#2"); + + var local_gs_props = await GetProperties(local_gs["objectId"]?.Value()); + await CheckProps(local_gs_props, new + { + Id = TString("local_gs#Id"), + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) + }, "local_gs_props#2"); + } // step check sc_arg.Id pause_location = await StepAndCheck(StepKind.Over, bp_loc, line + 2, col, function_name); - { - var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); - await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#2"); - - var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); - await CheckProps(sc_arg_props, new - { - X = TNumber(10), - Y = TNumber(45), - Id = TString("sc_arg#Id"), // <------- This changed - Color = TEnum("DebuggerTests.RGB", "Blue"), - PointWithCustomGetter = TGetter("PointWithCustomGetter") - }, "sc_arg_props#2"); - } - }); + { + var sc_arg = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "sc_arg"); + await CheckValue(sc_arg, TObject("DebuggerTests.SimpleClass"), "sc_arg#2"); + + var sc_arg_props = await GetProperties(sc_arg["objectId"]?.Value()); + await CheckProps(sc_arg_props, new + { + X = TNumber(10), + Y = TNumber(45), + Id = TString("sc_arg#Id"), // <------- This changed + Color = TEnum("DebuggerTests.RGB", "Blue"), + PointWithCustomGetter = TGetter("PointWithCustomGetter") + }, "sc_arg_props#2"); + } + }); } [Fact] @@ -173,37 +173,37 @@ public async Task EvaluateExpressions() => await CheckInspectLocalsAtBreakpointS "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, "run", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d + e"); - CheckContentValue(evaluate, "203"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e + 10"); - CheckContentValue(evaluate, "112"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a + a"); - CheckContentValue(evaluate, "2"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a + this.b"); - CheckContentValue(evaluate, "3"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "\"test\" + \"test\""); - CheckContentValue(evaluate, "testtest"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "5 + 5"); - CheckContentValue(evaluate, "10"); - }); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "d + e"); + CheckContentValue(evaluate, "203"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "e + 10"); + CheckContentValue(evaluate, "112"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "a + a"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a + this.b"); + CheckContentValue(evaluate, "3"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "\"test\" + \"test\""); + CheckContentValue(evaluate, "testtest"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "5 + 5"); + CheckContentValue(evaluate, "10"); + }); [Fact] public async Task EvaluateThisExpressions() => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-evaluate-test.cs", 25, 16, "run", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EvaluateTestsClass:EvaluateLocals'); })", - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a"); - CheckContentValue(evaluate, "1"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.b"); - CheckContentValue(evaluate, "2"); - evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.c"); - CheckContentValue(evaluate, "3"); + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.a"); + CheckContentValue(evaluate, "1"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.b"); + CheckContentValue(evaluate, "2"); + evaluate = await EvaluateOnCallFrame(pause_location["callFrames"][0]["callFrameId"].Value(), "this.c"); + CheckContentValue(evaluate, "3"); // FIXME: not supported yet // evaluate = await EvaluateOnCallFrame (pause_location ["callFrames"][0] ["callFrameId"].Value (), "this.dt"); @@ -211,4 +211,4 @@ public async Task EvaluateThisExpressions() => await CheckInspectLocalsAtBreakpo }); } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs index 301c4227cf48..415956a6c2e3 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -24,7 +24,7 @@ public async Task ExceptionTestAll() string entry_method_name = "[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions"; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-exception-test.cs"; @@ -35,12 +35,12 @@ await insp.Ready(async(cli, token) => $"'{entry_method_name}'" + "); }, 1);"; - var pause_location = await EvaluateAndCheck(eval_expr, null, 0, 0, null); + var pause_location = await EvaluateAndCheck(eval_expr, null, 0, 0, null); //stop in the managed caught exception pause_location = await WaitForManagedException(pause_location); - AssertEqual("run", pause_location["callFrames"] ? [0] ? ["functionName"]?.Value(), "pause0"); - + AssertEqual("run", pause_location["callFrames"]?[0]?["functionName"]?.Value(), "pause0"); + await CheckValue(pause_location["data"], JObject.FromObject(new { type = "object", @@ -53,7 +53,7 @@ await CheckValue(pause_location["data"], JObject.FromObject(new CheckString(exception_members, "message", "not implemented caught"); pause_location = await WaitForManagedException(null); - AssertEqual("run", pause_location["callFrames"] ? [0] ? ["functionName"]?.Value(), "pause1"); + AssertEqual("run", pause_location["callFrames"]?[0]?["functionName"]?.Value(), "pause1"); //stop in the uncaught exception CheckLocation(debugger_test_loc, 28, 16, scripts, pause_location["callFrames"][0]["location"]); @@ -79,7 +79,7 @@ public async Task JSExceptionTestAll() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -127,7 +127,7 @@ public async Task ExceptionTestNone() string entry_method_name = "[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions"; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -146,9 +146,9 @@ await insp.Ready(async(cli, token) => var eo = JObject.Parse(ae.Message); // AssertEqual (line, eo ["exceptionDetails"]?["lineNumber"]?.Value (), "lineNumber"); - AssertEqual("Uncaught", eo["exceptionDetails"] ? ["text"]?.Value(), "text"); + AssertEqual("Uncaught", eo["exceptionDetails"]?["text"]?.Value(), "text"); - await CheckValue(eo["exceptionDetails"] ? ["exception"], JObject.FromObject(new + await CheckValue(eo["exceptionDetails"]?["exception"], JObject.FromObject(new { type = "object", subtype = "error", @@ -170,7 +170,7 @@ public async Task JSExceptionTestNone() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -188,10 +188,10 @@ await insp.Ready(async(cli, token) => Console.WriteLine($"{ae}"); var eo = JObject.Parse(ae.Message); - AssertEqual(line, eo["exceptionDetails"] ? ["lineNumber"]?.Value(), "lineNumber"); - AssertEqual("Uncaught", eo["exceptionDetails"] ? ["text"]?.Value(), "text"); + AssertEqual(line, eo["exceptionDetails"]?["lineNumber"]?.Value(), "lineNumber"); + AssertEqual("Uncaught", eo["exceptionDetails"]?["text"]?.Value(), "text"); - await CheckValue(eo["exceptionDetails"] ? ["exception"], JObject.FromObject(new + await CheckValue(eo["exceptionDetails"]?["exception"], JObject.FromObject(new { type = "object", subtype = "error", @@ -217,7 +217,7 @@ public async Task ExceptionTestUncaught(string eval_fn, string loc, int line, in //Collect events var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -246,16 +246,16 @@ async Task WaitForManagedException(JObject pause_location) { if (pause_location != null) { - AssertEqual("exception", pause_location ["reason"]?.Value (), $"Expected to only pause because of an exception. {pause_location}"); + AssertEqual("exception", pause_location["reason"]?.Value(), $"Expected to only pause because of an exception. {pause_location}"); // return in case of a managed exception, and ignore JS ones - if (pause_location["data"]?["objectId"]?.Value ()?.StartsWith("dotnet:object:") == true) + if (pause_location["data"]?["objectId"]?.Value()?.StartsWith("dotnet:object:") == true) { break; } } - pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); } return pause_location; diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs b/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs index d62bfc21f0aa..7a8e1c871680 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs @@ -13,7 +13,7 @@ namespace Microsoft.WebAssembly.Diagnostics { internal class InspectorClient : DevToolsClient { - List < (int, TaskCompletionSource) > pending_cmds = new List < (int, TaskCompletionSource) > (); + List<(int, TaskCompletionSource)> pending_cmds = new List<(int, TaskCompletionSource)>(); Func onEvent; int next_cmd_id; @@ -57,8 +57,8 @@ public Task SendCommand(string method, JObject args, CancellationToken t var o = JObject.FromObject(new { id = id, - method = method, - @params = args + method = method, + @params = args }); var tcs = new TaskCompletionSource(); @@ -78,4 +78,4 @@ protected virtual void DumpProtocol(string msg) //XXX make logging not stupid } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs index 2a62a67422c4..26b54066cd5f 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests @@ -27,354 +27,354 @@ public class PointerTests : DebuggerTestBase public async Task InspectLocalPointersToPrimitiveTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - ip = TPointer("int*"), - ip_null = TPointer("int*", is_null : true), - ipp = TPointer("int**"), - ipp_null = TPointer("int**"), - - cvalue0 = TSymbol("113 'q'"), - cp = TPointer("char*"), - - vp = TPointer("void*"), - vp_null = TPointer("void*", is_null : true), - }, "locals", num_fields : 26); - - var props = await GetObjectOnLocals(locals, "ip"); - await CheckPointerValue(props, "*ip", TNumber(5), "locals"); - - { - var ipp_props = await GetObjectOnLocals(locals, "ipp"); - await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); - - ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); - await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); - } - - { - var ipp_props = await GetObjectOnLocals(locals, "ipp_null"); - await CheckPointerValue(ipp_props, "*ipp_null", TPointer("int*", is_null : true)); - } + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ip = TPointer("int*"), + ip_null = TPointer("int*", is_null: true), + ipp = TPointer("int**"), + ipp_null = TPointer("int**"), + + cvalue0 = TSymbol("113 'q'"), + cp = TPointer("char*"), + + vp = TPointer("void*"), + vp_null = TPointer("void*", is_null: true), + }, "locals", num_fields: 26); + + var props = await GetObjectOnLocals(locals, "ip"); + await CheckPointerValue(props, "*ip", TNumber(5), "locals"); + + { + var ipp_props = await GetObjectOnLocals(locals, "ipp"); + await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); + + ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); + await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); + } + + { + var ipp_props = await GetObjectOnLocals(locals, "ipp_null"); + await CheckPointerValue(ipp_props, "*ipp_null", TPointer("int*", is_null: true)); + } // *cp props = await GetObjectOnLocals(locals, "cp"); - await CheckPointerValue(props, "*cp", TSymbol("113 'q'")); - }); + await CheckPointerValue(props, "*cp", TSymbol("113 'q'")); + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalPointerArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - ipa = TArray("int*[]", 3) - }, "locals", num_fields : 26); - - var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ipa = TArray("int*[]", 3) + }, "locals", num_fields: 26); + + var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new[] + { TPointer("int*"), TPointer("int*"), TPointer("int*", is_null : true) - }); + }); - await CheckArrayElements(ipa_elems, new [] - { + await CheckArrayElements(ipa_elems, new[] + { TNumber(5), TNumber(10), null - }); - }); + }); + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalDoublePointerToPrimitiveTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - ippa = TArray("int**[]", 5) - }, "locals", num_fields : 26); - - var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new [] - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ippa = TArray("int**[]", 5) + }, "locals", num_fields: 26); + + var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new[] + { TPointer("int**"), TPointer("int**"), TPointer("int**"), TPointer("int**"), TPointer("int**", is_null : true) - }); + }); - { - var actual_elems = await CheckArrayElements(ippa_elems, new [] - { + { + var actual_elems = await CheckArrayElements(ippa_elems, new[] + { TPointer("int*"), TPointer("int*", is_null : true), TPointer("int*"), TPointer("int*", is_null : true), null - }); + }); - var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); - await CheckPointerValue(val, "**[0]", TNumber(5)); + var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); + await CheckPointerValue(val, "**[0]", TNumber(5)); - val = await GetObjectOnLocals(actual_elems[2], "*[2]"); - await CheckPointerValue(val, "**[2]", TNumber(5)); - } - }); + val = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckPointerValue(val, "**[2]", TNumber(5)); + } + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalPointersToValueTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - dt = TValueType("System.DateTime", dt.ToString()), - dtp = TPointer("System.DateTime*"), - dtp_null = TPointer("System.DateTime*", is_null : true), + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dt = TValueType("System.DateTime", dt.ToString()), + dtp = TPointer("System.DateTime*"), + dtp_null = TPointer("System.DateTime*", is_null: true), - gsp = TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), - gsp_null = TPointer("DebuggerTests.GenericStructWithUnmanagedT*") - }, "locals", num_fields : 26); + gsp = TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), + gsp_null = TPointer("DebuggerTests.GenericStructWithUnmanagedT*") + }, "locals", num_fields: 26); - await CheckDateTime(locals, "dt", dt); + await CheckDateTime(locals, "dt", dt); // *dtp var props = await GetObjectOnLocals(locals, "dtp"); - await CheckDateTime(props, "*dtp", dt); - - var gsp_props = await GetObjectOnLocals(locals, "gsp"); - await CheckPointerValue(gsp_props, "*gsp", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); - - { - var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); - - var gsp_deref_props = await GetObjectOnLocals(gsp_props, "*gsp"); - await CheckProps(gsp_deref_props, new - { - Value = TValueType("System.DateTime", gs_dt.ToString()), - IntField = TNumber(4), - DTPP = TPointer("System.DateTime**") - }, "locals#gsp#deref"); - { - var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); - await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); - - var dtpp_deref_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); - await CheckDateTime(dtpp_deref_props, "**DTPP", dt); - } - } + await CheckDateTime(props, "*dtp", dt); + + var gsp_props = await GetObjectOnLocals(locals, "gsp"); + await CheckPointerValue(gsp_props, "*gsp", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); + + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + + var gsp_deref_props = await GetObjectOnLocals(gsp_props, "*gsp"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); + + var dtpp_deref_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); + await CheckDateTime(dtpp_deref_props, "**DTPP", dt); + } + } // gsp_null var gsp_w_n_props = await GetObjectOnLocals(locals, "gsp_null"); - await CheckPointerValue(gsp_w_n_props, "*gsp_null", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); - - { - var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); - - var gsp_deref_props = await GetObjectOnLocals(gsp_w_n_props, "*gsp_null"); - await CheckProps(gsp_deref_props, new - { - Value = TValueType("System.DateTime", gs_dt.ToString()), - IntField = TNumber(4), - DTPP = TPointer("System.DateTime**") - }, "locals#gsp#deref"); - { - var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); - await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null : true), "locals#*gsp"); - } - } - }); + await CheckPointerValue(gsp_w_n_props, "*gsp_null", TValueType("DebuggerTests.GenericStructWithUnmanagedT"), "locals#gsp"); + + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + + var gsp_deref_props = await GetObjectOnLocals(gsp_w_n_props, "*gsp_null"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null: true), "locals#*gsp"); + } + } + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalPointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - dtpa = TArray("System.DateTime*[]", 2) - }, "locals", num_fields : 26); + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtpa = TArray("System.DateTime*[]", 2) + }, "locals", num_fields: 26); // dtpa - var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new [] - { + var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new[] + { TPointer("System.DateTime*"), TPointer("System.DateTime*", is_null : true) - })); - { - var actual_elems = await CheckArrayElements(dtpa_elems, new [] - { + })); + { + var actual_elems = await CheckArrayElements(dtpa_elems, new[] + { TValueType("System.DateTime", dt.ToString()), null - }); + }); - await CheckDateTime(actual_elems[0], "*[0]", dt); - } - }); + await CheckDateTime(actual_elems[0], "*[0]", dt); + } + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalPointersToGenericValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT*[]", 3), - }, "locals", num_fields : 26); + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT*[]", 3), + }, "locals", num_fields: 26); // dtpa - var gspa_elems = await CompareObjectPropertiesFor(locals, "gspa", new [] - { + var gspa_elems = await CompareObjectPropertiesFor(locals, "gspa", new[] + { TPointer("DebuggerTests.GenericStructWithUnmanagedT*", is_null : true), TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), TPointer("DebuggerTests.GenericStructWithUnmanagedT*"), - }); - { - var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); - var actual_elems = await CheckArrayElements(gspa_elems, new [] - { + }); + { + var gs_dt = new DateTime(1, 2, 3, 4, 5, 6); + var actual_elems = await CheckArrayElements(gspa_elems, new[] + { null, TValueType("DebuggerTests.GenericStructWithUnmanagedT"), TValueType("DebuggerTests.GenericStructWithUnmanagedT") - }); + }); // *[1] { - var gsp_deref_props = await GetObjectOnLocals(actual_elems[1], "*[1]"); - await CheckProps(gsp_deref_props, new - { - Value = TValueType("System.DateTime", gs_dt.ToString()), - IntField = TNumber(4), - DTPP = TPointer("System.DateTime**") - }, "locals#gsp#deref"); - { - var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); - await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); - - dtpp_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); - await CheckDateTime(dtpp_props, "**DTPP", dt); - } - } + var gsp_deref_props = await GetObjectOnLocals(actual_elems[1], "*[1]"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp"); + + dtpp_props = await GetObjectOnLocals(dtpp_props, "*DTPP"); + await CheckDateTime(dtpp_props, "**DTPP", dt); + } + } // *[2] { - var gsp_deref_props = await GetObjectOnLocals(actual_elems[2], "*[2]"); - await CheckProps(gsp_deref_props, new - { - Value = TValueType("System.DateTime", gs_dt.ToString()), - IntField = TNumber(4), - DTPP = TPointer("System.DateTime**") - }, "locals#gsp#deref"); - { - var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); - await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null : true), "locals#*gsp"); - } - } - } - }); + var gsp_deref_props = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckProps(gsp_deref_props, new + { + Value = TValueType("System.DateTime", gs_dt.ToString()), + IntField = TNumber(4), + DTPP = TPointer("System.DateTime**") + }, "locals#gsp#deref"); + { + var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP"); + await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null: true), "locals#*gsp"); + } + } + } + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalDoublePointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - dtppa = TArray("System.DateTime**[]", 3), - }, "locals", num_fields : 26); + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtppa = TArray("System.DateTime**[]", 3), + }, "locals", num_fields: 26); // DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null }; - var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new [] - { + var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new[] + { TPointer("System.DateTime**"), TPointer("System.DateTime**"), TPointer("System.DateTime**", is_null : true) - })); + })); - var exp_elems = new [] - { + var exp_elems = new[] + { TPointer("System.DateTime*"), TPointer("System.DateTime*", is_null : true), null - }; - - var actual_elems = new JToken[exp_elems.Length]; - for (int i = 0; i < exp_elems.Length; i++) - { - if (exp_elems[i] != null) - { - actual_elems[i] = await GetObjectOnLocals(dtppa_elems, i.ToString()); - await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->"); - } - } - }); + }; + + var actual_elems = new JToken[exp_elems.Length]; + for (int i = 0; i < exp_elems.Length; i++) + { + if (exp_elems[i] != null) + { + actual_elems[i] = await GetObjectOnLocals(dtppa_elems, i.ToString()); + await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->"); + } + } + }); [Theory] [MemberDataAttribute(nameof(PointersTestData))] public async Task InspectLocalPointersInClasses(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - cwp = TObject("DebuggerTests.GenericClassWithPointers"), - cwp_null = TObject("DebuggerTests.GenericClassWithPointers") - }, "locals", num_fields : 26); - - var cwp_props = await GetObjectOnLocals(locals, "cwp"); - var ptr_props = await GetObjectOnLocals(cwp_props, "Ptr"); - await CheckDateTime(ptr_props, "*Ptr", dt); - }); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + cwp = TObject("DebuggerTests.GenericClassWithPointers"), + cwp_null = TObject("DebuggerTests.GenericClassWithPointers") + }, "locals", num_fields: 26); + + var cwp_props = await GetObjectOnLocals(locals, "cwp"); + var ptr_props = await GetObjectOnLocals(cwp_props, "Ptr"); + await CheckDateTime(ptr_props, "*Ptr", dt); + }); public static TheoryData PointersAsMethodArgsTestData => new TheoryData @@ -387,137 +387,137 @@ public async Task InspectLocalPointersInClasses(string eval_fn, string type, str public async Task InspectPrimitiveTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - ip = TPointer("int*"), - ipp = TPointer("int**"), - ipa = TArray("int*[]", 3), - ippa = TArray("int**[]", 5) - }, "locals", num_fields : 8); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + ip = TPointer("int*"), + ipp = TPointer("int**"), + ipa = TArray("int*[]", 3), + ippa = TArray("int**[]", 5) + }, "locals", num_fields: 8); // ip var props = await GetObjectOnLocals(locals, "ip"); - await CheckPointerValue(props, "*ip", TNumber(5), "locals"); + await CheckPointerValue(props, "*ip", TNumber(5), "locals"); // ipp var ipp_props = await GetObjectOnLocals(locals, "ipp"); - await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); + await CheckPointerValue(ipp_props, "*ipp", TPointer("int*")); - ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); - await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); + ipp_props = await GetObjectOnLocals(ipp_props, "*ipp"); + await CheckPointerValue(ipp_props, "**ipp", TNumber(5)); // ipa - var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new [] - { + var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new[] + { TPointer("int*"), TPointer("int*"), TPointer("int*", is_null : true) - }); + }); - await CheckArrayElements(ipa_elems, new [] - { + await CheckArrayElements(ipa_elems, new[] + { TNumber(5), TNumber(10), null - }); + }); // ippa - var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new [] - { + var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new[] + { TPointer("int**"), TPointer("int**"), TPointer("int**"), TPointer("int**"), TPointer("int**", is_null : true) - }); + }); - { - var actual_elems = await CheckArrayElements(ippa_elems, new [] - { + { + var actual_elems = await CheckArrayElements(ippa_elems, new[] + { TPointer("int*"), TPointer("int*", is_null : true), TPointer("int*"), TPointer("int*", is_null : true), null - }); + }); - var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); - await CheckPointerValue(val, "**[0]", TNumber(5)); + var val = await GetObjectOnLocals(actual_elems[0], "*[0]"); + await CheckPointerValue(val, "**[0]", TNumber(5)); - val = await GetObjectOnLocals(actual_elems[2], "*[2]"); - await CheckPointerValue(val, "**[2]", TNumber(5)); - } - }); + val = await GetObjectOnLocals(actual_elems[2], "*[2]"); + await CheckPointerValue(val, "**[2]", TNumber(5)); + } + }); [Theory] [MemberDataAttribute(nameof(PointersAsMethodArgsTestData))] public async Task InspectValueTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - var dt = new DateTime(5, 6, 7, 8, 9, 10); - await CheckProps(locals, new - { - dtp = TPointer("System.DateTime*"), - dtpp = TPointer("System.DateTime**"), - dtpa = TArray("System.DateTime*[]", 2), - dtppa = TArray("System.DateTime**[]", 3) - }, "locals", num_fields : 8); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var dt = new DateTime(5, 6, 7, 8, 9, 10); + await CheckProps(locals, new + { + dtp = TPointer("System.DateTime*"), + dtpp = TPointer("System.DateTime**"), + dtpa = TArray("System.DateTime*[]", 2), + dtppa = TArray("System.DateTime**[]", 3) + }, "locals", num_fields: 8); // *dtp var dtp_props = await GetObjectOnLocals(locals, "dtp"); - await CheckDateTime(dtp_props, "*dtp", dt); + await CheckDateTime(dtp_props, "*dtp", dt); // *dtpp var dtpp_props = await GetObjectOnLocals(locals, "dtpp"); - await CheckPointerValue(dtpp_props, "*dtpp", TPointer("System.DateTime*"), "locals"); + await CheckPointerValue(dtpp_props, "*dtpp", TPointer("System.DateTime*"), "locals"); - dtpp_props = await GetObjectOnLocals(dtpp_props, "*dtpp"); - await CheckDateTime(dtpp_props, "**dtpp", dt); + dtpp_props = await GetObjectOnLocals(dtpp_props, "*dtpp"); + await CheckDateTime(dtpp_props, "**dtpp", dt); // dtpa - var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new [] - { + var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new[] + { TPointer("System.DateTime*"), TPointer("System.DateTime*", is_null : true) - })); - { - var actual_elems = await CheckArrayElements(dtpa_elems, new [] - { + })); + { + var actual_elems = await CheckArrayElements(dtpa_elems, new[] + { TValueType("System.DateTime", dt.ToString()), null - }); + }); - await CheckDateTime(actual_elems[0], "*[0]", dt); - } + await CheckDateTime(actual_elems[0], "*[0]", dt); + } // dtppa = new DateTime**[] { &dtp, &dtp_null, null }; - var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new [] - { + var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new[] + { TPointer("System.DateTime**"), TPointer("System.DateTime**"), TPointer("System.DateTime**", is_null : true) - })); + })); - var exp_elems = new [] - { + var exp_elems = new[] + { TPointer("System.DateTime*"), TPointer("System.DateTime*", is_null : true), null - }; + }; - await CheckArrayElements(dtppa_elems, exp_elems); - }); + await CheckArrayElements(dtppa_elems, exp_elems); + }); [Theory] [InlineData("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", false)] @@ -525,20 +525,20 @@ public async Task InspectValueTypePointersAsMethodArgs(string eval_fn, string ty public async Task DerefNonPointerObject(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( type, method, line_offset, bp_function_name, "window.setTimeout(function() { " + eval_fn + " })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { // this will generate the object ids var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - var complex = GetAndAssertObjectWithName(locals, "complex"); + var complex = GetAndAssertObjectWithName(locals, "complex"); // try to deref the non-pointer object, as a pointer await GetProperties(complex["value"]["objectId"].Value().Replace(":object:", ":pointer:"), expect_ok: false); // try to deref an invalid pointer id await GetProperties("dotnet:pointer:123897", expect_ok: false); - }); + }); async Task CheckArrayElements(JToken array, JToken[] exp_elems) { @@ -555,4 +555,4 @@ async Task CheckArrayElements(JToken array, JToken[] exp_elems) return actual_elems; } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs index ac8570978353..67f9c5de77bb 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Support.cs @@ -10,9 +10,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.WebAssembly.Diagnostics; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Microsoft.WebAssembly.Diagnostics; using Xunit; namespace DebuggerTests @@ -66,7 +66,7 @@ async Task OnMessage(string method, JObject args, CancellationToken token) NotifyOf(READY, args); break; case "Runtime.consoleAPICalled": - Console.WriteLine("CWL: {0}", args?["args"] ? [0] ? ["value"]); + Console.WriteLine("CWL: {0}", args?["args"]?[0]?["value"]); break; } if (eventListeners.ContainsKey(method)) @@ -77,17 +77,17 @@ async Task OnMessage(string method, JObject args, CancellationToken token) public async Task Ready(Func cb = null, TimeSpan? span = null) { - using(var cts = new CancellationTokenSource()) + using (var cts = new CancellationTokenSource()) { cts.CancelAfter(span?.Milliseconds ?? 60 * 1000); //tests have 1 minute to complete by default var uri = new Uri($"ws://{TestHarnessProxy.Endpoint.Authority}/launch-chrome-and-connect"); using var loggerFactory = LoggerFactory.Create( builder => builder.AddConsole().AddFilter(null, LogLevel.Information)); - using(var client = new InspectorClient(loggerFactory.CreateLogger())) + using (var client = new InspectorClient(loggerFactory.CreateLogger())) { await client.Connect(uri, OnMessage, async token => { - Task[] init_cmds = { + Task[] init_cmds = { client.SendCommand("Profiler.enable", null, token), client.SendCommand("Runtime.enable", null, token), client.SendCommand("Debugger.enable", null, token), @@ -173,7 +173,7 @@ internal Dictionary SubscribeToScripts(Inspector insp) { dicScriptsIdToUrl = new Dictionary(); dicFileToUrl = new Dictionary(); - insp.On("Debugger.scriptParsed", async(args, c) => + insp.On("Debugger.scriptParsed", async (args, c) => { var script_id = args?["scriptId"]?.Value(); var url = args["url"]?.Value(); @@ -202,7 +202,7 @@ internal async Task CheckInspectLocalsAtBreakpointSite(string url_key, int line, var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -212,21 +212,21 @@ await insp.Ready(async(cli, token) => await EvaluateAndCheck( eval_expression, url_key, line, column, function_name, - wait_for_event_fn : async(pause_location) => - { + wait_for_event_fn: async (pause_location) => + { //make sure we're on the right bp - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); - var top_frame = pause_location["callFrames"][0]; + var top_frame = pause_location["callFrames"][0]; - var scope = top_frame["scopeChain"][0]; - Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); - if (wait_for_event_fn != null) - await wait_for_event_fn(pause_location); - else - await Task.CompletedTask; - }, + var scope = top_frame["scopeChain"][0]; + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + if (wait_for_event_fn != null) + await wait_for_event_fn(pause_location); + else + await Task.CompletedTask; + }, locals_fn: (locals) => { if (test_fn != null) @@ -245,7 +245,7 @@ internal async Task CheckInspectLocalsAtBreakpointSite(string type, string metho var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -256,16 +256,16 @@ await insp.Ready(async(cli, token) => var res = await ctx.cli.SendCommand("Runtime.evaluate", args, ctx.token); if (!res.IsOk) { - Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); - Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString()}\nresult: {res.Error.ToString()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString()}"); } var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE); if (bp_function_name != null) - Assert.Equal(bp_function_name, pause_location["callFrames"] ? [0] ? ["functionName"]?.Value()); + Assert.Equal(bp_function_name, pause_location["callFrames"]?[0]?["functionName"]?.Value()); - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); var top_frame = pause_location["callFrames"][0]; @@ -286,8 +286,8 @@ await insp.Ready(async(cli, token) => internal void CheckLocation(string script_loc, int line, int column, Dictionary scripts, JToken location) { var loc_str = $"{ scripts[location["scriptId"].Value()] }" + - $"#{ location ["lineNumber"].Value () }" + - $"#{ location ["columnNumber"].Value () }"; + $"#{ location["lineNumber"].Value() }" + + $"#{ location["columnNumber"].Value() }"; var expected_loc_str = $"{script_loc}#{line}#{column}"; Assert.Equal(expected_loc_str, loc_str); @@ -415,8 +415,8 @@ internal async Task SendCommand(string method, JObject args) var res = await ctx.cli.SendCommand(method, args, ctx.token); if (!res.IsOk) { - Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); - Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString()}\nresult: {res.Error.ToString()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString()}"); } return res; } @@ -428,7 +428,7 @@ internal async Task Evaluate(string expression) internal void AssertLocation(JObject args, string methodName) { - Assert.Equal(methodName, args["callFrames"] ? [0] ? ["functionName"]?.Value()); + Assert.Equal(methodName, args["callFrames"]?[0]?["functionName"]?.Value()); } // Place a breakpoint in the given method and run until its hit @@ -448,8 +448,8 @@ internal async Task InvokeGetter(JToken obj, object arguments, string fn var req = JObject.FromObject(new { functionDeclaration = fn, - objectId = obj["value"]?["objectId"]?.Value(), - arguments = new[] { new { value = arguments } } + objectId = obj["value"]?["objectId"]?.Value(), + arguments = new[] { new { value = arguments } } }); if (returnByValue != null) req["returnByValue"] = returnByValue.Value; @@ -465,22 +465,22 @@ internal async Task StepAndCheck(StepKind kind, string script_loc, int { for (int i = 0; i < times - 1; i++) { - await SendCommandAndCheck(null, $"Debugger.step{kind.ToString ()}", null, -1, -1, null); + await SendCommandAndCheck(null, $"Debugger.step{kind.ToString()}", null, -1, -1, null); } // Check for method/line etc only at the last step return await SendCommandAndCheck( - null, $"Debugger.step{kind.ToString ()}", script_loc, line, column, function_name, - wait_for_event_fn : wait_for_event_fn, - locals_fn : locals_fn); + null, $"Debugger.step{kind.ToString()}", script_loc, line, column, function_name, + wait_for_event_fn: wait_for_event_fn, + locals_fn: locals_fn); } internal async Task EvaluateAndCheck(string expression, string script_loc, int line, int column, string function_name, Func wait_for_event_fn = null, Action locals_fn = null) => await SendCommandAndCheck( JObject.FromObject(new { expression = expression }), "Runtime.evaluate", script_loc, line, column, function_name, - wait_for_event_fn : wait_for_event_fn, - locals_fn : locals_fn); + wait_for_event_fn: wait_for_event_fn, + locals_fn: locals_fn); internal async Task SendCommandAndCheck(JObject args, string method, string script_loc, int line, int column, string function_name, Func wait_for_event_fn = null, Action locals_fn = null, string waitForEvent = Inspector.PAUSE) @@ -488,14 +488,14 @@ internal async Task SendCommandAndCheck(JObject args, string method, st var res = await ctx.cli.SendCommand(method, args, ctx.token); if (!res.IsOk) { - Console.WriteLine($"Failed to run command {method} with args: {args?.ToString ()}\nresult: {res.Error.ToString ()}"); - Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString ()}"); + Console.WriteLine($"Failed to run command {method} with args: {args?.ToString()}\nresult: {res.Error.ToString()}"); + Assert.True(false, $"SendCommand for {method} failed with {res.Error.ToString()}"); } var wait_res = await ctx.insp.WaitFor(waitForEvent); if (function_name != null) - Assert.Equal(function_name, wait_res["callFrames"] ? [0] ? ["functionName"]?.Value()); + Assert.Equal(function_name, wait_res["callFrames"]?[0]?["functionName"]?.Value()); if (script_loc != null) CheckLocation(script_loc, line, column, ctx.scripts, wait_res["callFrames"][0]["location"]); @@ -537,8 +537,8 @@ internal async Task CheckDelegate(JToken actual_val, JToken exp_val, string labe var obj = del_props.Where(jt => jt["name"]?.Value() == "Target").FirstOrDefault(); Assert.True(obj != null, $"[{label}] Property named 'Target' found found in delegate properties"); - AssertEqual("symbol", obj["value"] ? ["type"]?.Value(), $"{label}#Target#type"); - CheckDelegateTarget(obj["value"] ? ["value"]?.Value(), exp_target); + AssertEqual("symbol", obj["value"]?["type"]?.Value(), $"{label}#Target#type"); + CheckDelegateTarget(obj["value"]?["value"]?.Value(), exp_target); return; @@ -578,7 +578,7 @@ internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string la { AssertEqual("symbol", actual_val["type"]?.Value(), $"{label}-type"); - var exp_val_str = $"({exp_val ["type_name"]?.Value()}) 0"; + var exp_val_str = $"({exp_val["type_name"]?.Value()}) 0"; AssertEqual(exp_val_str, actual_val["value"]?.Value(), $"{label}-value"); AssertEqual(exp_val_str, actual_val["description"]?.Value(), $"{label}-description"); } @@ -586,7 +586,7 @@ internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string la { AssertEqual("symbol", actual_val["type"]?.Value(), $"{label}-type"); - var exp_val_str = $"({exp_val ["type_name"]?.Value()})"; + var exp_val_str = $"({exp_val["type_name"]?.Value()})"; AssertStartsWith(exp_val_str, actual_val["value"]?.Value(), $"{label}-value"); AssertStartsWith(exp_val_str, actual_val["description"]?.Value(), $"{label}-description"); } @@ -594,7 +594,7 @@ internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string la { AssertEqual("object", actual_val["type"]?.Value(), $"{label}-type"); - var exp_prefix = $"({exp_val ["type_name"]?.Value()})"; + var exp_prefix = $"({exp_val["type_name"]?.Value()})"; AssertStartsWith(exp_prefix, actual_val["className"]?.Value(), $"{label}-className"); AssertStartsWith(exp_prefix, actual_val["description"]?.Value(), $"{label}-description"); Assert.False(actual_val["className"]?.Value() == $"{exp_prefix} 0", $"[{label}] Expected a non-null value, but got {actual_val}"); @@ -607,10 +607,10 @@ internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string la // For getter, `actual_val` is not `.value`, instead it's the container object // which has a `.get` instead of a `.value` var get = actual_val["get"]; - Assert.True(get != null, $"[{label}] No `get` found. {(actual_val != null ? "Make sure to pass the container object for testing getters, and not the ['value']": String.Empty)}"); + Assert.True(get != null, $"[{label}] No `get` found. {(actual_val != null ? "Make sure to pass the container object for testing getters, and not the ['value']" : String.Empty)}"); AssertEqual("Function", get["className"]?.Value(), $"{label}-className"); - AssertStartsWith($"get {exp_val ["type_name"]?.Value ()} ()", get["description"]?.Value(), $"{label}-description"); + AssertStartsWith($"get {exp_val["type_name"]?.Value()} ()", get["description"]?.Value(), $"{label}-description"); AssertEqual("function", get["type"]?.Value(), $"{label}-type"); break; @@ -727,8 +727,8 @@ internal async Task CheckValue(JToken actual_val, JToken exp_val, string label) Assert.True(exp_val_str == actual_field_val_str, $"[{label}] Value for json property named {jp.Name} didn't match.\n" + - $"Expected: {jp.Value.Value ()}\n" + - $"Actual: {actual_field_val.Value.Value ()}"); + $"Expected: {jp.Value.Value()}\n" + + $"Actual: {actual_field_val.Value.Value()}"); } } @@ -782,16 +782,16 @@ internal async Task GetProperties(string id, JToken fn_args = null, bool var cfo_args = JObject.FromObject(new { functionDeclaration = fn_decl, - objectId = id + objectId = id }); if (fn_args != null) cfo_args["arguments"] = fn_args; var result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token); - AssertEqual(expect_ok, result.IsOk, $"Runtime.getProperties returned {result.IsOk} instead of {expect_ok}, for {cfo_args.ToString ()}, with Result: {result}"); + AssertEqual(expect_ok, result.IsOk, $"Runtime.getProperties returned {result.IsOk} instead of {expect_ok}, for {cfo_args.ToString()}, with Result: {result}"); if (!result.IsOk) return null; - id = result.Value["result"] ? ["objectId"]?.Value(); + id = result.Value["result"]?["objectId"]?.Value(); } var get_prop_req = JObject.FromObject(new @@ -827,12 +827,12 @@ internal async Task EvaluateOnCallFrame(string id, string expression) var evaluate_req = JObject.FromObject(new { callFrameId = id, - expression = expression + expression = expression }); var frame_evaluate = await ctx.cli.SendCommand("Debugger.evaluateOnCallFrame", evaluate_req, ctx.token); if (!frame_evaluate.IsOk) - Assert.True(false, $"Debugger.evaluateOnCallFrame failed for {evaluate_req.ToString ()}, with Result: {frame_evaluate}"); + Assert.True(false, $"Debugger.evaluateOnCallFrame failed for {evaluate_req.ToString()}, with Result: {frame_evaluate}"); var evaluate_result = frame_evaluate.Value["result"]; return evaluate_result; @@ -870,8 +870,8 @@ internal async Task SetBreakpointInMethod(string assembly, string type, var bp1_req = JObject.FromObject(new { lineNumber = m_line + lineOffset, - columnNumber = col, - url = m_url + columnNumber = col, + url = m_url }); res = await ctx.cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, ctx.token); @@ -907,7 +907,7 @@ internal void AssertEqual(object expected, object actual, string label) => Asser //FIXME: um maybe we don't need to convert jobject right here! internal static JObject TString(string value) => value == null ? - TObject("string", is_null : true) : + TObject("string", is_null: true) : JObject.FromObject(new { type = "string", value = @value }); internal static JObject TNumber(int value) => @@ -942,8 +942,8 @@ For target names with generated method names like internal static JObject TDelegate(string className, string target) => JObject.FromObject(new { __custom_type = "delegate", - className = className, - target = target + className = className, + target = target }); internal static JObject TPointer(string type_name, bool is_null = false) => JObject.FromObject(new { __custom_type = "pointer", type_name = type_name, is_null = is_null, is_void = type_name.StartsWith("void*") }); @@ -1036,4 +1036,4 @@ enum StepKind Over, Out } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 5ba31d8c3701..75bedf72aead 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -4,11 +4,11 @@ using System; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; using Xunit; -[assembly : CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] +[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] namespace DebuggerTests { @@ -40,7 +40,7 @@ public async Task CreateGoodBreakpoint() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -49,7 +49,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-test.cs", bp1_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); - var loc = bp1_res.Value["locations"]?.Value() [0]; + var loc = bp1_res.Value["locations"]?.Value()[0]; Assert.NotNull(loc["scriptId"]); Assert.Equal("dotnet://debugger-test.dll/debugger-test.cs", scripts[loc["scriptId"]?.Value()]); @@ -68,7 +68,7 @@ public async Task CreateJSBreakpoint() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); // 13 24 @@ -78,7 +78,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); - var loc = bp1_res.Value["locations"]?.Value() [0]; + var loc = bp1_res.Value["locations"]?.Value()[0]; Assert.NotNull(loc["scriptId"]); Assert.Equal(13, loc["lineNumber"]); @@ -89,7 +89,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); - var loc2 = bp2_res.Value["locations"]?.Value() [0]; + var loc2 = bp2_res.Value["locations"]?.Value()[0]; Assert.NotNull(loc2["scriptId"]); Assert.Equal(13, loc2["lineNumber"]); @@ -107,7 +107,7 @@ public async Task CreateJS0Breakpoint() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); // 13 24 @@ -117,7 +117,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); - var loc = bp1_res.Value["locations"]?.Value() [0]; + var loc = bp1_res.Value["locations"]?.Value()[0]; Assert.NotNull(loc["scriptId"]); Assert.Equal(13, loc["lineNumber"]); @@ -128,7 +128,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); - var loc2 = bp2_res.Value["locations"]?.Value() [0]; + var loc2 = bp2_res.Value["locations"]?.Value()[0]; Assert.NotNull(loc2["scriptId"]); Assert.Equal(13, loc2["lineNumber"]); @@ -146,7 +146,7 @@ public async Task CheckMultipleBreakpointsOnSameLine(int col) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -154,7 +154,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-array-test.cs", bp1_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); - var loc = bp1_res.Value["locations"]?.Value() [0]; + var loc = bp1_res.Value["locations"]?.Value()[0]; CheckLocation("dotnet://debugger-test.dll/debugger-array-test.cs", 219, 50, scripts, loc); @@ -162,7 +162,7 @@ await insp.Ready(async(cli, token) => Assert.EndsWith("debugger-array-test.cs", bp2_res.Value["breakpointId"].ToString()); Assert.Equal(1, bp2_res.Value["locations"]?.Value()?.Count); - var loc2 = bp2_res.Value["locations"]?.Value() [0]; + var loc2 = bp2_res.Value["locations"]?.Value()[0]; CheckLocation("dotnet://debugger-test.dll/debugger-array-test.cs", 219, 55, scripts, loc2); }); @@ -177,13 +177,13 @@ public async Task CreateBadBreakpoint() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { var bp1_req = JObject.FromObject(new { lineNumber = 8, - columnNumber = 2, - url = "dotnet://debugger-test.dll/this-file-doesnt-exist.cs", + columnNumber = 2, + url = "dotnet://debugger-test.dll/this-file-doesnt-exist.cs", }); var bp1_res = await cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, token); @@ -203,7 +203,7 @@ public async Task CreateGoodBreakpointAndHit() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -221,7 +221,7 @@ await EvaluateAndCheck( wait_for_event_fn: (pause_location) => { Assert.Equal("other", pause_location["reason"]?.Value()); - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); var top_frame = pause_location["callFrames"][0]; Assert.Equal("IntAdd", top_frame["functionName"].Value()); @@ -254,7 +254,7 @@ public async Task ExceptionThrownInJS() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { var eval_req = JObject.FromObject(new { @@ -263,7 +263,7 @@ await insp.Ready(async(cli, token) => var eval_res = await cli.SendCommand("Runtime.evaluate", eval_req, token); Assert.True(eval_res.IsErr); - Assert.Equal("Uncaught", eval_res.Error["exceptionDetails"] ? ["text"]?.Value()); + Assert.Equal("Uncaught", eval_res.Error["exceptionDetails"]?["text"]?.Value()); }); } @@ -276,7 +276,7 @@ public async Task ExceptionThrownInJSOutOfBand() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -291,9 +291,9 @@ await insp.Ready(async(cli, token) => // Response here will be the id for the timer from JS! Assert.True(eval_res.IsOk); - var ex = await Assert.ThrowsAsync(async() => await insp.WaitFor("Runtime.exceptionThrown")); + var ex = await Assert.ThrowsAsync(async () => await insp.WaitFor("Runtime.exceptionThrown")); var ex_json = JObject.Parse(ex.Message); - Assert.Equal(dicFileToUrl["/debugger-driver.html"], ex_json["exceptionDetails"] ? ["url"]?.Value()); + Assert.Equal(dicFileToUrl["/debugger-driver.html"], ex_json["exceptionDetails"]?["url"]?.Value()); }); } @@ -305,7 +305,7 @@ public async Task InspectLocalsAtBreakpointSite(bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd", "window.setTimeout(function() { invoke_add(); }, 1);", - use_cfo : use_cfo, + use_cfo: use_cfo, test_fn: (locals) => { CheckNumber(locals, "a", 10); @@ -333,17 +333,17 @@ public async Task InspectLocalsTypesAtBreakpointSite() => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test2.cs", 48, 8, "Types", "window.setTimeout(function() { invoke_static_method (\"[debugger-test] Fancy:Types\")(); }, 1);", - use_cfo : false, + use_cfo: false, test_fn: (locals) => { CheckNumber(locals, "dPI", Math.PI); - CheckNumber(locals, "fPI", (float) Math.PI); + CheckNumber(locals, "fPI", (float)Math.PI); CheckNumber(locals, "iMax", int.MaxValue); CheckNumber(locals, "iMin", int.MinValue); CheckNumber(locals, "uiMax", uint.MaxValue); CheckNumber(locals, "uiMin", uint.MinValue); - CheckNumber(locals, "l", uint.MaxValue * (long) 2); + CheckNumber(locals, "l", uint.MaxValue * (long)2); //CheckNumber (locals, "lMax", long.MaxValue); // cannot be represented as double //CheckNumber (locals, "lMin", long.MinValue); // cannot be represented as double @@ -366,21 +366,21 @@ public async Task InspectLocalsWithGenericTypesAtBreakpointSite(bool use_cfo) => await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test.cs", 74, 8, "GenericTypesTest", "window.setTimeout(function() { invoke_generic_types_test (); }, 1);", - use_cfo : use_cfo, + use_cfo: use_cfo, test_fn: (locals) => { CheckObject(locals, "list", "System.Collections.Generic.Dictionary"); - CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null : true); + CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null: true); CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]", 1); - CheckObject(locals, "list_arr_null", "System.Collections.Generic.Dictionary[]", is_null : true); + CheckObject(locals, "list_arr_null", "System.Collections.Generic.Dictionary[]", is_null: true); // Unused locals CheckObject(locals, "list_unused", "System.Collections.Generic.Dictionary"); - CheckObject(locals, "list_null_unused", "System.Collections.Generic.Dictionary", is_null : true); + CheckObject(locals, "list_null_unused", "System.Collections.Generic.Dictionary", is_null: true); CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]", 1); - CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null : true); + CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null: true); } ); @@ -398,7 +398,7 @@ public async Task RuntimeGetPropertiesWithInvalidScopeIdTest() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -408,25 +408,25 @@ await EvaluateAndCheck( "window.setTimeout(function() { invoke_delegates_test (); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 49, 8, "DelegatesTest", - wait_for_event_fn : async(pause_location) => - { + wait_for_event_fn: async (pause_location) => + { //make sure we're on the right bp - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); - var top_frame = pause_location["callFrames"][0]; + var top_frame = pause_location["callFrames"][0]; - var scope = top_frame["scopeChain"][0]; - Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); + var scope = top_frame["scopeChain"][0]; + Assert.Equal("dotnet:scope:0", scope["object"]["objectId"]); // Try to get an invalid scope! var get_prop_req = JObject.FromObject(new - { - objectId = "dotnet:scope:23490871", - }); + { + objectId = "dotnet:scope:23490871", + }); - var frame_props = await cli.SendCommand("Runtime.getProperties", get_prop_req, token); - Assert.True(frame_props.IsErr); - } + var frame_props = await cli.SendCommand("Runtime.getProperties", get_prop_req, token); + Assert.True(frame_props.IsErr); + } ); }); } @@ -439,7 +439,7 @@ public async Task TrivalStepping() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -452,7 +452,7 @@ await EvaluateAndCheck( wait_for_event_fn: (pause_location) => { //make sure we're on the right bp - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); var top_frame = pause_location["callFrames"][0]; CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); @@ -479,7 +479,7 @@ public async Task InspectLocalsDuringStepping() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -534,7 +534,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -579,7 +579,7 @@ await insp.Ready(async(cli, token) => CheckString(props, "B", "xx"); CheckObject(props, "c", "object"); - pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 23, 8, "DoStuff", times : 2); + pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 23, 8, "DoStuff", times: 2); // Check UseComplex frame again locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][1], debugger_test_loc, 23, 8, "UseComplex"); Assert.Equal(7, locals_m1.Count()); @@ -610,7 +610,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -639,7 +639,8 @@ await insp.Ready(async(cli, token) => var ss_props = await GetObjectOnLocals(this_props, "SimpleStructProperty"); var dt = new DateTime(2020, 1, 2, 3, 4, 5); - await CheckProps(ss_props, new { + await CheckProps(ss_props, new + { dt = TValueType("System.DateTime", dt.ToString()), gs = TValueType("Math.GenericStruct") }, "ss_props"); @@ -656,7 +657,7 @@ await insp.Ready(async(cli, token) => CheckObject(locals_m1, "nim", "Math.NestedInMath"); // step back into OuterMethod - await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times : 9, + await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times: 9, locals_fn: (locals) => { Assert.Equal(5, locals.Count()); @@ -683,7 +684,7 @@ await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", } ); - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times : 4, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times: 4, locals_fn: (locals) => { Assert.Equal(3, locals.Count()); @@ -694,7 +695,7 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", } ); - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times : 2, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times: 2, locals_fn: (locals) => { Assert.Equal(5, locals.Count()); @@ -717,7 +718,7 @@ public async Task InspectLocalsDuringSteppingIn() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -752,7 +753,7 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", // Step into InnerMethod await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 105, 8, "InnerMethod"); - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 109, 12, "InnerMethod", times : 5, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 109, 12, "InnerMethod", times: 5, locals_fn: (locals) => { Assert.Equal(4, locals.Count()); @@ -765,7 +766,7 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", ); // Step back to OuterMethod - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 88, 8, "OuterMethod", times : 6, + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 88, 8, "OuterMethod", times: 6, locals_fn: (locals) => { Assert.Equal(5, locals.Count()); @@ -790,7 +791,7 @@ public async Task InspectLocalsInAsyncMethods(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -855,7 +856,7 @@ public async Task InspectLocalsWithStructs(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -889,11 +890,11 @@ await insp.Ready(async(cli, token) => var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); await CheckProps(ss_local_props, new { - V = TGetter("V"), + V = TGetter("V"), str_member = TString("set in MethodWithLocalStructs#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Utc") + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") }, "ss_local"); { @@ -913,8 +914,8 @@ await insp.Ready(async(cli, token) => await CheckProps(gs_local_props, new { StringField = TString("gs_local#GenericStruct#StringField"), - List = TObject("System.Collections.Generic.List", is_null : true), - Options = TEnum("DebuggerTests.Options", "None") + List = TObject("System.Collections.Generic.List", is_null: true), + Options = TEnum("DebuggerTests.Options", "None") }, "gs_local"); // Check vt_local's properties @@ -931,17 +932,17 @@ await insp.Ready(async(cli, token) => var ssp_props = await CompareObjectPropertiesFor(vt_local_props, name, new { - V = TGetter("V"), + V = TGetter("V"), str_member = TString($"{name}#string#0#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", dt_kind) + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", dt_kind) }, label: $"vt_local_props.{name}"); await CheckDateTime(ssp_props, "dt", dt); var gres = await InvokeGetter(GetAndAssertObjectWithName(vt_local_props, name), "V"); - await CheckValue(gres.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), $"{name}#V"); + await CheckValue(gres.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), $"{name}#V"); } // FIXME: check ss_local.gs.List's members @@ -958,7 +959,7 @@ public async Task InspectValueTypeMethodArgs(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -998,7 +999,7 @@ await insp.Ready(async(cli, token) => await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_arg"); var res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V"); - await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), "ss_arg#V"); + await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V"); { // Check ss_local.dt @@ -1008,7 +1009,7 @@ await insp.Ready(async(cli, token) => await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs); } - pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 38, 8, "MethodWithStructArgs", times : 4, + pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 38, 8, "MethodWithStructArgs", times: 4, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); { @@ -1032,15 +1033,15 @@ await insp.Ready(async(cli, token) => await CheckProps(ss_arg_props, ss_arg_updated, "ss_arg"); res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V"); - await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint) dt.Month), "ss_arg#V"); + await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V"); { // Check ss_local.gs await CompareObjectPropertiesFor(ss_arg_props, "gs", new { StringField = TString("ValueTypesTest#MethodWithStructArgs#updated#gs#StringField#3"), - List = TObject("System.Collections.Generic.List"), - Options = TEnum("DebuggerTests.Options", "Option1") + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option1") }); await CheckDateTime(ss_arg_props, "dt", dt); @@ -1063,13 +1064,13 @@ await insp.Ready(async(cli, token) => // ----------- Step back to the caller --------- pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 28, 12, "TestStructsAsMethodArgs", - times : 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); + times: 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new - { - ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"), - ss_ret = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct") - }, + { + ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"), + ss_ret = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct") + }, "locals#0"); ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); @@ -1092,12 +1093,12 @@ public async Task CheckUpdatedValueTypeFieldsOnResume() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 203, 206 }; + var lines = new[] { 203, 206 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1118,7 +1119,7 @@ async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt) await CheckProps(locals, new { obj = TObject("DebuggerTests.ClassForToStringTests"), - vt = TObject("DebuggerTests.StructForToStringTests") + vt = TObject("DebuggerTests.StructForToStringTests") }, "locals"); var obj_props = await GetObjectOnLocals(locals, "obj"); @@ -1126,7 +1127,7 @@ async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt) await CheckProps(obj_props, new { DT = TValueType("System.DateTime", obj_dt.ToString()) - }, "locals#obj.DT", num_fields : 5); + }, "locals#obj.DT", num_fields: 5); await CheckDateTime(obj_props, "DT", obj_dt); } @@ -1136,7 +1137,7 @@ async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt) await CheckProps(vt_props, new { DT = TValueType("System.DateTime", vt_dt.ToString()) - }, "locals#obj.DT", num_fields : 5); + }, "locals#obj.DT", num_fields: 5); await CheckDateTime(vt_props, "DT", vt_dt); } @@ -1151,12 +1152,12 @@ public async Task CheckUpdatedValueTypeLocalsOnResumeAsync() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 212, 214 }; + var lines = new[] { 212, 214 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1184,12 +1185,12 @@ public async Task CheckUpdatedVTArrayMembersOnResume() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; - var lines = new [] { 223, 225 }; + var lines = new[] { 223, 225 }; await SetBreakpoint(debugger_test_loc, lines[0], 12); await SetBreakpoint(debugger_test_loc, lines[1], 12); @@ -1218,7 +1219,7 @@ async Task CheckArrayElements(JToken pause_location, DateTime dt) await CheckProps(sst0, new { DT = TValueType("System.DateTime", dt.ToString()) - }, "dta [0]", num_fields : 5); + }, "dta [0]", num_fields: 5); await CheckDateTime(sst0, "DT", dt); } @@ -1234,7 +1235,7 @@ public async Task InspectLocalsWithStructsStaticAsync(bool use_cfo) var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); ctx.UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -1250,11 +1251,11 @@ await insp.Ready(async(cli, token) => var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new - { - ss_local = TObject("DebuggerTests.ValueTypesTest.SimpleStruct"), - gs_local = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - result = TBool(true) - }, + { + ss_local = TObject("DebuggerTests.ValueTypesTest.SimpleStruct"), + gs_local = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + result = TBool(true) + }, "locals#0"); var dt = new DateTime(2021, 2, 3, 4, 6, 7); @@ -1262,11 +1263,11 @@ await insp.Ready(async(cli, token) => var ss_local_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local"); await CheckProps(ss_local_props, new { - V = TGetter("V"), + V = TGetter("V"), str_member = TString("set in MethodWithLocalStructsStaticAsync#SimpleStruct#str_member"), - dt = TValueType("System.DateTime", dt.ToString()), - gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), - Kind = TEnum("System.DateTimeKind", "Utc") + dt = TValueType("System.DateTime", dt.ToString()), + gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct"), + Kind = TEnum("System.DateTimeKind", "Utc") }, "ss_local"); { @@ -1281,8 +1282,8 @@ await CompareObjectPropertiesFor(ss_local_props, "gs", new { StringField = TString("set in MethodWithLocalStructsStaticAsync#SimpleStruct#gs#StringField"), - List = TObject("System.Collections.Generic.List"), - Options = TEnum("DebuggerTests.Options", "Option1") + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option1") } ); } @@ -1292,8 +1293,8 @@ await CompareObjectPropertiesFor(ss_local_props, "gs", await CheckProps(gs_local_props, new { StringField = TString("gs_local#GenericStruct#StringField"), - List = TObject("System.Collections.Generic.List"), - Options = TEnum("DebuggerTests.Options", "Option2") + List = TObject("System.Collections.Generic.List"), + Options = TEnum("DebuggerTests.Options", "Option2") }, "gs_local"); // FIXME: check ss_local.gs.List's members @@ -1314,7 +1315,7 @@ public async Task InspectLocalsForToStringDescriptions(int line, int col, string int frame_idx = 0; await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs"; @@ -1339,15 +1340,15 @@ await insp.Ready(async(cli, token) => await CheckProps(frame_locals, new { call_other = TBool(call_other), - dt0 = TValueType("System.DateTime", dt0.ToString()), - dt1 = TValueType("System.DateTime", dt1.ToString()), - dto = TValueType("System.DateTimeOffset", dto.ToString()), - ts = TValueType("System.TimeSpan", ts.ToString()), - dec = TValueType("System.Decimal", "123987123"), - guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014"), - dts = TArray("System.DateTime[]", 2), - obj = TObject("DebuggerTests.ClassForToStringTests"), - sst = TObject("DebuggerTests.StructForToStringTests") + dt0 = TValueType("System.DateTime", dt0.ToString()), + dt1 = TValueType("System.DateTime", dt1.ToString()), + dto = TValueType("System.DateTimeOffset", dto.ToString()), + ts = TValueType("System.TimeSpan", ts.ToString()), + dec = TValueType("System.Decimal", "123987123"), + guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014"), + dts = TArray("System.DateTime[]", 2), + obj = TObject("DebuggerTests.ClassForToStringTests"), + sst = TObject("DebuggerTests.StructForToStringTests") }, "locals#0"); var dts_0 = new DateTime(1983, 6, 7, 5, 6, 10); @@ -1361,18 +1362,18 @@ await CompareObjectPropertiesFor(frame_locals, "ts", new { Days = TNumber(3530), - Minutes = TNumber(2), - Seconds = TNumber(4), - }, "ts_props", num_fields : 12); + Minutes = TNumber(2), + Seconds = TNumber(4), + }, "ts_props", num_fields: 12); // DateTimeOffset await CompareObjectPropertiesFor(frame_locals, "dto", new { Day = TNumber(2), - Year = TNumber(2020), - DayOfWeek = TEnum("System.DayOfWeek", "Thursday") - }, "dto_props", num_fields : 22); + Year = TNumber(2020), + DayOfWeek = TEnum("System.DayOfWeek", "Thursday") + }, "dto_props", num_fields: 22); var DT = new DateTime(2004, 10, 15, 1, 2, 3); var DTO = new DateTimeOffset(dt0, new TimeSpan(2, 14, 0)); @@ -1381,10 +1382,10 @@ await CompareObjectPropertiesFor(frame_locals, "dto", new { DT = TValueType("System.DateTime", DT.ToString()), - DTO = TValueType("System.DateTimeOffset", DTO.ToString()), - TS = TValueType("System.TimeSpan", ts.ToString()), - Dec = TValueType("System.Decimal", "1239871"), - Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") + DTO = TValueType("System.DateTimeOffset", DTO.ToString()), + TS = TValueType("System.TimeSpan", ts.ToString()), + Dec = TValueType("System.Decimal", "1239871"), + Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") }, "obj_props"); DTO = new DateTimeOffset(dt0, new TimeSpan(3, 15, 0)); @@ -1392,10 +1393,10 @@ await CompareObjectPropertiesFor(frame_locals, "dto", new { DT = TValueType("System.DateTime", DT.ToString()), - DTO = TValueType("System.DateTimeOffset", DTO.ToString()), - TS = TValueType("System.TimeSpan", ts.ToString()), - Dec = TValueType("System.Decimal", "1239871"), - Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") + DTO = TValueType("System.DateTimeOffset", DTO.ToString()), + TS = TValueType("System.TimeSpan", ts.ToString()), + Dec = TValueType("System.Decimal", "1239871"), + Guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014") }, "sst_props"); }); } @@ -1407,7 +1408,7 @@ public async Task InspectLocals() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -1423,37 +1424,37 @@ public async Task InspectLocalsForStructInstanceMethod(bool use_cfo) => await Ch "dotnet://debugger-test.dll/debugger-array-test.cs", 258, 12, "GenericInstanceMethod", "window.setTimeout(function() { invoke_static_method_async ('[debugger-test] DebuggerTests.EntryClass:run'); })", - use_cfo : use_cfo, - wait_for_event_fn : async(pause_location) => - { - var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); - - await CheckProps(frame_locals, new - { - sc_arg = TObject("DebuggerTests.SimpleClass"), - @this = TValueType("DebuggerTests.Point"), - local_gs = TValueType("DebuggerTests.SimpleGenericStruct") - }, - "locals#0"); - - await CompareObjectPropertiesFor(frame_locals, "local_gs", - new - { - Id = TString("local_gs#Id"), - Color = TEnum("DebuggerTests.RGB", "Green"), - Value = TNumber(4) - }, - label: "local_gs#0"); - - await CompareObjectPropertiesFor(frame_locals, "sc_arg", - TSimpleClass(10, 45, "sc_arg#Id", "Blue"), - label: "sc_arg#0"); - - await CompareObjectPropertiesFor(frame_locals, "this", - TPoint(90, -4, "point#Id", "Green"), - label: "this#0"); - - }); + use_cfo: use_cfo, + wait_for_event_fn: async (pause_location) => + { + var frame_locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + await CheckProps(frame_locals, new + { + sc_arg = TObject("DebuggerTests.SimpleClass"), + @this = TValueType("DebuggerTests.Point"), + local_gs = TValueType("DebuggerTests.SimpleGenericStruct") + }, + "locals#0"); + + await CompareObjectPropertiesFor(frame_locals, "local_gs", + new + { + Id = TString("local_gs#Id"), + Color = TEnum("DebuggerTests.RGB", "Green"), + Value = TNumber(4) + }, + label: "local_gs#0"); + + await CompareObjectPropertiesFor(frame_locals, "sc_arg", + TSimpleClass(10, 45, "sc_arg#Id", "Blue"), + label: "sc_arg#0"); + + await CompareObjectPropertiesFor(frame_locals, "this", + TPoint(90, -4, "point#Id", "Green"), + label: "this#0"); + + }); [Fact] public async Task SteppingIntoMscorlib() @@ -1463,7 +1464,7 @@ public async Task SteppingIntoMscorlib() var scripts = SubscribeToScripts(insp); await Ready(); - await insp.Ready(async(cli, token) => + await insp.Ready(async (cli, token) => { ctx = new DebugTestContext(cli, insp, token, scripts); @@ -1474,7 +1475,7 @@ await insp.Ready(async(cli, token) => "OuterMethod"); //make sure we're on the right bp - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"] ? [0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); pause_location = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null); var top_frame = pause_location["callFrames"][0]; @@ -1492,24 +1493,24 @@ await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test.cs", 85, 8, "OuterMethod", "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:OuterMethod'); })", - wait_for_event_fn : async(pause_location) => - { - var new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 4 }});"); - await _invoke_getter(new_id, "NonExistant", expect_ok : false); + wait_for_event_fn: async (pause_location) => + { + var new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 4 }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok: false); - new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3 }});"); - await _invoke_getter(new_id, "NonExistant", expect_ok : false); + new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3 }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok: false); - new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 'AA' }});"); - await _invoke_getter(new_id, "NonExistant", expect_ok : false); - }); + new_id = await CreateNewId(@"MONO._new_or_add_id_props ({ scheme: 'valuetype', idArgs: { containerId: 1 }, props: { klass: 3, value64: 'AA' }});"); + await _invoke_getter(new_id, "NonExistant", expect_ok: false); + }); async Task CreateNewId(string expr) { var res = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = expr }), ctx.token); Assert.True(res.IsOk, "Expected Runtime.evaluate to succeed"); - AssertEqual("string", res.Value["result"] ? ["type"]?.Value(), "Expected Runtime.evaluate to return a string type result"); - return res.Value["result"] ? ["value"]?.Value(); + AssertEqual("string", res.Value["result"]?["type"]?.Value(), "Expected Runtime.evaluate to return a string type result"); + return res.Value["result"]?["value"]?.Value(); } async Task _invoke_getter(string obj_id, string property_name, bool expect_ok) From 4988c25c0be065da30981dcebec18da195c580af Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Mon, 10 Aug 2020 11:10:53 -0700 Subject: [PATCH 366/755] Fix #33948 by decreasing number of tests per group (#40491) --- .../AdvSimd.Arm64_Part0_r.csproj | 156 -------- .../AdvSimd.Arm64_Part0_ro.csproj | 156 -------- .../AdvSimd.Arm64_Part1_r.csproj | 356 +++++------------- .../AdvSimd.Arm64_Part1_ro.csproj | 356 +++++------------- .../AdvSimd.Arm64_Part2_r.csproj | 176 +++++---- .../AdvSimd.Arm64_Part2_ro.csproj | 176 +++++---- .../AdvSimd.Arm64_Part3_r.csproj | 115 ++++++ .../AdvSimd.Arm64_Part3_ro.csproj | 115 ++++++ .../AdvSimd.Arm64_Part4_r.csproj | 115 ++++++ .../AdvSimd.Arm64_Part4_ro.csproj | 115 ++++++ .../AdvSimd.Arm64_Part5_r.csproj | 103 +++++ .../AdvSimd.Arm64_Part5_ro.csproj | 103 +++++ .../Program.AdvSimd.Arm64_Part0.cs | 156 -------- .../Program.AdvSimd.Arm64_Part1.cs | 356 +++++------------- .../Program.AdvSimd.Arm64_Part2.cs | 176 +++++---- .../Program.AdvSimd.Arm64_Part3.cs | 117 ++++++ .../Program.AdvSimd.Arm64_Part4.cs | 117 ++++++ .../Program.AdvSimd.Arm64_Part5.cs | 105 ++++++ .../Arm/AdvSimd/AdvSimd_Part0_r.csproj | 156 -------- .../Arm/AdvSimd/AdvSimd_Part0_ro.csproj | 156 -------- .../Arm/AdvSimd/AdvSimd_Part10_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part10_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part11_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part11_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part12_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part12_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part13_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part13_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part14_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part14_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part15_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part15_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part16_r.csproj | 41 ++ .../Arm/AdvSimd/AdvSimd_Part16_ro.csproj | 41 ++ .../Arm/AdvSimd/AdvSimd_Part1_r.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part1_ro.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part2_r.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part2_ro.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part3_r.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part3_ro.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part4_r.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part4_ro.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part5_r.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part5_ro.csproj | 356 +++++------------- .../Arm/AdvSimd/AdvSimd_Part6_r.csproj | 190 +++++----- .../Arm/AdvSimd/AdvSimd_Part6_ro.csproj | 190 +++++----- .../Arm/AdvSimd/AdvSimd_Part7_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part7_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part8_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part8_ro.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part9_r.csproj | 115 ++++++ .../Arm/AdvSimd/AdvSimd_Part9_ro.csproj | 115 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part0.cs | 156 -------- .../Arm/AdvSimd/Program.AdvSimd_Part1.cs | 356 +++++------------- .../Arm/AdvSimd/Program.AdvSimd_Part10.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part11.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part12.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part13.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part14.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part15.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part16.cs | 43 +++ .../Arm/AdvSimd/Program.AdvSimd_Part2.cs | 356 +++++------------- .../Arm/AdvSimd/Program.AdvSimd_Part3.cs | 356 +++++------------- .../Arm/AdvSimd/Program.AdvSimd_Part4.cs | 356 +++++------------- .../Arm/AdvSimd/Program.AdvSimd_Part5.cs | 356 +++++------------- .../Arm/AdvSimd/Program.AdvSimd_Part6.cs | 190 +++++----- .../Arm/AdvSimd/Program.AdvSimd_Part7.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part8.cs | 117 ++++++ .../Arm/AdvSimd/Program.AdvSimd_Part9.cs | 117 ++++++ .../Arm/Shared/GenerateTests.csx | 2 +- 70 files changed, 6654 insertions(+), 6043 deletions(-) create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part3.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part4.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part5.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part10.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part11.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part12.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part13.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part14.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part15.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part16.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part7.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part8.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part9.cs diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_r.csproj index e8243fcd5f9d..c07b7716c3d5 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_r.csproj @@ -108,162 +108,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_ro.csproj index d6eddfbf84f4..eed3df42b40e 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part0_ro.csproj @@ -108,162 +108,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_r.csproj index 8f551beaefa2..591e487a180d 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_ro.csproj index 4941c87b8d58..0176825d3a24 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part1_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_r.csproj index 57b35cfad4f1..9e5bb852c66c 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_r.csproj @@ -8,82 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_ro.csproj index fd6c1b8a634a..0f2b16160a21 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part2_ro.csproj @@ -8,82 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_r.csproj new file mode 100644 index 000000000000..437f1067d107 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_ro.csproj new file mode 100644 index 000000000000..13580d32dfa2 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part3_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_r.csproj new file mode 100644 index 000000000000..143f9a5b8ecd --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_ro.csproj new file mode 100644 index 000000000000..88cd888f1281 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part4_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_r.csproj new file mode 100644 index 000000000000..39e343813daa --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_r.csproj @@ -0,0 +1,103 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_ro.csproj new file mode 100644 index 000000000000..66171e3eb6c9 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_Part5_ro.csproj @@ -0,0 +1,103 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part0.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part0.cs index 0d7f9662b413..e935da8b57bb 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part0.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part0.cs @@ -111,162 +111,6 @@ static Program() ["CompareGreaterThanScalar.Vector64.Double"] = CompareGreaterThanScalar_Vector64_Double, ["CompareGreaterThanScalar.Vector64.Int64"] = CompareGreaterThanScalar_Vector64_Int64, ["CompareGreaterThanScalar.Vector64.Single"] = CompareGreaterThanScalar_Vector64_Single, - ["CompareGreaterThanScalar.Vector64.UInt64"] = CompareGreaterThanScalar_Vector64_UInt64, - ["CompareGreaterThanOrEqual.Vector128.Double"] = CompareGreaterThanOrEqual_Vector128_Double, - ["CompareGreaterThanOrEqual.Vector128.Int64"] = CompareGreaterThanOrEqual_Vector128_Int64, - ["CompareGreaterThanOrEqual.Vector128.UInt64"] = CompareGreaterThanOrEqual_Vector128_UInt64, - ["CompareGreaterThanOrEqualScalar.Vector64.Double"] = CompareGreaterThanOrEqualScalar_Vector64_Double, - ["CompareGreaterThanOrEqualScalar.Vector64.Int64"] = CompareGreaterThanOrEqualScalar_Vector64_Int64, - ["CompareGreaterThanOrEqualScalar.Vector64.Single"] = CompareGreaterThanOrEqualScalar_Vector64_Single, - ["CompareGreaterThanOrEqualScalar.Vector64.UInt64"] = CompareGreaterThanOrEqualScalar_Vector64_UInt64, - ["CompareLessThan.Vector128.Double"] = CompareLessThan_Vector128_Double, - ["CompareLessThan.Vector128.Int64"] = CompareLessThan_Vector128_Int64, - ["CompareLessThan.Vector128.UInt64"] = CompareLessThan_Vector128_UInt64, - ["CompareLessThanScalar.Vector64.Double"] = CompareLessThanScalar_Vector64_Double, - ["CompareLessThanScalar.Vector64.Int64"] = CompareLessThanScalar_Vector64_Int64, - ["CompareLessThanScalar.Vector64.Single"] = CompareLessThanScalar_Vector64_Single, - ["CompareLessThanScalar.Vector64.UInt64"] = CompareLessThanScalar_Vector64_UInt64, - ["CompareLessThanOrEqual.Vector128.Double"] = CompareLessThanOrEqual_Vector128_Double, - ["CompareLessThanOrEqual.Vector128.Int64"] = CompareLessThanOrEqual_Vector128_Int64, - ["CompareLessThanOrEqual.Vector128.UInt64"] = CompareLessThanOrEqual_Vector128_UInt64, - ["CompareLessThanOrEqualScalar.Vector64.Double"] = CompareLessThanOrEqualScalar_Vector64_Double, - ["CompareLessThanOrEqualScalar.Vector64.Int64"] = CompareLessThanOrEqualScalar_Vector64_Int64, - ["CompareLessThanOrEqualScalar.Vector64.Single"] = CompareLessThanOrEqualScalar_Vector64_Single, - ["CompareLessThanOrEqualScalar.Vector64.UInt64"] = CompareLessThanOrEqualScalar_Vector64_UInt64, - ["CompareTest.Vector128.Double"] = CompareTest_Vector128_Double, - ["CompareTest.Vector128.Int64"] = CompareTest_Vector128_Int64, - ["CompareTest.Vector128.UInt64"] = CompareTest_Vector128_UInt64, - ["CompareTestScalar.Vector64.Double"] = CompareTestScalar_Vector64_Double, - ["CompareTestScalar.Vector64.Int64"] = CompareTestScalar_Vector64_Int64, - ["CompareTestScalar.Vector64.UInt64"] = CompareTestScalar_Vector64_UInt64, - ["ConvertToDouble.Vector64.Single"] = ConvertToDouble_Vector64_Single, - ["ConvertToDouble.Vector128.Int64"] = ConvertToDouble_Vector128_Int64, - ["ConvertToDouble.Vector128.UInt64"] = ConvertToDouble_Vector128_UInt64, - ["ConvertToDoubleScalar.Vector64.Int64"] = ConvertToDoubleScalar_Vector64_Int64, - ["ConvertToDoubleScalar.Vector64.UInt64"] = ConvertToDoubleScalar_Vector64_UInt64, - ["ConvertToDoubleUpper.Vector128.Single"] = ConvertToDoubleUpper_Vector128_Single, - ["ConvertToInt64RoundAwayFromZero.Vector128.Double"] = ConvertToInt64RoundAwayFromZero_Vector128_Double, - ["ConvertToInt64RoundAwayFromZeroScalar.Vector64.Double"] = ConvertToInt64RoundAwayFromZeroScalar_Vector64_Double, - ["ConvertToInt64RoundToEven.Vector128.Double"] = ConvertToInt64RoundToEven_Vector128_Double, - ["ConvertToInt64RoundToEvenScalar.Vector64.Double"] = ConvertToInt64RoundToEvenScalar_Vector64_Double, - ["ConvertToInt64RoundToNegativeInfinity.Vector128.Double"] = ConvertToInt64RoundToNegativeInfinity_Vector128_Double, - ["ConvertToInt64RoundToNegativeInfinityScalar.Vector64.Double"] = ConvertToInt64RoundToNegativeInfinityScalar_Vector64_Double, - ["ConvertToInt64RoundToPositiveInfinity.Vector128.Double"] = ConvertToInt64RoundToPositiveInfinity_Vector128_Double, - ["ConvertToInt64RoundToPositiveInfinityScalar.Vector64.Double"] = ConvertToInt64RoundToPositiveInfinityScalar_Vector64_Double, - ["ConvertToInt64RoundToZero.Vector128.Double"] = ConvertToInt64RoundToZero_Vector128_Double, - ["ConvertToInt64RoundToZeroScalar.Vector64.Double"] = ConvertToInt64RoundToZeroScalar_Vector64_Double, - ["ConvertToSingleLower.Vector64.Single"] = ConvertToSingleLower_Vector64_Single, - ["ConvertToSingleRoundToOddLower.Vector64.Single"] = ConvertToSingleRoundToOddLower_Vector64_Single, - ["ConvertToSingleRoundToOddUpper.Vector128.Single"] = ConvertToSingleRoundToOddUpper_Vector128_Single, - ["ConvertToSingleUpper.Vector128.Single"] = ConvertToSingleUpper_Vector128_Single, - ["ConvertToUInt64RoundAwayFromZero.Vector128.Double"] = ConvertToUInt64RoundAwayFromZero_Vector128_Double, - ["ConvertToUInt64RoundAwayFromZeroScalar.Vector64.Double"] = ConvertToUInt64RoundAwayFromZeroScalar_Vector64_Double, - ["ConvertToUInt64RoundToEven.Vector128.Double"] = ConvertToUInt64RoundToEven_Vector128_Double, - ["ConvertToUInt64RoundToEvenScalar.Vector64.Double"] = ConvertToUInt64RoundToEvenScalar_Vector64_Double, - ["ConvertToUInt64RoundToNegativeInfinity.Vector128.Double"] = ConvertToUInt64RoundToNegativeInfinity_Vector128_Double, - ["ConvertToUInt64RoundToNegativeInfinityScalar.Vector64.Double"] = ConvertToUInt64RoundToNegativeInfinityScalar_Vector64_Double, - ["ConvertToUInt64RoundToPositiveInfinity.Vector128.Double"] = ConvertToUInt64RoundToPositiveInfinity_Vector128_Double, - ["ConvertToUInt64RoundToPositiveInfinityScalar.Vector64.Double"] = ConvertToUInt64RoundToPositiveInfinityScalar_Vector64_Double, - ["ConvertToUInt64RoundToZero.Vector128.Double"] = ConvertToUInt64RoundToZero_Vector128_Double, - ["ConvertToUInt64RoundToZeroScalar.Vector64.Double"] = ConvertToUInt64RoundToZeroScalar_Vector64_Double, - ["Divide.Vector64.Single"] = Divide_Vector64_Single, - ["Divide.Vector128.Double"] = Divide_Vector128_Double, - ["Divide.Vector128.Single"] = Divide_Vector128_Single, - ["DuplicateSelectedScalarToVector128.V128.Double.1"] = DuplicateSelectedScalarToVector128_V128_Double_1, - ["DuplicateSelectedScalarToVector128.V128.Int64.1"] = DuplicateSelectedScalarToVector128_V128_Int64_1, - ["DuplicateSelectedScalarToVector128.V128.UInt64.1"] = DuplicateSelectedScalarToVector128_V128_UInt64_1, - ["DuplicateToVector128.Double"] = DuplicateToVector128_Double, - ["DuplicateToVector128.Double.31"] = DuplicateToVector128_Double_31, - ["DuplicateToVector128.Int64"] = DuplicateToVector128_Int64, - ["DuplicateToVector128.Int64.31"] = DuplicateToVector128_Int64_31, - ["DuplicateToVector128.UInt64"] = DuplicateToVector128_UInt64, - ["DuplicateToVector128.UInt64.31"] = DuplicateToVector128_UInt64_31, - ["ExtractNarrowingSaturateScalar.Vector64.Byte"] = ExtractNarrowingSaturateScalar_Vector64_Byte, - ["ExtractNarrowingSaturateScalar.Vector64.Int16"] = ExtractNarrowingSaturateScalar_Vector64_Int16, - ["ExtractNarrowingSaturateScalar.Vector64.Int32"] = ExtractNarrowingSaturateScalar_Vector64_Int32, - ["ExtractNarrowingSaturateScalar.Vector64.SByte"] = ExtractNarrowingSaturateScalar_Vector64_SByte, - ["ExtractNarrowingSaturateScalar.Vector64.UInt16"] = ExtractNarrowingSaturateScalar_Vector64_UInt16, - ["ExtractNarrowingSaturateScalar.Vector64.UInt32"] = ExtractNarrowingSaturateScalar_Vector64_UInt32, - ["ExtractNarrowingSaturateUnsignedScalar.Vector64.Byte"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_Byte, - ["ExtractNarrowingSaturateUnsignedScalar.Vector64.UInt16"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt16, - ["ExtractNarrowingSaturateUnsignedScalar.Vector64.UInt32"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt32, - ["Floor.Vector128.Double"] = Floor_Vector128_Double, - ["FusedMultiplyAdd.Vector128.Double"] = FusedMultiplyAdd_Vector128_Double, - ["FusedMultiplyAddByScalar.Vector64.Single"] = FusedMultiplyAddByScalar_Vector64_Single, - ["FusedMultiplyAddByScalar.Vector128.Double"] = FusedMultiplyAddByScalar_Vector128_Double, - ["FusedMultiplyAddByScalar.Vector128.Single"] = FusedMultiplyAddByScalar_Vector128_Single, - ["FusedMultiplyAddBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["FusedMultiplyAddBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["FusedMultiplyAddBySelectedScalar.Vector128.Double.Vector128.Double.1"] = FusedMultiplyAddBySelectedScalar_Vector128_Double_Vector128_Double_1, - ["FusedMultiplyAddBySelectedScalar.Vector128.Single.Vector64.Single.1"] = FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector64_Single_1, - ["FusedMultiplyAddBySelectedScalar.Vector128.Single.Vector128.Single.3"] = FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector128_Single_3, - ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, - ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["FusedMultiplySubtract.Vector128.Double"] = FusedMultiplySubtract_Vector128_Double, - ["FusedMultiplySubtractByScalar.Vector64.Single"] = FusedMultiplySubtractByScalar_Vector64_Single, - ["FusedMultiplySubtractByScalar.Vector128.Double"] = FusedMultiplySubtractByScalar_Vector128_Double, - ["FusedMultiplySubtractByScalar.Vector128.Single"] = FusedMultiplySubtractByScalar_Vector128_Single, - ["FusedMultiplySubtractBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["FusedMultiplySubtractBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["FusedMultiplySubtractBySelectedScalar.Vector128.Double.Vector128.Double.1"] = FusedMultiplySubtractBySelectedScalar_Vector128_Double_Vector128_Double_1, - ["FusedMultiplySubtractBySelectedScalar.Vector128.Single.Vector64.Single.1"] = FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector64_Single_1, - ["FusedMultiplySubtractBySelectedScalar.Vector128.Single.Vector128.Single.3"] = FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector128_Single_3, - ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, - ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["InsertSelectedScalar.Vector64.Byte.7.Vector64.Byte.7"] = InsertSelectedScalar_Vector64_Byte_7_Vector64_Byte_7, - ["InsertSelectedScalar.Vector64.Byte.7.Vector128.Byte.15"] = InsertSelectedScalar_Vector64_Byte_7_Vector128_Byte_15, - ["InsertSelectedScalar.Vector64.Int16.3.Vector64.Int16.3"] = InsertSelectedScalar_Vector64_Int16_3_Vector64_Int16_3, - ["InsertSelectedScalar.Vector64.Int16.3.Vector128.Int16.7"] = InsertSelectedScalar_Vector64_Int16_3_Vector128_Int16_7, - ["InsertSelectedScalar.Vector64.Int32.1.Vector64.Int32.1"] = InsertSelectedScalar_Vector64_Int32_1_Vector64_Int32_1, - ["InsertSelectedScalar.Vector64.Int32.1.Vector128.Int32.3"] = InsertSelectedScalar_Vector64_Int32_1_Vector128_Int32_3, - ["InsertSelectedScalar.Vector64.SByte.7.Vector64.SByte.7"] = InsertSelectedScalar_Vector64_SByte_7_Vector64_SByte_7, - ["InsertSelectedScalar.Vector64.SByte.7.Vector128.SByte.15"] = InsertSelectedScalar_Vector64_SByte_7_Vector128_SByte_15, - ["InsertSelectedScalar.Vector64.Single.1.Vector64.Single.1"] = InsertSelectedScalar_Vector64_Single_1_Vector64_Single_1, - ["InsertSelectedScalar.Vector64.Single.1.Vector128.Single.3"] = InsertSelectedScalar_Vector64_Single_1_Vector128_Single_3, - ["InsertSelectedScalar.Vector64.UInt16.3.Vector64.UInt16.3"] = InsertSelectedScalar_Vector64_UInt16_3_Vector64_UInt16_3, - ["InsertSelectedScalar.Vector64.UInt16.3.Vector128.UInt16.7"] = InsertSelectedScalar_Vector64_UInt16_3_Vector128_UInt16_7, - ["InsertSelectedScalar.Vector64.UInt32.1.Vector64.UInt32.1"] = InsertSelectedScalar_Vector64_UInt32_1_Vector64_UInt32_1, - ["InsertSelectedScalar.Vector64.UInt32.1.Vector128.UInt32.3"] = InsertSelectedScalar_Vector64_UInt32_1_Vector128_UInt32_3, - ["InsertSelectedScalar.Vector128.Byte.15.Vector64.Byte.7"] = InsertSelectedScalar_Vector128_Byte_15_Vector64_Byte_7, - ["InsertSelectedScalar.Vector128.Byte.15.Vector128.Byte.15"] = InsertSelectedScalar_Vector128_Byte_15_Vector128_Byte_15, - ["InsertSelectedScalar.Vector128.Double.1.Vector128.Double.1"] = InsertSelectedScalar_Vector128_Double_1_Vector128_Double_1, - ["InsertSelectedScalar.Vector128.Int16.7.Vector64.Int16.3"] = InsertSelectedScalar_Vector128_Int16_7_Vector64_Int16_3, - ["InsertSelectedScalar.Vector128.Int16.7.Vector128.Int16.7"] = InsertSelectedScalar_Vector128_Int16_7_Vector128_Int16_7, - ["InsertSelectedScalar.Vector128.Int32.3.Vector64.Int32.1"] = InsertSelectedScalar_Vector128_Int32_3_Vector64_Int32_1, - ["InsertSelectedScalar.Vector128.Int32.3.Vector128.Int32.3"] = InsertSelectedScalar_Vector128_Int32_3_Vector128_Int32_3, - ["InsertSelectedScalar.Vector128.Int64.1.Vector128.Int64.1"] = InsertSelectedScalar_Vector128_Int64_1_Vector128_Int64_1, - ["InsertSelectedScalar.Vector128.SByte.15.Vector64.SByte.7"] = InsertSelectedScalar_Vector128_SByte_15_Vector64_SByte_7, - ["InsertSelectedScalar.Vector128.SByte.15.Vector128.SByte.15"] = InsertSelectedScalar_Vector128_SByte_15_Vector128_SByte_15, - ["InsertSelectedScalar.Vector128.Single.3.Vector64.Single.1"] = InsertSelectedScalar_Vector128_Single_3_Vector64_Single_1, - ["InsertSelectedScalar.Vector128.Single.3.Vector128.Single.3"] = InsertSelectedScalar_Vector128_Single_3_Vector128_Single_3, - ["InsertSelectedScalar.Vector128.UInt16.7.Vector64.UInt16.3"] = InsertSelectedScalar_Vector128_UInt16_7_Vector64_UInt16_3, - ["InsertSelectedScalar.Vector128.UInt16.7.Vector128.UInt16.7"] = InsertSelectedScalar_Vector128_UInt16_7_Vector128_UInt16_7, - ["InsertSelectedScalar.Vector128.UInt32.3.Vector64.UInt32.1"] = InsertSelectedScalar_Vector128_UInt32_3_Vector64_UInt32_1, - ["InsertSelectedScalar.Vector128.UInt32.3.Vector128.UInt32.3"] = InsertSelectedScalar_Vector128_UInt32_3_Vector128_UInt32_3, - ["InsertSelectedScalar.Vector128.UInt64.1.Vector128.UInt64.1"] = InsertSelectedScalar_Vector128_UInt64_1_Vector128_UInt64_1, - ["LoadAndReplicateToVector128.Double"] = LoadAndReplicateToVector128_Double, - ["LoadAndReplicateToVector128.Int64"] = LoadAndReplicateToVector128_Int64, - ["LoadAndReplicateToVector128.UInt64"] = LoadAndReplicateToVector128_UInt64, - ["Max.Vector128.Double"] = Max_Vector128_Double, - ["MaxAcross.Vector64.Byte"] = MaxAcross_Vector64_Byte, - ["MaxAcross.Vector64.Int16"] = MaxAcross_Vector64_Int16, - ["MaxAcross.Vector64.SByte"] = MaxAcross_Vector64_SByte, - ["MaxAcross.Vector64.UInt16"] = MaxAcross_Vector64_UInt16, - ["MaxAcross.Vector128.Byte"] = MaxAcross_Vector128_Byte, - ["MaxAcross.Vector128.Int16"] = MaxAcross_Vector128_Int16, - ["MaxAcross.Vector128.Int32"] = MaxAcross_Vector128_Int32, - ["MaxAcross.Vector128.SByte"] = MaxAcross_Vector128_SByte, - ["MaxAcross.Vector128.Single"] = MaxAcross_Vector128_Single, - ["MaxAcross.Vector128.UInt16"] = MaxAcross_Vector128_UInt16, - ["MaxAcross.Vector128.UInt32"] = MaxAcross_Vector128_UInt32, - ["MaxNumber.Vector128.Double"] = MaxNumber_Vector128_Double, - ["MaxNumberAcross.Vector128.Single"] = MaxNumberAcross_Vector128_Single, - ["MaxNumberPairwise.Vector64.Single"] = MaxNumberPairwise_Vector64_Single, - ["MaxNumberPairwise.Vector128.Double"] = MaxNumberPairwise_Vector128_Double, - ["MaxNumberPairwise.Vector128.Single"] = MaxNumberPairwise_Vector128_Single, - ["MaxNumberPairwiseScalar.Vector64.Single"] = MaxNumberPairwiseScalar_Vector64_Single, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part1.cs index 194a1238d81c..1414162b780f 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part1.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["MaxNumberPairwiseScalar.Vector128.Double"] = MaxNumberPairwiseScalar_Vector128_Double, - ["MaxPairwise.Vector128.Byte"] = MaxPairwise_Vector128_Byte, - ["MaxPairwise.Vector128.Double"] = MaxPairwise_Vector128_Double, - ["MaxPairwise.Vector128.Int16"] = MaxPairwise_Vector128_Int16, - ["MaxPairwise.Vector128.Int32"] = MaxPairwise_Vector128_Int32, - ["MaxPairwise.Vector128.SByte"] = MaxPairwise_Vector128_SByte, - ["MaxPairwise.Vector128.Single"] = MaxPairwise_Vector128_Single, - ["MaxPairwise.Vector128.UInt16"] = MaxPairwise_Vector128_UInt16, - ["MaxPairwise.Vector128.UInt32"] = MaxPairwise_Vector128_UInt32, - ["MaxPairwiseScalar.Vector64.Single"] = MaxPairwiseScalar_Vector64_Single, - ["MaxPairwiseScalar.Vector128.Double"] = MaxPairwiseScalar_Vector128_Double, - ["MaxScalar.Vector64.Double"] = MaxScalar_Vector64_Double, - ["MaxScalar.Vector64.Single"] = MaxScalar_Vector64_Single, - ["Min.Vector128.Double"] = Min_Vector128_Double, - ["MinAcross.Vector64.Byte"] = MinAcross_Vector64_Byte, - ["MinAcross.Vector64.Int16"] = MinAcross_Vector64_Int16, - ["MinAcross.Vector64.SByte"] = MinAcross_Vector64_SByte, - ["MinAcross.Vector64.UInt16"] = MinAcross_Vector64_UInt16, - ["MinAcross.Vector128.Byte"] = MinAcross_Vector128_Byte, - ["MinAcross.Vector128.Int16"] = MinAcross_Vector128_Int16, - ["MinAcross.Vector128.Int32"] = MinAcross_Vector128_Int32, - ["MinAcross.Vector128.SByte"] = MinAcross_Vector128_SByte, - ["MinAcross.Vector128.Single"] = MinAcross_Vector128_Single, - ["MinAcross.Vector128.UInt16"] = MinAcross_Vector128_UInt16, - ["MinAcross.Vector128.UInt32"] = MinAcross_Vector128_UInt32, - ["MinNumber.Vector128.Double"] = MinNumber_Vector128_Double, - ["MinNumberAcross.Vector128.Single"] = MinNumberAcross_Vector128_Single, - ["MinNumberPairwise.Vector64.Single"] = MinNumberPairwise_Vector64_Single, - ["MinNumberPairwise.Vector128.Double"] = MinNumberPairwise_Vector128_Double, - ["MinNumberPairwise.Vector128.Single"] = MinNumberPairwise_Vector128_Single, - ["MinNumberPairwiseScalar.Vector64.Single"] = MinNumberPairwiseScalar_Vector64_Single, - ["MinNumberPairwiseScalar.Vector128.Double"] = MinNumberPairwiseScalar_Vector128_Double, - ["MinPairwise.Vector128.Byte"] = MinPairwise_Vector128_Byte, - ["MinPairwise.Vector128.Double"] = MinPairwise_Vector128_Double, - ["MinPairwise.Vector128.Int16"] = MinPairwise_Vector128_Int16, - ["MinPairwise.Vector128.Int32"] = MinPairwise_Vector128_Int32, - ["MinPairwise.Vector128.SByte"] = MinPairwise_Vector128_SByte, - ["MinPairwise.Vector128.Single"] = MinPairwise_Vector128_Single, - ["MinPairwise.Vector128.UInt16"] = MinPairwise_Vector128_UInt16, - ["MinPairwise.Vector128.UInt32"] = MinPairwise_Vector128_UInt32, - ["MinPairwiseScalar.Vector64.Single"] = MinPairwiseScalar_Vector64_Single, - ["MinPairwiseScalar.Vector128.Double"] = MinPairwiseScalar_Vector128_Double, - ["MinScalar.Vector64.Double"] = MinScalar_Vector64_Double, - ["MinScalar.Vector64.Single"] = MinScalar_Vector64_Single, - ["Multiply.Vector128.Double"] = Multiply_Vector128_Double, - ["MultiplyByScalar.Vector128.Double"] = MultiplyByScalar_Vector128_Double, - ["MultiplyBySelectedScalar.Vector128.Double.Vector128.Double.1"] = MultiplyBySelectedScalar_Vector128_Double_Vector128_Double_1, - ["MultiplyDoublingSaturateHighScalar.Vector64.Int16"] = MultiplyDoublingSaturateHighScalar_Vector64_Int16, - ["MultiplyDoublingSaturateHighScalar.Vector64.Int32"] = MultiplyDoublingSaturateHighScalar_Vector64_Int32, - ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningAndAddSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int16, - ["MultiplyDoublingWideningAndAddSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int32, - ["MultiplyDoublingWideningAndSubtractSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int16, - ["MultiplyDoublingWideningAndSubtractSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int32, - ["MultiplyDoublingWideningSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningSaturateScalar_Vector64_Int16, - ["MultiplyDoublingWideningSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningSaturateScalar_Vector64_Int32, - ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3, - ["MultiplyExtended.Vector64.Single"] = MultiplyExtended_Vector64_Single, - ["MultiplyExtended.Vector128.Double"] = MultiplyExtended_Vector128_Double, - ["MultiplyExtended.Vector128.Single"] = MultiplyExtended_Vector128_Single, - ["MultiplyExtendedByScalar.Vector128.Double"] = MultiplyExtendedByScalar_Vector128_Double, - ["MultiplyExtendedBySelectedScalar.Vector128.Double.Vector128.Double.1"] = MultiplyExtendedBySelectedScalar_Vector128_Double_Vector128_Double_1, - ["MultiplyExtendedScalar.Vector64.Double"] = MultiplyExtendedScalar_Vector64_Double, - ["MultiplyExtendedScalar.Vector64.Single"] = MultiplyExtendedScalar_Vector64_Single, - ["MultiplyExtendedScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, - ["MultiplyExtendedScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["MultiplyExtendedScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["MultiplyRoundedDoublingSaturateHighScalar.Vector64.Int16"] = MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int16, - ["MultiplyRoundedDoublingSaturateHighScalar.Vector64.Int32"] = MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int32, - ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, - ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, - ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, - ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, - ["MultiplyScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = MultiplyScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, - ["Negate.Vector128.Double"] = Negate_Vector128_Double, - ["Negate.Vector128.Int64"] = Negate_Vector128_Int64, - ["NegateSaturate.Vector128.Int64"] = NegateSaturate_Vector128_Int64, - ["NegateSaturateScalar.Vector64.Int16"] = NegateSaturateScalar_Vector64_Int16, - ["NegateSaturateScalar.Vector64.Int32"] = NegateSaturateScalar_Vector64_Int32, - ["NegateSaturateScalar.Vector64.Int64"] = NegateSaturateScalar_Vector64_Int64, - ["NegateSaturateScalar.Vector64.SByte"] = NegateSaturateScalar_Vector64_SByte, - ["NegateScalar.Vector64.Int64"] = NegateScalar_Vector64_Int64, - ["ReciprocalEstimate.Vector128.Double"] = ReciprocalEstimate_Vector128_Double, - ["ReciprocalEstimateScalar.Vector64.Double"] = ReciprocalEstimateScalar_Vector64_Double, - ["ReciprocalEstimateScalar.Vector64.Single"] = ReciprocalEstimateScalar_Vector64_Single, - ["ReciprocalExponentScalar.Vector64.Double"] = ReciprocalExponentScalar_Vector64_Double, - ["ReciprocalExponentScalar.Vector64.Single"] = ReciprocalExponentScalar_Vector64_Single, - ["ReciprocalSquareRootEstimate.Vector128.Double"] = ReciprocalSquareRootEstimate_Vector128_Double, - ["ReciprocalSquareRootEstimateScalar.Vector64.Double"] = ReciprocalSquareRootEstimateScalar_Vector64_Double, - ["ReciprocalSquareRootEstimateScalar.Vector64.Single"] = ReciprocalSquareRootEstimateScalar_Vector64_Single, - ["ReciprocalSquareRootStep.Vector128.Double"] = ReciprocalSquareRootStep_Vector128_Double, - ["ReciprocalSquareRootStepScalar.Vector64.Double"] = ReciprocalSquareRootStepScalar_Vector64_Double, - ["ReciprocalSquareRootStepScalar.Vector64.Single"] = ReciprocalSquareRootStepScalar_Vector64_Single, - ["ReciprocalStep.Vector128.Double"] = ReciprocalStep_Vector128_Double, - ["ReciprocalStepScalar.Vector64.Double"] = ReciprocalStepScalar_Vector64_Double, - ["ReciprocalStepScalar.Vector64.Single"] = ReciprocalStepScalar_Vector64_Single, - ["ReverseElementBits.Vector128.Byte"] = ReverseElementBits_Vector128_Byte, - ["ReverseElementBits.Vector128.SByte"] = ReverseElementBits_Vector128_SByte, - ["ReverseElementBits.Vector64.Byte"] = ReverseElementBits_Vector64_Byte, - ["ReverseElementBits.Vector64.SByte"] = ReverseElementBits_Vector64_SByte, - ["RoundAwayFromZero.Vector128.Double"] = RoundAwayFromZero_Vector128_Double, - ["RoundToNearest.Vector128.Double"] = RoundToNearest_Vector128_Double, - ["RoundToNegativeInfinity.Vector128.Double"] = RoundToNegativeInfinity_Vector128_Double, - ["RoundToPositiveInfinity.Vector128.Double"] = RoundToPositiveInfinity_Vector128_Double, - ["RoundToZero.Vector128.Double"] = RoundToZero_Vector128_Double, - ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int16"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int16, - ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int32"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int32, - ["ShiftArithmeticRoundedSaturateScalar.Vector64.SByte"] = ShiftArithmeticRoundedSaturateScalar_Vector64_SByte, - ["ShiftArithmeticSaturateScalar.Vector64.Int16"] = ShiftArithmeticSaturateScalar_Vector64_Int16, - ["ShiftArithmeticSaturateScalar.Vector64.Int32"] = ShiftArithmeticSaturateScalar_Vector64_Int32, - ["ShiftArithmeticSaturateScalar.Vector64.SByte"] = ShiftArithmeticSaturateScalar_Vector64_SByte, - ["ShiftLeftLogicalSaturateScalar.Vector64.Byte.7"] = ShiftLeftLogicalSaturateScalar_Vector64_Byte_7, - ["ShiftLeftLogicalSaturateScalar.Vector64.Int16.15"] = ShiftLeftLogicalSaturateScalar_Vector64_Int16_15, - ["ShiftLeftLogicalSaturateScalar.Vector64.Int32.31"] = ShiftLeftLogicalSaturateScalar_Vector64_Int32_31, - ["ShiftLeftLogicalSaturateScalar.Vector64.SByte.1"] = ShiftLeftLogicalSaturateScalar_Vector64_SByte_1, - ["ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1, - ["ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1, - ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5, - ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7, - ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3, - ["ShiftLogicalRoundedSaturateScalar.Vector64.Byte"] = ShiftLogicalRoundedSaturateScalar_Vector64_Byte, - ["ShiftLogicalRoundedSaturateScalar.Vector64.Int16"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int16, - ["ShiftLogicalRoundedSaturateScalar.Vector64.Int32"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int32, - ["ShiftLogicalRoundedSaturateScalar.Vector64.SByte"] = ShiftLogicalRoundedSaturateScalar_Vector64_SByte, - ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt16"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt16, - ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt32"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt32, - ["ShiftLogicalSaturateScalar.Vector64.Byte"] = ShiftLogicalSaturateScalar_Vector64_Byte, - ["ShiftLogicalSaturateScalar.Vector64.Int16"] = ShiftLogicalSaturateScalar_Vector64_Int16, - ["ShiftLogicalSaturateScalar.Vector64.Int32"] = ShiftLogicalSaturateScalar_Vector64_Int32, - ["ShiftLogicalSaturateScalar.Vector64.SByte"] = ShiftLogicalSaturateScalar_Vector64_SByte, - ["ShiftLogicalSaturateScalar.Vector64.UInt16"] = ShiftLogicalSaturateScalar_Vector64_UInt16, - ["ShiftLogicalSaturateScalar.Vector64.UInt32"] = ShiftLogicalSaturateScalar_Vector64_UInt32, - ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16, - ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32, - ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8, - ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3, - ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5, - ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7, - ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32, - ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64, - ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5, - ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1, - ["Sqrt.Vector64.Single"] = Sqrt_Vector64_Single, - ["Sqrt.Vector128.Double"] = Sqrt_Vector128_Double, - ["Sqrt.Vector128.Single"] = Sqrt_Vector128_Single, - ["StorePair.Vector64.Byte"] = StorePair_Vector64_Byte, - ["StorePair.Vector64.Double"] = StorePair_Vector64_Double, - ["StorePair.Vector64.Int16"] = StorePair_Vector64_Int16, - ["StorePair.Vector64.Int32"] = StorePair_Vector64_Int32, - ["StorePair.Vector64.Int64"] = StorePair_Vector64_Int64, - ["StorePair.Vector64.SByte"] = StorePair_Vector64_SByte, - ["StorePair.Vector64.Single"] = StorePair_Vector64_Single, - ["StorePair.Vector64.UInt16"] = StorePair_Vector64_UInt16, - ["StorePair.Vector64.UInt32"] = StorePair_Vector64_UInt32, - ["StorePair.Vector64.UInt64"] = StorePair_Vector64_UInt64, - ["StorePair.Vector128.Byte"] = StorePair_Vector128_Byte, - ["StorePair.Vector128.Double"] = StorePair_Vector128_Double, - ["StorePair.Vector128.Int16"] = StorePair_Vector128_Int16, - ["StorePair.Vector128.Int32"] = StorePair_Vector128_Int32, - ["StorePair.Vector128.Int64"] = StorePair_Vector128_Int64, - ["StorePair.Vector128.SByte"] = StorePair_Vector128_SByte, - ["StorePair.Vector128.Single"] = StorePair_Vector128_Single, - ["StorePair.Vector128.UInt16"] = StorePair_Vector128_UInt16, - ["StorePair.Vector128.UInt32"] = StorePair_Vector128_UInt32, - ["StorePair.Vector128.UInt64"] = StorePair_Vector128_UInt64, - ["StorePairScalar.Vector64.Int32"] = StorePairScalar_Vector64_Int32, - ["StorePairScalar.Vector64.Single"] = StorePairScalar_Vector64_Single, - ["StorePairScalar.Vector64.UInt32"] = StorePairScalar_Vector64_UInt32, - ["StorePairScalarNonTemporal.Vector64.Int32"] = StorePairScalarNonTemporal_Vector64_Int32, - ["StorePairScalarNonTemporal.Vector64.Single"] = StorePairScalarNonTemporal_Vector64_Single, - ["StorePairScalarNonTemporal.Vector64.UInt32"] = StorePairScalarNonTemporal_Vector64_UInt32, - ["StorePairNonTemporal.Vector64.Byte"] = StorePairNonTemporal_Vector64_Byte, - ["StorePairNonTemporal.Vector64.Double"] = StorePairNonTemporal_Vector64_Double, - ["StorePairNonTemporal.Vector64.Int16"] = StorePairNonTemporal_Vector64_Int16, - ["StorePairNonTemporal.Vector64.Int32"] = StorePairNonTemporal_Vector64_Int32, - ["StorePairNonTemporal.Vector64.Int64"] = StorePairNonTemporal_Vector64_Int64, - ["StorePairNonTemporal.Vector64.SByte"] = StorePairNonTemporal_Vector64_SByte, - ["StorePairNonTemporal.Vector64.Single"] = StorePairNonTemporal_Vector64_Single, - ["StorePairNonTemporal.Vector64.UInt16"] = StorePairNonTemporal_Vector64_UInt16, - ["StorePairNonTemporal.Vector64.UInt32"] = StorePairNonTemporal_Vector64_UInt32, - ["StorePairNonTemporal.Vector64.UInt64"] = StorePairNonTemporal_Vector64_UInt64, - ["StorePairNonTemporal.Vector128.Byte"] = StorePairNonTemporal_Vector128_Byte, - ["StorePairNonTemporal.Vector128.Double"] = StorePairNonTemporal_Vector128_Double, - ["StorePairNonTemporal.Vector128.Int16"] = StorePairNonTemporal_Vector128_Int16, - ["StorePairNonTemporal.Vector128.Int32"] = StorePairNonTemporal_Vector128_Int32, - ["StorePairNonTemporal.Vector128.Int64"] = StorePairNonTemporal_Vector128_Int64, - ["StorePairNonTemporal.Vector128.SByte"] = StorePairNonTemporal_Vector128_SByte, - ["StorePairNonTemporal.Vector128.Single"] = StorePairNonTemporal_Vector128_Single, - ["StorePairNonTemporal.Vector128.UInt16"] = StorePairNonTemporal_Vector128_UInt16, - ["StorePairNonTemporal.Vector128.UInt32"] = StorePairNonTemporal_Vector128_UInt32, - ["StorePairNonTemporal.Vector128.UInt64"] = StorePairNonTemporal_Vector128_UInt64, - ["Subtract.Vector128.Double"] = Subtract_Vector128_Double, - ["SubtractSaturateScalar.Vector64.Byte"] = SubtractSaturateScalar_Vector64_Byte, - ["SubtractSaturateScalar.Vector64.Int16"] = SubtractSaturateScalar_Vector64_Int16, - ["SubtractSaturateScalar.Vector64.Int32"] = SubtractSaturateScalar_Vector64_Int32, - ["SubtractSaturateScalar.Vector64.SByte"] = SubtractSaturateScalar_Vector64_SByte, - ["SubtractSaturateScalar.Vector64.UInt16"] = SubtractSaturateScalar_Vector64_UInt16, - ["SubtractSaturateScalar.Vector64.UInt32"] = SubtractSaturateScalar_Vector64_UInt32, - ["TransposeEven.Vector64.Byte"] = TransposeEven_Vector64_Byte, - ["TransposeEven.Vector64.Int16"] = TransposeEven_Vector64_Int16, - ["TransposeEven.Vector64.Int32"] = TransposeEven_Vector64_Int32, - ["TransposeEven.Vector64.SByte"] = TransposeEven_Vector64_SByte, - ["TransposeEven.Vector64.Single"] = TransposeEven_Vector64_Single, - ["TransposeEven.Vector64.UInt16"] = TransposeEven_Vector64_UInt16, - ["TransposeEven.Vector64.UInt32"] = TransposeEven_Vector64_UInt32, - ["TransposeEven.Vector128.Byte"] = TransposeEven_Vector128_Byte, - ["TransposeEven.Vector128.Double"] = TransposeEven_Vector128_Double, - ["TransposeEven.Vector128.Int16"] = TransposeEven_Vector128_Int16, - ["TransposeEven.Vector128.Int32"] = TransposeEven_Vector128_Int32, - ["TransposeEven.Vector128.Int64"] = TransposeEven_Vector128_Int64, - ["TransposeEven.Vector128.SByte"] = TransposeEven_Vector128_SByte, - ["TransposeEven.Vector128.Single"] = TransposeEven_Vector128_Single, - ["TransposeEven.Vector128.UInt16"] = TransposeEven_Vector128_UInt16, - ["TransposeEven.Vector128.UInt32"] = TransposeEven_Vector128_UInt32, - ["TransposeEven.Vector128.UInt64"] = TransposeEven_Vector128_UInt64, - ["TransposeOdd.Vector64.Byte"] = TransposeOdd_Vector64_Byte, - ["TransposeOdd.Vector64.Int16"] = TransposeOdd_Vector64_Int16, - ["TransposeOdd.Vector64.Int32"] = TransposeOdd_Vector64_Int32, - ["TransposeOdd.Vector64.SByte"] = TransposeOdd_Vector64_SByte, - ["TransposeOdd.Vector64.Single"] = TransposeOdd_Vector64_Single, - ["TransposeOdd.Vector64.UInt16"] = TransposeOdd_Vector64_UInt16, - ["TransposeOdd.Vector64.UInt32"] = TransposeOdd_Vector64_UInt32, - ["TransposeOdd.Vector128.Byte"] = TransposeOdd_Vector128_Byte, - ["TransposeOdd.Vector128.Double"] = TransposeOdd_Vector128_Double, - ["TransposeOdd.Vector128.Int16"] = TransposeOdd_Vector128_Int16, - ["TransposeOdd.Vector128.Int32"] = TransposeOdd_Vector128_Int32, - ["TransposeOdd.Vector128.Int64"] = TransposeOdd_Vector128_Int64, - ["TransposeOdd.Vector128.SByte"] = TransposeOdd_Vector128_SByte, + ["CompareGreaterThanScalar.Vector64.UInt64"] = CompareGreaterThanScalar_Vector64_UInt64, + ["CompareGreaterThanOrEqual.Vector128.Double"] = CompareGreaterThanOrEqual_Vector128_Double, + ["CompareGreaterThanOrEqual.Vector128.Int64"] = CompareGreaterThanOrEqual_Vector128_Int64, + ["CompareGreaterThanOrEqual.Vector128.UInt64"] = CompareGreaterThanOrEqual_Vector128_UInt64, + ["CompareGreaterThanOrEqualScalar.Vector64.Double"] = CompareGreaterThanOrEqualScalar_Vector64_Double, + ["CompareGreaterThanOrEqualScalar.Vector64.Int64"] = CompareGreaterThanOrEqualScalar_Vector64_Int64, + ["CompareGreaterThanOrEqualScalar.Vector64.Single"] = CompareGreaterThanOrEqualScalar_Vector64_Single, + ["CompareGreaterThanOrEqualScalar.Vector64.UInt64"] = CompareGreaterThanOrEqualScalar_Vector64_UInt64, + ["CompareLessThan.Vector128.Double"] = CompareLessThan_Vector128_Double, + ["CompareLessThan.Vector128.Int64"] = CompareLessThan_Vector128_Int64, + ["CompareLessThan.Vector128.UInt64"] = CompareLessThan_Vector128_UInt64, + ["CompareLessThanScalar.Vector64.Double"] = CompareLessThanScalar_Vector64_Double, + ["CompareLessThanScalar.Vector64.Int64"] = CompareLessThanScalar_Vector64_Int64, + ["CompareLessThanScalar.Vector64.Single"] = CompareLessThanScalar_Vector64_Single, + ["CompareLessThanScalar.Vector64.UInt64"] = CompareLessThanScalar_Vector64_UInt64, + ["CompareLessThanOrEqual.Vector128.Double"] = CompareLessThanOrEqual_Vector128_Double, + ["CompareLessThanOrEqual.Vector128.Int64"] = CompareLessThanOrEqual_Vector128_Int64, + ["CompareLessThanOrEqual.Vector128.UInt64"] = CompareLessThanOrEqual_Vector128_UInt64, + ["CompareLessThanOrEqualScalar.Vector64.Double"] = CompareLessThanOrEqualScalar_Vector64_Double, + ["CompareLessThanOrEqualScalar.Vector64.Int64"] = CompareLessThanOrEqualScalar_Vector64_Int64, + ["CompareLessThanOrEqualScalar.Vector64.Single"] = CompareLessThanOrEqualScalar_Vector64_Single, + ["CompareLessThanOrEqualScalar.Vector64.UInt64"] = CompareLessThanOrEqualScalar_Vector64_UInt64, + ["CompareTest.Vector128.Double"] = CompareTest_Vector128_Double, + ["CompareTest.Vector128.Int64"] = CompareTest_Vector128_Int64, + ["CompareTest.Vector128.UInt64"] = CompareTest_Vector128_UInt64, + ["CompareTestScalar.Vector64.Double"] = CompareTestScalar_Vector64_Double, + ["CompareTestScalar.Vector64.Int64"] = CompareTestScalar_Vector64_Int64, + ["CompareTestScalar.Vector64.UInt64"] = CompareTestScalar_Vector64_UInt64, + ["ConvertToDouble.Vector64.Single"] = ConvertToDouble_Vector64_Single, + ["ConvertToDouble.Vector128.Int64"] = ConvertToDouble_Vector128_Int64, + ["ConvertToDouble.Vector128.UInt64"] = ConvertToDouble_Vector128_UInt64, + ["ConvertToDoubleScalar.Vector64.Int64"] = ConvertToDoubleScalar_Vector64_Int64, + ["ConvertToDoubleScalar.Vector64.UInt64"] = ConvertToDoubleScalar_Vector64_UInt64, + ["ConvertToDoubleUpper.Vector128.Single"] = ConvertToDoubleUpper_Vector128_Single, + ["ConvertToInt64RoundAwayFromZero.Vector128.Double"] = ConvertToInt64RoundAwayFromZero_Vector128_Double, + ["ConvertToInt64RoundAwayFromZeroScalar.Vector64.Double"] = ConvertToInt64RoundAwayFromZeroScalar_Vector64_Double, + ["ConvertToInt64RoundToEven.Vector128.Double"] = ConvertToInt64RoundToEven_Vector128_Double, + ["ConvertToInt64RoundToEvenScalar.Vector64.Double"] = ConvertToInt64RoundToEvenScalar_Vector64_Double, + ["ConvertToInt64RoundToNegativeInfinity.Vector128.Double"] = ConvertToInt64RoundToNegativeInfinity_Vector128_Double, + ["ConvertToInt64RoundToNegativeInfinityScalar.Vector64.Double"] = ConvertToInt64RoundToNegativeInfinityScalar_Vector64_Double, + ["ConvertToInt64RoundToPositiveInfinity.Vector128.Double"] = ConvertToInt64RoundToPositiveInfinity_Vector128_Double, + ["ConvertToInt64RoundToPositiveInfinityScalar.Vector64.Double"] = ConvertToInt64RoundToPositiveInfinityScalar_Vector64_Double, + ["ConvertToInt64RoundToZero.Vector128.Double"] = ConvertToInt64RoundToZero_Vector128_Double, + ["ConvertToInt64RoundToZeroScalar.Vector64.Double"] = ConvertToInt64RoundToZeroScalar_Vector64_Double, + ["ConvertToSingleLower.Vector64.Single"] = ConvertToSingleLower_Vector64_Single, + ["ConvertToSingleRoundToOddLower.Vector64.Single"] = ConvertToSingleRoundToOddLower_Vector64_Single, + ["ConvertToSingleRoundToOddUpper.Vector128.Single"] = ConvertToSingleRoundToOddUpper_Vector128_Single, + ["ConvertToSingleUpper.Vector128.Single"] = ConvertToSingleUpper_Vector128_Single, + ["ConvertToUInt64RoundAwayFromZero.Vector128.Double"] = ConvertToUInt64RoundAwayFromZero_Vector128_Double, + ["ConvertToUInt64RoundAwayFromZeroScalar.Vector64.Double"] = ConvertToUInt64RoundAwayFromZeroScalar_Vector64_Double, + ["ConvertToUInt64RoundToEven.Vector128.Double"] = ConvertToUInt64RoundToEven_Vector128_Double, + ["ConvertToUInt64RoundToEvenScalar.Vector64.Double"] = ConvertToUInt64RoundToEvenScalar_Vector64_Double, + ["ConvertToUInt64RoundToNegativeInfinity.Vector128.Double"] = ConvertToUInt64RoundToNegativeInfinity_Vector128_Double, + ["ConvertToUInt64RoundToNegativeInfinityScalar.Vector64.Double"] = ConvertToUInt64RoundToNegativeInfinityScalar_Vector64_Double, + ["ConvertToUInt64RoundToPositiveInfinity.Vector128.Double"] = ConvertToUInt64RoundToPositiveInfinity_Vector128_Double, + ["ConvertToUInt64RoundToPositiveInfinityScalar.Vector64.Double"] = ConvertToUInt64RoundToPositiveInfinityScalar_Vector64_Double, + ["ConvertToUInt64RoundToZero.Vector128.Double"] = ConvertToUInt64RoundToZero_Vector128_Double, + ["ConvertToUInt64RoundToZeroScalar.Vector64.Double"] = ConvertToUInt64RoundToZeroScalar_Vector64_Double, + ["Divide.Vector64.Single"] = Divide_Vector64_Single, + ["Divide.Vector128.Double"] = Divide_Vector128_Double, + ["Divide.Vector128.Single"] = Divide_Vector128_Single, + ["DuplicateSelectedScalarToVector128.V128.Double.1"] = DuplicateSelectedScalarToVector128_V128_Double_1, + ["DuplicateSelectedScalarToVector128.V128.Int64.1"] = DuplicateSelectedScalarToVector128_V128_Int64_1, + ["DuplicateSelectedScalarToVector128.V128.UInt64.1"] = DuplicateSelectedScalarToVector128_V128_UInt64_1, + ["DuplicateToVector128.Double"] = DuplicateToVector128_Double, + ["DuplicateToVector128.Double.31"] = DuplicateToVector128_Double_31, + ["DuplicateToVector128.Int64"] = DuplicateToVector128_Int64, + ["DuplicateToVector128.Int64.31"] = DuplicateToVector128_Int64_31, + ["DuplicateToVector128.UInt64"] = DuplicateToVector128_UInt64, + ["DuplicateToVector128.UInt64.31"] = DuplicateToVector128_UInt64_31, + ["ExtractNarrowingSaturateScalar.Vector64.Byte"] = ExtractNarrowingSaturateScalar_Vector64_Byte, + ["ExtractNarrowingSaturateScalar.Vector64.Int16"] = ExtractNarrowingSaturateScalar_Vector64_Int16, + ["ExtractNarrowingSaturateScalar.Vector64.Int32"] = ExtractNarrowingSaturateScalar_Vector64_Int32, + ["ExtractNarrowingSaturateScalar.Vector64.SByte"] = ExtractNarrowingSaturateScalar_Vector64_SByte, + ["ExtractNarrowingSaturateScalar.Vector64.UInt16"] = ExtractNarrowingSaturateScalar_Vector64_UInt16, + ["ExtractNarrowingSaturateScalar.Vector64.UInt32"] = ExtractNarrowingSaturateScalar_Vector64_UInt32, + ["ExtractNarrowingSaturateUnsignedScalar.Vector64.Byte"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_Byte, + ["ExtractNarrowingSaturateUnsignedScalar.Vector64.UInt16"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt16, + ["ExtractNarrowingSaturateUnsignedScalar.Vector64.UInt32"] = ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt32, + ["Floor.Vector128.Double"] = Floor_Vector128_Double, + ["FusedMultiplyAdd.Vector128.Double"] = FusedMultiplyAdd_Vector128_Double, + ["FusedMultiplyAddByScalar.Vector64.Single"] = FusedMultiplyAddByScalar_Vector64_Single, + ["FusedMultiplyAddByScalar.Vector128.Double"] = FusedMultiplyAddByScalar_Vector128_Double, + ["FusedMultiplyAddByScalar.Vector128.Single"] = FusedMultiplyAddByScalar_Vector128_Single, + ["FusedMultiplyAddBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["FusedMultiplyAddBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["FusedMultiplyAddBySelectedScalar.Vector128.Double.Vector128.Double.1"] = FusedMultiplyAddBySelectedScalar_Vector128_Double_Vector128_Double_1, + ["FusedMultiplyAddBySelectedScalar.Vector128.Single.Vector64.Single.1"] = FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector64_Single_1, + ["FusedMultiplyAddBySelectedScalar.Vector128.Single.Vector128.Single.3"] = FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector128_Single_3, + ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, + ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["FusedMultiplyAddScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["FusedMultiplySubtract.Vector128.Double"] = FusedMultiplySubtract_Vector128_Double, + ["FusedMultiplySubtractByScalar.Vector64.Single"] = FusedMultiplySubtractByScalar_Vector64_Single, + ["FusedMultiplySubtractByScalar.Vector128.Double"] = FusedMultiplySubtractByScalar_Vector128_Double, + ["FusedMultiplySubtractByScalar.Vector128.Single"] = FusedMultiplySubtractByScalar_Vector128_Single, + ["FusedMultiplySubtractBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["FusedMultiplySubtractBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["FusedMultiplySubtractBySelectedScalar.Vector128.Double.Vector128.Double.1"] = FusedMultiplySubtractBySelectedScalar_Vector128_Double_Vector128_Double_1, + ["FusedMultiplySubtractBySelectedScalar.Vector128.Single.Vector64.Single.1"] = FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector64_Single_1, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part2.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part2.cs index 934d1df2c4ed..29788e0053f1 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part2.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part2.cs @@ -11,82 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["TransposeOdd.Vector128.Single"] = TransposeOdd_Vector128_Single, - ["TransposeOdd.Vector128.UInt16"] = TransposeOdd_Vector128_UInt16, - ["TransposeOdd.Vector128.UInt32"] = TransposeOdd_Vector128_UInt32, - ["TransposeOdd.Vector128.UInt64"] = TransposeOdd_Vector128_UInt64, - ["VectorTableLookup.Vector128.Byte"] = VectorTableLookup_Vector128_Byte, - ["VectorTableLookup.Vector128.SByte"] = VectorTableLookup_Vector128_SByte, - ["VectorTableLookupExtension.Vector128.Byte"] = VectorTableLookupExtension_Vector128_Byte, - ["VectorTableLookupExtension.Vector128.SByte"] = VectorTableLookupExtension_Vector128_SByte, - ["UnzipEven.Vector64.Byte"] = UnzipEven_Vector64_Byte, - ["UnzipEven.Vector64.Int16"] = UnzipEven_Vector64_Int16, - ["UnzipEven.Vector64.Int32"] = UnzipEven_Vector64_Int32, - ["UnzipEven.Vector64.SByte"] = UnzipEven_Vector64_SByte, - ["UnzipEven.Vector64.Single"] = UnzipEven_Vector64_Single, - ["UnzipEven.Vector64.UInt16"] = UnzipEven_Vector64_UInt16, - ["UnzipEven.Vector64.UInt32"] = UnzipEven_Vector64_UInt32, - ["UnzipEven.Vector128.Byte"] = UnzipEven_Vector128_Byte, - ["UnzipEven.Vector128.Double"] = UnzipEven_Vector128_Double, - ["UnzipEven.Vector128.Int16"] = UnzipEven_Vector128_Int16, - ["UnzipEven.Vector128.Int32"] = UnzipEven_Vector128_Int32, - ["UnzipEven.Vector128.Int64"] = UnzipEven_Vector128_Int64, - ["UnzipEven.Vector128.SByte"] = UnzipEven_Vector128_SByte, - ["UnzipEven.Vector128.Single"] = UnzipEven_Vector128_Single, - ["UnzipEven.Vector128.UInt16"] = UnzipEven_Vector128_UInt16, - ["UnzipEven.Vector128.UInt32"] = UnzipEven_Vector128_UInt32, - ["UnzipEven.Vector128.UInt64"] = UnzipEven_Vector128_UInt64, - ["UnzipOdd.Vector64.Byte"] = UnzipOdd_Vector64_Byte, - ["UnzipOdd.Vector64.Int16"] = UnzipOdd_Vector64_Int16, - ["UnzipOdd.Vector64.Int32"] = UnzipOdd_Vector64_Int32, - ["UnzipOdd.Vector64.SByte"] = UnzipOdd_Vector64_SByte, - ["UnzipOdd.Vector64.Single"] = UnzipOdd_Vector64_Single, - ["UnzipOdd.Vector64.UInt16"] = UnzipOdd_Vector64_UInt16, - ["UnzipOdd.Vector64.UInt32"] = UnzipOdd_Vector64_UInt32, - ["UnzipOdd.Vector128.Byte"] = UnzipOdd_Vector128_Byte, - ["UnzipOdd.Vector128.Double"] = UnzipOdd_Vector128_Double, - ["UnzipOdd.Vector128.Int16"] = UnzipOdd_Vector128_Int16, - ["UnzipOdd.Vector128.Int32"] = UnzipOdd_Vector128_Int32, - ["UnzipOdd.Vector128.Int64"] = UnzipOdd_Vector128_Int64, - ["UnzipOdd.Vector128.SByte"] = UnzipOdd_Vector128_SByte, - ["UnzipOdd.Vector128.Single"] = UnzipOdd_Vector128_Single, - ["UnzipOdd.Vector128.UInt16"] = UnzipOdd_Vector128_UInt16, - ["UnzipOdd.Vector128.UInt32"] = UnzipOdd_Vector128_UInt32, - ["UnzipOdd.Vector128.UInt64"] = UnzipOdd_Vector128_UInt64, - ["ZipHigh.Vector64.Byte"] = ZipHigh_Vector64_Byte, - ["ZipHigh.Vector64.Int16"] = ZipHigh_Vector64_Int16, - ["ZipHigh.Vector64.Int32"] = ZipHigh_Vector64_Int32, - ["ZipHigh.Vector64.SByte"] = ZipHigh_Vector64_SByte, - ["ZipHigh.Vector64.Single"] = ZipHigh_Vector64_Single, - ["ZipHigh.Vector64.UInt16"] = ZipHigh_Vector64_UInt16, - ["ZipHigh.Vector64.UInt32"] = ZipHigh_Vector64_UInt32, - ["ZipHigh.Vector128.Byte"] = ZipHigh_Vector128_Byte, - ["ZipHigh.Vector128.Double"] = ZipHigh_Vector128_Double, - ["ZipHigh.Vector128.Int16"] = ZipHigh_Vector128_Int16, - ["ZipHigh.Vector128.Int32"] = ZipHigh_Vector128_Int32, - ["ZipHigh.Vector128.Int64"] = ZipHigh_Vector128_Int64, - ["ZipHigh.Vector128.SByte"] = ZipHigh_Vector128_SByte, - ["ZipHigh.Vector128.Single"] = ZipHigh_Vector128_Single, - ["ZipHigh.Vector128.UInt16"] = ZipHigh_Vector128_UInt16, - ["ZipHigh.Vector128.UInt32"] = ZipHigh_Vector128_UInt32, - ["ZipHigh.Vector128.UInt64"] = ZipHigh_Vector128_UInt64, - ["ZipLow.Vector64.Byte"] = ZipLow_Vector64_Byte, - ["ZipLow.Vector64.Int16"] = ZipLow_Vector64_Int16, - ["ZipLow.Vector64.Int32"] = ZipLow_Vector64_Int32, - ["ZipLow.Vector64.SByte"] = ZipLow_Vector64_SByte, - ["ZipLow.Vector64.Single"] = ZipLow_Vector64_Single, - ["ZipLow.Vector64.UInt16"] = ZipLow_Vector64_UInt16, - ["ZipLow.Vector64.UInt32"] = ZipLow_Vector64_UInt32, - ["ZipLow.Vector128.Byte"] = ZipLow_Vector128_Byte, - ["ZipLow.Vector128.Double"] = ZipLow_Vector128_Double, - ["ZipLow.Vector128.Int16"] = ZipLow_Vector128_Int16, - ["ZipLow.Vector128.Int32"] = ZipLow_Vector128_Int32, - ["ZipLow.Vector128.Int64"] = ZipLow_Vector128_Int64, - ["ZipLow.Vector128.SByte"] = ZipLow_Vector128_SByte, - ["ZipLow.Vector128.Single"] = ZipLow_Vector128_Single, - ["ZipLow.Vector128.UInt16"] = ZipLow_Vector128_UInt16, - ["ZipLow.Vector128.UInt32"] = ZipLow_Vector128_UInt32, - ["ZipLow.Vector128.UInt64"] = ZipLow_Vector128_UInt64, + ["FusedMultiplySubtractBySelectedScalar.Vector128.Single.Vector128.Single.3"] = FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector128_Single_3, + ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, + ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["FusedMultiplySubtractScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["InsertSelectedScalar.Vector64.Byte.7.Vector64.Byte.7"] = InsertSelectedScalar_Vector64_Byte_7_Vector64_Byte_7, + ["InsertSelectedScalar.Vector64.Byte.7.Vector128.Byte.15"] = InsertSelectedScalar_Vector64_Byte_7_Vector128_Byte_15, + ["InsertSelectedScalar.Vector64.Int16.3.Vector64.Int16.3"] = InsertSelectedScalar_Vector64_Int16_3_Vector64_Int16_3, + ["InsertSelectedScalar.Vector64.Int16.3.Vector128.Int16.7"] = InsertSelectedScalar_Vector64_Int16_3_Vector128_Int16_7, + ["InsertSelectedScalar.Vector64.Int32.1.Vector64.Int32.1"] = InsertSelectedScalar_Vector64_Int32_1_Vector64_Int32_1, + ["InsertSelectedScalar.Vector64.Int32.1.Vector128.Int32.3"] = InsertSelectedScalar_Vector64_Int32_1_Vector128_Int32_3, + ["InsertSelectedScalar.Vector64.SByte.7.Vector64.SByte.7"] = InsertSelectedScalar_Vector64_SByte_7_Vector64_SByte_7, + ["InsertSelectedScalar.Vector64.SByte.7.Vector128.SByte.15"] = InsertSelectedScalar_Vector64_SByte_7_Vector128_SByte_15, + ["InsertSelectedScalar.Vector64.Single.1.Vector64.Single.1"] = InsertSelectedScalar_Vector64_Single_1_Vector64_Single_1, + ["InsertSelectedScalar.Vector64.Single.1.Vector128.Single.3"] = InsertSelectedScalar_Vector64_Single_1_Vector128_Single_3, + ["InsertSelectedScalar.Vector64.UInt16.3.Vector64.UInt16.3"] = InsertSelectedScalar_Vector64_UInt16_3_Vector64_UInt16_3, + ["InsertSelectedScalar.Vector64.UInt16.3.Vector128.UInt16.7"] = InsertSelectedScalar_Vector64_UInt16_3_Vector128_UInt16_7, + ["InsertSelectedScalar.Vector64.UInt32.1.Vector64.UInt32.1"] = InsertSelectedScalar_Vector64_UInt32_1_Vector64_UInt32_1, + ["InsertSelectedScalar.Vector64.UInt32.1.Vector128.UInt32.3"] = InsertSelectedScalar_Vector64_UInt32_1_Vector128_UInt32_3, + ["InsertSelectedScalar.Vector128.Byte.15.Vector64.Byte.7"] = InsertSelectedScalar_Vector128_Byte_15_Vector64_Byte_7, + ["InsertSelectedScalar.Vector128.Byte.15.Vector128.Byte.15"] = InsertSelectedScalar_Vector128_Byte_15_Vector128_Byte_15, + ["InsertSelectedScalar.Vector128.Double.1.Vector128.Double.1"] = InsertSelectedScalar_Vector128_Double_1_Vector128_Double_1, + ["InsertSelectedScalar.Vector128.Int16.7.Vector64.Int16.3"] = InsertSelectedScalar_Vector128_Int16_7_Vector64_Int16_3, + ["InsertSelectedScalar.Vector128.Int16.7.Vector128.Int16.7"] = InsertSelectedScalar_Vector128_Int16_7_Vector128_Int16_7, + ["InsertSelectedScalar.Vector128.Int32.3.Vector64.Int32.1"] = InsertSelectedScalar_Vector128_Int32_3_Vector64_Int32_1, + ["InsertSelectedScalar.Vector128.Int32.3.Vector128.Int32.3"] = InsertSelectedScalar_Vector128_Int32_3_Vector128_Int32_3, + ["InsertSelectedScalar.Vector128.Int64.1.Vector128.Int64.1"] = InsertSelectedScalar_Vector128_Int64_1_Vector128_Int64_1, + ["InsertSelectedScalar.Vector128.SByte.15.Vector64.SByte.7"] = InsertSelectedScalar_Vector128_SByte_15_Vector64_SByte_7, + ["InsertSelectedScalar.Vector128.SByte.15.Vector128.SByte.15"] = InsertSelectedScalar_Vector128_SByte_15_Vector128_SByte_15, + ["InsertSelectedScalar.Vector128.Single.3.Vector64.Single.1"] = InsertSelectedScalar_Vector128_Single_3_Vector64_Single_1, + ["InsertSelectedScalar.Vector128.Single.3.Vector128.Single.3"] = InsertSelectedScalar_Vector128_Single_3_Vector128_Single_3, + ["InsertSelectedScalar.Vector128.UInt16.7.Vector64.UInt16.3"] = InsertSelectedScalar_Vector128_UInt16_7_Vector64_UInt16_3, + ["InsertSelectedScalar.Vector128.UInt16.7.Vector128.UInt16.7"] = InsertSelectedScalar_Vector128_UInt16_7_Vector128_UInt16_7, + ["InsertSelectedScalar.Vector128.UInt32.3.Vector64.UInt32.1"] = InsertSelectedScalar_Vector128_UInt32_3_Vector64_UInt32_1, + ["InsertSelectedScalar.Vector128.UInt32.3.Vector128.UInt32.3"] = InsertSelectedScalar_Vector128_UInt32_3_Vector128_UInt32_3, + ["InsertSelectedScalar.Vector128.UInt64.1.Vector128.UInt64.1"] = InsertSelectedScalar_Vector128_UInt64_1_Vector128_UInt64_1, + ["LoadAndReplicateToVector128.Double"] = LoadAndReplicateToVector128_Double, + ["LoadAndReplicateToVector128.Int64"] = LoadAndReplicateToVector128_Int64, + ["LoadAndReplicateToVector128.UInt64"] = LoadAndReplicateToVector128_UInt64, + ["Max.Vector128.Double"] = Max_Vector128_Double, + ["MaxAcross.Vector64.Byte"] = MaxAcross_Vector64_Byte, + ["MaxAcross.Vector64.Int16"] = MaxAcross_Vector64_Int16, + ["MaxAcross.Vector64.SByte"] = MaxAcross_Vector64_SByte, + ["MaxAcross.Vector64.UInt16"] = MaxAcross_Vector64_UInt16, + ["MaxAcross.Vector128.Byte"] = MaxAcross_Vector128_Byte, + ["MaxAcross.Vector128.Int16"] = MaxAcross_Vector128_Int16, + ["MaxAcross.Vector128.Int32"] = MaxAcross_Vector128_Int32, + ["MaxAcross.Vector128.SByte"] = MaxAcross_Vector128_SByte, + ["MaxAcross.Vector128.Single"] = MaxAcross_Vector128_Single, + ["MaxAcross.Vector128.UInt16"] = MaxAcross_Vector128_UInt16, + ["MaxAcross.Vector128.UInt32"] = MaxAcross_Vector128_UInt32, + ["MaxNumber.Vector128.Double"] = MaxNumber_Vector128_Double, + ["MaxNumberAcross.Vector128.Single"] = MaxNumberAcross_Vector128_Single, + ["MaxNumberPairwise.Vector64.Single"] = MaxNumberPairwise_Vector64_Single, + ["MaxNumberPairwise.Vector128.Double"] = MaxNumberPairwise_Vector128_Double, + ["MaxNumberPairwise.Vector128.Single"] = MaxNumberPairwise_Vector128_Single, + ["MaxNumberPairwiseScalar.Vector64.Single"] = MaxNumberPairwiseScalar_Vector64_Single, + ["MaxNumberPairwiseScalar.Vector128.Double"] = MaxNumberPairwiseScalar_Vector128_Double, + ["MaxPairwise.Vector128.Byte"] = MaxPairwise_Vector128_Byte, + ["MaxPairwise.Vector128.Double"] = MaxPairwise_Vector128_Double, + ["MaxPairwise.Vector128.Int16"] = MaxPairwise_Vector128_Int16, + ["MaxPairwise.Vector128.Int32"] = MaxPairwise_Vector128_Int32, + ["MaxPairwise.Vector128.SByte"] = MaxPairwise_Vector128_SByte, + ["MaxPairwise.Vector128.Single"] = MaxPairwise_Vector128_Single, + ["MaxPairwise.Vector128.UInt16"] = MaxPairwise_Vector128_UInt16, + ["MaxPairwise.Vector128.UInt32"] = MaxPairwise_Vector128_UInt32, + ["MaxPairwiseScalar.Vector64.Single"] = MaxPairwiseScalar_Vector64_Single, + ["MaxPairwiseScalar.Vector128.Double"] = MaxPairwiseScalar_Vector128_Double, + ["MaxScalar.Vector64.Double"] = MaxScalar_Vector64_Double, + ["MaxScalar.Vector64.Single"] = MaxScalar_Vector64_Single, + ["Min.Vector128.Double"] = Min_Vector128_Double, + ["MinAcross.Vector64.Byte"] = MinAcross_Vector64_Byte, + ["MinAcross.Vector64.Int16"] = MinAcross_Vector64_Int16, + ["MinAcross.Vector64.SByte"] = MinAcross_Vector64_SByte, + ["MinAcross.Vector64.UInt16"] = MinAcross_Vector64_UInt16, + ["MinAcross.Vector128.Byte"] = MinAcross_Vector128_Byte, + ["MinAcross.Vector128.Int16"] = MinAcross_Vector128_Int16, + ["MinAcross.Vector128.Int32"] = MinAcross_Vector128_Int32, + ["MinAcross.Vector128.SByte"] = MinAcross_Vector128_SByte, + ["MinAcross.Vector128.Single"] = MinAcross_Vector128_Single, + ["MinAcross.Vector128.UInt16"] = MinAcross_Vector128_UInt16, + ["MinAcross.Vector128.UInt32"] = MinAcross_Vector128_UInt32, + ["MinNumber.Vector128.Double"] = MinNumber_Vector128_Double, + ["MinNumberAcross.Vector128.Single"] = MinNumberAcross_Vector128_Single, + ["MinNumberPairwise.Vector64.Single"] = MinNumberPairwise_Vector64_Single, + ["MinNumberPairwise.Vector128.Double"] = MinNumberPairwise_Vector128_Double, + ["MinNumberPairwise.Vector128.Single"] = MinNumberPairwise_Vector128_Single, + ["MinNumberPairwiseScalar.Vector64.Single"] = MinNumberPairwiseScalar_Vector64_Single, + ["MinNumberPairwiseScalar.Vector128.Double"] = MinNumberPairwiseScalar_Vector128_Double, + ["MinPairwise.Vector128.Byte"] = MinPairwise_Vector128_Byte, + ["MinPairwise.Vector128.Double"] = MinPairwise_Vector128_Double, + ["MinPairwise.Vector128.Int16"] = MinPairwise_Vector128_Int16, + ["MinPairwise.Vector128.Int32"] = MinPairwise_Vector128_Int32, + ["MinPairwise.Vector128.SByte"] = MinPairwise_Vector128_SByte, + ["MinPairwise.Vector128.Single"] = MinPairwise_Vector128_Single, + ["MinPairwise.Vector128.UInt16"] = MinPairwise_Vector128_UInt16, + ["MinPairwise.Vector128.UInt32"] = MinPairwise_Vector128_UInt32, + ["MinPairwiseScalar.Vector64.Single"] = MinPairwiseScalar_Vector64_Single, + ["MinPairwiseScalar.Vector128.Double"] = MinPairwiseScalar_Vector128_Double, + ["MinScalar.Vector64.Double"] = MinScalar_Vector64_Double, + ["MinScalar.Vector64.Single"] = MinScalar_Vector64_Single, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part3.cs new file mode 100644 index 000000000000..c7c238a050d7 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part3.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["Multiply.Vector128.Double"] = Multiply_Vector128_Double, + ["MultiplyByScalar.Vector128.Double"] = MultiplyByScalar_Vector128_Double, + ["MultiplyBySelectedScalar.Vector128.Double.Vector128.Double.1"] = MultiplyBySelectedScalar_Vector128_Double_Vector128_Double_1, + ["MultiplyDoublingSaturateHighScalar.Vector64.Int16"] = MultiplyDoublingSaturateHighScalar_Vector64_Int16, + ["MultiplyDoublingSaturateHighScalar.Vector64.Int32"] = MultiplyDoublingSaturateHighScalar_Vector64_Int32, + ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningAndAddSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int16, + ["MultiplyDoublingWideningAndAddSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int32, + ["MultiplyDoublingWideningAndSubtractSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int16, + ["MultiplyDoublingWideningAndSubtractSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int32, + ["MultiplyDoublingWideningSaturateScalar.Vector64.Int16"] = MultiplyDoublingWideningSaturateScalar_Vector64_Int16, + ["MultiplyDoublingWideningSaturateScalar.Vector64.Int32"] = MultiplyDoublingWideningSaturateScalar_Vector64_Int32, + ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningSaturateScalarBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3, + ["MultiplyExtended.Vector64.Single"] = MultiplyExtended_Vector64_Single, + ["MultiplyExtended.Vector128.Double"] = MultiplyExtended_Vector128_Double, + ["MultiplyExtended.Vector128.Single"] = MultiplyExtended_Vector128_Single, + ["MultiplyExtendedByScalar.Vector128.Double"] = MultiplyExtendedByScalar_Vector128_Double, + ["MultiplyExtendedBySelectedScalar.Vector128.Double.Vector128.Double.1"] = MultiplyExtendedBySelectedScalar_Vector128_Double_Vector128_Double_1, + ["MultiplyExtendedScalar.Vector64.Double"] = MultiplyExtendedScalar_Vector64_Double, + ["MultiplyExtendedScalar.Vector64.Single"] = MultiplyExtendedScalar_Vector64_Single, + ["MultiplyExtendedScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, + ["MultiplyExtendedScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["MultiplyExtendedScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["MultiplyRoundedDoublingSaturateHighScalar.Vector64.Int16"] = MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int16, + ["MultiplyRoundedDoublingSaturateHighScalar.Vector64.Int32"] = MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int32, + ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, + ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, + ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, + ["MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, + ["MultiplyScalarBySelectedScalar.Vector64.Double.Vector128.Double.1"] = MultiplyScalarBySelectedScalar_Vector64_Double_Vector128_Double_1, + ["Negate.Vector128.Double"] = Negate_Vector128_Double, + ["Negate.Vector128.Int64"] = Negate_Vector128_Int64, + ["NegateSaturate.Vector128.Int64"] = NegateSaturate_Vector128_Int64, + ["NegateSaturateScalar.Vector64.Int16"] = NegateSaturateScalar_Vector64_Int16, + ["NegateSaturateScalar.Vector64.Int32"] = NegateSaturateScalar_Vector64_Int32, + ["NegateSaturateScalar.Vector64.Int64"] = NegateSaturateScalar_Vector64_Int64, + ["NegateSaturateScalar.Vector64.SByte"] = NegateSaturateScalar_Vector64_SByte, + ["NegateScalar.Vector64.Int64"] = NegateScalar_Vector64_Int64, + ["ReciprocalEstimate.Vector128.Double"] = ReciprocalEstimate_Vector128_Double, + ["ReciprocalEstimateScalar.Vector64.Double"] = ReciprocalEstimateScalar_Vector64_Double, + ["ReciprocalEstimateScalar.Vector64.Single"] = ReciprocalEstimateScalar_Vector64_Single, + ["ReciprocalExponentScalar.Vector64.Double"] = ReciprocalExponentScalar_Vector64_Double, + ["ReciprocalExponentScalar.Vector64.Single"] = ReciprocalExponentScalar_Vector64_Single, + ["ReciprocalSquareRootEstimate.Vector128.Double"] = ReciprocalSquareRootEstimate_Vector128_Double, + ["ReciprocalSquareRootEstimateScalar.Vector64.Double"] = ReciprocalSquareRootEstimateScalar_Vector64_Double, + ["ReciprocalSquareRootEstimateScalar.Vector64.Single"] = ReciprocalSquareRootEstimateScalar_Vector64_Single, + ["ReciprocalSquareRootStep.Vector128.Double"] = ReciprocalSquareRootStep_Vector128_Double, + ["ReciprocalSquareRootStepScalar.Vector64.Double"] = ReciprocalSquareRootStepScalar_Vector64_Double, + ["ReciprocalSquareRootStepScalar.Vector64.Single"] = ReciprocalSquareRootStepScalar_Vector64_Single, + ["ReciprocalStep.Vector128.Double"] = ReciprocalStep_Vector128_Double, + ["ReciprocalStepScalar.Vector64.Double"] = ReciprocalStepScalar_Vector64_Double, + ["ReciprocalStepScalar.Vector64.Single"] = ReciprocalStepScalar_Vector64_Single, + ["ReverseElementBits.Vector128.Byte"] = ReverseElementBits_Vector128_Byte, + ["ReverseElementBits.Vector128.SByte"] = ReverseElementBits_Vector128_SByte, + ["ReverseElementBits.Vector64.Byte"] = ReverseElementBits_Vector64_Byte, + ["ReverseElementBits.Vector64.SByte"] = ReverseElementBits_Vector64_SByte, + ["RoundAwayFromZero.Vector128.Double"] = RoundAwayFromZero_Vector128_Double, + ["RoundToNearest.Vector128.Double"] = RoundToNearest_Vector128_Double, + ["RoundToNegativeInfinity.Vector128.Double"] = RoundToNegativeInfinity_Vector128_Double, + ["RoundToPositiveInfinity.Vector128.Double"] = RoundToPositiveInfinity_Vector128_Double, + ["RoundToZero.Vector128.Double"] = RoundToZero_Vector128_Double, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int16"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int16, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int32"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int32, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.SByte"] = ShiftArithmeticRoundedSaturateScalar_Vector64_SByte, + ["ShiftArithmeticSaturateScalar.Vector64.Int16"] = ShiftArithmeticSaturateScalar_Vector64_Int16, + ["ShiftArithmeticSaturateScalar.Vector64.Int32"] = ShiftArithmeticSaturateScalar_Vector64_Int32, + ["ShiftArithmeticSaturateScalar.Vector64.SByte"] = ShiftArithmeticSaturateScalar_Vector64_SByte, + ["ShiftLeftLogicalSaturateScalar.Vector64.Byte.7"] = ShiftLeftLogicalSaturateScalar_Vector64_Byte_7, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int16.15"] = ShiftLeftLogicalSaturateScalar_Vector64_Int16_15, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int32.31"] = ShiftLeftLogicalSaturateScalar_Vector64_Int32_31, + ["ShiftLeftLogicalSaturateScalar.Vector64.SByte.1"] = ShiftLeftLogicalSaturateScalar_Vector64_SByte_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Byte"] = ShiftLogicalRoundedSaturateScalar_Vector64_Byte, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int16"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int16, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int32"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int32, + ["ShiftLogicalRoundedSaturateScalar.Vector64.SByte"] = ShiftLogicalRoundedSaturateScalar_Vector64_SByte, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt16"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt16, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt32"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt32, + ["ShiftLogicalSaturateScalar.Vector64.Byte"] = ShiftLogicalSaturateScalar_Vector64_Byte, + ["ShiftLogicalSaturateScalar.Vector64.Int16"] = ShiftLogicalSaturateScalar_Vector64_Int16, + ["ShiftLogicalSaturateScalar.Vector64.Int32"] = ShiftLogicalSaturateScalar_Vector64_Int32, + ["ShiftLogicalSaturateScalar.Vector64.SByte"] = ShiftLogicalSaturateScalar_Vector64_SByte, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part4.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part4.cs new file mode 100644 index 000000000000..af2a7dcb3c8a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part4.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["ShiftLogicalSaturateScalar.Vector64.UInt16"] = ShiftLogicalSaturateScalar_Vector64_UInt16, + ["ShiftLogicalSaturateScalar.Vector64.UInt32"] = ShiftLogicalSaturateScalar_Vector64_UInt32, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1, + ["Sqrt.Vector64.Single"] = Sqrt_Vector64_Single, + ["Sqrt.Vector128.Double"] = Sqrt_Vector128_Double, + ["Sqrt.Vector128.Single"] = Sqrt_Vector128_Single, + ["StorePair.Vector64.Byte"] = StorePair_Vector64_Byte, + ["StorePair.Vector64.Double"] = StorePair_Vector64_Double, + ["StorePair.Vector64.Int16"] = StorePair_Vector64_Int16, + ["StorePair.Vector64.Int32"] = StorePair_Vector64_Int32, + ["StorePair.Vector64.Int64"] = StorePair_Vector64_Int64, + ["StorePair.Vector64.SByte"] = StorePair_Vector64_SByte, + ["StorePair.Vector64.Single"] = StorePair_Vector64_Single, + ["StorePair.Vector64.UInt16"] = StorePair_Vector64_UInt16, + ["StorePair.Vector64.UInt32"] = StorePair_Vector64_UInt32, + ["StorePair.Vector64.UInt64"] = StorePair_Vector64_UInt64, + ["StorePair.Vector128.Byte"] = StorePair_Vector128_Byte, + ["StorePair.Vector128.Double"] = StorePair_Vector128_Double, + ["StorePair.Vector128.Int16"] = StorePair_Vector128_Int16, + ["StorePair.Vector128.Int32"] = StorePair_Vector128_Int32, + ["StorePair.Vector128.Int64"] = StorePair_Vector128_Int64, + ["StorePair.Vector128.SByte"] = StorePair_Vector128_SByte, + ["StorePair.Vector128.Single"] = StorePair_Vector128_Single, + ["StorePair.Vector128.UInt16"] = StorePair_Vector128_UInt16, + ["StorePair.Vector128.UInt32"] = StorePair_Vector128_UInt32, + ["StorePair.Vector128.UInt64"] = StorePair_Vector128_UInt64, + ["StorePairScalar.Vector64.Int32"] = StorePairScalar_Vector64_Int32, + ["StorePairScalar.Vector64.Single"] = StorePairScalar_Vector64_Single, + ["StorePairScalar.Vector64.UInt32"] = StorePairScalar_Vector64_UInt32, + ["StorePairScalarNonTemporal.Vector64.Int32"] = StorePairScalarNonTemporal_Vector64_Int32, + ["StorePairScalarNonTemporal.Vector64.Single"] = StorePairScalarNonTemporal_Vector64_Single, + ["StorePairScalarNonTemporal.Vector64.UInt32"] = StorePairScalarNonTemporal_Vector64_UInt32, + ["StorePairNonTemporal.Vector64.Byte"] = StorePairNonTemporal_Vector64_Byte, + ["StorePairNonTemporal.Vector64.Double"] = StorePairNonTemporal_Vector64_Double, + ["StorePairNonTemporal.Vector64.Int16"] = StorePairNonTemporal_Vector64_Int16, + ["StorePairNonTemporal.Vector64.Int32"] = StorePairNonTemporal_Vector64_Int32, + ["StorePairNonTemporal.Vector64.Int64"] = StorePairNonTemporal_Vector64_Int64, + ["StorePairNonTemporal.Vector64.SByte"] = StorePairNonTemporal_Vector64_SByte, + ["StorePairNonTemporal.Vector64.Single"] = StorePairNonTemporal_Vector64_Single, + ["StorePairNonTemporal.Vector64.UInt16"] = StorePairNonTemporal_Vector64_UInt16, + ["StorePairNonTemporal.Vector64.UInt32"] = StorePairNonTemporal_Vector64_UInt32, + ["StorePairNonTemporal.Vector64.UInt64"] = StorePairNonTemporal_Vector64_UInt64, + ["StorePairNonTemporal.Vector128.Byte"] = StorePairNonTemporal_Vector128_Byte, + ["StorePairNonTemporal.Vector128.Double"] = StorePairNonTemporal_Vector128_Double, + ["StorePairNonTemporal.Vector128.Int16"] = StorePairNonTemporal_Vector128_Int16, + ["StorePairNonTemporal.Vector128.Int32"] = StorePairNonTemporal_Vector128_Int32, + ["StorePairNonTemporal.Vector128.Int64"] = StorePairNonTemporal_Vector128_Int64, + ["StorePairNonTemporal.Vector128.SByte"] = StorePairNonTemporal_Vector128_SByte, + ["StorePairNonTemporal.Vector128.Single"] = StorePairNonTemporal_Vector128_Single, + ["StorePairNonTemporal.Vector128.UInt16"] = StorePairNonTemporal_Vector128_UInt16, + ["StorePairNonTemporal.Vector128.UInt32"] = StorePairNonTemporal_Vector128_UInt32, + ["StorePairNonTemporal.Vector128.UInt64"] = StorePairNonTemporal_Vector128_UInt64, + ["Subtract.Vector128.Double"] = Subtract_Vector128_Double, + ["SubtractSaturateScalar.Vector64.Byte"] = SubtractSaturateScalar_Vector64_Byte, + ["SubtractSaturateScalar.Vector64.Int16"] = SubtractSaturateScalar_Vector64_Int16, + ["SubtractSaturateScalar.Vector64.Int32"] = SubtractSaturateScalar_Vector64_Int32, + ["SubtractSaturateScalar.Vector64.SByte"] = SubtractSaturateScalar_Vector64_SByte, + ["SubtractSaturateScalar.Vector64.UInt16"] = SubtractSaturateScalar_Vector64_UInt16, + ["SubtractSaturateScalar.Vector64.UInt32"] = SubtractSaturateScalar_Vector64_UInt32, + ["TransposeEven.Vector64.Byte"] = TransposeEven_Vector64_Byte, + ["TransposeEven.Vector64.Int16"] = TransposeEven_Vector64_Int16, + ["TransposeEven.Vector64.Int32"] = TransposeEven_Vector64_Int32, + ["TransposeEven.Vector64.SByte"] = TransposeEven_Vector64_SByte, + ["TransposeEven.Vector64.Single"] = TransposeEven_Vector64_Single, + ["TransposeEven.Vector64.UInt16"] = TransposeEven_Vector64_UInt16, + ["TransposeEven.Vector64.UInt32"] = TransposeEven_Vector64_UInt32, + ["TransposeEven.Vector128.Byte"] = TransposeEven_Vector128_Byte, + ["TransposeEven.Vector128.Double"] = TransposeEven_Vector128_Double, + ["TransposeEven.Vector128.Int16"] = TransposeEven_Vector128_Int16, + ["TransposeEven.Vector128.Int32"] = TransposeEven_Vector128_Int32, + ["TransposeEven.Vector128.Int64"] = TransposeEven_Vector128_Int64, + ["TransposeEven.Vector128.SByte"] = TransposeEven_Vector128_SByte, + ["TransposeEven.Vector128.Single"] = TransposeEven_Vector128_Single, + ["TransposeEven.Vector128.UInt16"] = TransposeEven_Vector128_UInt16, + ["TransposeEven.Vector128.UInt32"] = TransposeEven_Vector128_UInt32, + ["TransposeEven.Vector128.UInt64"] = TransposeEven_Vector128_UInt64, + ["TransposeOdd.Vector64.Byte"] = TransposeOdd_Vector64_Byte, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part5.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part5.cs new file mode 100644 index 000000000000..ce885756d0e3 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64_Part5.cs @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["TransposeOdd.Vector64.Int16"] = TransposeOdd_Vector64_Int16, + ["TransposeOdd.Vector64.Int32"] = TransposeOdd_Vector64_Int32, + ["TransposeOdd.Vector64.SByte"] = TransposeOdd_Vector64_SByte, + ["TransposeOdd.Vector64.Single"] = TransposeOdd_Vector64_Single, + ["TransposeOdd.Vector64.UInt16"] = TransposeOdd_Vector64_UInt16, + ["TransposeOdd.Vector64.UInt32"] = TransposeOdd_Vector64_UInt32, + ["TransposeOdd.Vector128.Byte"] = TransposeOdd_Vector128_Byte, + ["TransposeOdd.Vector128.Double"] = TransposeOdd_Vector128_Double, + ["TransposeOdd.Vector128.Int16"] = TransposeOdd_Vector128_Int16, + ["TransposeOdd.Vector128.Int32"] = TransposeOdd_Vector128_Int32, + ["TransposeOdd.Vector128.Int64"] = TransposeOdd_Vector128_Int64, + ["TransposeOdd.Vector128.SByte"] = TransposeOdd_Vector128_SByte, + ["TransposeOdd.Vector128.Single"] = TransposeOdd_Vector128_Single, + ["TransposeOdd.Vector128.UInt16"] = TransposeOdd_Vector128_UInt16, + ["TransposeOdd.Vector128.UInt32"] = TransposeOdd_Vector128_UInt32, + ["TransposeOdd.Vector128.UInt64"] = TransposeOdd_Vector128_UInt64, + ["VectorTableLookup.Vector128.Byte"] = VectorTableLookup_Vector128_Byte, + ["VectorTableLookup.Vector128.SByte"] = VectorTableLookup_Vector128_SByte, + ["VectorTableLookupExtension.Vector128.Byte"] = VectorTableLookupExtension_Vector128_Byte, + ["VectorTableLookupExtension.Vector128.SByte"] = VectorTableLookupExtension_Vector128_SByte, + ["UnzipEven.Vector64.Byte"] = UnzipEven_Vector64_Byte, + ["UnzipEven.Vector64.Int16"] = UnzipEven_Vector64_Int16, + ["UnzipEven.Vector64.Int32"] = UnzipEven_Vector64_Int32, + ["UnzipEven.Vector64.SByte"] = UnzipEven_Vector64_SByte, + ["UnzipEven.Vector64.Single"] = UnzipEven_Vector64_Single, + ["UnzipEven.Vector64.UInt16"] = UnzipEven_Vector64_UInt16, + ["UnzipEven.Vector64.UInt32"] = UnzipEven_Vector64_UInt32, + ["UnzipEven.Vector128.Byte"] = UnzipEven_Vector128_Byte, + ["UnzipEven.Vector128.Double"] = UnzipEven_Vector128_Double, + ["UnzipEven.Vector128.Int16"] = UnzipEven_Vector128_Int16, + ["UnzipEven.Vector128.Int32"] = UnzipEven_Vector128_Int32, + ["UnzipEven.Vector128.Int64"] = UnzipEven_Vector128_Int64, + ["UnzipEven.Vector128.SByte"] = UnzipEven_Vector128_SByte, + ["UnzipEven.Vector128.Single"] = UnzipEven_Vector128_Single, + ["UnzipEven.Vector128.UInt16"] = UnzipEven_Vector128_UInt16, + ["UnzipEven.Vector128.UInt32"] = UnzipEven_Vector128_UInt32, + ["UnzipEven.Vector128.UInt64"] = UnzipEven_Vector128_UInt64, + ["UnzipOdd.Vector64.Byte"] = UnzipOdd_Vector64_Byte, + ["UnzipOdd.Vector64.Int16"] = UnzipOdd_Vector64_Int16, + ["UnzipOdd.Vector64.Int32"] = UnzipOdd_Vector64_Int32, + ["UnzipOdd.Vector64.SByte"] = UnzipOdd_Vector64_SByte, + ["UnzipOdd.Vector64.Single"] = UnzipOdd_Vector64_Single, + ["UnzipOdd.Vector64.UInt16"] = UnzipOdd_Vector64_UInt16, + ["UnzipOdd.Vector64.UInt32"] = UnzipOdd_Vector64_UInt32, + ["UnzipOdd.Vector128.Byte"] = UnzipOdd_Vector128_Byte, + ["UnzipOdd.Vector128.Double"] = UnzipOdd_Vector128_Double, + ["UnzipOdd.Vector128.Int16"] = UnzipOdd_Vector128_Int16, + ["UnzipOdd.Vector128.Int32"] = UnzipOdd_Vector128_Int32, + ["UnzipOdd.Vector128.Int64"] = UnzipOdd_Vector128_Int64, + ["UnzipOdd.Vector128.SByte"] = UnzipOdd_Vector128_SByte, + ["UnzipOdd.Vector128.Single"] = UnzipOdd_Vector128_Single, + ["UnzipOdd.Vector128.UInt16"] = UnzipOdd_Vector128_UInt16, + ["UnzipOdd.Vector128.UInt32"] = UnzipOdd_Vector128_UInt32, + ["UnzipOdd.Vector128.UInt64"] = UnzipOdd_Vector128_UInt64, + ["ZipHigh.Vector64.Byte"] = ZipHigh_Vector64_Byte, + ["ZipHigh.Vector64.Int16"] = ZipHigh_Vector64_Int16, + ["ZipHigh.Vector64.Int32"] = ZipHigh_Vector64_Int32, + ["ZipHigh.Vector64.SByte"] = ZipHigh_Vector64_SByte, + ["ZipHigh.Vector64.Single"] = ZipHigh_Vector64_Single, + ["ZipHigh.Vector64.UInt16"] = ZipHigh_Vector64_UInt16, + ["ZipHigh.Vector64.UInt32"] = ZipHigh_Vector64_UInt32, + ["ZipHigh.Vector128.Byte"] = ZipHigh_Vector128_Byte, + ["ZipHigh.Vector128.Double"] = ZipHigh_Vector128_Double, + ["ZipHigh.Vector128.Int16"] = ZipHigh_Vector128_Int16, + ["ZipHigh.Vector128.Int32"] = ZipHigh_Vector128_Int32, + ["ZipHigh.Vector128.Int64"] = ZipHigh_Vector128_Int64, + ["ZipHigh.Vector128.SByte"] = ZipHigh_Vector128_SByte, + ["ZipHigh.Vector128.Single"] = ZipHigh_Vector128_Single, + ["ZipHigh.Vector128.UInt16"] = ZipHigh_Vector128_UInt16, + ["ZipHigh.Vector128.UInt32"] = ZipHigh_Vector128_UInt32, + ["ZipHigh.Vector128.UInt64"] = ZipHigh_Vector128_UInt64, + ["ZipLow.Vector64.Byte"] = ZipLow_Vector64_Byte, + ["ZipLow.Vector64.Int16"] = ZipLow_Vector64_Int16, + ["ZipLow.Vector64.Int32"] = ZipLow_Vector64_Int32, + ["ZipLow.Vector64.SByte"] = ZipLow_Vector64_SByte, + ["ZipLow.Vector64.Single"] = ZipLow_Vector64_Single, + ["ZipLow.Vector64.UInt16"] = ZipLow_Vector64_UInt16, + ["ZipLow.Vector64.UInt32"] = ZipLow_Vector64_UInt32, + ["ZipLow.Vector128.Byte"] = ZipLow_Vector128_Byte, + ["ZipLow.Vector128.Double"] = ZipLow_Vector128_Double, + ["ZipLow.Vector128.Int16"] = ZipLow_Vector128_Int16, + ["ZipLow.Vector128.Int32"] = ZipLow_Vector128_Int32, + ["ZipLow.Vector128.Int64"] = ZipLow_Vector128_Int64, + ["ZipLow.Vector128.SByte"] = ZipLow_Vector128_SByte, + ["ZipLow.Vector128.Single"] = ZipLow_Vector128_Single, + ["ZipLow.Vector128.UInt16"] = ZipLow_Vector128_UInt16, + ["ZipLow.Vector128.UInt32"] = ZipLow_Vector128_UInt32, + ["ZipLow.Vector128.UInt64"] = ZipLow_Vector128_UInt64, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_r.csproj index ed472d13f75b..30921c19c3c9 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_r.csproj @@ -108,162 +108,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_ro.csproj index 9297df20bf21..9f046d28902e 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part0_ro.csproj @@ -108,162 +108,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_r.csproj new file mode 100644 index 000000000000..1ee091aa07c0 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_ro.csproj new file mode 100644 index 000000000000..7d7ee6e054ec --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part10_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_r.csproj new file mode 100644 index 000000000000..b13b25f71f1d --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_ro.csproj new file mode 100644 index 000000000000..83e4a310ec7a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part11_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_r.csproj new file mode 100644 index 000000000000..f71c7d338a62 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_ro.csproj new file mode 100644 index 000000000000..aded274dfb79 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part12_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_r.csproj new file mode 100644 index 000000000000..74c0e0c15227 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_ro.csproj new file mode 100644 index 000000000000..f68b360cc0e6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part13_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_r.csproj new file mode 100644 index 000000000000..2b56e4ab6d9b --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_ro.csproj new file mode 100644 index 000000000000..33fead32fa51 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part14_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_r.csproj new file mode 100644 index 000000000000..62fd34edfd0f --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_ro.csproj new file mode 100644 index 000000000000..543fe0ce0a95 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part15_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_r.csproj new file mode 100644 index 000000000000..d006f1a715fa --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_r.csproj @@ -0,0 +1,41 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_ro.csproj new file mode 100644 index 000000000000..6d7a4d719200 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part16_ro.csproj @@ -0,0 +1,41 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_r.csproj index 699642203c99..349739d80073 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_ro.csproj index 8a5e955447fe..91b69f03fca0 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part1_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_r.csproj index f4df25ca3c4d..4ac086c5eb00 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_ro.csproj index d81245d16163..8b0f3fb27112 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part2_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_r.csproj index 00b6e610dfdd..88f56816d3b9 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_ro.csproj index 2c7d1ddad6cb..22fbf089b59a 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part3_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_r.csproj index e2c69e920ab3..794d092b600f 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_ro.csproj index 6628ff090599..a7a1d2262d24 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part4_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_r.csproj index 1fbb4d7feafb..7745fa0bfc76 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_r.csproj @@ -8,262 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_ro.csproj index 64e7ed1f0f04..b1b57ae63e1a 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part5_ro.csproj @@ -8,262 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_r.csproj index f5045d7ad840..8ed0e6473f16 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_r.csproj @@ -8,96 +8,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_ro.csproj index 0058e654f449..0520b792032b 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part6_ro.csproj @@ -8,96 +8,106 @@ True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_r.csproj new file mode 100644 index 000000000000..1bb5d0489732 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_ro.csproj new file mode 100644 index 000000000000..9d9364a99220 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part7_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_r.csproj new file mode 100644 index 000000000000..b7465422babc --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_ro.csproj new file mode 100644 index 000000000000..ffbdf964e36c --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part8_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_r.csproj new file mode 100644 index 000000000000..83b39f57f192 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_r.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_ro.csproj new file mode 100644 index 000000000000..150cebc294ae --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_Part9_ro.csproj @@ -0,0 +1,115 @@ + + + Exe + true + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part0.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part0.cs index fab5e44f7d28..1447a3f7b612 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part0.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part0.cs @@ -111,162 +111,6 @@ static Program() ["AddHighNarrowingUpper.Vector128.Int16"] = AddHighNarrowingUpper_Vector128_Int16, ["AddHighNarrowingUpper.Vector128.Int32"] = AddHighNarrowingUpper_Vector128_Int32, ["AddHighNarrowingUpper.Vector128.SByte"] = AddHighNarrowingUpper_Vector128_SByte, - ["AddHighNarrowingUpper.Vector128.UInt16"] = AddHighNarrowingUpper_Vector128_UInt16, - ["AddHighNarrowingUpper.Vector128.UInt32"] = AddHighNarrowingUpper_Vector128_UInt32, - ["AddPairwise.Vector64.Byte"] = AddPairwise_Vector64_Byte, - ["AddPairwise.Vector64.Int16"] = AddPairwise_Vector64_Int16, - ["AddPairwise.Vector64.Int32"] = AddPairwise_Vector64_Int32, - ["AddPairwise.Vector64.SByte"] = AddPairwise_Vector64_SByte, - ["AddPairwise.Vector64.Single"] = AddPairwise_Vector64_Single, - ["AddPairwise.Vector64.UInt16"] = AddPairwise_Vector64_UInt16, - ["AddPairwise.Vector64.UInt32"] = AddPairwise_Vector64_UInt32, - ["AddPairwiseWidening.Vector64.Byte"] = AddPairwiseWidening_Vector64_Byte, - ["AddPairwiseWidening.Vector64.Int16"] = AddPairwiseWidening_Vector64_Int16, - ["AddPairwiseWidening.Vector64.SByte"] = AddPairwiseWidening_Vector64_SByte, - ["AddPairwiseWidening.Vector64.UInt16"] = AddPairwiseWidening_Vector64_UInt16, - ["AddPairwiseWidening.Vector128.Byte"] = AddPairwiseWidening_Vector128_Byte, - ["AddPairwiseWidening.Vector128.Int16"] = AddPairwiseWidening_Vector128_Int16, - ["AddPairwiseWidening.Vector128.Int32"] = AddPairwiseWidening_Vector128_Int32, - ["AddPairwiseWidening.Vector128.SByte"] = AddPairwiseWidening_Vector128_SByte, - ["AddPairwiseWidening.Vector128.UInt16"] = AddPairwiseWidening_Vector128_UInt16, - ["AddPairwiseWidening.Vector128.UInt32"] = AddPairwiseWidening_Vector128_UInt32, - ["AddPairwiseWideningAndAdd.Vector64.Byte"] = AddPairwiseWideningAndAdd_Vector64_Byte, - ["AddPairwiseWideningAndAdd.Vector64.Int16"] = AddPairwiseWideningAndAdd_Vector64_Int16, - ["AddPairwiseWideningAndAdd.Vector64.SByte"] = AddPairwiseWideningAndAdd_Vector64_SByte, - ["AddPairwiseWideningAndAdd.Vector64.UInt16"] = AddPairwiseWideningAndAdd_Vector64_UInt16, - ["AddPairwiseWideningAndAdd.Vector128.Byte"] = AddPairwiseWideningAndAdd_Vector128_Byte, - ["AddPairwiseWideningAndAdd.Vector128.Int16"] = AddPairwiseWideningAndAdd_Vector128_Int16, - ["AddPairwiseWideningAndAdd.Vector128.Int32"] = AddPairwiseWideningAndAdd_Vector128_Int32, - ["AddPairwiseWideningAndAdd.Vector128.SByte"] = AddPairwiseWideningAndAdd_Vector128_SByte, - ["AddPairwiseWideningAndAdd.Vector128.UInt16"] = AddPairwiseWideningAndAdd_Vector128_UInt16, - ["AddPairwiseWideningAndAdd.Vector128.UInt32"] = AddPairwiseWideningAndAdd_Vector128_UInt32, - ["AddPairwiseWideningAndAddScalar.Vector64.Int32"] = AddPairwiseWideningAndAddScalar_Vector64_Int32, - ["AddPairwiseWideningAndAddScalar.Vector64.UInt32"] = AddPairwiseWideningAndAddScalar_Vector64_UInt32, - ["AddPairwiseWideningScalar.Vector64.Int32"] = AddPairwiseWideningScalar_Vector64_Int32, - ["AddPairwiseWideningScalar.Vector64.UInt32"] = AddPairwiseWideningScalar_Vector64_UInt32, - ["AddRoundedHighNarrowingLower.Vector64.Byte"] = AddRoundedHighNarrowingLower_Vector64_Byte, - ["AddRoundedHighNarrowingLower.Vector64.Int16"] = AddRoundedHighNarrowingLower_Vector64_Int16, - ["AddRoundedHighNarrowingLower.Vector64.Int32"] = AddRoundedHighNarrowingLower_Vector64_Int32, - ["AddRoundedHighNarrowingLower.Vector64.SByte"] = AddRoundedHighNarrowingLower_Vector64_SByte, - ["AddRoundedHighNarrowingLower.Vector64.UInt16"] = AddRoundedHighNarrowingLower_Vector64_UInt16, - ["AddRoundedHighNarrowingLower.Vector64.UInt32"] = AddRoundedHighNarrowingLower_Vector64_UInt32, - ["AddRoundedHighNarrowingUpper.Vector128.Byte"] = AddRoundedHighNarrowingUpper_Vector128_Byte, - ["AddRoundedHighNarrowingUpper.Vector128.Int16"] = AddRoundedHighNarrowingUpper_Vector128_Int16, - ["AddRoundedHighNarrowingUpper.Vector128.Int32"] = AddRoundedHighNarrowingUpper_Vector128_Int32, - ["AddRoundedHighNarrowingUpper.Vector128.SByte"] = AddRoundedHighNarrowingUpper_Vector128_SByte, - ["AddRoundedHighNarrowingUpper.Vector128.UInt16"] = AddRoundedHighNarrowingUpper_Vector128_UInt16, - ["AddRoundedHighNarrowingUpper.Vector128.UInt32"] = AddRoundedHighNarrowingUpper_Vector128_UInt32, - ["AddSaturate.Vector64.Byte.Vector64.Byte"] = AddSaturate_Vector64_Byte_Vector64_Byte, - ["AddSaturate.Vector64.Int16.Vector64.Int16"] = AddSaturate_Vector64_Int16_Vector64_Int16, - ["AddSaturate.Vector64.Int32.Vector64.Int32"] = AddSaturate_Vector64_Int32_Vector64_Int32, - ["AddSaturate.Vector64.SByte.Vector64.SByte"] = AddSaturate_Vector64_SByte_Vector64_SByte, - ["AddSaturate.Vector64.UInt16.Vector64.UInt16"] = AddSaturate_Vector64_UInt16_Vector64_UInt16, - ["AddSaturate.Vector64.UInt32.Vector64.UInt32"] = AddSaturate_Vector64_UInt32_Vector64_UInt32, - ["AddSaturate.Vector128.Byte.Vector128.Byte"] = AddSaturate_Vector128_Byte_Vector128_Byte, - ["AddSaturate.Vector128.Int16.Vector128.Int16"] = AddSaturate_Vector128_Int16_Vector128_Int16, - ["AddSaturate.Vector128.Int32.Vector128.Int32"] = AddSaturate_Vector128_Int32_Vector128_Int32, - ["AddSaturate.Vector128.Int64.Vector128.Int64"] = AddSaturate_Vector128_Int64_Vector128_Int64, - ["AddSaturate.Vector128.SByte.Vector128.SByte"] = AddSaturate_Vector128_SByte_Vector128_SByte, - ["AddSaturate.Vector128.UInt16.Vector128.UInt16"] = AddSaturate_Vector128_UInt16_Vector128_UInt16, - ["AddSaturate.Vector128.UInt32.Vector128.UInt32"] = AddSaturate_Vector128_UInt32_Vector128_UInt32, - ["AddSaturate.Vector128.UInt64.Vector128.UInt64"] = AddSaturate_Vector128_UInt64_Vector128_UInt64, - ["AddSaturateScalar.Vector64.Int64.Vector64.Int64"] = AddSaturateScalar_Vector64_Int64_Vector64_Int64, - ["AddSaturateScalar.Vector64.UInt64.Vector64.UInt64"] = AddSaturateScalar_Vector64_UInt64_Vector64_UInt64, - ["AddScalar.Vector64.Double"] = AddScalar_Vector64_Double, - ["AddScalar.Vector64.Int64"] = AddScalar_Vector64_Int64, - ["AddScalar.Vector64.Single"] = AddScalar_Vector64_Single, - ["AddScalar.Vector64.UInt64"] = AddScalar_Vector64_UInt64, - ["AddWideningLower.Vector64.Byte"] = AddWideningLower_Vector64_Byte, - ["AddWideningLower.Vector64.Int16"] = AddWideningLower_Vector64_Int16, - ["AddWideningLower.Vector64.Int32"] = AddWideningLower_Vector64_Int32, - ["AddWideningLower.Vector64.SByte"] = AddWideningLower_Vector64_SByte, - ["AddWideningLower.Vector64.UInt16"] = AddWideningLower_Vector64_UInt16, - ["AddWideningLower.Vector64.UInt32"] = AddWideningLower_Vector64_UInt32, - ["AddWideningLower.Vector128.Int16"] = AddWideningLower_Vector128_Int16, - ["AddWideningLower.Vector128.Int32"] = AddWideningLower_Vector128_Int32, - ["AddWideningLower.Vector128.Int64"] = AddWideningLower_Vector128_Int64, - ["AddWideningLower.Vector128.UInt16"] = AddWideningLower_Vector128_UInt16, - ["AddWideningLower.Vector128.UInt32"] = AddWideningLower_Vector128_UInt32, - ["AddWideningLower.Vector128.UInt64"] = AddWideningLower_Vector128_UInt64, - ["AddWideningUpper.Vector128.Byte.Vector128.Byte"] = AddWideningUpper_Vector128_Byte_Vector128_Byte, - ["AddWideningUpper.Vector128.Int16.Vector128.Int16"] = AddWideningUpper_Vector128_Int16_Vector128_Int16, - ["AddWideningUpper.Vector128.Int16.Vector128.SByte"] = AddWideningUpper_Vector128_Int16_Vector128_SByte, - ["AddWideningUpper.Vector128.Int32.Vector128.Int16"] = AddWideningUpper_Vector128_Int32_Vector128_Int16, - ["AddWideningUpper.Vector128.Int32.Vector128.Int32"] = AddWideningUpper_Vector128_Int32_Vector128_Int32, - ["AddWideningUpper.Vector128.Int64.Vector128.Int32"] = AddWideningUpper_Vector128_Int64_Vector128_Int32, - ["AddWideningUpper.Vector128.SByte.Vector128.SByte"] = AddWideningUpper_Vector128_SByte_Vector128_SByte, - ["AddWideningUpper.Vector128.UInt16.Vector128.Byte"] = AddWideningUpper_Vector128_UInt16_Vector128_Byte, - ["AddWideningUpper.Vector128.UInt16.Vector128.UInt16"] = AddWideningUpper_Vector128_UInt16_Vector128_UInt16, - ["AddWideningUpper.Vector128.UInt32.Vector128.UInt16"] = AddWideningUpper_Vector128_UInt32_Vector128_UInt16, - ["AddWideningUpper.Vector128.UInt32.Vector128.UInt32"] = AddWideningUpper_Vector128_UInt32_Vector128_UInt32, - ["AddWideningUpper.Vector128.UInt64.Vector128.UInt32"] = AddWideningUpper_Vector128_UInt64_Vector128_UInt32, - ["And.Vector64.Byte"] = And_Vector64_Byte, - ["And.Vector64.Double"] = And_Vector64_Double, - ["And.Vector64.Int16"] = And_Vector64_Int16, - ["And.Vector64.Int32"] = And_Vector64_Int32, - ["And.Vector64.Int64"] = And_Vector64_Int64, - ["And.Vector64.SByte"] = And_Vector64_SByte, - ["And.Vector64.Single"] = And_Vector64_Single, - ["And.Vector64.UInt16"] = And_Vector64_UInt16, - ["And.Vector64.UInt32"] = And_Vector64_UInt32, - ["And.Vector64.UInt64"] = And_Vector64_UInt64, - ["And.Vector128.Byte"] = And_Vector128_Byte, - ["And.Vector128.Double"] = And_Vector128_Double, - ["And.Vector128.Int16"] = And_Vector128_Int16, - ["And.Vector128.Int32"] = And_Vector128_Int32, - ["And.Vector128.Int64"] = And_Vector128_Int64, - ["And.Vector128.SByte"] = And_Vector128_SByte, - ["And.Vector128.Single"] = And_Vector128_Single, - ["And.Vector128.UInt16"] = And_Vector128_UInt16, - ["And.Vector128.UInt32"] = And_Vector128_UInt32, - ["And.Vector128.UInt64"] = And_Vector128_UInt64, - ["BitwiseClear.Vector64.Byte"] = BitwiseClear_Vector64_Byte, - ["BitwiseClear.Vector64.Double"] = BitwiseClear_Vector64_Double, - ["BitwiseClear.Vector64.Int16"] = BitwiseClear_Vector64_Int16, - ["BitwiseClear.Vector64.Int32"] = BitwiseClear_Vector64_Int32, - ["BitwiseClear.Vector64.Int64"] = BitwiseClear_Vector64_Int64, - ["BitwiseClear.Vector64.SByte"] = BitwiseClear_Vector64_SByte, - ["BitwiseClear.Vector64.Single"] = BitwiseClear_Vector64_Single, - ["BitwiseClear.Vector64.UInt16"] = BitwiseClear_Vector64_UInt16, - ["BitwiseClear.Vector64.UInt32"] = BitwiseClear_Vector64_UInt32, - ["BitwiseClear.Vector64.UInt64"] = BitwiseClear_Vector64_UInt64, - ["BitwiseClear.Vector128.Byte"] = BitwiseClear_Vector128_Byte, - ["BitwiseClear.Vector128.Double"] = BitwiseClear_Vector128_Double, - ["BitwiseClear.Vector128.Int16"] = BitwiseClear_Vector128_Int16, - ["BitwiseClear.Vector128.Int32"] = BitwiseClear_Vector128_Int32, - ["BitwiseClear.Vector128.Int64"] = BitwiseClear_Vector128_Int64, - ["BitwiseClear.Vector128.SByte"] = BitwiseClear_Vector128_SByte, - ["BitwiseClear.Vector128.Single"] = BitwiseClear_Vector128_Single, - ["BitwiseClear.Vector128.UInt16"] = BitwiseClear_Vector128_UInt16, - ["BitwiseClear.Vector128.UInt32"] = BitwiseClear_Vector128_UInt32, - ["BitwiseClear.Vector128.UInt64"] = BitwiseClear_Vector128_UInt64, - ["BitwiseSelect.Vector64.Byte"] = BitwiseSelect_Vector64_Byte, - ["BitwiseSelect.Vector64.Double"] = BitwiseSelect_Vector64_Double, - ["BitwiseSelect.Vector64.Int16"] = BitwiseSelect_Vector64_Int16, - ["BitwiseSelect.Vector64.Int32"] = BitwiseSelect_Vector64_Int32, - ["BitwiseSelect.Vector64.Int64"] = BitwiseSelect_Vector64_Int64, - ["BitwiseSelect.Vector64.SByte"] = BitwiseSelect_Vector64_SByte, - ["BitwiseSelect.Vector64.Single"] = BitwiseSelect_Vector64_Single, - ["BitwiseSelect.Vector64.UInt16"] = BitwiseSelect_Vector64_UInt16, - ["BitwiseSelect.Vector64.UInt32"] = BitwiseSelect_Vector64_UInt32, - ["BitwiseSelect.Vector64.UInt64"] = BitwiseSelect_Vector64_UInt64, - ["BitwiseSelect.Vector128.Byte"] = BitwiseSelect_Vector128_Byte, - ["BitwiseSelect.Vector128.Double"] = BitwiseSelect_Vector128_Double, - ["BitwiseSelect.Vector128.Int16"] = BitwiseSelect_Vector128_Int16, - ["BitwiseSelect.Vector128.Int32"] = BitwiseSelect_Vector128_Int32, - ["BitwiseSelect.Vector128.Int64"] = BitwiseSelect_Vector128_Int64, - ["BitwiseSelect.Vector128.SByte"] = BitwiseSelect_Vector128_SByte, - ["BitwiseSelect.Vector128.Single"] = BitwiseSelect_Vector128_Single, - ["BitwiseSelect.Vector128.UInt16"] = BitwiseSelect_Vector128_UInt16, - ["BitwiseSelect.Vector128.UInt32"] = BitwiseSelect_Vector128_UInt32, - ["BitwiseSelect.Vector128.UInt64"] = BitwiseSelect_Vector128_UInt64, - ["Ceiling.Vector64.Single"] = Ceiling_Vector64_Single, - ["Ceiling.Vector128.Single"] = Ceiling_Vector128_Single, - ["CeilingScalar.Vector64.Double"] = CeilingScalar_Vector64_Double, - ["CeilingScalar.Vector64.Single"] = CeilingScalar_Vector64_Single, - ["CompareEqual.Vector64.Byte"] = CompareEqual_Vector64_Byte, - ["CompareEqual.Vector64.Int16"] = CompareEqual_Vector64_Int16, - ["CompareEqual.Vector64.Int32"] = CompareEqual_Vector64_Int32, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part1.cs index 8531f089d99d..d2886e40f366 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part1.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["CompareEqual.Vector64.SByte"] = CompareEqual_Vector64_SByte, - ["CompareEqual.Vector64.Single"] = CompareEqual_Vector64_Single, - ["CompareEqual.Vector64.UInt16"] = CompareEqual_Vector64_UInt16, - ["CompareEqual.Vector64.UInt32"] = CompareEqual_Vector64_UInt32, - ["CompareEqual.Vector128.Byte"] = CompareEqual_Vector128_Byte, - ["CompareEqual.Vector128.Int16"] = CompareEqual_Vector128_Int16, - ["CompareEqual.Vector128.Int32"] = CompareEqual_Vector128_Int32, - ["CompareEqual.Vector128.SByte"] = CompareEqual_Vector128_SByte, - ["CompareEqual.Vector128.Single"] = CompareEqual_Vector128_Single, - ["CompareEqual.Vector128.UInt16"] = CompareEqual_Vector128_UInt16, - ["CompareEqual.Vector128.UInt32"] = CompareEqual_Vector128_UInt32, - ["CompareGreaterThan.Vector64.Byte"] = CompareGreaterThan_Vector64_Byte, - ["CompareGreaterThan.Vector64.Int16"] = CompareGreaterThan_Vector64_Int16, - ["CompareGreaterThan.Vector64.Int32"] = CompareGreaterThan_Vector64_Int32, - ["CompareGreaterThan.Vector64.SByte"] = CompareGreaterThan_Vector64_SByte, - ["CompareGreaterThan.Vector64.Single"] = CompareGreaterThan_Vector64_Single, - ["CompareGreaterThan.Vector64.UInt16"] = CompareGreaterThan_Vector64_UInt16, - ["CompareGreaterThan.Vector64.UInt32"] = CompareGreaterThan_Vector64_UInt32, - ["CompareGreaterThan.Vector128.Byte"] = CompareGreaterThan_Vector128_Byte, - ["CompareGreaterThan.Vector128.Int16"] = CompareGreaterThan_Vector128_Int16, - ["CompareGreaterThan.Vector128.Int32"] = CompareGreaterThan_Vector128_Int32, - ["CompareGreaterThan.Vector128.SByte"] = CompareGreaterThan_Vector128_SByte, - ["CompareGreaterThan.Vector128.Single"] = CompareGreaterThan_Vector128_Single, - ["CompareGreaterThan.Vector128.UInt16"] = CompareGreaterThan_Vector128_UInt16, - ["CompareGreaterThan.Vector128.UInt32"] = CompareGreaterThan_Vector128_UInt32, - ["CompareGreaterThanOrEqual.Vector64.Byte"] = CompareGreaterThanOrEqual_Vector64_Byte, - ["CompareGreaterThanOrEqual.Vector64.Int16"] = CompareGreaterThanOrEqual_Vector64_Int16, - ["CompareGreaterThanOrEqual.Vector64.Int32"] = CompareGreaterThanOrEqual_Vector64_Int32, - ["CompareGreaterThanOrEqual.Vector64.SByte"] = CompareGreaterThanOrEqual_Vector64_SByte, - ["CompareGreaterThanOrEqual.Vector64.Single"] = CompareGreaterThanOrEqual_Vector64_Single, - ["CompareGreaterThanOrEqual.Vector64.UInt16"] = CompareGreaterThanOrEqual_Vector64_UInt16, - ["CompareGreaterThanOrEqual.Vector64.UInt32"] = CompareGreaterThanOrEqual_Vector64_UInt32, - ["CompareGreaterThanOrEqual.Vector128.Byte"] = CompareGreaterThanOrEqual_Vector128_Byte, - ["CompareGreaterThanOrEqual.Vector128.Int16"] = CompareGreaterThanOrEqual_Vector128_Int16, - ["CompareGreaterThanOrEqual.Vector128.Int32"] = CompareGreaterThanOrEqual_Vector128_Int32, - ["CompareGreaterThanOrEqual.Vector128.SByte"] = CompareGreaterThanOrEqual_Vector128_SByte, - ["CompareGreaterThanOrEqual.Vector128.Single"] = CompareGreaterThanOrEqual_Vector128_Single, - ["CompareGreaterThanOrEqual.Vector128.UInt16"] = CompareGreaterThanOrEqual_Vector128_UInt16, - ["CompareGreaterThanOrEqual.Vector128.UInt32"] = CompareGreaterThanOrEqual_Vector128_UInt32, - ["CompareLessThan.Vector64.Byte"] = CompareLessThan_Vector64_Byte, - ["CompareLessThan.Vector64.Int16"] = CompareLessThan_Vector64_Int16, - ["CompareLessThan.Vector64.Int32"] = CompareLessThan_Vector64_Int32, - ["CompareLessThan.Vector64.SByte"] = CompareLessThan_Vector64_SByte, - ["CompareLessThan.Vector64.Single"] = CompareLessThan_Vector64_Single, - ["CompareLessThan.Vector64.UInt16"] = CompareLessThan_Vector64_UInt16, - ["CompareLessThan.Vector64.UInt32"] = CompareLessThan_Vector64_UInt32, - ["CompareLessThan.Vector128.Byte"] = CompareLessThan_Vector128_Byte, - ["CompareLessThan.Vector128.Int16"] = CompareLessThan_Vector128_Int16, - ["CompareLessThan.Vector128.Int32"] = CompareLessThan_Vector128_Int32, - ["CompareLessThan.Vector128.SByte"] = CompareLessThan_Vector128_SByte, - ["CompareLessThan.Vector128.Single"] = CompareLessThan_Vector128_Single, - ["CompareLessThan.Vector128.UInt16"] = CompareLessThan_Vector128_UInt16, - ["CompareLessThan.Vector128.UInt32"] = CompareLessThan_Vector128_UInt32, - ["CompareLessThanOrEqual.Vector64.Byte"] = CompareLessThanOrEqual_Vector64_Byte, - ["CompareLessThanOrEqual.Vector64.Int16"] = CompareLessThanOrEqual_Vector64_Int16, - ["CompareLessThanOrEqual.Vector64.Int32"] = CompareLessThanOrEqual_Vector64_Int32, - ["CompareLessThanOrEqual.Vector64.SByte"] = CompareLessThanOrEqual_Vector64_SByte, - ["CompareLessThanOrEqual.Vector64.Single"] = CompareLessThanOrEqual_Vector64_Single, - ["CompareLessThanOrEqual.Vector64.UInt16"] = CompareLessThanOrEqual_Vector64_UInt16, - ["CompareLessThanOrEqual.Vector64.UInt32"] = CompareLessThanOrEqual_Vector64_UInt32, - ["CompareLessThanOrEqual.Vector128.Byte"] = CompareLessThanOrEqual_Vector128_Byte, - ["CompareLessThanOrEqual.Vector128.Int16"] = CompareLessThanOrEqual_Vector128_Int16, - ["CompareLessThanOrEqual.Vector128.Int32"] = CompareLessThanOrEqual_Vector128_Int32, - ["CompareLessThanOrEqual.Vector128.SByte"] = CompareLessThanOrEqual_Vector128_SByte, - ["CompareLessThanOrEqual.Vector128.Single"] = CompareLessThanOrEqual_Vector128_Single, - ["CompareLessThanOrEqual.Vector128.UInt16"] = CompareLessThanOrEqual_Vector128_UInt16, - ["CompareLessThanOrEqual.Vector128.UInt32"] = CompareLessThanOrEqual_Vector128_UInt32, - ["CompareTest.Vector64.Byte"] = CompareTest_Vector64_Byte, - ["CompareTest.Vector64.Int16"] = CompareTest_Vector64_Int16, - ["CompareTest.Vector64.Int32"] = CompareTest_Vector64_Int32, - ["CompareTest.Vector64.SByte"] = CompareTest_Vector64_SByte, - ["CompareTest.Vector64.Single"] = CompareTest_Vector64_Single, - ["CompareTest.Vector64.UInt16"] = CompareTest_Vector64_UInt16, - ["CompareTest.Vector64.UInt32"] = CompareTest_Vector64_UInt32, - ["CompareTest.Vector128.Byte"] = CompareTest_Vector128_Byte, - ["CompareTest.Vector128.Int16"] = CompareTest_Vector128_Int16, - ["CompareTest.Vector128.Int32"] = CompareTest_Vector128_Int32, - ["CompareTest.Vector128.SByte"] = CompareTest_Vector128_SByte, - ["CompareTest.Vector128.Single"] = CompareTest_Vector128_Single, - ["CompareTest.Vector128.UInt16"] = CompareTest_Vector128_UInt16, - ["CompareTest.Vector128.UInt32"] = CompareTest_Vector128_UInt32, - ["ConvertToInt32RoundAwayFromZero.Vector64.Single"] = ConvertToInt32RoundAwayFromZero_Vector64_Single, - ["ConvertToInt32RoundAwayFromZero.Vector128.Single"] = ConvertToInt32RoundAwayFromZero_Vector128_Single, - ["ConvertToInt32RoundAwayFromZeroScalar.Vector64.Single"] = ConvertToInt32RoundAwayFromZeroScalar_Vector64_Single, - ["ConvertToInt32RoundToEven.Vector64.Single"] = ConvertToInt32RoundToEven_Vector64_Single, - ["ConvertToInt32RoundToEven.Vector128.Single"] = ConvertToInt32RoundToEven_Vector128_Single, - ["ConvertToInt32RoundToEvenScalar.Vector64.Single"] = ConvertToInt32RoundToEvenScalar_Vector64_Single, - ["ConvertToInt32RoundToNegativeInfinity.Vector64.Single"] = ConvertToInt32RoundToNegativeInfinity_Vector64_Single, - ["ConvertToInt32RoundToNegativeInfinity.Vector128.Single"] = ConvertToInt32RoundToNegativeInfinity_Vector128_Single, - ["ConvertToInt32RoundToNegativeInfinityScalar.Vector64.Single"] = ConvertToInt32RoundToNegativeInfinityScalar_Vector64_Single, - ["ConvertToInt32RoundToPositiveInfinity.Vector64.Single"] = ConvertToInt32RoundToPositiveInfinity_Vector64_Single, - ["ConvertToInt32RoundToPositiveInfinity.Vector128.Single"] = ConvertToInt32RoundToPositiveInfinity_Vector128_Single, - ["ConvertToInt32RoundToPositiveInfinityScalar.Vector64.Single"] = ConvertToInt32RoundToPositiveInfinityScalar_Vector64_Single, - ["ConvertToInt32RoundToZero.Vector64.Single"] = ConvertToInt32RoundToZero_Vector64_Single, - ["ConvertToInt32RoundToZero.Vector128.Single"] = ConvertToInt32RoundToZero_Vector128_Single, - ["ConvertToInt32RoundToZeroScalar.Vector64.Single"] = ConvertToInt32RoundToZeroScalar_Vector64_Single, - ["ConvertToSingle.Vector64.Int32"] = ConvertToSingle_Vector64_Int32, - ["ConvertToSingle.Vector64.UInt32"] = ConvertToSingle_Vector64_UInt32, - ["ConvertToSingle.Vector128.Int32"] = ConvertToSingle_Vector128_Int32, - ["ConvertToSingle.Vector128.UInt32"] = ConvertToSingle_Vector128_UInt32, - ["ConvertToSingleScalar.Vector64.Int32"] = ConvertToSingleScalar_Vector64_Int32, - ["ConvertToSingleScalar.Vector64.UInt32"] = ConvertToSingleScalar_Vector64_UInt32, - ["ConvertToUInt32RoundAwayFromZero.Vector64.Single"] = ConvertToUInt32RoundAwayFromZero_Vector64_Single, - ["ConvertToUInt32RoundAwayFromZero.Vector128.Single"] = ConvertToUInt32RoundAwayFromZero_Vector128_Single, - ["ConvertToUInt32RoundAwayFromZeroScalar.Vector64.Single"] = ConvertToUInt32RoundAwayFromZeroScalar_Vector64_Single, - ["ConvertToUInt32RoundToEven.Vector64.Single"] = ConvertToUInt32RoundToEven_Vector64_Single, - ["ConvertToUInt32RoundToEven.Vector128.Single"] = ConvertToUInt32RoundToEven_Vector128_Single, - ["ConvertToUInt32RoundToEvenScalar.Vector64.Single"] = ConvertToUInt32RoundToEvenScalar_Vector64_Single, - ["ConvertToUInt32RoundToNegativeInfinity.Vector64.Single"] = ConvertToUInt32RoundToNegativeInfinity_Vector64_Single, - ["ConvertToUInt32RoundToNegativeInfinity.Vector128.Single"] = ConvertToUInt32RoundToNegativeInfinity_Vector128_Single, - ["ConvertToUInt32RoundToNegativeInfinityScalar.Vector64.Single"] = ConvertToUInt32RoundToNegativeInfinityScalar_Vector64_Single, - ["ConvertToUInt32RoundToPositiveInfinity.Vector64.Single"] = ConvertToUInt32RoundToPositiveInfinity_Vector64_Single, - ["ConvertToUInt32RoundToPositiveInfinity.Vector128.Single"] = ConvertToUInt32RoundToPositiveInfinity_Vector128_Single, - ["ConvertToUInt32RoundToPositiveInfinityScalar.Vector64.Single"] = ConvertToUInt32RoundToPositiveInfinityScalar_Vector64_Single, - ["ConvertToUInt32RoundToZero.Vector64.Single"] = ConvertToUInt32RoundToZero_Vector64_Single, - ["ConvertToUInt32RoundToZero.Vector128.Single"] = ConvertToUInt32RoundToZero_Vector128_Single, - ["ConvertToUInt32RoundToZeroScalar.Vector64.Single"] = ConvertToUInt32RoundToZeroScalar_Vector64_Single, - ["DivideScalar.Vector64.Double"] = DivideScalar_Vector64_Double, - ["DivideScalar.Vector64.Single"] = DivideScalar_Vector64_Single, - ["DuplicateSelectedScalarToVector64.Vector64.Byte.1"] = DuplicateSelectedScalarToVector64_Vector64_Byte_1, - ["DuplicateSelectedScalarToVector64.Vector64.Int16.1"] = DuplicateSelectedScalarToVector64_Vector64_Int16_1, - ["DuplicateSelectedScalarToVector64.Vector64.Int32.1"] = DuplicateSelectedScalarToVector64_Vector64_Int32_1, - ["DuplicateSelectedScalarToVector64.Vector64.SByte.1"] = DuplicateSelectedScalarToVector64_Vector64_SByte_1, - ["DuplicateSelectedScalarToVector64.Vector64.Single.1"] = DuplicateSelectedScalarToVector64_Vector64_Single_1, - ["DuplicateSelectedScalarToVector64.Vector64.UInt16.1"] = DuplicateSelectedScalarToVector64_Vector64_UInt16_1, - ["DuplicateSelectedScalarToVector64.Vector64.UInt32.1"] = DuplicateSelectedScalarToVector64_Vector64_UInt32_1, - ["DuplicateSelectedScalarToVector64.Vector128.Byte.8"] = DuplicateSelectedScalarToVector64_Vector128_Byte_8, - ["DuplicateSelectedScalarToVector64.Vector128.Int16.4"] = DuplicateSelectedScalarToVector64_Vector128_Int16_4, - ["DuplicateSelectedScalarToVector64.Vector128.Int32.2"] = DuplicateSelectedScalarToVector64_Vector128_Int32_2, - ["DuplicateSelectedScalarToVector64.Vector128.SByte.8"] = DuplicateSelectedScalarToVector64_Vector128_SByte_8, - ["DuplicateSelectedScalarToVector64.Vector128.Single.2"] = DuplicateSelectedScalarToVector64_Vector128_Single_2, - ["DuplicateSelectedScalarToVector64.Vector128.UInt16.4"] = DuplicateSelectedScalarToVector64_Vector128_UInt16_4, - ["DuplicateSelectedScalarToVector64.Vector128.UInt32.2"] = DuplicateSelectedScalarToVector64_Vector128_UInt32_2, - ["DuplicateSelectedScalarToVector128.Vector64.Byte.1"] = DuplicateSelectedScalarToVector128_Vector64_Byte_1, - ["DuplicateSelectedScalarToVector128.Vector64.Int16.1"] = DuplicateSelectedScalarToVector128_Vector64_Int16_1, - ["DuplicateSelectedScalarToVector128.Vector64.Int32.1"] = DuplicateSelectedScalarToVector128_Vector64_Int32_1, - ["DuplicateSelectedScalarToVector128.Vector64.SByte.1"] = DuplicateSelectedScalarToVector128_Vector64_SByte_1, - ["DuplicateSelectedScalarToVector128.Vector64.Single.1"] = DuplicateSelectedScalarToVector128_Vector64_Single_1, - ["DuplicateSelectedScalarToVector128.Vector64.UInt16.1"] = DuplicateSelectedScalarToVector128_Vector64_UInt16_1, - ["DuplicateSelectedScalarToVector128.Vector64.UInt32.1"] = DuplicateSelectedScalarToVector128_Vector64_UInt32_1, - ["DuplicateSelectedScalarToVector128.Vector128.Byte.8"] = DuplicateSelectedScalarToVector128_Vector128_Byte_8, - ["DuplicateSelectedScalarToVector128.Vector128.Int16.4"] = DuplicateSelectedScalarToVector128_Vector128_Int16_4, - ["DuplicateSelectedScalarToVector128.Vector128.Int32.2"] = DuplicateSelectedScalarToVector128_Vector128_Int32_2, - ["DuplicateSelectedScalarToVector128.Vector128.SByte.8"] = DuplicateSelectedScalarToVector128_Vector128_SByte_8, - ["DuplicateSelectedScalarToVector128.Vector128.Single.2"] = DuplicateSelectedScalarToVector128_Vector128_Single_2, - ["DuplicateSelectedScalarToVector128.Vector128.UInt16.4"] = DuplicateSelectedScalarToVector128_Vector128_UInt16_4, - ["DuplicateSelectedScalarToVector128.Vector128.UInt32.2"] = DuplicateSelectedScalarToVector128_Vector128_UInt32_2, - ["DuplicateToVector64.Byte"] = DuplicateToVector64_Byte, - ["DuplicateToVector64.Byte.31"] = DuplicateToVector64_Byte_31, - ["DuplicateToVector64.Int16"] = DuplicateToVector64_Int16, - ["DuplicateToVector64.Int16.31"] = DuplicateToVector64_Int16_31, - ["DuplicateToVector64.Int32"] = DuplicateToVector64_Int32, - ["DuplicateToVector64.Int32.31"] = DuplicateToVector64_Int32_31, - ["DuplicateToVector64.SByte"] = DuplicateToVector64_SByte, - ["DuplicateToVector64.SByte.31"] = DuplicateToVector64_SByte_31, - ["DuplicateToVector64.Single"] = DuplicateToVector64_Single, - ["DuplicateToVector64.Single.31"] = DuplicateToVector64_Single_31, - ["DuplicateToVector64.UInt16"] = DuplicateToVector64_UInt16, - ["DuplicateToVector64.UInt16.31"] = DuplicateToVector64_UInt16_31, - ["DuplicateToVector64.UInt32"] = DuplicateToVector64_UInt32, - ["DuplicateToVector64.UInt32.31"] = DuplicateToVector64_UInt32_31, - ["DuplicateToVector128.Byte"] = DuplicateToVector128_Byte, - ["DuplicateToVector128.Byte.31"] = DuplicateToVector128_Byte_31, - ["DuplicateToVector128.Int16"] = DuplicateToVector128_Int16, - ["DuplicateToVector128.Int16.31"] = DuplicateToVector128_Int16_31, - ["DuplicateToVector128.Int32"] = DuplicateToVector128_Int32, - ["DuplicateToVector128.Int32.31"] = DuplicateToVector128_Int32_31, - ["DuplicateToVector128.SByte"] = DuplicateToVector128_SByte, - ["DuplicateToVector128.SByte.31"] = DuplicateToVector128_SByte_31, - ["DuplicateToVector128.Single"] = DuplicateToVector128_Single, - ["DuplicateToVector128.Single.31"] = DuplicateToVector128_Single_31, - ["DuplicateToVector128.UInt16"] = DuplicateToVector128_UInt16, - ["DuplicateToVector128.UInt16.31"] = DuplicateToVector128_UInt16_31, - ["DuplicateToVector128.UInt32"] = DuplicateToVector128_UInt32, - ["DuplicateToVector128.UInt32.31"] = DuplicateToVector128_UInt32_31, - ["Extract.Vector64.Byte.1"] = Extract_Vector64_Byte_1, - ["Extract.Vector64.Int16.1"] = Extract_Vector64_Int16_1, - ["Extract.Vector64.Int32.1"] = Extract_Vector64_Int32_1, - ["Extract.Vector64.SByte.1"] = Extract_Vector64_SByte_1, - ["Extract.Vector64.Single.1"] = Extract_Vector64_Single_1, - ["Extract.Vector64.UInt16.1"] = Extract_Vector64_UInt16_1, - ["Extract.Vector64.UInt32.1"] = Extract_Vector64_UInt32_1, - ["Extract.Vector128.Byte.1"] = Extract_Vector128_Byte_1, - ["Extract.Vector128.Double.1"] = Extract_Vector128_Double_1, - ["Extract.Vector128.Int16.1"] = Extract_Vector128_Int16_1, - ["Extract.Vector128.Int32.1"] = Extract_Vector128_Int32_1, - ["Extract.Vector128.Int64.1"] = Extract_Vector128_Int64_1, - ["Extract.Vector128.SByte.1"] = Extract_Vector128_SByte_1, - ["Extract.Vector128.Single.1"] = Extract_Vector128_Single_1, - ["Extract.Vector128.UInt16.1"] = Extract_Vector128_UInt16_1, - ["Extract.Vector128.UInt32.1"] = Extract_Vector128_UInt32_1, - ["Extract.Vector128.UInt64.1"] = Extract_Vector128_UInt64_1, - ["ExtractNarrowingLower.Vector64.Byte"] = ExtractNarrowingLower_Vector64_Byte, - ["ExtractNarrowingLower.Vector64.Int16"] = ExtractNarrowingLower_Vector64_Int16, - ["ExtractNarrowingLower.Vector64.Int32"] = ExtractNarrowingLower_Vector64_Int32, - ["ExtractNarrowingLower.Vector64.SByte"] = ExtractNarrowingLower_Vector64_SByte, - ["ExtractNarrowingLower.Vector64.UInt16"] = ExtractNarrowingLower_Vector64_UInt16, - ["ExtractNarrowingLower.Vector64.UInt32"] = ExtractNarrowingLower_Vector64_UInt32, - ["ExtractNarrowingSaturateLower.Vector64.Byte"] = ExtractNarrowingSaturateLower_Vector64_Byte, - ["ExtractNarrowingSaturateLower.Vector64.Int16"] = ExtractNarrowingSaturateLower_Vector64_Int16, - ["ExtractNarrowingSaturateLower.Vector64.Int32"] = ExtractNarrowingSaturateLower_Vector64_Int32, - ["ExtractNarrowingSaturateLower.Vector64.SByte"] = ExtractNarrowingSaturateLower_Vector64_SByte, - ["ExtractNarrowingSaturateLower.Vector64.UInt16"] = ExtractNarrowingSaturateLower_Vector64_UInt16, - ["ExtractNarrowingSaturateLower.Vector64.UInt32"] = ExtractNarrowingSaturateLower_Vector64_UInt32, - ["ExtractNarrowingSaturateUnsignedLower.Vector64.Byte"] = ExtractNarrowingSaturateUnsignedLower_Vector64_Byte, - ["ExtractNarrowingSaturateUnsignedLower.Vector64.UInt16"] = ExtractNarrowingSaturateUnsignedLower_Vector64_UInt16, - ["ExtractNarrowingSaturateUnsignedLower.Vector64.UInt32"] = ExtractNarrowingSaturateUnsignedLower_Vector64_UInt32, - ["ExtractNarrowingSaturateUnsignedUpper.Vector128.Byte"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_Byte, - ["ExtractNarrowingSaturateUnsignedUpper.Vector128.UInt16"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt16, - ["ExtractNarrowingSaturateUnsignedUpper.Vector128.UInt32"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt32, - ["ExtractNarrowingSaturateUpper.Vector128.Byte"] = ExtractNarrowingSaturateUpper_Vector128_Byte, - ["ExtractNarrowingSaturateUpper.Vector128.Int16"] = ExtractNarrowingSaturateUpper_Vector128_Int16, - ["ExtractNarrowingSaturateUpper.Vector128.Int32"] = ExtractNarrowingSaturateUpper_Vector128_Int32, - ["ExtractNarrowingSaturateUpper.Vector128.SByte"] = ExtractNarrowingSaturateUpper_Vector128_SByte, - ["ExtractNarrowingSaturateUpper.Vector128.UInt16"] = ExtractNarrowingSaturateUpper_Vector128_UInt16, - ["ExtractNarrowingSaturateUpper.Vector128.UInt32"] = ExtractNarrowingSaturateUpper_Vector128_UInt32, - ["ExtractNarrowingUpper.Vector128.Byte"] = ExtractNarrowingUpper_Vector128_Byte, - ["ExtractNarrowingUpper.Vector128.Int16"] = ExtractNarrowingUpper_Vector128_Int16, - ["ExtractNarrowingUpper.Vector128.Int32"] = ExtractNarrowingUpper_Vector128_Int32, - ["ExtractNarrowingUpper.Vector128.SByte"] = ExtractNarrowingUpper_Vector128_SByte, - ["ExtractNarrowingUpper.Vector128.UInt16"] = ExtractNarrowingUpper_Vector128_UInt16, - ["ExtractNarrowingUpper.Vector128.UInt32"] = ExtractNarrowingUpper_Vector128_UInt32, - ["ExtractVector64.Byte.1"] = ExtractVector64_Byte_1, - ["ExtractVector64.Int16.1"] = ExtractVector64_Int16_1, - ["ExtractVector64.Int32.1"] = ExtractVector64_Int32_1, - ["ExtractVector64.SByte.1"] = ExtractVector64_SByte_1, - ["ExtractVector64.Single.1"] = ExtractVector64_Single_1, - ["ExtractVector64.UInt16.1"] = ExtractVector64_UInt16_1, - ["ExtractVector64.UInt32.1"] = ExtractVector64_UInt32_1, - ["ExtractVector128.Byte.1"] = ExtractVector128_Byte_1, - ["ExtractVector128.Double.1"] = ExtractVector128_Double_1, - ["ExtractVector128.Int16.1"] = ExtractVector128_Int16_1, - ["ExtractVector128.Int32.1"] = ExtractVector128_Int32_1, - ["ExtractVector128.Int64.1"] = ExtractVector128_Int64_1, - ["ExtractVector128.SByte.1"] = ExtractVector128_SByte_1, - ["ExtractVector128.Single.1"] = ExtractVector128_Single_1, - ["ExtractVector128.UInt16.1"] = ExtractVector128_UInt16_1, - ["ExtractVector128.UInt32.1"] = ExtractVector128_UInt32_1, - ["ExtractVector128.UInt64.1"] = ExtractVector128_UInt64_1, - ["Floor.Vector64.Single"] = Floor_Vector64_Single, - ["Floor.Vector128.Single"] = Floor_Vector128_Single, - ["FloorScalar.Vector64.Double"] = FloorScalar_Vector64_Double, - ["FloorScalar.Vector64.Single"] = FloorScalar_Vector64_Single, - ["FusedAddHalving.Vector64.Byte"] = FusedAddHalving_Vector64_Byte, - ["FusedAddHalving.Vector64.Int16"] = FusedAddHalving_Vector64_Int16, - ["FusedAddHalving.Vector64.Int32"] = FusedAddHalving_Vector64_Int32, - ["FusedAddHalving.Vector64.SByte"] = FusedAddHalving_Vector64_SByte, - ["FusedAddHalving.Vector64.UInt16"] = FusedAddHalving_Vector64_UInt16, - ["FusedAddHalving.Vector64.UInt32"] = FusedAddHalving_Vector64_UInt32, - ["FusedAddHalving.Vector128.Byte"] = FusedAddHalving_Vector128_Byte, - ["FusedAddHalving.Vector128.Int16"] = FusedAddHalving_Vector128_Int16, - ["FusedAddHalving.Vector128.Int32"] = FusedAddHalving_Vector128_Int32, - ["FusedAddHalving.Vector128.SByte"] = FusedAddHalving_Vector128_SByte, - ["FusedAddHalving.Vector128.UInt16"] = FusedAddHalving_Vector128_UInt16, - ["FusedAddHalving.Vector128.UInt32"] = FusedAddHalving_Vector128_UInt32, - ["FusedAddRoundedHalving.Vector64.Byte"] = FusedAddRoundedHalving_Vector64_Byte, + ["AddHighNarrowingUpper.Vector128.UInt16"] = AddHighNarrowingUpper_Vector128_UInt16, + ["AddHighNarrowingUpper.Vector128.UInt32"] = AddHighNarrowingUpper_Vector128_UInt32, + ["AddPairwise.Vector64.Byte"] = AddPairwise_Vector64_Byte, + ["AddPairwise.Vector64.Int16"] = AddPairwise_Vector64_Int16, + ["AddPairwise.Vector64.Int32"] = AddPairwise_Vector64_Int32, + ["AddPairwise.Vector64.SByte"] = AddPairwise_Vector64_SByte, + ["AddPairwise.Vector64.Single"] = AddPairwise_Vector64_Single, + ["AddPairwise.Vector64.UInt16"] = AddPairwise_Vector64_UInt16, + ["AddPairwise.Vector64.UInt32"] = AddPairwise_Vector64_UInt32, + ["AddPairwiseWidening.Vector64.Byte"] = AddPairwiseWidening_Vector64_Byte, + ["AddPairwiseWidening.Vector64.Int16"] = AddPairwiseWidening_Vector64_Int16, + ["AddPairwiseWidening.Vector64.SByte"] = AddPairwiseWidening_Vector64_SByte, + ["AddPairwiseWidening.Vector64.UInt16"] = AddPairwiseWidening_Vector64_UInt16, + ["AddPairwiseWidening.Vector128.Byte"] = AddPairwiseWidening_Vector128_Byte, + ["AddPairwiseWidening.Vector128.Int16"] = AddPairwiseWidening_Vector128_Int16, + ["AddPairwiseWidening.Vector128.Int32"] = AddPairwiseWidening_Vector128_Int32, + ["AddPairwiseWidening.Vector128.SByte"] = AddPairwiseWidening_Vector128_SByte, + ["AddPairwiseWidening.Vector128.UInt16"] = AddPairwiseWidening_Vector128_UInt16, + ["AddPairwiseWidening.Vector128.UInt32"] = AddPairwiseWidening_Vector128_UInt32, + ["AddPairwiseWideningAndAdd.Vector64.Byte"] = AddPairwiseWideningAndAdd_Vector64_Byte, + ["AddPairwiseWideningAndAdd.Vector64.Int16"] = AddPairwiseWideningAndAdd_Vector64_Int16, + ["AddPairwiseWideningAndAdd.Vector64.SByte"] = AddPairwiseWideningAndAdd_Vector64_SByte, + ["AddPairwiseWideningAndAdd.Vector64.UInt16"] = AddPairwiseWideningAndAdd_Vector64_UInt16, + ["AddPairwiseWideningAndAdd.Vector128.Byte"] = AddPairwiseWideningAndAdd_Vector128_Byte, + ["AddPairwiseWideningAndAdd.Vector128.Int16"] = AddPairwiseWideningAndAdd_Vector128_Int16, + ["AddPairwiseWideningAndAdd.Vector128.Int32"] = AddPairwiseWideningAndAdd_Vector128_Int32, + ["AddPairwiseWideningAndAdd.Vector128.SByte"] = AddPairwiseWideningAndAdd_Vector128_SByte, + ["AddPairwiseWideningAndAdd.Vector128.UInt16"] = AddPairwiseWideningAndAdd_Vector128_UInt16, + ["AddPairwiseWideningAndAdd.Vector128.UInt32"] = AddPairwiseWideningAndAdd_Vector128_UInt32, + ["AddPairwiseWideningAndAddScalar.Vector64.Int32"] = AddPairwiseWideningAndAddScalar_Vector64_Int32, + ["AddPairwiseWideningAndAddScalar.Vector64.UInt32"] = AddPairwiseWideningAndAddScalar_Vector64_UInt32, + ["AddPairwiseWideningScalar.Vector64.Int32"] = AddPairwiseWideningScalar_Vector64_Int32, + ["AddPairwiseWideningScalar.Vector64.UInt32"] = AddPairwiseWideningScalar_Vector64_UInt32, + ["AddRoundedHighNarrowingLower.Vector64.Byte"] = AddRoundedHighNarrowingLower_Vector64_Byte, + ["AddRoundedHighNarrowingLower.Vector64.Int16"] = AddRoundedHighNarrowingLower_Vector64_Int16, + ["AddRoundedHighNarrowingLower.Vector64.Int32"] = AddRoundedHighNarrowingLower_Vector64_Int32, + ["AddRoundedHighNarrowingLower.Vector64.SByte"] = AddRoundedHighNarrowingLower_Vector64_SByte, + ["AddRoundedHighNarrowingLower.Vector64.UInt16"] = AddRoundedHighNarrowingLower_Vector64_UInt16, + ["AddRoundedHighNarrowingLower.Vector64.UInt32"] = AddRoundedHighNarrowingLower_Vector64_UInt32, + ["AddRoundedHighNarrowingUpper.Vector128.Byte"] = AddRoundedHighNarrowingUpper_Vector128_Byte, + ["AddRoundedHighNarrowingUpper.Vector128.Int16"] = AddRoundedHighNarrowingUpper_Vector128_Int16, + ["AddRoundedHighNarrowingUpper.Vector128.Int32"] = AddRoundedHighNarrowingUpper_Vector128_Int32, + ["AddRoundedHighNarrowingUpper.Vector128.SByte"] = AddRoundedHighNarrowingUpper_Vector128_SByte, + ["AddRoundedHighNarrowingUpper.Vector128.UInt16"] = AddRoundedHighNarrowingUpper_Vector128_UInt16, + ["AddRoundedHighNarrowingUpper.Vector128.UInt32"] = AddRoundedHighNarrowingUpper_Vector128_UInt32, + ["AddSaturate.Vector64.Byte.Vector64.Byte"] = AddSaturate_Vector64_Byte_Vector64_Byte, + ["AddSaturate.Vector64.Int16.Vector64.Int16"] = AddSaturate_Vector64_Int16_Vector64_Int16, + ["AddSaturate.Vector64.Int32.Vector64.Int32"] = AddSaturate_Vector64_Int32_Vector64_Int32, + ["AddSaturate.Vector64.SByte.Vector64.SByte"] = AddSaturate_Vector64_SByte_Vector64_SByte, + ["AddSaturate.Vector64.UInt16.Vector64.UInt16"] = AddSaturate_Vector64_UInt16_Vector64_UInt16, + ["AddSaturate.Vector64.UInt32.Vector64.UInt32"] = AddSaturate_Vector64_UInt32_Vector64_UInt32, + ["AddSaturate.Vector128.Byte.Vector128.Byte"] = AddSaturate_Vector128_Byte_Vector128_Byte, + ["AddSaturate.Vector128.Int16.Vector128.Int16"] = AddSaturate_Vector128_Int16_Vector128_Int16, + ["AddSaturate.Vector128.Int32.Vector128.Int32"] = AddSaturate_Vector128_Int32_Vector128_Int32, + ["AddSaturate.Vector128.Int64.Vector128.Int64"] = AddSaturate_Vector128_Int64_Vector128_Int64, + ["AddSaturate.Vector128.SByte.Vector128.SByte"] = AddSaturate_Vector128_SByte_Vector128_SByte, + ["AddSaturate.Vector128.UInt16.Vector128.UInt16"] = AddSaturate_Vector128_UInt16_Vector128_UInt16, + ["AddSaturate.Vector128.UInt32.Vector128.UInt32"] = AddSaturate_Vector128_UInt32_Vector128_UInt32, + ["AddSaturate.Vector128.UInt64.Vector128.UInt64"] = AddSaturate_Vector128_UInt64_Vector128_UInt64, + ["AddSaturateScalar.Vector64.Int64.Vector64.Int64"] = AddSaturateScalar_Vector64_Int64_Vector64_Int64, + ["AddSaturateScalar.Vector64.UInt64.Vector64.UInt64"] = AddSaturateScalar_Vector64_UInt64_Vector64_UInt64, + ["AddScalar.Vector64.Double"] = AddScalar_Vector64_Double, + ["AddScalar.Vector64.Int64"] = AddScalar_Vector64_Int64, + ["AddScalar.Vector64.Single"] = AddScalar_Vector64_Single, + ["AddScalar.Vector64.UInt64"] = AddScalar_Vector64_UInt64, + ["AddWideningLower.Vector64.Byte"] = AddWideningLower_Vector64_Byte, + ["AddWideningLower.Vector64.Int16"] = AddWideningLower_Vector64_Int16, + ["AddWideningLower.Vector64.Int32"] = AddWideningLower_Vector64_Int32, + ["AddWideningLower.Vector64.SByte"] = AddWideningLower_Vector64_SByte, + ["AddWideningLower.Vector64.UInt16"] = AddWideningLower_Vector64_UInt16, + ["AddWideningLower.Vector64.UInt32"] = AddWideningLower_Vector64_UInt32, + ["AddWideningLower.Vector128.Int16"] = AddWideningLower_Vector128_Int16, + ["AddWideningLower.Vector128.Int32"] = AddWideningLower_Vector128_Int32, + ["AddWideningLower.Vector128.Int64"] = AddWideningLower_Vector128_Int64, + ["AddWideningLower.Vector128.UInt16"] = AddWideningLower_Vector128_UInt16, + ["AddWideningLower.Vector128.UInt32"] = AddWideningLower_Vector128_UInt32, + ["AddWideningLower.Vector128.UInt64"] = AddWideningLower_Vector128_UInt64, + ["AddWideningUpper.Vector128.Byte.Vector128.Byte"] = AddWideningUpper_Vector128_Byte_Vector128_Byte, + ["AddWideningUpper.Vector128.Int16.Vector128.Int16"] = AddWideningUpper_Vector128_Int16_Vector128_Int16, + ["AddWideningUpper.Vector128.Int16.Vector128.SByte"] = AddWideningUpper_Vector128_Int16_Vector128_SByte, + ["AddWideningUpper.Vector128.Int32.Vector128.Int16"] = AddWideningUpper_Vector128_Int32_Vector128_Int16, + ["AddWideningUpper.Vector128.Int32.Vector128.Int32"] = AddWideningUpper_Vector128_Int32_Vector128_Int32, + ["AddWideningUpper.Vector128.Int64.Vector128.Int32"] = AddWideningUpper_Vector128_Int64_Vector128_Int32, + ["AddWideningUpper.Vector128.SByte.Vector128.SByte"] = AddWideningUpper_Vector128_SByte_Vector128_SByte, + ["AddWideningUpper.Vector128.UInt16.Vector128.Byte"] = AddWideningUpper_Vector128_UInt16_Vector128_Byte, + ["AddWideningUpper.Vector128.UInt16.Vector128.UInt16"] = AddWideningUpper_Vector128_UInt16_Vector128_UInt16, + ["AddWideningUpper.Vector128.UInt32.Vector128.UInt16"] = AddWideningUpper_Vector128_UInt32_Vector128_UInt16, + ["AddWideningUpper.Vector128.UInt32.Vector128.UInt32"] = AddWideningUpper_Vector128_UInt32_Vector128_UInt32, + ["AddWideningUpper.Vector128.UInt64.Vector128.UInt32"] = AddWideningUpper_Vector128_UInt64_Vector128_UInt32, + ["And.Vector64.Byte"] = And_Vector64_Byte, + ["And.Vector64.Double"] = And_Vector64_Double, + ["And.Vector64.Int16"] = And_Vector64_Int16, + ["And.Vector64.Int32"] = And_Vector64_Int32, + ["And.Vector64.Int64"] = And_Vector64_Int64, + ["And.Vector64.SByte"] = And_Vector64_SByte, + ["And.Vector64.Single"] = And_Vector64_Single, + ["And.Vector64.UInt16"] = And_Vector64_UInt16, + ["And.Vector64.UInt32"] = And_Vector64_UInt32, + ["And.Vector64.UInt64"] = And_Vector64_UInt64, + ["And.Vector128.Byte"] = And_Vector128_Byte, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part10.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part10.cs new file mode 100644 index 000000000000..9ab2011c8654 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part10.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["Not.Vector128.Int64"] = Not_Vector128_Int64, + ["Not.Vector128.SByte"] = Not_Vector128_SByte, + ["Not.Vector128.Single"] = Not_Vector128_Single, + ["Not.Vector128.UInt16"] = Not_Vector128_UInt16, + ["Not.Vector128.UInt32"] = Not_Vector128_UInt32, + ["Not.Vector128.UInt64"] = Not_Vector128_UInt64, + ["Or.Vector64.Byte"] = Or_Vector64_Byte, + ["Or.Vector64.Double"] = Or_Vector64_Double, + ["Or.Vector64.Int16"] = Or_Vector64_Int16, + ["Or.Vector64.Int32"] = Or_Vector64_Int32, + ["Or.Vector64.Int64"] = Or_Vector64_Int64, + ["Or.Vector64.SByte"] = Or_Vector64_SByte, + ["Or.Vector64.Single"] = Or_Vector64_Single, + ["Or.Vector64.UInt16"] = Or_Vector64_UInt16, + ["Or.Vector64.UInt32"] = Or_Vector64_UInt32, + ["Or.Vector64.UInt64"] = Or_Vector64_UInt64, + ["Or.Vector128.Byte"] = Or_Vector128_Byte, + ["Or.Vector128.Double"] = Or_Vector128_Double, + ["Or.Vector128.Int16"] = Or_Vector128_Int16, + ["Or.Vector128.Int32"] = Or_Vector128_Int32, + ["Or.Vector128.Int64"] = Or_Vector128_Int64, + ["Or.Vector128.SByte"] = Or_Vector128_SByte, + ["Or.Vector128.Single"] = Or_Vector128_Single, + ["Or.Vector128.UInt16"] = Or_Vector128_UInt16, + ["Or.Vector128.UInt32"] = Or_Vector128_UInt32, + ["Or.Vector128.UInt64"] = Or_Vector128_UInt64, + ["OrNot.Vector64.Byte"] = OrNot_Vector64_Byte, + ["OrNot.Vector64.Double"] = OrNot_Vector64_Double, + ["OrNot.Vector64.Int16"] = OrNot_Vector64_Int16, + ["OrNot.Vector64.Int32"] = OrNot_Vector64_Int32, + ["OrNot.Vector64.Int64"] = OrNot_Vector64_Int64, + ["OrNot.Vector64.SByte"] = OrNot_Vector64_SByte, + ["OrNot.Vector64.Single"] = OrNot_Vector64_Single, + ["OrNot.Vector64.UInt16"] = OrNot_Vector64_UInt16, + ["OrNot.Vector64.UInt32"] = OrNot_Vector64_UInt32, + ["OrNot.Vector64.UInt64"] = OrNot_Vector64_UInt64, + ["OrNot.Vector128.Byte"] = OrNot_Vector128_Byte, + ["OrNot.Vector128.Double"] = OrNot_Vector128_Double, + ["OrNot.Vector128.Int16"] = OrNot_Vector128_Int16, + ["OrNot.Vector128.Int32"] = OrNot_Vector128_Int32, + ["OrNot.Vector128.Int64"] = OrNot_Vector128_Int64, + ["OrNot.Vector128.SByte"] = OrNot_Vector128_SByte, + ["OrNot.Vector128.Single"] = OrNot_Vector128_Single, + ["OrNot.Vector128.UInt16"] = OrNot_Vector128_UInt16, + ["OrNot.Vector128.UInt32"] = OrNot_Vector128_UInt32, + ["OrNot.Vector128.UInt64"] = OrNot_Vector128_UInt64, + ["PolynomialMultiply.Vector64.Byte"] = PolynomialMultiply_Vector64_Byte, + ["PolynomialMultiply.Vector64.SByte"] = PolynomialMultiply_Vector64_SByte, + ["PolynomialMultiply.Vector128.Byte"] = PolynomialMultiply_Vector128_Byte, + ["PolynomialMultiply.Vector128.SByte"] = PolynomialMultiply_Vector128_SByte, + ["PolynomialMultiplyWideningLower.Vector64.Byte"] = PolynomialMultiplyWideningLower_Vector64_Byte, + ["PolynomialMultiplyWideningLower.Vector64.SByte"] = PolynomialMultiplyWideningLower_Vector64_SByte, + ["PolynomialMultiplyWideningUpper.Vector128.Byte"] = PolynomialMultiplyWideningUpper_Vector128_Byte, + ["PolynomialMultiplyWideningUpper.Vector128.SByte"] = PolynomialMultiplyWideningUpper_Vector128_SByte, + ["PopCount.Vector64.Byte"] = PopCount_Vector64_Byte, + ["PopCount.Vector64.SByte"] = PopCount_Vector64_SByte, + ["PopCount.Vector128.Byte"] = PopCount_Vector128_Byte, + ["PopCount.Vector128.SByte"] = PopCount_Vector128_SByte, + ["ReciprocalEstimate.Vector64.Single"] = ReciprocalEstimate_Vector64_Single, + ["ReciprocalEstimate.Vector64.UInt32"] = ReciprocalEstimate_Vector64_UInt32, + ["ReciprocalEstimate.Vector128.Single"] = ReciprocalEstimate_Vector128_Single, + ["ReciprocalEstimate.Vector128.UInt32"] = ReciprocalEstimate_Vector128_UInt32, + ["ReciprocalSquareRootEstimate.Vector64.Single"] = ReciprocalSquareRootEstimate_Vector64_Single, + ["ReciprocalSquareRootEstimate.Vector64.UInt32"] = ReciprocalSquareRootEstimate_Vector64_UInt32, + ["ReciprocalSquareRootEstimate.Vector128.Single"] = ReciprocalSquareRootEstimate_Vector128_Single, + ["ReciprocalSquareRootEstimate.Vector128.UInt32"] = ReciprocalSquareRootEstimate_Vector128_UInt32, + ["ReciprocalSquareRootStep.Vector64.Single"] = ReciprocalSquareRootStep_Vector64_Single, + ["ReciprocalSquareRootStep.Vector128.Single"] = ReciprocalSquareRootStep_Vector128_Single, + ["ReciprocalStep.Vector64.Single"] = ReciprocalStep_Vector64_Single, + ["ReciprocalStep.Vector128.Single"] = ReciprocalStep_Vector128_Single, + ["ReverseElement16.Vector64.Int32"] = ReverseElement16_Vector64_Int32, + ["ReverseElement16.Vector64.Int64"] = ReverseElement16_Vector64_Int64, + ["ReverseElement16.Vector64.UInt32"] = ReverseElement16_Vector64_UInt32, + ["ReverseElement16.Vector64.UInt64"] = ReverseElement16_Vector64_UInt64, + ["ReverseElement16.Vector128.Int32"] = ReverseElement16_Vector128_Int32, + ["ReverseElement16.Vector128.Int64"] = ReverseElement16_Vector128_Int64, + ["ReverseElement16.Vector128.UInt32"] = ReverseElement16_Vector128_UInt32, + ["ReverseElement16.Vector128.UInt64"] = ReverseElement16_Vector128_UInt64, + ["ReverseElement32.Vector64.Int64"] = ReverseElement32_Vector64_Int64, + ["ReverseElement32.Vector64.UInt64"] = ReverseElement32_Vector64_UInt64, + ["ReverseElement32.Vector128.Int64"] = ReverseElement32_Vector128_Int64, + ["ReverseElement32.Vector128.UInt64"] = ReverseElement32_Vector128_UInt64, + ["ReverseElement8.Vector64.Int16"] = ReverseElement8_Vector64_Int16, + ["ReverseElement8.Vector64.Int32"] = ReverseElement8_Vector64_Int32, + ["ReverseElement8.Vector64.Int64"] = ReverseElement8_Vector64_Int64, + ["ReverseElement8.Vector64.UInt16"] = ReverseElement8_Vector64_UInt16, + ["ReverseElement8.Vector64.UInt32"] = ReverseElement8_Vector64_UInt32, + ["ReverseElement8.Vector64.UInt64"] = ReverseElement8_Vector64_UInt64, + ["ReverseElement8.Vector128.Int16"] = ReverseElement8_Vector128_Int16, + ["ReverseElement8.Vector128.Int32"] = ReverseElement8_Vector128_Int32, + ["ReverseElement8.Vector128.Int64"] = ReverseElement8_Vector128_Int64, + ["ReverseElement8.Vector128.UInt16"] = ReverseElement8_Vector128_UInt16, + ["ReverseElement8.Vector128.UInt32"] = ReverseElement8_Vector128_UInt32, + ["ReverseElement8.Vector128.UInt64"] = ReverseElement8_Vector128_UInt64, + ["RoundAwayFromZero.Vector64.Single"] = RoundAwayFromZero_Vector64_Single, + ["RoundAwayFromZero.Vector128.Single"] = RoundAwayFromZero_Vector128_Single, + ["RoundAwayFromZeroScalar.Vector64.Double"] = RoundAwayFromZeroScalar_Vector64_Double, + ["RoundAwayFromZeroScalar.Vector64.Single"] = RoundAwayFromZeroScalar_Vector64_Single, + ["RoundToNearest.Vector64.Single"] = RoundToNearest_Vector64_Single, + ["RoundToNearest.Vector128.Single"] = RoundToNearest_Vector128_Single, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part11.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part11.cs new file mode 100644 index 000000000000..491dda706526 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part11.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["RoundToNearestScalar.Vector64.Double"] = RoundToNearestScalar_Vector64_Double, + ["RoundToNearestScalar.Vector64.Single"] = RoundToNearestScalar_Vector64_Single, + ["RoundToNegativeInfinity.Vector64.Single"] = RoundToNegativeInfinity_Vector64_Single, + ["RoundToNegativeInfinity.Vector128.Single"] = RoundToNegativeInfinity_Vector128_Single, + ["RoundToNegativeInfinityScalar.Vector64.Double"] = RoundToNegativeInfinityScalar_Vector64_Double, + ["RoundToNegativeInfinityScalar.Vector64.Single"] = RoundToNegativeInfinityScalar_Vector64_Single, + ["RoundToPositiveInfinity.Vector64.Single"] = RoundToPositiveInfinity_Vector64_Single, + ["RoundToPositiveInfinity.Vector128.Single"] = RoundToPositiveInfinity_Vector128_Single, + ["RoundToPositiveInfinityScalar.Vector64.Double"] = RoundToPositiveInfinityScalar_Vector64_Double, + ["RoundToPositiveInfinityScalar.Vector64.Single"] = RoundToPositiveInfinityScalar_Vector64_Single, + ["RoundToZero.Vector64.Single"] = RoundToZero_Vector64_Single, + ["RoundToZero.Vector128.Single"] = RoundToZero_Vector128_Single, + ["RoundToZeroScalar.Vector64.Double"] = RoundToZeroScalar_Vector64_Double, + ["RoundToZeroScalar.Vector64.Single"] = RoundToZeroScalar_Vector64_Single, + ["ShiftArithmetic.Vector64.Int16"] = ShiftArithmetic_Vector64_Int16, + ["ShiftArithmetic.Vector64.Int32"] = ShiftArithmetic_Vector64_Int32, + ["ShiftArithmetic.Vector64.SByte"] = ShiftArithmetic_Vector64_SByte, + ["ShiftArithmetic.Vector128.Int16"] = ShiftArithmetic_Vector128_Int16, + ["ShiftArithmetic.Vector128.Int32"] = ShiftArithmetic_Vector128_Int32, + ["ShiftArithmetic.Vector128.Int64"] = ShiftArithmetic_Vector128_Int64, + ["ShiftArithmetic.Vector128.SByte"] = ShiftArithmetic_Vector128_SByte, + ["ShiftArithmeticRounded.Vector64.Int16"] = ShiftArithmeticRounded_Vector64_Int16, + ["ShiftArithmeticRounded.Vector64.Int32"] = ShiftArithmeticRounded_Vector64_Int32, + ["ShiftArithmeticRounded.Vector64.SByte"] = ShiftArithmeticRounded_Vector64_SByte, + ["ShiftArithmeticRounded.Vector128.Int16"] = ShiftArithmeticRounded_Vector128_Int16, + ["ShiftArithmeticRounded.Vector128.Int32"] = ShiftArithmeticRounded_Vector128_Int32, + ["ShiftArithmeticRounded.Vector128.Int64"] = ShiftArithmeticRounded_Vector128_Int64, + ["ShiftArithmeticRounded.Vector128.SByte"] = ShiftArithmeticRounded_Vector128_SByte, + ["ShiftArithmeticRoundedSaturate.Vector64.Int16"] = ShiftArithmeticRoundedSaturate_Vector64_Int16, + ["ShiftArithmeticRoundedSaturate.Vector64.Int32"] = ShiftArithmeticRoundedSaturate_Vector64_Int32, + ["ShiftArithmeticRoundedSaturate.Vector64.SByte"] = ShiftArithmeticRoundedSaturate_Vector64_SByte, + ["ShiftArithmeticRoundedSaturate.Vector128.Int16"] = ShiftArithmeticRoundedSaturate_Vector128_Int16, + ["ShiftArithmeticRoundedSaturate.Vector128.Int32"] = ShiftArithmeticRoundedSaturate_Vector128_Int32, + ["ShiftArithmeticRoundedSaturate.Vector128.Int64"] = ShiftArithmeticRoundedSaturate_Vector128_Int64, + ["ShiftArithmeticRoundedSaturate.Vector128.SByte"] = ShiftArithmeticRoundedSaturate_Vector128_SByte, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int64"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int64, + ["ShiftArithmeticRoundedScalar.Vector64.Int64"] = ShiftArithmeticRoundedScalar_Vector64_Int64, + ["ShiftArithmeticSaturate.Vector64.Int16"] = ShiftArithmeticSaturate_Vector64_Int16, + ["ShiftArithmeticSaturate.Vector64.Int32"] = ShiftArithmeticSaturate_Vector64_Int32, + ["ShiftArithmeticSaturate.Vector64.SByte"] = ShiftArithmeticSaturate_Vector64_SByte, + ["ShiftArithmeticSaturate.Vector128.Int16"] = ShiftArithmeticSaturate_Vector128_Int16, + ["ShiftArithmeticSaturate.Vector128.Int32"] = ShiftArithmeticSaturate_Vector128_Int32, + ["ShiftArithmeticSaturate.Vector128.Int64"] = ShiftArithmeticSaturate_Vector128_Int64, + ["ShiftArithmeticSaturate.Vector128.SByte"] = ShiftArithmeticSaturate_Vector128_SByte, + ["ShiftArithmeticSaturateScalar.Vector64.Int64"] = ShiftArithmeticSaturateScalar_Vector64_Int64, + ["ShiftArithmeticScalar.Vector64.Int64"] = ShiftArithmeticScalar_Vector64_Int64, + ["ShiftLeftAndInsert.Vector64.Byte"] = ShiftLeftAndInsert_Vector64_Byte, + ["ShiftLeftAndInsert.Vector64.Int16"] = ShiftLeftAndInsert_Vector64_Int16, + ["ShiftLeftAndInsert.Vector64.Int32"] = ShiftLeftAndInsert_Vector64_Int32, + ["ShiftLeftAndInsert.Vector64.SByte"] = ShiftLeftAndInsert_Vector64_SByte, + ["ShiftLeftAndInsert.Vector64.UInt16"] = ShiftLeftAndInsert_Vector64_UInt16, + ["ShiftLeftAndInsert.Vector64.UInt32"] = ShiftLeftAndInsert_Vector64_UInt32, + ["ShiftLeftAndInsert.Vector128.Byte"] = ShiftLeftAndInsert_Vector128_Byte, + ["ShiftLeftAndInsert.Vector128.Int16"] = ShiftLeftAndInsert_Vector128_Int16, + ["ShiftLeftAndInsert.Vector128.Int32"] = ShiftLeftAndInsert_Vector128_Int32, + ["ShiftLeftAndInsert.Vector128.Int64"] = ShiftLeftAndInsert_Vector128_Int64, + ["ShiftLeftAndInsert.Vector128.SByte"] = ShiftLeftAndInsert_Vector128_SByte, + ["ShiftLeftAndInsert.Vector128.UInt16"] = ShiftLeftAndInsert_Vector128_UInt16, + ["ShiftLeftAndInsert.Vector128.UInt32"] = ShiftLeftAndInsert_Vector128_UInt32, + ["ShiftLeftAndInsert.Vector128.UInt64"] = ShiftLeftAndInsert_Vector128_UInt64, + ["ShiftLeftAndInsertScalar.Vector64.Int64"] = ShiftLeftAndInsertScalar_Vector64_Int64, + ["ShiftLeftAndInsertScalar.Vector64.UInt64"] = ShiftLeftAndInsertScalar_Vector64_UInt64, + ["ShiftLeftLogical.Vector64.Byte.1"] = ShiftLeftLogical_Vector64_Byte_1, + ["ShiftLeftLogical.Vector64.Int16.1"] = ShiftLeftLogical_Vector64_Int16_1, + ["ShiftLeftLogical.Vector64.Int32.1"] = ShiftLeftLogical_Vector64_Int32_1, + ["ShiftLeftLogical.Vector64.SByte.1"] = ShiftLeftLogical_Vector64_SByte_1, + ["ShiftLeftLogical.Vector64.UInt16.1"] = ShiftLeftLogical_Vector64_UInt16_1, + ["ShiftLeftLogical.Vector64.UInt32.1"] = ShiftLeftLogical_Vector64_UInt32_1, + ["ShiftLeftLogical.Vector128.Byte.1"] = ShiftLeftLogical_Vector128_Byte_1, + ["ShiftLeftLogical.Vector128.Int16.1"] = ShiftLeftLogical_Vector128_Int16_1, + ["ShiftLeftLogical.Vector128.Int64.1"] = ShiftLeftLogical_Vector128_Int64_1, + ["ShiftLeftLogical.Vector128.SByte.1"] = ShiftLeftLogical_Vector128_SByte_1, + ["ShiftLeftLogical.Vector128.UInt16.1"] = ShiftLeftLogical_Vector128_UInt16_1, + ["ShiftLeftLogical.Vector128.UInt32.1"] = ShiftLeftLogical_Vector128_UInt32_1, + ["ShiftLeftLogical.Vector128.UInt64.1"] = ShiftLeftLogical_Vector128_UInt64_1, + ["ShiftLeftLogicalSaturate.Vector64.Byte.1"] = ShiftLeftLogicalSaturate_Vector64_Byte_1, + ["ShiftLeftLogicalSaturate.Vector64.Int16.1"] = ShiftLeftLogicalSaturate_Vector64_Int16_1, + ["ShiftLeftLogicalSaturate.Vector64.Int32.1"] = ShiftLeftLogicalSaturate_Vector64_Int32_1, + ["ShiftLeftLogicalSaturate.Vector64.SByte.1"] = ShiftLeftLogicalSaturate_Vector64_SByte_1, + ["ShiftLeftLogicalSaturate.Vector64.UInt16.1"] = ShiftLeftLogicalSaturate_Vector64_UInt16_1, + ["ShiftLeftLogicalSaturate.Vector64.UInt32.1"] = ShiftLeftLogicalSaturate_Vector64_UInt32_1, + ["ShiftLeftLogicalSaturate.Vector128.Byte.1"] = ShiftLeftLogicalSaturate_Vector128_Byte_1, + ["ShiftLeftLogicalSaturate.Vector128.Int16.1"] = ShiftLeftLogicalSaturate_Vector128_Int16_1, + ["ShiftLeftLogicalSaturate.Vector128.Int32.1"] = ShiftLeftLogicalSaturate_Vector128_Int32_1, + ["ShiftLeftLogicalSaturate.Vector128.Int64.1"] = ShiftLeftLogicalSaturate_Vector128_Int64_1, + ["ShiftLeftLogicalSaturate.Vector128.SByte.1"] = ShiftLeftLogicalSaturate_Vector128_SByte_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt16.1"] = ShiftLeftLogicalSaturate_Vector128_UInt16_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt32.1"] = ShiftLeftLogicalSaturate_Vector128_UInt32_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt64.1"] = ShiftLeftLogicalSaturate_Vector128_UInt64_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_Int64_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1, + ["ShiftLeftLogicalScalar.Vector64.Int64.1"] = ShiftLeftLogicalScalar_Vector64_Int64_1, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part12.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part12.cs new file mode 100644 index 000000000000..b471eff3acf6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part12.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["ShiftLeftLogicalScalar.Vector64.UInt64.1"] = ShiftLeftLogicalScalar_Vector64_UInt64_1, + ["ShiftLeftLogicalWideningLower.Vector64.Byte.1"] = ShiftLeftLogicalWideningLower_Vector64_Byte_1, + ["ShiftLeftLogicalWideningLower.Vector64.Int16.1"] = ShiftLeftLogicalWideningLower_Vector64_Int16_1, + ["ShiftLeftLogicalWideningLower.Vector64.Int32.1"] = ShiftLeftLogicalWideningLower_Vector64_Int32_1, + ["ShiftLeftLogicalWideningLower.Vector64.SByte.1"] = ShiftLeftLogicalWideningLower_Vector64_SByte_1, + ["ShiftLeftLogicalWideningLower.Vector64.UInt16.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt16_1, + ["ShiftLeftLogicalWideningLower.Vector64.UInt32.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt32_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Byte.1"] = ShiftLeftLogicalWideningUpper_Vector128_Byte_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Int16.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int16_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Int32.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int32_1, + ["ShiftLeftLogicalWideningUpper.Vector128.SByte.1"] = ShiftLeftLogicalWideningUpper_Vector128_SByte_1, + ["ShiftLeftLogicalWideningUpper.Vector128.UInt16.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt16_1, + ["ShiftLeftLogicalWideningUpper.Vector128.UInt32.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt32_1, + ["ShiftLogical.Vector64.Byte"] = ShiftLogical_Vector64_Byte, + ["ShiftLogical.Vector64.Int16"] = ShiftLogical_Vector64_Int16, + ["ShiftLogical.Vector64.Int32"] = ShiftLogical_Vector64_Int32, + ["ShiftLogical.Vector64.SByte"] = ShiftLogical_Vector64_SByte, + ["ShiftLogical.Vector64.UInt16"] = ShiftLogical_Vector64_UInt16, + ["ShiftLogical.Vector64.UInt32"] = ShiftLogical_Vector64_UInt32, + ["ShiftLogical.Vector128.Byte"] = ShiftLogical_Vector128_Byte, + ["ShiftLogical.Vector128.Int16"] = ShiftLogical_Vector128_Int16, + ["ShiftLogical.Vector128.Int32"] = ShiftLogical_Vector128_Int32, + ["ShiftLogical.Vector128.Int64"] = ShiftLogical_Vector128_Int64, + ["ShiftLogical.Vector128.SByte"] = ShiftLogical_Vector128_SByte, + ["ShiftLogical.Vector128.UInt16"] = ShiftLogical_Vector128_UInt16, + ["ShiftLogical.Vector128.UInt32"] = ShiftLogical_Vector128_UInt32, + ["ShiftLogical.Vector128.UInt64"] = ShiftLogical_Vector128_UInt64, + ["ShiftLogicalRounded.Vector64.Byte"] = ShiftLogicalRounded_Vector64_Byte, + ["ShiftLogicalRounded.Vector64.Int16"] = ShiftLogicalRounded_Vector64_Int16, + ["ShiftLogicalRounded.Vector64.Int32"] = ShiftLogicalRounded_Vector64_Int32, + ["ShiftLogicalRounded.Vector64.SByte"] = ShiftLogicalRounded_Vector64_SByte, + ["ShiftLogicalRounded.Vector64.UInt16"] = ShiftLogicalRounded_Vector64_UInt16, + ["ShiftLogicalRounded.Vector64.UInt32"] = ShiftLogicalRounded_Vector64_UInt32, + ["ShiftLogicalRounded.Vector128.Byte"] = ShiftLogicalRounded_Vector128_Byte, + ["ShiftLogicalRounded.Vector128.Int16"] = ShiftLogicalRounded_Vector128_Int16, + ["ShiftLogicalRounded.Vector128.Int32"] = ShiftLogicalRounded_Vector128_Int32, + ["ShiftLogicalRounded.Vector128.Int64"] = ShiftLogicalRounded_Vector128_Int64, + ["ShiftLogicalRounded.Vector128.SByte"] = ShiftLogicalRounded_Vector128_SByte, + ["ShiftLogicalRounded.Vector128.UInt16"] = ShiftLogicalRounded_Vector128_UInt16, + ["ShiftLogicalRounded.Vector128.UInt32"] = ShiftLogicalRounded_Vector128_UInt32, + ["ShiftLogicalRounded.Vector128.UInt64"] = ShiftLogicalRounded_Vector128_UInt64, + ["ShiftLogicalRoundedSaturate.Vector64.Byte"] = ShiftLogicalRoundedSaturate_Vector64_Byte, + ["ShiftLogicalRoundedSaturate.Vector64.Int16"] = ShiftLogicalRoundedSaturate_Vector64_Int16, + ["ShiftLogicalRoundedSaturate.Vector64.Int32"] = ShiftLogicalRoundedSaturate_Vector64_Int32, + ["ShiftLogicalRoundedSaturate.Vector64.SByte"] = ShiftLogicalRoundedSaturate_Vector64_SByte, + ["ShiftLogicalRoundedSaturate.Vector64.UInt16"] = ShiftLogicalRoundedSaturate_Vector64_UInt16, + ["ShiftLogicalRoundedSaturate.Vector64.UInt32"] = ShiftLogicalRoundedSaturate_Vector64_UInt32, + ["ShiftLogicalRoundedSaturate.Vector128.Byte"] = ShiftLogicalRoundedSaturate_Vector128_Byte, + ["ShiftLogicalRoundedSaturate.Vector128.Int16"] = ShiftLogicalRoundedSaturate_Vector128_Int16, + ["ShiftLogicalRoundedSaturate.Vector128.Int32"] = ShiftLogicalRoundedSaturate_Vector128_Int32, + ["ShiftLogicalRoundedSaturate.Vector128.Int64"] = ShiftLogicalRoundedSaturate_Vector128_Int64, + ["ShiftLogicalRoundedSaturate.Vector128.SByte"] = ShiftLogicalRoundedSaturate_Vector128_SByte, + ["ShiftLogicalRoundedSaturate.Vector128.UInt16"] = ShiftLogicalRoundedSaturate_Vector128_UInt16, + ["ShiftLogicalRoundedSaturate.Vector128.UInt32"] = ShiftLogicalRoundedSaturate_Vector128_UInt32, + ["ShiftLogicalRoundedSaturate.Vector128.UInt64"] = ShiftLogicalRoundedSaturate_Vector128_UInt64, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int64"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int64, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt64"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt64, + ["ShiftLogicalRoundedScalar.Vector64.Int64"] = ShiftLogicalRoundedScalar_Vector64_Int64, + ["ShiftLogicalRoundedScalar.Vector64.UInt64"] = ShiftLogicalRoundedScalar_Vector64_UInt64, + ["ShiftLogicalSaturate.Vector64.Byte"] = ShiftLogicalSaturate_Vector64_Byte, + ["ShiftLogicalSaturate.Vector64.Int16"] = ShiftLogicalSaturate_Vector64_Int16, + ["ShiftLogicalSaturate.Vector64.Int32"] = ShiftLogicalSaturate_Vector64_Int32, + ["ShiftLogicalSaturate.Vector64.SByte"] = ShiftLogicalSaturate_Vector64_SByte, + ["ShiftLogicalSaturate.Vector64.UInt16"] = ShiftLogicalSaturate_Vector64_UInt16, + ["ShiftLogicalSaturate.Vector64.UInt32"] = ShiftLogicalSaturate_Vector64_UInt32, + ["ShiftLogicalSaturate.Vector128.Byte"] = ShiftLogicalSaturate_Vector128_Byte, + ["ShiftLogicalSaturate.Vector128.Int16"] = ShiftLogicalSaturate_Vector128_Int16, + ["ShiftLogicalSaturate.Vector128.Int32"] = ShiftLogicalSaturate_Vector128_Int32, + ["ShiftLogicalSaturate.Vector128.Int64"] = ShiftLogicalSaturate_Vector128_Int64, + ["ShiftLogicalSaturate.Vector128.SByte"] = ShiftLogicalSaturate_Vector128_SByte, + ["ShiftLogicalSaturate.Vector128.UInt16"] = ShiftLogicalSaturate_Vector128_UInt16, + ["ShiftLogicalSaturate.Vector128.UInt32"] = ShiftLogicalSaturate_Vector128_UInt32, + ["ShiftLogicalSaturate.Vector128.UInt64"] = ShiftLogicalSaturate_Vector128_UInt64, + ["ShiftLogicalSaturateScalar.Vector64.Int64"] = ShiftLogicalSaturateScalar_Vector64_Int64, + ["ShiftLogicalSaturateScalar.Vector64.UInt64"] = ShiftLogicalSaturateScalar_Vector64_UInt64, + ["ShiftLogicalScalar.Vector64.Int64"] = ShiftLogicalScalar_Vector64_Int64, + ["ShiftLogicalScalar.Vector64.UInt64"] = ShiftLogicalScalar_Vector64_UInt64, + ["ShiftRightAndInsert.Vector64.Byte"] = ShiftRightAndInsert_Vector64_Byte, + ["ShiftRightAndInsert.Vector64.Int16"] = ShiftRightAndInsert_Vector64_Int16, + ["ShiftRightAndInsert.Vector64.Int32"] = ShiftRightAndInsert_Vector64_Int32, + ["ShiftRightAndInsert.Vector64.SByte"] = ShiftRightAndInsert_Vector64_SByte, + ["ShiftRightAndInsert.Vector64.UInt16"] = ShiftRightAndInsert_Vector64_UInt16, + ["ShiftRightAndInsert.Vector64.UInt32"] = ShiftRightAndInsert_Vector64_UInt32, + ["ShiftRightAndInsert.Vector128.Byte"] = ShiftRightAndInsert_Vector128_Byte, + ["ShiftRightAndInsert.Vector128.Int16"] = ShiftRightAndInsert_Vector128_Int16, + ["ShiftRightAndInsert.Vector128.Int32"] = ShiftRightAndInsert_Vector128_Int32, + ["ShiftRightAndInsert.Vector128.Int64"] = ShiftRightAndInsert_Vector128_Int64, + ["ShiftRightAndInsert.Vector128.SByte"] = ShiftRightAndInsert_Vector128_SByte, + ["ShiftRightAndInsert.Vector128.UInt16"] = ShiftRightAndInsert_Vector128_UInt16, + ["ShiftRightAndInsert.Vector128.UInt32"] = ShiftRightAndInsert_Vector128_UInt32, + ["ShiftRightAndInsert.Vector128.UInt64"] = ShiftRightAndInsert_Vector128_UInt64, + ["ShiftRightAndInsertScalar.Vector64.Int64"] = ShiftRightAndInsertScalar_Vector64_Int64, + ["ShiftRightAndInsertScalar.Vector64.UInt64"] = ShiftRightAndInsertScalar_Vector64_UInt64, + ["ShiftRightArithmetic.Vector64.Int16.1"] = ShiftRightArithmetic_Vector64_Int16_1, + ["ShiftRightArithmetic.Vector64.Int32.1"] = ShiftRightArithmetic_Vector64_Int32_1, + ["ShiftRightArithmetic.Vector64.SByte.1"] = ShiftRightArithmetic_Vector64_SByte_1, + ["ShiftRightArithmetic.Vector128.Int16.1"] = ShiftRightArithmetic_Vector128_Int16_1, + ["ShiftRightArithmetic.Vector128.Int32.1"] = ShiftRightArithmetic_Vector128_Int32_1, + ["ShiftRightArithmetic.Vector128.Int64.1"] = ShiftRightArithmetic_Vector128_Int64_1, + ["ShiftRightArithmetic.Vector128.SByte.1"] = ShiftRightArithmetic_Vector128_SByte_1, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part13.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part13.cs new file mode 100644 index 000000000000..a076639659e6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part13.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["ShiftRightArithmeticAdd.Vector64.Int16.1"] = ShiftRightArithmeticAdd_Vector64_Int16_1, + ["ShiftRightArithmeticAdd.Vector64.Int32.1"] = ShiftRightArithmeticAdd_Vector64_Int32_1, + ["ShiftRightArithmeticAdd.Vector64.SByte.1"] = ShiftRightArithmeticAdd_Vector64_SByte_1, + ["ShiftRightArithmeticAdd.Vector128.Int16.1"] = ShiftRightArithmeticAdd_Vector128_Int16_1, + ["ShiftRightArithmeticAdd.Vector128.Int32.1"] = ShiftRightArithmeticAdd_Vector128_Int32_1, + ["ShiftRightArithmeticAdd.Vector128.Int64.1"] = ShiftRightArithmeticAdd_Vector128_Int64_1, + ["ShiftRightArithmeticAdd.Vector128.SByte.1"] = ShiftRightArithmeticAdd_Vector128_SByte_1, + ["ShiftRightArithmeticAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticAddScalar_Vector64_Int64_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightArithmeticRounded.Vector64.Int16.1"] = ShiftRightArithmeticRounded_Vector64_Int16_1, + ["ShiftRightArithmeticRounded.Vector64.Int32.1"] = ShiftRightArithmeticRounded_Vector64_Int32_1, + ["ShiftRightArithmeticRounded.Vector64.SByte.1"] = ShiftRightArithmeticRounded_Vector64_SByte_1, + ["ShiftRightArithmeticRounded.Vector128.Int16.1"] = ShiftRightArithmeticRounded_Vector128_Int16_1, + ["ShiftRightArithmeticRounded.Vector128.Int32.1"] = ShiftRightArithmeticRounded_Vector128_Int32_1, + ["ShiftRightArithmeticRounded.Vector128.Int64.1"] = ShiftRightArithmeticRounded_Vector128_Int64_1, + ["ShiftRightArithmeticRounded.Vector128.SByte.1"] = ShiftRightArithmeticRounded_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int16_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int32_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector64_SByte_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int16_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int32_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int64.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int64_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedScalar_Vector64_Int64_1, + ["ShiftRightArithmeticScalar.Vector64.Int64.1"] = ShiftRightArithmeticScalar_Vector64_Int64_1, + ["ShiftRightLogical.Vector64.Byte.1"] = ShiftRightLogical_Vector64_Byte_1, + ["ShiftRightLogical.Vector64.Int16.1"] = ShiftRightLogical_Vector64_Int16_1, + ["ShiftRightLogical.Vector64.Int32.1"] = ShiftRightLogical_Vector64_Int32_1, + ["ShiftRightLogical.Vector64.SByte.1"] = ShiftRightLogical_Vector64_SByte_1, + ["ShiftRightLogical.Vector64.UInt16.1"] = ShiftRightLogical_Vector64_UInt16_1, + ["ShiftRightLogical.Vector64.UInt32.1"] = ShiftRightLogical_Vector64_UInt32_1, + ["ShiftRightLogical.Vector128.Byte.1"] = ShiftRightLogical_Vector128_Byte_1, + ["ShiftRightLogical.Vector128.Int16.1"] = ShiftRightLogical_Vector128_Int16_1, + ["ShiftRightLogical.Vector128.Int32.1"] = ShiftRightLogical_Vector128_Int32_1, + ["ShiftRightLogical.Vector128.Int64.1"] = ShiftRightLogical_Vector128_Int64_1, + ["ShiftRightLogical.Vector128.SByte.1"] = ShiftRightLogical_Vector128_SByte_1, + ["ShiftRightLogical.Vector128.UInt16.1"] = ShiftRightLogical_Vector128_UInt16_1, + ["ShiftRightLogical.Vector128.UInt32.1"] = ShiftRightLogical_Vector128_UInt32_1, + ["ShiftRightLogical.Vector128.UInt64.1"] = ShiftRightLogical_Vector128_UInt64_1, + ["ShiftRightLogicalAdd.Vector64.Byte.1"] = ShiftRightLogicalAdd_Vector64_Byte_1, + ["ShiftRightLogicalAdd.Vector64.Int16.1"] = ShiftRightLogicalAdd_Vector64_Int16_1, + ["ShiftRightLogicalAdd.Vector64.Int32.1"] = ShiftRightLogicalAdd_Vector64_Int32_1, + ["ShiftRightLogicalAdd.Vector64.SByte.1"] = ShiftRightLogicalAdd_Vector64_SByte_1, + ["ShiftRightLogicalAdd.Vector64.UInt16.1"] = ShiftRightLogicalAdd_Vector64_UInt16_1, + ["ShiftRightLogicalAdd.Vector64.UInt32.1"] = ShiftRightLogicalAdd_Vector64_UInt32_1, + ["ShiftRightLogicalAdd.Vector128.Byte.1"] = ShiftRightLogicalAdd_Vector128_Byte_1, + ["ShiftRightLogicalAdd.Vector128.Int16.1"] = ShiftRightLogicalAdd_Vector128_Int16_1, + ["ShiftRightLogicalAdd.Vector128.Int32.1"] = ShiftRightLogicalAdd_Vector128_Int32_1, + ["ShiftRightLogicalAdd.Vector128.Int64.1"] = ShiftRightLogicalAdd_Vector128_Int64_1, + ["ShiftRightLogicalAdd.Vector128.SByte.1"] = ShiftRightLogicalAdd_Vector128_SByte_1, + ["ShiftRightLogicalAdd.Vector128.UInt16.1"] = ShiftRightLogicalAdd_Vector128_UInt16_1, + ["ShiftRightLogicalAdd.Vector128.UInt32.1"] = ShiftRightLogicalAdd_Vector128_UInt32_1, + ["ShiftRightLogicalAdd.Vector128.UInt64.1"] = ShiftRightLogicalAdd_Vector128_UInt64_1, + ["ShiftRightLogicalAddScalar.Vector64.Int64.1"] = ShiftRightLogicalAddScalar_Vector64_Int64_1, + ["ShiftRightLogicalAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalAddScalar_Vector64_UInt64_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingLower_Vector64_Byte_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int16_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int32_1, + ["ShiftRightLogicalNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingLower_Vector64_SByte_1, + ["ShiftRightLogicalNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt16_1, + ["ShiftRightLogicalNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Byte_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int16_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int32_1, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part14.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part14.cs new file mode 100644 index 000000000000..731a5a567fea --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part14.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["ShiftRightLogicalNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_SByte_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRounded.Vector64.Byte.1"] = ShiftRightLogicalRounded_Vector64_Byte_1, + ["ShiftRightLogicalRounded.Vector64.Int16.1"] = ShiftRightLogicalRounded_Vector64_Int16_1, + ["ShiftRightLogicalRounded.Vector64.Int32.1"] = ShiftRightLogicalRounded_Vector64_Int32_1, + ["ShiftRightLogicalRounded.Vector64.SByte.1"] = ShiftRightLogicalRounded_Vector64_SByte_1, + ["ShiftRightLogicalRounded.Vector64.UInt16.1"] = ShiftRightLogicalRounded_Vector64_UInt16_1, + ["ShiftRightLogicalRounded.Vector64.UInt32.1"] = ShiftRightLogicalRounded_Vector64_UInt32_1, + ["ShiftRightLogicalRounded.Vector128.Byte.1"] = ShiftRightLogicalRounded_Vector128_Byte_1, + ["ShiftRightLogicalRounded.Vector128.Int16.1"] = ShiftRightLogicalRounded_Vector128_Int16_1, + ["ShiftRightLogicalRounded.Vector128.Int32.1"] = ShiftRightLogicalRounded_Vector128_Int32_1, + ["ShiftRightLogicalRounded.Vector128.Int64.1"] = ShiftRightLogicalRounded_Vector128_Int64_1, + ["ShiftRightLogicalRounded.Vector128.SByte.1"] = ShiftRightLogicalRounded_Vector128_SByte_1, + ["ShiftRightLogicalRounded.Vector128.UInt16.1"] = ShiftRightLogicalRounded_Vector128_UInt16_1, + ["ShiftRightLogicalRounded.Vector128.UInt32.1"] = ShiftRightLogicalRounded_Vector128_UInt32_1, + ["ShiftRightLogicalRounded.Vector128.UInt64.1"] = ShiftRightLogicalRounded_Vector128_UInt64_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector64_Byte_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int16_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int32_1, + ["ShiftRightLogicalRoundedAdd.Vector64.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector64_SByte_1, + ["ShiftRightLogicalRoundedAdd.Vector64.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedAdd.Vector64.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector128_Byte_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int16_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int64.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int64_1, + ["ShiftRightLogicalRoundedAdd.Vector128.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector128_SByte_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt64.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt64_1, + ["ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1, + ["ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedScalar_Vector64_Int64_1, + ["ShiftRightLogicalRoundedScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedScalar_Vector64_UInt64_1, + ["ShiftRightLogicalScalar.Vector64.Int64.1"] = ShiftRightLogicalScalar_Vector64_Int64_1, + ["ShiftRightLogicalScalar.Vector64.UInt64.1"] = ShiftRightLogicalScalar_Vector64_UInt64_1, + ["SignExtendWideningLower.Vector64.Int16"] = SignExtendWideningLower_Vector64_Int16, + ["SignExtendWideningLower.Vector64.Int32"] = SignExtendWideningLower_Vector64_Int32, + ["SignExtendWideningLower.Vector64.SByte"] = SignExtendWideningLower_Vector64_SByte, + ["SignExtendWideningUpper.Vector128.Int16"] = SignExtendWideningUpper_Vector128_Int16, + ["SignExtendWideningUpper.Vector128.Int32"] = SignExtendWideningUpper_Vector128_Int32, + ["SignExtendWideningUpper.Vector128.SByte"] = SignExtendWideningUpper_Vector128_SByte, + ["SqrtScalar.Vector64.Double"] = SqrtScalar_Vector64_Double, + ["SqrtScalar.Vector64.Single"] = SqrtScalar_Vector64_Single, + ["Store.Vector64.Byte"] = Store_Vector64_Byte, + ["Store.Vector64.Double"] = Store_Vector64_Double, + ["Store.Vector64.Int16"] = Store_Vector64_Int16, + ["Store.Vector64.Int32"] = Store_Vector64_Int32, + ["Store.Vector64.Int64"] = Store_Vector64_Int64, + ["Store.Vector64.SByte"] = Store_Vector64_SByte, + ["Store.Vector64.Single"] = Store_Vector64_Single, + ["Store.Vector64.UInt16"] = Store_Vector64_UInt16, + ["Store.Vector64.UInt32"] = Store_Vector64_UInt32, + ["Store.Vector64.UInt64"] = Store_Vector64_UInt64, + ["Store.Vector128.Byte"] = Store_Vector128_Byte, + ["Store.Vector128.Double"] = Store_Vector128_Double, + ["Store.Vector128.Int16"] = Store_Vector128_Int16, + ["Store.Vector128.Int32"] = Store_Vector128_Int32, + ["Store.Vector128.Int64"] = Store_Vector128_Int64, + ["Store.Vector128.SByte"] = Store_Vector128_SByte, + ["Store.Vector128.Single"] = Store_Vector128_Single, + ["Store.Vector128.UInt16"] = Store_Vector128_UInt16, + ["Store.Vector128.UInt32"] = Store_Vector128_UInt32, + ["Store.Vector128.UInt64"] = Store_Vector128_UInt64, + ["StoreSelectedScalar.Vector64.Byte.7"] = StoreSelectedScalar_Vector64_Byte_7, + ["StoreSelectedScalar.Vector64.Int16.3"] = StoreSelectedScalar_Vector64_Int16_3, + ["StoreSelectedScalar.Vector64.Int32.1"] = StoreSelectedScalar_Vector64_Int32_1, + ["StoreSelectedScalar.Vector64.SByte.7"] = StoreSelectedScalar_Vector64_SByte_7, + ["StoreSelectedScalar.Vector64.Single.1"] = StoreSelectedScalar_Vector64_Single_1, + ["StoreSelectedScalar.Vector64.UInt16.3"] = StoreSelectedScalar_Vector64_UInt16_3, + ["StoreSelectedScalar.Vector64.UInt32.1"] = StoreSelectedScalar_Vector64_UInt32_1, + ["StoreSelectedScalar.Vector128.Byte.15"] = StoreSelectedScalar_Vector128_Byte_15, + ["StoreSelectedScalar.Vector128.Double.1"] = StoreSelectedScalar_Vector128_Double_1, + ["StoreSelectedScalar.Vector128.Int16.7"] = StoreSelectedScalar_Vector128_Int16_7, + ["StoreSelectedScalar.Vector128.Int32.3"] = StoreSelectedScalar_Vector128_Int32_3, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part15.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part15.cs new file mode 100644 index 000000000000..7cf4294fb003 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part15.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["StoreSelectedScalar.Vector128.Int64.1"] = StoreSelectedScalar_Vector128_Int64_1, + ["StoreSelectedScalar.Vector128.SByte.15"] = StoreSelectedScalar_Vector128_SByte_15, + ["StoreSelectedScalar.Vector128.Single.3"] = StoreSelectedScalar_Vector128_Single_3, + ["StoreSelectedScalar.Vector128.UInt16.7"] = StoreSelectedScalar_Vector128_UInt16_7, + ["StoreSelectedScalar.Vector128.UInt32.3"] = StoreSelectedScalar_Vector128_UInt32_3, + ["StoreSelectedScalar.Vector128.UInt64.1"] = StoreSelectedScalar_Vector128_UInt64_1, + ["Subtract.Vector64.Byte"] = Subtract_Vector64_Byte, + ["Subtract.Vector64.Int16"] = Subtract_Vector64_Int16, + ["Subtract.Vector64.Int32"] = Subtract_Vector64_Int32, + ["Subtract.Vector64.SByte"] = Subtract_Vector64_SByte, + ["Subtract.Vector64.Single"] = Subtract_Vector64_Single, + ["Subtract.Vector64.UInt16"] = Subtract_Vector64_UInt16, + ["Subtract.Vector64.UInt32"] = Subtract_Vector64_UInt32, + ["Subtract.Vector128.Byte"] = Subtract_Vector128_Byte, + ["Subtract.Vector128.Int16"] = Subtract_Vector128_Int16, + ["Subtract.Vector128.Int32"] = Subtract_Vector128_Int32, + ["Subtract.Vector128.Int64"] = Subtract_Vector128_Int64, + ["Subtract.Vector128.SByte"] = Subtract_Vector128_SByte, + ["Subtract.Vector128.Single"] = Subtract_Vector128_Single, + ["Subtract.Vector128.UInt16"] = Subtract_Vector128_UInt16, + ["Subtract.Vector128.UInt32"] = Subtract_Vector128_UInt32, + ["Subtract.Vector128.UInt64"] = Subtract_Vector128_UInt64, + ["SubtractHighNarrowingLower.Vector64.Byte"] = SubtractHighNarrowingLower_Vector64_Byte, + ["SubtractHighNarrowingLower.Vector64.Int16"] = SubtractHighNarrowingLower_Vector64_Int16, + ["SubtractHighNarrowingLower.Vector64.Int32"] = SubtractHighNarrowingLower_Vector64_Int32, + ["SubtractHighNarrowingLower.Vector64.SByte"] = SubtractHighNarrowingLower_Vector64_SByte, + ["SubtractHighNarrowingLower.Vector64.UInt16"] = SubtractHighNarrowingLower_Vector64_UInt16, + ["SubtractHighNarrowingLower.Vector64.UInt32"] = SubtractHighNarrowingLower_Vector64_UInt32, + ["SubtractHighNarrowingUpper.Vector128.Byte"] = SubtractHighNarrowingUpper_Vector128_Byte, + ["SubtractHighNarrowingUpper.Vector128.Int16"] = SubtractHighNarrowingUpper_Vector128_Int16, + ["SubtractHighNarrowingUpper.Vector128.Int32"] = SubtractHighNarrowingUpper_Vector128_Int32, + ["SubtractHighNarrowingUpper.Vector128.SByte"] = SubtractHighNarrowingUpper_Vector128_SByte, + ["SubtractHighNarrowingUpper.Vector128.UInt16"] = SubtractHighNarrowingUpper_Vector128_UInt16, + ["SubtractHighNarrowingUpper.Vector128.UInt32"] = SubtractHighNarrowingUpper_Vector128_UInt32, + ["SubtractRoundedHighNarrowingLower.Vector64.Byte"] = SubtractRoundedHighNarrowingLower_Vector64_Byte, + ["SubtractRoundedHighNarrowingLower.Vector64.Int16"] = SubtractRoundedHighNarrowingLower_Vector64_Int16, + ["SubtractRoundedHighNarrowingLower.Vector64.Int32"] = SubtractRoundedHighNarrowingLower_Vector64_Int32, + ["SubtractRoundedHighNarrowingLower.Vector64.SByte"] = SubtractRoundedHighNarrowingLower_Vector64_SByte, + ["SubtractRoundedHighNarrowingLower.Vector64.UInt16"] = SubtractRoundedHighNarrowingLower_Vector64_UInt16, + ["SubtractRoundedHighNarrowingLower.Vector64.UInt32"] = SubtractRoundedHighNarrowingLower_Vector64_UInt32, + ["SubtractRoundedHighNarrowingUpper.Vector128.Byte"] = SubtractRoundedHighNarrowingUpper_Vector128_Byte, + ["SubtractRoundedHighNarrowingUpper.Vector128.Int16"] = SubtractRoundedHighNarrowingUpper_Vector128_Int16, + ["SubtractRoundedHighNarrowingUpper.Vector128.Int32"] = SubtractRoundedHighNarrowingUpper_Vector128_Int32, + ["SubtractRoundedHighNarrowingUpper.Vector128.SByte"] = SubtractRoundedHighNarrowingUpper_Vector128_SByte, + ["SubtractRoundedHighNarrowingUpper.Vector128.UInt16"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt16, + ["SubtractRoundedHighNarrowingUpper.Vector128.UInt32"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt32, + ["SubtractSaturate.Vector64.Byte"] = SubtractSaturate_Vector64_Byte, + ["SubtractSaturate.Vector64.Int16"] = SubtractSaturate_Vector64_Int16, + ["SubtractSaturate.Vector64.Int32"] = SubtractSaturate_Vector64_Int32, + ["SubtractSaturate.Vector64.SByte"] = SubtractSaturate_Vector64_SByte, + ["SubtractSaturate.Vector64.UInt16"] = SubtractSaturate_Vector64_UInt16, + ["SubtractSaturate.Vector64.UInt32"] = SubtractSaturate_Vector64_UInt32, + ["SubtractSaturate.Vector128.Byte"] = SubtractSaturate_Vector128_Byte, + ["SubtractSaturate.Vector128.Int16"] = SubtractSaturate_Vector128_Int16, + ["SubtractSaturate.Vector128.Int32"] = SubtractSaturate_Vector128_Int32, + ["SubtractSaturate.Vector128.Int64"] = SubtractSaturate_Vector128_Int64, + ["SubtractSaturate.Vector128.SByte"] = SubtractSaturate_Vector128_SByte, + ["SubtractSaturate.Vector128.UInt16"] = SubtractSaturate_Vector128_UInt16, + ["SubtractSaturate.Vector128.UInt32"] = SubtractSaturate_Vector128_UInt32, + ["SubtractSaturate.Vector128.UInt64"] = SubtractSaturate_Vector128_UInt64, + ["SubtractSaturateScalar.Vector64.Int64"] = SubtractSaturateScalar_Vector64_Int64, + ["SubtractSaturateScalar.Vector64.UInt64"] = SubtractSaturateScalar_Vector64_UInt64, + ["SubtractScalar.Vector64.Double"] = SubtractScalar_Vector64_Double, + ["SubtractScalar.Vector64.Int64"] = SubtractScalar_Vector64_Int64, + ["SubtractScalar.Vector64.Single"] = SubtractScalar_Vector64_Single, + ["SubtractScalar.Vector64.UInt64"] = SubtractScalar_Vector64_UInt64, + ["SubtractWideningLower.Vector64.Byte"] = SubtractWideningLower_Vector64_Byte, + ["SubtractWideningLower.Vector64.Int16"] = SubtractWideningLower_Vector64_Int16, + ["SubtractWideningLower.Vector64.Int32"] = SubtractWideningLower_Vector64_Int32, + ["SubtractWideningLower.Vector64.SByte"] = SubtractWideningLower_Vector64_SByte, + ["SubtractWideningLower.Vector64.UInt16"] = SubtractWideningLower_Vector64_UInt16, + ["SubtractWideningLower.Vector64.UInt32"] = SubtractWideningLower_Vector64_UInt32, + ["SubtractWideningLower.Vector128.Int16"] = SubtractWideningLower_Vector128_Int16, + ["SubtractWideningLower.Vector128.Int32"] = SubtractWideningLower_Vector128_Int32, + ["SubtractWideningLower.Vector128.Int64"] = SubtractWideningLower_Vector128_Int64, + ["SubtractWideningLower.Vector128.UInt16"] = SubtractWideningLower_Vector128_UInt16, + ["SubtractWideningLower.Vector128.UInt32"] = SubtractWideningLower_Vector128_UInt32, + ["SubtractWideningLower.Vector128.UInt64"] = SubtractWideningLower_Vector128_UInt64, + ["SubtractWideningUpper.Vector128.Byte.Vector128.Byte"] = SubtractWideningUpper_Vector128_Byte_Vector128_Byte, + ["SubtractWideningUpper.Vector128.Int16.Vector128.Int16"] = SubtractWideningUpper_Vector128_Int16_Vector128_Int16, + ["SubtractWideningUpper.Vector128.Int16.Vector128.SByte"] = SubtractWideningUpper_Vector128_Int16_Vector128_SByte, + ["SubtractWideningUpper.Vector128.Int32.Vector128.Int16"] = SubtractWideningUpper_Vector128_Int32_Vector128_Int16, + ["SubtractWideningUpper.Vector128.Int32.Vector128.Int32"] = SubtractWideningUpper_Vector128_Int32_Vector128_Int32, + ["SubtractWideningUpper.Vector128.Int64.Vector128.Int32"] = SubtractWideningUpper_Vector128_Int64_Vector128_Int32, + ["SubtractWideningUpper.Vector128.SByte.Vector128.SByte"] = SubtractWideningUpper_Vector128_SByte_Vector128_SByte, + ["SubtractWideningUpper.Vector128.UInt16.Vector128.Byte"] = SubtractWideningUpper_Vector128_UInt16_Vector128_Byte, + ["SubtractWideningUpper.Vector128.UInt16.Vector128.UInt16"] = SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16, + ["SubtractWideningUpper.Vector128.UInt32.Vector128.UInt16"] = SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16, + ["SubtractWideningUpper.Vector128.UInt32.Vector128.UInt32"] = SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32, + ["SubtractWideningUpper.Vector128.UInt64.Vector128.UInt32"] = SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32, + ["VectorTableLookup.Vector64.Byte"] = VectorTableLookup_Vector64_Byte, + ["VectorTableLookup.Vector64.SByte"] = VectorTableLookup_Vector64_SByte, + ["VectorTableLookupExtension.Vector64.Byte"] = VectorTableLookupExtension_Vector64_Byte, + ["VectorTableLookupExtension.Vector64.SByte"] = VectorTableLookupExtension_Vector64_SByte, + ["Xor.Vector64.Byte"] = Xor_Vector64_Byte, + ["Xor.Vector64.Double"] = Xor_Vector64_Double, + ["Xor.Vector64.Int16"] = Xor_Vector64_Int16, + ["Xor.Vector64.Int32"] = Xor_Vector64_Int32, + ["Xor.Vector64.Int64"] = Xor_Vector64_Int64, + ["Xor.Vector64.SByte"] = Xor_Vector64_SByte, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part16.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part16.cs new file mode 100644 index 000000000000..c77860df01f6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part16.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["Xor.Vector64.Single"] = Xor_Vector64_Single, + ["Xor.Vector64.UInt16"] = Xor_Vector64_UInt16, + ["Xor.Vector64.UInt32"] = Xor_Vector64_UInt32, + ["Xor.Vector64.UInt64"] = Xor_Vector64_UInt64, + ["Xor.Vector128.Byte"] = Xor_Vector128_Byte, + ["Xor.Vector128.Double"] = Xor_Vector128_Double, + ["Xor.Vector128.Int16"] = Xor_Vector128_Int16, + ["Xor.Vector128.Int32"] = Xor_Vector128_Int32, + ["Xor.Vector128.Int64"] = Xor_Vector128_Int64, + ["Xor.Vector128.SByte"] = Xor_Vector128_SByte, + ["Xor.Vector128.Single"] = Xor_Vector128_Single, + ["Xor.Vector128.UInt16"] = Xor_Vector128_UInt16, + ["Xor.Vector128.UInt32"] = Xor_Vector128_UInt32, + ["Xor.Vector128.UInt64"] = Xor_Vector128_UInt64, + ["ZeroExtendWideningLower.Vector64.Byte"] = ZeroExtendWideningLower_Vector64_Byte, + ["ZeroExtendWideningLower.Vector64.Int16"] = ZeroExtendWideningLower_Vector64_Int16, + ["ZeroExtendWideningLower.Vector64.Int32"] = ZeroExtendWideningLower_Vector64_Int32, + ["ZeroExtendWideningLower.Vector64.SByte"] = ZeroExtendWideningLower_Vector64_SByte, + ["ZeroExtendWideningLower.Vector64.UInt16"] = ZeroExtendWideningLower_Vector64_UInt16, + ["ZeroExtendWideningLower.Vector64.UInt32"] = ZeroExtendWideningLower_Vector64_UInt32, + ["ZeroExtendWideningUpper.Vector128.Byte"] = ZeroExtendWideningUpper_Vector128_Byte, + ["ZeroExtendWideningUpper.Vector128.Int16"] = ZeroExtendWideningUpper_Vector128_Int16, + ["ZeroExtendWideningUpper.Vector128.Int32"] = ZeroExtendWideningUpper_Vector128_Int32, + ["ZeroExtendWideningUpper.Vector128.SByte"] = ZeroExtendWideningUpper_Vector128_SByte, + ["ZeroExtendWideningUpper.Vector128.UInt16"] = ZeroExtendWideningUpper_Vector128_UInt16, + ["ZeroExtendWideningUpper.Vector128.UInt32"] = ZeroExtendWideningUpper_Vector128_UInt32, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part2.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part2.cs index 3a5d741ddbe3..a652b488f3ae 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part2.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part2.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["FusedAddRoundedHalving.Vector64.Int16"] = FusedAddRoundedHalving_Vector64_Int16, - ["FusedAddRoundedHalving.Vector64.Int32"] = FusedAddRoundedHalving_Vector64_Int32, - ["FusedAddRoundedHalving.Vector64.SByte"] = FusedAddRoundedHalving_Vector64_SByte, - ["FusedAddRoundedHalving.Vector64.UInt16"] = FusedAddRoundedHalving_Vector64_UInt16, - ["FusedAddRoundedHalving.Vector64.UInt32"] = FusedAddRoundedHalving_Vector64_UInt32, - ["FusedAddRoundedHalving.Vector128.Byte"] = FusedAddRoundedHalving_Vector128_Byte, - ["FusedAddRoundedHalving.Vector128.Int16"] = FusedAddRoundedHalving_Vector128_Int16, - ["FusedAddRoundedHalving.Vector128.Int32"] = FusedAddRoundedHalving_Vector128_Int32, - ["FusedAddRoundedHalving.Vector128.SByte"] = FusedAddRoundedHalving_Vector128_SByte, - ["FusedAddRoundedHalving.Vector128.UInt16"] = FusedAddRoundedHalving_Vector128_UInt16, - ["FusedAddRoundedHalving.Vector128.UInt32"] = FusedAddRoundedHalving_Vector128_UInt32, - ["FusedMultiplyAdd.Vector64.Single"] = FusedMultiplyAdd_Vector64_Single, - ["FusedMultiplyAdd.Vector128.Single"] = FusedMultiplyAdd_Vector128_Single, - ["FusedMultiplyAddScalar.Vector64.Double"] = FusedMultiplyAddScalar_Vector64_Double, - ["FusedMultiplyAddScalar.Vector64.Single"] = FusedMultiplyAddScalar_Vector64_Single, - ["FusedMultiplyAddNegatedScalar.Vector64.Double"] = FusedMultiplyAddNegatedScalar_Vector64_Double, - ["FusedMultiplyAddNegatedScalar.Vector64.Single"] = FusedMultiplyAddNegatedScalar_Vector64_Single, - ["FusedMultiplySubtract.Vector64.Single"] = FusedMultiplySubtract_Vector64_Single, - ["FusedMultiplySubtract.Vector128.Single"] = FusedMultiplySubtract_Vector128_Single, - ["FusedMultiplySubtractScalar.Vector64.Double"] = FusedMultiplySubtractScalar_Vector64_Double, - ["FusedMultiplySubtractScalar.Vector64.Single"] = FusedMultiplySubtractScalar_Vector64_Single, - ["FusedMultiplySubtractNegatedScalar.Vector64.Double"] = FusedMultiplySubtractNegatedScalar_Vector64_Double, - ["FusedMultiplySubtractNegatedScalar.Vector64.Single"] = FusedMultiplySubtractNegatedScalar_Vector64_Single, - ["FusedSubtractHalving.Vector64.Byte"] = FusedSubtractHalving_Vector64_Byte, - ["FusedSubtractHalving.Vector64.Int16"] = FusedSubtractHalving_Vector64_Int16, - ["FusedSubtractHalving.Vector64.Int32"] = FusedSubtractHalving_Vector64_Int32, - ["FusedSubtractHalving.Vector64.SByte"] = FusedSubtractHalving_Vector64_SByte, - ["FusedSubtractHalving.Vector64.UInt16"] = FusedSubtractHalving_Vector64_UInt16, - ["FusedSubtractHalving.Vector64.UInt32"] = FusedSubtractHalving_Vector64_UInt32, - ["FusedSubtractHalving.Vector128.Byte"] = FusedSubtractHalving_Vector128_Byte, - ["FusedSubtractHalving.Vector128.Int16"] = FusedSubtractHalving_Vector128_Int16, - ["FusedSubtractHalving.Vector128.Int32"] = FusedSubtractHalving_Vector128_Int32, - ["FusedSubtractHalving.Vector128.SByte"] = FusedSubtractHalving_Vector128_SByte, - ["FusedSubtractHalving.Vector128.UInt16"] = FusedSubtractHalving_Vector128_UInt16, - ["FusedSubtractHalving.Vector128.UInt32"] = FusedSubtractHalving_Vector128_UInt32, - ["Insert.Vector64.Byte.1"] = Insert_Vector64_Byte_1, - ["Insert.Vector64.Int16.1"] = Insert_Vector64_Int16_1, - ["Insert.Vector64.Int32.1"] = Insert_Vector64_Int32_1, - ["Insert.Vector64.SByte.1"] = Insert_Vector64_SByte_1, - ["Insert.Vector64.Single.1"] = Insert_Vector64_Single_1, - ["Insert.Vector64.UInt16.1"] = Insert_Vector64_UInt16_1, - ["Insert.Vector64.UInt32.1"] = Insert_Vector64_UInt32_1, - ["Insert.Vector128.Byte.1"] = Insert_Vector128_Byte_1, - ["Insert.Vector128.Double.1"] = Insert_Vector128_Double_1, - ["Insert.Vector128.Int16.1"] = Insert_Vector128_Int16_1, - ["Insert.Vector128.Int32.1"] = Insert_Vector128_Int32_1, - ["Insert.Vector128.Int64.1"] = Insert_Vector128_Int64_1, - ["Insert.Vector128.SByte.1"] = Insert_Vector128_SByte_1, - ["Insert.Vector128.Single.1"] = Insert_Vector128_Single_1, - ["Insert.Vector128.UInt16.1"] = Insert_Vector128_UInt16_1, - ["Insert.Vector128.UInt32.1"] = Insert_Vector128_UInt32_1, - ["Insert.Vector128.UInt64.1"] = Insert_Vector128_UInt64_1, - ["InsertScalar.Vector128.Double.1"] = InsertScalar_Vector128_Double_1, - ["InsertScalar.Vector128.Int64.1"] = InsertScalar_Vector128_Int64_1, - ["InsertScalar.Vector128.UInt64.1"] = InsertScalar_Vector128_UInt64_1, - ["LeadingSignCount.Vector64.Int16"] = LeadingSignCount_Vector64_Int16, - ["LeadingSignCount.Vector64.Int32"] = LeadingSignCount_Vector64_Int32, - ["LeadingSignCount.Vector64.SByte"] = LeadingSignCount_Vector64_SByte, - ["LeadingSignCount.Vector128.Int16"] = LeadingSignCount_Vector128_Int16, - ["LeadingSignCount.Vector128.Int32"] = LeadingSignCount_Vector128_Int32, - ["LeadingSignCount.Vector128.SByte"] = LeadingSignCount_Vector128_SByte, - ["LeadingZeroCount.Vector64.Byte"] = LeadingZeroCount_Vector64_Byte, - ["LeadingZeroCount.Vector64.Int16"] = LeadingZeroCount_Vector64_Int16, - ["LeadingZeroCount.Vector64.Int32"] = LeadingZeroCount_Vector64_Int32, - ["LeadingZeroCount.Vector64.SByte"] = LeadingZeroCount_Vector64_SByte, - ["LeadingZeroCount.Vector64.UInt16"] = LeadingZeroCount_Vector64_UInt16, - ["LeadingZeroCount.Vector64.UInt32"] = LeadingZeroCount_Vector64_UInt32, - ["LeadingZeroCount.Vector128.Byte"] = LeadingZeroCount_Vector128_Byte, - ["LeadingZeroCount.Vector128.Int16"] = LeadingZeroCount_Vector128_Int16, - ["LeadingZeroCount.Vector128.Int32"] = LeadingZeroCount_Vector128_Int32, - ["LeadingZeroCount.Vector128.SByte"] = LeadingZeroCount_Vector128_SByte, - ["LeadingZeroCount.Vector128.UInt16"] = LeadingZeroCount_Vector128_UInt16, - ["LeadingZeroCount.Vector128.UInt32"] = LeadingZeroCount_Vector128_UInt32, - ["LoadAndInsertScalar.Vector64.Byte.7"] = LoadAndInsertScalar_Vector64_Byte_7, - ["LoadAndInsertScalar.Vector64.Int16.3"] = LoadAndInsertScalar_Vector64_Int16_3, - ["LoadAndInsertScalar.Vector64.Int32.1"] = LoadAndInsertScalar_Vector64_Int32_1, - ["LoadAndInsertScalar.Vector64.SByte.7"] = LoadAndInsertScalar_Vector64_SByte_7, - ["LoadAndInsertScalar.Vector64.Single.1"] = LoadAndInsertScalar_Vector64_Single_1, - ["LoadAndInsertScalar.Vector64.UInt16.3"] = LoadAndInsertScalar_Vector64_UInt16_3, - ["LoadAndInsertScalar.Vector64.UInt32.1"] = LoadAndInsertScalar_Vector64_UInt32_1, - ["LoadAndInsertScalar.Vector128.Byte.15"] = LoadAndInsertScalar_Vector128_Byte_15, - ["LoadAndInsertScalar.Vector128.Double.1"] = LoadAndInsertScalar_Vector128_Double_1, - ["LoadAndInsertScalar.Vector128.Int16.7"] = LoadAndInsertScalar_Vector128_Int16_7, - ["LoadAndInsertScalar.Vector128.Int32.3"] = LoadAndInsertScalar_Vector128_Int32_3, - ["LoadAndInsertScalar.Vector128.Int64.1"] = LoadAndInsertScalar_Vector128_Int64_1, - ["LoadAndInsertScalar.Vector128.SByte.15"] = LoadAndInsertScalar_Vector128_SByte_15, - ["LoadAndInsertScalar.Vector128.Single.3"] = LoadAndInsertScalar_Vector128_Single_3, - ["LoadAndInsertScalar.Vector128.UInt16.7"] = LoadAndInsertScalar_Vector128_UInt16_7, - ["LoadAndInsertScalar.Vector128.UInt32.3"] = LoadAndInsertScalar_Vector128_UInt32_3, - ["LoadAndInsertScalar.Vector128.UInt64.1"] = LoadAndInsertScalar_Vector128_UInt64_1, - ["LoadAndReplicateToVector64.Byte"] = LoadAndReplicateToVector64_Byte, - ["LoadAndReplicateToVector64.Int16"] = LoadAndReplicateToVector64_Int16, - ["LoadAndReplicateToVector64.Int32"] = LoadAndReplicateToVector64_Int32, - ["LoadAndReplicateToVector64.SByte"] = LoadAndReplicateToVector64_SByte, - ["LoadAndReplicateToVector64.Single"] = LoadAndReplicateToVector64_Single, - ["LoadAndReplicateToVector64.UInt16"] = LoadAndReplicateToVector64_UInt16, - ["LoadAndReplicateToVector64.UInt32"] = LoadAndReplicateToVector64_UInt32, - ["LoadAndReplicateToVector128.Byte"] = LoadAndReplicateToVector128_Byte, - ["LoadAndReplicateToVector128.Int16"] = LoadAndReplicateToVector128_Int16, - ["LoadAndReplicateToVector128.Int32"] = LoadAndReplicateToVector128_Int32, - ["LoadAndReplicateToVector128.SByte"] = LoadAndReplicateToVector128_SByte, - ["LoadAndReplicateToVector128.Single"] = LoadAndReplicateToVector128_Single, - ["LoadAndReplicateToVector128.UInt16"] = LoadAndReplicateToVector128_UInt16, - ["LoadAndReplicateToVector128.UInt32"] = LoadAndReplicateToVector128_UInt32, - ["LoadVector64.Byte"] = LoadVector64_Byte, - ["LoadVector64.Double"] = LoadVector64_Double, - ["LoadVector64.Int16"] = LoadVector64_Int16, - ["LoadVector64.Int32"] = LoadVector64_Int32, - ["LoadVector64.Int64"] = LoadVector64_Int64, - ["LoadVector64.SByte"] = LoadVector64_SByte, - ["LoadVector64.Single"] = LoadVector64_Single, - ["LoadVector64.UInt16"] = LoadVector64_UInt16, - ["LoadVector64.UInt32"] = LoadVector64_UInt32, - ["LoadVector64.UInt64"] = LoadVector64_UInt64, - ["LoadVector128.Byte"] = LoadVector128_Byte, - ["LoadVector128.Double"] = LoadVector128_Double, - ["LoadVector128.Int16"] = LoadVector128_Int16, - ["LoadVector128.Int32"] = LoadVector128_Int32, - ["LoadVector128.Int64"] = LoadVector128_Int64, - ["LoadVector128.SByte"] = LoadVector128_SByte, - ["LoadVector128.Single"] = LoadVector128_Single, - ["LoadVector128.UInt16"] = LoadVector128_UInt16, - ["LoadVector128.UInt32"] = LoadVector128_UInt32, - ["LoadVector128.UInt64"] = LoadVector128_UInt64, - ["Max.Vector64.Byte"] = Max_Vector64_Byte, - ["Max.Vector64.Int16"] = Max_Vector64_Int16, - ["Max.Vector64.Int32"] = Max_Vector64_Int32, - ["Max.Vector64.SByte"] = Max_Vector64_SByte, - ["Max.Vector64.Single"] = Max_Vector64_Single, - ["Max.Vector64.UInt16"] = Max_Vector64_UInt16, - ["Max.Vector64.UInt32"] = Max_Vector64_UInt32, - ["Max.Vector128.Byte"] = Max_Vector128_Byte, - ["Max.Vector128.Int16"] = Max_Vector128_Int16, - ["Max.Vector128.Int32"] = Max_Vector128_Int32, - ["Max.Vector128.SByte"] = Max_Vector128_SByte, - ["Max.Vector128.Single"] = Max_Vector128_Single, - ["Max.Vector128.UInt16"] = Max_Vector128_UInt16, - ["Max.Vector128.UInt32"] = Max_Vector128_UInt32, - ["MaxNumber.Vector64.Single"] = MaxNumber_Vector64_Single, - ["MaxNumber.Vector128.Single"] = MaxNumber_Vector128_Single, - ["MaxNumberScalar.Vector64.Double"] = MaxNumberScalar_Vector64_Double, - ["MaxNumberScalar.Vector64.Single"] = MaxNumberScalar_Vector64_Single, - ["MaxPairwise.Vector64.Byte"] = MaxPairwise_Vector64_Byte, - ["MaxPairwise.Vector64.Int16"] = MaxPairwise_Vector64_Int16, - ["MaxPairwise.Vector64.Int32"] = MaxPairwise_Vector64_Int32, - ["MaxPairwise.Vector64.SByte"] = MaxPairwise_Vector64_SByte, - ["MaxPairwise.Vector64.Single"] = MaxPairwise_Vector64_Single, - ["MaxPairwise.Vector64.UInt16"] = MaxPairwise_Vector64_UInt16, - ["MaxPairwise.Vector64.UInt32"] = MaxPairwise_Vector64_UInt32, - ["Min.Vector64.Byte"] = Min_Vector64_Byte, - ["Min.Vector64.Int16"] = Min_Vector64_Int16, - ["Min.Vector64.Int32"] = Min_Vector64_Int32, - ["Min.Vector64.SByte"] = Min_Vector64_SByte, - ["Min.Vector64.Single"] = Min_Vector64_Single, - ["Min.Vector64.UInt16"] = Min_Vector64_UInt16, - ["Min.Vector64.UInt32"] = Min_Vector64_UInt32, - ["Min.Vector128.Byte"] = Min_Vector128_Byte, - ["Min.Vector128.Int16"] = Min_Vector128_Int16, - ["Min.Vector128.Int32"] = Min_Vector128_Int32, - ["Min.Vector128.SByte"] = Min_Vector128_SByte, - ["Min.Vector128.Single"] = Min_Vector128_Single, - ["Min.Vector128.UInt16"] = Min_Vector128_UInt16, - ["Min.Vector128.UInt32"] = Min_Vector128_UInt32, - ["MinNumber.Vector64.Single"] = MinNumber_Vector64_Single, - ["MinNumber.Vector128.Single"] = MinNumber_Vector128_Single, - ["MinNumberScalar.Vector64.Double"] = MinNumberScalar_Vector64_Double, - ["MinNumberScalar.Vector64.Single"] = MinNumberScalar_Vector64_Single, - ["MinPairwise.Vector64.Byte"] = MinPairwise_Vector64_Byte, - ["MinPairwise.Vector64.Int16"] = MinPairwise_Vector64_Int16, - ["MinPairwise.Vector64.Int32"] = MinPairwise_Vector64_Int32, - ["MinPairwise.Vector64.SByte"] = MinPairwise_Vector64_SByte, - ["MinPairwise.Vector64.Single"] = MinPairwise_Vector64_Single, - ["MinPairwise.Vector64.UInt16"] = MinPairwise_Vector64_UInt16, - ["MinPairwise.Vector64.UInt32"] = MinPairwise_Vector64_UInt32, - ["Multiply.Vector64.Byte"] = Multiply_Vector64_Byte, - ["Multiply.Vector64.Int16"] = Multiply_Vector64_Int16, - ["Multiply.Vector64.Int32"] = Multiply_Vector64_Int32, - ["Multiply.Vector64.SByte"] = Multiply_Vector64_SByte, - ["Multiply.Vector64.Single"] = Multiply_Vector64_Single, - ["Multiply.Vector64.UInt16"] = Multiply_Vector64_UInt16, - ["Multiply.Vector64.UInt32"] = Multiply_Vector64_UInt32, - ["Multiply.Vector128.Byte"] = Multiply_Vector128_Byte, - ["Multiply.Vector128.Int16"] = Multiply_Vector128_Int16, - ["Multiply.Vector128.Int32"] = Multiply_Vector128_Int32, - ["Multiply.Vector128.SByte"] = Multiply_Vector128_SByte, - ["Multiply.Vector128.Single"] = Multiply_Vector128_Single, - ["Multiply.Vector128.UInt16"] = Multiply_Vector128_UInt16, - ["Multiply.Vector128.UInt32"] = Multiply_Vector128_UInt32, - ["MultiplyScalar.Vector64.Double"] = MultiplyScalar_Vector64_Double, - ["MultiplyScalar.Vector64.Single"] = MultiplyScalar_Vector64_Single, - ["MultiplyAdd.Vector64.Byte"] = MultiplyAdd_Vector64_Byte, - ["MultiplyAdd.Vector64.Int16"] = MultiplyAdd_Vector64_Int16, - ["MultiplyAdd.Vector64.Int32"] = MultiplyAdd_Vector64_Int32, - ["MultiplyAdd.Vector64.SByte"] = MultiplyAdd_Vector64_SByte, - ["MultiplyAdd.Vector64.UInt16"] = MultiplyAdd_Vector64_UInt16, - ["MultiplyAdd.Vector64.UInt32"] = MultiplyAdd_Vector64_UInt32, - ["MultiplyAdd.Vector128.Byte"] = MultiplyAdd_Vector128_Byte, - ["MultiplyAdd.Vector128.Int16"] = MultiplyAdd_Vector128_Int16, - ["MultiplyAdd.Vector128.Int32"] = MultiplyAdd_Vector128_Int32, - ["MultiplyAdd.Vector128.SByte"] = MultiplyAdd_Vector128_SByte, - ["MultiplyAdd.Vector128.UInt16"] = MultiplyAdd_Vector128_UInt16, - ["MultiplyAdd.Vector128.UInt32"] = MultiplyAdd_Vector128_UInt32, - ["MultiplyAddByScalar.Vector64.Int16"] = MultiplyAddByScalar_Vector64_Int16, - ["MultiplyAddByScalar.Vector64.Int32"] = MultiplyAddByScalar_Vector64_Int32, - ["MultiplyAddByScalar.Vector64.UInt16"] = MultiplyAddByScalar_Vector64_UInt16, - ["MultiplyAddByScalar.Vector64.UInt32"] = MultiplyAddByScalar_Vector64_UInt32, - ["MultiplyAddByScalar.Vector128.Int16"] = MultiplyAddByScalar_Vector128_Int16, - ["MultiplyAddByScalar.Vector128.Int32"] = MultiplyAddByScalar_Vector128_Int32, - ["MultiplyAddByScalar.Vector128.UInt16"] = MultiplyAddByScalar_Vector128_UInt16, - ["MultiplyAddByScalar.Vector128.UInt32"] = MultiplyAddByScalar_Vector128_UInt32, - ["MultiplyAddBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyAddBySelectedScalar_Vector64_Int16_Vector64_Int16_3, - ["MultiplyAddBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyAddBySelectedScalar_Vector64_Int16_Vector128_Int16_7, - ["MultiplyAddBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyAddBySelectedScalar_Vector64_Int32_Vector64_Int32_1, - ["MultiplyAddBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyAddBySelectedScalar_Vector64_Int32_Vector128_Int32_3, - ["MultiplyAddBySelectedScalar.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyAddBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3, - ["MultiplyAddBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyAddBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplyAddBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyAddBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplyAddBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyAddBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplyAddBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplyAddBySelectedScalar_Vector128_Int16_Vector64_Int16_3, - ["MultiplyAddBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyAddBySelectedScalar_Vector128_Int16_Vector128_Int16_7, - ["MultiplyAddBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyAddBySelectedScalar_Vector128_Int32_Vector64_Int32_1, - ["MultiplyAddBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyAddBySelectedScalar_Vector128_Int32_Vector128_Int32_3, - ["MultiplyAddBySelectedScalar.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyAddBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3, - ["MultiplyAddBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyAddBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplyAddBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyAddBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplyAddBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyAddBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, - ["MultiplyByScalar.Vector64.Int16"] = MultiplyByScalar_Vector64_Int16, - ["MultiplyByScalar.Vector64.Int32"] = MultiplyByScalar_Vector64_Int32, - ["MultiplyByScalar.Vector64.Single"] = MultiplyByScalar_Vector64_Single, - ["MultiplyByScalar.Vector64.UInt16"] = MultiplyByScalar_Vector64_UInt16, - ["MultiplyByScalar.Vector64.UInt32"] = MultiplyByScalar_Vector64_UInt32, - ["MultiplyByScalar.Vector128.Int16"] = MultiplyByScalar_Vector128_Int16, - ["MultiplyByScalar.Vector128.Int32"] = MultiplyByScalar_Vector128_Int32, - ["MultiplyByScalar.Vector128.Single"] = MultiplyByScalar_Vector128_Single, - ["MultiplyByScalar.Vector128.UInt16"] = MultiplyByScalar_Vector128_UInt16, - ["MultiplyByScalar.Vector128.UInt32"] = MultiplyByScalar_Vector128_UInt32, - ["MultiplyBySelectedScalar.Vector64.Int16.Vector64.Int16.1"] = MultiplyBySelectedScalar_Vector64_Int16_Vector64_Int16_1, - ["MultiplyBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalar_Vector64_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalar_Vector64_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalar_Vector64_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["MultiplyBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["MultiplyBySelectedScalar.Vector64.UInt16.Vector64.UInt16.1"] = MultiplyBySelectedScalar_Vector64_UInt16_Vector64_UInt16_1, - ["MultiplyBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalar.Vector128.Int16.Vector64.Int16.1"] = MultiplyBySelectedScalar_Vector128_Int16_Vector64_Int16_1, - ["MultiplyBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalar_Vector128_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalar_Vector128_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalar_Vector128_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalar.Vector128.Single.Vector64.Single.1"] = MultiplyBySelectedScalar_Vector128_Single_Vector64_Single_1, - ["MultiplyBySelectedScalar.Vector128.Single.Vector128.Single.3"] = MultiplyBySelectedScalar_Vector128_Single_Vector128_Single_3, - ["MultiplyBySelectedScalar.Vector128.UInt16.Vector64.UInt16.1"] = MultiplyBySelectedScalar_Vector128_UInt16_Vector64_UInt16_1, - ["MultiplyBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, + ["And.Vector128.Double"] = And_Vector128_Double, + ["And.Vector128.Int16"] = And_Vector128_Int16, + ["And.Vector128.Int32"] = And_Vector128_Int32, + ["And.Vector128.Int64"] = And_Vector128_Int64, + ["And.Vector128.SByte"] = And_Vector128_SByte, + ["And.Vector128.Single"] = And_Vector128_Single, + ["And.Vector128.UInt16"] = And_Vector128_UInt16, + ["And.Vector128.UInt32"] = And_Vector128_UInt32, + ["And.Vector128.UInt64"] = And_Vector128_UInt64, + ["BitwiseClear.Vector64.Byte"] = BitwiseClear_Vector64_Byte, + ["BitwiseClear.Vector64.Double"] = BitwiseClear_Vector64_Double, + ["BitwiseClear.Vector64.Int16"] = BitwiseClear_Vector64_Int16, + ["BitwiseClear.Vector64.Int32"] = BitwiseClear_Vector64_Int32, + ["BitwiseClear.Vector64.Int64"] = BitwiseClear_Vector64_Int64, + ["BitwiseClear.Vector64.SByte"] = BitwiseClear_Vector64_SByte, + ["BitwiseClear.Vector64.Single"] = BitwiseClear_Vector64_Single, + ["BitwiseClear.Vector64.UInt16"] = BitwiseClear_Vector64_UInt16, + ["BitwiseClear.Vector64.UInt32"] = BitwiseClear_Vector64_UInt32, + ["BitwiseClear.Vector64.UInt64"] = BitwiseClear_Vector64_UInt64, + ["BitwiseClear.Vector128.Byte"] = BitwiseClear_Vector128_Byte, + ["BitwiseClear.Vector128.Double"] = BitwiseClear_Vector128_Double, + ["BitwiseClear.Vector128.Int16"] = BitwiseClear_Vector128_Int16, + ["BitwiseClear.Vector128.Int32"] = BitwiseClear_Vector128_Int32, + ["BitwiseClear.Vector128.Int64"] = BitwiseClear_Vector128_Int64, + ["BitwiseClear.Vector128.SByte"] = BitwiseClear_Vector128_SByte, + ["BitwiseClear.Vector128.Single"] = BitwiseClear_Vector128_Single, + ["BitwiseClear.Vector128.UInt16"] = BitwiseClear_Vector128_UInt16, + ["BitwiseClear.Vector128.UInt32"] = BitwiseClear_Vector128_UInt32, + ["BitwiseClear.Vector128.UInt64"] = BitwiseClear_Vector128_UInt64, + ["BitwiseSelect.Vector64.Byte"] = BitwiseSelect_Vector64_Byte, + ["BitwiseSelect.Vector64.Double"] = BitwiseSelect_Vector64_Double, + ["BitwiseSelect.Vector64.Int16"] = BitwiseSelect_Vector64_Int16, + ["BitwiseSelect.Vector64.Int32"] = BitwiseSelect_Vector64_Int32, + ["BitwiseSelect.Vector64.Int64"] = BitwiseSelect_Vector64_Int64, + ["BitwiseSelect.Vector64.SByte"] = BitwiseSelect_Vector64_SByte, + ["BitwiseSelect.Vector64.Single"] = BitwiseSelect_Vector64_Single, + ["BitwiseSelect.Vector64.UInt16"] = BitwiseSelect_Vector64_UInt16, + ["BitwiseSelect.Vector64.UInt32"] = BitwiseSelect_Vector64_UInt32, + ["BitwiseSelect.Vector64.UInt64"] = BitwiseSelect_Vector64_UInt64, + ["BitwiseSelect.Vector128.Byte"] = BitwiseSelect_Vector128_Byte, + ["BitwiseSelect.Vector128.Double"] = BitwiseSelect_Vector128_Double, + ["BitwiseSelect.Vector128.Int16"] = BitwiseSelect_Vector128_Int16, + ["BitwiseSelect.Vector128.Int32"] = BitwiseSelect_Vector128_Int32, + ["BitwiseSelect.Vector128.Int64"] = BitwiseSelect_Vector128_Int64, + ["BitwiseSelect.Vector128.SByte"] = BitwiseSelect_Vector128_SByte, + ["BitwiseSelect.Vector128.Single"] = BitwiseSelect_Vector128_Single, + ["BitwiseSelect.Vector128.UInt16"] = BitwiseSelect_Vector128_UInt16, + ["BitwiseSelect.Vector128.UInt32"] = BitwiseSelect_Vector128_UInt32, + ["BitwiseSelect.Vector128.UInt64"] = BitwiseSelect_Vector128_UInt64, + ["Ceiling.Vector64.Single"] = Ceiling_Vector64_Single, + ["Ceiling.Vector128.Single"] = Ceiling_Vector128_Single, + ["CeilingScalar.Vector64.Double"] = CeilingScalar_Vector64_Double, + ["CeilingScalar.Vector64.Single"] = CeilingScalar_Vector64_Single, + ["CompareEqual.Vector64.Byte"] = CompareEqual_Vector64_Byte, + ["CompareEqual.Vector64.Int16"] = CompareEqual_Vector64_Int16, + ["CompareEqual.Vector64.Int32"] = CompareEqual_Vector64_Int32, + ["CompareEqual.Vector64.SByte"] = CompareEqual_Vector64_SByte, + ["CompareEqual.Vector64.Single"] = CompareEqual_Vector64_Single, + ["CompareEqual.Vector64.UInt16"] = CompareEqual_Vector64_UInt16, + ["CompareEqual.Vector64.UInt32"] = CompareEqual_Vector64_UInt32, + ["CompareEqual.Vector128.Byte"] = CompareEqual_Vector128_Byte, + ["CompareEqual.Vector128.Int16"] = CompareEqual_Vector128_Int16, + ["CompareEqual.Vector128.Int32"] = CompareEqual_Vector128_Int32, + ["CompareEqual.Vector128.SByte"] = CompareEqual_Vector128_SByte, + ["CompareEqual.Vector128.Single"] = CompareEqual_Vector128_Single, + ["CompareEqual.Vector128.UInt16"] = CompareEqual_Vector128_UInt16, + ["CompareEqual.Vector128.UInt32"] = CompareEqual_Vector128_UInt32, + ["CompareGreaterThan.Vector64.Byte"] = CompareGreaterThan_Vector64_Byte, + ["CompareGreaterThan.Vector64.Int16"] = CompareGreaterThan_Vector64_Int16, + ["CompareGreaterThan.Vector64.Int32"] = CompareGreaterThan_Vector64_Int32, + ["CompareGreaterThan.Vector64.SByte"] = CompareGreaterThan_Vector64_SByte, + ["CompareGreaterThan.Vector64.Single"] = CompareGreaterThan_Vector64_Single, + ["CompareGreaterThan.Vector64.UInt16"] = CompareGreaterThan_Vector64_UInt16, + ["CompareGreaterThan.Vector64.UInt32"] = CompareGreaterThan_Vector64_UInt32, + ["CompareGreaterThan.Vector128.Byte"] = CompareGreaterThan_Vector128_Byte, + ["CompareGreaterThan.Vector128.Int16"] = CompareGreaterThan_Vector128_Int16, + ["CompareGreaterThan.Vector128.Int32"] = CompareGreaterThan_Vector128_Int32, + ["CompareGreaterThan.Vector128.SByte"] = CompareGreaterThan_Vector128_SByte, + ["CompareGreaterThan.Vector128.Single"] = CompareGreaterThan_Vector128_Single, + ["CompareGreaterThan.Vector128.UInt16"] = CompareGreaterThan_Vector128_UInt16, + ["CompareGreaterThan.Vector128.UInt32"] = CompareGreaterThan_Vector128_UInt32, + ["CompareGreaterThanOrEqual.Vector64.Byte"] = CompareGreaterThanOrEqual_Vector64_Byte, + ["CompareGreaterThanOrEqual.Vector64.Int16"] = CompareGreaterThanOrEqual_Vector64_Int16, + ["CompareGreaterThanOrEqual.Vector64.Int32"] = CompareGreaterThanOrEqual_Vector64_Int32, + ["CompareGreaterThanOrEqual.Vector64.SByte"] = CompareGreaterThanOrEqual_Vector64_SByte, + ["CompareGreaterThanOrEqual.Vector64.Single"] = CompareGreaterThanOrEqual_Vector64_Single, + ["CompareGreaterThanOrEqual.Vector64.UInt16"] = CompareGreaterThanOrEqual_Vector64_UInt16, + ["CompareGreaterThanOrEqual.Vector64.UInt32"] = CompareGreaterThanOrEqual_Vector64_UInt32, + ["CompareGreaterThanOrEqual.Vector128.Byte"] = CompareGreaterThanOrEqual_Vector128_Byte, + ["CompareGreaterThanOrEqual.Vector128.Int16"] = CompareGreaterThanOrEqual_Vector128_Int16, + ["CompareGreaterThanOrEqual.Vector128.Int32"] = CompareGreaterThanOrEqual_Vector128_Int32, + ["CompareGreaterThanOrEqual.Vector128.SByte"] = CompareGreaterThanOrEqual_Vector128_SByte, + ["CompareGreaterThanOrEqual.Vector128.Single"] = CompareGreaterThanOrEqual_Vector128_Single, + ["CompareGreaterThanOrEqual.Vector128.UInt16"] = CompareGreaterThanOrEqual_Vector128_UInt16, + ["CompareGreaterThanOrEqual.Vector128.UInt32"] = CompareGreaterThanOrEqual_Vector128_UInt32, + ["CompareLessThan.Vector64.Byte"] = CompareLessThan_Vector64_Byte, + ["CompareLessThan.Vector64.Int16"] = CompareLessThan_Vector64_Int16, + ["CompareLessThan.Vector64.Int32"] = CompareLessThan_Vector64_Int32, + ["CompareLessThan.Vector64.SByte"] = CompareLessThan_Vector64_SByte, + ["CompareLessThan.Vector64.Single"] = CompareLessThan_Vector64_Single, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part3.cs index 93fc25375a71..cecabeabc533 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part3.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["MultiplyBySelectedScalarWideningLower.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningLower.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningLower.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningLower.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningLower.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningLower.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningLower.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningLower.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalarWideningUpper.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningUpper.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningUpper.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningUpper.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector128_UInt32_3, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector64_Int16_3, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector128_Int16_7, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector64_Int32_1, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector128_Int32_3, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector64_UInt16_3, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector128_UInt32_3, - ["MultiplyDoublingByScalarSaturateHigh.Vector64.Int16"] = MultiplyDoublingByScalarSaturateHigh_Vector64_Int16, - ["MultiplyDoublingByScalarSaturateHigh.Vector64.Int32"] = MultiplyDoublingByScalarSaturateHigh_Vector64_Int32, - ["MultiplyDoublingByScalarSaturateHigh.Vector128.Int16"] = MultiplyDoublingByScalarSaturateHigh_Vector128_Int16, - ["MultiplyDoublingByScalarSaturateHigh.Vector128.Int32"] = MultiplyDoublingByScalarSaturateHigh_Vector128_Int32, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_3, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1, - ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3, - ["MultiplyDoublingSaturateHigh.Vector64.Int16"] = MultiplyDoublingSaturateHigh_Vector64_Int16, - ["MultiplyDoublingSaturateHigh.Vector64.Int32"] = MultiplyDoublingSaturateHigh_Vector64_Int32, - ["MultiplyDoublingSaturateHigh.Vector128.Int16"] = MultiplyDoublingSaturateHigh_Vector128_Int16, - ["MultiplyDoublingSaturateHigh.Vector128.Int32"] = MultiplyDoublingSaturateHigh_Vector128_Int32, - ["MultiplyDoublingWideningLowerAndAddSaturate.Vector64.Int16"] = MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int16, - ["MultiplyDoublingWideningLowerAndAddSaturate.Vector64.Int32"] = MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int32, - ["MultiplyDoublingWideningLowerAndSubtractSaturate.Vector64.Int16"] = MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int16, - ["MultiplyDoublingWideningLowerAndSubtractSaturate.Vector64.Int32"] = MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int32, - ["MultiplyDoublingWideningLowerByScalarAndAddSaturate.Vector64.Int16.Vector64.Int16"] = MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int16_Vector64_Int16, - ["MultiplyDoublingWideningLowerByScalarAndAddSaturate.Vector64.Int32.Vector64.Int32"] = MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int32_Vector64_Int32, - ["MultiplyDoublingWideningLowerByScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16"] = MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16, - ["MultiplyDoublingWideningLowerByScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32"] = MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32, - ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningSaturateLower.Vector64.Int16"] = MultiplyDoublingWideningSaturateLower_Vector64_Int16, - ["MultiplyDoublingWideningSaturateLower.Vector64.Int32"] = MultiplyDoublingWideningSaturateLower_Vector64_Int32, - ["MultiplyDoublingWideningSaturateLowerByScalar.Vector64.Int16"] = MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int16, - ["MultiplyDoublingWideningSaturateLowerByScalar.Vector64.Int32"] = MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int32, - ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningSaturateUpper.Vector128.Int16"] = MultiplyDoublingWideningSaturateUpper_Vector128_Int16, - ["MultiplyDoublingWideningSaturateUpper.Vector128.Int32"] = MultiplyDoublingWideningSaturateUpper_Vector128_Int32, - ["MultiplyDoublingWideningSaturateUpperByScalar.Vector128.Int16"] = MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int16, - ["MultiplyDoublingWideningSaturateUpperByScalar.Vector128.Int32"] = MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int32, - ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningUpperAndAddSaturate.Vector128.Int16"] = MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int16, - ["MultiplyDoublingWideningUpperAndAddSaturate.Vector128.Int32"] = MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int32, - ["MultiplyDoublingWideningUpperAndSubtractSaturate.Vector128.Int16"] = MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int16, - ["MultiplyDoublingWideningUpperAndSubtractSaturate.Vector128.Int32"] = MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int32, - ["MultiplyDoublingWideningUpperByScalarAndAddSaturate.Vector128.Int16.Vector64.Int16"] = MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int16_Vector64_Int16, - ["MultiplyDoublingWideningUpperByScalarAndAddSaturate.Vector128.Int32.Vector64.Int32"] = MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int32_Vector64_Int32, - ["MultiplyDoublingWideningUpperByScalarAndSubtractSaturate.Vector128.Int16.Vector64.Int16"] = MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16, - ["MultiplyDoublingWideningUpperByScalarAndSubtractSaturate.Vector128.Int32.Vector64.Int32"] = MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32, - ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector128_Int32_3, - ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16_3, - ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector128_Int16_7, - ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32_1, - ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector128_Int32_3, - ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector64.Int16"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int16, - ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector64.Int32"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int32, - ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector128.Int16"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int16, - ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector128.Int32"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int32, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector64.Int16.2"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_2, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1, - ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3, - ["MultiplyRoundedDoublingSaturateHigh.Vector64.Int16"] = MultiplyRoundedDoublingSaturateHigh_Vector64_Int16, - ["MultiplyRoundedDoublingSaturateHigh.Vector64.Int32"] = MultiplyRoundedDoublingSaturateHigh_Vector64_Int32, - ["MultiplyRoundedDoublingSaturateHigh.Vector128.Int16"] = MultiplyRoundedDoublingSaturateHigh_Vector128_Int16, - ["MultiplyRoundedDoublingSaturateHigh.Vector128.Int32"] = MultiplyRoundedDoublingSaturateHigh_Vector128_Int32, - ["MultiplyScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, - ["MultiplyScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, - ["MultiplySubtract.Vector64.Byte"] = MultiplySubtract_Vector64_Byte, - ["MultiplySubtract.Vector64.Int16"] = MultiplySubtract_Vector64_Int16, - ["MultiplySubtract.Vector64.Int32"] = MultiplySubtract_Vector64_Int32, - ["MultiplySubtract.Vector64.SByte"] = MultiplySubtract_Vector64_SByte, - ["MultiplySubtract.Vector64.UInt16"] = MultiplySubtract_Vector64_UInt16, - ["MultiplySubtract.Vector64.UInt32"] = MultiplySubtract_Vector64_UInt32, - ["MultiplySubtract.Vector128.Byte"] = MultiplySubtract_Vector128_Byte, - ["MultiplySubtract.Vector128.Int16"] = MultiplySubtract_Vector128_Int16, - ["MultiplySubtract.Vector128.Int32"] = MultiplySubtract_Vector128_Int32, - ["MultiplySubtract.Vector128.SByte"] = MultiplySubtract_Vector128_SByte, - ["MultiplySubtract.Vector128.UInt16"] = MultiplySubtract_Vector128_UInt16, - ["MultiplySubtract.Vector128.UInt32"] = MultiplySubtract_Vector128_UInt32, - ["MultiplySubtractBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplySubtractBySelectedScalar_Vector64_Int16_Vector64_Int16_3, - ["MultiplySubtractBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplySubtractBySelectedScalar_Vector64_Int16_Vector128_Int16_7, - ["MultiplySubtractBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplySubtractBySelectedScalar_Vector64_Int32_Vector64_Int32_1, - ["MultiplySubtractBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplySubtractBySelectedScalar_Vector64_Int32_Vector128_Int32_3, - ["MultiplySubtractBySelectedScalar.Vector64.UInt16.Vector64.UInt16.3"] = MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3, - ["MultiplySubtractBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, - ["MultiplySubtractBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, - ["MultiplySubtractBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, - ["MultiplySubtractBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplySubtractBySelectedScalar_Vector128_Int16_Vector64_Int16_3, - ["MultiplySubtractBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplySubtractBySelectedScalar_Vector128_Int16_Vector128_Int16_7, - ["MultiplySubtractBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplySubtractBySelectedScalar_Vector128_Int32_Vector64_Int32_1, - ["MultiplySubtractBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplySubtractBySelectedScalar_Vector128_Int32_Vector128_Int32_3, - ["MultiplySubtractBySelectedScalar.Vector128.UInt16.Vector64.UInt16.3"] = MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3, - ["MultiplySubtractBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, - ["MultiplySubtractBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, - ["MultiplySubtractBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, - ["MultiplySubtractByScalar.Vector64.Int16"] = MultiplySubtractByScalar_Vector64_Int16, - ["MultiplySubtractByScalar.Vector64.Int32"] = MultiplySubtractByScalar_Vector64_Int32, - ["MultiplySubtractByScalar.Vector64.UInt16"] = MultiplySubtractByScalar_Vector64_UInt16, - ["MultiplySubtractByScalar.Vector64.UInt32"] = MultiplySubtractByScalar_Vector64_UInt32, - ["MultiplySubtractByScalar.Vector128.Int16"] = MultiplySubtractByScalar_Vector128_Int16, - ["MultiplySubtractByScalar.Vector128.Int32"] = MultiplySubtractByScalar_Vector128_Int32, - ["MultiplySubtractByScalar.Vector128.UInt16"] = MultiplySubtractByScalar_Vector128_UInt16, - ["MultiplySubtractByScalar.Vector128.UInt32"] = MultiplySubtractByScalar_Vector128_UInt32, - ["MultiplyWideningLower.Vector64.Byte"] = MultiplyWideningLower_Vector64_Byte, - ["MultiplyWideningLower.Vector64.Int16"] = MultiplyWideningLower_Vector64_Int16, - ["MultiplyWideningLower.Vector64.Int32"] = MultiplyWideningLower_Vector64_Int32, - ["MultiplyWideningLower.Vector64.SByte"] = MultiplyWideningLower_Vector64_SByte, - ["MultiplyWideningLower.Vector64.UInt16"] = MultiplyWideningLower_Vector64_UInt16, - ["MultiplyWideningLower.Vector64.UInt32"] = MultiplyWideningLower_Vector64_UInt32, - ["MultiplyWideningLowerAndAdd.Vector64.Byte"] = MultiplyWideningLowerAndAdd_Vector64_Byte, - ["MultiplyWideningLowerAndAdd.Vector64.Int16"] = MultiplyWideningLowerAndAdd_Vector64_Int16, - ["MultiplyWideningLowerAndAdd.Vector64.Int32"] = MultiplyWideningLowerAndAdd_Vector64_Int32, - ["MultiplyWideningLowerAndAdd.Vector64.SByte"] = MultiplyWideningLowerAndAdd_Vector64_SByte, - ["MultiplyWideningLowerAndAdd.Vector64.UInt16"] = MultiplyWideningLowerAndAdd_Vector64_UInt16, - ["MultiplyWideningLowerAndAdd.Vector64.UInt32"] = MultiplyWideningLowerAndAdd_Vector64_UInt32, - ["MultiplyWideningLowerAndSubtract.Vector64.Byte"] = MultiplyWideningLowerAndSubtract_Vector64_Byte, - ["MultiplyWideningLowerAndSubtract.Vector64.Int16"] = MultiplyWideningLowerAndSubtract_Vector64_Int16, - ["MultiplyWideningLowerAndSubtract.Vector64.Int32"] = MultiplyWideningLowerAndSubtract_Vector64_Int32, - ["MultiplyWideningLowerAndSubtract.Vector64.SByte"] = MultiplyWideningLowerAndSubtract_Vector64_SByte, - ["MultiplyWideningLowerAndSubtract.Vector64.UInt16"] = MultiplyWideningLowerAndSubtract_Vector64_UInt16, - ["MultiplyWideningLowerAndSubtract.Vector64.UInt32"] = MultiplyWideningLowerAndSubtract_Vector64_UInt32, - ["MultiplyWideningUpper.Vector128.Byte"] = MultiplyWideningUpper_Vector128_Byte, - ["MultiplyWideningUpper.Vector128.Int16"] = MultiplyWideningUpper_Vector128_Int16, - ["MultiplyWideningUpper.Vector128.Int32"] = MultiplyWideningUpper_Vector128_Int32, - ["MultiplyWideningUpper.Vector128.SByte"] = MultiplyWideningUpper_Vector128_SByte, - ["MultiplyWideningUpper.Vector128.UInt16"] = MultiplyWideningUpper_Vector128_UInt16, - ["MultiplyWideningUpper.Vector128.UInt32"] = MultiplyWideningUpper_Vector128_UInt32, - ["MultiplyWideningUpperAndAdd.Vector128.Byte"] = MultiplyWideningUpperAndAdd_Vector128_Byte, - ["MultiplyWideningUpperAndAdd.Vector128.Int16"] = MultiplyWideningUpperAndAdd_Vector128_Int16, - ["MultiplyWideningUpperAndAdd.Vector128.Int32"] = MultiplyWideningUpperAndAdd_Vector128_Int32, - ["MultiplyWideningUpperAndAdd.Vector128.SByte"] = MultiplyWideningUpperAndAdd_Vector128_SByte, - ["MultiplyWideningUpperAndAdd.Vector128.UInt16"] = MultiplyWideningUpperAndAdd_Vector128_UInt16, - ["MultiplyWideningUpperAndAdd.Vector128.UInt32"] = MultiplyWideningUpperAndAdd_Vector128_UInt32, - ["MultiplyWideningUpperAndSubtract.Vector128.Byte"] = MultiplyWideningUpperAndSubtract_Vector128_Byte, - ["MultiplyWideningUpperAndSubtract.Vector128.Int16"] = MultiplyWideningUpperAndSubtract_Vector128_Int16, - ["MultiplyWideningUpperAndSubtract.Vector128.Int32"] = MultiplyWideningUpperAndSubtract_Vector128_Int32, - ["MultiplyWideningUpperAndSubtract.Vector128.SByte"] = MultiplyWideningUpperAndSubtract_Vector128_SByte, - ["MultiplyWideningUpperAndSubtract.Vector128.UInt16"] = MultiplyWideningUpperAndSubtract_Vector128_UInt16, - ["MultiplyWideningUpperAndSubtract.Vector128.UInt32"] = MultiplyWideningUpperAndSubtract_Vector128_UInt32, - ["Negate.Vector64.Int16"] = Negate_Vector64_Int16, - ["Negate.Vector64.Int32"] = Negate_Vector64_Int32, - ["Negate.Vector64.SByte"] = Negate_Vector64_SByte, - ["Negate.Vector64.Single"] = Negate_Vector64_Single, - ["Negate.Vector128.Int16"] = Negate_Vector128_Int16, - ["Negate.Vector128.Int32"] = Negate_Vector128_Int32, - ["Negate.Vector128.SByte"] = Negate_Vector128_SByte, - ["Negate.Vector128.Single"] = Negate_Vector128_Single, - ["NegateSaturate.Vector64.Int16"] = NegateSaturate_Vector64_Int16, - ["NegateSaturate.Vector64.Int32"] = NegateSaturate_Vector64_Int32, - ["NegateSaturate.Vector64.SByte"] = NegateSaturate_Vector64_SByte, - ["NegateSaturate.Vector128.Int16"] = NegateSaturate_Vector128_Int16, - ["NegateSaturate.Vector128.Int32"] = NegateSaturate_Vector128_Int32, - ["NegateSaturate.Vector128.SByte"] = NegateSaturate_Vector128_SByte, - ["NegateScalar.Vector64.Double"] = NegateScalar_Vector64_Double, - ["NegateScalar.Vector64.Single"] = NegateScalar_Vector64_Single, - ["Not.Vector64.Byte"] = Not_Vector64_Byte, - ["Not.Vector64.Double"] = Not_Vector64_Double, - ["Not.Vector64.Int16"] = Not_Vector64_Int16, - ["Not.Vector64.Int32"] = Not_Vector64_Int32, - ["Not.Vector64.Int64"] = Not_Vector64_Int64, - ["Not.Vector64.SByte"] = Not_Vector64_SByte, - ["Not.Vector64.Single"] = Not_Vector64_Single, - ["Not.Vector64.UInt16"] = Not_Vector64_UInt16, - ["Not.Vector64.UInt32"] = Not_Vector64_UInt32, - ["Not.Vector64.UInt64"] = Not_Vector64_UInt64, - ["Not.Vector128.Byte"] = Not_Vector128_Byte, - ["Not.Vector128.Double"] = Not_Vector128_Double, - ["Not.Vector128.Int16"] = Not_Vector128_Int16, - ["Not.Vector128.Int32"] = Not_Vector128_Int32, - ["Not.Vector128.Int64"] = Not_Vector128_Int64, - ["Not.Vector128.SByte"] = Not_Vector128_SByte, - ["Not.Vector128.Single"] = Not_Vector128_Single, - ["Not.Vector128.UInt16"] = Not_Vector128_UInt16, - ["Not.Vector128.UInt32"] = Not_Vector128_UInt32, - ["Not.Vector128.UInt64"] = Not_Vector128_UInt64, - ["Or.Vector64.Byte"] = Or_Vector64_Byte, - ["Or.Vector64.Double"] = Or_Vector64_Double, - ["Or.Vector64.Int16"] = Or_Vector64_Int16, - ["Or.Vector64.Int32"] = Or_Vector64_Int32, - ["Or.Vector64.Int64"] = Or_Vector64_Int64, - ["Or.Vector64.SByte"] = Or_Vector64_SByte, - ["Or.Vector64.Single"] = Or_Vector64_Single, - ["Or.Vector64.UInt16"] = Or_Vector64_UInt16, - ["Or.Vector64.UInt32"] = Or_Vector64_UInt32, - ["Or.Vector64.UInt64"] = Or_Vector64_UInt64, - ["Or.Vector128.Byte"] = Or_Vector128_Byte, - ["Or.Vector128.Double"] = Or_Vector128_Double, - ["Or.Vector128.Int16"] = Or_Vector128_Int16, - ["Or.Vector128.Int32"] = Or_Vector128_Int32, - ["Or.Vector128.Int64"] = Or_Vector128_Int64, - ["Or.Vector128.SByte"] = Or_Vector128_SByte, - ["Or.Vector128.Single"] = Or_Vector128_Single, - ["Or.Vector128.UInt16"] = Or_Vector128_UInt16, + ["CompareLessThan.Vector64.UInt16"] = CompareLessThan_Vector64_UInt16, + ["CompareLessThan.Vector64.UInt32"] = CompareLessThan_Vector64_UInt32, + ["CompareLessThan.Vector128.Byte"] = CompareLessThan_Vector128_Byte, + ["CompareLessThan.Vector128.Int16"] = CompareLessThan_Vector128_Int16, + ["CompareLessThan.Vector128.Int32"] = CompareLessThan_Vector128_Int32, + ["CompareLessThan.Vector128.SByte"] = CompareLessThan_Vector128_SByte, + ["CompareLessThan.Vector128.Single"] = CompareLessThan_Vector128_Single, + ["CompareLessThan.Vector128.UInt16"] = CompareLessThan_Vector128_UInt16, + ["CompareLessThan.Vector128.UInt32"] = CompareLessThan_Vector128_UInt32, + ["CompareLessThanOrEqual.Vector64.Byte"] = CompareLessThanOrEqual_Vector64_Byte, + ["CompareLessThanOrEqual.Vector64.Int16"] = CompareLessThanOrEqual_Vector64_Int16, + ["CompareLessThanOrEqual.Vector64.Int32"] = CompareLessThanOrEqual_Vector64_Int32, + ["CompareLessThanOrEqual.Vector64.SByte"] = CompareLessThanOrEqual_Vector64_SByte, + ["CompareLessThanOrEqual.Vector64.Single"] = CompareLessThanOrEqual_Vector64_Single, + ["CompareLessThanOrEqual.Vector64.UInt16"] = CompareLessThanOrEqual_Vector64_UInt16, + ["CompareLessThanOrEqual.Vector64.UInt32"] = CompareLessThanOrEqual_Vector64_UInt32, + ["CompareLessThanOrEqual.Vector128.Byte"] = CompareLessThanOrEqual_Vector128_Byte, + ["CompareLessThanOrEqual.Vector128.Int16"] = CompareLessThanOrEqual_Vector128_Int16, + ["CompareLessThanOrEqual.Vector128.Int32"] = CompareLessThanOrEqual_Vector128_Int32, + ["CompareLessThanOrEqual.Vector128.SByte"] = CompareLessThanOrEqual_Vector128_SByte, + ["CompareLessThanOrEqual.Vector128.Single"] = CompareLessThanOrEqual_Vector128_Single, + ["CompareLessThanOrEqual.Vector128.UInt16"] = CompareLessThanOrEqual_Vector128_UInt16, + ["CompareLessThanOrEqual.Vector128.UInt32"] = CompareLessThanOrEqual_Vector128_UInt32, + ["CompareTest.Vector64.Byte"] = CompareTest_Vector64_Byte, + ["CompareTest.Vector64.Int16"] = CompareTest_Vector64_Int16, + ["CompareTest.Vector64.Int32"] = CompareTest_Vector64_Int32, + ["CompareTest.Vector64.SByte"] = CompareTest_Vector64_SByte, + ["CompareTest.Vector64.Single"] = CompareTest_Vector64_Single, + ["CompareTest.Vector64.UInt16"] = CompareTest_Vector64_UInt16, + ["CompareTest.Vector64.UInt32"] = CompareTest_Vector64_UInt32, + ["CompareTest.Vector128.Byte"] = CompareTest_Vector128_Byte, + ["CompareTest.Vector128.Int16"] = CompareTest_Vector128_Int16, + ["CompareTest.Vector128.Int32"] = CompareTest_Vector128_Int32, + ["CompareTest.Vector128.SByte"] = CompareTest_Vector128_SByte, + ["CompareTest.Vector128.Single"] = CompareTest_Vector128_Single, + ["CompareTest.Vector128.UInt16"] = CompareTest_Vector128_UInt16, + ["CompareTest.Vector128.UInt32"] = CompareTest_Vector128_UInt32, + ["ConvertToInt32RoundAwayFromZero.Vector64.Single"] = ConvertToInt32RoundAwayFromZero_Vector64_Single, + ["ConvertToInt32RoundAwayFromZero.Vector128.Single"] = ConvertToInt32RoundAwayFromZero_Vector128_Single, + ["ConvertToInt32RoundAwayFromZeroScalar.Vector64.Single"] = ConvertToInt32RoundAwayFromZeroScalar_Vector64_Single, + ["ConvertToInt32RoundToEven.Vector64.Single"] = ConvertToInt32RoundToEven_Vector64_Single, + ["ConvertToInt32RoundToEven.Vector128.Single"] = ConvertToInt32RoundToEven_Vector128_Single, + ["ConvertToInt32RoundToEvenScalar.Vector64.Single"] = ConvertToInt32RoundToEvenScalar_Vector64_Single, + ["ConvertToInt32RoundToNegativeInfinity.Vector64.Single"] = ConvertToInt32RoundToNegativeInfinity_Vector64_Single, + ["ConvertToInt32RoundToNegativeInfinity.Vector128.Single"] = ConvertToInt32RoundToNegativeInfinity_Vector128_Single, + ["ConvertToInt32RoundToNegativeInfinityScalar.Vector64.Single"] = ConvertToInt32RoundToNegativeInfinityScalar_Vector64_Single, + ["ConvertToInt32RoundToPositiveInfinity.Vector64.Single"] = ConvertToInt32RoundToPositiveInfinity_Vector64_Single, + ["ConvertToInt32RoundToPositiveInfinity.Vector128.Single"] = ConvertToInt32RoundToPositiveInfinity_Vector128_Single, + ["ConvertToInt32RoundToPositiveInfinityScalar.Vector64.Single"] = ConvertToInt32RoundToPositiveInfinityScalar_Vector64_Single, + ["ConvertToInt32RoundToZero.Vector64.Single"] = ConvertToInt32RoundToZero_Vector64_Single, + ["ConvertToInt32RoundToZero.Vector128.Single"] = ConvertToInt32RoundToZero_Vector128_Single, + ["ConvertToInt32RoundToZeroScalar.Vector64.Single"] = ConvertToInt32RoundToZeroScalar_Vector64_Single, + ["ConvertToSingle.Vector64.Int32"] = ConvertToSingle_Vector64_Int32, + ["ConvertToSingle.Vector64.UInt32"] = ConvertToSingle_Vector64_UInt32, + ["ConvertToSingle.Vector128.Int32"] = ConvertToSingle_Vector128_Int32, + ["ConvertToSingle.Vector128.UInt32"] = ConvertToSingle_Vector128_UInt32, + ["ConvertToSingleScalar.Vector64.Int32"] = ConvertToSingleScalar_Vector64_Int32, + ["ConvertToSingleScalar.Vector64.UInt32"] = ConvertToSingleScalar_Vector64_UInt32, + ["ConvertToUInt32RoundAwayFromZero.Vector64.Single"] = ConvertToUInt32RoundAwayFromZero_Vector64_Single, + ["ConvertToUInt32RoundAwayFromZero.Vector128.Single"] = ConvertToUInt32RoundAwayFromZero_Vector128_Single, + ["ConvertToUInt32RoundAwayFromZeroScalar.Vector64.Single"] = ConvertToUInt32RoundAwayFromZeroScalar_Vector64_Single, + ["ConvertToUInt32RoundToEven.Vector64.Single"] = ConvertToUInt32RoundToEven_Vector64_Single, + ["ConvertToUInt32RoundToEven.Vector128.Single"] = ConvertToUInt32RoundToEven_Vector128_Single, + ["ConvertToUInt32RoundToEvenScalar.Vector64.Single"] = ConvertToUInt32RoundToEvenScalar_Vector64_Single, + ["ConvertToUInt32RoundToNegativeInfinity.Vector64.Single"] = ConvertToUInt32RoundToNegativeInfinity_Vector64_Single, + ["ConvertToUInt32RoundToNegativeInfinity.Vector128.Single"] = ConvertToUInt32RoundToNegativeInfinity_Vector128_Single, + ["ConvertToUInt32RoundToNegativeInfinityScalar.Vector64.Single"] = ConvertToUInt32RoundToNegativeInfinityScalar_Vector64_Single, + ["ConvertToUInt32RoundToPositiveInfinity.Vector64.Single"] = ConvertToUInt32RoundToPositiveInfinity_Vector64_Single, + ["ConvertToUInt32RoundToPositiveInfinity.Vector128.Single"] = ConvertToUInt32RoundToPositiveInfinity_Vector128_Single, + ["ConvertToUInt32RoundToPositiveInfinityScalar.Vector64.Single"] = ConvertToUInt32RoundToPositiveInfinityScalar_Vector64_Single, + ["ConvertToUInt32RoundToZero.Vector64.Single"] = ConvertToUInt32RoundToZero_Vector64_Single, + ["ConvertToUInt32RoundToZero.Vector128.Single"] = ConvertToUInt32RoundToZero_Vector128_Single, + ["ConvertToUInt32RoundToZeroScalar.Vector64.Single"] = ConvertToUInt32RoundToZeroScalar_Vector64_Single, + ["DivideScalar.Vector64.Double"] = DivideScalar_Vector64_Double, + ["DivideScalar.Vector64.Single"] = DivideScalar_Vector64_Single, + ["DuplicateSelectedScalarToVector64.Vector64.Byte.1"] = DuplicateSelectedScalarToVector64_Vector64_Byte_1, + ["DuplicateSelectedScalarToVector64.Vector64.Int16.1"] = DuplicateSelectedScalarToVector64_Vector64_Int16_1, + ["DuplicateSelectedScalarToVector64.Vector64.Int32.1"] = DuplicateSelectedScalarToVector64_Vector64_Int32_1, + ["DuplicateSelectedScalarToVector64.Vector64.SByte.1"] = DuplicateSelectedScalarToVector64_Vector64_SByte_1, + ["DuplicateSelectedScalarToVector64.Vector64.Single.1"] = DuplicateSelectedScalarToVector64_Vector64_Single_1, + ["DuplicateSelectedScalarToVector64.Vector64.UInt16.1"] = DuplicateSelectedScalarToVector64_Vector64_UInt16_1, + ["DuplicateSelectedScalarToVector64.Vector64.UInt32.1"] = DuplicateSelectedScalarToVector64_Vector64_UInt32_1, + ["DuplicateSelectedScalarToVector64.Vector128.Byte.8"] = DuplicateSelectedScalarToVector64_Vector128_Byte_8, + ["DuplicateSelectedScalarToVector64.Vector128.Int16.4"] = DuplicateSelectedScalarToVector64_Vector128_Int16_4, + ["DuplicateSelectedScalarToVector64.Vector128.Int32.2"] = DuplicateSelectedScalarToVector64_Vector128_Int32_2, + ["DuplicateSelectedScalarToVector64.Vector128.SByte.8"] = DuplicateSelectedScalarToVector64_Vector128_SByte_8, + ["DuplicateSelectedScalarToVector64.Vector128.Single.2"] = DuplicateSelectedScalarToVector64_Vector128_Single_2, + ["DuplicateSelectedScalarToVector64.Vector128.UInt16.4"] = DuplicateSelectedScalarToVector64_Vector128_UInt16_4, + ["DuplicateSelectedScalarToVector64.Vector128.UInt32.2"] = DuplicateSelectedScalarToVector64_Vector128_UInt32_2, + ["DuplicateSelectedScalarToVector128.Vector64.Byte.1"] = DuplicateSelectedScalarToVector128_Vector64_Byte_1, + ["DuplicateSelectedScalarToVector128.Vector64.Int16.1"] = DuplicateSelectedScalarToVector128_Vector64_Int16_1, + ["DuplicateSelectedScalarToVector128.Vector64.Int32.1"] = DuplicateSelectedScalarToVector128_Vector64_Int32_1, + ["DuplicateSelectedScalarToVector128.Vector64.SByte.1"] = DuplicateSelectedScalarToVector128_Vector64_SByte_1, + ["DuplicateSelectedScalarToVector128.Vector64.Single.1"] = DuplicateSelectedScalarToVector128_Vector64_Single_1, + ["DuplicateSelectedScalarToVector128.Vector64.UInt16.1"] = DuplicateSelectedScalarToVector128_Vector64_UInt16_1, + ["DuplicateSelectedScalarToVector128.Vector64.UInt32.1"] = DuplicateSelectedScalarToVector128_Vector64_UInt32_1, + ["DuplicateSelectedScalarToVector128.Vector128.Byte.8"] = DuplicateSelectedScalarToVector128_Vector128_Byte_8, + ["DuplicateSelectedScalarToVector128.Vector128.Int16.4"] = DuplicateSelectedScalarToVector128_Vector128_Int16_4, + ["DuplicateSelectedScalarToVector128.Vector128.Int32.2"] = DuplicateSelectedScalarToVector128_Vector128_Int32_2, + ["DuplicateSelectedScalarToVector128.Vector128.SByte.8"] = DuplicateSelectedScalarToVector128_Vector128_SByte_8, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part4.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part4.cs index 50c9bc08dc23..9b316164edef 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part4.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part4.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["Or.Vector128.UInt32"] = Or_Vector128_UInt32, - ["Or.Vector128.UInt64"] = Or_Vector128_UInt64, - ["OrNot.Vector64.Byte"] = OrNot_Vector64_Byte, - ["OrNot.Vector64.Double"] = OrNot_Vector64_Double, - ["OrNot.Vector64.Int16"] = OrNot_Vector64_Int16, - ["OrNot.Vector64.Int32"] = OrNot_Vector64_Int32, - ["OrNot.Vector64.Int64"] = OrNot_Vector64_Int64, - ["OrNot.Vector64.SByte"] = OrNot_Vector64_SByte, - ["OrNot.Vector64.Single"] = OrNot_Vector64_Single, - ["OrNot.Vector64.UInt16"] = OrNot_Vector64_UInt16, - ["OrNot.Vector64.UInt32"] = OrNot_Vector64_UInt32, - ["OrNot.Vector64.UInt64"] = OrNot_Vector64_UInt64, - ["OrNot.Vector128.Byte"] = OrNot_Vector128_Byte, - ["OrNot.Vector128.Double"] = OrNot_Vector128_Double, - ["OrNot.Vector128.Int16"] = OrNot_Vector128_Int16, - ["OrNot.Vector128.Int32"] = OrNot_Vector128_Int32, - ["OrNot.Vector128.Int64"] = OrNot_Vector128_Int64, - ["OrNot.Vector128.SByte"] = OrNot_Vector128_SByte, - ["OrNot.Vector128.Single"] = OrNot_Vector128_Single, - ["OrNot.Vector128.UInt16"] = OrNot_Vector128_UInt16, - ["OrNot.Vector128.UInt32"] = OrNot_Vector128_UInt32, - ["OrNot.Vector128.UInt64"] = OrNot_Vector128_UInt64, - ["PolynomialMultiply.Vector64.Byte"] = PolynomialMultiply_Vector64_Byte, - ["PolynomialMultiply.Vector64.SByte"] = PolynomialMultiply_Vector64_SByte, - ["PolynomialMultiply.Vector128.Byte"] = PolynomialMultiply_Vector128_Byte, - ["PolynomialMultiply.Vector128.SByte"] = PolynomialMultiply_Vector128_SByte, - ["PolynomialMultiplyWideningLower.Vector64.Byte"] = PolynomialMultiplyWideningLower_Vector64_Byte, - ["PolynomialMultiplyWideningLower.Vector64.SByte"] = PolynomialMultiplyWideningLower_Vector64_SByte, - ["PolynomialMultiplyWideningUpper.Vector128.Byte"] = PolynomialMultiplyWideningUpper_Vector128_Byte, - ["PolynomialMultiplyWideningUpper.Vector128.SByte"] = PolynomialMultiplyWideningUpper_Vector128_SByte, - ["PopCount.Vector64.Byte"] = PopCount_Vector64_Byte, - ["PopCount.Vector64.SByte"] = PopCount_Vector64_SByte, - ["PopCount.Vector128.Byte"] = PopCount_Vector128_Byte, - ["PopCount.Vector128.SByte"] = PopCount_Vector128_SByte, - ["ReciprocalEstimate.Vector64.Single"] = ReciprocalEstimate_Vector64_Single, - ["ReciprocalEstimate.Vector64.UInt32"] = ReciprocalEstimate_Vector64_UInt32, - ["ReciprocalEstimate.Vector128.Single"] = ReciprocalEstimate_Vector128_Single, - ["ReciprocalEstimate.Vector128.UInt32"] = ReciprocalEstimate_Vector128_UInt32, - ["ReciprocalSquareRootEstimate.Vector64.Single"] = ReciprocalSquareRootEstimate_Vector64_Single, - ["ReciprocalSquareRootEstimate.Vector64.UInt32"] = ReciprocalSquareRootEstimate_Vector64_UInt32, - ["ReciprocalSquareRootEstimate.Vector128.Single"] = ReciprocalSquareRootEstimate_Vector128_Single, - ["ReciprocalSquareRootEstimate.Vector128.UInt32"] = ReciprocalSquareRootEstimate_Vector128_UInt32, - ["ReciprocalSquareRootStep.Vector64.Single"] = ReciprocalSquareRootStep_Vector64_Single, - ["ReciprocalSquareRootStep.Vector128.Single"] = ReciprocalSquareRootStep_Vector128_Single, - ["ReciprocalStep.Vector64.Single"] = ReciprocalStep_Vector64_Single, - ["ReciprocalStep.Vector128.Single"] = ReciprocalStep_Vector128_Single, - ["ReverseElement16.Vector64.Int32"] = ReverseElement16_Vector64_Int32, - ["ReverseElement16.Vector64.Int64"] = ReverseElement16_Vector64_Int64, - ["ReverseElement16.Vector64.UInt32"] = ReverseElement16_Vector64_UInt32, - ["ReverseElement16.Vector64.UInt64"] = ReverseElement16_Vector64_UInt64, - ["ReverseElement16.Vector128.Int32"] = ReverseElement16_Vector128_Int32, - ["ReverseElement16.Vector128.Int64"] = ReverseElement16_Vector128_Int64, - ["ReverseElement16.Vector128.UInt32"] = ReverseElement16_Vector128_UInt32, - ["ReverseElement16.Vector128.UInt64"] = ReverseElement16_Vector128_UInt64, - ["ReverseElement32.Vector64.Int64"] = ReverseElement32_Vector64_Int64, - ["ReverseElement32.Vector64.UInt64"] = ReverseElement32_Vector64_UInt64, - ["ReverseElement32.Vector128.Int64"] = ReverseElement32_Vector128_Int64, - ["ReverseElement32.Vector128.UInt64"] = ReverseElement32_Vector128_UInt64, - ["ReverseElement8.Vector64.Int16"] = ReverseElement8_Vector64_Int16, - ["ReverseElement8.Vector64.Int32"] = ReverseElement8_Vector64_Int32, - ["ReverseElement8.Vector64.Int64"] = ReverseElement8_Vector64_Int64, - ["ReverseElement8.Vector64.UInt16"] = ReverseElement8_Vector64_UInt16, - ["ReverseElement8.Vector64.UInt32"] = ReverseElement8_Vector64_UInt32, - ["ReverseElement8.Vector64.UInt64"] = ReverseElement8_Vector64_UInt64, - ["ReverseElement8.Vector128.Int16"] = ReverseElement8_Vector128_Int16, - ["ReverseElement8.Vector128.Int32"] = ReverseElement8_Vector128_Int32, - ["ReverseElement8.Vector128.Int64"] = ReverseElement8_Vector128_Int64, - ["ReverseElement8.Vector128.UInt16"] = ReverseElement8_Vector128_UInt16, - ["ReverseElement8.Vector128.UInt32"] = ReverseElement8_Vector128_UInt32, - ["ReverseElement8.Vector128.UInt64"] = ReverseElement8_Vector128_UInt64, - ["RoundAwayFromZero.Vector64.Single"] = RoundAwayFromZero_Vector64_Single, - ["RoundAwayFromZero.Vector128.Single"] = RoundAwayFromZero_Vector128_Single, - ["RoundAwayFromZeroScalar.Vector64.Double"] = RoundAwayFromZeroScalar_Vector64_Double, - ["RoundAwayFromZeroScalar.Vector64.Single"] = RoundAwayFromZeroScalar_Vector64_Single, - ["RoundToNearest.Vector64.Single"] = RoundToNearest_Vector64_Single, - ["RoundToNearest.Vector128.Single"] = RoundToNearest_Vector128_Single, - ["RoundToNearestScalar.Vector64.Double"] = RoundToNearestScalar_Vector64_Double, - ["RoundToNearestScalar.Vector64.Single"] = RoundToNearestScalar_Vector64_Single, - ["RoundToNegativeInfinity.Vector64.Single"] = RoundToNegativeInfinity_Vector64_Single, - ["RoundToNegativeInfinity.Vector128.Single"] = RoundToNegativeInfinity_Vector128_Single, - ["RoundToNegativeInfinityScalar.Vector64.Double"] = RoundToNegativeInfinityScalar_Vector64_Double, - ["RoundToNegativeInfinityScalar.Vector64.Single"] = RoundToNegativeInfinityScalar_Vector64_Single, - ["RoundToPositiveInfinity.Vector64.Single"] = RoundToPositiveInfinity_Vector64_Single, - ["RoundToPositiveInfinity.Vector128.Single"] = RoundToPositiveInfinity_Vector128_Single, - ["RoundToPositiveInfinityScalar.Vector64.Double"] = RoundToPositiveInfinityScalar_Vector64_Double, - ["RoundToPositiveInfinityScalar.Vector64.Single"] = RoundToPositiveInfinityScalar_Vector64_Single, - ["RoundToZero.Vector64.Single"] = RoundToZero_Vector64_Single, - ["RoundToZero.Vector128.Single"] = RoundToZero_Vector128_Single, - ["RoundToZeroScalar.Vector64.Double"] = RoundToZeroScalar_Vector64_Double, - ["RoundToZeroScalar.Vector64.Single"] = RoundToZeroScalar_Vector64_Single, - ["ShiftArithmetic.Vector64.Int16"] = ShiftArithmetic_Vector64_Int16, - ["ShiftArithmetic.Vector64.Int32"] = ShiftArithmetic_Vector64_Int32, - ["ShiftArithmetic.Vector64.SByte"] = ShiftArithmetic_Vector64_SByte, - ["ShiftArithmetic.Vector128.Int16"] = ShiftArithmetic_Vector128_Int16, - ["ShiftArithmetic.Vector128.Int32"] = ShiftArithmetic_Vector128_Int32, - ["ShiftArithmetic.Vector128.Int64"] = ShiftArithmetic_Vector128_Int64, - ["ShiftArithmetic.Vector128.SByte"] = ShiftArithmetic_Vector128_SByte, - ["ShiftArithmeticRounded.Vector64.Int16"] = ShiftArithmeticRounded_Vector64_Int16, - ["ShiftArithmeticRounded.Vector64.Int32"] = ShiftArithmeticRounded_Vector64_Int32, - ["ShiftArithmeticRounded.Vector64.SByte"] = ShiftArithmeticRounded_Vector64_SByte, - ["ShiftArithmeticRounded.Vector128.Int16"] = ShiftArithmeticRounded_Vector128_Int16, - ["ShiftArithmeticRounded.Vector128.Int32"] = ShiftArithmeticRounded_Vector128_Int32, - ["ShiftArithmeticRounded.Vector128.Int64"] = ShiftArithmeticRounded_Vector128_Int64, - ["ShiftArithmeticRounded.Vector128.SByte"] = ShiftArithmeticRounded_Vector128_SByte, - ["ShiftArithmeticRoundedSaturate.Vector64.Int16"] = ShiftArithmeticRoundedSaturate_Vector64_Int16, - ["ShiftArithmeticRoundedSaturate.Vector64.Int32"] = ShiftArithmeticRoundedSaturate_Vector64_Int32, - ["ShiftArithmeticRoundedSaturate.Vector64.SByte"] = ShiftArithmeticRoundedSaturate_Vector64_SByte, - ["ShiftArithmeticRoundedSaturate.Vector128.Int16"] = ShiftArithmeticRoundedSaturate_Vector128_Int16, - ["ShiftArithmeticRoundedSaturate.Vector128.Int32"] = ShiftArithmeticRoundedSaturate_Vector128_Int32, - ["ShiftArithmeticRoundedSaturate.Vector128.Int64"] = ShiftArithmeticRoundedSaturate_Vector128_Int64, - ["ShiftArithmeticRoundedSaturate.Vector128.SByte"] = ShiftArithmeticRoundedSaturate_Vector128_SByte, - ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int64"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int64, - ["ShiftArithmeticRoundedScalar.Vector64.Int64"] = ShiftArithmeticRoundedScalar_Vector64_Int64, - ["ShiftArithmeticSaturate.Vector64.Int16"] = ShiftArithmeticSaturate_Vector64_Int16, - ["ShiftArithmeticSaturate.Vector64.Int32"] = ShiftArithmeticSaturate_Vector64_Int32, - ["ShiftArithmeticSaturate.Vector64.SByte"] = ShiftArithmeticSaturate_Vector64_SByte, - ["ShiftArithmeticSaturate.Vector128.Int16"] = ShiftArithmeticSaturate_Vector128_Int16, - ["ShiftArithmeticSaturate.Vector128.Int32"] = ShiftArithmeticSaturate_Vector128_Int32, - ["ShiftArithmeticSaturate.Vector128.Int64"] = ShiftArithmeticSaturate_Vector128_Int64, - ["ShiftArithmeticSaturate.Vector128.SByte"] = ShiftArithmeticSaturate_Vector128_SByte, - ["ShiftArithmeticSaturateScalar.Vector64.Int64"] = ShiftArithmeticSaturateScalar_Vector64_Int64, - ["ShiftArithmeticScalar.Vector64.Int64"] = ShiftArithmeticScalar_Vector64_Int64, - ["ShiftLeftAndInsert.Vector64.Byte"] = ShiftLeftAndInsert_Vector64_Byte, - ["ShiftLeftAndInsert.Vector64.Int16"] = ShiftLeftAndInsert_Vector64_Int16, - ["ShiftLeftAndInsert.Vector64.Int32"] = ShiftLeftAndInsert_Vector64_Int32, - ["ShiftLeftAndInsert.Vector64.SByte"] = ShiftLeftAndInsert_Vector64_SByte, - ["ShiftLeftAndInsert.Vector64.UInt16"] = ShiftLeftAndInsert_Vector64_UInt16, - ["ShiftLeftAndInsert.Vector64.UInt32"] = ShiftLeftAndInsert_Vector64_UInt32, - ["ShiftLeftAndInsert.Vector128.Byte"] = ShiftLeftAndInsert_Vector128_Byte, - ["ShiftLeftAndInsert.Vector128.Int16"] = ShiftLeftAndInsert_Vector128_Int16, - ["ShiftLeftAndInsert.Vector128.Int32"] = ShiftLeftAndInsert_Vector128_Int32, - ["ShiftLeftAndInsert.Vector128.Int64"] = ShiftLeftAndInsert_Vector128_Int64, - ["ShiftLeftAndInsert.Vector128.SByte"] = ShiftLeftAndInsert_Vector128_SByte, - ["ShiftLeftAndInsert.Vector128.UInt16"] = ShiftLeftAndInsert_Vector128_UInt16, - ["ShiftLeftAndInsert.Vector128.UInt32"] = ShiftLeftAndInsert_Vector128_UInt32, - ["ShiftLeftAndInsert.Vector128.UInt64"] = ShiftLeftAndInsert_Vector128_UInt64, - ["ShiftLeftAndInsertScalar.Vector64.Int64"] = ShiftLeftAndInsertScalar_Vector64_Int64, - ["ShiftLeftAndInsertScalar.Vector64.UInt64"] = ShiftLeftAndInsertScalar_Vector64_UInt64, - ["ShiftLeftLogical.Vector64.Byte.1"] = ShiftLeftLogical_Vector64_Byte_1, - ["ShiftLeftLogical.Vector64.Int16.1"] = ShiftLeftLogical_Vector64_Int16_1, - ["ShiftLeftLogical.Vector64.Int32.1"] = ShiftLeftLogical_Vector64_Int32_1, - ["ShiftLeftLogical.Vector64.SByte.1"] = ShiftLeftLogical_Vector64_SByte_1, - ["ShiftLeftLogical.Vector64.UInt16.1"] = ShiftLeftLogical_Vector64_UInt16_1, - ["ShiftLeftLogical.Vector64.UInt32.1"] = ShiftLeftLogical_Vector64_UInt32_1, - ["ShiftLeftLogical.Vector128.Byte.1"] = ShiftLeftLogical_Vector128_Byte_1, - ["ShiftLeftLogical.Vector128.Int16.1"] = ShiftLeftLogical_Vector128_Int16_1, - ["ShiftLeftLogical.Vector128.Int64.1"] = ShiftLeftLogical_Vector128_Int64_1, - ["ShiftLeftLogical.Vector128.SByte.1"] = ShiftLeftLogical_Vector128_SByte_1, - ["ShiftLeftLogical.Vector128.UInt16.1"] = ShiftLeftLogical_Vector128_UInt16_1, - ["ShiftLeftLogical.Vector128.UInt32.1"] = ShiftLeftLogical_Vector128_UInt32_1, - ["ShiftLeftLogical.Vector128.UInt64.1"] = ShiftLeftLogical_Vector128_UInt64_1, - ["ShiftLeftLogicalSaturate.Vector64.Byte.1"] = ShiftLeftLogicalSaturate_Vector64_Byte_1, - ["ShiftLeftLogicalSaturate.Vector64.Int16.1"] = ShiftLeftLogicalSaturate_Vector64_Int16_1, - ["ShiftLeftLogicalSaturate.Vector64.Int32.1"] = ShiftLeftLogicalSaturate_Vector64_Int32_1, - ["ShiftLeftLogicalSaturate.Vector64.SByte.1"] = ShiftLeftLogicalSaturate_Vector64_SByte_1, - ["ShiftLeftLogicalSaturate.Vector64.UInt16.1"] = ShiftLeftLogicalSaturate_Vector64_UInt16_1, - ["ShiftLeftLogicalSaturate.Vector64.UInt32.1"] = ShiftLeftLogicalSaturate_Vector64_UInt32_1, - ["ShiftLeftLogicalSaturate.Vector128.Byte.1"] = ShiftLeftLogicalSaturate_Vector128_Byte_1, - ["ShiftLeftLogicalSaturate.Vector128.Int16.1"] = ShiftLeftLogicalSaturate_Vector128_Int16_1, - ["ShiftLeftLogicalSaturate.Vector128.Int32.1"] = ShiftLeftLogicalSaturate_Vector128_Int32_1, - ["ShiftLeftLogicalSaturate.Vector128.Int64.1"] = ShiftLeftLogicalSaturate_Vector128_Int64_1, - ["ShiftLeftLogicalSaturate.Vector128.SByte.1"] = ShiftLeftLogicalSaturate_Vector128_SByte_1, - ["ShiftLeftLogicalSaturate.Vector128.UInt16.1"] = ShiftLeftLogicalSaturate_Vector128_UInt16_1, - ["ShiftLeftLogicalSaturate.Vector128.UInt32.1"] = ShiftLeftLogicalSaturate_Vector128_UInt32_1, - ["ShiftLeftLogicalSaturate.Vector128.UInt64.1"] = ShiftLeftLogicalSaturate_Vector128_UInt64_1, - ["ShiftLeftLogicalSaturateScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_Int64_1, - ["ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1, - ["ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1, - ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1, - ["ShiftLeftLogicalScalar.Vector64.Int64.1"] = ShiftLeftLogicalScalar_Vector64_Int64_1, - ["ShiftLeftLogicalScalar.Vector64.UInt64.1"] = ShiftLeftLogicalScalar_Vector64_UInt64_1, - ["ShiftLeftLogicalWideningLower.Vector64.Byte.1"] = ShiftLeftLogicalWideningLower_Vector64_Byte_1, - ["ShiftLeftLogicalWideningLower.Vector64.Int16.1"] = ShiftLeftLogicalWideningLower_Vector64_Int16_1, - ["ShiftLeftLogicalWideningLower.Vector64.Int32.1"] = ShiftLeftLogicalWideningLower_Vector64_Int32_1, - ["ShiftLeftLogicalWideningLower.Vector64.SByte.1"] = ShiftLeftLogicalWideningLower_Vector64_SByte_1, - ["ShiftLeftLogicalWideningLower.Vector64.UInt16.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt16_1, - ["ShiftLeftLogicalWideningLower.Vector64.UInt32.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt32_1, - ["ShiftLeftLogicalWideningUpper.Vector128.Byte.1"] = ShiftLeftLogicalWideningUpper_Vector128_Byte_1, - ["ShiftLeftLogicalWideningUpper.Vector128.Int16.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int16_1, - ["ShiftLeftLogicalWideningUpper.Vector128.Int32.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int32_1, - ["ShiftLeftLogicalWideningUpper.Vector128.SByte.1"] = ShiftLeftLogicalWideningUpper_Vector128_SByte_1, - ["ShiftLeftLogicalWideningUpper.Vector128.UInt16.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt16_1, - ["ShiftLeftLogicalWideningUpper.Vector128.UInt32.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt32_1, - ["ShiftLogical.Vector64.Byte"] = ShiftLogical_Vector64_Byte, - ["ShiftLogical.Vector64.Int16"] = ShiftLogical_Vector64_Int16, - ["ShiftLogical.Vector64.Int32"] = ShiftLogical_Vector64_Int32, - ["ShiftLogical.Vector64.SByte"] = ShiftLogical_Vector64_SByte, - ["ShiftLogical.Vector64.UInt16"] = ShiftLogical_Vector64_UInt16, - ["ShiftLogical.Vector64.UInt32"] = ShiftLogical_Vector64_UInt32, - ["ShiftLogical.Vector128.Byte"] = ShiftLogical_Vector128_Byte, - ["ShiftLogical.Vector128.Int16"] = ShiftLogical_Vector128_Int16, - ["ShiftLogical.Vector128.Int32"] = ShiftLogical_Vector128_Int32, - ["ShiftLogical.Vector128.Int64"] = ShiftLogical_Vector128_Int64, - ["ShiftLogical.Vector128.SByte"] = ShiftLogical_Vector128_SByte, - ["ShiftLogical.Vector128.UInt16"] = ShiftLogical_Vector128_UInt16, - ["ShiftLogical.Vector128.UInt32"] = ShiftLogical_Vector128_UInt32, - ["ShiftLogical.Vector128.UInt64"] = ShiftLogical_Vector128_UInt64, - ["ShiftLogicalRounded.Vector64.Byte"] = ShiftLogicalRounded_Vector64_Byte, - ["ShiftLogicalRounded.Vector64.Int16"] = ShiftLogicalRounded_Vector64_Int16, - ["ShiftLogicalRounded.Vector64.Int32"] = ShiftLogicalRounded_Vector64_Int32, - ["ShiftLogicalRounded.Vector64.SByte"] = ShiftLogicalRounded_Vector64_SByte, - ["ShiftLogicalRounded.Vector64.UInt16"] = ShiftLogicalRounded_Vector64_UInt16, - ["ShiftLogicalRounded.Vector64.UInt32"] = ShiftLogicalRounded_Vector64_UInt32, - ["ShiftLogicalRounded.Vector128.Byte"] = ShiftLogicalRounded_Vector128_Byte, - ["ShiftLogicalRounded.Vector128.Int16"] = ShiftLogicalRounded_Vector128_Int16, - ["ShiftLogicalRounded.Vector128.Int32"] = ShiftLogicalRounded_Vector128_Int32, - ["ShiftLogicalRounded.Vector128.Int64"] = ShiftLogicalRounded_Vector128_Int64, - ["ShiftLogicalRounded.Vector128.SByte"] = ShiftLogicalRounded_Vector128_SByte, - ["ShiftLogicalRounded.Vector128.UInt16"] = ShiftLogicalRounded_Vector128_UInt16, - ["ShiftLogicalRounded.Vector128.UInt32"] = ShiftLogicalRounded_Vector128_UInt32, - ["ShiftLogicalRounded.Vector128.UInt64"] = ShiftLogicalRounded_Vector128_UInt64, - ["ShiftLogicalRoundedSaturate.Vector64.Byte"] = ShiftLogicalRoundedSaturate_Vector64_Byte, - ["ShiftLogicalRoundedSaturate.Vector64.Int16"] = ShiftLogicalRoundedSaturate_Vector64_Int16, - ["ShiftLogicalRoundedSaturate.Vector64.Int32"] = ShiftLogicalRoundedSaturate_Vector64_Int32, - ["ShiftLogicalRoundedSaturate.Vector64.SByte"] = ShiftLogicalRoundedSaturate_Vector64_SByte, - ["ShiftLogicalRoundedSaturate.Vector64.UInt16"] = ShiftLogicalRoundedSaturate_Vector64_UInt16, - ["ShiftLogicalRoundedSaturate.Vector64.UInt32"] = ShiftLogicalRoundedSaturate_Vector64_UInt32, - ["ShiftLogicalRoundedSaturate.Vector128.Byte"] = ShiftLogicalRoundedSaturate_Vector128_Byte, - ["ShiftLogicalRoundedSaturate.Vector128.Int16"] = ShiftLogicalRoundedSaturate_Vector128_Int16, - ["ShiftLogicalRoundedSaturate.Vector128.Int32"] = ShiftLogicalRoundedSaturate_Vector128_Int32, - ["ShiftLogicalRoundedSaturate.Vector128.Int64"] = ShiftLogicalRoundedSaturate_Vector128_Int64, - ["ShiftLogicalRoundedSaturate.Vector128.SByte"] = ShiftLogicalRoundedSaturate_Vector128_SByte, - ["ShiftLogicalRoundedSaturate.Vector128.UInt16"] = ShiftLogicalRoundedSaturate_Vector128_UInt16, - ["ShiftLogicalRoundedSaturate.Vector128.UInt32"] = ShiftLogicalRoundedSaturate_Vector128_UInt32, - ["ShiftLogicalRoundedSaturate.Vector128.UInt64"] = ShiftLogicalRoundedSaturate_Vector128_UInt64, - ["ShiftLogicalRoundedSaturateScalar.Vector64.Int64"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int64, - ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt64"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt64, - ["ShiftLogicalRoundedScalar.Vector64.Int64"] = ShiftLogicalRoundedScalar_Vector64_Int64, - ["ShiftLogicalRoundedScalar.Vector64.UInt64"] = ShiftLogicalRoundedScalar_Vector64_UInt64, - ["ShiftLogicalSaturate.Vector64.Byte"] = ShiftLogicalSaturate_Vector64_Byte, - ["ShiftLogicalSaturate.Vector64.Int16"] = ShiftLogicalSaturate_Vector64_Int16, - ["ShiftLogicalSaturate.Vector64.Int32"] = ShiftLogicalSaturate_Vector64_Int32, - ["ShiftLogicalSaturate.Vector64.SByte"] = ShiftLogicalSaturate_Vector64_SByte, - ["ShiftLogicalSaturate.Vector64.UInt16"] = ShiftLogicalSaturate_Vector64_UInt16, - ["ShiftLogicalSaturate.Vector64.UInt32"] = ShiftLogicalSaturate_Vector64_UInt32, - ["ShiftLogicalSaturate.Vector128.Byte"] = ShiftLogicalSaturate_Vector128_Byte, - ["ShiftLogicalSaturate.Vector128.Int16"] = ShiftLogicalSaturate_Vector128_Int16, - ["ShiftLogicalSaturate.Vector128.Int32"] = ShiftLogicalSaturate_Vector128_Int32, - ["ShiftLogicalSaturate.Vector128.Int64"] = ShiftLogicalSaturate_Vector128_Int64, - ["ShiftLogicalSaturate.Vector128.SByte"] = ShiftLogicalSaturate_Vector128_SByte, - ["ShiftLogicalSaturate.Vector128.UInt16"] = ShiftLogicalSaturate_Vector128_UInt16, - ["ShiftLogicalSaturate.Vector128.UInt32"] = ShiftLogicalSaturate_Vector128_UInt32, - ["ShiftLogicalSaturate.Vector128.UInt64"] = ShiftLogicalSaturate_Vector128_UInt64, - ["ShiftLogicalSaturateScalar.Vector64.Int64"] = ShiftLogicalSaturateScalar_Vector64_Int64, - ["ShiftLogicalSaturateScalar.Vector64.UInt64"] = ShiftLogicalSaturateScalar_Vector64_UInt64, - ["ShiftLogicalScalar.Vector64.Int64"] = ShiftLogicalScalar_Vector64_Int64, - ["ShiftLogicalScalar.Vector64.UInt64"] = ShiftLogicalScalar_Vector64_UInt64, - ["ShiftRightAndInsert.Vector64.Byte"] = ShiftRightAndInsert_Vector64_Byte, - ["ShiftRightAndInsert.Vector64.Int16"] = ShiftRightAndInsert_Vector64_Int16, - ["ShiftRightAndInsert.Vector64.Int32"] = ShiftRightAndInsert_Vector64_Int32, + ["DuplicateSelectedScalarToVector128.Vector128.Single.2"] = DuplicateSelectedScalarToVector128_Vector128_Single_2, + ["DuplicateSelectedScalarToVector128.Vector128.UInt16.4"] = DuplicateSelectedScalarToVector128_Vector128_UInt16_4, + ["DuplicateSelectedScalarToVector128.Vector128.UInt32.2"] = DuplicateSelectedScalarToVector128_Vector128_UInt32_2, + ["DuplicateToVector64.Byte"] = DuplicateToVector64_Byte, + ["DuplicateToVector64.Byte.31"] = DuplicateToVector64_Byte_31, + ["DuplicateToVector64.Int16"] = DuplicateToVector64_Int16, + ["DuplicateToVector64.Int16.31"] = DuplicateToVector64_Int16_31, + ["DuplicateToVector64.Int32"] = DuplicateToVector64_Int32, + ["DuplicateToVector64.Int32.31"] = DuplicateToVector64_Int32_31, + ["DuplicateToVector64.SByte"] = DuplicateToVector64_SByte, + ["DuplicateToVector64.SByte.31"] = DuplicateToVector64_SByte_31, + ["DuplicateToVector64.Single"] = DuplicateToVector64_Single, + ["DuplicateToVector64.Single.31"] = DuplicateToVector64_Single_31, + ["DuplicateToVector64.UInt16"] = DuplicateToVector64_UInt16, + ["DuplicateToVector64.UInt16.31"] = DuplicateToVector64_UInt16_31, + ["DuplicateToVector64.UInt32"] = DuplicateToVector64_UInt32, + ["DuplicateToVector64.UInt32.31"] = DuplicateToVector64_UInt32_31, + ["DuplicateToVector128.Byte"] = DuplicateToVector128_Byte, + ["DuplicateToVector128.Byte.31"] = DuplicateToVector128_Byte_31, + ["DuplicateToVector128.Int16"] = DuplicateToVector128_Int16, + ["DuplicateToVector128.Int16.31"] = DuplicateToVector128_Int16_31, + ["DuplicateToVector128.Int32"] = DuplicateToVector128_Int32, + ["DuplicateToVector128.Int32.31"] = DuplicateToVector128_Int32_31, + ["DuplicateToVector128.SByte"] = DuplicateToVector128_SByte, + ["DuplicateToVector128.SByte.31"] = DuplicateToVector128_SByte_31, + ["DuplicateToVector128.Single"] = DuplicateToVector128_Single, + ["DuplicateToVector128.Single.31"] = DuplicateToVector128_Single_31, + ["DuplicateToVector128.UInt16"] = DuplicateToVector128_UInt16, + ["DuplicateToVector128.UInt16.31"] = DuplicateToVector128_UInt16_31, + ["DuplicateToVector128.UInt32"] = DuplicateToVector128_UInt32, + ["DuplicateToVector128.UInt32.31"] = DuplicateToVector128_UInt32_31, + ["Extract.Vector64.Byte.1"] = Extract_Vector64_Byte_1, + ["Extract.Vector64.Int16.1"] = Extract_Vector64_Int16_1, + ["Extract.Vector64.Int32.1"] = Extract_Vector64_Int32_1, + ["Extract.Vector64.SByte.1"] = Extract_Vector64_SByte_1, + ["Extract.Vector64.Single.1"] = Extract_Vector64_Single_1, + ["Extract.Vector64.UInt16.1"] = Extract_Vector64_UInt16_1, + ["Extract.Vector64.UInt32.1"] = Extract_Vector64_UInt32_1, + ["Extract.Vector128.Byte.1"] = Extract_Vector128_Byte_1, + ["Extract.Vector128.Double.1"] = Extract_Vector128_Double_1, + ["Extract.Vector128.Int16.1"] = Extract_Vector128_Int16_1, + ["Extract.Vector128.Int32.1"] = Extract_Vector128_Int32_1, + ["Extract.Vector128.Int64.1"] = Extract_Vector128_Int64_1, + ["Extract.Vector128.SByte.1"] = Extract_Vector128_SByte_1, + ["Extract.Vector128.Single.1"] = Extract_Vector128_Single_1, + ["Extract.Vector128.UInt16.1"] = Extract_Vector128_UInt16_1, + ["Extract.Vector128.UInt32.1"] = Extract_Vector128_UInt32_1, + ["Extract.Vector128.UInt64.1"] = Extract_Vector128_UInt64_1, + ["ExtractNarrowingLower.Vector64.Byte"] = ExtractNarrowingLower_Vector64_Byte, + ["ExtractNarrowingLower.Vector64.Int16"] = ExtractNarrowingLower_Vector64_Int16, + ["ExtractNarrowingLower.Vector64.Int32"] = ExtractNarrowingLower_Vector64_Int32, + ["ExtractNarrowingLower.Vector64.SByte"] = ExtractNarrowingLower_Vector64_SByte, + ["ExtractNarrowingLower.Vector64.UInt16"] = ExtractNarrowingLower_Vector64_UInt16, + ["ExtractNarrowingLower.Vector64.UInt32"] = ExtractNarrowingLower_Vector64_UInt32, + ["ExtractNarrowingSaturateLower.Vector64.Byte"] = ExtractNarrowingSaturateLower_Vector64_Byte, + ["ExtractNarrowingSaturateLower.Vector64.Int16"] = ExtractNarrowingSaturateLower_Vector64_Int16, + ["ExtractNarrowingSaturateLower.Vector64.Int32"] = ExtractNarrowingSaturateLower_Vector64_Int32, + ["ExtractNarrowingSaturateLower.Vector64.SByte"] = ExtractNarrowingSaturateLower_Vector64_SByte, + ["ExtractNarrowingSaturateLower.Vector64.UInt16"] = ExtractNarrowingSaturateLower_Vector64_UInt16, + ["ExtractNarrowingSaturateLower.Vector64.UInt32"] = ExtractNarrowingSaturateLower_Vector64_UInt32, + ["ExtractNarrowingSaturateUnsignedLower.Vector64.Byte"] = ExtractNarrowingSaturateUnsignedLower_Vector64_Byte, + ["ExtractNarrowingSaturateUnsignedLower.Vector64.UInt16"] = ExtractNarrowingSaturateUnsignedLower_Vector64_UInt16, + ["ExtractNarrowingSaturateUnsignedLower.Vector64.UInt32"] = ExtractNarrowingSaturateUnsignedLower_Vector64_UInt32, + ["ExtractNarrowingSaturateUnsignedUpper.Vector128.Byte"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_Byte, + ["ExtractNarrowingSaturateUnsignedUpper.Vector128.UInt16"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt16, + ["ExtractNarrowingSaturateUnsignedUpper.Vector128.UInt32"] = ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt32, + ["ExtractNarrowingSaturateUpper.Vector128.Byte"] = ExtractNarrowingSaturateUpper_Vector128_Byte, + ["ExtractNarrowingSaturateUpper.Vector128.Int16"] = ExtractNarrowingSaturateUpper_Vector128_Int16, + ["ExtractNarrowingSaturateUpper.Vector128.Int32"] = ExtractNarrowingSaturateUpper_Vector128_Int32, + ["ExtractNarrowingSaturateUpper.Vector128.SByte"] = ExtractNarrowingSaturateUpper_Vector128_SByte, + ["ExtractNarrowingSaturateUpper.Vector128.UInt16"] = ExtractNarrowingSaturateUpper_Vector128_UInt16, + ["ExtractNarrowingSaturateUpper.Vector128.UInt32"] = ExtractNarrowingSaturateUpper_Vector128_UInt32, + ["ExtractNarrowingUpper.Vector128.Byte"] = ExtractNarrowingUpper_Vector128_Byte, + ["ExtractNarrowingUpper.Vector128.Int16"] = ExtractNarrowingUpper_Vector128_Int16, + ["ExtractNarrowingUpper.Vector128.Int32"] = ExtractNarrowingUpper_Vector128_Int32, + ["ExtractNarrowingUpper.Vector128.SByte"] = ExtractNarrowingUpper_Vector128_SByte, + ["ExtractNarrowingUpper.Vector128.UInt16"] = ExtractNarrowingUpper_Vector128_UInt16, + ["ExtractNarrowingUpper.Vector128.UInt32"] = ExtractNarrowingUpper_Vector128_UInt32, + ["ExtractVector64.Byte.1"] = ExtractVector64_Byte_1, + ["ExtractVector64.Int16.1"] = ExtractVector64_Int16_1, + ["ExtractVector64.Int32.1"] = ExtractVector64_Int32_1, + ["ExtractVector64.SByte.1"] = ExtractVector64_SByte_1, + ["ExtractVector64.Single.1"] = ExtractVector64_Single_1, + ["ExtractVector64.UInt16.1"] = ExtractVector64_UInt16_1, + ["ExtractVector64.UInt32.1"] = ExtractVector64_UInt32_1, + ["ExtractVector128.Byte.1"] = ExtractVector128_Byte_1, + ["ExtractVector128.Double.1"] = ExtractVector128_Double_1, + ["ExtractVector128.Int16.1"] = ExtractVector128_Int16_1, + ["ExtractVector128.Int32.1"] = ExtractVector128_Int32_1, + ["ExtractVector128.Int64.1"] = ExtractVector128_Int64_1, + ["ExtractVector128.SByte.1"] = ExtractVector128_SByte_1, + ["ExtractVector128.Single.1"] = ExtractVector128_Single_1, + ["ExtractVector128.UInt16.1"] = ExtractVector128_UInt16_1, + ["ExtractVector128.UInt32.1"] = ExtractVector128_UInt32_1, + ["ExtractVector128.UInt64.1"] = ExtractVector128_UInt64_1, + ["Floor.Vector64.Single"] = Floor_Vector64_Single, + ["Floor.Vector128.Single"] = Floor_Vector128_Single, + ["FloorScalar.Vector64.Double"] = FloorScalar_Vector64_Double, + ["FloorScalar.Vector64.Single"] = FloorScalar_Vector64_Single, + ["FusedAddHalving.Vector64.Byte"] = FusedAddHalving_Vector64_Byte, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part5.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part5.cs index 7225c4bfd268..9b906de9804c 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part5.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part5.cs @@ -11,262 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["ShiftRightAndInsert.Vector64.SByte"] = ShiftRightAndInsert_Vector64_SByte, - ["ShiftRightAndInsert.Vector64.UInt16"] = ShiftRightAndInsert_Vector64_UInt16, - ["ShiftRightAndInsert.Vector64.UInt32"] = ShiftRightAndInsert_Vector64_UInt32, - ["ShiftRightAndInsert.Vector128.Byte"] = ShiftRightAndInsert_Vector128_Byte, - ["ShiftRightAndInsert.Vector128.Int16"] = ShiftRightAndInsert_Vector128_Int16, - ["ShiftRightAndInsert.Vector128.Int32"] = ShiftRightAndInsert_Vector128_Int32, - ["ShiftRightAndInsert.Vector128.Int64"] = ShiftRightAndInsert_Vector128_Int64, - ["ShiftRightAndInsert.Vector128.SByte"] = ShiftRightAndInsert_Vector128_SByte, - ["ShiftRightAndInsert.Vector128.UInt16"] = ShiftRightAndInsert_Vector128_UInt16, - ["ShiftRightAndInsert.Vector128.UInt32"] = ShiftRightAndInsert_Vector128_UInt32, - ["ShiftRightAndInsert.Vector128.UInt64"] = ShiftRightAndInsert_Vector128_UInt64, - ["ShiftRightAndInsertScalar.Vector64.Int64"] = ShiftRightAndInsertScalar_Vector64_Int64, - ["ShiftRightAndInsertScalar.Vector64.UInt64"] = ShiftRightAndInsertScalar_Vector64_UInt64, - ["ShiftRightArithmetic.Vector64.Int16.1"] = ShiftRightArithmetic_Vector64_Int16_1, - ["ShiftRightArithmetic.Vector64.Int32.1"] = ShiftRightArithmetic_Vector64_Int32_1, - ["ShiftRightArithmetic.Vector64.SByte.1"] = ShiftRightArithmetic_Vector64_SByte_1, - ["ShiftRightArithmetic.Vector128.Int16.1"] = ShiftRightArithmetic_Vector128_Int16_1, - ["ShiftRightArithmetic.Vector128.Int32.1"] = ShiftRightArithmetic_Vector128_Int32_1, - ["ShiftRightArithmetic.Vector128.Int64.1"] = ShiftRightArithmetic_Vector128_Int64_1, - ["ShiftRightArithmetic.Vector128.SByte.1"] = ShiftRightArithmetic_Vector128_SByte_1, - ["ShiftRightArithmeticAdd.Vector64.Int16.1"] = ShiftRightArithmeticAdd_Vector64_Int16_1, - ["ShiftRightArithmeticAdd.Vector64.Int32.1"] = ShiftRightArithmeticAdd_Vector64_Int32_1, - ["ShiftRightArithmeticAdd.Vector64.SByte.1"] = ShiftRightArithmeticAdd_Vector64_SByte_1, - ["ShiftRightArithmeticAdd.Vector128.Int16.1"] = ShiftRightArithmeticAdd_Vector128_Int16_1, - ["ShiftRightArithmeticAdd.Vector128.Int32.1"] = ShiftRightArithmeticAdd_Vector128_Int32_1, - ["ShiftRightArithmeticAdd.Vector128.Int64.1"] = ShiftRightArithmeticAdd_Vector128_Int64_1, - ["ShiftRightArithmeticAdd.Vector128.SByte.1"] = ShiftRightArithmeticAdd_Vector128_SByte_1, - ["ShiftRightArithmeticAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticAddScalar_Vector64_Int64_1, - ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1, - ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1, - ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, - ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, - ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1, - ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1, - ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1, - ["ShiftRightArithmeticRounded.Vector64.Int16.1"] = ShiftRightArithmeticRounded_Vector64_Int16_1, - ["ShiftRightArithmeticRounded.Vector64.Int32.1"] = ShiftRightArithmeticRounded_Vector64_Int32_1, - ["ShiftRightArithmeticRounded.Vector64.SByte.1"] = ShiftRightArithmeticRounded_Vector64_SByte_1, - ["ShiftRightArithmeticRounded.Vector128.Int16.1"] = ShiftRightArithmeticRounded_Vector128_Int16_1, - ["ShiftRightArithmeticRounded.Vector128.Int32.1"] = ShiftRightArithmeticRounded_Vector128_Int32_1, - ["ShiftRightArithmeticRounded.Vector128.Int64.1"] = ShiftRightArithmeticRounded_Vector128_Int64_1, - ["ShiftRightArithmeticRounded.Vector128.SByte.1"] = ShiftRightArithmeticRounded_Vector128_SByte_1, - ["ShiftRightArithmeticRoundedAdd.Vector64.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int16_1, - ["ShiftRightArithmeticRoundedAdd.Vector64.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int32_1, - ["ShiftRightArithmeticRoundedAdd.Vector64.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector64_SByte_1, - ["ShiftRightArithmeticRoundedAdd.Vector128.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int16_1, - ["ShiftRightArithmeticRoundedAdd.Vector128.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int32_1, - ["ShiftRightArithmeticRoundedAdd.Vector128.Int64.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int64_1, - ["ShiftRightArithmeticRoundedAdd.Vector128.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector128_SByte_1, - ["ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1, - ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1, - ["ShiftRightArithmeticRoundedScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedScalar_Vector64_Int64_1, - ["ShiftRightArithmeticScalar.Vector64.Int64.1"] = ShiftRightArithmeticScalar_Vector64_Int64_1, - ["ShiftRightLogical.Vector64.Byte.1"] = ShiftRightLogical_Vector64_Byte_1, - ["ShiftRightLogical.Vector64.Int16.1"] = ShiftRightLogical_Vector64_Int16_1, - ["ShiftRightLogical.Vector64.Int32.1"] = ShiftRightLogical_Vector64_Int32_1, - ["ShiftRightLogical.Vector64.SByte.1"] = ShiftRightLogical_Vector64_SByte_1, - ["ShiftRightLogical.Vector64.UInt16.1"] = ShiftRightLogical_Vector64_UInt16_1, - ["ShiftRightLogical.Vector64.UInt32.1"] = ShiftRightLogical_Vector64_UInt32_1, - ["ShiftRightLogical.Vector128.Byte.1"] = ShiftRightLogical_Vector128_Byte_1, - ["ShiftRightLogical.Vector128.Int16.1"] = ShiftRightLogical_Vector128_Int16_1, - ["ShiftRightLogical.Vector128.Int32.1"] = ShiftRightLogical_Vector128_Int32_1, - ["ShiftRightLogical.Vector128.Int64.1"] = ShiftRightLogical_Vector128_Int64_1, - ["ShiftRightLogical.Vector128.SByte.1"] = ShiftRightLogical_Vector128_SByte_1, - ["ShiftRightLogical.Vector128.UInt16.1"] = ShiftRightLogical_Vector128_UInt16_1, - ["ShiftRightLogical.Vector128.UInt32.1"] = ShiftRightLogical_Vector128_UInt32_1, - ["ShiftRightLogical.Vector128.UInt64.1"] = ShiftRightLogical_Vector128_UInt64_1, - ["ShiftRightLogicalAdd.Vector64.Byte.1"] = ShiftRightLogicalAdd_Vector64_Byte_1, - ["ShiftRightLogicalAdd.Vector64.Int16.1"] = ShiftRightLogicalAdd_Vector64_Int16_1, - ["ShiftRightLogicalAdd.Vector64.Int32.1"] = ShiftRightLogicalAdd_Vector64_Int32_1, - ["ShiftRightLogicalAdd.Vector64.SByte.1"] = ShiftRightLogicalAdd_Vector64_SByte_1, - ["ShiftRightLogicalAdd.Vector64.UInt16.1"] = ShiftRightLogicalAdd_Vector64_UInt16_1, - ["ShiftRightLogicalAdd.Vector64.UInt32.1"] = ShiftRightLogicalAdd_Vector64_UInt32_1, - ["ShiftRightLogicalAdd.Vector128.Byte.1"] = ShiftRightLogicalAdd_Vector128_Byte_1, - ["ShiftRightLogicalAdd.Vector128.Int16.1"] = ShiftRightLogicalAdd_Vector128_Int16_1, - ["ShiftRightLogicalAdd.Vector128.Int32.1"] = ShiftRightLogicalAdd_Vector128_Int32_1, - ["ShiftRightLogicalAdd.Vector128.Int64.1"] = ShiftRightLogicalAdd_Vector128_Int64_1, - ["ShiftRightLogicalAdd.Vector128.SByte.1"] = ShiftRightLogicalAdd_Vector128_SByte_1, - ["ShiftRightLogicalAdd.Vector128.UInt16.1"] = ShiftRightLogicalAdd_Vector128_UInt16_1, - ["ShiftRightLogicalAdd.Vector128.UInt32.1"] = ShiftRightLogicalAdd_Vector128_UInt32_1, - ["ShiftRightLogicalAdd.Vector128.UInt64.1"] = ShiftRightLogicalAdd_Vector128_UInt64_1, - ["ShiftRightLogicalAddScalar.Vector64.Int64.1"] = ShiftRightLogicalAddScalar_Vector64_Int64_1, - ["ShiftRightLogicalAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalAddScalar_Vector64_UInt64_1, - ["ShiftRightLogicalNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingLower_Vector64_Byte_1, - ["ShiftRightLogicalNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int16_1, - ["ShiftRightLogicalNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int32_1, - ["ShiftRightLogicalNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingLower_Vector64_SByte_1, - ["ShiftRightLogicalNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt16_1, - ["ShiftRightLogicalNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt32_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1, - ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1, - ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Byte_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int16_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int32_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_SByte_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1, - ["ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1, - ["ShiftRightLogicalRounded.Vector64.Byte.1"] = ShiftRightLogicalRounded_Vector64_Byte_1, - ["ShiftRightLogicalRounded.Vector64.Int16.1"] = ShiftRightLogicalRounded_Vector64_Int16_1, - ["ShiftRightLogicalRounded.Vector64.Int32.1"] = ShiftRightLogicalRounded_Vector64_Int32_1, - ["ShiftRightLogicalRounded.Vector64.SByte.1"] = ShiftRightLogicalRounded_Vector64_SByte_1, - ["ShiftRightLogicalRounded.Vector64.UInt16.1"] = ShiftRightLogicalRounded_Vector64_UInt16_1, - ["ShiftRightLogicalRounded.Vector64.UInt32.1"] = ShiftRightLogicalRounded_Vector64_UInt32_1, - ["ShiftRightLogicalRounded.Vector128.Byte.1"] = ShiftRightLogicalRounded_Vector128_Byte_1, - ["ShiftRightLogicalRounded.Vector128.Int16.1"] = ShiftRightLogicalRounded_Vector128_Int16_1, - ["ShiftRightLogicalRounded.Vector128.Int32.1"] = ShiftRightLogicalRounded_Vector128_Int32_1, - ["ShiftRightLogicalRounded.Vector128.Int64.1"] = ShiftRightLogicalRounded_Vector128_Int64_1, - ["ShiftRightLogicalRounded.Vector128.SByte.1"] = ShiftRightLogicalRounded_Vector128_SByte_1, - ["ShiftRightLogicalRounded.Vector128.UInt16.1"] = ShiftRightLogicalRounded_Vector128_UInt16_1, - ["ShiftRightLogicalRounded.Vector128.UInt32.1"] = ShiftRightLogicalRounded_Vector128_UInt32_1, - ["ShiftRightLogicalRounded.Vector128.UInt64.1"] = ShiftRightLogicalRounded_Vector128_UInt64_1, - ["ShiftRightLogicalRoundedAdd.Vector64.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector64_Byte_1, - ["ShiftRightLogicalRoundedAdd.Vector64.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int16_1, - ["ShiftRightLogicalRoundedAdd.Vector64.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int32_1, - ["ShiftRightLogicalRoundedAdd.Vector64.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector64_SByte_1, - ["ShiftRightLogicalRoundedAdd.Vector64.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt16_1, - ["ShiftRightLogicalRoundedAdd.Vector64.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt32_1, - ["ShiftRightLogicalRoundedAdd.Vector128.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector128_Byte_1, - ["ShiftRightLogicalRoundedAdd.Vector128.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int16_1, - ["ShiftRightLogicalRoundedAdd.Vector128.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int32_1, - ["ShiftRightLogicalRoundedAdd.Vector128.Int64.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int64_1, - ["ShiftRightLogicalRoundedAdd.Vector128.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector128_SByte_1, - ["ShiftRightLogicalRoundedAdd.Vector128.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt16_1, - ["ShiftRightLogicalRoundedAdd.Vector128.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt32_1, - ["ShiftRightLogicalRoundedAdd.Vector128.UInt64.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt64_1, - ["ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1, - ["ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1, - ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1, - ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1, - ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1, - ["ShiftRightLogicalRoundedScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedScalar_Vector64_Int64_1, - ["ShiftRightLogicalRoundedScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedScalar_Vector64_UInt64_1, - ["ShiftRightLogicalScalar.Vector64.Int64.1"] = ShiftRightLogicalScalar_Vector64_Int64_1, - ["ShiftRightLogicalScalar.Vector64.UInt64.1"] = ShiftRightLogicalScalar_Vector64_UInt64_1, - ["SignExtendWideningLower.Vector64.Int16"] = SignExtendWideningLower_Vector64_Int16, - ["SignExtendWideningLower.Vector64.Int32"] = SignExtendWideningLower_Vector64_Int32, - ["SignExtendWideningLower.Vector64.SByte"] = SignExtendWideningLower_Vector64_SByte, - ["SignExtendWideningUpper.Vector128.Int16"] = SignExtendWideningUpper_Vector128_Int16, - ["SignExtendWideningUpper.Vector128.Int32"] = SignExtendWideningUpper_Vector128_Int32, - ["SignExtendWideningUpper.Vector128.SByte"] = SignExtendWideningUpper_Vector128_SByte, - ["SqrtScalar.Vector64.Double"] = SqrtScalar_Vector64_Double, - ["SqrtScalar.Vector64.Single"] = SqrtScalar_Vector64_Single, - ["Store.Vector64.Byte"] = Store_Vector64_Byte, - ["Store.Vector64.Double"] = Store_Vector64_Double, - ["Store.Vector64.Int16"] = Store_Vector64_Int16, - ["Store.Vector64.Int32"] = Store_Vector64_Int32, - ["Store.Vector64.Int64"] = Store_Vector64_Int64, - ["Store.Vector64.SByte"] = Store_Vector64_SByte, - ["Store.Vector64.Single"] = Store_Vector64_Single, - ["Store.Vector64.UInt16"] = Store_Vector64_UInt16, - ["Store.Vector64.UInt32"] = Store_Vector64_UInt32, - ["Store.Vector64.UInt64"] = Store_Vector64_UInt64, - ["Store.Vector128.Byte"] = Store_Vector128_Byte, - ["Store.Vector128.Double"] = Store_Vector128_Double, - ["Store.Vector128.Int16"] = Store_Vector128_Int16, - ["Store.Vector128.Int32"] = Store_Vector128_Int32, - ["Store.Vector128.Int64"] = Store_Vector128_Int64, - ["Store.Vector128.SByte"] = Store_Vector128_SByte, - ["Store.Vector128.Single"] = Store_Vector128_Single, - ["Store.Vector128.UInt16"] = Store_Vector128_UInt16, - ["Store.Vector128.UInt32"] = Store_Vector128_UInt32, - ["Store.Vector128.UInt64"] = Store_Vector128_UInt64, - ["StoreSelectedScalar.Vector64.Byte.7"] = StoreSelectedScalar_Vector64_Byte_7, - ["StoreSelectedScalar.Vector64.Int16.3"] = StoreSelectedScalar_Vector64_Int16_3, - ["StoreSelectedScalar.Vector64.Int32.1"] = StoreSelectedScalar_Vector64_Int32_1, - ["StoreSelectedScalar.Vector64.SByte.7"] = StoreSelectedScalar_Vector64_SByte_7, - ["StoreSelectedScalar.Vector64.Single.1"] = StoreSelectedScalar_Vector64_Single_1, - ["StoreSelectedScalar.Vector64.UInt16.3"] = StoreSelectedScalar_Vector64_UInt16_3, - ["StoreSelectedScalar.Vector64.UInt32.1"] = StoreSelectedScalar_Vector64_UInt32_1, - ["StoreSelectedScalar.Vector128.Byte.15"] = StoreSelectedScalar_Vector128_Byte_15, - ["StoreSelectedScalar.Vector128.Double.1"] = StoreSelectedScalar_Vector128_Double_1, - ["StoreSelectedScalar.Vector128.Int16.7"] = StoreSelectedScalar_Vector128_Int16_7, - ["StoreSelectedScalar.Vector128.Int32.3"] = StoreSelectedScalar_Vector128_Int32_3, - ["StoreSelectedScalar.Vector128.Int64.1"] = StoreSelectedScalar_Vector128_Int64_1, - ["StoreSelectedScalar.Vector128.SByte.15"] = StoreSelectedScalar_Vector128_SByte_15, - ["StoreSelectedScalar.Vector128.Single.3"] = StoreSelectedScalar_Vector128_Single_3, - ["StoreSelectedScalar.Vector128.UInt16.7"] = StoreSelectedScalar_Vector128_UInt16_7, - ["StoreSelectedScalar.Vector128.UInt32.3"] = StoreSelectedScalar_Vector128_UInt32_3, - ["StoreSelectedScalar.Vector128.UInt64.1"] = StoreSelectedScalar_Vector128_UInt64_1, - ["Subtract.Vector64.Byte"] = Subtract_Vector64_Byte, - ["Subtract.Vector64.Int16"] = Subtract_Vector64_Int16, - ["Subtract.Vector64.Int32"] = Subtract_Vector64_Int32, - ["Subtract.Vector64.SByte"] = Subtract_Vector64_SByte, - ["Subtract.Vector64.Single"] = Subtract_Vector64_Single, - ["Subtract.Vector64.UInt16"] = Subtract_Vector64_UInt16, - ["Subtract.Vector64.UInt32"] = Subtract_Vector64_UInt32, - ["Subtract.Vector128.Byte"] = Subtract_Vector128_Byte, - ["Subtract.Vector128.Int16"] = Subtract_Vector128_Int16, - ["Subtract.Vector128.Int32"] = Subtract_Vector128_Int32, - ["Subtract.Vector128.Int64"] = Subtract_Vector128_Int64, - ["Subtract.Vector128.SByte"] = Subtract_Vector128_SByte, - ["Subtract.Vector128.Single"] = Subtract_Vector128_Single, - ["Subtract.Vector128.UInt16"] = Subtract_Vector128_UInt16, - ["Subtract.Vector128.UInt32"] = Subtract_Vector128_UInt32, - ["Subtract.Vector128.UInt64"] = Subtract_Vector128_UInt64, - ["SubtractHighNarrowingLower.Vector64.Byte"] = SubtractHighNarrowingLower_Vector64_Byte, - ["SubtractHighNarrowingLower.Vector64.Int16"] = SubtractHighNarrowingLower_Vector64_Int16, - ["SubtractHighNarrowingLower.Vector64.Int32"] = SubtractHighNarrowingLower_Vector64_Int32, - ["SubtractHighNarrowingLower.Vector64.SByte"] = SubtractHighNarrowingLower_Vector64_SByte, - ["SubtractHighNarrowingLower.Vector64.UInt16"] = SubtractHighNarrowingLower_Vector64_UInt16, - ["SubtractHighNarrowingLower.Vector64.UInt32"] = SubtractHighNarrowingLower_Vector64_UInt32, - ["SubtractHighNarrowingUpper.Vector128.Byte"] = SubtractHighNarrowingUpper_Vector128_Byte, - ["SubtractHighNarrowingUpper.Vector128.Int16"] = SubtractHighNarrowingUpper_Vector128_Int16, - ["SubtractHighNarrowingUpper.Vector128.Int32"] = SubtractHighNarrowingUpper_Vector128_Int32, - ["SubtractHighNarrowingUpper.Vector128.SByte"] = SubtractHighNarrowingUpper_Vector128_SByte, - ["SubtractHighNarrowingUpper.Vector128.UInt16"] = SubtractHighNarrowingUpper_Vector128_UInt16, - ["SubtractHighNarrowingUpper.Vector128.UInt32"] = SubtractHighNarrowingUpper_Vector128_UInt32, - ["SubtractRoundedHighNarrowingLower.Vector64.Byte"] = SubtractRoundedHighNarrowingLower_Vector64_Byte, - ["SubtractRoundedHighNarrowingLower.Vector64.Int16"] = SubtractRoundedHighNarrowingLower_Vector64_Int16, + ["FusedAddHalving.Vector64.Int16"] = FusedAddHalving_Vector64_Int16, + ["FusedAddHalving.Vector64.Int32"] = FusedAddHalving_Vector64_Int32, + ["FusedAddHalving.Vector64.SByte"] = FusedAddHalving_Vector64_SByte, + ["FusedAddHalving.Vector64.UInt16"] = FusedAddHalving_Vector64_UInt16, + ["FusedAddHalving.Vector64.UInt32"] = FusedAddHalving_Vector64_UInt32, + ["FusedAddHalving.Vector128.Byte"] = FusedAddHalving_Vector128_Byte, + ["FusedAddHalving.Vector128.Int16"] = FusedAddHalving_Vector128_Int16, + ["FusedAddHalving.Vector128.Int32"] = FusedAddHalving_Vector128_Int32, + ["FusedAddHalving.Vector128.SByte"] = FusedAddHalving_Vector128_SByte, + ["FusedAddHalving.Vector128.UInt16"] = FusedAddHalving_Vector128_UInt16, + ["FusedAddHalving.Vector128.UInt32"] = FusedAddHalving_Vector128_UInt32, + ["FusedAddRoundedHalving.Vector64.Byte"] = FusedAddRoundedHalving_Vector64_Byte, + ["FusedAddRoundedHalving.Vector64.Int16"] = FusedAddRoundedHalving_Vector64_Int16, + ["FusedAddRoundedHalving.Vector64.Int32"] = FusedAddRoundedHalving_Vector64_Int32, + ["FusedAddRoundedHalving.Vector64.SByte"] = FusedAddRoundedHalving_Vector64_SByte, + ["FusedAddRoundedHalving.Vector64.UInt16"] = FusedAddRoundedHalving_Vector64_UInt16, + ["FusedAddRoundedHalving.Vector64.UInt32"] = FusedAddRoundedHalving_Vector64_UInt32, + ["FusedAddRoundedHalving.Vector128.Byte"] = FusedAddRoundedHalving_Vector128_Byte, + ["FusedAddRoundedHalving.Vector128.Int16"] = FusedAddRoundedHalving_Vector128_Int16, + ["FusedAddRoundedHalving.Vector128.Int32"] = FusedAddRoundedHalving_Vector128_Int32, + ["FusedAddRoundedHalving.Vector128.SByte"] = FusedAddRoundedHalving_Vector128_SByte, + ["FusedAddRoundedHalving.Vector128.UInt16"] = FusedAddRoundedHalving_Vector128_UInt16, + ["FusedAddRoundedHalving.Vector128.UInt32"] = FusedAddRoundedHalving_Vector128_UInt32, + ["FusedMultiplyAdd.Vector64.Single"] = FusedMultiplyAdd_Vector64_Single, + ["FusedMultiplyAdd.Vector128.Single"] = FusedMultiplyAdd_Vector128_Single, + ["FusedMultiplyAddScalar.Vector64.Double"] = FusedMultiplyAddScalar_Vector64_Double, + ["FusedMultiplyAddScalar.Vector64.Single"] = FusedMultiplyAddScalar_Vector64_Single, + ["FusedMultiplyAddNegatedScalar.Vector64.Double"] = FusedMultiplyAddNegatedScalar_Vector64_Double, + ["FusedMultiplyAddNegatedScalar.Vector64.Single"] = FusedMultiplyAddNegatedScalar_Vector64_Single, + ["FusedMultiplySubtract.Vector64.Single"] = FusedMultiplySubtract_Vector64_Single, + ["FusedMultiplySubtract.Vector128.Single"] = FusedMultiplySubtract_Vector128_Single, + ["FusedMultiplySubtractScalar.Vector64.Double"] = FusedMultiplySubtractScalar_Vector64_Double, + ["FusedMultiplySubtractScalar.Vector64.Single"] = FusedMultiplySubtractScalar_Vector64_Single, + ["FusedMultiplySubtractNegatedScalar.Vector64.Double"] = FusedMultiplySubtractNegatedScalar_Vector64_Double, + ["FusedMultiplySubtractNegatedScalar.Vector64.Single"] = FusedMultiplySubtractNegatedScalar_Vector64_Single, + ["FusedSubtractHalving.Vector64.Byte"] = FusedSubtractHalving_Vector64_Byte, + ["FusedSubtractHalving.Vector64.Int16"] = FusedSubtractHalving_Vector64_Int16, + ["FusedSubtractHalving.Vector64.Int32"] = FusedSubtractHalving_Vector64_Int32, + ["FusedSubtractHalving.Vector64.SByte"] = FusedSubtractHalving_Vector64_SByte, + ["FusedSubtractHalving.Vector64.UInt16"] = FusedSubtractHalving_Vector64_UInt16, + ["FusedSubtractHalving.Vector64.UInt32"] = FusedSubtractHalving_Vector64_UInt32, + ["FusedSubtractHalving.Vector128.Byte"] = FusedSubtractHalving_Vector128_Byte, + ["FusedSubtractHalving.Vector128.Int16"] = FusedSubtractHalving_Vector128_Int16, + ["FusedSubtractHalving.Vector128.Int32"] = FusedSubtractHalving_Vector128_Int32, + ["FusedSubtractHalving.Vector128.SByte"] = FusedSubtractHalving_Vector128_SByte, + ["FusedSubtractHalving.Vector128.UInt16"] = FusedSubtractHalving_Vector128_UInt16, + ["FusedSubtractHalving.Vector128.UInt32"] = FusedSubtractHalving_Vector128_UInt32, + ["Insert.Vector64.Byte.1"] = Insert_Vector64_Byte_1, + ["Insert.Vector64.Int16.1"] = Insert_Vector64_Int16_1, + ["Insert.Vector64.Int32.1"] = Insert_Vector64_Int32_1, + ["Insert.Vector64.SByte.1"] = Insert_Vector64_SByte_1, + ["Insert.Vector64.Single.1"] = Insert_Vector64_Single_1, + ["Insert.Vector64.UInt16.1"] = Insert_Vector64_UInt16_1, + ["Insert.Vector64.UInt32.1"] = Insert_Vector64_UInt32_1, + ["Insert.Vector128.Byte.1"] = Insert_Vector128_Byte_1, + ["Insert.Vector128.Double.1"] = Insert_Vector128_Double_1, + ["Insert.Vector128.Int16.1"] = Insert_Vector128_Int16_1, + ["Insert.Vector128.Int32.1"] = Insert_Vector128_Int32_1, + ["Insert.Vector128.Int64.1"] = Insert_Vector128_Int64_1, + ["Insert.Vector128.SByte.1"] = Insert_Vector128_SByte_1, + ["Insert.Vector128.Single.1"] = Insert_Vector128_Single_1, + ["Insert.Vector128.UInt16.1"] = Insert_Vector128_UInt16_1, + ["Insert.Vector128.UInt32.1"] = Insert_Vector128_UInt32_1, + ["Insert.Vector128.UInt64.1"] = Insert_Vector128_UInt64_1, + ["InsertScalar.Vector128.Double.1"] = InsertScalar_Vector128_Double_1, + ["InsertScalar.Vector128.Int64.1"] = InsertScalar_Vector128_Int64_1, + ["InsertScalar.Vector128.UInt64.1"] = InsertScalar_Vector128_UInt64_1, + ["LeadingSignCount.Vector64.Int16"] = LeadingSignCount_Vector64_Int16, + ["LeadingSignCount.Vector64.Int32"] = LeadingSignCount_Vector64_Int32, + ["LeadingSignCount.Vector64.SByte"] = LeadingSignCount_Vector64_SByte, + ["LeadingSignCount.Vector128.Int16"] = LeadingSignCount_Vector128_Int16, + ["LeadingSignCount.Vector128.Int32"] = LeadingSignCount_Vector128_Int32, + ["LeadingSignCount.Vector128.SByte"] = LeadingSignCount_Vector128_SByte, + ["LeadingZeroCount.Vector64.Byte"] = LeadingZeroCount_Vector64_Byte, + ["LeadingZeroCount.Vector64.Int16"] = LeadingZeroCount_Vector64_Int16, + ["LeadingZeroCount.Vector64.Int32"] = LeadingZeroCount_Vector64_Int32, + ["LeadingZeroCount.Vector64.SByte"] = LeadingZeroCount_Vector64_SByte, + ["LeadingZeroCount.Vector64.UInt16"] = LeadingZeroCount_Vector64_UInt16, + ["LeadingZeroCount.Vector64.UInt32"] = LeadingZeroCount_Vector64_UInt32, + ["LeadingZeroCount.Vector128.Byte"] = LeadingZeroCount_Vector128_Byte, + ["LeadingZeroCount.Vector128.Int16"] = LeadingZeroCount_Vector128_Int16, + ["LeadingZeroCount.Vector128.Int32"] = LeadingZeroCount_Vector128_Int32, + ["LeadingZeroCount.Vector128.SByte"] = LeadingZeroCount_Vector128_SByte, + ["LeadingZeroCount.Vector128.UInt16"] = LeadingZeroCount_Vector128_UInt16, + ["LeadingZeroCount.Vector128.UInt32"] = LeadingZeroCount_Vector128_UInt32, + ["LoadAndInsertScalar.Vector64.Byte.7"] = LoadAndInsertScalar_Vector64_Byte_7, + ["LoadAndInsertScalar.Vector64.Int16.3"] = LoadAndInsertScalar_Vector64_Int16_3, + ["LoadAndInsertScalar.Vector64.Int32.1"] = LoadAndInsertScalar_Vector64_Int32_1, + ["LoadAndInsertScalar.Vector64.SByte.7"] = LoadAndInsertScalar_Vector64_SByte_7, + ["LoadAndInsertScalar.Vector64.Single.1"] = LoadAndInsertScalar_Vector64_Single_1, + ["LoadAndInsertScalar.Vector64.UInt16.3"] = LoadAndInsertScalar_Vector64_UInt16_3, + ["LoadAndInsertScalar.Vector64.UInt32.1"] = LoadAndInsertScalar_Vector64_UInt32_1, + ["LoadAndInsertScalar.Vector128.Byte.15"] = LoadAndInsertScalar_Vector128_Byte_15, + ["LoadAndInsertScalar.Vector128.Double.1"] = LoadAndInsertScalar_Vector128_Double_1, + ["LoadAndInsertScalar.Vector128.Int16.7"] = LoadAndInsertScalar_Vector128_Int16_7, + ["LoadAndInsertScalar.Vector128.Int32.3"] = LoadAndInsertScalar_Vector128_Int32_3, + ["LoadAndInsertScalar.Vector128.Int64.1"] = LoadAndInsertScalar_Vector128_Int64_1, + ["LoadAndInsertScalar.Vector128.SByte.15"] = LoadAndInsertScalar_Vector128_SByte_15, + ["LoadAndInsertScalar.Vector128.Single.3"] = LoadAndInsertScalar_Vector128_Single_3, + ["LoadAndInsertScalar.Vector128.UInt16.7"] = LoadAndInsertScalar_Vector128_UInt16_7, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part6.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part6.cs index a25972164028..87943f475dad 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part6.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part6.cs @@ -11,96 +11,106 @@ public static partial class Program static Program() { TestList = new Dictionary() { - ["SubtractRoundedHighNarrowingLower.Vector64.Int32"] = SubtractRoundedHighNarrowingLower_Vector64_Int32, - ["SubtractRoundedHighNarrowingLower.Vector64.SByte"] = SubtractRoundedHighNarrowingLower_Vector64_SByte, - ["SubtractRoundedHighNarrowingLower.Vector64.UInt16"] = SubtractRoundedHighNarrowingLower_Vector64_UInt16, - ["SubtractRoundedHighNarrowingLower.Vector64.UInt32"] = SubtractRoundedHighNarrowingLower_Vector64_UInt32, - ["SubtractRoundedHighNarrowingUpper.Vector128.Byte"] = SubtractRoundedHighNarrowingUpper_Vector128_Byte, - ["SubtractRoundedHighNarrowingUpper.Vector128.Int16"] = SubtractRoundedHighNarrowingUpper_Vector128_Int16, - ["SubtractRoundedHighNarrowingUpper.Vector128.Int32"] = SubtractRoundedHighNarrowingUpper_Vector128_Int32, - ["SubtractRoundedHighNarrowingUpper.Vector128.SByte"] = SubtractRoundedHighNarrowingUpper_Vector128_SByte, - ["SubtractRoundedHighNarrowingUpper.Vector128.UInt16"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt16, - ["SubtractRoundedHighNarrowingUpper.Vector128.UInt32"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt32, - ["SubtractSaturate.Vector64.Byte"] = SubtractSaturate_Vector64_Byte, - ["SubtractSaturate.Vector64.Int16"] = SubtractSaturate_Vector64_Int16, - ["SubtractSaturate.Vector64.Int32"] = SubtractSaturate_Vector64_Int32, - ["SubtractSaturate.Vector64.SByte"] = SubtractSaturate_Vector64_SByte, - ["SubtractSaturate.Vector64.UInt16"] = SubtractSaturate_Vector64_UInt16, - ["SubtractSaturate.Vector64.UInt32"] = SubtractSaturate_Vector64_UInt32, - ["SubtractSaturate.Vector128.Byte"] = SubtractSaturate_Vector128_Byte, - ["SubtractSaturate.Vector128.Int16"] = SubtractSaturate_Vector128_Int16, - ["SubtractSaturate.Vector128.Int32"] = SubtractSaturate_Vector128_Int32, - ["SubtractSaturate.Vector128.Int64"] = SubtractSaturate_Vector128_Int64, - ["SubtractSaturate.Vector128.SByte"] = SubtractSaturate_Vector128_SByte, - ["SubtractSaturate.Vector128.UInt16"] = SubtractSaturate_Vector128_UInt16, - ["SubtractSaturate.Vector128.UInt32"] = SubtractSaturate_Vector128_UInt32, - ["SubtractSaturate.Vector128.UInt64"] = SubtractSaturate_Vector128_UInt64, - ["SubtractSaturateScalar.Vector64.Int64"] = SubtractSaturateScalar_Vector64_Int64, - ["SubtractSaturateScalar.Vector64.UInt64"] = SubtractSaturateScalar_Vector64_UInt64, - ["SubtractScalar.Vector64.Double"] = SubtractScalar_Vector64_Double, - ["SubtractScalar.Vector64.Int64"] = SubtractScalar_Vector64_Int64, - ["SubtractScalar.Vector64.Single"] = SubtractScalar_Vector64_Single, - ["SubtractScalar.Vector64.UInt64"] = SubtractScalar_Vector64_UInt64, - ["SubtractWideningLower.Vector64.Byte"] = SubtractWideningLower_Vector64_Byte, - ["SubtractWideningLower.Vector64.Int16"] = SubtractWideningLower_Vector64_Int16, - ["SubtractWideningLower.Vector64.Int32"] = SubtractWideningLower_Vector64_Int32, - ["SubtractWideningLower.Vector64.SByte"] = SubtractWideningLower_Vector64_SByte, - ["SubtractWideningLower.Vector64.UInt16"] = SubtractWideningLower_Vector64_UInt16, - ["SubtractWideningLower.Vector64.UInt32"] = SubtractWideningLower_Vector64_UInt32, - ["SubtractWideningLower.Vector128.Int16"] = SubtractWideningLower_Vector128_Int16, - ["SubtractWideningLower.Vector128.Int32"] = SubtractWideningLower_Vector128_Int32, - ["SubtractWideningLower.Vector128.Int64"] = SubtractWideningLower_Vector128_Int64, - ["SubtractWideningLower.Vector128.UInt16"] = SubtractWideningLower_Vector128_UInt16, - ["SubtractWideningLower.Vector128.UInt32"] = SubtractWideningLower_Vector128_UInt32, - ["SubtractWideningLower.Vector128.UInt64"] = SubtractWideningLower_Vector128_UInt64, - ["SubtractWideningUpper.Vector128.Byte.Vector128.Byte"] = SubtractWideningUpper_Vector128_Byte_Vector128_Byte, - ["SubtractWideningUpper.Vector128.Int16.Vector128.Int16"] = SubtractWideningUpper_Vector128_Int16_Vector128_Int16, - ["SubtractWideningUpper.Vector128.Int16.Vector128.SByte"] = SubtractWideningUpper_Vector128_Int16_Vector128_SByte, - ["SubtractWideningUpper.Vector128.Int32.Vector128.Int16"] = SubtractWideningUpper_Vector128_Int32_Vector128_Int16, - ["SubtractWideningUpper.Vector128.Int32.Vector128.Int32"] = SubtractWideningUpper_Vector128_Int32_Vector128_Int32, - ["SubtractWideningUpper.Vector128.Int64.Vector128.Int32"] = SubtractWideningUpper_Vector128_Int64_Vector128_Int32, - ["SubtractWideningUpper.Vector128.SByte.Vector128.SByte"] = SubtractWideningUpper_Vector128_SByte_Vector128_SByte, - ["SubtractWideningUpper.Vector128.UInt16.Vector128.Byte"] = SubtractWideningUpper_Vector128_UInt16_Vector128_Byte, - ["SubtractWideningUpper.Vector128.UInt16.Vector128.UInt16"] = SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16, - ["SubtractWideningUpper.Vector128.UInt32.Vector128.UInt16"] = SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16, - ["SubtractWideningUpper.Vector128.UInt32.Vector128.UInt32"] = SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32, - ["SubtractWideningUpper.Vector128.UInt64.Vector128.UInt32"] = SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32, - ["VectorTableLookup.Vector64.Byte"] = VectorTableLookup_Vector64_Byte, - ["VectorTableLookup.Vector64.SByte"] = VectorTableLookup_Vector64_SByte, - ["VectorTableLookupExtension.Vector64.Byte"] = VectorTableLookupExtension_Vector64_Byte, - ["VectorTableLookupExtension.Vector64.SByte"] = VectorTableLookupExtension_Vector64_SByte, - ["Xor.Vector64.Byte"] = Xor_Vector64_Byte, - ["Xor.Vector64.Double"] = Xor_Vector64_Double, - ["Xor.Vector64.Int16"] = Xor_Vector64_Int16, - ["Xor.Vector64.Int32"] = Xor_Vector64_Int32, - ["Xor.Vector64.Int64"] = Xor_Vector64_Int64, - ["Xor.Vector64.SByte"] = Xor_Vector64_SByte, - ["Xor.Vector64.Single"] = Xor_Vector64_Single, - ["Xor.Vector64.UInt16"] = Xor_Vector64_UInt16, - ["Xor.Vector64.UInt32"] = Xor_Vector64_UInt32, - ["Xor.Vector64.UInt64"] = Xor_Vector64_UInt64, - ["Xor.Vector128.Byte"] = Xor_Vector128_Byte, - ["Xor.Vector128.Double"] = Xor_Vector128_Double, - ["Xor.Vector128.Int16"] = Xor_Vector128_Int16, - ["Xor.Vector128.Int32"] = Xor_Vector128_Int32, - ["Xor.Vector128.Int64"] = Xor_Vector128_Int64, - ["Xor.Vector128.SByte"] = Xor_Vector128_SByte, - ["Xor.Vector128.Single"] = Xor_Vector128_Single, - ["Xor.Vector128.UInt16"] = Xor_Vector128_UInt16, - ["Xor.Vector128.UInt32"] = Xor_Vector128_UInt32, - ["Xor.Vector128.UInt64"] = Xor_Vector128_UInt64, - ["ZeroExtendWideningLower.Vector64.Byte"] = ZeroExtendWideningLower_Vector64_Byte, - ["ZeroExtendWideningLower.Vector64.Int16"] = ZeroExtendWideningLower_Vector64_Int16, - ["ZeroExtendWideningLower.Vector64.Int32"] = ZeroExtendWideningLower_Vector64_Int32, - ["ZeroExtendWideningLower.Vector64.SByte"] = ZeroExtendWideningLower_Vector64_SByte, - ["ZeroExtendWideningLower.Vector64.UInt16"] = ZeroExtendWideningLower_Vector64_UInt16, - ["ZeroExtendWideningLower.Vector64.UInt32"] = ZeroExtendWideningLower_Vector64_UInt32, - ["ZeroExtendWideningUpper.Vector128.Byte"] = ZeroExtendWideningUpper_Vector128_Byte, - ["ZeroExtendWideningUpper.Vector128.Int16"] = ZeroExtendWideningUpper_Vector128_Int16, - ["ZeroExtendWideningUpper.Vector128.Int32"] = ZeroExtendWideningUpper_Vector128_Int32, - ["ZeroExtendWideningUpper.Vector128.SByte"] = ZeroExtendWideningUpper_Vector128_SByte, - ["ZeroExtendWideningUpper.Vector128.UInt16"] = ZeroExtendWideningUpper_Vector128_UInt16, - ["ZeroExtendWideningUpper.Vector128.UInt32"] = ZeroExtendWideningUpper_Vector128_UInt32, + ["LoadAndInsertScalar.Vector128.UInt32.3"] = LoadAndInsertScalar_Vector128_UInt32_3, + ["LoadAndInsertScalar.Vector128.UInt64.1"] = LoadAndInsertScalar_Vector128_UInt64_1, + ["LoadAndReplicateToVector64.Byte"] = LoadAndReplicateToVector64_Byte, + ["LoadAndReplicateToVector64.Int16"] = LoadAndReplicateToVector64_Int16, + ["LoadAndReplicateToVector64.Int32"] = LoadAndReplicateToVector64_Int32, + ["LoadAndReplicateToVector64.SByte"] = LoadAndReplicateToVector64_SByte, + ["LoadAndReplicateToVector64.Single"] = LoadAndReplicateToVector64_Single, + ["LoadAndReplicateToVector64.UInt16"] = LoadAndReplicateToVector64_UInt16, + ["LoadAndReplicateToVector64.UInt32"] = LoadAndReplicateToVector64_UInt32, + ["LoadAndReplicateToVector128.Byte"] = LoadAndReplicateToVector128_Byte, + ["LoadAndReplicateToVector128.Int16"] = LoadAndReplicateToVector128_Int16, + ["LoadAndReplicateToVector128.Int32"] = LoadAndReplicateToVector128_Int32, + ["LoadAndReplicateToVector128.SByte"] = LoadAndReplicateToVector128_SByte, + ["LoadAndReplicateToVector128.Single"] = LoadAndReplicateToVector128_Single, + ["LoadAndReplicateToVector128.UInt16"] = LoadAndReplicateToVector128_UInt16, + ["LoadAndReplicateToVector128.UInt32"] = LoadAndReplicateToVector128_UInt32, + ["LoadVector64.Byte"] = LoadVector64_Byte, + ["LoadVector64.Double"] = LoadVector64_Double, + ["LoadVector64.Int16"] = LoadVector64_Int16, + ["LoadVector64.Int32"] = LoadVector64_Int32, + ["LoadVector64.Int64"] = LoadVector64_Int64, + ["LoadVector64.SByte"] = LoadVector64_SByte, + ["LoadVector64.Single"] = LoadVector64_Single, + ["LoadVector64.UInt16"] = LoadVector64_UInt16, + ["LoadVector64.UInt32"] = LoadVector64_UInt32, + ["LoadVector64.UInt64"] = LoadVector64_UInt64, + ["LoadVector128.Byte"] = LoadVector128_Byte, + ["LoadVector128.Double"] = LoadVector128_Double, + ["LoadVector128.Int16"] = LoadVector128_Int16, + ["LoadVector128.Int32"] = LoadVector128_Int32, + ["LoadVector128.Int64"] = LoadVector128_Int64, + ["LoadVector128.SByte"] = LoadVector128_SByte, + ["LoadVector128.Single"] = LoadVector128_Single, + ["LoadVector128.UInt16"] = LoadVector128_UInt16, + ["LoadVector128.UInt32"] = LoadVector128_UInt32, + ["LoadVector128.UInt64"] = LoadVector128_UInt64, + ["Max.Vector64.Byte"] = Max_Vector64_Byte, + ["Max.Vector64.Int16"] = Max_Vector64_Int16, + ["Max.Vector64.Int32"] = Max_Vector64_Int32, + ["Max.Vector64.SByte"] = Max_Vector64_SByte, + ["Max.Vector64.Single"] = Max_Vector64_Single, + ["Max.Vector64.UInt16"] = Max_Vector64_UInt16, + ["Max.Vector64.UInt32"] = Max_Vector64_UInt32, + ["Max.Vector128.Byte"] = Max_Vector128_Byte, + ["Max.Vector128.Int16"] = Max_Vector128_Int16, + ["Max.Vector128.Int32"] = Max_Vector128_Int32, + ["Max.Vector128.SByte"] = Max_Vector128_SByte, + ["Max.Vector128.Single"] = Max_Vector128_Single, + ["Max.Vector128.UInt16"] = Max_Vector128_UInt16, + ["Max.Vector128.UInt32"] = Max_Vector128_UInt32, + ["MaxNumber.Vector64.Single"] = MaxNumber_Vector64_Single, + ["MaxNumber.Vector128.Single"] = MaxNumber_Vector128_Single, + ["MaxNumberScalar.Vector64.Double"] = MaxNumberScalar_Vector64_Double, + ["MaxNumberScalar.Vector64.Single"] = MaxNumberScalar_Vector64_Single, + ["MaxPairwise.Vector64.Byte"] = MaxPairwise_Vector64_Byte, + ["MaxPairwise.Vector64.Int16"] = MaxPairwise_Vector64_Int16, + ["MaxPairwise.Vector64.Int32"] = MaxPairwise_Vector64_Int32, + ["MaxPairwise.Vector64.SByte"] = MaxPairwise_Vector64_SByte, + ["MaxPairwise.Vector64.Single"] = MaxPairwise_Vector64_Single, + ["MaxPairwise.Vector64.UInt16"] = MaxPairwise_Vector64_UInt16, + ["MaxPairwise.Vector64.UInt32"] = MaxPairwise_Vector64_UInt32, + ["Min.Vector64.Byte"] = Min_Vector64_Byte, + ["Min.Vector64.Int16"] = Min_Vector64_Int16, + ["Min.Vector64.Int32"] = Min_Vector64_Int32, + ["Min.Vector64.SByte"] = Min_Vector64_SByte, + ["Min.Vector64.Single"] = Min_Vector64_Single, + ["Min.Vector64.UInt16"] = Min_Vector64_UInt16, + ["Min.Vector64.UInt32"] = Min_Vector64_UInt32, + ["Min.Vector128.Byte"] = Min_Vector128_Byte, + ["Min.Vector128.Int16"] = Min_Vector128_Int16, + ["Min.Vector128.Int32"] = Min_Vector128_Int32, + ["Min.Vector128.SByte"] = Min_Vector128_SByte, + ["Min.Vector128.Single"] = Min_Vector128_Single, + ["Min.Vector128.UInt16"] = Min_Vector128_UInt16, + ["Min.Vector128.UInt32"] = Min_Vector128_UInt32, + ["MinNumber.Vector64.Single"] = MinNumber_Vector64_Single, + ["MinNumber.Vector128.Single"] = MinNumber_Vector128_Single, + ["MinNumberScalar.Vector64.Double"] = MinNumberScalar_Vector64_Double, + ["MinNumberScalar.Vector64.Single"] = MinNumberScalar_Vector64_Single, + ["MinPairwise.Vector64.Byte"] = MinPairwise_Vector64_Byte, + ["MinPairwise.Vector64.Int16"] = MinPairwise_Vector64_Int16, + ["MinPairwise.Vector64.Int32"] = MinPairwise_Vector64_Int32, + ["MinPairwise.Vector64.SByte"] = MinPairwise_Vector64_SByte, + ["MinPairwise.Vector64.Single"] = MinPairwise_Vector64_Single, + ["MinPairwise.Vector64.UInt16"] = MinPairwise_Vector64_UInt16, + ["MinPairwise.Vector64.UInt32"] = MinPairwise_Vector64_UInt32, + ["Multiply.Vector64.Byte"] = Multiply_Vector64_Byte, + ["Multiply.Vector64.Int16"] = Multiply_Vector64_Int16, + ["Multiply.Vector64.Int32"] = Multiply_Vector64_Int32, + ["Multiply.Vector64.SByte"] = Multiply_Vector64_SByte, + ["Multiply.Vector64.Single"] = Multiply_Vector64_Single, + ["Multiply.Vector64.UInt16"] = Multiply_Vector64_UInt16, + ["Multiply.Vector64.UInt32"] = Multiply_Vector64_UInt32, + ["Multiply.Vector128.Byte"] = Multiply_Vector128_Byte, + ["Multiply.Vector128.Int16"] = Multiply_Vector128_Int16, + ["Multiply.Vector128.Int32"] = Multiply_Vector128_Int32, + ["Multiply.Vector128.SByte"] = Multiply_Vector128_SByte, + ["Multiply.Vector128.Single"] = Multiply_Vector128_Single, + ["Multiply.Vector128.UInt16"] = Multiply_Vector128_UInt16, + ["Multiply.Vector128.UInt32"] = Multiply_Vector128_UInt32, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part7.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part7.cs new file mode 100644 index 000000000000..3debb286fb93 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part7.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["MultiplyScalar.Vector64.Double"] = MultiplyScalar_Vector64_Double, + ["MultiplyScalar.Vector64.Single"] = MultiplyScalar_Vector64_Single, + ["MultiplyAdd.Vector64.Byte"] = MultiplyAdd_Vector64_Byte, + ["MultiplyAdd.Vector64.Int16"] = MultiplyAdd_Vector64_Int16, + ["MultiplyAdd.Vector64.Int32"] = MultiplyAdd_Vector64_Int32, + ["MultiplyAdd.Vector64.SByte"] = MultiplyAdd_Vector64_SByte, + ["MultiplyAdd.Vector64.UInt16"] = MultiplyAdd_Vector64_UInt16, + ["MultiplyAdd.Vector64.UInt32"] = MultiplyAdd_Vector64_UInt32, + ["MultiplyAdd.Vector128.Byte"] = MultiplyAdd_Vector128_Byte, + ["MultiplyAdd.Vector128.Int16"] = MultiplyAdd_Vector128_Int16, + ["MultiplyAdd.Vector128.Int32"] = MultiplyAdd_Vector128_Int32, + ["MultiplyAdd.Vector128.SByte"] = MultiplyAdd_Vector128_SByte, + ["MultiplyAdd.Vector128.UInt16"] = MultiplyAdd_Vector128_UInt16, + ["MultiplyAdd.Vector128.UInt32"] = MultiplyAdd_Vector128_UInt32, + ["MultiplyAddByScalar.Vector64.Int16"] = MultiplyAddByScalar_Vector64_Int16, + ["MultiplyAddByScalar.Vector64.Int32"] = MultiplyAddByScalar_Vector64_Int32, + ["MultiplyAddByScalar.Vector64.UInt16"] = MultiplyAddByScalar_Vector64_UInt16, + ["MultiplyAddByScalar.Vector64.UInt32"] = MultiplyAddByScalar_Vector64_UInt32, + ["MultiplyAddByScalar.Vector128.Int16"] = MultiplyAddByScalar_Vector128_Int16, + ["MultiplyAddByScalar.Vector128.Int32"] = MultiplyAddByScalar_Vector128_Int32, + ["MultiplyAddByScalar.Vector128.UInt16"] = MultiplyAddByScalar_Vector128_UInt16, + ["MultiplyAddByScalar.Vector128.UInt32"] = MultiplyAddByScalar_Vector128_UInt32, + ["MultiplyAddBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyAddBySelectedScalar_Vector64_Int16_Vector64_Int16_3, + ["MultiplyAddBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyAddBySelectedScalar_Vector64_Int16_Vector128_Int16_7, + ["MultiplyAddBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyAddBySelectedScalar_Vector64_Int32_Vector64_Int32_1, + ["MultiplyAddBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyAddBySelectedScalar_Vector64_Int32_Vector128_Int32_3, + ["MultiplyAddBySelectedScalar.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyAddBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3, + ["MultiplyAddBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyAddBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplyAddBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyAddBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplyAddBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyAddBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplyAddBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplyAddBySelectedScalar_Vector128_Int16_Vector64_Int16_3, + ["MultiplyAddBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyAddBySelectedScalar_Vector128_Int16_Vector128_Int16_7, + ["MultiplyAddBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyAddBySelectedScalar_Vector128_Int32_Vector64_Int32_1, + ["MultiplyAddBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyAddBySelectedScalar_Vector128_Int32_Vector128_Int32_3, + ["MultiplyAddBySelectedScalar.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyAddBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3, + ["MultiplyAddBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyAddBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplyAddBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyAddBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplyAddBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyAddBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, + ["MultiplyByScalar.Vector64.Int16"] = MultiplyByScalar_Vector64_Int16, + ["MultiplyByScalar.Vector64.Int32"] = MultiplyByScalar_Vector64_Int32, + ["MultiplyByScalar.Vector64.Single"] = MultiplyByScalar_Vector64_Single, + ["MultiplyByScalar.Vector64.UInt16"] = MultiplyByScalar_Vector64_UInt16, + ["MultiplyByScalar.Vector64.UInt32"] = MultiplyByScalar_Vector64_UInt32, + ["MultiplyByScalar.Vector128.Int16"] = MultiplyByScalar_Vector128_Int16, + ["MultiplyByScalar.Vector128.Int32"] = MultiplyByScalar_Vector128_Int32, + ["MultiplyByScalar.Vector128.Single"] = MultiplyByScalar_Vector128_Single, + ["MultiplyByScalar.Vector128.UInt16"] = MultiplyByScalar_Vector128_UInt16, + ["MultiplyByScalar.Vector128.UInt32"] = MultiplyByScalar_Vector128_UInt32, + ["MultiplyBySelectedScalar.Vector64.Int16.Vector64.Int16.1"] = MultiplyBySelectedScalar_Vector64_Int16_Vector64_Int16_1, + ["MultiplyBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalar_Vector64_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalar_Vector64_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalar_Vector64_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["MultiplyBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["MultiplyBySelectedScalar.Vector64.UInt16.Vector64.UInt16.1"] = MultiplyBySelectedScalar_Vector64_UInt16_Vector64_UInt16_1, + ["MultiplyBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalar.Vector128.Int16.Vector64.Int16.1"] = MultiplyBySelectedScalar_Vector128_Int16_Vector64_Int16_1, + ["MultiplyBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalar_Vector128_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalar_Vector128_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalar_Vector128_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalar.Vector128.Single.Vector64.Single.1"] = MultiplyBySelectedScalar_Vector128_Single_Vector64_Single_1, + ["MultiplyBySelectedScalar.Vector128.Single.Vector128.Single.3"] = MultiplyBySelectedScalar_Vector128_Single_Vector128_Single_3, + ["MultiplyBySelectedScalar.Vector128.UInt16.Vector64.UInt16.1"] = MultiplyBySelectedScalar_Vector128_UInt16_Vector64_UInt16_1, + ["MultiplyBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalarWideningLower.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningLower.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningLower.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningLower.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningLower.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningLower.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningLower.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningLower.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningLowerAndAdd.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningLowerAndSubtract.Vector64.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalarWideningUpper.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningUpper.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningUpper.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningUpper.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningUpper.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector128_UInt32_3, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part8.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part8.cs new file mode 100644 index 000000000000..84670aead920 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part8.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningUpperAndAdd.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector128_UInt32_3, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int16.Vector64.Int16.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector64_Int16_3, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int16.Vector128.Int16.7"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector128_Int16_7, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int32.Vector64.Int32.1"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector64_Int32_1, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.Int32.Vector128.Int32.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector128_Int32_3, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt16.Vector64.UInt16.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector64_UInt16_3, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt16.Vector128.UInt16.7"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt32.Vector64.UInt32.1"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplyBySelectedScalarWideningUpperAndSubtract.Vector128.UInt32.Vector128.UInt32.3"] = MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector128_UInt32_3, + ["MultiplyDoublingByScalarSaturateHigh.Vector64.Int16"] = MultiplyDoublingByScalarSaturateHigh_Vector64_Int16, + ["MultiplyDoublingByScalarSaturateHigh.Vector64.Int32"] = MultiplyDoublingByScalarSaturateHigh_Vector64_Int32, + ["MultiplyDoublingByScalarSaturateHigh.Vector128.Int16"] = MultiplyDoublingByScalarSaturateHigh_Vector128_Int16, + ["MultiplyDoublingByScalarSaturateHigh.Vector128.Int32"] = MultiplyDoublingByScalarSaturateHigh_Vector128_Int32, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_3, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1, + ["MultiplyDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3, + ["MultiplyDoublingSaturateHigh.Vector64.Int16"] = MultiplyDoublingSaturateHigh_Vector64_Int16, + ["MultiplyDoublingSaturateHigh.Vector64.Int32"] = MultiplyDoublingSaturateHigh_Vector64_Int32, + ["MultiplyDoublingSaturateHigh.Vector128.Int16"] = MultiplyDoublingSaturateHigh_Vector128_Int16, + ["MultiplyDoublingSaturateHigh.Vector128.Int32"] = MultiplyDoublingSaturateHigh_Vector128_Int32, + ["MultiplyDoublingWideningLowerAndAddSaturate.Vector64.Int16"] = MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int16, + ["MultiplyDoublingWideningLowerAndAddSaturate.Vector64.Int32"] = MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int32, + ["MultiplyDoublingWideningLowerAndSubtractSaturate.Vector64.Int16"] = MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int16, + ["MultiplyDoublingWideningLowerAndSubtractSaturate.Vector64.Int32"] = MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int32, + ["MultiplyDoublingWideningLowerByScalarAndAddSaturate.Vector64.Int16.Vector64.Int16"] = MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int16_Vector64_Int16, + ["MultiplyDoublingWideningLowerByScalarAndAddSaturate.Vector64.Int32.Vector64.Int32"] = MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int32_Vector64_Int32, + ["MultiplyDoublingWideningLowerByScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16"] = MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16, + ["MultiplyDoublingWideningLowerByScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32"] = MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32, + ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningSaturateLower.Vector64.Int16"] = MultiplyDoublingWideningSaturateLower_Vector64_Int16, + ["MultiplyDoublingWideningSaturateLower.Vector64.Int32"] = MultiplyDoublingWideningSaturateLower_Vector64_Int32, + ["MultiplyDoublingWideningSaturateLowerByScalar.Vector64.Int16"] = MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int16, + ["MultiplyDoublingWideningSaturateLowerByScalar.Vector64.Int32"] = MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int32, + ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningSaturateLowerBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningSaturateUpper.Vector128.Int16"] = MultiplyDoublingWideningSaturateUpper_Vector128_Int16, + ["MultiplyDoublingWideningSaturateUpper.Vector128.Int32"] = MultiplyDoublingWideningSaturateUpper_Vector128_Int32, + ["MultiplyDoublingWideningSaturateUpperByScalar.Vector128.Int16"] = MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int16, + ["MultiplyDoublingWideningSaturateUpperByScalar.Vector128.Int32"] = MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int32, + ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningSaturateUpperBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningUpperAndAddSaturate.Vector128.Int16"] = MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int16, + ["MultiplyDoublingWideningUpperAndAddSaturate.Vector128.Int32"] = MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int32, + ["MultiplyDoublingWideningUpperAndSubtractSaturate.Vector128.Int16"] = MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int16, + ["MultiplyDoublingWideningUpperAndSubtractSaturate.Vector128.Int32"] = MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int32, + ["MultiplyDoublingWideningUpperByScalarAndAddSaturate.Vector128.Int16.Vector64.Int16"] = MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int16_Vector64_Int16, + ["MultiplyDoublingWideningUpperByScalarAndAddSaturate.Vector128.Int32.Vector64.Int32"] = MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int32_Vector64_Int32, + ["MultiplyDoublingWideningUpperByScalarAndSubtractSaturate.Vector128.Int16.Vector64.Int16"] = MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16, + ["MultiplyDoublingWideningUpperByScalarAndSubtractSaturate.Vector128.Int32.Vector64.Int32"] = MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32, + ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector128_Int32_3, + ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int16.Vector64.Int16.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16_3, + ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int16.Vector128.Int16.7"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector128_Int16_7, + ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int32.Vector64.Int32.1"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32_1, + ["MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate.Vector128.Int32.Vector128.Int32.3"] = MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector128_Int32_3, + ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector64.Int16"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int16, + ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector64.Int32"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int32, + ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector128.Int16"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int16, + ["MultiplyRoundedDoublingByScalarSaturateHigh.Vector128.Int32"] = MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int32, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector64.Int16.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector64.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector64.Int16.2"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_2, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int16.Vector128.Int16.7"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector64.Int32.1"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1, + ["MultiplyRoundedDoublingBySelectedScalarSaturateHigh.Vector128.Int32.Vector128.Int32.3"] = MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3, + ["MultiplyRoundedDoublingSaturateHigh.Vector64.Int16"] = MultiplyRoundedDoublingSaturateHigh_Vector64_Int16, + ["MultiplyRoundedDoublingSaturateHigh.Vector64.Int32"] = MultiplyRoundedDoublingSaturateHigh_Vector64_Int32, + ["MultiplyRoundedDoublingSaturateHigh.Vector128.Int16"] = MultiplyRoundedDoublingSaturateHigh_Vector128_Int16, + ["MultiplyRoundedDoublingSaturateHigh.Vector128.Int32"] = MultiplyRoundedDoublingSaturateHigh_Vector128_Int32, + ["MultiplyScalarBySelectedScalar.Vector64.Single.Vector64.Single.1"] = MultiplyScalarBySelectedScalar_Vector64_Single_Vector64_Single_1, + ["MultiplyScalarBySelectedScalar.Vector64.Single.Vector128.Single.3"] = MultiplyScalarBySelectedScalar_Vector64_Single_Vector128_Single_3, + ["MultiplySubtract.Vector64.Byte"] = MultiplySubtract_Vector64_Byte, + ["MultiplySubtract.Vector64.Int16"] = MultiplySubtract_Vector64_Int16, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part9.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part9.cs new file mode 100644 index 000000000000..ac57e2481a56 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd_Part9.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["MultiplySubtract.Vector64.Int32"] = MultiplySubtract_Vector64_Int32, + ["MultiplySubtract.Vector64.SByte"] = MultiplySubtract_Vector64_SByte, + ["MultiplySubtract.Vector64.UInt16"] = MultiplySubtract_Vector64_UInt16, + ["MultiplySubtract.Vector64.UInt32"] = MultiplySubtract_Vector64_UInt32, + ["MultiplySubtract.Vector128.Byte"] = MultiplySubtract_Vector128_Byte, + ["MultiplySubtract.Vector128.Int16"] = MultiplySubtract_Vector128_Int16, + ["MultiplySubtract.Vector128.Int32"] = MultiplySubtract_Vector128_Int32, + ["MultiplySubtract.Vector128.SByte"] = MultiplySubtract_Vector128_SByte, + ["MultiplySubtract.Vector128.UInt16"] = MultiplySubtract_Vector128_UInt16, + ["MultiplySubtract.Vector128.UInt32"] = MultiplySubtract_Vector128_UInt32, + ["MultiplySubtractBySelectedScalar.Vector64.Int16.Vector64.Int16.3"] = MultiplySubtractBySelectedScalar_Vector64_Int16_Vector64_Int16_3, + ["MultiplySubtractBySelectedScalar.Vector64.Int16.Vector128.Int16.7"] = MultiplySubtractBySelectedScalar_Vector64_Int16_Vector128_Int16_7, + ["MultiplySubtractBySelectedScalar.Vector64.Int32.Vector64.Int32.1"] = MultiplySubtractBySelectedScalar_Vector64_Int32_Vector64_Int32_1, + ["MultiplySubtractBySelectedScalar.Vector64.Int32.Vector128.Int32.3"] = MultiplySubtractBySelectedScalar_Vector64_Int32_Vector128_Int32_3, + ["MultiplySubtractBySelectedScalar.Vector64.UInt16.Vector64.UInt16.3"] = MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3, + ["MultiplySubtractBySelectedScalar.Vector64.UInt16.Vector128.UInt16.7"] = MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7, + ["MultiplySubtractBySelectedScalar.Vector64.UInt32.Vector64.UInt32.1"] = MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1, + ["MultiplySubtractBySelectedScalar.Vector64.UInt32.Vector128.UInt32.3"] = MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3, + ["MultiplySubtractBySelectedScalar.Vector128.Int16.Vector64.Int16.3"] = MultiplySubtractBySelectedScalar_Vector128_Int16_Vector64_Int16_3, + ["MultiplySubtractBySelectedScalar.Vector128.Int16.Vector128.Int16.7"] = MultiplySubtractBySelectedScalar_Vector128_Int16_Vector128_Int16_7, + ["MultiplySubtractBySelectedScalar.Vector128.Int32.Vector64.Int32.1"] = MultiplySubtractBySelectedScalar_Vector128_Int32_Vector64_Int32_1, + ["MultiplySubtractBySelectedScalar.Vector128.Int32.Vector128.Int32.3"] = MultiplySubtractBySelectedScalar_Vector128_Int32_Vector128_Int32_3, + ["MultiplySubtractBySelectedScalar.Vector128.UInt16.Vector64.UInt16.3"] = MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3, + ["MultiplySubtractBySelectedScalar.Vector128.UInt16.Vector128.UInt16.7"] = MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7, + ["MultiplySubtractBySelectedScalar.Vector128.UInt32.Vector64.UInt32.1"] = MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1, + ["MultiplySubtractBySelectedScalar.Vector128.UInt32.Vector128.UInt32.3"] = MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3, + ["MultiplySubtractByScalar.Vector64.Int16"] = MultiplySubtractByScalar_Vector64_Int16, + ["MultiplySubtractByScalar.Vector64.Int32"] = MultiplySubtractByScalar_Vector64_Int32, + ["MultiplySubtractByScalar.Vector64.UInt16"] = MultiplySubtractByScalar_Vector64_UInt16, + ["MultiplySubtractByScalar.Vector64.UInt32"] = MultiplySubtractByScalar_Vector64_UInt32, + ["MultiplySubtractByScalar.Vector128.Int16"] = MultiplySubtractByScalar_Vector128_Int16, + ["MultiplySubtractByScalar.Vector128.Int32"] = MultiplySubtractByScalar_Vector128_Int32, + ["MultiplySubtractByScalar.Vector128.UInt16"] = MultiplySubtractByScalar_Vector128_UInt16, + ["MultiplySubtractByScalar.Vector128.UInt32"] = MultiplySubtractByScalar_Vector128_UInt32, + ["MultiplyWideningLower.Vector64.Byte"] = MultiplyWideningLower_Vector64_Byte, + ["MultiplyWideningLower.Vector64.Int16"] = MultiplyWideningLower_Vector64_Int16, + ["MultiplyWideningLower.Vector64.Int32"] = MultiplyWideningLower_Vector64_Int32, + ["MultiplyWideningLower.Vector64.SByte"] = MultiplyWideningLower_Vector64_SByte, + ["MultiplyWideningLower.Vector64.UInt16"] = MultiplyWideningLower_Vector64_UInt16, + ["MultiplyWideningLower.Vector64.UInt32"] = MultiplyWideningLower_Vector64_UInt32, + ["MultiplyWideningLowerAndAdd.Vector64.Byte"] = MultiplyWideningLowerAndAdd_Vector64_Byte, + ["MultiplyWideningLowerAndAdd.Vector64.Int16"] = MultiplyWideningLowerAndAdd_Vector64_Int16, + ["MultiplyWideningLowerAndAdd.Vector64.Int32"] = MultiplyWideningLowerAndAdd_Vector64_Int32, + ["MultiplyWideningLowerAndAdd.Vector64.SByte"] = MultiplyWideningLowerAndAdd_Vector64_SByte, + ["MultiplyWideningLowerAndAdd.Vector64.UInt16"] = MultiplyWideningLowerAndAdd_Vector64_UInt16, + ["MultiplyWideningLowerAndAdd.Vector64.UInt32"] = MultiplyWideningLowerAndAdd_Vector64_UInt32, + ["MultiplyWideningLowerAndSubtract.Vector64.Byte"] = MultiplyWideningLowerAndSubtract_Vector64_Byte, + ["MultiplyWideningLowerAndSubtract.Vector64.Int16"] = MultiplyWideningLowerAndSubtract_Vector64_Int16, + ["MultiplyWideningLowerAndSubtract.Vector64.Int32"] = MultiplyWideningLowerAndSubtract_Vector64_Int32, + ["MultiplyWideningLowerAndSubtract.Vector64.SByte"] = MultiplyWideningLowerAndSubtract_Vector64_SByte, + ["MultiplyWideningLowerAndSubtract.Vector64.UInt16"] = MultiplyWideningLowerAndSubtract_Vector64_UInt16, + ["MultiplyWideningLowerAndSubtract.Vector64.UInt32"] = MultiplyWideningLowerAndSubtract_Vector64_UInt32, + ["MultiplyWideningUpper.Vector128.Byte"] = MultiplyWideningUpper_Vector128_Byte, + ["MultiplyWideningUpper.Vector128.Int16"] = MultiplyWideningUpper_Vector128_Int16, + ["MultiplyWideningUpper.Vector128.Int32"] = MultiplyWideningUpper_Vector128_Int32, + ["MultiplyWideningUpper.Vector128.SByte"] = MultiplyWideningUpper_Vector128_SByte, + ["MultiplyWideningUpper.Vector128.UInt16"] = MultiplyWideningUpper_Vector128_UInt16, + ["MultiplyWideningUpper.Vector128.UInt32"] = MultiplyWideningUpper_Vector128_UInt32, + ["MultiplyWideningUpperAndAdd.Vector128.Byte"] = MultiplyWideningUpperAndAdd_Vector128_Byte, + ["MultiplyWideningUpperAndAdd.Vector128.Int16"] = MultiplyWideningUpperAndAdd_Vector128_Int16, + ["MultiplyWideningUpperAndAdd.Vector128.Int32"] = MultiplyWideningUpperAndAdd_Vector128_Int32, + ["MultiplyWideningUpperAndAdd.Vector128.SByte"] = MultiplyWideningUpperAndAdd_Vector128_SByte, + ["MultiplyWideningUpperAndAdd.Vector128.UInt16"] = MultiplyWideningUpperAndAdd_Vector128_UInt16, + ["MultiplyWideningUpperAndAdd.Vector128.UInt32"] = MultiplyWideningUpperAndAdd_Vector128_UInt32, + ["MultiplyWideningUpperAndSubtract.Vector128.Byte"] = MultiplyWideningUpperAndSubtract_Vector128_Byte, + ["MultiplyWideningUpperAndSubtract.Vector128.Int16"] = MultiplyWideningUpperAndSubtract_Vector128_Int16, + ["MultiplyWideningUpperAndSubtract.Vector128.Int32"] = MultiplyWideningUpperAndSubtract_Vector128_Int32, + ["MultiplyWideningUpperAndSubtract.Vector128.SByte"] = MultiplyWideningUpperAndSubtract_Vector128_SByte, + ["MultiplyWideningUpperAndSubtract.Vector128.UInt16"] = MultiplyWideningUpperAndSubtract_Vector128_UInt16, + ["MultiplyWideningUpperAndSubtract.Vector128.UInt32"] = MultiplyWideningUpperAndSubtract_Vector128_UInt32, + ["Negate.Vector64.Int16"] = Negate_Vector64_Int16, + ["Negate.Vector64.Int32"] = Negate_Vector64_Int32, + ["Negate.Vector64.SByte"] = Negate_Vector64_SByte, + ["Negate.Vector64.Single"] = Negate_Vector64_Single, + ["Negate.Vector128.Int16"] = Negate_Vector128_Int16, + ["Negate.Vector128.Int32"] = Negate_Vector128_Int32, + ["Negate.Vector128.SByte"] = Negate_Vector128_SByte, + ["Negate.Vector128.Single"] = Negate_Vector128_Single, + ["NegateSaturate.Vector64.Int16"] = NegateSaturate_Vector64_Int16, + ["NegateSaturate.Vector64.Int32"] = NegateSaturate_Vector64_Int32, + ["NegateSaturate.Vector64.SByte"] = NegateSaturate_Vector64_SByte, + ["NegateSaturate.Vector128.Int16"] = NegateSaturate_Vector128_Int16, + ["NegateSaturate.Vector128.Int32"] = NegateSaturate_Vector128_Int32, + ["NegateSaturate.Vector128.SByte"] = NegateSaturate_Vector128_SByte, + ["NegateScalar.Vector64.Double"] = NegateScalar_Vector64_Double, + ["NegateScalar.Vector64.Single"] = NegateScalar_Vector64_Single, + ["Not.Vector64.Byte"] = Not_Vector64_Byte, + ["Not.Vector64.Double"] = Not_Vector64_Double, + ["Not.Vector64.Int16"] = Not_Vector64_Int16, + ["Not.Vector64.Int32"] = Not_Vector64_Int32, + ["Not.Vector64.Int64"] = Not_Vector64_Int64, + ["Not.Vector64.SByte"] = Not_Vector64_SByte, + ["Not.Vector64.Single"] = Not_Vector64_Single, + ["Not.Vector64.UInt16"] = Not_Vector64_UInt16, + ["Not.Vector64.UInt32"] = Not_Vector64_UInt32, + ["Not.Vector64.UInt64"] = Not_Vector64_UInt64, + ["Not.Vector128.Byte"] = Not_Vector128_Byte, + ["Not.Vector128.Double"] = Not_Vector128_Double, + ["Not.Vector128.Int16"] = Not_Vector128_Int16, + ["Not.Vector128.Int32"] = Not_Vector128_Int32, + }; + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index 21a9c7d8b905..e20d87414c25 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -2456,7 +2456,7 @@ private static readonly (string templateFileName, Dictionary tem private static void ProcessInputs(string groupName, (string templateFileName, Dictionary templateData)[] inputs) { // Too many tests may time out in CI or various stress modes - const int MaxGroupSize = 256; + const int MaxGroupSize = 100; var numGroups = (inputs.Length + (MaxGroupSize - 1)) / MaxGroupSize; From 495e929a8d0957fde4d85945db9a35822679734e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 10 Aug 2020 11:20:34 -0700 Subject: [PATCH 367/755] Fixing an issue with the CPUID check for BMI1/BMI2 (#40615) --- src/coreclr/src/vm/codeman.cpp | 39 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 8b8070bdf2d5..3f48cb00db59 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1353,56 +1353,61 @@ void EEJitManager::SetCpuInfo() int cpuidInfo[4]; + const int EAX = 0; + const int EBX = 1; + const int ECX = 2; + const int EDX = 3; + __cpuid(cpuidInfo, 0x00000000); - uint32_t maxCpuId = static_cast(cpuidInfo[0]); + uint32_t maxCpuId = static_cast(cpuidInfo[EAX]); if (maxCpuId >= 1) { __cpuid(cpuidInfo, 0x00000001); - if (((cpuidInfo[3] & (1 << 25)) != 0) && ((cpuidInfo[3] & (1 << 26)) != 0)) // SSE & SSE2 + if (((cpuidInfo[EDX] & (1 << 25)) != 0) && ((cpuidInfo[EDX] & (1 << 26)) != 0)) // SSE & SSE2 { CPUCompileFlags.Set(InstructionSet_SSE); CPUCompileFlags.Set(InstructionSet_SSE2); - if ((cpuidInfo[2] & (1 << 25)) != 0) // AESNI + if ((cpuidInfo[ECX] & (1 << 25)) != 0) // AESNI { CPUCompileFlags.Set(InstructionSet_AES); } - if ((cpuidInfo[2] & (1 << 1)) != 0) // PCLMULQDQ + if ((cpuidInfo[ECX] & (1 << 1)) != 0) // PCLMULQDQ { CPUCompileFlags.Set(InstructionSet_PCLMULQDQ); } - if ((cpuidInfo[2] & (1 << 0)) != 0) // SSE3 + if ((cpuidInfo[ECX] & (1 << 0)) != 0) // SSE3 { CPUCompileFlags.Set(InstructionSet_SSE3); - if ((cpuidInfo[2] & (1 << 9)) != 0) // SSSE3 + if ((cpuidInfo[ECX] & (1 << 9)) != 0) // SSSE3 { CPUCompileFlags.Set(InstructionSet_SSSE3); - if ((cpuidInfo[2] & (1 << 19)) != 0) // SSE4.1 + if ((cpuidInfo[ECX] & (1 << 19)) != 0) // SSE4.1 { CPUCompileFlags.Set(InstructionSet_SSE41); - if ((cpuidInfo[2] & (1 << 20)) != 0) // SSE4.2 + if ((cpuidInfo[ECX] & (1 << 20)) != 0) // SSE4.2 { CPUCompileFlags.Set(InstructionSet_SSE42); - if ((cpuidInfo[2] & (1 << 23)) != 0) // POPCNT + if ((cpuidInfo[ECX] & (1 << 23)) != 0) // POPCNT { CPUCompileFlags.Set(InstructionSet_POPCNT); } - if (((cpuidInfo[2] & (1 << 27)) != 0) && ((cpuidInfo[2] & (1 << 28)) != 0)) // OSXSAVE & AVX + if (((cpuidInfo[ECX] & (1 << 27)) != 0) && ((cpuidInfo[ECX] & (1 << 28)) != 0)) // OSXSAVE & AVX { - if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1)) // XGETBV == 11 + if(DoesOSSupportAVX() && (xmmYmmStateSupport() == 1)) // XGETBV == 11 { CPUCompileFlags.Set(InstructionSet_AVX); - if ((cpuidInfo[2] & (1 << 12)) != 0) // FMA + if ((cpuidInfo[ECX] & (1 << 12)) != 0) // FMA { CPUCompileFlags.Set(InstructionSet_FMA); } @@ -1411,7 +1416,7 @@ void EEJitManager::SetCpuInfo() { __cpuidex(cpuidInfo, 0x00000007, 0x00000000); - if ((cpuidInfo[1] & (1 << 5)) != 0) // AVX2 + if ((cpuidInfo[EBX] & (1 << 5)) != 0) // AVX2 { CPUCompileFlags.Set(InstructionSet_AVX2); } @@ -1440,12 +1445,12 @@ void EEJitManager::SetCpuInfo() { __cpuidex(cpuidInfo, 0x00000007, 0x00000000); - if ((cpuidInfo[2] & (1 << 3)) != 0) // BMI1 + if ((cpuidInfo[EBX] & (1 << 3)) != 0) // BMI1 { CPUCompileFlags.Set(InstructionSet_BMI1); } - if ((cpuidInfo[2] & (1 << 8)) != 0) // BMI2 + if ((cpuidInfo[EBX] & (1 << 8)) != 0) // BMI2 { CPUCompileFlags.Set(InstructionSet_BMI2); } @@ -1453,13 +1458,13 @@ void EEJitManager::SetCpuInfo() } __cpuid(cpuidInfo, 0x80000000); - uint32_t maxCpuIdEx = static_cast(cpuidInfo[0]); + uint32_t maxCpuIdEx = static_cast(cpuidInfo[EAX]); if (maxCpuIdEx >= 0x80000001) { __cpuid(cpuidInfo, 0x80000001); - if ((cpuidInfo[3] & (1 << 5)) != 0) // LZCNT + if ((cpuidInfo[ECX] & (1 << 5)) != 0) // LZCNT { CPUCompileFlags.Set(InstructionSet_LZCNT); } From eb243f03285ae23ce7ca78b0f3857cb6c2a2fd4e Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 10 Aug 2020 12:02:08 -0700 Subject: [PATCH 368/755] fix certificate ctx on windows and macOS (#39818) * fix certificate ctx on windows * fix linux * fix osx pal * feedback from review * feedback from review --- .../Security/Pal.OSX/SafeDeleteSslContext.cs | 74 ++++----------- .../Pal.OSX/SafeFreeSslCredentials.cs | 22 ++--- .../src/System/Net/Security/SecureChannel.cs | 15 ++- .../SslStreamCertificateContext.Linux.cs | 8 ++ .../SslStreamCertificateContext.OSX.cs | 9 ++ .../SslStreamCertificateContext.Windows.cs | 92 +++++++++++++++++++ .../Security/SslStreamCertificateContext.cs | 18 ++-- .../System/Net/Security/SslStreamPal.OSX.cs | 4 +- .../System/Net/Security/SslStreamPal.Unix.cs | 4 +- .../Net/Security/SslStreamPal.Windows.cs | 6 +- .../SslStreamNetworkStreamTest.cs | 39 +++++--- .../tests/FunctionalTests/TestHelper.cs | 52 ++++++++++- 12 files changed, 236 insertions(+), 107 deletions(-) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs index ae52439d1629..06ecc8d9ed1d 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs @@ -118,9 +118,9 @@ private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential, SetProtocols(sslContext, credential.Protocols); } - if (credential.Certificate != null) + if (credential.CertificateContext != null) { - SetCertificate(sslContext, credential.Certificate); + SetCertificate(sslContext, credential.CertificateContext); } Interop.AppleCrypto.SslBreakOnServerAuth(sslContext, true); @@ -315,68 +315,34 @@ private static void SetProtocols(SafeSslHandle sslContext, SslProtocols protocol Interop.AppleCrypto.SslSetMaxProtocolVersion(sslContext, maxProtocolId); } - private static void SetCertificate(SafeSslHandle sslContext, X509Certificate2 certificate) + private static void SetCertificate(SafeSslHandle sslContext, SslStreamCertificateContext context) { Debug.Assert(sslContext != null, "sslContext != null"); - Debug.Assert(certificate != null, "certificate != null"); - Debug.Assert(certificate.HasPrivateKey, "certificate.HasPrivateKey"); - X509Chain chain = TLSCertificateExtensions.BuildNewChain( - certificate, - includeClientApplicationPolicy: false)!; - using (chain) - { - X509ChainElementCollection elements = chain.ChainElements; - - // We need to leave off the EE (first) and root (last) certificate from the intermediates. - X509Certificate2[] intermediateCerts = elements.Count < 3 - ? Array.Empty() - : new X509Certificate2[elements.Count - 2]; - - // Build an array which is [ - // SecIdentityRef for EE cert, - // SecCertificateRef for intermed0, - // SecCertificateREf for intermed1, - // ... - // ] - IntPtr[] ptrs = new IntPtr[intermediateCerts.Length + 1]; - - for (int i = 0; i < intermediateCerts.Length; i++) - { - X509Certificate2 intermediateCert = elements[i + 1].Certificate!; + IntPtr[] ptrs = new IntPtr[context!.IntermediateCertificates!.Length + 1]; - if (intermediateCert.HasPrivateKey) - { - // In the unlikely event that we get a certificate with a private key from - // a chain, clear it to the certificate. - // - // The current value of intermediateCert is still in elements, which will - // get Disposed at the end of this method. The new value will be - // in the intermediate certs array, which also gets serially Disposed. - intermediateCert = new X509Certificate2(intermediateCert.RawData); - } + for (int i = 0; i < context.IntermediateCertificates.Length; i++) + { + X509Certificate2 intermediateCert = context.IntermediateCertificates[i]; - intermediateCerts[i] = intermediateCert; - ptrs[i + 1] = intermediateCert.Handle; + if (intermediateCert.HasPrivateKey) + { + // In the unlikely event that we get a certificate with a private key from + // a chain, clear it to the certificate. + // + // The current value of intermediateCert is still in elements, which will + // get Disposed at the end of this method. The new value will be + // in the intermediate certs array, which also gets serially Disposed. + intermediateCert = new X509Certificate2(intermediateCert.RawData); } - ptrs[0] = certificate.Handle; - - Interop.AppleCrypto.SslSetCertificate(sslContext, ptrs); + ptrs[i + 1] = intermediateCert.Handle; + } - // The X509Chain created all new certs for us, so Dispose them. - // And since the intermediateCerts could have been new instances, Dispose them, too - for (int i = 0; i < elements.Count; i++) - { - elements[i].Certificate!.Dispose(); + ptrs[0] = context!.Certificate!.Handle; - if (i < intermediateCerts.Length) - { - intermediateCerts[i].Dispose(); - } - } - } + Interop.AppleCrypto.SslSetCertificate(sslContext, ptrs); } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeFreeSslCredentials.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeFreeSslCredentials.cs index 9a894cb81122..24a4e7be7843 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeFreeSslCredentials.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeFreeSslCredentials.cs @@ -10,30 +10,22 @@ namespace System.Net { internal sealed class SafeFreeSslCredentials : SafeFreeCredentials { - public SafeFreeSslCredentials(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy) + public SafeFreeSslCredentials(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy) : base(IntPtr.Zero, true) { - Debug.Assert( - certificate == null || certificate is X509Certificate2, - "Only X509Certificate2 certificates are supported at this time"); - - X509Certificate2? cert = (X509Certificate2?)certificate; - - if (cert != null) + if (certificateContext != null) { - Debug.Assert(cert.HasPrivateKey, "cert.HasPrivateKey"); - // Make a defensive copy of the certificate. In some async cases the // certificate can have been disposed before being provided to the handshake. // // This meshes with the Unix (OpenSSL) PAL, because it extracts the private key // and cert handle (which get up-reffed) to match the API expectations. - cert = new X509Certificate2(cert); + certificateContext = certificateContext.Duplicate(); - Debug.Assert(cert.HasPrivateKey, "cert clone.HasPrivateKey"); + Debug.Assert(certificateContext.Certificate.HasPrivateKey, "cert clone.HasPrivateKey"); } - Certificate = cert; + CertificateContext = certificateContext; Protocols = protocols; Policy = policy; } @@ -42,13 +34,13 @@ public SafeFreeSslCredentials(X509Certificate certificate, SslProtocols protocol public SslProtocols Protocols { get; } - public X509Certificate2? Certificate { get; } + public SslStreamCertificateContext? CertificateContext { get; } public override bool IsInvalid => false; protected override bool ReleaseHandle() { - Certificate?.Dispose(); + CertificateContext?.Certificate.Dispose(); return true; } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs index 4d20cea9c251..c8cdcb780a26 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -596,21 +596,27 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint) { if (NetEventSource.Log.IsEnabled()) NetEventSource.Log.UsingCachedCredential(this); - _credentialsHandle = cachedCredentialHandle; _selectedClientCertificate = clientCertificate; cachedCred = true; } else { - _credentialsHandle = SslStreamPal.AcquireCredentialsHandle(selectedCert!, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.EncryptionPolicy, _sslAuthenticationOptions.IsServer); + if (selectedCert != null) + { + _sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(selectedCert!); + } + + _credentialsHandle = SslStreamPal.AcquireCredentialsHandle(_sslAuthenticationOptions.CertificateContext, + _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.EncryptionPolicy, _sslAuthenticationOptions.IsServer); + thumbPrint = guessedThumbPrint; // Delay until here in case something above threw. _selectedClientCertificate = clientCertificate; } } finally { - if (selectedCert != null) + if (selectedCert != null && _sslAuthenticationOptions.CertificateContext != null) { _sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(selectedCert); } @@ -710,7 +716,8 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) } else { - _credentialsHandle = SslStreamPal.AcquireCredentialsHandle(selectedCert, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.EncryptionPolicy, _sslAuthenticationOptions.IsServer); + _credentialsHandle = SslStreamPal.AcquireCredentialsHandle(_sslAuthenticationOptions.CertificateContext, _sslAuthenticationOptions.EnabledSslProtocols, + _sslAuthenticationOptions.EncryptionPolicy, _sslAuthenticationOptions.IsServer); thumbPrint = guessedThumbPrint; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs index e4260aeaac78..f5e9dd2114d6 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs @@ -7,6 +7,14 @@ namespace System.Net.Security { public partial class SslStreamCertificateContext { + private const bool TrimRootCertificate = true; + + private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates) + { + Certificate = target; + IntermediateCertificates = intermediates; + } + internal static SslStreamCertificateContext Create(X509Certificate2 target) => Create(target, null); } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs index d616c9e8e6b9..4579f15407fd 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.OSX.cs @@ -7,6 +7,15 @@ namespace System.Net.Security { public partial class SslStreamCertificateContext { + // No leaf, no root. + private const bool TrimRootCertificate = true; + + private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates) + { + Certificate = target; + IntermediateCertificates = intermediates; + } + internal static SslStreamCertificateContext Create(X509Certificate2 target) { // On OSX we do not need to build chain unless we are asked for it. diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs index 5906a13a68b7..0827eca16d57 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs @@ -7,10 +7,102 @@ namespace System.Net.Security { public partial class SslStreamCertificateContext { + // No leaf, include root. + private const bool TrimRootCertificate = false; + internal static SslStreamCertificateContext Create(X509Certificate2 target) { // On Windows we do not need to build chain unless we are asked for it. return new SslStreamCertificateContext(target, Array.Empty()); } + + private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates) + { + if (intermediates.Length > 0) + { + using (X509Chain chain = new X509Chain()) + { + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + chain.ChainPolicy.DisableCertificateDownloads = true; + bool osCanBuildChain = chain.Build(target); + + int count = 0; + foreach (X509ChainStatus status in chain.ChainStatus) + { + if (status.Status.HasFlag(X509ChainStatusFlags.PartialChain) || status.Status.HasFlag(X509ChainStatusFlags.NotSignatureValid)) + { + osCanBuildChain = false; + break; + } + + count++; + } + + // OS failed to build the chain but we have at least some intermediates. + // We will try to add them to "Intermediate Certification Authorities" store. + if (!osCanBuildChain) + { + X509Store? store = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); + + try + { + store.Open(OpenFlags.ReadWrite); + } + catch + { + // If using system store fails, try to fall-back to user store. + store.Dispose(); + store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); + try + { + store.Open(OpenFlags.ReadWrite); + } + catch + { + store.Dispose(); + store = null; + if (NetEventSource.IsEnabled) + { + NetEventSource.Error(this, $"Failed to open certificate store for intermediates."); + } + } + } + + if (store != null) + { + using (store) + { + // Add everything except the root + for (int index = count; index < intermediates.Length - 1; index++) + { + store.Add(intermediates[index]); + } + + osCanBuildChain = chain.Build(target); + foreach (X509ChainStatus status in chain.ChainStatus) + { + if (status.Status.HasFlag(X509ChainStatusFlags.PartialChain) || status.Status.HasFlag(X509ChainStatusFlags.NotSignatureValid)) + { + osCanBuildChain = false; + break; + } + } + + if (!osCanBuildChain) + { + // Add also root to Intermediate CA store so OS can complete building chain. + // (This does not make it trusted. + store.Add(intermediates[intermediates.Length - 1]); + } + } + } + } + } + } + + Certificate = target; + IntermediateCertificates = intermediates; + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs index 621ab20079d5..4cba3232be53 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs @@ -18,7 +18,6 @@ public static SslStreamCertificateContext Create(X509Certificate2 target, X509Ce } X509Certificate2[] intermediates = Array.Empty(); - using (X509Chain chain = new X509Chain()) { if (additionalCertificates != null) @@ -32,11 +31,14 @@ public static SslStreamCertificateContext Create(X509Certificate2 target, X509Ce chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.DisableCertificateDownloads = offline; - chain.Build(target); + bool chainStatus = chain.Build(target); - // No leaf, no root. - int count = chain.ChainElements.Count - 2; + if (!chainStatus && NetEventSource.IsEnabled) + { + NetEventSource.Error(null, $"Failed to build chain for {target.Subject}"); + } + int count = chain.ChainElements.Count - (TrimRootCertificate ? 1 : 2); foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status.HasFlag(X509ChainStatusFlags.PartialChain)) @@ -48,7 +50,7 @@ public static SslStreamCertificateContext Create(X509Certificate2 target, X509Ce } // Count can be zero for a self-signed certificate, or a cert issued directly from a root. - if (count > 0) + if (count > 0 && chain.ChainElements.Count > 1) { intermediates = new X509Certificate2[count]; for (int i = 0; i < count; i++) @@ -70,10 +72,10 @@ public static SslStreamCertificateContext Create(X509Certificate2 target, X509Ce return new SslStreamCertificateContext(target, intermediates); } - private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates) + internal SslStreamCertificateContext Duplicate() { - Certificate = target; - IntermediateCertificates = intermediates; + return new SslStreamCertificateContext(new X509Certificate2(Certificate), IntermediateCertificates); + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs index 4f5a99069851..5f1c1bb34667 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs @@ -53,12 +53,12 @@ public static SecurityStatusPal InitializeSecurityContext( } public static SafeFreeCredentials AcquireCredentialsHandle( - X509Certificate certificate, + SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { - return new SafeFreeSslCredentials(certificate, protocols, policy); + return new SafeFreeSslCredentials(certificateContext, protocols, policy); } internal static byte[]? GetNegotiatedApplicationProtocol(SafeDeleteContext? context) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs index 4864d32b63c6..aeae1edc9fe9 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs @@ -36,10 +36,10 @@ public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredential return HandshakeInternal(credential!, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions); } - public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate? certificate, + public static SafeFreeCredentials AcquireCredentialsHandle(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { - return new SafeFreeSslCredentials(certificate, protocols, policy); + return new SafeFreeSslCredentials(certificateContext?.Certificate, protocols, policy); } public static SecurityStatusPal EncryptMessage(SafeDeleteContext securityContext, ReadOnlyMemory input, int headerSize, int trailerSize, ref byte[] output, out int resultSize) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 5e72e6b553b0..4c3c2c22db42 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -110,12 +110,12 @@ public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredential return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode); } - public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate? certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) + public static SafeFreeCredentials AcquireCredentialsHandle(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { // New crypto API supports TLS1.3 but it does not allow to force NULL encryption. return !UseNewCryptoApi || policy == EncryptionPolicy.NoEncryption ? - AcquireCredentialsHandleSchannelCred(certificate, protocols, policy, isServer) : - AcquireCredentialsHandleSchCredentials(certificate, protocols, policy, isServer); + AcquireCredentialsHandleSchannelCred(certificateContext?.Certificate, protocols, policy, isServer) : + AcquireCredentialsHandleSchCredentials(certificateContext?.Certificate, protocols, policy, isServer); } // This is legacy crypto API used on .NET Framework and older Windows versions. diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index 28cb9233b638..14d61a3d7407 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -7,6 +7,7 @@ using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -15,14 +16,19 @@ namespace System.Net.Security.Tests { using Configuration = System.Net.Test.Common.Configuration; - public class SslStreamNetworkStreamTest + public class SslStreamNetworkStreamTest : IDisposable { private readonly X509Certificate2 _serverCert; - private readonly X509CertificateCollection _serverChain; + private readonly X509Certificate2Collection _serverChain; public SslStreamNetworkStreamTest() { - (_serverCert, _serverChain) = TestHelper.GenerateCertificates("localhost"); + (_serverCert, _serverChain) = TestHelper.GenerateCertificates("localhost", this.GetType().Name); + } + + public void Dispose() + { + TestHelper.CleanupCertificates(this.GetType().Name); } [Fact] @@ -269,14 +275,12 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] public async Task SslStream_UntrustedCaWithCustomCallback_OK() { - var options = new SslClientAuthenticationOptions() { TargetHost = "localhost" }; - options.RemoteCertificateValidationCallback = + var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost" }; + clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { - chain.ChainPolicy.ExtraStore.AddRange(_serverChain); chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count -1]); chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; @@ -286,14 +290,17 @@ public async Task SslStream_UntrustedCaWithCustomCallback_OK() return result; }; + var serverOptions = new SslServerAuthenticationOptions(); + serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(_serverCert, _serverChain); + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (clientStream) using (serverStream) using (SslStream client = new SslStream(clientStream)) using (SslStream server = new SslStream(serverStream)) { - Task t1 = client.AuthenticateAsClientAsync(options, default); - Task t2 = server.AuthenticateAsServerAsync(_serverCert); + Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); + Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); } @@ -306,13 +313,12 @@ public async Task SslStream_UntrustedCaWithCustomCallback_OK() public async Task SslStream_UntrustedCaWithCustomCallback_Throws(bool customCallback) { string errorMessage; - var options = new SslClientAuthenticationOptions() { TargetHost = "localhost" }; + var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost" }; if (customCallback) { - options.RemoteCertificateValidationCallback = + clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { - chain.ChainPolicy.ExtraStore.AddRange(_serverChain); chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count -1]); chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; // This should work and we should be able to trust the chain. @@ -325,17 +331,20 @@ public async Task SslStream_UntrustedCaWithCustomCallback_Throws(bool customCall } else { - errorMessage = "PartialChain"; + errorMessage = "UntrustedRoot"; } + var serverOptions = new SslServerAuthenticationOptions(); + serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(_serverCert, _serverChain); + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (clientStream) using (serverStream) using (SslStream client = new SslStream(clientStream)) using (SslStream server = new SslStream(serverStream)) { - Task t1 = client.AuthenticateAsClientAsync(options, default); - Task t2 = server.AuthenticateAsServerAsync(_serverCert); + Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); + Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); var e = await Assert.ThrowsAsync(() => t1); Assert.Contains(errorMessage, e.Message); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs index 4e9a9a8ea37a..b16bcac29825 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs @@ -72,14 +72,53 @@ internal static (VirtualNetworkStream ClientStream, VirtualNetworkStream ServerS return (new VirtualNetworkStream(vn, isServer: false), new VirtualNetworkStream(vn, isServer: true)); } - internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string name, string? testName = null) + internal static void CleanupCertificates(string testName) { - X509Certificate2Collection chain = new X509Certificate2Collection(); + string caName = $"O={testName}"; + try + { + using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine)) + { + store.Open(OpenFlags.ReadWrite); + foreach (X509Certificate2 cert in store.Certificates) + { + if (cert.Subject.Contains(caName)) + { + store.Remove(cert); + } + } + } + } + catch { }; + + try + { + using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) + { + store.Open(OpenFlags.ReadWrite); + foreach (X509Certificate2 cert in store.Certificates) + { + if (cert.Subject.Contains(caName)) + { + store.Remove(cert); + } + } + } + } + catch { }; + } + internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string targetName, string? testName = null) + { + if (PlatformDetection.IsWindows && testName != null) + { + CleanupCertificates(testName); + } + X509Certificate2Collection chain = new X509Certificate2Collection(); X509ExtensionCollection extensions = new X509ExtensionCollection(); SubjectAlternativeNameBuilder builder = new SubjectAlternativeNameBuilder(); - builder.AddDnsName(name); + builder.AddDnsName(targetName); extensions.Add(builder.Build()); extensions.Add(s_eeConstraints); extensions.Add(s_eeKeyUsage); @@ -91,7 +130,7 @@ internal static (X509Certificate2 certificate, X509Certificate2Collection) Gener out CertificateAuthority root, out CertificateAuthority intermediate, out X509Certificate2 endEntity, - subjectName: name, + subjectName: targetName, testName: testName, keySize: 2048, extensions: extensions); @@ -103,6 +142,11 @@ internal static (X509Certificate2 certificate, X509Certificate2Collection) Gener root.Dispose(); intermediate.Dispose(); + if (PlatformDetection.IsWindows) + { + endEntity = new X509Certificate2(endEntity.Export(X509ContentType.Pfx)); + } + return (endEntity, chain); } } From a4eba0a0e1ecb31b7cb3482509bd461c8e9f5ccf Mon Sep 17 00:00:00 2001 From: wooooooood <40855076+wooooooood@users.noreply.github.com> Date: Tue, 11 Aug 2020 05:09:20 +0900 Subject: [PATCH 369/755] Remove unused local in System.Configuration.ConfigurationManager (#40583) --- .../src/System/Configuration/ApplicationSettingsBase.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs index 61d110cf3bf1..b23e49ccb8e4 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs @@ -725,7 +725,6 @@ private object GetPropertyValue(string propertyName) } } - object temp = base[propertyName]; SettingsProperty setting = Properties[propertyName]; SettingsProvider provider = setting != null ? setting.Provider : null; From 4dbe414c31cdd479289c496a8687251f2f2aa52a Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 10 Aug 2020 22:35:25 +0200 Subject: [PATCH 370/755] [browser][file system] Tests System.IO.FileSystem (#39768) * [browser][file system] Tests System.IO.FileSystem * Remove FileSystem from test project exclusions. * [browser][filesystem] Comment on skipped tests due to IO.Pipes not supported * [browser][filesystem] Comment on skipped tests due to monitor not supported * Address review comments * Address review comments on how to handle monitor PNSE * Update src/libraries/System.IO.FileSystem/tests/File/GetSetTimes.cs Co-authored-by: Jan Kotas * Add ActiveIssue for browser platform ``` [ActiveIssue("https://github.com/dotnet/runtime/issues/39955", TestPlatforms.Browser)] public void NotFoundErrorIsExpected() ``` * Simplify test case with `PlatformDetection.IsSuperUser` as per review comment * Remove unused variable from tests * Browser platform volume does not limit each component of the path to a total of 255 characters. - Remove the test `DirectoryWithComponentLongerThanMaxComponentAsPath_ThrowsException` for Browser platform. - Add new test `DirectoryWithComponentLongerThanMaxComponentAsPath_BrowserDoesNotThrowsException` for Browser platform in case this check is added in the future. * Fix windows tests * Add ActiveIssue to test System.IO.Tests.DirectoryInfo_Name.CurrentDirectory - System.IO.Tests.DirectoryInfo_Name.CurrentDirectory does not pass because it is using Path.GetFileName on the current directory of "/". - See issue https://github.com/dotnet/runtime/issues/39998 for more information * Add active issue for tests that need to support file locking. * Add active issue for tests that need to support file locking. * Browser volume does not have a limit on segments * Remove browser platform test * Remove active issue for NotFoundErrorIsExpected * Remove platform specific from SkippingHiddenFiles * Fix enumeration test errors failing from `HiddenFilesAreReturned`. - WebAssembly (BROWSER) has dirent d_type but is not identifying correctly but by returning UNKNOWN the managed code properly stats the file to detect if entry is directory or not. * Fix enumeration test errors failing from `HiddenFilesAreReturned`. - WebAssembly (BROWSER) has dirent d_type but is not identifying correctly but by returning UNKNOWN the managed code properly stats the file to detect if entry is directory or not. * Fix build for TARGET_WASM not defined * Address review comment by add check for IsWindows to IsSuperUser. * Address review comment by add check for IsWindows to IsSuperUser. * Platform Specific test for hidden files no longer needed. * Platform Specific test fno longer needed. * Use active issue for rename issue * ActiveIssue no longer needed - PR https://github.com/dotnet/runtime/pull/40310 works around the issue for now while waiting for fix https://github.com/emscripten-core/emscripten/issues/11804 / https://github.com/emscripten-core/emscripten/pull/11812 * Use ActiveIssue for SettingUpdatesProperties * Use ActiveIssue for TimesIncludeMillisecondPart * Use ActiveIssue for ErrorHandlingTests failures * Use ActiveIssue for SetUptoNanoseconds * Use ActiveIssue for GetSetTimes test failures * Use ActiveIssue for tests failing with DirectoryNotFoundException * Use ActiveIssue for tests failing with UnauthorizedAccessException * Remove debugging statement from pal_io * Address type in CreateDirectory method name Co-authored-by: Jan Kotas Co-authored-by: Mitchell Hwang --- .../System/PlatformDetection.Unix.cs | 4 +--- src/libraries/Native/Unix/System.Native/pal_io.c | 10 ++++++++-- .../tests/Base/BaseGetSetTimes.cs | 2 ++ .../tests/Directory/CreateDirectory.cs | 15 ++++++++++++--- .../tests/Directory/Delete.cs | 1 + .../tests/Directory/Exists.cs | 2 +- .../System.IO.FileSystem/tests/Directory/Move.cs | 1 + .../tests/DirectoryInfo/Exists.cs | 2 +- .../tests/DirectoryInfo/MoveTo.cs | 1 + .../tests/DirectoryInfo/Name.cs | 1 + .../tests/Enumeration/ErrorHandlingTests.cs | 2 ++ .../System.IO.FileSystem/tests/File/Copy.cs | 6 +++++- .../System.IO.FileSystem/tests/File/Create.cs | 10 ++++++---- .../System.IO.FileSystem/tests/File/Exists.cs | 2 +- .../tests/File/GetSetTimes.cs | 3 ++- .../tests/File/ReadWriteAllBytes.cs | 3 ++- .../tests/File/ReadWriteAllBytesAsync.cs | 3 ++- .../tests/File/ReadWriteAllLines.cs | 6 ++++-- .../tests/File/ReadWriteAllLinesAsync.cs | 3 ++- .../tests/File/ReadWriteAllText.cs | 3 ++- .../tests/File/ReadWriteAllTextAsync.cs | 3 ++- .../tests/FileInfo/Exists.cs | 2 +- .../tests/FileInfo/GetSetTimes.cs | 3 +++ .../tests/FileStream/CanSeek.cs | 1 + .../tests/FileStream/CopyToAsync.cs | 1 + .../tests/FileStream/Flush.cs | 1 + .../tests/FileStream/Pipes.cs | 2 ++ .../tests/FileStream/ReadWriteSpan.cs | 6 +++--- .../tests/FileStream/WriteAsync.cs | 2 +- .../tests/FileStream/ctor_str_fm_fa_fs.cs | 1 + .../tests/FileStream/ctor_str_fm_fa_fs.write.cs | 1 + .../tests/FileSystemTest.Browser.cs | 16 ++++++++++++++++ .../tests/System.IO.FileSystem.Tests.csproj | 5 ++++- .../MemoryMappedFile.CreateFromFile.Tests.cs | 4 ++-- src/libraries/tests.proj | 1 - 35 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 src/libraries/System.IO.FileSystem/tests/FileSystemTest.Browser.cs diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs index a04299384915..fb7db1e40d04 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs @@ -47,9 +47,7 @@ public static partial class PlatformDetection public static bool IsNotFedoraOrRedHatFamily => !IsFedora && !IsRedHatFamily; public static bool IsNotDebian10 => !IsDebian10; - public static bool IsSuperUser => IsBrowser ? false : (!IsWindows ? - libc.geteuid() == 0 : - throw new PlatformNotSupportedException()); + public static bool IsSuperUser => IsBrowser || IsWindows ? false : libc.geteuid() == 0; public static Version OpenSslVersion => !IsOSXLike && !IsWindows ? GetOpenSslVersion() : diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 85c5bf045bf3..e0ed6cadfd68 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -91,7 +91,10 @@ c_static_assert(PAL_S_IFSOCK == S_IFSOCK); // Validate that our enum for inode types is the same as what is // declared by the dirent.h header on the local system. // (AIX doesn't have dirent d_type, so none of this there) -#if defined(DT_UNKNOWN) +// WebAssembly (BROWSER) has dirent d_type but is not correct +// by returning UNKNOWN the managed code properly stats the file +// to detect if entry is directory or not. +#if defined(DT_UNKNOWN) || defined(TARGET_WASM) c_static_assert((int)PAL_DT_UNKNOWN == (int)DT_UNKNOWN); c_static_assert((int)PAL_DT_FIFO == (int)DT_FIFO); c_static_assert((int)PAL_DT_CHR == (int)DT_CHR); @@ -345,10 +348,13 @@ static void ConvertDirent(const struct dirent* entry, DirectoryEntry* outputEntr // the start of the unmanaged string. Give the caller back a pointer to the // location of the start of the string that exists in their own byte buffer. outputEntry->Name = entry->d_name; -#if !defined(DT_UNKNOWN) +#if !defined(DT_UNKNOWN) || defined(TARGET_WASM) // AIX has no d_type, and since we can't get the directory that goes with // the filename from ReadDir, we can't stat the file. Return unknown and // hope that managed code can properly stat the file. + // WebAssembly (BROWSER) has dirent d_type but is not correct + // by returning UNKNOWN the managed code properly stats the file + // to detect if entry is directory or not. outputEntry->InodeType = PAL_DT_UNKNOWN; #else outputEntry->InodeType = (int32_t)entry->d_type; diff --git a/src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetTimes.cs b/src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetTimes.cs index 58a515e0b7d4..67d9655b1fee 100644 --- a/src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetTimes.cs +++ b/src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetTimes.cs @@ -41,6 +41,7 @@ public static TimeFunction Create(SetTime setter, GetTime getter, DateTimeKind k } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40528", TestPlatforms.Browser)] public void SettingUpdatesProperties() { T item = GetExistingItem(); @@ -77,6 +78,7 @@ public void CanGetAllTimesAfterCreation() } [ConditionalFact(nameof(isNotHFS))] // OSX HFS driver format does not support millisec granularity + [ActiveIssue("https://github.com/dotnet/runtime/issues/40530", TestPlatforms.Browser)] public void TimesIncludeMillisecondPart() { T item = GetExistingItem(); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs b/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs index 5b3b2dcbf79b..78c234d5627c 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs @@ -210,17 +210,26 @@ public void DirectoryEqualToMaxDirectory_CanBeCreatedAllAtOnce() Assert.Equal(path, result.FullName); Assert.True(Directory.Exists(result.FullName)); } + #endregion + + #region PlatformSpecific [Theory, MemberData(nameof(PathsWithComponentLongerThanMaxComponent))] + [PlatformSpecific(~TestPlatforms.Browser)] // Browser does not have a limit on the maximum component length public void DirectoryWithComponentLongerThanMaxComponentAsPath_ThrowsException(string path) { AssertExtensions.ThrowsAny(() => Create(path)); } - #endregion - - #region PlatformSpecific + [Theory, + MemberData(nameof(PathsWithComponentLongerThanMaxComponent))] + [PlatformSpecific(TestPlatforms.Browser)] // Browser specific test in case the check changes in the future + public void DirectoryWithComponentLongerThanMaxComponentAsPath_BrowserDoesNotThrowException(string path) + { + DirectoryInfo result = Create(path); + Assert.True(Directory.Exists(path)); + } [Theory, MemberData(nameof(PathsWithInvalidColons))] [PlatformSpecific(TestPlatforms.Windows)] diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs index 386b847728eb..00d5c46cef7e 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs @@ -244,6 +244,7 @@ public void RecursiveDelete() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void RecursiveDeleteWithTrailingSlash() { DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs index 04b1411fca3a..44d07e2c7749 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs @@ -390,7 +390,7 @@ public void SubdirectoryOnNonExistentDriveAsPath_ReturnsFalse() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Makes call to native code (libc) + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Makes call to native code (libc) public void FalseForNonRegularFile() { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs index 3dcd99c3a44c..c5a145c686cf 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs @@ -173,6 +173,7 @@ public void DirectoryNameWithSpaces() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void TrailingDirectorySeparators() { string testDirSource = Path.Combine(TestDirectory, GetTestFileName()); diff --git a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs index 615bd4c1b1db..1be25240b0d6 100644 --- a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Exists.cs @@ -110,7 +110,7 @@ public void FalseForFile() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Uses P/Invokes + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Uses P/Invokes public void FalseForNonRegularFile() { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs index e5e5478fcb39..fba22eb09282 100644 --- a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs +++ b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs @@ -24,6 +24,7 @@ protected virtual void Move(DirectoryInfo sourceDir, string destDir) #region UniversalTests [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void DirectoryPathUpdatesOnMove() { //NOTE: MoveTo adds a trailing separator character to the FullName of a DirectoryInfo diff --git a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Name.cs b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Name.cs index 52e08f5c6a08..30021757a4d6 100644 --- a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Name.cs +++ b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/Name.cs @@ -8,6 +8,7 @@ namespace System.IO.Tests public class DirectoryInfo_Name : FileSystemTest { [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39998", TestPlatforms.Browser)] public void CurrentDirectory() { var info = new DirectoryInfo("."); diff --git a/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs b/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs index 2c330cb0b2e7..675b86ccda22 100644 --- a/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs +++ b/src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.cs @@ -102,6 +102,7 @@ public void DeleteDirectoryAfterOpening() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40531", TestPlatforms.Browser)] public void VariableLengthFileNames_AllCreatableFilesAreEnumerable() { DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath()); @@ -119,6 +120,7 @@ public void VariableLengthFileNames_AllCreatableFilesAreEnumerable() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40531", TestPlatforms.Browser)] public void VariableLengthDirectoryNames_AllCreatableDirectoriesAreEnumerable() { DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath()); diff --git a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs index 9da51a7cd607..e0b69578aca9 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs @@ -108,6 +108,7 @@ public static IEnumerable CopyFileWithData_MemberData() [Theory] [MemberData(nameof(CopyFileWithData_MemberData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40543", TestPlatforms.Browser)] public void CopyFileWithData(char[] data, bool readOnly) { string testFileSource = GetTestFilePath(); @@ -140,7 +141,10 @@ public void CopyFileWithData(char[] data, bool readOnly) } // Ensure last write/access time on the new file is appropriate - Assert.InRange(File.GetLastWriteTimeUtc(testFileDest), lastWriteTime.AddSeconds(-1), lastWriteTime.AddSeconds(1)); + if (PlatformDetection.IsNotBrowser) // There is only one write time on browser vfs + { + Assert.InRange(File.GetLastWriteTimeUtc(testFileDest), lastWriteTime.AddSeconds(-1), lastWriteTime.AddSeconds(1)); + } Assert.Equal(readOnly, (File.GetAttributes(testFileDest) & FileAttributes.ReadOnly) != 0); if (readOnly) diff --git a/src/libraries/System.IO.FileSystem/tests/File/Create.cs b/src/libraries/System.IO.FileSystem/tests/File/Create.cs index 405d1f92ba69..447bb323baff 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Create.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Create.cs @@ -111,6 +111,7 @@ public void InvalidDirectory() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void FileInUse() { DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); @@ -144,7 +145,12 @@ public void OverwriteReadOnly() Assert.True(File.Exists(testFile)); } + #endregion + + #region PlatformSpecific + [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // Browser platform volume does not limit segments public void LongPathSegment() { DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); @@ -153,10 +159,6 @@ public void LongPathSegment() Create(Path.Combine(testDir.FullName, new string('a', 300)))); } - #endregion - - #region PlatformSpecific - [Fact] [PlatformSpecific(TestPlatforms.AnyUnix)] public void LongDirectoryName() diff --git a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs index 40d5ebce3d4b..225ed8e04e89 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs @@ -247,7 +247,7 @@ public void DirectoryWithComponentLongerThanMaxComponentAsPath_ReturnsFalse(stri } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Uses P/Invokes + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Uses P/Invokes public void FalseForNonRegularFile() { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/GetSetTimes.cs b/src/libraries/System.IO.FileSystem/tests/File/GetSetTimes.cs index a7840ebf9491..07140ac9c4ee 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/GetSetTimes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/GetSetTimes.cs @@ -13,7 +13,7 @@ public class File_GetSetTimes : StaticGetSetTimes { // OSX has the limitation of setting upto 2262-04-11T23:47:16 (long.Max) date. // 32bit Unix has time_t up to ~ 2038. - private static bool SupportsLongMaxDateTime => PlatformDetection.IsWindows || (RuntimeInformation.ProcessArchitecture != Architecture.Arm && RuntimeInformation.ProcessArchitecture != Architecture.X86 && !PlatformDetection.IsOSXLike); + private static bool SupportsLongMaxDateTime => PlatformDetection.IsWindows || (!PlatformDetection.Is32BitProcess && !PlatformDetection.IsOSXLike); protected override string GetExistingItem() { @@ -135,6 +135,7 @@ public void SetLastWriteTimeTicks() } [ConditionalFact(nameof(isNotHFS))] // OSX HFS driver format does not support nanosecond granularity. + [ActiveIssue("https://github.com/dotnet/runtime/issues/40532", TestPlatforms.Browser)] public void SetUptoNanoseconds() { string file = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index b6b47961363b..a5d9b5ee9952 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -80,6 +80,7 @@ public void Overwrite() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void OpenFile_ThrowsIOException() { string path = GetTestFilePath(); @@ -105,7 +106,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { File.WriteAllBytes(path, Encoding.UTF8.GetBytes("text")); Assert.Equal(Encoding.UTF8.GetBytes("text"), File.ReadAllBytes(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs index 598fc0184871..3c46acff8b4b 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs @@ -94,6 +94,7 @@ public async Task OverwriteAsync() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public async Task OpenFile_ThrowsIOExceptionAsync() { string path = GetTestFilePath(); @@ -119,7 +120,7 @@ public async Task WriteToReadOnlyFileAsync() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { await File.WriteAllBytesAsync(path, Encoding.UTF8.GetBytes("text")); Assert.Equal(Encoding.UTF8.GetBytes("text"), await File.ReadAllBytesAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs index d5ef0eed9cee..62ff39339e2b 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs @@ -78,6 +78,7 @@ public virtual void Overwrite() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void OpenFile_ThrowsIOException() { string path = GetTestFilePath(); @@ -111,7 +112,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { Write(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, Read(path)); @@ -266,6 +267,7 @@ public virtual void Overwrite() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void OpenFile_ThrowsIOException() { string path = GetTestFilePath(); @@ -299,7 +301,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { Write(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, Read(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs index 87b3ad7df7cb..d717e2839956 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs @@ -76,6 +76,7 @@ public virtual async Task OverwriteAsync() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public async Task OpenFile_ThrowsIOExceptionAsync() { string path = GetTestFilePath(); @@ -106,7 +107,7 @@ public async Task WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { await WriteAsync(path, new string[] { "text" }); Assert.Equal(new string[] { "text" }, await ReadAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs index e511b69540c7..9d330b27583e 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs @@ -85,6 +85,7 @@ public virtual void Overwrite() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void OpenFile_ThrowsIOException() { string path = GetTestFilePath(); @@ -118,7 +119,7 @@ public void WriteToReadOnlyFile() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { Write(path, "text"); Assert.Equal("text", Read(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs index 33813987cd10..ac77b2509bb1 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs @@ -84,6 +84,7 @@ public virtual async Task OverwriteAsync() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public async Task OpenFile_ThrowsIOExceptionAsync() { string path = GetTestFilePath(); @@ -114,7 +115,7 @@ public async Task WriteToReadOnlyFileAsync() try { // Operation succeeds when being run by the Unix superuser - if (!OperatingSystem.IsWindows() && geteuid() == 0) + if (PlatformDetection.IsSuperUser) { await WriteAsync(path, "text"); Assert.Equal("text", await ReadAsync(path)); diff --git a/src/libraries/System.IO.FileSystem/tests/FileInfo/Exists.cs b/src/libraries/System.IO.FileSystem/tests/FileInfo/Exists.cs index 777a5448afc7..b0f1779745f6 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileInfo/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileInfo/Exists.cs @@ -91,7 +91,7 @@ public void FalseForDirectory() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Uses P/Invokes + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Uses P/Invokes public void TrueForNonRegularFile() { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs b/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs index b27adf59f27c..27b2e845868b 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs @@ -104,6 +104,7 @@ public override IEnumerable TimeFunctions(bool requiresRoundtrippi } [ConditionalFact(nameof(isNotHFS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40530", TestPlatforms.Browser)] public void CopyToMillisecondPresent() { FileInfo input = GetNonZeroMilliseconds(); @@ -118,6 +119,7 @@ public void CopyToMillisecondPresent() } [ConditionalFact(nameof(isNotHFS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40530", TestPlatforms.Browser)] public void CopyToNanosecondsPresent() { FileInfo input = GetNonZeroNanoseconds(); @@ -160,6 +162,7 @@ public void MoveToMillisecondPresent_HFS() } [ConditionalFact(nameof(isNotHFS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40530", TestPlatforms.Browser)] public void MoveToMillisecondPresent() { FileInfo input = GetNonZeroMilliseconds(); diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/CanSeek.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/CanSeek.cs index 0bf573c15cb8..bb1c7836e95e 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/CanSeek.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/CanSeek.cs @@ -43,6 +43,7 @@ public void CanSeekFalseForDisposedStream() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // IO.Pipes not supported public void CanSeekReturnsFalseForPipe() { using (var pipeStream = new AnonymousPipeServerStream()) diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs index da7145719b90..6141240ce7f7 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs @@ -177,6 +177,7 @@ public static IEnumerable File_AllDataCopied_MemberData() [Theory] [InlineData(10, 1024)] + [PlatformSpecific(~TestPlatforms.Browser)] // IO.Pipes not supported public async Task AnonymousPipeViaFileStream_AllDataCopied(int writeSize, int numWrites) { long totalLength = writeSize * numWrites; diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/Flush.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/Flush.cs index ba965283fb16..b9552084b60e 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/Flush.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Flush.cs @@ -135,6 +135,7 @@ public void FlushCallsFlush_flushToDisk_False() [InlineData(null)] [InlineData(false)] [InlineData(true)] + [PlatformSpecific(~TestPlatforms.Browser)] // IO.Pipes not supported public void FlushCanBeUsedOnPipes_Success(bool? flushToDisk) { using (var pipeStream = new AnonymousPipeServerStream(PipeDirection.In)) diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/Pipes.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/Pipes.cs index 7c6f08e2057e..fd366dc702ff 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/Pipes.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Pipes.cs @@ -15,6 +15,7 @@ public class Pipes : FileSystemTest [Theory] [InlineData(true)] [InlineData(false)] + [PlatformSpecific(~TestPlatforms.Browser)] // IO.Pipes not supported public async Task AnonymousPipeWriteViaFileStream(bool asyncWrites) { using (var server = new AnonymousPipeServerStream(PipeDirection.In)) @@ -70,6 +71,7 @@ await Task.WhenAll( [Theory] [InlineData(true)] [InlineData(false)] + [PlatformSpecific(~TestPlatforms.Browser)] // IO.Pipes not supported public async Task AnonymousPipeReadViaFileStream(bool asyncReads) { using (var server = new AnonymousPipeServerStream(PipeDirection.Out)) diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/ReadWriteSpan.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/ReadWriteSpan.cs index f6b74164f5ac..4d66807a3c99 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/ReadWriteSpan.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/ReadWriteSpan.cs @@ -23,7 +23,7 @@ public void DisposedStream_ReadWrite_Throws() Assert.Throws(() => fs.Write(new Span(new byte[1]))); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] // Browser PNSE: Cannot wait on monitors public void EmptyFile_Read_Succeeds() { using (var fs = CreateFileStream(GetTestFilePath(), FileMode.Create)) @@ -46,7 +46,7 @@ public void EmptyFile_Read_Succeeds() } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] // Browser PNSE: Cannot wait on monitors public void NonEmptyFile_Read_GetsExpectedData() { string fileName = GetTestFilePath(); @@ -111,7 +111,7 @@ public void EmptyWrites_NoDataWritten() } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] // Browser PNSE: Cannot wait on monitors public void NonEmptyWrite_WritesExpectedData() { using (var fs = CreateFileStream(GetTestFilePath(), FileMode.Create)) diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs index 5f606907dcb2..7b236db7b4b2 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs @@ -276,7 +276,7 @@ public static IEnumerable MemberData_FileStreamAsyncWriting() } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] // Browser PNSE: Cannot wait on monitors public Task ManyConcurrentWriteAsyncs() { // For inner loop, just test one case diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.cs index b719725f2a45..805354e31cd4 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.cs @@ -121,6 +121,7 @@ public void FileShareOpenOrCreate() [Theory] [InlineData(FileMode.Create)] [InlineData(FileMode.Truncate)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void NoTruncateOnFileShareViolation(FileMode fileMode) { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.write.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.write.cs index 6f1abef3d17a..e0d619187c39 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.write.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_str_fm_fa_fs.write.cs @@ -40,6 +40,7 @@ public void FileShareWriteExisting() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40065", TestPlatforms.Browser)] public void FileShareWithoutWriteThrows() { string fileName = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/FileSystemTest.Browser.cs b/src/libraries/System.IO.FileSystem/tests/FileSystemTest.Browser.cs new file mode 100644 index 000000000000..afaa1cc90e91 --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/FileSystemTest.Browser.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Xunit; + +namespace System.IO.Tests +{ + public abstract partial class FileSystemTest + { + protected static int mkfifo(string path, int mode) + { + throw new PlatformNotSupportedException(); + } + } +} diff --git a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj index e0769d47d16a..7115d412c074 100644 --- a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj +++ b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj @@ -46,12 +46,15 @@ - + + + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs index f23da731a67e..4a08c3f7e3a8 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs @@ -696,13 +696,13 @@ private void WriteToReadOnlyFile(MemoryMappedFileAccess access, bool succeeds) public void WriteToReadOnlyFile_ReadWrite(MemoryMappedFileAccess access) { WriteToReadOnlyFile(access, access == MemoryMappedFileAccess.Read || - (!OperatingSystem.IsWindows() && PlatformDetection.IsSuperUser)); + PlatformDetection.IsSuperUser); } [Fact] public void WriteToReadOnlyFile_CopyOnWrite() { - WriteToReadOnlyFile(MemoryMappedFileAccess.CopyOnWrite, (!OperatingSystem.IsWindows() && PlatformDetection.IsSuperUser)); + WriteToReadOnlyFile(MemoryMappedFileAccess.CopyOnWrite, PlatformDetection.IsSuperUser); } /// diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 9ba9856ed656..28cee277be5e 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -25,7 +25,6 @@ - From 13b2a181e1082a659a97197cabdec524008dcc30 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 10 Aug 2020 17:18:13 -0400 Subject: [PATCH 371/755] =?UTF-8?q?Fixing=20debugger=20hang=20that=20would?= =?UTF-8?q?=20occur=20when=20inspecting=20a=20field=20that=20ha=E2=80=A6?= =?UTF-8?q?=20(#40455)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …s a Debugger.Break in it's accessor. fixes mono/mono#20209 Co-authored-by: UnityAlex --- src/mono/mono/mini/debugger-agent.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index 5b6d729a3390..780332672fc6 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -4027,6 +4027,9 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx DebuggerTlsData *tls; tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); g_assert (tls); + // We are already processing a breakpoint event + if (tls->disable_breakpoints) + return; mono_stopwatch_stop (&tls->step_time); break; } From a6a15e165321f88a33963cb10ba8e585a783605f Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 10 Aug 2020 16:19:13 -0500 Subject: [PATCH 372/755] Sync Microsoft.Extensions ref assembiles for new linker attributes. (#40621) * Sync Microsoft.Extensions ref assembiles for new linker attributes. * Suppress two linker warnings in DependencyInjection. These warnings are safe since they are calling Array.Empty through reflection. --- ...nsions.DependencyInjection.Abstractions.cs | 72 +++++++++---------- .../Expressions/ExpressionResolverBuilder.cs | 13 ++-- .../ILEmit/ILEmitResolverBuilder.cs | 4 +- ...crosoft.Extensions.Hosting.Abstractions.cs | 2 +- ...oft.Extensions.Hosting.Abstractions.csproj | 2 + .../ref/Microsoft.Extensions.Http.cs | 30 ++++---- .../ref/Microsoft.Extensions.Http.csproj | 2 + .../Microsoft.Extensions.Logging.Console.cs | 4 +- ...icrosoft.Extensions.Logging.Console.csproj | 2 + 9 files changed, 70 insertions(+), 61 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs index dffd433b92de..6b5248699392 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.cs @@ -8,11 +8,11 @@ namespace Microsoft.Extensions.DependencyInjection { public static partial class ActivatorUtilities { - public static Microsoft.Extensions.DependencyInjection.ObjectFactory CreateFactory(System.Type instanceType, System.Type[] argumentTypes) { throw null; } - public static object CreateInstance(System.IServiceProvider provider, System.Type instanceType, params object[] parameters) { throw null; } - public static T CreateInstance(System.IServiceProvider provider, params object[] parameters) { throw null; } - public static object GetServiceOrCreateInstance(System.IServiceProvider provider, System.Type type) { throw null; } - public static T GetServiceOrCreateInstance(System.IServiceProvider provider) { throw null; } + public static Microsoft.Extensions.DependencyInjection.ObjectFactory CreateFactory([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type instanceType, System.Type[] argumentTypes) { throw null; } + public static object CreateInstance(System.IServiceProvider provider, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type instanceType, params object[] parameters) { throw null; } + public static T CreateInstance<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] T>(System.IServiceProvider provider, params object[] parameters) { throw null; } + public static object GetServiceOrCreateInstance(System.IServiceProvider provider, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { throw null; } + public static T GetServiceOrCreateInstance<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] T>(System.IServiceProvider provider) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.All)] public partial class ActivatorUtilitiesConstructorAttribute : System.Attribute @@ -42,28 +42,28 @@ public partial interface ISupportRequiredService public delegate object ObjectFactory(System.IServiceProvider serviceProvider, object?[]? arguments); public static partial class ServiceCollectionServiceExtensions { - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type serviceType) { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Func implementationFactory) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Type implementationType) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type serviceType) { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Func implementationFactory) { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, object implementationInstance) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Type implementationType) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, TService implementationInstance) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type serviceType) { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Func implementationFactory) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, System.Type implementationType) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } } public partial class ServiceDescriptor @@ -78,24 +78,24 @@ public ServiceDescriptor(System.Type serviceType, [System.Diagnostics.CodeAnalys public Microsoft.Extensions.DependencyInjection.ServiceLifetime Lifetime { get { throw null; } } public System.Type ServiceType { get { throw null; } } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Describe(System.Type serviceType, System.Func implementationFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Describe(System.Type serviceType, System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Describe(System.Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped(System.Type service, System.Func implementationFactory) { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped(System.Type service, System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped(System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped(System.Func implementationFactory) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped() where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped() where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Scoped(System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Type serviceType, System.Func implementationFactory) { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Type serviceType, object implementationInstance) { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Type service, System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Func implementationFactory) where TService : class { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(TService implementationInstance) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton() where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton() where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Singleton(System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } public override string ToString() { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient(System.Type service, System.Func implementationFactory) { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient(System.Type service, System.Type implementationType) { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient(System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient(System.Func implementationFactory) where TService : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient() where TService : class where TImplementation : class, TService { throw null; } + public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient() where TService : class where TImplementation : class, TService { throw null; } public static Microsoft.Extensions.DependencyInjection.ServiceDescriptor Transient(System.Func implementationFactory) where TService : class where TImplementation : class, TService { throw null; } } public enum ServiceLifetime @@ -127,24 +127,24 @@ public static void TryAdd(this Microsoft.Extensions.DependencyInjection.IService public static void TryAdd(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Collections.Generic.IEnumerable descriptors) { } public static void TryAddEnumerable(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceDescriptor descriptor) { } public static void TryAddEnumerable(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Collections.Generic.IEnumerable descriptors) { } - public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service) { } + public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type service) { } public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Func implementationFactory) { } - public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Type implementationType) { } - public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } + public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { } + public static void TryAddScoped<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { } - public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } - public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service) { } + public static void TryAddScoped(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } + public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type service) { } public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Func implementationFactory) { } - public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Type implementationType) { } - public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } + public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { } + public static void TryAddSingleton<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { } public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, TService instance) where TService : class { } - public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } - public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service) { } + public static void TryAddSingleton(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } + public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type service) { } public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Func implementationFactory) { } - public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, System.Type implementationType) { } - public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } + public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection, System.Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type implementationType) { } + public static void TryAddTransient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class { } public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where TService : class { } - public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } + public static void TryAddTransient(this Microsoft.Extensions.DependencyInjection.IServiceCollection collection) where TService : class where TImplementation : class, TService { } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs index c60ff37721cf..9e995de6a698 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -21,7 +21,7 @@ internal class ExpressionResolverBuilder : CallSiteVisitor internal static readonly MethodInfo MonitorEnterMethodInfo = GetMethodInfo>((lockObj, lockTaken) => Monitor.Enter(lockObj, ref lockTaken)); internal static readonly MethodInfo MonitorExitMethodInfo = GetMethodInfo>(lockObj => Monitor.Exit(lockObj)); - internal static readonly MethodInfo ArrayEmptyMethodInfo = typeof(Array).GetMethod(nameof(Array.Empty)); + private static readonly MethodInfo ArrayEmptyMethodInfo = typeof(Array).GetMethod(nameof(Array.Empty)); private static readonly ParameterExpression ScopeParameter = Expression.Parameter(typeof(ServiceProviderEngineScope)); @@ -132,8 +132,8 @@ protected override Expression VisitIEnumerable(IEnumerableCallSite callSite, obj { if (callSite.ServiceCallSites.Length == 0) { - return Expression.Constant(ArrayEmptyMethodInfo - .MakeGenericMethod(callSite.ItemType) + return Expression.Constant( + GetArrayEmptyMethodInfo(callSite.ItemType) .Invoke(obj: null, parameters: Array.Empty())); } @@ -154,6 +154,11 @@ protected override Expression VisitDisposeCache(ServiceCallSite callSite, object VisitCallSiteMain(callSite, context)); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Calling Array.Empty() is safe since the T doesn't have linker annotations.")] + internal static MethodInfo GetArrayEmptyMethodInfo(Type itemType) => + ArrayEmptyMethodInfo.MakeGenericMethod(itemType); + private Expression TryCaptureDisposable(ServiceCallSite callSite, ParameterExpression scope, Expression service) { if (!callSite.CaptureDisposable) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs index 06288b46704d..f4b5ca964edc 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -213,11 +212,10 @@ protected override object VisitIEnumerable(IEnumerableCallSite enumerableCallSit { if (enumerableCallSite.ServiceCallSites.Length == 0) { - argument.Generator.Emit(OpCodes.Call, ExpressionResolverBuilder.ArrayEmptyMethodInfo.MakeGenericMethod(enumerableCallSite.ItemType)); + argument.Generator.Emit(OpCodes.Call, ExpressionResolverBuilder.GetArrayEmptyMethodInfo(enumerableCallSite.ItemType)); } else { - // var array = new ItemType[]; // array[0] = [Create argument0]; // array[1] = [Create argument1]; diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.cs b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.cs index 2d573c554e98..ff5578976a5e 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.DependencyInjection { public static partial class ServiceCollectionHostedServiceExtensions { - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddHostedService(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where THostedService : class, Microsoft.Extensions.Hosting.IHostedService { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddHostedService<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] THostedService>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where THostedService : class, Microsoft.Extensions.Hosting.IHostedService { throw null; } public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddHostedService(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func implementationFactory) where THostedService : class, Microsoft.Extensions.Hosting.IHostedService { throw null; } } } diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj index e651cdd660c9..4bdb11c052a4 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -5,6 +5,8 @@ + + diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs index d7230602169a..319806f2ae8e 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs @@ -8,10 +8,10 @@ public static partial class HttpClientBuilderExtensions public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpMessageHandler(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Func configureHandler) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpMessageHandler(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Func configureHandler) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpMessageHandler(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) where THandler : System.Net.Http.DelegatingHandler { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) where TClient : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Func factory) where TClient : class { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Func factory) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddTypedClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder ConfigureHttpClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Action configureClient) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder ConfigureHttpClient(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Action configureClient) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder ConfigureHttpMessageHandlerBuilder(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Action configureBuilder) { throw null; } @@ -28,20 +28,20 @@ public static partial class HttpClientFactoryServiceCollectionExtensions public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } + public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } } @@ -76,7 +76,7 @@ public partial interface IHttpMessageHandlerBuilderFilter { System.Action Configure(System.Action next); } - public partial interface ITypedHttpClientFactory + public partial interface ITypedHttpClientFactory<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TClient> { TClient CreateClient(System.Net.Http.HttpClient httpClient); } diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj index d0551567b5ec..24bab7c79b7b 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj @@ -4,6 +4,8 @@ + + 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 0ffa7866b579..80e365a65753 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 @@ -10,8 +10,8 @@ public static partial class ConsoleLoggerExtensions { public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } 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 AddConsoleFormatter<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(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<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(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; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj index f56ed2cc9d0b..048eb0459608 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj @@ -5,6 +5,8 @@ + + From f4efb11817d97535aa947855fe66ff4622e030e6 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 10 Aug 2020 15:12:58 -0700 Subject: [PATCH 373/755] Disable SB test (#40628) --- .../System.Runtime/tests/System/Text/StringBuilderTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs b/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs index 0d2489c2030a..493a0594142e 100644 --- a/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs @@ -2231,6 +2231,7 @@ public static void EqualsIgnoresMaxCapacity() Assert.True(sb1.Equals(sb2)); } + [ActiveIssue("https://github.com/dotnet/runtime/issues/40625")] // Hangs expanding the SB [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public static unsafe void FailureOnLargeString() { From e5779655a7b0f885cc8870a0c6f8502fc3d00dc5 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Mon, 10 Aug 2020 23:34:07 +0100 Subject: [PATCH 374/755] Fix DelayPromise constructor race condition (#40356) --- .../System.Private.CoreLib/src/System/Threading/Tasks/Task.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 3b34af008a2b..13b49140ff04 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 @@ -5382,9 +5382,9 @@ internal DelayPromise(int millisecondsDelay) if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout { _timer = new TimerQueueTimer(state => ((DelayPromise)state!).CompleteTimedOut(), this, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false); - if (IsCanceled) + if (IsCompleted) { - // Handle rare race condition where cancellation occurs prior to our having created and stored the timer, in which case + // Handle rare race condition where completion occurs prior to our having created and stored the timer, in which case // the timer won't have been cleaned up appropriately. This call to close might race with the Cleanup call to Close, // but Close is thread-safe and will be a nop if it's already been closed. _timer.Close(); From 0cd114272fd31896dba3746a105dab64b2be98cb Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 11 Aug 2020 00:34:31 +0200 Subject: [PATCH 375/755] Don't call user operator for null check of HttpMethod value (#40306) --- .../System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs index 83ee09fd1781..5e1d9bb25f1b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs @@ -167,7 +167,7 @@ public override string ToString() [MemberNotNull(nameof(_version))] private void InitializeValues(HttpMethod method, Uri? requestUri) { - if (method == null) + if (method is null) { throw new ArgumentNullException(nameof(method)); } From 8e85874b8ea85b19de486a135151d36121ea68fb Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Mon, 10 Aug 2020 15:55:00 -0700 Subject: [PATCH 376/755] Update using-dotnet-cli.md (#40580) Fixes "error NU1102: Unable to find package Microsoft.WindowsDesktop.App.Runtime.win-x64 with version (= 5.0.0-dev)" --- docs/workflow/using-dotnet-cli.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/workflow/using-dotnet-cli.md b/docs/workflow/using-dotnet-cli.md index 68cadd5bf4f8..8090f0eddc2c 100644 --- a/docs/workflow/using-dotnet-cli.md +++ b/docs/workflow/using-dotnet-cli.md @@ -58,13 +58,16 @@ Please run `dotnet new console` in the app folder and update the created `.cspro Exe net5.0 win-x64 - 5.0.0-dev + + + + ``` -**You have to set the correct values for `RuntimeIdentifier` (RI), `RuntimeFrameworkVersion` and versions of both packages.** +**You have to set the correct values for `RuntimeIdentifier` (RI) and `RuntimeFrameworkVersion`.** You can generally figure that out by looking at the packages you found in your output. In our example you will see there is a package with the name `Microsoft.NETCore.App.Runtime.win-x64.5.0.0-dev.nupkg` From b9557bc4e73cf6a25d5674b5704f02b2cabde023 Mon Sep 17 00:00:00 2001 From: Prashanth Govindarajan Date: Mon, 10 Aug 2020 16:48:35 -0700 Subject: [PATCH 377/755] Widen ascii to utf16 (#39510) * WidenAsciiToUtf16 * sq * Address nits --- .../src/System/Text/ASCIIUtility.cs | 112 ++++++++++++++---- 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 76075a5e66dc..0dde692dc68d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -1478,11 +1478,11 @@ public static unsafe nuint WidenAsciiToUtf16(byte* pAsciiBuffer, char* pUtf16Buf // pmovmskb which we know are optimized, and (b) we can avoid downclocking the processor while // this method is running. - if (Sse2.IsSupported) + if (BitConverter.IsLittleEndian && (Sse2.IsSupported || AdvSimd.Arm64.IsSupported)) { if (elementCount >= 2 * (uint)Unsafe.SizeOf>()) { - currentOffset = WidenAsciiToUtf16_Sse2(pAsciiBuffer, pUtf16Buffer, elementCount); + currentOffset = WidenAsciiToUtf16_Intrinsified(pAsciiBuffer, pUtf16Buffer, elementCount); } } else if (Vector.IsHardwareAccelerated) @@ -1597,7 +1597,18 @@ public static unsafe nuint WidenAsciiToUtf16(byte* pAsciiBuffer, char* pUtf16Buf goto Finish; } - private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUtf16Buffer, nuint elementCount) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ContainsNonAsciiByte(Vector128 value) + { + if (!AdvSimd.Arm64.IsSupported) + { + throw new PlatformNotSupportedException(); + } + value = AdvSimd.Arm64.MaxPairwise(value, value); + return (value.AsUInt64().ToScalar() & 0x8080808080808080) != 0; + } + + private static unsafe nuint WidenAsciiToUtf16_Intrinsified(byte* pAsciiBuffer, char* pUtf16Buffer, nuint elementCount) { // JIT turns the below into constants @@ -1608,7 +1619,7 @@ private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUt // jumps as much as possible in the optimistic case of "all ASCII". If we see non-ASCII // data, we jump out of the hot paths to targets at the end of the method. - Debug.Assert(Sse2.IsSupported); + Debug.Assert(Sse2.IsSupported || AdvSimd.Arm64.IsSupported); Debug.Assert(BitConverter.IsLittleEndian); Debug.Assert(elementCount >= 2 * SizeOfVector128); @@ -1617,16 +1628,28 @@ private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUt Vector128 asciiVector; Vector128 utf16FirstHalfVector; - uint mask; + bool containsNonAsciiBytes; // First, perform an unaligned read of the first part of the input buffer. - asciiVector = Sse2.LoadVector128(pAsciiBuffer); // unaligned load - mask = (uint)Sse2.MoveMask(asciiVector); + if (Sse2.IsSupported) + { + asciiVector = Sse2.LoadVector128(pAsciiBuffer); // unaligned load + containsNonAsciiBytes = (uint)Sse2.MoveMask(asciiVector) != 0; + } + else if (AdvSimd.Arm64.IsSupported) + { + asciiVector = AdvSimd.LoadVector128(pAsciiBuffer); + containsNonAsciiBytes = ContainsNonAsciiByte(asciiVector); + } + else + { + throw new PlatformNotSupportedException(); + } // If there's non-ASCII data in the first 8 elements of the vector, there's nothing we can do. - if ((byte)mask != 0) + if (containsNonAsciiBytes) { return 0; } @@ -1635,8 +1658,20 @@ private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUt Vector128 zeroVector = Vector128.Zero; - utf16FirstHalfVector = Sse2.UnpackLow(asciiVector, zeroVector); - Sse2.Store((byte*)pUtf16Buffer, utf16FirstHalfVector); // unaligned + if (Sse2.IsSupported) + { + utf16FirstHalfVector = Sse2.UnpackLow(asciiVector, zeroVector); + Sse2.Store((byte*)pUtf16Buffer, utf16FirstHalfVector); // unaligned + } + else if (AdvSimd.IsSupported) + { + utf16FirstHalfVector = AdvSimd.ZeroExtendWideningLower(asciiVector.GetLower()).AsByte(); + AdvSimd.Store((byte*)pUtf16Buffer, utf16FirstHalfVector); // unaligned + } + else + { + throw new PlatformNotSupportedException(); + } // Calculate how many elements we wrote in order to get pOutputBuffer to its next alignment // point, then use that as the base offset going forward. Remember the >> 1 to account for @@ -1658,20 +1693,45 @@ private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUt { // In a loop, perform an unaligned read, widen to two vectors, then aligned write the two vectors. - asciiVector = Sse2.LoadVector128(pAsciiBuffer + currentOffset); // unaligned load - mask = (uint)Sse2.MoveMask(asciiVector); + if (Sse2.IsSupported) + { + asciiVector = Sse2.LoadVector128(pAsciiBuffer + currentOffset); // unaligned load + containsNonAsciiBytes = (uint)Sse2.MoveMask(asciiVector) != 0; + } + else if (AdvSimd.Arm64.IsSupported) + { + asciiVector = AdvSimd.LoadVector128(pAsciiBuffer + currentOffset); + containsNonAsciiBytes = ContainsNonAsciiByte(asciiVector); + } + else + { + throw new PlatformNotSupportedException(); + } - if (mask != 0) + if (containsNonAsciiBytes) { // non-ASCII byte somewhere goto NonAsciiDataSeenInInnerLoop; } - Vector128 low = Sse2.UnpackLow(asciiVector, zeroVector); - Sse2.StoreAligned((byte*)pCurrentWriteAddress, low); + if (Sse2.IsSupported) + { + Vector128 low = Sse2.UnpackLow(asciiVector, zeroVector); + Sse2.StoreAligned((byte*)pCurrentWriteAddress, low); - Vector128 high = Sse2.UnpackHigh(asciiVector, zeroVector); - Sse2.StoreAligned((byte*)pCurrentWriteAddress + SizeOfVector128, high); + Vector128 high = Sse2.UnpackHigh(asciiVector, zeroVector); + Sse2.StoreAligned((byte*)pCurrentWriteAddress + SizeOfVector128, high); + } + else if (AdvSimd.Arm64.IsSupported) + { + Vector128 low = AdvSimd.ZeroExtendWideningLower(asciiVector.GetLower()); + Vector128 high = AdvSimd.ZeroExtendWideningUpper(asciiVector); + AdvSimd.Arm64.StorePair((ushort*)pCurrentWriteAddress, low, high); + } + else + { + throw new PlatformNotSupportedException(); + } currentOffset += SizeOfVector128; pCurrentWriteAddress += SizeOfVector128; @@ -1685,11 +1745,23 @@ private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUt // Can we at least widen the first part of the vector? - if ((byte)mask == 0) + if (!containsNonAsciiBytes) { // First part was all ASCII, widen - utf16FirstHalfVector = Sse2.UnpackLow(asciiVector, zeroVector); - Sse2.StoreAligned((byte*)(pUtf16Buffer + currentOffset), utf16FirstHalfVector); + if (Sse2.IsSupported) + { + utf16FirstHalfVector = Sse2.UnpackLow(asciiVector, zeroVector); + Sse2.StoreAligned((byte*)(pUtf16Buffer + currentOffset), utf16FirstHalfVector); + } + else if (AdvSimd.Arm64.IsSupported) + { + Vector128 lower = AdvSimd.ZeroExtendWideningLower(asciiVector.GetLower()); + AdvSimd.Store((ushort*)(pUtf16Buffer + currentOffset), lower); + } + else + { + throw new PlatformNotSupportedException(); + } currentOffset += SizeOfVector128 / 2; } From 095cb1637f4e51ecf4e3d068dd56eb296979c075 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 10 Aug 2020 19:54:22 -0400 Subject: [PATCH 378/755] [runtime] If the initial pinvoke lookup fails, emit some code inside the managed-to-native wrapper to retry to lookup on every call until it succeeds. (#40153) * [runtime] If the initial pinvoke lookup fails, emit some code inside the managed-to-native wrapper to retry to lookup on every call until it succeeds. Add a cache to prevent further lookups. This is needed on netcore where pinvoke resolver callbacks can be added any time. * Fix AOT support. * Remove debug printf. * Fix test failures. * Fix a c++-ism. --- src/mono/mono/cil/cil-opcodes.xml | 2 + src/mono/mono/cil/opcode.def | 2 + src/mono/mono/metadata/jit-icall-reg.h | 1 + src/mono/mono/metadata/marshal-ilgen.c | 62 ++++++++++++++++++++------ src/mono/mono/metadata/marshal.c | 21 ++++++--- src/mono/mono/metadata/marshal.h | 4 ++ src/mono/mono/mini/aot-compiler.c | 4 +- src/mono/mono/mini/aot-runtime.c | 3 +- src/mono/mono/mini/interp/transform.c | 12 +++++ src/mono/mono/mini/method-to-ir.c | 18 ++++++++ src/mono/mono/mini/mini-runtime.c | 5 +++ src/mono/mono/mini/patch-info.h | 3 ++ 12 files changed, 116 insertions(+), 21 deletions(-) diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index 365b258eaf3d..50b70144d16a 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -325,4 +325,6 @@ + + diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index 43722f6d3282..a39b315bac5e 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -325,6 +325,8 @@ OPDEF(CEE_MONO_LDPTR_PROFILER_ALLOCATION_COUNT, "mono_ldptr_profiler_allocation_ OPDEF(CEE_MONO_LD_DELEGATE_METHOD_PTR, "mono_ld_delegate_method_ptr", Pop1, PushI, InlineNone, 0, 2, 0xF0, 0x1E, NEXT) OPDEF(CEE_MONO_RETHROW, "mono_rethrow", PopRef, Push0, InlineNone, 0, 2, 0xF0, 0x1F, ERROR) OPDEF(CEE_MONO_GET_SP, "mono_get_sp", Pop0, PushI, InlineNone, 0, 2, 0xF0, 0x20, NEXT) +OPDEF(CEE_MONO_METHODCONST, "mono_methodconst", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x21, NEXT) +OPDEF(CEE_MONO_PINVOKE_ADDR_CACHE, "mono_pinvoke_addr_cache", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x22, NEXT) #ifndef OPALIAS #define _MONO_CIL_OPALIAS_DEFINED_ #define OPALIAS(a,s,r) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 3abbdf45da4d..a9bff58883d7 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -340,6 +340,7 @@ MONO_JIT_ICALL (ves_icall_runtime_class_init) \ MONO_JIT_ICALL (ves_icall_string_alloc) \ MONO_JIT_ICALL (ves_icall_string_new_wrapper) \ MONO_JIT_ICALL (ves_icall_thread_finish_async_abort) \ +MONO_JIT_ICALL (mono_marshal_lookup_pinvoke) \ \ MONO_JIT_ICALL (count) \ diff --git a/src/mono/mono/metadata/marshal-ilgen.c b/src/mono/mono/metadata/marshal-ilgen.c index 2235a8eb3394..df3cfb315035 100644 --- a/src/mono/mono/metadata/marshal-ilgen.c +++ b/src/mono/mono/metadata/marshal-ilgen.c @@ -2007,6 +2007,7 @@ emit_native_wrapper_ilgen (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSi MonoClass *klass; int i, argnum, *tmp_locals; int type, param_shift = 0; + int func_addr_local = -1; gboolean need_gc_safe = FALSE; GCSafeTransitionBuilder gc_safe_transition_builder; @@ -2051,8 +2052,40 @@ emit_native_wrapper_ilgen (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSi mono_mb_add_local (mb, sig->ret); } - if (need_gc_safe) { - gc_safe_transition_builder_add_locals (&gc_safe_transition_builder); + if (need_gc_safe) + gc_safe_transition_builder_add_locals (&gc_safe_transition_builder); + + if (!func && !aot && !func_param && !MONO_CLASS_IS_IMPORT (mb->method->klass)) { + /* + * On netcore, its possible to register pinvoke resolvers at runtime, so + * a pinvoke lookup can fail, and then succeed later. So if the + * original lookup failed, do a lookup every time until it + * succeeds. + * This adds some overhead, but only when the pinvoke lookup + * was not initially successful. + * FIXME: AOT case + */ + func_addr_local = mono_mb_add_local (mb, int_type); + + int cache_local = mono_mb_add_local (mb, int_type); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_op (mb, CEE_MONO_PINVOKE_ADDR_CACHE, &piinfo->method); + mono_mb_emit_stloc (mb, cache_local); + + mono_mb_emit_ldloc (mb, cache_local); + mono_mb_emit_byte (mb, CEE_LDIND_I); + int pos = mono_mb_emit_branch (mb, CEE_BRTRUE); + + mono_mb_emit_ldloc (mb, cache_local); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_op (mb, CEE_MONO_METHODCONST, &piinfo->method); + mono_mb_emit_icall (mb, mono_marshal_lookup_pinvoke); + mono_mb_emit_byte (mb, CEE_STIND_I); + + mono_mb_patch_branch (mb, pos); + mono_mb_emit_ldloc (mb, cache_local); + mono_mb_emit_byte (mb, CEE_LDIND_I); + mono_mb_emit_stloc (mb, func_addr_local); } /* @@ -2123,22 +2156,23 @@ emit_native_wrapper_ilgen (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSi g_assert_not_reached (); #endif } else { - if (aot) { - /* Reuse the ICALL_ADDR opcode for pinvokes too */ - mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); - mono_mb_emit_op (mb, CEE_MONO_ICALL_ADDR, &piinfo->method); - if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) { - mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); - mono_mb_emit_byte (mb, CEE_MONO_SAVE_LAST_ERROR); - } - mono_mb_emit_calli (mb, csig); + if (func_addr_local != -1) { + mono_mb_emit_ldloc (mb, func_addr_local); } else { - if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) { + if (aot) { + /* Reuse the ICALL_ADDR opcode for pinvokes too */ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); - mono_mb_emit_byte (mb, CEE_MONO_SAVE_LAST_ERROR); + mono_mb_emit_op (mb, CEE_MONO_ICALL_ADDR, &piinfo->method); } - mono_mb_emit_native_call (mb, csig, func); } + if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) { + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_byte (mb, CEE_MONO_SAVE_LAST_ERROR); + } + if (func_addr_local != -1 || aot) + mono_mb_emit_calli (mb, csig); + else + mono_mb_emit_native_call (mb, csig, func); } if (MONO_TYPE_ISSTRUCT (sig->ret)) { diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 91358142a40b..55f3c95673e0 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -255,6 +255,7 @@ mono_marshal_init (void) register_icall (mono_threads_attach_coop, mono_icall_sig_ptr_ptr_ptr, TRUE); register_icall (mono_threads_detach_coop, mono_icall_sig_void_ptr_ptr, TRUE); register_icall (mono_marshal_get_type_object, mono_icall_sig_object_ptr, TRUE); + register_icall (mono_marshal_lookup_pinvoke, mono_icall_sig_ptr_ptr, FALSE); mono_cominterop_init (); mono_remoting_init (); @@ -3683,7 +3684,7 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, * In AOT mode and embedding scenarios, it is possible that the icall is not * registered in the runtime doing the AOT compilation. */ - if (!piinfo->addr && !aot) { + if (!pinvoke && !piinfo->addr && !aot) { /* if there's no code but the error isn't set, just use a fairly generic exception. */ if (is_ok (emitted_error)) mono_error_set_generic_error (emitted_error, "System", "MissingMethodException", ""); @@ -3702,8 +3703,6 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, return res; } - g_assert (is_ok (emitted_error)); - /* internal calls: we simply push all arguments and call the method (no conversions) */ if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) { if (sig->hasthis) @@ -3732,8 +3731,6 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, } g_assert (pinvoke); - if (!aot) - g_assert (piinfo->addr); csig = mono_metadata_signature_dup_full (get_method_image (method), sig); mono_marshal_set_callconv_from_modopt (method, csig, FALSE); @@ -6755,6 +6752,20 @@ mono_marshal_get_type_object (MonoClass *klass) return result; } +gpointer +mono_marshal_lookup_pinvoke (MonoMethod *method) +{ + ERROR_DECL (error); + gpointer addr; + + g_assert (method); + addr = mono_lookup_pinvoke_call_internal (method, error); + if (!addr) + g_assert (!is_ok (error)); + mono_error_set_pending_exception (error); + return addr; +} + void mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func, gboolean aot, gboolean check_exceptions, gboolean func_param, gboolean skip_gc_trans) { diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index 0d35659368cb..18e237363459 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -605,6 +605,10 @@ mono_marshal_need_free (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec ICALL_EXTERN_C MonoObject* mono_marshal_get_type_object (MonoClass *klass); +ICALL_EXTERN_C +gpointer +mono_marshal_lookup_pinvoke (MonoMethod *method); + ICALL_EXPORT guint32 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error (void); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 5e8d1d3ab734..63f6d12930b7 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6605,6 +6605,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint case MONO_PATCH_INFO_ICALL_ADDR_CALL: case MONO_PATCH_INFO_METHOD_RGCTX: case MONO_PATCH_INFO_METHOD_CODE_SLOT: + case MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE: encode_method_ref (acfg, patch_info->data.method, p, &p); break; case MONO_PATCH_INFO_AOT_JIT_INFO: @@ -8484,7 +8485,8 @@ can_encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info) case MONO_PATCH_INFO_METHOD: case MONO_PATCH_INFO_METHOD_FTNDESC: case MONO_PATCH_INFO_METHODCONST: - case MONO_PATCH_INFO_METHOD_CODE_SLOT: { + case MONO_PATCH_INFO_METHOD_CODE_SLOT: + case MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE: { MonoMethod *method = patch_info->data.method; return can_encode_method (acfg, method); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index b42c76efba75..64ef649bf694 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -3854,7 +3854,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin case MONO_PATCH_INFO_ICALL_ADDR: case MONO_PATCH_INFO_ICALL_ADDR_CALL: case MONO_PATCH_INFO_METHOD_RGCTX: - case MONO_PATCH_INFO_METHOD_CODE_SLOT: { + case MONO_PATCH_INFO_METHOD_CODE_SLOT: + case MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE: { MethodRef ref; gboolean res; diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index b81d5f90742c..a0fd6c0b0689 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -6125,12 +6125,24 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, } case CEE_MONO_LDPTR: case CEE_MONO_CLASSCONST: + case CEE_MONO_METHODCONST: token = read32 (td->ip + 1); td->ip += 5; interp_add_ins (td, MINT_MONO_LDPTR); td->last_ins->data [0] = get_data_item_index (td, mono_method_get_wrapper_data (method, token)); PUSH_SIMPLE_TYPE (td, STACK_TYPE_I); break; + case CEE_MONO_PINVOKE_ADDR_CACHE: { + token = read32 (td->ip + 1); + td->ip += 5; + interp_add_ins (td, MINT_MONO_LDPTR); + g_assert (method->wrapper_type != MONO_WRAPPER_NONE); + /* This is a memory slot used by the wrapper */ + gpointer addr = mono_domain_alloc0 (td->rtm->domain, sizeof (gpointer)); + td->last_ins->data [0] = get_data_item_index (td, addr); + PUSH_SIMPLE_TYPE (td, STACK_TYPE_I); + break; + } case CEE_MONO_OBJADDR: CHECK_STACK (td, 1); ++td->ip; diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 6d1667ffcb02..9b7fc50f440c 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -10752,6 +10752,24 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; inline_costs += CALL_COST * MIN(10, num_calls++); break; + case MONO_CEE_MONO_METHODCONST: + g_assert (method->wrapper_type != MONO_WRAPPER_NONE); + EMIT_NEW_METHODCONST (cfg, ins, mono_method_get_wrapper_data (method, token)); + *sp++ = ins; + break; + case MONO_CEE_MONO_PINVOKE_ADDR_CACHE: { + g_assert (method->wrapper_type != MONO_WRAPPER_NONE); + MonoMethod *pinvoke_method = (MonoMethod*)mono_method_get_wrapper_data (method, token); + /* This is a memory slot used by the wrapper */ + if (cfg->compile_aot) { + EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE, pinvoke_method); + } else { + gpointer addr = mono_domain_alloc0 (cfg->domain, sizeof (gpointer)); + EMIT_NEW_PCONST (cfg, ins, addr); + } + *sp++ = ins; + break; + } case MONO_CEE_MONO_NOT_TAKEN: g_assert (method->wrapper_type != MONO_WRAPPER_NONE); cfg->cbb->out_of_line = TRUE; diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index caf65d40e88a..14ea80746a3a 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1239,6 +1239,7 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_METHOD_CODE_SLOT: case MONO_PATCH_INFO_AOT_JIT_INFO: + case MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE: return hash | (gssize)ji->data.target; case MONO_PATCH_INFO_GSHAREDVT_CALL: return hash | (gssize)ji->data.gsharedvt->method; @@ -1444,6 +1445,10 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = code_slot; break; } + case MONO_PATCH_INFO_METHOD_PINVOKE_ADDR_CACHE: { + target = mono_domain_alloc0 (domain, sizeof (gpointer)); + break; + } case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: target = (gpointer)&mono_polling_required; break; diff --git a/src/mono/mono/mini/patch-info.h b/src/mono/mono/mini/patch-info.h index 3adcde561526..6807f92b5c64 100644 --- a/src/mono/mono/mini/patch-info.h +++ b/src/mono/mono/mini/patch-info.h @@ -82,3 +82,6 @@ PATCH_INFO(SPECIFIC_TRAMPOLINES_GOT_SLOTS_BASE, "specific_trampolines_got_slots_ */ PATCH_INFO(R8_GOT, "r8_got") PATCH_INFO(R4_GOT, "r4_got") + +/* MonoMethod* -> the address of a memory slot which is used to cache the pinvoke address */ +PATCH_INFO(METHOD_PINVOKE_ADDR_CACHE, "pinvoke_addr_cache") From 8a734ff2b8bac913c0fa4d3954ba1f335799bc0c Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Mon, 10 Aug 2020 17:02:26 -0700 Subject: [PATCH 379/755] Remove unused locals in System.ServiceProcess.ServiceController (#39640) Remove unused locals and private methods in System.ServiceProcess.ServiceController. This fixes a part of #30457. --- .../tests/ServiceControllerTests.cs | 32 +------------------ .../tests/TestServiceProvider.cs | 1 - 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceControllerTests.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceControllerTests.cs index 3638b80ac626..f03e42478898 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceControllerTests.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceControllerTests.cs @@ -15,7 +15,6 @@ public class ServiceControllerTests : IDisposable private static readonly Lazy s_isElevated = new Lazy(() => AdminHelpers.IsProcessElevated()); protected static bool IsProcessElevated => s_isElevated.Value; - private const int ExpectedDependentServiceCount = 3; private bool _disposed; public ServiceControllerTests() @@ -58,7 +57,7 @@ public void ConstructWithMachineName() var controller = new ServiceController(_testService.TestServiceName, _testService.TestMachineName); AssertExpectedProperties(controller); - AssertExtensions.Throws(null, () => { var c = new ServiceController(_testService.TestServiceName, ""); }); + AssertExtensions.Throws(null, () => { new ServiceController(_testService.TestServiceName, ""); }); } [ConditionalFact(nameof(IsProcessElevated))] @@ -184,34 +183,5 @@ public void Dispose() _disposed = true; } } - - private static ServiceController AssertHasDependent(ServiceController controller, string serviceName, string displayName) - { - var dependent = FindService(controller.DependentServices, serviceName, displayName); - Assert.NotNull(dependent); - - return dependent; - } - - private static ServiceController AssertDependsOn(ServiceController controller, string serviceName, string displayName) - { - var dependency = FindService(controller.ServicesDependedOn, serviceName, displayName); - Assert.NotNull(dependency); - - return dependency; - } - - private static ServiceController FindService(ServiceController[] services, string serviceName, string displayName) - { - foreach (ServiceController service in services) - { - if (service.ServiceName == serviceName && service.DisplayName == displayName) - { - return service; - } - } - - return null; - } } } diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/TestServiceProvider.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/TestServiceProvider.cs index 1be86a61785d..54e6ee33942a 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/TestServiceProvider.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/TestServiceProvider.cs @@ -106,7 +106,6 @@ private void CreateTestServices() testServiceInstaller.ServicesDependedOn = new string[] { _dependentServices.TestServiceName }; } - var comparer = PlatformDetection.IsNetFramework ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; // .NET Framework upper cases the name string processName = Process.GetCurrentProcess().MainModule.FileName; string entryPointName = typeof(TestService).Assembly.Location; string arguments = TestServiceName; From 71283319d0bf0f8c9132e117419fc2294342b510 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 11 Aug 2020 01:09:14 +0100 Subject: [PATCH 380/755] Type.IsAssignableTo (#40326) * IsAssignableTo * ifdef mono C change * Add Jit optimization * Add [Intrinsic] attribute * Add tests * More tests * Add null test --- .../Collections/Generic/ComparerHelpers.cs | 2 +- src/coreclr/src/jit/compiler.h | 1 + src/coreclr/src/jit/importer.cpp | 89 +++++--- src/coreclr/src/jit/namedintrinsiclist.h | 1 + .../src/System/Diagnostics/StackTrace.cs | 4 +- .../System.Private.CoreLib/src/System/Type.cs | 3 + .../tests/TypeDerivedTests.cs | 15 ++ .../System.Reflection/tests/TypeInfoTests.cs | 22 +- .../System.Runtime/ref/System.Runtime.cs | 1 + .../System/Reflection/TypeDelegatorTests.cs | 11 + src/mono/mono/metadata/reflection.c | 4 + .../Reflection/Emit/TypeBuilder.Mono.cs | 6 +- .../TypeIntrinsics.IsAssignableTo.cs | 190 ++++++++++++++++++ .../JIT/Intrinsics/TypeIntrinsics_r.csproj | 1 + .../JIT/Intrinsics/TypeIntrinsics_ro.csproj | 1 + 15 files changed, 310 insertions(+), 41 deletions(-) create mode 100644 src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ComparerHelpers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ComparerHelpers.cs index 7a49fad02133..1fb54677d0c5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ComparerHelpers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ComparerHelpers.cs @@ -126,7 +126,7 @@ internal static object CreateDefaultEqualityComparer(Type type) result = new ByteEqualityComparer(); } // If T implements IEquatable return a GenericEqualityComparer - else if (typeof(IEquatable<>).MakeGenericType(type).IsAssignableFrom(type)) + else if (type.IsAssignableTo(typeof(IEquatable<>).MakeGenericType(type))) { result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer), runtimeType); } diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 22ceceea5ae0..1c6f87851f52 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3730,6 +3730,7 @@ class Compiler void impImportLeave(BasicBlock* block); void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr); + GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom); GenTree* impIntrinsic(GenTree* newobjThis, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 463054b9b989..2823851cd094 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -4126,44 +4126,19 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_IsAssignableFrom: { - // Optimize patterns like: - // - // typeof(TTo).IsAssignableFrom(typeof(TTFrom)) - // valueTypeVar.GetType().IsAssignableFrom(typeof(TTFrom)) - // - // to true/false GenTree* typeTo = impStackTop(1).val; GenTree* typeFrom = impStackTop(0).val; - if (typeTo->IsCall() && typeFrom->IsCall()) - { - // make sure both arguments are `typeof()` - CORINFO_METHOD_HANDLE hTypeof = eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE); - if ((typeTo->AsCall()->gtCallMethHnd == hTypeof) && (typeFrom->AsCall()->gtCallMethHnd == hTypeof)) - { - CORINFO_CLASS_HANDLE hClassTo = - gtGetHelperArgClassHandle(typeTo->AsCall()->gtCallArgs->GetNode()); - CORINFO_CLASS_HANDLE hClassFrom = - gtGetHelperArgClassHandle(typeFrom->AsCall()->gtCallArgs->GetNode()); - - if (hClassTo == NO_CLASS_HANDLE || hClassFrom == NO_CLASS_HANDLE) - { - break; - } + retNode = impTypeIsAssignable(typeTo, typeFrom); + break; + } - TypeCompareState castResult = info.compCompHnd->compareTypesForCast(hClassFrom, hClassTo); - if (castResult == TypeCompareState::May) - { - // requires runtime check - // e.g. __Canon, COMObjects, Nullable - break; - } + case NI_System_Type_IsAssignableTo: + { + GenTree* typeTo = impStackTop(0).val; + GenTree* typeFrom = impStackTop(1).val; - retNode = gtNewIconNode((castResult == TypeCompareState::Must) ? 1 : 0); - impPopStack(); // drop both CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE calls - impPopStack(); - } - } + retNode = impTypeIsAssignable(typeTo, typeFrom); break; } @@ -4368,6 +4343,50 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, return retNode; } +GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) +{ + // Optimize patterns like: + // + // typeof(TTo).IsAssignableFrom(typeof(TTFrom)) + // valueTypeVar.GetType().IsAssignableFrom(typeof(TTFrom)) + // typeof(TTFrom).IsAssignableTo(typeof(TTo)) + // typeof(TTFrom).IsAssignableTo(valueTypeVar.GetType()) + // + // to true/false + + if (typeTo->IsCall() && typeFrom->IsCall()) + { + // make sure both arguments are `typeof()` + CORINFO_METHOD_HANDLE hTypeof = eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE); + if ((typeTo->AsCall()->gtCallMethHnd == hTypeof) && (typeFrom->AsCall()->gtCallMethHnd == hTypeof)) + { + CORINFO_CLASS_HANDLE hClassTo = gtGetHelperArgClassHandle(typeTo->AsCall()->gtCallArgs->GetNode()); + CORINFO_CLASS_HANDLE hClassFrom = gtGetHelperArgClassHandle(typeFrom->AsCall()->gtCallArgs->GetNode()); + + if (hClassTo == NO_CLASS_HANDLE || hClassFrom == NO_CLASS_HANDLE) + { + return nullptr; + } + + TypeCompareState castResult = info.compCompHnd->compareTypesForCast(hClassFrom, hClassTo); + if (castResult == TypeCompareState::May) + { + // requires runtime check + // e.g. __Canon, COMObjects, Nullable + return nullptr; + } + + GenTreeIntCon* retNode = gtNewIconNode((castResult == TypeCompareState::Must) ? 1 : 0); + impPopStack(); // drop both CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE calls + impPopStack(); + + return retNode; + } + } + + return nullptr; +} + GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, @@ -4614,6 +4633,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_IsAssignableFrom; } + else if (strcmp(methodName, "IsAssignableTo") == 0) + { + result = NI_System_Type_IsAssignableTo; + } } } #if defined(TARGET_XARCH) || defined(TARGET_ARM64) diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h index bc84f851deac..8ab264e36061 100644 --- a/src/coreclr/src/jit/namedintrinsiclist.h +++ b/src/coreclr/src/jit/namedintrinsiclist.h @@ -39,6 +39,7 @@ enum NamedIntrinsic : unsigned short NI_System_GC_KeepAlive, NI_System_Type_get_IsValueType, NI_System_Type_IsAssignableFrom, + NI_System_Type_IsAssignableTo, // These are used by HWIntrinsics but are defined more generally // to allow dead code optimization and handle the recursion case diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs index b6d86eac806c..84cd6745f306 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs @@ -227,8 +227,8 @@ internal void ToString(TraceFormat traceFormat, StringBuilder sb) bool methodChanged = false; if (declaringType != null && declaringType.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false)) { - isAsync = typeof(IAsyncStateMachine).IsAssignableFrom(declaringType); - if (isAsync || typeof(IEnumerator).IsAssignableFrom(declaringType)) + isAsync = declaringType.IsAssignableTo(typeof(IAsyncStateMachine)); + if (isAsync || declaringType.IsAssignableTo(typeof(IEnumerator))) { methodChanged = TryResolveStateMachineMethod(ref mb, out declaringType); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index f1e7c35b754c..ca6c780e136c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -109,6 +109,9 @@ public virtual Type[] GetGenericParameterConstraints() public bool IsPrimitive => IsPrimitiveImpl(); protected abstract bool IsPrimitiveImpl(); public bool IsValueType { [Intrinsic] get => IsValueTypeImpl(); } + + [Intrinsic] + public bool IsAssignableTo([NotNullWhen(true)] Type? targetType) => targetType?.IsAssignableFrom(this) ?? false; protected virtual bool IsValueTypeImpl() => IsSubclassOf(typeof(ValueType)); public virtual bool IsSignatureType => false; diff --git a/src/libraries/System.Reflection/tests/TypeDerivedTests.cs b/src/libraries/System.Reflection/tests/TypeDerivedTests.cs index 5a2be15d5ef1..310caabe4b5d 100644 --- a/src/libraries/System.Reflection/tests/TypeDerivedTests.cs +++ b/src/libraries/System.Reflection/tests/TypeDerivedTests.cs @@ -25,5 +25,20 @@ public void IsAssignableFrom_NullUnderlyingSystemType() Assert.False(testType.IsAssignableFrom(compareType)); Assert.False(compareType.IsAssignableFrom(testType)); } + + [Fact] + public void IsAssignableTo_NullUnderlyingSystemType() + { + var testType = new TypeWithNullUnderlyingSystemType(); + Assert.Null(testType.UnderlyingSystemType); + Assert.True(testType.IsAssignableTo(testType)); + + Type compareType = typeof(int); + Assert.False(testType.IsAssignableTo(compareType)); + Assert.False(compareType.IsAssignableTo(testType)); + + Assert.False(testType.IsAssignableTo(null)); + Assert.False(typeof(object).IsAssignableTo(null)); + } } } diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index 3660d5cb5beb..e2198b092140 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -498,6 +498,7 @@ public void ImplementedInterfaces(Type type, Type[] expected) Assert.Equal(expected, implementedInterfaces); Assert.All(expected, ti => Assert.True(ti.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))); + Assert.All(expected, ti => Assert.True(type.GetTypeInfo().IsAssignableTo(ti.GetTypeInfo()))); } public static IEnumerable IsInstanceOfType_TestData() @@ -568,10 +569,13 @@ public void IsInstanceOfType(Type type, object o, bool expected) [InlineData(typeof(uint[]), typeof(int[]), true)] [InlineData(typeof(IList), typeof(int[]), true)] [InlineData(typeof(IList), typeof(int[]), true)] - public void IsAssignableFrom(Type type, Type c, bool expected) + public void IsAssignable(Type type, Type c, bool expected) { Assert.Equal(expected, type.GetTypeInfo().IsAssignableFrom(c)); Assert.Equal(expected, type.GetTypeInfo().IsAssignableFrom(c?.GetTypeInfo())); + + Assert.Equal(expected, c?.IsAssignableTo(type) ?? false); + Assert.Equal(expected, c?.GetTypeInfo().IsAssignableTo(type.GetTypeInfo()) ?? false); } class G where T : U @@ -581,7 +585,7 @@ class G where T : U static volatile object s_boxedInt32; [Fact] - public void IsAssignableFromNullable() + public void IsAssignableNullable() { Type nubInt = typeof(Nullable); Type intType = typeof(int); @@ -592,6 +596,8 @@ public void IsAssignableFromNullable() // Nullable is assignable from int Assert.True(nubInt.IsAssignableFrom(intType)); Assert.False(intType.IsAssignableFrom(nubInt)); + Assert.False(nubInt.IsAssignableTo(intType)); + Assert.True(intType.IsAssignableTo(nubInt)); Type nubOfT = nubInt.GetGenericTypeDefinition(); Type T = nubOfT.GetTypeInfo().GenericTypeParameters[0]; @@ -601,11 +607,18 @@ public void IsAssignableFromNullable() Assert.True(objType.IsAssignableFrom(T)); Assert.True(valTypeType.IsAssignableFrom(T)); + Assert.True(T.IsAssignableTo(T)); + Assert.True(T.IsAssignableTo(objType)); + Assert.True(T.IsAssignableTo(valTypeType)); + // should be false // Nullable is not assignable from T Assert.False(nubOfT.IsAssignableFrom(T)); Assert.False(T.IsAssignableFrom(nubOfT)); + Assert.False(nubOfT.IsAssignableTo(T)); + Assert.False(T.IsAssignableTo(nubOfT)); + // illegal type construction due to T->T? Assert.Throws(() => typeof(G<,>).MakeGenericType(typeof(int), typeof(int?))); @@ -648,12 +661,17 @@ public void OpenGenericArrays() Assert.True(typeof(IFace[]).IsAssignableFrom(a)); Assert.True(typeof(IEnumerable).IsAssignableFrom(a)); + Assert.True(a.IsAssignableTo(typeof(IFace[]))); + Assert.True(a.IsAssignableTo(typeof(IEnumerable))); + Type a1 = typeof(GG<,>).GetGenericArguments()[0].MakeArrayType(); Type a2 = typeof(GG<,>).GetGenericArguments()[1].MakeArrayType(); Assert.True(a2.IsAssignableFrom(a1)); + Assert.True(a1.IsAssignableTo(a2)); Type ie = typeof(IEnumerable<>).MakeGenericType(typeof(GG<,>).GetGenericArguments()[1]); Assert.True(ie.IsAssignableFrom(a1)); + Assert.True(a1.IsAssignableTo(ie)); } public static IEnumerable IsEquivilentTo_TestData() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 8ebce34c3dbf..6481c43f3808 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -4337,6 +4337,7 @@ protected Type() { } public abstract 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); protected abstract bool IsArrayImpl(); public virtual bool IsAssignableFrom([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Type? c) { throw null; } + public bool IsAssignableTo([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] System.Type? targetType) { throw null; } protected abstract bool IsByRefImpl(); protected abstract bool IsCOMObjectImpl(); protected virtual bool IsContextfulImpl() { throw null; } diff --git a/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.cs index d358512609c7..ca6dccd6a8c9 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.cs @@ -19,6 +19,17 @@ public void IsAssignableFrom() Assert.False(td.IsAssignableFrom(typeof(string))); } + [Fact] + public void IsAssignableTo() + { + TypeDelegator td = new TypeDelegator(typeof(int)); + + Assert.True(td.IsAssignableTo(typeof(int))); + Assert.False(td.IsAssignableTo(typeof(string))); + Assert.True(typeof(int).IsAssignableTo(td)); + Assert.False(typeof(string).IsAssignableTo(td)); + } + [Fact] public void CreateInstance() { diff --git a/src/mono/mono/metadata/reflection.c b/src/mono/mono/metadata/reflection.c index 09851b355a1f..49c907829eb7 100644 --- a/src/mono/mono/metadata/reflection.c +++ b/src/mono/mono/metadata/reflection.c @@ -3131,7 +3131,11 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass, Mono error_init (error); if (method == NULL) { +#ifdef ENABLE_NETCORE + method = mono_class_get_method_from_name_checked (mono_class_get_type_builder_class (), "IsAssignableToInternal", 1, 0, error); +#else method = mono_class_get_method_from_name_checked (mono_class_get_type_builder_class (), "IsAssignableTo", 1, 0, error); +#endif mono_error_assert_ok (error); g_assert (method); } 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 346c55914498..821b091b68ed 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 @@ -90,7 +90,7 @@ protected override TypeAttributes GetAttributeFlagsImpl() } [DynamicDependency(nameof(state))] // Automatically keeps all previous fields too due to StructLayout - [DynamicDependency(nameof(IsAssignableTo))] // Used from reflection.c: mono_reflection_call_is_assignable_to + [DynamicDependency(nameof(IsAssignableToInternal))] // Used from reflection.c: mono_reflection_call_is_assignable_to internal TypeBuilder(ModuleBuilder mb, TypeAttributes attr, int table_idx) { this.parent = null; @@ -107,7 +107,7 @@ internal TypeBuilder(ModuleBuilder mb, TypeAttributes attr, int table_idx) Justification = "Linker doesn't analyze ResolveUserType but it's an identity function")] [DynamicDependency(nameof(state))] // Automatically keeps all previous fields too due to StructLayout - [DynamicDependency(nameof(IsAssignableTo))] // Used from reflection.c: mono_reflection_call_is_assignable_to + [DynamicDependency(nameof(IsAssignableToInternal))] // Used from reflection.c: mono_reflection_call_is_assignable_to internal TypeBuilder(ModuleBuilder mb, string fullname, TypeAttributes attr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]Type? parent, Type[]? interfaces, PackingSize packing_size, int type_size, Type? nesting_type) { int sep_index; @@ -1718,7 +1718,7 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) } // FIXME: "arrays" - internal bool IsAssignableTo([NotNullWhen(true)] Type? c) + internal bool IsAssignableToInternal([NotNullWhen(true)] Type? c) { if (c == this) return true; diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs new file mode 100644 index 000000000000..6a7ccc73e362 --- /dev/null +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs @@ -0,0 +1,190 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +public partial class Program +{ + public static void TestIsAssignableTo() + { + // Primitive types + IsTrue (typeof(void).IsAssignableTo(typeof(void))); + IsTrue (typeof(byte).IsAssignableTo(typeof(byte))); + IsTrue (typeof(int).IsAssignableTo(typeof(int))); + IsTrue (typeof(float).IsAssignableTo(typeof(float))); + IsTrue (typeof(double).IsAssignableTo(typeof(double))); + IsTrue (typeof(byte*).IsAssignableTo(typeof(byte*))); + IsTrue (typeof(byte*).IsAssignableTo(typeof(sbyte*))); + IsTrue (typeof(void*).IsAssignableTo(typeof(void*))); + IsTrue (typeof(byte**).IsAssignableTo(typeof(byte**))); + IsFalse(typeof(sbyte).IsAssignableTo(typeof(byte))); + IsFalse(typeof(byte).IsAssignableTo(typeof(sbyte))); + IsFalse(typeof(long).IsAssignableTo(typeof(int))); + IsFalse(typeof(void).IsAssignableTo(typeof(int))); + IsFalse(typeof(long).IsAssignableTo(typeof(void))); + IsFalse(typeof(int).IsAssignableTo(typeof(long))); + IsFalse(typeof(double).IsAssignableTo(typeof(float))); + IsFalse(typeof(float).IsAssignableTo(typeof(double))); + IsFalse(typeof(long).IsAssignableTo(typeof(double))); + IsFalse(typeof(float).IsAssignableTo(typeof(int))); + IsFalse(typeof(ulong*).IsAssignableTo(typeof(sbyte*))); + IsFalse(typeof(void*).IsAssignableTo(typeof(sbyte*))); + IsFalse(typeof(ulong*).IsAssignableTo(typeof(void*))); + IsFalse(typeof(IntPtr).IsAssignableTo(typeof(sbyte*))); + IsFalse(typeof(sbyte*).IsAssignableTo(typeof(IntPtr))); + IsFalse(typeof(byte*).IsAssignableTo(typeof(byte**))); + IsFalse(typeof(byte**).IsAssignableTo(typeof(byte*))); + + // Nullable + IsTrue (typeof(int).IsAssignableTo(typeof(int?))); + IsTrue (typeof(int?).IsAssignableTo(typeof(int?))); + IsTrue (typeof(GenericStruct1?).IsAssignableTo(typeof(GenericStruct1?))); + IsTrue (typeof(GenericStruct1?).IsAssignableTo(typeof(GenericStruct1?))); + IsTrue (typeof(SimpleEnum_int?).IsAssignableTo(typeof(SimpleEnum_int?))); + IsFalse(typeof(int?).IsAssignableTo(typeof(int))); + IsFalse(typeof(int?).IsAssignableTo(typeof(uint?))); + IsFalse(typeof(uint?).IsAssignableTo(typeof(int?))); + IsFalse(typeof(SimpleEnum_int?).IsAssignableTo(typeof(SimpleEnum_uint?))); + IsFalse(typeof(SimpleEnum_uint?).IsAssignableTo(typeof(SimpleEnum_int?))); + IsFalse(typeof(GenericStruct1?).IsAssignableTo(typeof(GenericStruct1?))); + + // Enums + IsTrue (typeof(SimpleEnum_int).IsAssignableTo(typeof(SimpleEnum_int))); + IsTrue (typeof(SimpleEnum_int?).IsAssignableTo(typeof(SimpleEnum_int?))); + IsTrue (typeof(SimpleEnum_uint).IsAssignableTo(typeof(SimpleEnum_uint))); + IsTrue (typeof(SimpleEnum_byte).IsAssignableTo(typeof(SimpleEnum_byte))); + IsTrue (typeof(SimpleEnum_uint).IsAssignableTo(typeof(ValueType))); + IsFalse(typeof(SimpleEnum_uint).IsAssignableTo(typeof(SimpleEnum_int))); + IsFalse(typeof(SimpleEnum_int).IsAssignableTo(typeof(SimpleEnum_uint))); + IsFalse(typeof(SimpleEnum_byte).IsAssignableTo(typeof(SimpleEnum_uint))); + IsFalse(typeof(SimpleEnum_uint).IsAssignableTo(typeof(SimpleEnum_byte))); + IsFalse(typeof(byte).IsAssignableTo(typeof(SimpleEnum_byte))); + IsFalse(typeof(SimpleEnum_byte).IsAssignableTo(typeof(byte))); + IsFalse(typeof(int).IsAssignableTo(typeof(SimpleEnum_int))); + IsFalse(typeof(SimpleEnum_int).IsAssignableTo(typeof(int))); + IsFalse(typeof(float).IsAssignableTo(typeof(SimpleEnum_uint))); + IsFalse(typeof(SimpleEnum_uint).IsAssignableTo(typeof(float))); + IsFalse(typeof(ValueType).IsAssignableTo(typeof(SimpleEnum_uint))); + + // Covariance/Contravariance + IsTrue (typeof(List).IsAssignableTo(typeof(IEnumerable))); + IsTrue (typeof(List).IsAssignableTo(typeof(IEnumerable))); + IsTrue (typeof(IList).IsAssignableTo(typeof(IEnumerable))); + IsTrue (typeof(IList).IsAssignableTo(typeof(IEnumerable))); + IsTrue (typeof(IList).IsAssignableTo(typeof(IEnumerable))); + IsTrue (typeof(Action).IsAssignableTo(typeof(Action))); + IsTrue (typeof(string[]).IsAssignableTo(typeof(object[]))); + IsTrue (typeof(string[,]).IsAssignableTo(typeof(object[,]))); + IsTrue (typeof(SimpleEnum_uint[,]).IsAssignableTo(typeof(SimpleEnum_int[,]))); + IsFalse(typeof(object[,]).IsAssignableTo(typeof(string[,]))); + IsFalse(typeof(string[,,]).IsAssignableTo(typeof(object[,]))); + IsFalse(typeof(IDictionary).IsAssignableTo(typeof(IDictionary))); + IsFalse(typeof(Dictionary).IsAssignableTo(typeof(IDictionary))); + IsFalse(typeof(Action).IsAssignableTo(typeof(Action))); + IsFalse(typeof(Action).IsAssignableTo(typeof(Action))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(List))); + IsFalse(typeof(Action).IsAssignableTo(typeof(Action))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(List))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(IList))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(IList))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(IList))); + + // Arrays + IsTrue(typeof(sbyte[]).IsAssignableTo(typeof(byte[]))); + IsTrue(typeof(byte[]).IsAssignableTo(typeof(sbyte[]))); + IsTrue(typeof(ushort[]).IsAssignableTo(typeof(short[]))); + IsTrue(typeof(short[]).IsAssignableTo(typeof(ushort[]))); + IsTrue(typeof(uint[]).IsAssignableTo(typeof(int[]))); + IsTrue(typeof(int[]).IsAssignableTo(typeof(uint[]))); + IsTrue(typeof(ulong[]).IsAssignableTo(typeof(long[]))); + IsTrue(typeof(long[]).IsAssignableTo(typeof(ulong[]))); + IsTrue(typeof(ulong[,]).IsAssignableTo(typeof(long[,]))); + IsTrue(typeof(long[,,]).IsAssignableTo(typeof(ulong[,,]))); + IsTrue(typeof(Struct1[]).IsAssignableTo(typeof(Struct1[]))); + IsFalse(typeof(byte[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(sbyte[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(short[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(ushort[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(float[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(double[]).IsAssignableTo(typeof(int[]))); + IsFalse(typeof(double[]).IsAssignableTo(typeof(long[]))); + IsFalse(typeof(Struct2[]).IsAssignableTo(typeof(Struct1[]))); + IsFalse(typeof(GenericStruct1[]).IsAssignableTo(typeof(Struct1[]))); + IsFalse(typeof(GenericStruct1[]).IsAssignableTo(typeof(GenericStruct1[]))); + + // Misc + IsTrue (typeof(byte).IsAssignableTo(typeof(object))); + IsTrue (typeof(int).IsAssignableTo(typeof(object))); + IsTrue (typeof(float).IsAssignableTo(typeof(object))); + IsTrue (typeof(SimpleEnum_uint).IsAssignableTo(typeof(object))); + IsTrue (typeof(IDisposable).IsAssignableTo(typeof(object))); + IsTrue (typeof(IDictionary).IsAssignableTo(typeof(object))); + IsTrue (typeof(List).IsAssignableTo(typeof(object))); + IsTrue (typeof(List<>).IsAssignableTo(typeof(object))); + IsTrue (typeof(Action<>).IsAssignableTo(typeof(object))); + IsTrue (typeof(Action).IsAssignableTo(typeof(object))); + IsTrue (typeof(Vector128).IsAssignableTo(typeof(object))); + IsTrue (typeof(Vector256).IsAssignableTo(typeof(object))); + IsTrue (typeof(ClassA).IsAssignableTo(typeof(ClassA))); + IsTrue (typeof(ClassB).IsAssignableTo(typeof(ClassA))); + IsTrue (typeof(ClassC).IsAssignableTo(typeof(ClassA))); + IsTrue (typeof(decimal).IsAssignableTo(typeof(decimal))); + IsTrue (typeof(Struct1).IsAssignableTo(typeof(Struct1))); + IsTrue (typeof(Struct3).IsAssignableTo(typeof(IDisposable))); + IsTrue (typeof(Dictionary<,>).IsAssignableTo(typeof(Dictionary<,>))); + IsTrue (typeof(IDictionary<,>).IsAssignableTo(typeof(IDictionary<,>))); + IsTrue (typeof(GenericStruct1<>).IsAssignableTo(typeof(GenericStruct1<>))); + IsTrue (typeof(GenericStruct1).IsAssignableTo(typeof(GenericStruct1))); + IsTrue (typeof(GenericStruct1).IsAssignableTo(typeof(GenericStruct1))); + IsFalse(typeof(IDisposable).IsAssignableTo(typeof(byte))); + IsFalse(typeof(IEnumerable).IsAssignableTo(typeof(IDisposable))); + IsFalse(typeof(IDictionary).IsAssignableTo(typeof(IDictionary))); + IsFalse(typeof(IList).IsAssignableTo(typeof(List))); + IsFalse(typeof(List).IsAssignableTo(typeof(List<>))); + IsFalse(typeof(Action).IsAssignableTo(typeof(Action<>))); + IsFalse(typeof(Func).IsAssignableTo(typeof(Action<>))); + IsFalse(typeof(CustomAction).IsAssignableTo(typeof(Action))); + IsFalse(typeof(void).IsAssignableTo(typeof(Action))); + IsFalse(typeof(ClassD).IsAssignableTo(typeof(ClassB))); + IsFalse(typeof(Dictionary).IsAssignableTo(typeof(Dictionary<,>))); + IsFalse(typeof(GenericStruct1).IsAssignableTo(typeof(GenericStruct1))); + IsFalse(typeof(Struct2).IsAssignableTo(typeof(Struct1))); + IsFalse(typeof(GenericStruct2<>).IsAssignableTo(typeof(GenericStruct1<>))); + IsFalse(typeof(GenericStruct2).IsAssignableTo(typeof(GenericStruct1))); + IsFalse(typeof(byte*).IsAssignableTo(typeof(object))); + IsFalse(typeof(byte**).IsAssignableTo(typeof(object))); + IsFalse(typeof(Vector128).IsAssignableTo(typeof(Vector128))); + IsFalse(typeof(Vector128).IsAssignableTo(typeof(Vector128))); + IsFalse(typeof(Vector128).IsAssignableTo(typeof(Vector128))); + IsFalse(typeof(Vector128).IsAssignableTo(typeof(Vector4))); + IsFalse(typeof(Vector4).IsAssignableTo(typeof(Vector128))); + IsFalse(typeof(Vector).IsAssignableTo(typeof(Vector128))); + IsFalse(typeof(Vector).IsAssignableTo(typeof(Vector256))); + + // System.__Canon + IsTrue (IsAssignableTo, KeyValuePair>()); + IsTrue (IsAssignableTo, KeyValuePair>()); + IsTrue (IsAssignableTo, IDictionary>()); + IsTrue (IsAssignableTo, IDictionary>()); + IsTrue (IsAssignableTo, Dictionary>()); + IsTrue (IsAssignableTo, Dictionary>()); + IsTrue (IsAssignableTo, KeyValuePair>()); + IsTrue (IsAssignableTo, IEnumerable>, KeyValuePair, IEnumerable>>()); + IsFalse(IsAssignableTo, KeyValuePair>()); + IsFalse(IsAssignableTo, KeyValuePair>()); + IsFalse(IsAssignableTo, IDictionary>()); + IsFalse(IsAssignableTo, IDictionary>()); + IsFalse(IsAssignableTo, Dictionary>()); + IsFalse(IsAssignableTo, Dictionary>()); + IsFalse(IsAssignableTo, KeyValuePair>()); + IsFalse(IsAssignableTo, IEnumerable>, KeyValuePair, IEnumerable>>()); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool IsAssignableTo() => typeof(TTFrom).IsAssignableTo(typeof(TTo)); +} diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj b/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj index 4e2edb234c81..9ee21d6e902b 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj @@ -7,5 +7,6 @@ + diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj b/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj index 2e35b529e622..d752cddd2a06 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj @@ -7,5 +7,6 @@ + From 23796081e0793e362bf493d112d3dbc8b577a4a1 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 10 Aug 2020 17:35:30 -0700 Subject: [PATCH 381/755] Inline underlying array into ImmutableArray.IsEmpty (#40635) --- .../System/Collections/Immutable/ImmutableArray_1.Minimal.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs index 6210a0a9a1f8..8e4de608cd31 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs @@ -156,7 +156,7 @@ public ref readonly T ItemRef(int index) public bool IsEmpty { [NonVersionable] - get { return this.Length == 0; } + get { return this.array!.Length == 0; } } /// From bcf3bd30adf33a82b13f8bd7586fe9dd0951c37d Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 10 Aug 2020 18:12:52 -0700 Subject: [PATCH 382/755] Fix concurrent collections CA1836 rule violations (#40629) * Fix concurrent collections CA1836 rule violations * Update dogfood analyzer version --- eng/Analyzers.props | 2 +- eng/CodeAnalysis.ruleset | 2 +- .../src/System/Data/ProviderBase/DbConnectionPoolGroup.cs | 6 +++--- .../src/DefaultHttpClientFactory.cs | 2 +- .../src/System/Data/ProviderBase/DbConnectionPoolGroup.cs | 6 +++--- .../src/System/Net/Security/SslSessionsCache.cs | 2 +- .../src/System/Threading/Tasks/Parallel.cs | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eng/Analyzers.props b/eng/Analyzers.props index c14a86901948..34eb83dff697 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -6,7 +6,7 @@ - + diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset index 3726904d2fd7..293d25a21616 100644 --- a/eng/CodeAnalysis.ruleset +++ b/eng/CodeAnalysis.ruleset @@ -112,7 +112,7 @@ - + diff --git a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs index 26ee3b6515dd..a3807e9a4307 100644 --- a/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs +++ b/src/libraries/Common/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs @@ -105,7 +105,7 @@ internal int Clear() ConcurrentDictionary? oldPoolCollection = null; lock (this) { - if (_poolCollection.Count > 0) + if (!_poolCollection.IsEmpty) { oldPoolCollection = _poolCollection; _poolCollection = new ConcurrentDictionary(); @@ -232,7 +232,7 @@ internal bool Prune() // to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry lock (this) { - if (_poolCollection.Count > 0) + if (!_poolCollection.IsEmpty) { var newPoolCollection = new ConcurrentDictionary(); @@ -267,7 +267,7 @@ internal bool Prune() // must be pruning thread to change state and no connections // otherwise pruning thread risks making entry disabled soon after user calls ClearPool - if (0 == _poolCollection.Count) + if (_poolCollection.IsEmpty) { if (PoolGroupStateActive == _state) { diff --git a/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs b/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs index d3ad266e2486..059111a2e66b 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs @@ -324,7 +324,7 @@ internal void CleanupTimer_Tick() } // We didn't totally empty the cleanup queue, try again later. - if (_expiredHandlers.Count > 0) + if (!_expiredHandlers.IsEmpty) { StartCleanupTimer(); } diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs index 792f6e7bc2d4..4a77e1c8ff58 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionPoolGroup.cs @@ -129,7 +129,7 @@ internal int Clear() ConcurrentDictionary? oldPoolCollection = null; lock (this) { - if (_poolCollection.Count > 0) + if (!_poolCollection.IsEmpty) { oldPoolCollection = _poolCollection; _poolCollection = new ConcurrentDictionary(); @@ -266,7 +266,7 @@ internal bool Prune() // to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry lock (this) { - if (_poolCollection.Count > 0) + if (!_poolCollection.IsEmpty) { var newPoolCollection = new ConcurrentDictionary(); @@ -309,7 +309,7 @@ internal bool Prune() // must be pruning thread to change state and no connections // otherwise pruning thread risks making entry disabled soon after user calls ClearPool - if (0 == _poolCollection.Count) + if (_poolCollection.IsEmpty) { if (PoolGroupStateActive == _state) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs index ea2c83e808fe..eccd25b2e0c8 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs @@ -115,7 +115,7 @@ public bool Equals(SslCredKey other) // internal static SafeFreeCredentials? TryCachedCredential(byte[]? thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy) { - if (s_cachedCreds.Count == 0) + if (s_cachedCreds.IsEmpty) { if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"Not found, Current Cache Count = {s_cachedCreds.Count}"); return null; diff --git a/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.cs b/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.cs index ac4a03726ac1..21cee18d3763 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.cs +++ b/src/libraries/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Parallel.cs @@ -318,7 +318,7 @@ public static void Invoke(ParallelOptions parallelOptions, params Action[] actio } // If we have encountered any exceptions, then throw. - if ((exceptionQ != null) && (exceptionQ.Count > 0)) + if ((exceptionQ != null) && (!exceptionQ.IsEmpty)) { ThrowSingleCancellationExceptionOrOtherException(exceptionQ, parallelOptions.CancellationToken, new AggregateException(exceptionQ)); From 88ab22d20acb21300c60969fe1c49f4d287bb780 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 10 Aug 2020 18:13:14 -0700 Subject: [PATCH 383/755] add eventsource doc (#40630) --- .../src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj index 8c2783236fc6..902e31dfc78c 100644 --- a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj +++ b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj @@ -4,6 +4,7 @@ $(DefineConstants);NO_EVENTCOMMANDEXECUTED_SUPPORT;ES_BUILD_STANDALONE;FEATURE_MANAGED_ETW;TARGET_WINDOWS net461-Windows_NT enable + $(OutputPath)$(AssemblyName).xml true From 857b2db411741ee57bfe24da58f77e6e124aa110 Mon Sep 17 00:00:00 2001 From: symphony Date: Tue, 11 Aug 2020 09:14:37 +0800 Subject: [PATCH 384/755] Path change for ryujit-overview.md (#40611) --- src/coreclr/src/jit/compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index b836a2efa2f2..214fc3a9d5f2 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -4224,7 +4224,7 @@ void Compiler::EndPhase(Phases phase) // code:CILJit::compileMethod function. // // For an overview of the structure of the JIT, see: -// https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/ryujit-overview.md +// https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/jit/ryujit-overview.md // // Also called for inlinees, though they will only be run through the first few phases. // From 7d152b7bc9a23a96929d818dded0854bcc943aac Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 10 Aug 2020 18:22:13 -0700 Subject: [PATCH 385/755] Suppress GS cookie checks in method epilogs (#40637) The information about end of GS cookie scope recorded in GC info is not accurate and it cannot even be made accurate without redesign that is not worth it. Detect end of GS cookie scope by comparing it with current SP instead. Fixes #13041 --- src/coreclr/src/vm/eetwain.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/vm/eetwain.cpp b/src/coreclr/src/vm/eetwain.cpp index 41008aac175f..88ba0a6b6f7f 100644 --- a/src/coreclr/src/vm/eetwain.cpp +++ b/src/coreclr/src/vm/eetwain.cpp @@ -5626,11 +5626,14 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, INT32 spOffsetGSCookie = gcInfoDecoder.GetGSCookieStackSlot(); if (spOffsetGSCookie != NO_GS_COOKIE) { - if(relOffset >= gcInfoDecoder.GetGSCookieValidRangeStart() - && relOffset < gcInfoDecoder.GetGSCookieValidRangeEnd()) + if(relOffset >= gcInfoDecoder.GetGSCookieValidRangeStart()) { - SIZE_T baseStackSlot = GetCallerSp(pContext); - return (LPVOID)( spOffsetGSCookie + baseStackSlot ); + TADDR ptr = GetCallerSp(pContext) + spOffsetGSCookie; + + // Detect the end of GS cookie scope by comparing its address with SP + // gcInfoDecoder.GetGSCookieValidRangeEnd() is not accurate. It does not + // account for GS cookie going out of scope inside epilog or multiple epilogs. + return (LPVOID) ((ptr >= pContext->SP) ? ptr : NULL); } } return NULL; From 7600720a60b9b1146807c4a71b104f98ed10bef1 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 11 Aug 2020 04:41:35 +0200 Subject: [PATCH 386/755] Ensure Http Telemetry correctness (#40338) * Ensure Http Telemetry correctness * Remove unnecessary GC.SuppressFinalize call * Add another Telemetry.IsEnabled() check * Rename MessageShouldEmitTelemetry to MessageAlreadySent_StopNotYetCalled * Improve Telemetry tests * Log Aborted instead of Stopped on Connection Dispose * Ensure request is canceled after a connection is established --- .../src/System/Net/Http/HttpRequestMessage.cs | 32 +++- .../ChunkedEncodingReadStream.cs | 2 - .../ConnectionCloseReadStream.cs | 3 - .../ContentLengthReadStream.cs | 3 - .../Http/SocketsHttpHandler/Http2Stream.cs | 8 +- .../Http/SocketsHttpHandler/HttpConnection.cs | 18 +- .../SocketsHttpHandler/HttpConnectionPool.cs | 4 +- .../HttpConnectionPoolManager.cs | 10 +- .../SocketsHttpHandler/HttpContentStream.cs | 13 -- .../SocketsHttpHandler/RawConnectionStream.cs | 3 - .../System.Net.Http.Functional.Tests.csproj | 1 + .../tests/FunctionalTests/TelemetryTest.cs | 178 ++++++++++++++++++ .../tests/UnitTests/Fakes/HttpTelemetry.cs | 16 ++ .../System.Net.Http.Unit.Tests.csproj | 1 + 14 files changed, 246 insertions(+), 46 deletions(-) create mode 100644 src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs create mode 100644 src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpTelemetry.cs diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs index 5e1d9bb25f1b..f74fd02a0da8 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; using System.Collections.Generic; +using System.Diagnostics; namespace System.Net.Http { @@ -13,9 +14,10 @@ public class HttpRequestMessage : IDisposable { private const int MessageNotYetSent = 0; private const int MessageAlreadySent = 1; + private const int MessageAlreadySent_StopNotYetCalled = 2; // Track whether the message has been sent. - // The message shouldn't be sent again if this field is equal to MessageAlreadySent. + // The message should only be sent if this field is equal to MessageNotYetSent. private int _sendStatus = MessageNotYetSent; private HttpMethod _method; @@ -183,7 +185,31 @@ private void InitializeValues(HttpMethod method, Uri? requestUri) internal bool MarkAsSent() { - return Interlocked.Exchange(ref _sendStatus, MessageAlreadySent) == MessageNotYetSent; + return Interlocked.CompareExchange(ref _sendStatus, MessageAlreadySent, MessageNotYetSent) == MessageNotYetSent; + } + + internal void MarkAsTrackedByTelemetry() + { + Debug.Assert(_sendStatus != MessageAlreadySent_StopNotYetCalled); + _sendStatus = MessageAlreadySent_StopNotYetCalled; + } + + internal void OnAborted() => OnStopped(aborted: true); + + internal void OnStopped(bool aborted = false) + { + if (HttpTelemetry.Log.IsEnabled()) + { + if (Interlocked.Exchange(ref _sendStatus, MessageAlreadySent) == MessageAlreadySent_StopNotYetCalled) + { + if (aborted) + { + HttpTelemetry.Log.RequestAborted(); + } + + HttpTelemetry.Log.RequestStop(); + } + } } #region IDisposable Members @@ -200,6 +226,8 @@ protected virtual void Dispose(bool disposing) _content.Dispose(); } } + + OnStopped(); } public void Dispose() 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 d747bd8ba233..b9ccbcef76d6 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 @@ -56,7 +56,6 @@ public override int Read(Span buffer) if (_connection == null) { // Fully consumed the response in ReadChunksFromConnectionBuffer. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); return 0; } @@ -362,7 +361,6 @@ private ReadOnlyMemory ReadChunkFromConnectionBuffer(int maxBytesToRead, C cancellationRegistration.Dispose(); CancellationHelper.ThrowIfCancellationRequested(cancellationRegistration.Token); - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _state = ParsingState.Done; _connection.CompleteResponse(); _connection = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs index 1d7a0b2c41af..28ef24fe4aa2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs @@ -28,7 +28,6 @@ public override int Read(Span buffer) if (bytesRead == 0) { // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection = null; connection.Dispose(); } @@ -81,7 +80,6 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation CancellationHelper.ThrowIfCancellationRequested(cancellationToken); // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection = null; connection.Dispose(); } @@ -143,7 +141,6 @@ private async Task CompleteCopyToAsync(Task copyTask, HttpConnection connection, private void Finish(HttpConnection connection) { // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection = null; connection.Dispose(); } 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 f6f7b44da3e1..a946a7aa1cfe 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 @@ -47,7 +47,6 @@ public override int Read(Span buffer) if (_contentBytesRemaining == 0) { // End of response body - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection.CompleteResponse(); _connection = null; } @@ -110,7 +109,6 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation if (_contentBytesRemaining == 0) { // End of response body - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection.CompleteResponse(); _connection = null; } @@ -165,7 +163,6 @@ private async Task CompleteCopyToAsync(Task copyTask, CancellationToken cancella private void Finish() { - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _contentBytesRemaining = 0; _connection!.CompleteResponse(); _connection = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index 0635de4df9b9..8671947e4cae 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 @@ -351,7 +351,7 @@ private void Complete() _creditWaiter = null; } - if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestStop(); + if (HttpTelemetry.Log.IsEnabled()) _request.OnStopped(); } private void Cancel() @@ -387,7 +387,7 @@ private void Cancel() _waitSource.SetResult(true); } - if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestAborted(); + if (HttpTelemetry.Log.IsEnabled()) _request.OnAborted(); } // Returns whether the waiter should be signalled or not. @@ -1147,6 +1147,10 @@ private void CloseResponseBody() { Cancel(); } + else + { + _request.OnStopped(); + } _responseBuffer.Dispose(); } 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 131af80227ee..ac88a2edb261 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 @@ -90,6 +90,8 @@ public HttpConnection( if (NetEventSource.Log.IsEnabled()) TraceConnection(_stream); } + ~HttpConnection() => Dispose(disposing: false); + public void Dispose() => Dispose(disposing: true); protected void Dispose(bool disposing) @@ -100,6 +102,9 @@ protected void Dispose(bool disposing) { if (NetEventSource.Log.IsEnabled()) Trace("Connection closing."); _pool.DecrementConnectionCount(); + + if (HttpTelemetry.Log.IsEnabled()) _currentRequest?.OnAborted(); + if (disposing) { GC.SuppressFinalize(this); @@ -630,7 +635,6 @@ public async Task SendAsyncCore(HttpRequestMessage request, Stream responseStream; if (ReferenceEquals(normalizedMethod, HttpMethod.Head) || response.StatusCode == HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.NotModified) { - if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestStop(); responseStream = EmptyReadStream.Instance; CompleteResponse(); } @@ -653,7 +657,6 @@ public async Task SendAsyncCore(HttpRequestMessage request, long contentLength = response.Content.Headers.ContentLength.GetValueOrDefault(); if (contentLength <= 0) { - if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestStop(); responseStream = EmptyReadStream.Instance; CompleteResponse(); } @@ -1850,6 +1853,8 @@ private void CompleteResponse() Debug.Assert(_currentRequest != null, "Expected the connection to be associated with a request."); Debug.Assert(_writeOffset == 0, "Everything in write buffer should have been flushed."); + if (HttpTelemetry.Log.IsEnabled()) _currentRequest.OnStopped(); + // Disassociate the connection from a request. _currentRequest = null; @@ -1963,13 +1968,4 @@ public sealed override void Trace(string message, [CallerMemberName] string? mem memberName, // method name message); // message } - - internal sealed class HttpConnectionWithFinalizer : HttpConnection - { - public HttpConnectionWithFinalizer(HttpConnectionPool pool, Connection connection, TransportContext? transportContext) : base(pool, connection, transportContext) { } - - // This class is separated from HttpConnection so we only pay the price of having a finalizer - // when it's actually needed, e.g. when MaxConnectionsPerServer is enabled. - ~HttpConnectionWithFinalizer() => Dispose(disposing: false); - } } 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 e2c2e3664248..e6644c14e8fe 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 @@ -1238,9 +1238,7 @@ private ValueTask ConnectToTcpHostAsync(string host, int port, HttpR private HttpConnection ConstructHttp11Connection(Connection connection, TransportContext? transportContext) { - return _maxConnections == int.MaxValue ? - new HttpConnection(this, connection, transportContext) : - new HttpConnectionWithFinalizer(this, connection, transportContext); // finalizer needed to signal the pool when a connection is dropped + return new HttpConnection(this, connection, transportContext); } // Returns the established stream or an HttpResponseMessage from the proxy indicating failure. 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 67906139abd5..06575e4350b9 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 @@ -354,20 +354,22 @@ private async ValueTask SendAsyncWithLogging(HttpRequestMes request.RequestUri.PathAndQuery, request.Version.Major, request.Version.Minor); + + request.MarkAsTrackedByTelemetry(); + try { return await SendAsyncHelper(request, async, doRequestAuth, cancellationToken).ConfigureAwait(false); } - catch (Exception e) when (LogException(e)) + catch when (LogException(request)) { // This code should never run. throw; } - static bool LogException(Exception e) + static bool LogException(HttpRequestMessage request) { - HttpTelemetry.Log.RequestAborted(); - HttpTelemetry.Log.RequestStop(); + request.OnAborted(); // Returning false means the catch handler isn't run. // So the exception isn't considered to be caught so it will now propagate up the stack. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs index 7530988e6c6d..c5da3efdd532 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs @@ -1,17 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Threading; - namespace System.Net.Http { internal abstract class HttpContentStream : HttpBaseStream { protected HttpConnection? _connection; - // Makes sure we don't call HttpTelemetry events more than once. - private int _requestStopCalled; // 0==no, 1==yes - public HttpContentStream(HttpConnection connection) { _connection = connection; @@ -45,14 +40,6 @@ protected HttpConnection GetConnectionOrThrow() ThrowObjectDisposedException(); } - protected void LogRequestStop() - { - if (Interlocked.Exchange(ref _requestStopCalled, 1) == 0) - { - HttpTelemetry.Log.RequestStop(); - } - } - private HttpConnection ThrowObjectDisposedException() => throw new ObjectDisposedException(GetType().Name); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs index 33b1935e7ce3..b1f8bd90c882 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs @@ -33,7 +33,6 @@ public override int Read(Span buffer) if (bytesRead == 0) { // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection = null; connection.Dispose(); } @@ -81,7 +80,6 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation CancellationHelper.ThrowIfCancellationRequested(cancellationToken); // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); _connection = null; connection.Dispose(); } @@ -143,7 +141,6 @@ private async Task CompleteCopyToAsync(Task copyTask, HttpConnection connection, private void Finish(HttpConnection connection) { // We cannot reuse this connection, so close it. - if (HttpTelemetry.Log.IsEnabled()) LogRequestStop(); connection.Dispose(); _connection = null; } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index 9a5928a025eb..baea536e52cb 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -224,6 +224,7 @@ + + { + using var listener = new TestEventListener("System.Net.Http", EventLevel.Verbose, eventCounterInterval: 0.1d); + + var events = new ConcurrentQueue(); + await listener.RunWithCallbackAsync(events.Enqueue, async () => + { + await GetFactoryForVersion(Version.Parse(useVersionString)).CreateClientAndServerAsync( + async uri => + { + using HttpClient client = CreateHttpClient(useVersionString); + await client.GetStringAsync(uri); + }, + async server => + { + await server.AcceptConnectionAsync(async connection => + { + await Task.Delay(300); + await connection.ReadRequestDataAsync(); + await connection.SendResponseAsync(); + }); + }); + + await Task.Delay(300); + }); + Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself + + EventWrittenEventArgs start = Assert.Single(events, e => e.EventName == "RequestStart"); + ValidateStartEventPayload(start); + + EventWrittenEventArgs stop = Assert.Single(events, e => e.EventName == "RequestStop"); + Assert.Equal(0, stop.Payload.Count); + + Assert.DoesNotContain(events, e => e.EventName == "RequestAborted"); + + VerifyEventCounters(events, shouldHaveFailures: false); + }, UseVersion.ToString()).Dispose(); + } + + [OuterLoop] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void EventSource_UnsuccessfulRequest_LogsStartAbortedStop() + { + RemoteExecutor.Invoke(async useVersionString => + { + using var listener = new TestEventListener("System.Net.Http", EventLevel.Verbose, eventCounterInterval: 0.1d); + + var events = new ConcurrentQueue(); + await listener.RunWithCallbackAsync(events.Enqueue, async () => + { + var semaphore = new SemaphoreSlim(0, 1); + var cts = new CancellationTokenSource(); + + await GetFactoryForVersion(Version.Parse(useVersionString)).CreateClientAndServerAsync( + async uri => + { + using HttpClient client = CreateHttpClient(useVersionString); + await Assert.ThrowsAsync(async () => await client.GetStringAsync(uri, cts.Token)); + semaphore.Release(); + }, + async server => + { + await server.AcceptConnectionAsync(async connection => + { + cts.CancelAfter(TimeSpan.FromMilliseconds(300)); + Assert.True(await semaphore.WaitAsync(TimeSpan.FromSeconds(5))); + connection.Dispose(); + }); + }); + + await Task.Delay(300); + }); + Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself + + EventWrittenEventArgs start = Assert.Single(events, e => e.EventName == "RequestStart"); + ValidateStartEventPayload(start); + + EventWrittenEventArgs abort = Assert.Single(events, e => e.EventName == "RequestAborted"); + Assert.Equal(0, abort.Payload.Count); + + EventWrittenEventArgs stop = Assert.Single(events, e => e.EventName == "RequestStop"); + Assert.Equal(0, stop.Payload.Count); + + VerifyEventCounters(events, shouldHaveFailures: true); + }, UseVersion.ToString()).Dispose(); + } + + private static void ValidateStartEventPayload(EventWrittenEventArgs startEvent) + { + Assert.Equal("RequestStart", startEvent.EventName); + Assert.Equal(6, startEvent.Payload.Count); + + Assert.Equal("http", (string)startEvent.Payload[0]); + Assert.NotEmpty((string)startEvent.Payload[1]); // host + Assert.True(startEvent.Payload[2] is int port && port >= 0 && port <= 65535); + Assert.NotEmpty((string)startEvent.Payload[3]); // pathAndQuery + Assert.True(startEvent.Payload[4] is int versionMajor && (versionMajor == 1 || versionMajor == 2)); + Assert.True(startEvent.Payload[5] is int versionMinor && (versionMinor == 1 || versionMinor == 0)); + } + + private static void VerifyEventCounters(ConcurrentQueue events, bool shouldHaveFailures) + { + Dictionary eventCounters = events + .Where(e => e.EventName == "EventCounters") + .Select(e => (IDictionary)e.Payload.Single()) + .GroupBy(d => (string)d["Name"], d => (double)(d.ContainsKey("Mean") ? d["Mean"] : d["Increment"])) + .ToDictionary(p => p.Key, p => p.ToArray()); + + Assert.True(eventCounters.TryGetValue("requests-started", out double[] requestsStarted)); + Assert.Equal(1, requestsStarted[^1]); + + Assert.True(eventCounters.TryGetValue("requests-started-rate", out double[] requestRate)); + Assert.Contains(requestRate, r => r > 0); + + Assert.True(eventCounters.TryGetValue("requests-aborted", out double[] requestsAborted)); + Assert.True(eventCounters.TryGetValue("requests-aborted-rate", out double[] requestsAbortedRate)); + if (shouldHaveFailures) + { + Assert.Equal(1, requestsAborted[^1]); + Assert.Contains(requestsAbortedRate, r => r > 0); + } + else + { + Assert.All(requestsAborted, a => Assert.Equal(0, a)); + Assert.All(requestsAbortedRate, r => Assert.Equal(0, r)); + } + + Assert.True(eventCounters.TryGetValue("current-requests", out double[] currentRequests)); + Assert.Contains(currentRequests, c => c > 0); + Assert.Equal(0, currentRequests[^1]); + } + } +} diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpTelemetry.cs b/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpTelemetry.cs new file mode 100644 index 000000000000..e6ca98293ba6 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpTelemetry.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Net.Http +{ + public class HttpTelemetry + { + public static readonly HttpTelemetry Log = new HttpTelemetry(); + + public bool IsEnabled() => false; + + public void RequestStop() { } + + public void RequestAborted() { } + } +} diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 19de137c6434..6bf7e93b754a 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -250,6 +250,7 @@ Link="ProductionCode\System\Net\Http\HttpHandlerDefaults.cs" /> + From e100d5ed292786284ef4f3ee678be5f7c43a0a53 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 10 Aug 2020 20:26:19 -0700 Subject: [PATCH 387/755] Fix ref counting in ComWrappers tests (#40636) --- .../Interop/COM/ComWrappers/API/ComWrappersTests.csproj | 2 -- src/tests/Interop/COM/ComWrappers/API/Program.cs | 5 +++++ .../MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp | 1 + .../COM/ComWrappers/WeakReference/WeakReferenceTest.csproj | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj index 4681477e2087..c4ddaac0367a 100644 --- a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj +++ b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj @@ -1,8 +1,6 @@ Exe - - true true true diff --git a/src/tests/Interop/COM/ComWrappers/API/Program.cs b/src/tests/Interop/COM/ComWrappers/API/Program.cs index d8135cc3785c..ad6e3b73c0e9 100644 --- a/src/tests/Interop/COM/ComWrappers/API/Program.cs +++ b/src/tests/Interop/COM/ComWrappers/API/Program.cs @@ -136,6 +136,9 @@ static void ValidateFallbackQueryInterface() const int E_NOINTERFACE = unchecked((int)0x80004002); Assert.AreEqual(hr, E_NOINTERFACE); Assert.AreEqual(result, IntPtr.Zero); + + int count = Marshal.Release(comWrapper); + Assert.AreEqual(count, 0); } static void ValidateCreateObjectCachingScenario() @@ -366,6 +369,8 @@ static void ValidateRuntimeTrackerScenario() // Retain the managed object wrapper ptr. testWrapperIds.Add(id); + + Marshal.Release(testWrapper); } Assert.IsTrue(testWrapperIds.Count <= Test.InstanceCount); diff --git a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index 8ac2ff9261bf..efec0855d05b 100644 --- a/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/tests/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -142,6 +142,7 @@ namespace if (S_OK == iter->second->QueryInterface(&mowMaybe)) { (void)mowMaybe->ReleaseFromReferenceTracker(); + (void)mowMaybe->Unpeg(); } _elements.erase(iter); diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj index f758175ec469..35d1e5dcbbc8 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj @@ -3,7 +3,7 @@ Exe true - + true true From 0d6d73a6439e394e3ea81ae60b286ecc1ba41691 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Mon, 10 Aug 2020 23:43:58 -0700 Subject: [PATCH 388/755] Fix versionless UCRT probing path (#40642) --- src/coreclr/build-runtime.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd index aa9573d790cb..628f4eefbff2 100644 --- a/src/coreclr/build-runtime.cmd +++ b/src/coreclr/build-runtime.cmd @@ -550,7 +550,7 @@ if %__BuildNative% EQU 1 ( if /i "%__BuildArch%" == "arm64" goto SkipCopyUcrt - set "__UCRTDir=%UniversalCRTSDKDIR%Redist\ucrxxxt\DLLs\%__BuildArch%\" + set "__UCRTDir=%UniversalCRTSDKDIR%Redist\ucrt\DLLs\%__BuildArch%\" if not exist "!__UCRTDir!" set "__UCRTDir=%UniversalCRTSDKDIR%Redist\%UCRTVersion%\ucrt\DLLs\%__BuildArch%\" if not exist "!__UCRTDir!" ( echo %__ErrMsgPrefix%%__MsgPrefix%Error: Please install the Redistributable Universal C Runtime. From 7a2671ad3600326a5f5b6794faaeafc480415ad5 Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Tue, 11 Aug 2020 15:26:25 +0300 Subject: [PATCH 389/755] Remove max header length check from WebHeaderCollection (#40529) Removed conditional max header length check from System.Net.WebHeaderCollection as it is redundant and produces puzzling behavior. Removed unused values of WebHeaderCollectionType enum. Contributes to #1486 --- .../tests/HttpListenerResponseTests.cs | 21 +++++ .../src/Resources/Strings.resx | 8 +- .../src/System/Net/WebHeaderCollection.cs | 82 +------------------ .../tests/WebHeaderCollectionTest.cs | 20 +++++ 4 files changed, 45 insertions(+), 86 deletions(-) diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs index b654fd429ae7..5b7fd28d1bbd 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs @@ -435,5 +435,26 @@ public async Task CloseResponseEntity_SendToClosedConnection_DoesNotThrow(bool w } } } + + [Fact] + public async Task AddLongHeader_DoesNotThrow() + { + string longString = new string('a', 65536); + + using (HttpListenerResponse response = await GetResponse()) + { + // WebHeaderCollection.Add(String,String) is called inside + response.AddHeader("Long-Header", longString); + + // WebHeaderCollection[HttpResponseHeader] is called inside + response.Redirect("someValueToChangeType"); // this will implicitly change WebHeaderCollection._type + + // WebHeaderCollection.Add(String,String) is called inside + response.AddHeader("Long-Header-2", longString); + + Assert.Equal(longString, response.Headers["Long-Header"]); + Assert.Equal(longString, response.Headers["Long-Header-2"]); + } + } } } diff --git a/src/libraries/System.Net.WebHeaderCollection/src/Resources/Strings.resx b/src/libraries/System.Net.WebHeaderCollection/src/Resources/Strings.resx index cab58a4e7876..eb1e5a648716 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/Resources/Strings.resx +++ b/src/libraries/System.Net.WebHeaderCollection/src/Resources/Strings.resx @@ -75,13 +75,7 @@ Specified value has invalid HTTP Header characters. - - Header values cannot be longer than {0} characters. - Specified value does not have a ':' separator. - - The {0} header must be modified using the appropriate property or method. - - \ No newline at end of file + diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs index 8997629f783d..1a97af3ccfb4 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs +++ b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs @@ -16,15 +16,7 @@ internal enum WebHeaderCollectionType : byte { Unknown, WebRequest, - WebResponse, - HttpWebRequest, - HttpWebResponse, - HttpListenerRequest, - HttpListenerResponse, - FtpWebRequest, - FtpWebResponse, - FileWebRequest, - FileWebResponse, + WebResponse } public class WebHeaderCollection : NameValueCollection, ISerializable @@ -49,9 +41,7 @@ private bool AllowHttpRequestHeader { _type = WebHeaderCollectionType.WebRequest; } - return _type == WebHeaderCollectionType.WebRequest || - _type == WebHeaderCollectionType.HttpWebRequest || - _type == WebHeaderCollectionType.HttpListenerRequest; + return _type == WebHeaderCollectionType.WebRequest; } } @@ -85,9 +75,7 @@ private bool AllowHttpResponseHeader { _type = WebHeaderCollectionType.WebResponse; } - return _type == WebHeaderCollectionType.WebResponse || - _type == WebHeaderCollectionType.HttpWebResponse || - _type == WebHeaderCollectionType.HttpListenerResponse; + return _type == WebHeaderCollectionType.WebResponse; } } @@ -141,15 +129,7 @@ public override void Set(string name, string? value) } name = HttpValidationHelpers.CheckBadHeaderNameChars(name); - ThrowOnRestrictedHeader(name); value = HttpValidationHelpers.CheckBadHeaderValueChars(value); - if (_type == WebHeaderCollectionType.WebResponse) - { - if (value != null && value.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } InvalidateCachedArrays(); InnerCollection.Set(name, value); } @@ -169,13 +149,6 @@ public void Set(HttpResponseHeader header, string? value) { throw new InvalidOperationException(SR.net_headers_rsp); } - if (_type == WebHeaderCollectionType.WebResponse) - { - if (value != null && value.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } this.Set(header.GetName(), value); } @@ -344,13 +317,6 @@ public void Add(HttpResponseHeader header, string? value) { throw new InvalidOperationException(SR.net_headers_rsp); } - if (_type == WebHeaderCollectionType.WebResponse) - { - if (value != null && value.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } this.Add(header.GetName(), value); } @@ -369,15 +335,7 @@ public void Add(string header) string name = header.Substring(0, colpos); string value = header.Substring(colpos + 1); name = HttpValidationHelpers.CheckBadHeaderNameChars(name); - ThrowOnRestrictedHeader(name); value = HttpValidationHelpers.CheckBadHeaderValueChars(value); - if (_type == WebHeaderCollectionType.WebResponse) - { - if (value != null && value.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(header), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } InvalidateCachedArrays(); InnerCollection.Add(name, value); } @@ -396,15 +354,7 @@ public override void Add(string name, string? value) } name = HttpValidationHelpers.CheckBadHeaderNameChars(name); - ThrowOnRestrictedHeader(name); value = HttpValidationHelpers.CheckBadHeaderValueChars(value); - if (_type == WebHeaderCollectionType.WebResponse) - { - if (value != null && value.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } InvalidateCachedArrays(); InnerCollection.Add(name, value); } @@ -413,35 +363,10 @@ protected void AddWithoutValidate(string headerName, string? headerValue) { headerName = HttpValidationHelpers.CheckBadHeaderNameChars(headerName); headerValue = HttpValidationHelpers.CheckBadHeaderValueChars(headerValue); - if (_type == WebHeaderCollectionType.WebResponse) - { - if (headerValue != null && headerValue.Length > ushort.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(headerValue), headerValue, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); - } - } InvalidateCachedArrays(); InnerCollection.Add(headerName, headerValue); } - internal void ThrowOnRestrictedHeader(string headerName) - { - if (_type == WebHeaderCollectionType.HttpWebRequest) - { - if (HeaderInfo[headerName].IsRequestRestricted) - { - throw new ArgumentException(SR.Format(SR.net_headerrestrict, headerName), nameof(headerName)); - } - } - else if (_type == WebHeaderCollectionType.HttpListenerResponse) - { - if (HeaderInfo[headerName].IsResponseRestricted) - { - throw new ArgumentException(SR.Format(SR.net_headerrestrict, headerName), nameof(headerName)); - } - } - } - // Remove - // Routine Description: // Removes give header with validation to see if they are "proper" headers. @@ -463,7 +388,6 @@ public override void Remove(string name) { throw new ArgumentNullException(nameof(name)); } - ThrowOnRestrictedHeader(name); name = HttpValidationHelpers.CheckBadHeaderNameChars(name); if (_innerCollection != null) { diff --git a/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs b/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs index 5e8b33364c66..6adb462906b7 100644 --- a/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs +++ b/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs @@ -752,5 +752,25 @@ public void NameValue_Set_Success() Assert.Equal(new[] { "firstName" }, w.AllKeys); Assert.Equal("first", w["firstName"]); } + + [Fact] + public void AddLongString_DoesNotThrow() + { + string longString = new string('a', 65536); + WebHeaderCollection headerCollection = new WebHeaderCollection(); + + headerCollection.Add("Long-Header", longString); + headerCollection["Long-Header-2"] = longString; + + headerCollection.Add(HttpResponseHeader.SetCookie, "someValueToChangeType"); // this will implicitly change _type + + headerCollection.Add("Long-Header-3", longString); + headerCollection["Long-Header-4"] = longString; + + Assert.Equal(longString, headerCollection["Long-Header"]); + Assert.Equal(longString, headerCollection["Long-Header-2"]); + Assert.Equal(longString, headerCollection["Long-Header-3"]); + Assert.Equal(longString, headerCollection["Long-Header-4"]); + } } } From 77b752b7cec435943668df438ab9cb33d5ece253 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 11 Aug 2020 16:18:34 +0200 Subject: [PATCH 390/755] Add additional Windows-specific APIs (#40610) * mark System.Data.OleDb assembly as Windows-specific * mark System.Windows.Extensions assembly as Windows-specific * mark System.IO.FileInfo Encrypt and Decrypt methods as Windows-specific * System.Runtime.InteropServices * VB * mark entire ComWrappers type as Windows-specific * mark CspParameters class as Windows-specific --- .../InteropServices/ComEventsHelper.cs | 3 +++ .../Runtime/InteropServices/ComWrappers.cs | 2 ++ .../Directory.Build.props | 1 + .../ref/Microsoft.VisualBasic.Core.cs | 20 +++++++++++++++---- .../src/Microsoft/VisualBasic/DateAndTime.vb | 5 +++++ .../src/Microsoft/VisualBasic/FileSystem.vb | 5 +++++ .../src/Microsoft/VisualBasic/Interaction.vb | 7 +++++++ .../src/Microsoft/VisualBasic/Strings.vb | 1 + .../System.Data.OleDb/Directory.Build.props | 1 + .../ref/System.IO.FileSystem.cs | 2 ++ .../src/System/IO/FileInfo.cs | 3 +++ .../InteropServices/ComEventsHelpers.NoCom.cs | 3 +++ .../ComWrappers.PlatformNotSupported.cs | 2 ++ .../InteropServices/DispatchWrapper.cs | 2 +- .../ref/System.Runtime.InteropServices.cs | 6 +++++- .../InteropServices/ComAwareEventInfo.cs | 3 +++ .../ref/System.Security.Cryptography.Csp.cs | 1 + .../Security/Cryptography/CspParameters.cs | 2 ++ .../Directory.Build.props | 1 + 19 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs index 368d942f403a..93fd276b9d26 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelper.cs @@ -81,12 +81,15 @@ // means that the problem is already quite complex and we should not be dealing with it - see // ComEventsMethod.Invoke +using System.Runtime.Versioning; + namespace System.Runtime.InteropServices { /// /// The static methods provided in ComEventsHelper allow using .NET delegates to subscribe to events /// raised COM objects. /// + [SupportedOSPlatform("windows")] public static class ComEventsHelper { /// diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index 1b0c1a717487..1e377a9978f4 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Threading; using System.Runtime.CompilerServices; +using System.Runtime.Versioning; using Internal.Runtime.CompilerServices; namespace System.Runtime.InteropServices @@ -68,6 +69,7 @@ internal enum ComWrappersScenario /// /// Class for managing wrappers of COM IUnknown types. /// + [SupportedOSPlatform("windows")] [CLSCompliant(false)] public abstract partial class ComWrappers { diff --git a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props index df1a19548772..de631ebfa736 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props +++ b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props @@ -5,5 +5,6 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) 10.0.6.0 Microsoft + true \ No newline at end of file diff --git a/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs b/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs index db978528bf99..922902e5d964 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/ref/Microsoft.VisualBasic.Core.cs @@ -250,12 +250,12 @@ internal Conversion() { } public sealed partial class DateAndTime { internal DateAndTime() { } - public static string DateString { get { throw null; } set { } } + public static string DateString { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static System.DateTime Now { get { throw null; } } - public static System.DateTime TimeOfDay { get { throw null; } set { } } + public static System.DateTime TimeOfDay { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static double Timer { get { throw null; } } - public static string TimeString { get { throw null; } set { } } - public static System.DateTime Today { get { throw null; } set { } } + public static string TimeString { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public static System.DateTime Today { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static System.DateTime DateAdd(Microsoft.VisualBasic.DateInterval Interval, double Number, System.DateTime DateValue) { throw null; } public static System.DateTime DateAdd(string Interval, double Number, object? DateValue) { throw null; } public static long DateDiff(Microsoft.VisualBasic.DateInterval Interval, System.DateTime Date1, System.DateTime Date2, Microsoft.VisualBasic.FirstDayOfWeek DayOfWeek = Microsoft.VisualBasic.FirstDayOfWeek.Sunday, Microsoft.VisualBasic.FirstWeekOfYear WeekOfYear = Microsoft.VisualBasic.FirstWeekOfYear.Jan1) { throw null; } @@ -332,11 +332,15 @@ public sealed partial class FileSystem { internal FileSystem() { } public static void ChDir(string Path) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void ChDrive(char Drive) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void ChDrive(string? Drive) { } public static string CurDir() { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string CurDir(char Drive) { throw null; } public static string Dir() { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string Dir(string PathName, Microsoft.VisualBasic.FileAttribute Attributes = Microsoft.VisualBasic.FileAttribute.Normal) { throw null; } public static bool EOF(int FileNumber) { throw null; } public static Microsoft.VisualBasic.OpenMode FileAttr(int FileNumber) { throw null; } @@ -401,6 +405,7 @@ public static void Lock(int FileNumber, long FromRecord, long ToRecord) { } public static void MkDir(string Path) { } public static void Print(int FileNumber, params object[] Output) { } public static void PrintLine(int FileNumber, params object[] Output) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void Rename(string OldPath, string NewPath) { } public static void Reset() { } public static void RmDir(string Path) { } @@ -486,21 +491,27 @@ public sealed partial class Interaction internal Interaction() { } public static void AppActivate(int ProcessId) { } public static void AppActivate(string Title) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void Beep() { } public static object? CallByName(object? ObjectRef, string ProcName, Microsoft.VisualBasic.CallType UseCallType, params object?[] Args) { throw null; } public static object? Choose(double Index, params object?[] Choice) { throw null; } public static string Command() { throw null; } public static object CreateObject(string ProgId, string? ServerName = "") { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void DeleteSetting(string AppName, string? Section = null, string? Key = null) { } public static string Environ(string? Expression) { throw null; } public static string Environ(int Expression) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string[,]? GetAllSettings(string AppName, string Section) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static object? GetObject(string? PathName = null, string? Class = null) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string? GetSetting(string AppName, string Section, string Key, string? Default = "") { throw null; } public static object? IIf(bool Expression, object? TruePart, object? FalsePart) { throw null; } public static string InputBox(string Prompt, string Title = "", string DefaultResponse = "", int XPos = -1, int YPos = -1) { throw null; } public static MsgBoxResult MsgBox(object Prompt, MsgBoxStyle Buttons = MsgBoxStyle.ApplicationModal, object? Title = null) { throw null; } public static string Partition(long Number, long Start, long Stop, long Interval) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void SaveSetting(string AppName, string Section, string Key, string Setting) { } public static int Shell(string PathName, AppWinStyle Style = AppWinStyle.MinimizedFocus, bool Wait = false, int Timeout = -1) { throw null; } public static object? Switch(params object?[]? VarExpr) { throw null; } @@ -634,6 +645,7 @@ internal Strings() { } public static string Space(int Number) { throw null; } public static string[] Split(string? Expression, string? Delimiter = " ", int Limit = -1, [Microsoft.VisualBasic.CompilerServices.OptionCompareAttribute] Microsoft.VisualBasic.CompareMethod Compare = Microsoft.VisualBasic.CompareMethod.Binary) { throw null; } public static int StrComp(string? String1, string? String2, Microsoft.VisualBasic.CompareMethod Compare = Microsoft.VisualBasic.CompareMethod.Binary) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static string? StrConv(string? str, Microsoft.VisualBasic.VbStrConv Conversion, int LocaleID = 0) { throw null; } public static string StrDup(int Number, char Character) { throw null; } public static object StrDup(int Number, object Character) { throw null; } diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/DateAndTime.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/DateAndTime.vb index bbaf10c8f723..44623d97fbb6 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/DateAndTime.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/DateAndTime.vb @@ -3,6 +3,7 @@ Imports System Imports System.Globalization +Imports System.Runtime.Versioning Imports Microsoft.VisualBasic.CompilerServices Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils Imports Microsoft.VisualBasic.CompilerServices.Utils @@ -20,6 +21,7 @@ Namespace Microsoft.VisualBasic Get Return DateTime.Today End Get + Set(ByVal Value As DateTime) SetDate(Value) End Set @@ -38,6 +40,7 @@ Namespace Microsoft.VisualBasic 'Truncate to the nearest second Return New DateTime(Ticks - Ticks Mod TimeSpan.TicksPerSecond) End Get + Set(ByVal Value As DateTime) SetTime(Value) End Set @@ -49,6 +52,7 @@ Namespace Microsoft.VisualBasic Get Return (New DateTime(DateTime.Now.TimeOfDay.Ticks)).ToString("HH:mm:ss", GetInvariantCultureInfo()) End Get + Set(ByVal Value As String) Dim dt As Date @@ -93,6 +97,7 @@ Namespace Microsoft.VisualBasic Return DateTime.Today.ToString("MM\-dd\-yyyy", GetInvariantCultureInfo()) End If End Get + Set(ByVal Value As String) Dim NewDate As Date diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/FileSystem.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/FileSystem.vb index 35ce134ec2d1..34c75b914ff2 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/FileSystem.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/FileSystem.vb @@ -73,6 +73,7 @@ Namespace Microsoft.VisualBasic End Sub + Public Sub ChDrive(ByVal Drive As Char) Drive = System.Char.ToUpperInvariant(Drive) @@ -87,6 +88,7 @@ Namespace Microsoft.VisualBasic IO.Directory.SetCurrentDirectory(Drive & Path.VolumeSeparatorChar) End Sub + Public Sub ChDrive(ByVal Drive As String) Debug.Assert(Not System.Reflection.Assembly.GetCallingAssembly() Is Utils.VBRuntimeAssembly, "Methods in Microsoft.VisualBasic should not call FileSystem public method.") @@ -105,6 +107,7 @@ Namespace Microsoft.VisualBasic Return Directory.GetCurrentDirectory() End Function + Public Function CurDir(ByVal Drive As Char) As String Debug.Assert(Not System.Reflection.Assembly.GetCallingAssembly() Is Utils.VBRuntimeAssembly, "Methods in Microsoft.VisualBasic should not call FileSystem public method.") @@ -130,6 +133,7 @@ Namespace Microsoft.VisualBasic Return FindNextFile(System.Reflection.Assembly.GetCallingAssembly()) End Function + Public Function Dir(ByVal PathName As String, Optional ByVal Attributes As FileAttribute = FileAttribute.Normal) As String @@ -1160,6 +1164,7 @@ Namespace Microsoft.VisualBasic CloseAllFiles(System.Reflection.Assembly.GetCallingAssembly()) End Sub + Public Sub Rename(ByVal OldPath As String, ByVal NewPath As String) diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Interaction.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Interaction.vb index 9be740f7c613..b8ec8bdb31a5 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Interaction.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Interaction.vb @@ -5,6 +5,7 @@ Imports System Imports System.Reflection Imports System.Text Imports System.Runtime.InteropServices +Imports System.Runtime.Versioning Imports Microsoft.Win32 Imports Microsoft.VisualBasic.CompilerServices @@ -117,6 +118,7 @@ Namespace Microsoft.VisualBasic ' User interaction functions. '============================================================================ + Public Sub Beep() #If TARGET_WINDOWS Then UnsafeNativeMethods.MessageBeep(0) @@ -315,6 +317,7 @@ Namespace Microsoft.VisualBasic ' Registry functions. '============================================================================ + Public Sub DeleteSetting(ByVal AppName As String, Optional ByVal Section As String = Nothing, Optional ByVal Key As String = Nothing) Dim AppSection As String Dim UserKey As RegistryKey @@ -346,6 +349,7 @@ Namespace Microsoft.VisualBasic End Try End Sub + Public Function GetAllSettings(ByVal AppName As String, ByVal Section As String) As String(,) Dim rk As RegistryKey Dim sAppSect As String @@ -404,6 +408,7 @@ Namespace Microsoft.VisualBasic End Try End Function + Public Function GetSetting(ByVal AppName As String, ByVal Section As String, ByVal Key As String, Optional ByVal [Default] As String = "") As String Dim rk As RegistryKey = Nothing Dim sAppSect As String @@ -443,6 +448,7 @@ Namespace Microsoft.VisualBasic End If End Function + Public Sub SaveSetting(ByVal AppName As String, ByVal Section As String, ByVal Key As String, ByVal Setting As String) Dim rk As RegistryKey Dim sIniSect As String @@ -534,6 +540,7 @@ Namespace Microsoft.VisualBasic End Try End Function + Public Function GetObject(Optional ByVal PathName As String = Nothing, Optional ByVal [Class] As String = Nothing) As Object 'Only works for Com2 objects, not for COM+ objects. diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Strings.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Strings.vb index 3db1df01ad95..d0fabafab219 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Strings.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Strings.vb @@ -1996,6 +1996,7 @@ RedimAndExit: End Try End Function + Public Function StrConv(ByVal [str] As String, ByVal Conversion As VbStrConv, Optional ByVal LocaleID As Integer = 0) As String #If TARGET_WINDOWS Then Try diff --git a/src/libraries/System.Data.OleDb/Directory.Build.props b/src/libraries/System.Data.OleDb/Directory.Build.props index 571905e4aade..cef5ef637b16 100644 --- a/src/libraries/System.Data.OleDb/Directory.Build.props +++ b/src/libraries/System.Data.OleDb/Directory.Build.props @@ -1,5 +1,6 @@  + true \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs index e6fbef2727e0..f84978d9b5e1 100644 --- a/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs +++ b/src/libraries/System.IO.FileSystem/ref/System.IO.FileSystem.cs @@ -190,8 +190,10 @@ public FileInfo(string fileName) { } public System.IO.FileInfo CopyTo(string destFileName, bool overwrite) { throw null; } public System.IO.FileStream Create() { throw null; } public System.IO.StreamWriter CreateText() { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void Decrypt() { } public override void Delete() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public void Encrypt() { } public void MoveTo(string destFileName) { } public void MoveTo(string destFileName, bool overwrite) { } diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/FileInfo.cs b/src/libraries/System.IO.FileSystem/src/System/IO/FileInfo.cs index b901d6577f71..fc391cdf8147 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/FileInfo.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/FileInfo.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Text; +using System.Runtime.Versioning; #if MS_IO_REDIST namespace Microsoft.IO @@ -182,8 +183,10 @@ public FileInfo Replace(string destinationFileName, string? destinationBackupFil return new FileInfo(destinationFileName); } + [SupportedOSPlatform("windows")] public void Decrypt() => File.Decrypt(FullPath); + [SupportedOSPlatform("windows")] public void Encrypt() => File.Encrypt(FullPath); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs index 7db1b92b16cf..394aa67d4df5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; + namespace System.Runtime.InteropServices { + [SupportedOSPlatform("windows")] public static class ComEventsHelper { public static void Combine(object rcw, Guid iid, int dispid, Delegate d) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs index 62aa162cbd02..3a622258b6e3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; +using System.Runtime.Versioning; namespace System.Runtime.InteropServices { @@ -21,6 +22,7 @@ public enum CreateObjectFlags UniqueInstance = 2, } + [SupportedOSPlatform("windows")] [CLSCompliant(false)] public abstract class ComWrappers { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs index 740d69aefde6..599830febf70 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/DispatchWrapper.cs @@ -6,6 +6,7 @@ namespace System.Runtime.InteropServices { // Wrapper that is converted to a variant with VT_DISPATCH + [SupportedOSPlatform("windows")] public sealed class DispatchWrapper { public DispatchWrapper(object? obj) @@ -22,7 +23,6 @@ public DispatchWrapper(object? obj) } } - [SupportedOSPlatform("windows")] public object? WrappedObject { get; } } } 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 7bc7065a9f01..8eebad55c02c 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -181,6 +181,7 @@ public ComAwareEventInfo(System.Type type, string eventName) { } public override System.Reflection.Module Module { get { throw null; } } public override string Name { get { throw null; } } public override System.Type? ReflectedType { get { throw null; } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public override void AddEventHandler(object target, System.Delegate handler) { } public override System.Reflection.MethodInfo? GetAddMethod(bool nonPublic) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } @@ -190,6 +191,7 @@ public override void AddEventHandler(object target, System.Delegate handler) { } public override System.Reflection.MethodInfo? GetRaiseMethod(bool nonPublic) { throw null; } public override System.Reflection.MethodInfo? GetRemoveMethod(bool nonPublic) { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public override void RemoveEventHandler(object target, System.Delegate handler) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, Inherited=false)] @@ -220,6 +222,7 @@ public ComEventInterfaceAttribute(System.Type SourceInterface, System.Type Event public System.Type EventProvider { get { throw null; } } public System.Type SourceInterface { get { throw null; } } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static partial class ComEventsHelper { @@ -313,11 +316,11 @@ public sealed partial class DefaultParameterValueAttribute : System.Attribute public DefaultParameterValueAttribute(object? value) { } public object? Value { get { throw null; } } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class DispatchWrapper { public DispatchWrapper(object? obj) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public object? WrappedObject { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Property, Inherited=false)] @@ -1019,6 +1022,7 @@ public enum CreateObjectFlags TrackerObject = 1, UniqueInstance = 2, } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.CLSCompliantAttribute(false)] public abstract class ComWrappers { diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs index 5bc80c6831de..197e8532b484 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection; +using System.Runtime.Versioning; // This type is obsolete, and is expected to be used in very specific ways or it may // throw null reference exceptions. @@ -19,6 +20,7 @@ public ComAwareEventInfo(Type type, string eventName) _innerEventInfo = type.GetEvent(eventName)!; } + [SupportedOSPlatform("windows")] #pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void AddEventHandler(object target, Delegate handler) #pragma warning restore CS8765 @@ -36,6 +38,7 @@ public override void AddEventHandler(object target, Delegate handler) } } + [SupportedOSPlatform("windows")] #pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void RemoveEventHandler(object target, Delegate handler) #pragma warning restore CS8765 diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs index d7b4db182225..35ccd65f4a2d 100644 --- a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs +++ b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs @@ -44,6 +44,7 @@ public CspKeyContainerInfo(System.Security.Cryptography.CspParameters parameters public bool Removable { get { throw null; } } public string UniqueKeyContainerName { get { throw null; } } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public sealed partial class CspParameters { public string? KeyContainerName; diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs index fa47f3992f10..67cb9c55f863 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs @@ -4,10 +4,12 @@ using System; using System.Diagnostics; using System.Security.Cryptography; +using System.Runtime.Versioning; using Internal.NativeCrypto; namespace System.Security.Cryptography { + [SupportedOSPlatform("windows")] public sealed class CspParameters { public int ProviderType; diff --git a/src/libraries/System.Windows.Extensions/Directory.Build.props b/src/libraries/System.Windows.Extensions/Directory.Build.props index bdcfca3b543c..2f8a8940e012 100644 --- a/src/libraries/System.Windows.Extensions/Directory.Build.props +++ b/src/libraries/System.Windows.Extensions/Directory.Build.props @@ -2,5 +2,6 @@ Open + true \ No newline at end of file From 50cd0c80315fe63ddabc57b83b86825ccb7076bd Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Tue, 11 Aug 2020 09:02:41 -0700 Subject: [PATCH 391/755] Remove unused locals in System.Security namespaces --- .../RSA/EncryptDecrypt.cs | 2 +- .../src/System/Security/AccessControl/ACL.cs | 1 - .../tests/RawAcl/RawAcl_RemoveAce.cs | 21 ++++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs index 85bdd124d8a6..891fbae55481 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs @@ -610,7 +610,7 @@ public void RsaDecryptAfterExport() byte[] crypt = Encrypt(rsa, TestData.HelloBytes, RSAEncryptionPadding.OaepSHA1); // Export the key, this should not clear/destroy the key. - RSAParameters ignored = rsa.ExportParameters(true); + rsa.ExportParameters(true); output = Decrypt(rsa, crypt, RSAEncryptionPadding.OaepSHA1); } diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs index 7f4c20d21a73..16dd918e4b95 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs @@ -587,7 +587,6 @@ public void InsertAce(int index, GenericAce ace) public void RemoveAce(int index) { - GenericAce ace = _aces[index]; _aces.RemoveAt(index); } diff --git a/src/libraries/System.Security.AccessControl/tests/RawAcl/RawAcl_RemoveAce.cs b/src/libraries/System.Security.AccessControl/tests/RawAcl/RawAcl_RemoveAce.cs index 3c385bc4c9fb..0cd61bc5193e 100644 --- a/src/libraries/System.Security.AccessControl/tests/RawAcl/RawAcl_RemoveAce.cs +++ b/src/libraries/System.Security.AccessControl/tests/RawAcl/RawAcl_RemoveAce.cs @@ -35,11 +35,22 @@ public static void TestRemoveAce(string sddl) count = rawAcl.Count; //test remove at -1 - Assert.Throws(() => - { - index = -1; - rawAcl.RemoveAce(index); - }); + AssertExtensions.Throws( + "index", + () => + { + index = -1; + rawAcl.RemoveAce(index); + }); + + //test remove at value too large + AssertExtensions.Throws( + "index", + () => + { + index = int.MaxValue; + rawAcl.RemoveAce(index); + }); //test remove at 0, only need to catch ArgumentOutOfRangeException if Count = 0 index = 0; From 65e51b7d7c3bd1c4f420931480bf4b09b6fb578d Mon Sep 17 00:00:00 2001 From: Alessio Franceschelli Date: Tue, 11 Aug 2020 17:22:02 +0100 Subject: [PATCH 392/755] Fixed XML docs for ILoggingBuilder AddProvider extension method (#40649) The description of the parameter was reversed. --- .../src/LoggingBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Logging/src/LoggingBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Logging/src/LoggingBuilderExtensions.cs index 7c90edff807b..ea3b7b0cb2b3 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/LoggingBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging/src/LoggingBuilderExtensions.cs @@ -29,7 +29,7 @@ public static ILoggingBuilder SetMinimumLevel(this ILoggingBuilder builder, LogL /// /// Adds the given to the /// - /// The to add to the . + /// The to add the to. /// The to add to the . /// The so that additional calls can be chained. public static ILoggingBuilder AddProvider(this ILoggingBuilder builder, ILoggerProvider provider) From 09048ded3891d3ebf0a396049286d2fa4cee0eff Mon Sep 17 00:00:00 2001 From: Carlos Sanchez <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 11 Aug 2020 09:39:56 -0700 Subject: [PATCH 393/755] Fix: FileStream.Dispose silently fails on Dispose when disk has run out of space (#38742) * Save last error info in SafeFileHandle.ReleaseHandle and read it in FileStream.Dispose * Add manual test * Remove Debug.Fail from SafeFileHandle, automate the drive filling step in the manual test, add suggested comments, make threadstatic field static. * Address suggestions * Update src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs Co-authored-by: Jan Kotas Co-authored-by: carlossanlop Co-authored-by: Jan Kotas --- .../System.IO.FileSystem.sln | 6 ++ .../tests/ManualTests/ManualTests.cs | 79 +++++++++++++++++++ .../System.IO.FileSystem.Manual.Tests.csproj | 8 ++ .../Win32/SafeHandles/SafeFileHandle.Unix.cs | 21 ++--- .../src/System/IO/FileStream.Unix.cs | 14 ++++ 5 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs create mode 100644 src/libraries/System.IO.FileSystem/tests/ManualTests/System.IO.FileSystem.Manual.Tests.csproj diff --git a/src/libraries/System.IO.FileSystem/System.IO.FileSystem.sln b/src/libraries/System.IO.FileSystem/System.IO.FileSystem.sln index e18c3a128894..3d4bdc1f490f 100644 --- a/src/libraries/System.IO.FileSystem/System.IO.FileSystem.sln +++ b/src/libraries/System.IO.FileSystem/System.IO.FileSystem.sln @@ -22,6 +22,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2ED EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{66810085-C596-4ED4-ACEE-C939CBD55C4E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.IO.FileSystem.ManualTests", "tests\ManualTests\System.IO.FileSystem.Manual.Tests.csproj", "{70FA2031-8D6E-4127-901E-2B0D90420E08}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -44,6 +46,10 @@ Global {66810085-C596-4ED4-ACEE-C939CBD55C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {66810085-C596-4ED4-ACEE-C939CBD55C4E}.Release|Any CPU.ActiveCfg = Release|Any CPU {66810085-C596-4ED4-ACEE-C939CBD55C4E}.Release|Any CPU.Build.0 = Release|Any CPU + {70FA2031-8D6E-4127-901E-2B0D90420E08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70FA2031-8D6E-4127-901E-2B0D90420E08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70FA2031-8D6E-4127-901E-2B0D90420E08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70FA2031-8D6E-4127-901E-2B0D90420E08}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs b/src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs new file mode 100644 index 000000000000..0e8ae5b96804 --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs @@ -0,0 +1,79 @@ +// 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.IO; +using Microsoft.DotNet.XUnitExtensions; +using Xunit; + +namespace System.IO.ManualTests +{ + public class FileSystemManualTests + { + public static bool ManualTestsEnabled => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MANUAL_TESTS")); + + [ConditionalFact(nameof(ManualTestsEnabled))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public static void Throw_FileStreamDispose_WhenRemoteMountRunsOutOfSpace() + { + /* + + Example of mounting a remote folder using sshfs and two Linux machines: + + In remote machine: + - Install openssh-server. + - Create an ext4 partition of 1 MB size. + + In local machine: + - Install sshfs and openssh-client. + - Create a local folder inside the current user's home, named "mountedremote": + $ mkdir ~/mountedremote + - Mount the remote folder into "mountedremote": + $ sudo sshfs -o allow_other,default_permissions remoteuser@xxx.xxx.xxx.xxx:/home/remoteuser/share /home/localuser/mountedremote + - Set the environment variable MANUAL_TESTS=1 + - Run this manual test. + - Expect the exception. + - Unmount the folder: + $ fusermount -u ~/mountedremote + */ + + string mountedPath = $"{Environment.GetEnvironmentVariable("HOME")}/mountedremote"; + string largefile = $"{mountedPath}/largefile.txt"; + string origin = $"{mountedPath}/copyme.txt"; + string destination = $"{mountedPath}/destination.txt"; + + // Ensure the remote folder exists + Assert.True(Directory.Exists(mountedPath)); + + // Delete copied file if exists + if (File.Exists(destination)) + { + File.Delete(destination); + } + + // Create huge file if not exists + if (!File.Exists(largefile)) + { + File.WriteAllBytes(largefile, new byte[925696]); + } + + // Create original file if not exists + if (!File.Exists(origin)) + { + File.WriteAllBytes(origin, new byte[8192]); + } + + Assert.True(File.Exists(largefile)); + Assert.True(File.Exists(origin)); + + using FileStream originStream = new FileStream(origin, FileMode.Open, FileAccess.Read); + Stream destinationStream = new FileStream(destination, FileMode.Create, FileAccess.Write); + originStream.CopyTo(destinationStream, 1); + + Assert.Throws(() => + { + destinationStream.Dispose(); + }); + } + } +} diff --git a/src/libraries/System.IO.FileSystem/tests/ManualTests/System.IO.FileSystem.Manual.Tests.csproj b/src/libraries/System.IO.FileSystem/tests/ManualTests/System.IO.FileSystem.Manual.Tests.csproj new file mode 100644 index 000000000000..3f5205d6a20d --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/ManualTests/System.IO.FileSystem.Manual.Tests.csproj @@ -0,0 +1,8 @@ + + + $(NetCoreAppCurrent) + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs index 61b240fa62e5..d8f83af4134a 100644 --- a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs @@ -92,19 +92,9 @@ private static bool DirectoryExists(string fullPath) return ((fileinfo.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR); } - /// Opens a SafeFileHandle for a file descriptor created by a provided delegate. - /// - /// The function that creates the file descriptor. Returns the file descriptor on success, or an invalid - /// file descriptor on error with Marshal.GetLastWin32Error() set to the error code. - /// - /// The created SafeFileHandle. - internal static SafeFileHandle Open(Func fdFunc) - { - SafeFileHandle handle = Interop.CheckIo(fdFunc()); - - Debug.Assert(!handle.IsInvalid, "File descriptor is invalid"); - return handle; - } + // Each thread will have its own copy. This prevents race conditions if the handle had the last error. + [ThreadStatic] + internal static Interop.ErrorInfo? t_lastCloseErrorInfo; protected override bool ReleaseHandle() { @@ -120,7 +110,10 @@ protected override bool ReleaseHandle() // to retry, as the descriptor could actually have been closed, been subsequently reassigned, and // be in use elsewhere in the process. Instead, we simply check whether the call was successful. int result = Interop.Sys.Close(handle); - Debug.Assert(result == 0, $"Close failed with result {result} and error {Interop.Sys.GetLastErrorInfo()}"); + if (result != 0) + { + t_lastCloseErrorInfo = Interop.Sys.GetLastErrorInfo(); + } return result == 0; } 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 8d823b5362fb..e7f88524b6b4 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 @@ -267,6 +267,20 @@ protected override void Dispose(bool disposing) // name will be removed immediately. Interop.Sys.Unlink(_path); // ignore errors; it's valid that the path may no longer exist } + + // Closing the file handle can fail, e.g. due to out of disk space + // Throw these errors as exceptions when disposing + if (_fileHandle != null && !_fileHandle.IsClosed && disposing) + { + SafeFileHandle.t_lastCloseErrorInfo = null; + + _fileHandle.Dispose(); + + if (SafeFileHandle.t_lastCloseErrorInfo != null) + { + throw Interop.GetExceptionForIoErrno(SafeFileHandle.t_lastCloseErrorInfo.GetValueOrDefault(), _path, isDirectory: false); + } + } } } finally From 5e220a614d5f2e555cea9f52601de99a29e59327 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 11 Aug 2020 18:47:36 +0200 Subject: [PATCH 394/755] Improve error details on DNS Telemetry test failure (#40665) --- .../tests/FunctionalTests/TelemetryTest.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libraries/System.Net.NameResolution/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.NameResolution/tests/FunctionalTests/TelemetryTest.cs index 739ae3c39e06..e0516f6dec09 100644 --- a/src/libraries/System.Net.NameResolution/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.NameResolution/tests/FunctionalTests/TelemetryTest.cs @@ -49,8 +49,6 @@ await listener.RunWithCallbackAsync(events.Enqueue, async () => Assert.DoesNotContain(events, e => e.EventId == 0); // errors from the EventSource itself - Assert.True(events.Count >= 2 * 6); - EventWrittenEventArgs[] starts = events.Where(e => e.EventName == "ResolutionStart").ToArray(); Assert.Equal(6, starts.Length); Assert.All(starts, s => Assert.Equal(ValidHostName, Assert.Single(s.Payload).ToString())); @@ -87,8 +85,6 @@ await listener.RunWithCallbackAsync(events.Enqueue, async () => Assert.DoesNotContain(events, e => e.EventId == 0); // errors from the EventSource itself - Assert.True(events.Count >= 3 * 6); - EventWrittenEventArgs[] starts = events.Where(e => e.EventName == "ResolutionStart").ToArray(); Assert.Equal(6, starts.Length); Assert.All(starts, s => Assert.Equal(InvalidHostName, Assert.Single(s.Payload).ToString())); @@ -129,8 +125,6 @@ await listener.RunWithCallbackAsync(events.Enqueue, async () => Assert.DoesNotContain(events, e => e.EventId == 0); // errors from the EventSource itself // Each GetHostEntry over an IP will yield 2 resolutions - Assert.True(events.Count >= 2 * 2 * 6); - EventWrittenEventArgs[] starts = events.Where(e => e.EventName == "ResolutionStart").ToArray(); Assert.Equal(12, starts.Length); Assert.Equal(6, starts.Count(s => Assert.Single(s.Payload).ToString() == ValidIPAddress)); From c78acdc4789e584cba370324bae3ea33e2b3d169 Mon Sep 17 00:00:00 2001 From: Buyaa Date: Tue, 11 Aug 2020 09:57:28 -0700 Subject: [PATCH 395/755] ICommand CanExecuteChanged should be nullable (#40648) --- src/libraries/System.ObjectModel/ref/System.ObjectModel.cs | 2 +- .../System.ObjectModel/src/System/Windows/Input/ICommand.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs index 150918a79900..582af3077aff 100644 --- a/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs +++ b/src/libraries/System.ObjectModel/ref/System.ObjectModel.cs @@ -227,7 +227,7 @@ namespace System.Windows.Input [System.Windows.Markup.ValueSerializerAttribute("System.Windows.Input.CommandValueSerializer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")] public partial interface ICommand { - event System.EventHandler CanExecuteChanged; + event System.EventHandler? CanExecuteChanged; bool CanExecute(object? parameter); void Execute(object? parameter); } diff --git a/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs b/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs index 4fde07c4d693..2fea0d73c10e 100644 --- a/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs +++ b/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs @@ -18,7 +18,7 @@ public interface ICommand /// /// Raised when the ability of the command to execute has changed. /// - event EventHandler CanExecuteChanged; + event EventHandler? CanExecuteChanged; /// /// Returns whether the command can be executed. From 302875d7f264e09e651d893bce23fb4f03e10a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Tue, 11 Aug 2020 19:33:44 +0200 Subject: [PATCH 396/755] HTTP/2 Continuation test (#40533) --- .../Net/Http/Http2LoopbackConnection.cs | 65 +++++++++++++++---- .../tests/System/Net/Http/LoopbackServer.cs | 1 + .../tests/System/Net/Http/QPackTestDecoder.cs | 9 ++- .../HttpClientHandlerTest.Headers.cs | 33 +++++++++- .../HttpClientHandlerTest.Http2.cs | 46 +++++++++++++ 5 files changed, 138 insertions(+), 16 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 4701cecd248f..acf18f558c96 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -203,6 +203,8 @@ private async Task ReadFrameAsync(CancellationToken cancellationToken) return PingFrame.ReadFrom(header, data); case FrameType.GoAway: return GoAwayFrame.ReadFrom(header, data); + case FrameType.Continuation: + return ContinuationFrame.ReadFrom(header, data); default: return header; } @@ -531,10 +533,8 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) return body; } - public async Task<(int streamId, HttpRequestData requestData)> ReadAndParseRequestHeaderAsync(bool readBody = true) + public async IAsyncEnumerable ReadRequestHeadersFrames() { - HttpRequestData requestData = new HttpRequestData(); - // Receive HEADERS frame for request. Frame frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); if (frame == null) @@ -542,15 +542,58 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) throw new IOException("Failed to read Headers frame."); } Assert.Equal(FrameType.Headers, frame.Type); - HeadersFrame headersFrame = (HeadersFrame) frame; + Assert.Equal(FrameFlags.None, frame.Flags & ~(FrameFlags.EndStream | FrameFlags.EndHeaders)); + + yield return frame; + + // Receive CONTINUATION frames for request. + while ((FrameFlags.EndHeaders & frame.Flags) != FrameFlags.EndHeaders) + { + + frame = await ReadFrameAsync(_timeout).ConfigureAwait(false); + if (frame == null) + { + throw new IOException("Failed to read Continuation frame."); + } + Assert.Equal(FrameType.Continuation, frame.Type); + Assert.Equal(FrameFlags.None, frame.Flags & ~FrameFlags.EndHeaders); + + yield return frame; + } + + Assert.Equal(FrameFlags.EndHeaders, FrameFlags.EndHeaders & frame.Flags); + } - // TODO CONTINUATION support - Assert.Equal(FrameFlags.EndHeaders, FrameFlags.EndHeaders & headersFrame.Flags); + public async Task<(int streamId, HttpRequestData requestData)> ReadAndParseRequestHeaderAsync(bool readBody = true) + { + HttpRequestData requestData = new HttpRequestData(); - int streamId = headersFrame.StreamId; - requestData.RequestId = streamId; + bool endOfStream = false; + + using MemoryStream buffer = new MemoryStream(); + await foreach (Frame frame in ReadRequestHeadersFrames()) + { + switch (frame.Type) + { + case FrameType.Headers: + var headersFrame = (HeadersFrame)frame; + requestData.RequestId = headersFrame.StreamId; + endOfStream = (headersFrame.Flags & FrameFlags.EndStream) == FrameFlags.EndStream; + await buffer.WriteAsync(headersFrame.Data); + break; + case FrameType.Continuation: + var continuationFrame = (ContinuationFrame)frame; + await buffer.WriteAsync(continuationFrame.Data); + break; + default: + // Assert.Fail is already merged in xUnit but not released yet. Replace once available. + // https://github.com/xunit/xunit/issues/2105 + Assert.True(false, $"Unexpected frame type '{frame.Type}'"); + break; + } + } - Memory data = headersFrame.Data; + Memory data = buffer.ToArray(); int i = 0; while (i < data.Length) { @@ -567,13 +610,13 @@ public async Task ReadBodyAsync(bool expectEndOfStream = false) requestData.Method = requestData.GetSingleHeaderValue(":method"); requestData.Path = requestData.GetSingleHeaderValue(":path"); - if (readBody && (frame.Flags & FrameFlags.EndStream) == 0) + if (readBody && !endOfStream) { // Read body until end of stream if needed. requestData.Body = await ReadBodyAsync().ConfigureAwait(false); } - return (streamId, requestData); + return (requestData.RequestId, requestData); } public override Task InitializeConnectionAsync() diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 2c027ca702cd..e9c7aa120dc5 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -573,6 +573,7 @@ private async Task ReadLineBytesAsync() _readStart = 0; _readEnd = dataLength; _readBuffer = newBuffer; + startSearch = dataLength; } } diff --git a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs index feda8109688c..988ca365ea16 100644 --- a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs @@ -92,12 +92,15 @@ public static (int bytesConsumed, int value) DecodeInteger(ReadOnlySpan he ulong extra = 0; int length = 1; - byte b; + ulong b; do { - b = headerBlock[length++]; - extra = checked(extra << 7) | b; + // https://http2.github.io/http2-spec/compression.html#integer.representation + // HPack encodes integers from the least significant byte to the most. + // Every 7-bits of the next byte is shifted by (7 * index) and added to the result. + b = (ulong)headerBlock[length++]; + extra = checked(b << (7 * (length - 2))) | extra; } while ((b & 0b10000000) != 0); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs index 3ed0f554fc06..d0bf72883344 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs @@ -45,6 +45,35 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }); } + [Fact] + public async Task SendAsync_LargeHeaders_CorrectlyWritten() + { + // Intentionally larger than 16K in total because that's the limit that will trigger a CONTINUATION frame in HTTP2. + string largeHeaderValue = new string('a', 1024); + int count = 20; + + await LoopbackServerFactory.CreateClientAndServerAsync(async uri => + { + using HttpClient client = CreateHttpClient(); + + var message = new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion }; + for (int i = 0; i < count; i++) + { + message.Headers.TryAddWithoutValidation("large-header" + i, largeHeaderValue); + } + var response = await client.SendAsync(TestAsync, message).ConfigureAwait(false); + }, + async server => + { + HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK); + + for (int i = 0; i < count; i++) + { + Assert.Equal(largeHeaderValue, requestData.GetSingleHeaderValue("large-header" + i)); + } + }); + } + [Fact] public async Task SendAsync_DefaultHeaders_CorrectlyWritten() { @@ -383,7 +412,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync( using HttpClient client = CreateHttpClient(handler); - await client.SendAsync(requestMessage); + await client.SendAsync(TestAsync, requestMessage); foreach ((string name, _, _) in s_nonAsciiHeaders) { @@ -439,7 +468,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync( using HttpClient client = CreateHttpClient(handler); - using HttpResponseMessage response = await client.SendAsync(requestMessage); + using HttpResponseMessage response = await client.SendAsync(TestAsync, requestMessage); foreach ((string name, Encoding valueEncoding, string[] values) in s_nonAsciiHeaders) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index defa4719d64f..9ef63d4bbcb1 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -2954,6 +2954,52 @@ public async Task Http2GetAsync_TrailigPseudo_Throw() } } + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(2)] + public async Task Http2SendAsync_LargeHeaders_CorrectlyWritten(int continuationCount) + { + // Intentionally larger than 2x16K in total because that's the limit that will trigger a CONTINUATION frame in HTTP2. + string largeHeaderValue = new string('a', 1024); + int count = continuationCount * 16 + 1; + + await Http2LoopbackServer.CreateClientAndServerAsync(async uri => + { + using HttpClient client = CreateHttpClient(); + + var message = new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion }; + for (int i = 0; i < count; i++) + { + message.Headers.TryAddWithoutValidation("large-header" + i, largeHeaderValue); + } + var response = await client.SendAsync(TestAsync, message).ConfigureAwait(false); + }, + async server => + { + // Primes the connection, i.e. forces it to exchange SETTINGS whose ACK sometimes flushed the headers as well. + // See: https://github.com/dotnet/runtime/issues/860 for repro description. + (Http2LoopbackConnection connection, SettingsFrame clientSettings) = await server.EstablishConnectionGetSettingsAsync(); + + // Read individual frames and assert number of CONTINUATIONs. + int receivedContinuations = 0; + int streamId = 0; + await foreach (Frame frame in connection.ReadRequestHeadersFrames()) + { + if (frame.Type == FrameType.Headers) + { + streamId = ((HeadersFrame)frame).StreamId; + } + if (frame.Type == FrameType.Continuation) + { + ++receivedContinuations; + } + } + Assert.Equal(continuationCount, receivedContinuations); + await connection.SendResponseAsync(HttpStatusCode.OK, requestId: streamId); + }); + } + [Fact] public async Task InboundWindowSize_Exceeded_Throw() { From 71a216819169a7ce609326e9404eacf8fb267637 Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Tue, 11 Aug 2020 10:44:28 -0700 Subject: [PATCH 397/755] Add feed for Nodejs 12.x (#40667) --- eng/pipelines/coreclr/templates/run-performance-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index c38d33405cca..e19f24fc26ad 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -53,7 +53,7 @@ jobs: - IsInternal: '' - HelixApiAccessToken: '' - HelixPreCommandStemWindows: 'py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install --user azure.storage.blob==12.0.0 --force-reinstall;py -3 -m pip install --user azure.storage.queue==12.0.0 --force-reinstall;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get -y install nodejs;sudo apt-get -y install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get update;sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates;curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -;sudo apt-get -y install nodejs;sudo apt-get -y install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"' - ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"' - HelixPreCommand: '' From bfe783ce7c9d294c1670271fcaa4b6832f7541be Mon Sep 17 00:00:00 2001 From: Alessio Franceschelli Date: Tue, 11 Aug 2020 19:13:47 +0100 Subject: [PATCH 398/755] Extensions.Logging: JsonConsoleFormatter serializes scope and state properties using native json type (#40067) --- .../src/JsonConsoleFormatter.cs | 65 ++++- .../JsonConsoleFormatterTests.cs | 228 ++++++++++++++++-- 2 files changed, 274 insertions(+), 19 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs index 3a5aafe0cffe..aabb5ab2e413 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs @@ -2,12 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -83,7 +87,7 @@ public override void Write(in LogEntry logEntry, IExternalScopeP { foreach (KeyValuePair item in stateProperties) { - writer.WriteString(item.Key, ToInvariantString(item.Value)); + WriteItem(writer, item); } } writer.WriteEndObject(); @@ -128,7 +132,7 @@ private void WriteScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider state.WriteString("Message", scope.ToString()); foreach (KeyValuePair item in scopes) { - state.WriteString(item.Key, ToInvariantString(item.Value)); + WriteItem(state, item); } state.WriteEndObject(); } @@ -141,6 +145,63 @@ private void WriteScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider } } + private void WriteItem(Utf8JsonWriter writer, KeyValuePair item) + { + var key = item.Key; + switch (item.Value) + { + case bool boolValue: + writer.WriteBoolean(key, boolValue); + break; + case byte byteValue: + writer.WriteNumber(key, byteValue); + break; + case sbyte sbyteValue: + writer.WriteNumber(key, sbyteValue); + break; + case char charValue: +#if NETCOREAPP + writer.WriteString(key, MemoryMarshal.CreateSpan(ref charValue, 1)); +#else + writer.WriteString(key, charValue.ToString()); +#endif + break; + case decimal decimalValue: + writer.WriteNumber(key, decimalValue); + break; + case double doubleValue: + writer.WriteNumber(key, doubleValue); + break; + case float floatValue: + writer.WriteNumber(key, floatValue); + break; + case int intValue: + writer.WriteNumber(key, intValue); + break; + case uint uintValue: + writer.WriteNumber(key, uintValue); + break; + case long longValue: + writer.WriteNumber(key, longValue); + break; + case ulong ulongValue: + writer.WriteNumber(key, ulongValue); + break; + case short shortValue: + writer.WriteNumber(key, shortValue); + break; + case ushort ushortValue: + writer.WriteNumber(key, ushortValue); + break; + case null: + writer.WriteNull(key); + break; + default: + writer.WriteString(key, ToInvariantString(item.Value)); + break; + } + } + private static string ToInvariantString(object obj) => Convert.ToString(obj, CultureInfo.InvariantCulture); internal JsonConsoleFormatterOptions FormatterOptions { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs index 09f4050a9ed4..8cdfd691af3b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/JsonConsoleFormatterTests.cs @@ -2,9 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; +using System.Globalization; using System.Text.Json; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Logging.Console; +using System.Text.RegularExpressions; using Microsoft.Extensions.Logging.Test.Console; using Xunit; @@ -20,9 +21,10 @@ public void NoLogScope_DoesNotWriteAnyScopeContentToOutput_Json() new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, new SimpleConsoleFormatterOptions { IncludeScopes = true }, new ConsoleFormatterOptions { IncludeScopes = true }, - new JsonConsoleFormatterOptions { + new JsonConsoleFormatterOptions + { IncludeScopes = true, - JsonWriterOptions = new JsonWriterOptions() { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping } + JsonWriterOptions = new JsonWriterOptions() { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping } }); var logger = t.Logger; var sink = t.Sink; @@ -99,12 +101,12 @@ public void Log_NullMessage_LogsWhenMessageIsNotProvided() Assert.Equal( "{\"EventId\":0,\"LogLevel\":\"Critical\",\"Category\":\"test\",\"Message\":\"[null]\"" + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" - + Environment.NewLine, + + Environment.NewLine, GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); Assert.Equal( "{\"EventId\":0,\"LogLevel\":\"Critical\",\"Category\":\"test\",\"Message\":\"[null]\"" + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" - + Environment.NewLine, + + Environment.NewLine, GetMessage(sink.Writes.GetRange(1 * t.WritesPerMsg, t.WritesPerMsg))); Assert.Equal( @@ -112,7 +114,7 @@ public void Log_NullMessage_LogsWhenMessageIsNotProvided() + ",\"Message\":\"[null]\"" + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + ",\"State\":{\"Message\":\"[null]\",\"{OriginalFormat}\":\"[null]\"}}" - + Environment.NewLine, + + Environment.NewLine, GetMessage(sink.Writes.GetRange(2 * t.WritesPerMsg, t.WritesPerMsg))); } @@ -137,7 +139,7 @@ public void Log_ExceptionWithMessage_ExtractsInfo() // Act logger.LogInformation(exception, "exception message with {0}", "stacktrace"); logger.Log(LogLevel.Information, 0, state: "exception message", exception: exception, formatter: (a, b) => a); - + using (logger.BeginScope("scope1 {name1}", 123)) using (logger.BeginScope("scope2 {name1} {name2}", 456, 789)) logger.Log(LogLevel.Information, 0, state: "exception message", exception: exception, formatter: (a, b) => a); @@ -150,7 +152,7 @@ public void Log_ExceptionWithMessage_ExtractsInfo() + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + ",\"State\":{\"Message\":\"exception message with stacktrace\",\"0\":\"stacktrace\",\"{OriginalFormat}\":\"exception message with {0}\"}" + ",\"Scopes\":[]" - +"}" + Environment.NewLine, + + "}" + Environment.NewLine, GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); Assert.Equal( "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" @@ -158,15 +160,15 @@ public void Log_ExceptionWithMessage_ExtractsInfo() + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + ",\"State\":{\"Message\":\"exception message\"}" + ",\"Scopes\":[]" - +"}" + Environment.NewLine, + + "}" + Environment.NewLine, GetMessage(sink.Writes.GetRange(1 * t.WritesPerMsg, t.WritesPerMsg))); Assert.Equal( "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + ",\"Message\":\"exception message\"" + ",\"Exception\":{\"Message\":\"Invalid value\",\"Type\":\"System.InvalidOperationException\",\"StackTrace\":[],\"HResult\":-2146233079}" + ",\"State\":{\"Message\":\"exception message\"}" - + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":\"123\",\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":\"456\",\"name2\":\"789\",\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" - +"}" + Environment.NewLine, + + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":123,\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":456,\"name2\":789,\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" + + "}" + Environment.NewLine, GetMessage(sink.Writes.GetRange(2 * t.WritesPerMsg, t.WritesPerMsg))); } @@ -198,8 +200,8 @@ public void Log_IncludeScopes_ContainsDuplicateNamedPropertiesInScope_Acceptable "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + ",\"Message\":\"exception message\"" + ",\"State\":{\"Message\":\"exception message\"}" - + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":\"123\",\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":\"456\",\"name2\":\"789\",\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" - +"}" + Environment.NewLine, + + ",\"Scopes\":[{\"Message\":\"scope1 123\",\"name1\":123,\"{OriginalFormat}\":\"scope1 {name1}\"},{\"Message\":\"scope2 456 789\",\"name1\":456,\"name2\":789,\"{OriginalFormat}\":\"scope2 {name1} {name2}\"}]" + + "}" + Environment.NewLine, GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); } @@ -232,10 +234,202 @@ public void Log_StateAndScopeAreCollections_IncludesMessageAndCollectionValues() Assert.Equal( "{\"EventId\":0,\"LogLevel\":\"Information\",\"Category\":\"test\"" + ",\"Message\":\"1\"" - + ",\"State\":{\"Message\":\"1\",\"LogEntryNumber\":\"1\",\"{OriginalFormat}\":\"{LogEntryNumber}\"}" - + ",\"Scopes\":[{\"Message\":\"2\",\"Number\":\"2\",\"{OriginalFormat}\":\"{Number}\"},{\"Message\":\"3\",\"AnotherNumber\":\"3\",\"{OriginalFormat}\":\"{AnotherNumber}\"}]" - +"}" + Environment.NewLine, + + ",\"State\":{\"Message\":\"1\",\"LogEntryNumber\":1,\"{OriginalFormat}\":\"{LogEntryNumber}\"}" + + ",\"Scopes\":[{\"Message\":\"2\",\"Number\":2,\"{OriginalFormat}\":\"{Number}\"},{\"Message\":\"3\",\"AnotherNumber\":3,\"{OriginalFormat}\":\"{AnotherNumber}\"}]" + + "}" + Environment.NewLine, GetMessage(sink.Writes.GetRange(0 * t.WritesPerMsg, t.WritesPerMsg))); } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [MemberData(nameof(SpecialCaseValues))] + public void Log_StateAndScopeContainsSpecialCaseValue_SerializesValueAsExpected(object value, string expectedJsonValue) + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + + // Act + using (logger.BeginScope("{Value}", value)) + { + logger.LogInformation("{LogEntryValue}", value); + } + + // Assert + string message = sink.Writes[0].Message; + Assert.Contains("\"Value\":" + expectedJsonValue + ",", message); + Assert.Contains("\"LogEntryValue\":" + expectedJsonValue + ",", message); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [MemberData(nameof(FloatingPointValues))] + public void Log_StateAndScopeContainsFloatingPointType_SerializesValue(object value) + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + + // Act + using (logger.BeginScope("{Value}", value)) + { + logger.LogInformation("{LogEntryValue}", value); + } + + // Assert + string message = sink.Writes[0].Message; + AssertMessageValue(message, "Value"); + AssertMessageValue(message, "LogEntryValue"); + + static void AssertMessageValue(string message, string propertyName) + { + var serializedValueMatch = Regex.Match(message, "\"" + propertyName + "\":(.*?),"); + Assert.Equal(2, serializedValueMatch.Groups.Count); + string jsonValue = serializedValueMatch.Groups[1].Value; + Assert.True(double.TryParse(jsonValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var floatingPointValue), "The json doesn not contain a floating point value: " + jsonValue); + Assert.Equal(1.2, floatingPointValue, 2); + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public void Log_StateAndScopeContainsNullValue_SerializesNull() + { + // Arrange + var t = SetUp( + new ConsoleLoggerOptions { FormatterName = ConsoleFormatterNames.Json }, + simpleOptions: null, + systemdOptions: null, + jsonOptions: new JsonConsoleFormatterOptions + { + JsonWriterOptions = new JsonWriterOptions() { Indented = false }, + IncludeScopes = true + } + ); + var logger = (ILogger)t.Logger; + var sink = t.Sink; + + // Act + using (logger.BeginScope(new WithNullValue("ScopeKey"))) + { + logger.Log(LogLevel.Information, 0, state: new WithNullValue("LogKey"), exception: null, formatter: (a, b) => string.Empty); + } + + // Assert + string message = sink.Writes[0].Message; + Assert.Contains("\"ScopeKey\":null", message); + Assert.Contains("\"LogKey\":null", message); + } + + public static TheoryData SpecialCaseValues + { + get + { + var data = new TheoryData + { + // primitives, excluding floating point + { true, "true" }, + { (byte)1, "1" }, + { (sbyte)1, "1" }, + { 'a', "\"a\"" }, + { 1, "1" }, + { (uint)1, "1" }, + { (long)1, "1" }, + { (ulong)1, "1" }, + { (short)1, "1" }, + { (ushort)1, "1" }, + { 1.2m, "1.2" }, + + // nullables primitives, excluding floating point + { (bool?)true, "true" }, + { (byte?)1, "1" }, + { (sbyte?)1, "1" }, + { (char?)'a', "\"a\"" }, + { (int?)1, "1" }, + { (uint?)1, "1" }, + { (long?)1, "1" }, + { (ulong?)1, "1" }, + { (short?)1, "1" }, + { (ushort?)1, "1" }, + { (decimal?)1.2m, "1.2" }, + + // Dynamic object serialized as string + { new { a = 1, b = 2 }, "\"{ a = 1, b = 2 }\"" }, + + // null serialized as special string + { null, "\"(null)\"" } + }; + return data; + } + } + + public static TheoryData FloatingPointValues + { + get + { + var data = new TheoryData + { + { 1.2 }, + { 1.2f }, + + // nullables + { (double?)1.2 }, + { (float?)1.2f } + }; + return data; + } + } + + internal class WithNullValue : IReadOnlyList> + { + private readonly string _key; + + public WithNullValue(string key) + { + _key = key; + } + + int IReadOnlyCollection>.Count { get; } = 1; + + KeyValuePair IReadOnlyList>.this[int index] + { + get + { + if (index == 0) + { + return new KeyValuePair(_key, null); + } + + throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + IEnumerator> IEnumerable>.GetEnumerator() + { + yield return new KeyValuePair(_key, null); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return ((IEnumerable>)this).GetEnumerator(); + } + } } } From 600e22e3ee047d86607a615f91caa01b9d0897b1 Mon Sep 17 00:00:00 2001 From: Jake Meiergerd Date: Tue, 11 Aug 2020 13:14:52 -0500 Subject: [PATCH 399/755] Added additional LoggerMessage.DefineScope() overloads, with more type parameters (up to 6 like .Define()). (#40568) --- ...crosoft.Extensions.Logging.Abstractions.cs | 3 ++ .../src/LoggerMessage.cs | 51 +++++++++++++++++++ .../tests/Common/LoggerMessageTest.cs | 15 ++++++ 3 files changed, 69 insertions(+) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index ce0feb995008..6c492ac9bd9c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -98,6 +98,9 @@ public static partial class LoggerMessage public static System.Func DefineScope(string formatString) { throw null; } public static System.Func DefineScope(string formatString) { throw null; } public static System.Func DefineScope(string formatString) { throw null; } + public static System.Func DefineScope(string formatString) { throw null; } + public static System.Func DefineScope(string formatString) { throw null; } + public static System.Func DefineScope(string formatString) { throw null; } public static System.Action Define(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; } public static System.Action Define(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; } public static System.Action Define(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs index dab0062fc60d..a039be3156f9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs @@ -69,6 +69,57 @@ public static Func DefineScope(str return (logger, arg1, arg2, arg3) => logger.BeginScope(new LogValues(formatter, arg1, arg2, arg3)); } + /// + /// Creates a delegate which can be invoked to create a log scope. + /// + /// The type of the first parameter passed to the named format string. + /// The type of the second parameter passed to the named format string. + /// The type of the third parameter passed to the named format string. + /// The type of the fourth parameter passed to the named format string. + /// The named format string + /// A delegate which when invoked creates a log scope. + public static Func DefineScope(string formatString) + { + var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 4); + + return (logger, arg1, arg2, arg3, arg4) => logger.BeginScope(new LogValues(formatter, arg1, arg2, arg3, arg4)); + } + + /// + /// Creates a delegate which can be invoked to create a log scope. + /// + /// The type of the first parameter passed to the named format string. + /// The type of the second parameter passed to the named format string. + /// The type of the third parameter passed to the named format string. + /// The type of the fourth parameter passed to the named format string. + /// The type of the fifth parameter passed to the named format string. + /// The named format string + /// A delegate which when invoked creates a log scope. + public static Func DefineScope(string formatString) + { + var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 5); + + return (logger, arg1, arg2, arg3, arg4, arg5) => logger.BeginScope(new LogValues(formatter, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// Creates a delegate which can be invoked to create a log scope. + /// + /// The type of the first parameter passed to the named format string. + /// The type of the second parameter passed to the named format string. + /// The type of the third parameter passed to the named format string. + /// The type of the fourth parameter passed to the named format string. + /// The type of the fifth parameter passed to the named format string. + /// The type of the sisxth parameter passed to the named format string. + /// The named format string + /// A delegate which when invoked creates a log scope. + public static Func DefineScope(string formatString) + { + var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 6); + + return (logger, arg1, arg2, arg3, arg4, arg5, arg6) => logger.BeginScope(new LogValues(formatter, arg1, arg2, arg3, arg4, arg5, arg6)); + } + /// /// Creates a delegate which can be invoked for logging a message. /// diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerMessageTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerMessageTest.cs index 9b50f555b5e9..41a351b6f1d0 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerMessageTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerMessageTest.cs @@ -276,6 +276,9 @@ public void DefineScope_WithNoParameters_ThrowsException_WhenFormatString_HasNam [InlineData(1)] [InlineData(2)] [InlineData(3)] + [InlineData(4)] + [InlineData(5)] + [InlineData(6)] public void DefineScope_ThrowsException_WhenExpectedFormatStringParameterCount_NotFound( int expectedNamedParameterCount) { @@ -300,6 +303,18 @@ public void DefineScope_ThrowsException_WhenExpectedFormatStringParameterCount_N exception = Assert.Throws( () => LoggerMessage.DefineScope(formatString)); break; + case 4: + exception = Assert.Throws( + () => LoggerMessage.DefineScope(formatString)); + break; + case 5: + exception = Assert.Throws( + () => LoggerMessage.DefineScope(formatString)); + break; + case 6: + exception = Assert.Throws( + () => LoggerMessage.DefineScope(formatString)); + break; default: throw new ArgumentException($"Invalid value for '{nameof(expectedNamedParameterCount)}'"); } From 1821567ab60e156101f2a5bdcd5dab6d96dc3c71 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Tue, 11 Aug 2020 14:26:30 -0400 Subject: [PATCH 400/755] [Wasm] Enable CopyWithData FileSystem test (#40663) --- .../System.IO.FileSystem/tests/File/Copy.cs | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs index e0b69578aca9..ccd37654f7e5 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs @@ -14,6 +14,13 @@ protected virtual void Copy(string source, string dest) File.Copy(source, dest); } + protected virtual void CopyReadOnlyFile(string source, string dest) + { + byte[] bits = File.ReadAllBytes(source); + File.WriteAllBytes(dest, bits); + File.SetAttributes(dest, FileAttributes.ReadOnly); + } + #region UniversalTests [Fact] @@ -108,7 +115,6 @@ public static IEnumerable CopyFileWithData_MemberData() [Theory] [MemberData(nameof(CopyFileWithData_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/40543", TestPlatforms.Browser)] public void CopyFileWithData(char[] data, bool readOnly) { string testFileSource = GetTestFilePath(); @@ -120,8 +126,21 @@ public void CopyFileWithData(char[] data, bool readOnly) stream.Write(data, 0, data.Length); } - // Set the last write time of the source file to something a while ago - DateTime lastWriteTime = DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)); + DateTime lastWriteTime; + if (PlatformDetection.IsBrowser) + { + // For browser, there is technically only 1 time. It's the max + // of LastWrite and LastAccess. Setting to a date/time in the future + // is a way of making this test work similarly. + // + // https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.utime + // + lastWriteTime = DateTime.UtcNow.Add(TimeSpan.FromHours(1)); + } + else + { + lastWriteTime = DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)); + } File.SetLastWriteTime(testFileSource, lastWriteTime); if (readOnly) @@ -130,7 +149,16 @@ public void CopyFileWithData(char[] data, bool readOnly) } // Copy over the data - Copy(testFileSource, testFileDest); + // + // For browser, work around limitation of File.Copy, which + // fails when trying to open the dest file + if (PlatformDetection.IsBrowser && readOnly) + { + CopyReadOnlyFile(testFileSource, testFileDest); + File.SetLastWriteTime(testFileDest, lastWriteTime); + } + else + Copy(testFileSource, testFileDest); // Ensure copy transferred written data using (StreamReader stream = new StreamReader(File.OpenRead(testFileDest))) @@ -141,10 +169,7 @@ public void CopyFileWithData(char[] data, bool readOnly) } // Ensure last write/access time on the new file is appropriate - if (PlatformDetection.IsNotBrowser) // There is only one write time on browser vfs - { - Assert.InRange(File.GetLastWriteTimeUtc(testFileDest), lastWriteTime.AddSeconds(-1), lastWriteTime.AddSeconds(1)); - } + Assert.InRange(File.GetLastWriteTimeUtc(testFileDest), lastWriteTime.AddSeconds(-1), lastWriteTime.AddSeconds(1)); Assert.Equal(readOnly, (File.GetAttributes(testFileDest) & FileAttributes.ReadOnly) != 0); if (readOnly) From 531f1af183870e7fa427b1f44c6cb7745883900f Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 11 Aug 2020 21:08:27 +0200 Subject: [PATCH 401/755] make ConsoleKeyInfo implement IEquatable (#40660) * make ConsoleKeyInfo implement IEquatable, fixes #2127 * remove unnecessary cast --- src/libraries/System.Console/ref/System.Console.cs | 2 +- src/libraries/System.Console/src/System/ConsoleKeyInfo.cs | 4 ++-- src/libraries/System.Console/tests/ConsoleKeyInfoTests.cs | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Console/ref/System.Console.cs b/src/libraries/System.Console/ref/System.Console.cs index 6c17987a1b49..b3faa6461124 100644 --- a/src/libraries/System.Console/ref/System.Console.cs +++ b/src/libraries/System.Console/ref/System.Console.cs @@ -281,7 +281,7 @@ public enum ConsoleKey Pa1 = 253, OemClear = 254, } - public readonly partial struct ConsoleKeyInfo + public readonly partial struct ConsoleKeyInfo : System.IEquatable { private readonly int _dummyPrimitive; public ConsoleKeyInfo(char keyChar, System.ConsoleKey key, bool shift, bool alt, bool control) { throw null; } diff --git a/src/libraries/System.Console/src/System/ConsoleKeyInfo.cs b/src/libraries/System.Console/src/System/ConsoleKeyInfo.cs index b4a8e2ffd00f..669416a820f1 100644 --- a/src/libraries/System.Console/src/System/ConsoleKeyInfo.cs +++ b/src/libraries/System.Console/src/System/ConsoleKeyInfo.cs @@ -5,7 +5,7 @@ namespace System { - public readonly struct ConsoleKeyInfo + public readonly struct ConsoleKeyInfo : IEquatable { private readonly char _keyChar; private readonly ConsoleKey _key; @@ -50,7 +50,7 @@ public ConsoleModifiers Modifiers public override bool Equals(object? value) { - return value is ConsoleKeyInfo && Equals((ConsoleKeyInfo)value); + return value is ConsoleKeyInfo info && Equals(info); } public bool Equals(ConsoleKeyInfo obj) diff --git a/src/libraries/System.Console/tests/ConsoleKeyInfoTests.cs b/src/libraries/System.Console/tests/ConsoleKeyInfoTests.cs index 2d63cd85ea2a..da3720a43d01 100644 --- a/src/libraries/System.Console/tests/ConsoleKeyInfoTests.cs +++ b/src/libraries/System.Console/tests/ConsoleKeyInfoTests.cs @@ -69,6 +69,9 @@ public void NotEquals_Object() Assert.False(default(ConsoleKeyInfo).Equals(new object())); } + [Fact] + public void ImplementsIEquatableInterface() => Assert.True(typeof(IEquatable).IsAssignableFrom(typeof(ConsoleKeyInfo))); + public static readonly object[][] NotEqualConsoleKeyInfos = { new object[] { new ConsoleKeyInfo('a', ConsoleKey.A, true, true, true), new ConsoleKeyInfo('b', ConsoleKey.A, true, true, true) }, new object[] { new ConsoleKeyInfo('a', ConsoleKey.A, true, true, true), new ConsoleKeyInfo('a', ConsoleKey.B, true, true, true) }, From 80e00f03ae7d936f0f26a89c4c5a60fe9bf2c045 Mon Sep 17 00:00:00 2001 From: Sam Patel <46026722+SamMonoRT@users.noreply.github.com> Date: Tue, 11 Aug 2020 15:14:35 -0400 Subject: [PATCH 402/755] Update Codeowners file (#40662) --- .github/CODEOWNERS | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e5a4552409f5..515707b1e073 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,12 +19,12 @@ /src/mono/llvm @vargaz @SamMonoRT @imhameed @EgorBo -/src/mono/mono/arch @vargaz @lewurm -/src/mono/mono/benchmark @SamMonoRT @lewurm +/src/mono/mono/arch @vargaz +/src/mono/mono/benchmark @SamMonoRT @naricc /src/mono/mono/dis @lambdageek @vargaz -/src/mono/mono/eglib @vargaz @lambdageek @CoffeeFlux @lewurm +/src/mono/mono/eglib @vargaz @lambdageek @CoffeeFlux -/src/mono/mono/metadata @vargaz @lambdageek @thaystg @CoffeeFlux @lewurm @alexischr +/src/mono/mono/metadata @vargaz @lambdageek @thaystg @CoffeeFlux /src/mono/mono/metadata/*-win* @lateralusX @lambdageek @CoffeeFlux /src/mono/mono/metadata/handle* @lambdageek @vargaz /src/mono/mono/metadata/monitor* @brzvlad @vargaz @@ -32,28 +32,28 @@ /src/mono/mono/metadata/thread* @lateralusX @lambdageek /src/mono/mono/metadata/w32* @lateralusX @lambdageek @CoffeeFlux -/src/mono/mono/mini @vargaz @lewurm @lambdageek @SamMonoRT @CoffeeFlux @alexischr -/src/mono/mono/mini/*cfgdump* @lewurm @vargaz -/src/mono/mono/mini/*exceptions* @lewurm @vargaz @BrzVlad +/src/mono/mono/mini @vargaz @lambdageek @SamMonoRT @CoffeeFlux +/src/mono/mono/mini/*cfgdump* @vargaz +/src/mono/mono/mini/*exceptions* @vargaz @BrzVlad /src/mono/mono/mini/*llvm* @vargaz @imhameed @EgorBo -/src/mono/mono/mini/*ppc* @lewurm @vargaz +/src/mono/mono/mini/*ppc* @vargaz /src/mono/mono/mini/*profiler* @BrzVlad @lambdageek -/src/mono/mono/mini/*riscv* @alexrp @lewurm -/src/mono/mono/mini/*type-check* @lewurm @lambdageek +/src/mono/mono/mini/*riscv* @alexrp +/src/mono/mono/mini/*type-check* @lambdageek /src/mono/mono/mini/debugger-agent.c @vargaz @thaystg @DavidKarlas @lambdageek -/src/mono/mono/mini/interp/* @lewurm @BrzVlad +/src/mono/mono/mini/interp/* @BrzVlad @vargaz -/src/mono/mono/native @baulig @egorbo @alexischr @marek-safar +/src/mono/mono/native @egorbo @marek-safar /src/mono/mono/profiler @BrzVlad @lambdageek -/src/mono/mono/sgen @BrzVlad @lambdageek +/src/mono/mono/sgen @BrzVlad @lambdageek @naricc -/src/mono/mono/utils @vargaz @lewurm @lambdageek @CoffeeFlux @alexischr +/src/mono/mono/utils @vargaz @lambdageek @CoffeeFlux /src/mono/mono/utils/*-win* @lateralusX @lambdageek @CoffeeFlux -/src/mono/mono/utils/atomic* @lewurm @vargaz -/src/mono/mono/utils/mono-hwcap* @lewurm @vargaz -/src/mono/mono/utils/mono-mem* @lewurm @vargaz -/src/mono/mono/utils/mono-merp* @alexischr @lambdageek -/src/mono/mono/utils/mono-state* @alexischr @lambdageek +/src/mono/mono/utils/atomic* @vargaz +/src/mono/mono/utils/mono-hwcap* @vargaz +/src/mono/mono/utils/mono-mem* @vargaz +/src/mono/mono/utils/mono-merp* @lambdageek @naricc @imhameed +/src/mono/mono/utils/mono-state* @lambdageek /src/mono/mono/utils/mono-threads* @lambdageek @vargaz /src/mono/msvc @lateralusX @kg @akoeplinger From 3642deea8235ce8316db8c37cc3e8f4ad5b15380 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 11 Aug 2020 12:23:13 -0700 Subject: [PATCH 403/755] Updating Matrix4x4 to accelerate several functions using Arm.AdvSimd (#40054) * Updating Matrix4x4 to accelerate several functions using Arm.AdvSimd * Fixing Matrix4x4 * Matrix4x4 * Fixing Matrix4x4.Transpose * Fix a copy paste error with Matrix4x4 != Matrix4x4 --- src/coreclr/src/jit/simdashwintrinsic.cpp | 22 +-- .../System.Private.CoreLib/src/System/Math.cs | 2 +- .../src/System/Numerics/Matrix4x4.cs | 179 +++++++++++++++--- .../src/System/Numerics/VectorMath.cs | 134 +++++++++---- 4 files changed, 259 insertions(+), 78 deletions(-) diff --git a/src/coreclr/src/jit/simdashwintrinsic.cpp b/src/coreclr/src/jit/simdashwintrinsic.cpp index 6e48db4d8212..dec5706181a4 100644 --- a/src/coreclr/src/jit/simdashwintrinsic.cpp +++ b/src/coreclr/src/jit/simdashwintrinsic.cpp @@ -1069,26 +1069,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicCndSel(CORINFO_CLASS_HANDLE clsHnd, assert(op3 != nullptr); #if defined(TARGET_XARCH) - bool isVectorT256 = (simdSize == 32); - // Vector for the rel-ops covered here requires at least SSE2 assert(compIsaSupportedDebugOnly(InstructionSet_SSE2)); // Vector, when 32-bytes, requires at least AVX2 - assert(!isVectorT256 || compIsaSupportedDebugOnly(InstructionSet_AVX2)); - - if (compOpportunisticallyDependsOn(InstructionSet_SSE41)) - { - NamedIntrinsic hwIntrinsic = NI_SSE41_BlendVariable; - - if (isVectorT256) - { - hwIntrinsic = varTypeIsIntegral(baseType) ? NI_AVX2_BlendVariable : NI_AVX_BlendVariable; - } - - return gtNewSimdAsHWIntrinsicNode(retType, op3, op2, op1, hwIntrinsic, baseType, simdSize); - } -#endif // TARGET_XARCH + assert((simdSize != 32) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); NamedIntrinsic hwIntrinsic; @@ -1113,6 +1098,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicCndSel(CORINFO_CLASS_HANDLE clsHnd, // result = op2 | op3 hwIntrinsic = SimdAsHWIntrinsicInfo::lookupHWIntrinsic(NI_VectorT128_op_BitwiseOr, baseType); return gtNewSimdAsHWIntrinsicNode(retType, op2, op3, hwIntrinsic, baseType, simdSize); +#elif defined(TARGET_ARM64) + return gtNewSimdAsHWIntrinsicNode(retType, op1, op2, op3, NI_AdvSimd_BitwiseSelect, baseType, simdSize); +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 } #if defined(TARGET_XARCH) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 015e7b7f9231..f1c058281739 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -226,7 +226,7 @@ public static double BitIncrement(double x) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double CopySign(double x, double y) { - if (Sse.IsSupported || AdvSimd.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return VectorMath.ConditionalSelectBitwise(Vector128.CreateScalarUnsafe(-0.0), Vector128.CreateScalarUnsafe(y), Vector128.CreateScalarUnsafe(x)).ToScalar(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs index 55919af94450..da139facf554 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs @@ -6,6 +6,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; namespace System.Numerics @@ -1113,9 +1114,15 @@ private static Vector128 Permute(Vector128 value, byte control) { return Avx.Permute(value, control); } - - Debug.Assert(Sse.IsSupported); - return Sse.Shuffle(value, value, control); + else if (Sse.IsSupported) + { + return Sse.Shuffle(value, value, control); + } + else + { + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); + } } /// @@ -1128,6 +1135,9 @@ private static Vector128 Permute(Vector128 value, byte control) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe bool Invert(Matrix4x4 matrix, out Matrix4x4 result) { + // This implementation is based on the DirectX Math Library XMMatrixInverse method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMatrix.inl + if (Sse.IsSupported) { return SseImpl(matrix, out result); @@ -1137,16 +1147,12 @@ public static unsafe bool Invert(Matrix4x4 matrix, out Matrix4x4 result) static unsafe bool SseImpl(Matrix4x4 matrix, out Matrix4x4 result) { - // Redundant test so we won't prejit remainder of this method - // on platforms without SSE. if (!Sse.IsSupported) { + // Redundant test so we won't prejit remainder of this method on platforms without SSE. throw new PlatformNotSupportedException(); } - // This implementation is based on the DirectX Math Library XMMInverse method - // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMatrix.inl - // Load the matrix values into rows Vector128 row1 = Sse.LoadVector128(&matrix.M11); Vector128 row2 = Sse.LoadVector128(&matrix.M21); @@ -1468,7 +1474,6 @@ static bool SoftwareFallback(Matrix4x4 matrix, out Matrix4x4 result) } } - private struct CanonicalBasis { public Vector3 Row0; @@ -1476,7 +1481,6 @@ private struct CanonicalBasis public Vector3 Row2; }; - private struct VectorBasis { public unsafe Vector3* Element0; @@ -1755,7 +1759,31 @@ public static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation) /// The transposed matrix. public static unsafe Matrix4x4 Transpose(Matrix4x4 matrix) { - if (Sse.IsSupported) + if (AdvSimd.Arm64.IsSupported) + { + // This implementation is based on the DirectX Math Library XMMatrixTranspose method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMatrix.inl + + Vector128 M11 = AdvSimd.LoadVector128(&matrix.M11); + Vector128 M31 = AdvSimd.LoadVector128(&matrix.M31); + + Vector128 P00 = AdvSimd.Arm64.ZipLow(M11, M31); + Vector128 P01 = AdvSimd.Arm64.ZipHigh(M11, M31); + + Vector128 M21 = AdvSimd.LoadVector128(&matrix.M21); + Vector128 M41 = AdvSimd.LoadVector128(&matrix.M41); + + Vector128 P10 = AdvSimd.Arm64.ZipLow(M21, M41); + Vector128 P11 = AdvSimd.Arm64.ZipHigh(M21, M41); + + AdvSimd.Store(&matrix.M11, AdvSimd.Arm64.ZipLow(P00, P10)); + AdvSimd.Store(&matrix.M21, AdvSimd.Arm64.ZipHigh(P00, P10)); + AdvSimd.Store(&matrix.M31, AdvSimd.Arm64.ZipLow(P01, P11)); + AdvSimd.Store(&matrix.M41, AdvSimd.Arm64.ZipHigh(P01, P11)); + + return matrix; + } + else if (Sse.IsSupported) { Vector128 row1 = Sse.LoadVector128(&matrix.M11); Vector128 row2 = Sse.LoadVector128(&matrix.M21); @@ -1806,7 +1834,16 @@ public static unsafe Matrix4x4 Transpose(Matrix4x4 matrix) /// The interpolated matrix. public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount) { - if (Sse.IsSupported) + if (AdvSimd.IsSupported) + { + Vector128 amountVec = Vector128.Create(amount); + AdvSimd.Store(&matrix1.M11, VectorMath.Lerp(AdvSimd.LoadVector128(&matrix1.M11), AdvSimd.LoadVector128(&matrix2.M11), amountVec)); + AdvSimd.Store(&matrix1.M21, VectorMath.Lerp(AdvSimd.LoadVector128(&matrix1.M21), AdvSimd.LoadVector128(&matrix2.M21), amountVec)); + AdvSimd.Store(&matrix1.M31, VectorMath.Lerp(AdvSimd.LoadVector128(&matrix1.M31), AdvSimd.LoadVector128(&matrix2.M31), amountVec)); + AdvSimd.Store(&matrix1.M41, VectorMath.Lerp(AdvSimd.LoadVector128(&matrix1.M41), AdvSimd.LoadVector128(&matrix2.M41), amountVec)); + return matrix1; + } + else if (Sse.IsSupported) { Vector128 amountVec = Vector128.Create(amount); Sse.Store(&matrix1.M11, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M11), Sse.LoadVector128(&matrix2.M11), amountVec)); @@ -1891,14 +1928,22 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// The negated matrix. public static unsafe Matrix4x4 operator -(Matrix4x4 value) { - if (Sse.IsSupported) + if (AdvSimd.IsSupported) + { + Vector128 zero = Vector128.Zero; + AdvSimd.Store(&value.M11, AdvSimd.Subtract(zero, AdvSimd.LoadVector128(&value.M11))); + AdvSimd.Store(&value.M21, AdvSimd.Subtract(zero, AdvSimd.LoadVector128(&value.M21))); + AdvSimd.Store(&value.M31, AdvSimd.Subtract(zero, AdvSimd.LoadVector128(&value.M31))); + AdvSimd.Store(&value.M41, AdvSimd.Subtract(zero, AdvSimd.LoadVector128(&value.M41))); + return value; + } + else if (Sse.IsSupported) { Vector128 zero = Vector128.Zero; Sse.Store(&value.M11, Sse.Subtract(zero, Sse.LoadVector128(&value.M11))); Sse.Store(&value.M21, Sse.Subtract(zero, Sse.LoadVector128(&value.M21))); Sse.Store(&value.M31, Sse.Subtract(zero, Sse.LoadVector128(&value.M31))); Sse.Store(&value.M41, Sse.Subtract(zero, Sse.LoadVector128(&value.M41))); - return value; } @@ -1932,7 +1977,15 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// The resulting matrix. public static unsafe Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2) { - if (Sse.IsSupported) + if (AdvSimd.IsSupported) + { + AdvSimd.Store(&value1.M11, AdvSimd.Add(AdvSimd.LoadVector128(&value1.M11), AdvSimd.LoadVector128(&value2.M11))); + AdvSimd.Store(&value1.M21, AdvSimd.Add(AdvSimd.LoadVector128(&value1.M21), AdvSimd.LoadVector128(&value2.M21))); + AdvSimd.Store(&value1.M31, AdvSimd.Add(AdvSimd.LoadVector128(&value1.M31), AdvSimd.LoadVector128(&value2.M31))); + AdvSimd.Store(&value1.M41, AdvSimd.Add(AdvSimd.LoadVector128(&value1.M41), AdvSimd.LoadVector128(&value2.M41))); + return value1; + } + else if (Sse.IsSupported) { Sse.Store(&value1.M11, Sse.Add(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11))); Sse.Store(&value1.M21, Sse.Add(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21))); @@ -1971,7 +2024,15 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// The result of the subtraction. public static unsafe Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2) { - if (Sse.IsSupported) + if (AdvSimd.IsSupported) + { + AdvSimd.Store(&value1.M11, AdvSimd.Subtract(AdvSimd.LoadVector128(&value1.M11), AdvSimd.LoadVector128(&value2.M11))); + AdvSimd.Store(&value1.M21, AdvSimd.Subtract(AdvSimd.LoadVector128(&value1.M21), AdvSimd.LoadVector128(&value2.M21))); + AdvSimd.Store(&value1.M31, AdvSimd.Subtract(AdvSimd.LoadVector128(&value1.M31), AdvSimd.LoadVector128(&value2.M31))); + AdvSimd.Store(&value1.M41, AdvSimd.Subtract(AdvSimd.LoadVector128(&value1.M41), AdvSimd.LoadVector128(&value2.M41))); + return value1; + } + else if (Sse.IsSupported) { Sse.Store(&value1.M11, Sse.Subtract(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11))); Sse.Store(&value1.M21, Sse.Subtract(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21))); @@ -2010,7 +2071,53 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// The result of the multiplication. public static unsafe Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2) { - if (Sse.IsSupported) + if (AdvSimd.Arm64.IsSupported) + { + Unsafe.SkipInit(out Matrix4x4 result); + + // Perform the operation on the first row + + Vector128 M11 = AdvSimd.LoadVector128(&value1.M11); + + Vector128 vX = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M11), M11, 0); + Vector128 vY = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M21), M11, 1); + Vector128 vZ = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vX, AdvSimd.LoadVector128(&value2.M31), M11, 2); + Vector128 vW = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vY, AdvSimd.LoadVector128(&value2.M41), M11, 3); + + AdvSimd.Store(&result.M11, AdvSimd.Add(vZ, vW)); + + // Repeat for the other 3 rows + + Vector128 M21 = AdvSimd.LoadVector128(&value1.M21); + + vX = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M11), M21, 0); + vY = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M21), M21, 1); + vZ = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vX, AdvSimd.LoadVector128(&value2.M31), M21, 2); + vW = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vY, AdvSimd.LoadVector128(&value2.M41), M21, 3); + + AdvSimd.Store(&result.M21, AdvSimd.Add(vZ, vW)); + + Vector128 M31 = AdvSimd.LoadVector128(&value1.M31); + + vX = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M11), M31, 0); + vY = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M21), M31, 1); + vZ = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vX, AdvSimd.LoadVector128(&value2.M31), M31, 2); + vW = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vY, AdvSimd.LoadVector128(&value2.M41), M31, 3); + + AdvSimd.Store(&result.M31, AdvSimd.Add(vZ, vW)); + + Vector128 M41 = AdvSimd.LoadVector128(&value1.M41); + + vX = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M11), M41, 0); + vY = AdvSimd.MultiplyBySelectedScalar(AdvSimd.LoadVector128(&value2.M21), M41, 1); + vZ = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vX, AdvSimd.LoadVector128(&value2.M31), M41, 2); + vW = AdvSimd.Arm64.FusedMultiplyAddBySelectedScalar(vY, AdvSimd.LoadVector128(&value2.M41), M41, 3); + + AdvSimd.Store(&result.M41, AdvSimd.Add(vZ, vW)); + + return result; + } + else if (Sse.IsSupported) { Vector128 row = Sse.LoadVector128(&value1.M11); Sse.Store(&value1.M11, @@ -2082,7 +2189,16 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// The scaled matrix. public static unsafe Matrix4x4 operator *(Matrix4x4 value1, float value2) { - if (Sse.IsSupported) + if (AdvSimd.IsSupported) + { + Vector128 value2Vec = Vector128.Create(value2); + AdvSimd.Store(&value1.M11, AdvSimd.Multiply(AdvSimd.LoadVector128(&value1.M11), value2Vec)); + AdvSimd.Store(&value1.M21, AdvSimd.Multiply(AdvSimd.LoadVector128(&value1.M21), value2Vec)); + AdvSimd.Store(&value1.M31, AdvSimd.Multiply(AdvSimd.LoadVector128(&value1.M31), value2Vec)); + AdvSimd.Store(&value1.M41, AdvSimd.Multiply(AdvSimd.LoadVector128(&value1.M41), value2Vec)); + return value1; + } + else if (Sse.IsSupported) { Vector128 value2Vec = Vector128.Create(value2); Sse.Store(&value1.M11, Sse.Multiply(Sse.LoadVector128(&value1.M11), value2Vec)); @@ -2121,13 +2237,19 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// True if the given matrices are equal; False otherwise. public static unsafe bool operator ==(Matrix4x4 value1, Matrix4x4 value2) { - if (Sse.IsSupported) + if (AdvSimd.Arm64.IsSupported) { - return - VectorMath.Equal(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)) && - VectorMath.Equal(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)) && - VectorMath.Equal(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)) && - VectorMath.Equal(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)); + return VectorMath.Equal(AdvSimd.LoadVector128(&value1.M11), AdvSimd.LoadVector128(&value2.M11)) && + VectorMath.Equal(AdvSimd.LoadVector128(&value1.M21), AdvSimd.LoadVector128(&value2.M21)) && + VectorMath.Equal(AdvSimd.LoadVector128(&value1.M31), AdvSimd.LoadVector128(&value2.M31)) && + VectorMath.Equal(AdvSimd.LoadVector128(&value1.M41), AdvSimd.LoadVector128(&value2.M41)); + } + else if (Sse.IsSupported) + { + return VectorMath.Equal(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)) && + VectorMath.Equal(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)) && + VectorMath.Equal(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)) && + VectorMath.Equal(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)); } return (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && // Check diagonal element first for early out. @@ -2144,7 +2266,14 @@ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float /// True if the given matrices are not equal; False if they are equal. public static unsafe bool operator !=(Matrix4x4 value1, Matrix4x4 value2) { - if (Sse.IsSupported) + if (AdvSimd.Arm64.IsSupported) + { + return VectorMath.NotEqual(AdvSimd.LoadVector128(&value1.M11), AdvSimd.LoadVector128(&value2.M11)) || + VectorMath.NotEqual(AdvSimd.LoadVector128(&value1.M21), AdvSimd.LoadVector128(&value2.M21)) || + VectorMath.NotEqual(AdvSimd.LoadVector128(&value1.M31), AdvSimd.LoadVector128(&value2.M31)) || + VectorMath.NotEqual(AdvSimd.LoadVector128(&value1.M41), AdvSimd.LoadVector128(&value2.M41)); + } + else if (Sse.IsSupported) { return VectorMath.NotEqual(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)) || diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/VectorMath.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/VectorMath.cs index 37ac73ffe73c..c8b4be93ac6e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/VectorMath.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/VectorMath.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.Arm; @@ -11,68 +10,131 @@ namespace System.Numerics { internal static class VectorMath { - public static Vector128 Lerp(Vector128 a, Vector128 b, Vector128 t) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 ConditionalSelectBitwise(Vector128 selector, Vector128 ifTrue, Vector128 ifFalse) { - Debug.Assert(Sse.IsSupported); - return Sse.Add(a, Sse.Multiply(Sse.Subtract(b, a), t)); + // This implementation is based on the DirectX Math Library XMVector4NotEqual method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl + + if (AdvSimd.IsSupported) + { + return AdvSimd.BitwiseSelect(selector, ifTrue, ifFalse); + } + else if (Sse.IsSupported) + { + return Sse.Or(Sse.And(ifTrue, selector), Sse.AndNot(selector, ifFalse)); + } + else + { + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); + } } - public static bool Equal(Vector128 vector1, Vector128 vector2) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 ConditionalSelectBitwise(Vector128 selector, Vector128 ifTrue, Vector128 ifFalse) { - Debug.Assert(Sse.IsSupported); - return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) == 0; + // This implementation is based on the DirectX Math Library XMVector4NotEqual method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl + + if (AdvSimd.IsSupported) + { + return AdvSimd.BitwiseSelect(selector, ifTrue, ifFalse); + } + else if (Sse2.IsSupported) + { + return Sse2.Or(Sse2.And(ifTrue, selector), Sse2.AndNot(selector, ifFalse)); + } + else + { + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); + } } - public static bool NotEqual(Vector128 vector1, Vector128 vector2) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Equal(Vector128 vector1, Vector128 vector2) { - Debug.Assert(Sse.IsSupported); - return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) != 0; + // This implementation is based on the DirectX Math Library XMVector4Equal method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl + + if (AdvSimd.Arm64.IsSupported) + { + Vector128 vResult = AdvSimd.CompareEqual(vector1, vector2).AsUInt32(); + + Vector64 vResult0 = vResult.GetLower().AsByte(); + Vector64 vResult1 = vResult.GetUpper().AsByte(); + + Vector64 vTemp10 = AdvSimd.Arm64.ZipLow(vResult0, vResult1); + Vector64 vTemp11 = AdvSimd.Arm64.ZipHigh(vResult0, vResult1); + + Vector64 vTemp21 = AdvSimd.Arm64.ZipHigh(vTemp10.AsUInt16(), vTemp11.AsUInt16()); + return vTemp21.AsUInt32().GetElement(1) == 0xFFFFFFFF; + } + else if (Sse.IsSupported) + { + return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) == 0; + } + else + { + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector128 ConditionalSelectBitwise(Vector128 selector, Vector128 ifTrue, Vector128 ifFalse) + public static Vector128 Lerp(Vector128 a, Vector128 b, Vector128 t) { - Debug.Assert(Sse.IsSupported || AdvSimd.IsSupported); + // This implementation is based on the DirectX Math Library XMVectorLerp method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl - if (Sse.IsSupported) + if (AdvSimd.IsSupported) { - return Sse.Or( - Sse.And(ifTrue, selector), - Sse.AndNot(selector, ifFalse) - ); + return AdvSimd.FusedMultiplyAdd(a, AdvSimd.Subtract(b, a), t); } - else if (AdvSimd.IsSupported) + else if (Fma.IsSupported) { - return AdvSimd.BitwiseSelect(selector.AsByte(), ifTrue.AsByte(), ifFalse.AsByte()).As(); + return Fma.MultiplyAdd(Sse.Subtract(b, a), t, a); + } + else if (Sse.IsSupported) + { + return Sse.Add(Sse.Multiply(a, Sse.Subtract(Vector128.Create(1.0f), t)), Sse.Multiply(b, t)); + } + else + { + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); } - - return default; } - public static Vector128 ConditionalSelectBitwise(Vector128 selector, Vector128 ifTrue, Vector128 ifFalse) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NotEqual(Vector128 vector1, Vector128 vector2) { - Debug.Assert(Sse.IsSupported || AdvSimd.IsSupported); + // This implementation is based on the DirectX Math Library XMVector4NotEqual method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl - if (Sse2.IsSupported) + if (AdvSimd.IsSupported) { - return Sse2.Or( - Sse2.And(ifTrue, selector), - Sse2.AndNot(selector, ifFalse) - ); + Vector128 vResult = AdvSimd.CompareEqual(vector1, vector2).AsUInt32(); + + Vector64 vResult0 = vResult.GetLower().AsByte(); + Vector64 vResult1 = vResult.GetUpper().AsByte(); + + Vector64 vTemp10 = AdvSimd.Arm64.ZipLow(vResult0, vResult1); + Vector64 vTemp11 = AdvSimd.Arm64.ZipHigh(vResult0, vResult1); + + Vector64 vTemp21 = AdvSimd.Arm64.ZipHigh(vTemp10.AsUInt16(), vTemp11.AsUInt16()); + return vTemp21.AsUInt32().GetElement(1) != 0xFFFFFFFF; } else if (Sse.IsSupported) { - return Sse.Or( - Sse.And(ifTrue.AsSingle(), selector.AsSingle()), - Sse.AndNot(selector.AsSingle(), ifFalse.AsSingle()) - ).As(); + return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) != 0; } - else if (AdvSimd.IsSupported) + else { - return AdvSimd.BitwiseSelect(selector.AsByte(), ifTrue.AsByte(), ifFalse.AsByte()).As(); + // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. + throw new PlatformNotSupportedException(); } - - return default; } } } From 82370978ea5ad36206a35abecefd0abeeaac3b92 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 11 Aug 2020 12:29:51 -0700 Subject: [PATCH 404/755] modifies flaky Microsoft.Win32 test (#40673) - TimerElapsedIsRoughlyEquivalentToInterval --- .../tests/SystemEvents.CreateTimer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Win32.SystemEvents/tests/SystemEvents.CreateTimer.cs b/src/libraries/Microsoft.Win32.SystemEvents/tests/SystemEvents.CreateTimer.cs index a969bc838e5d..07e35f273b5a 100644 --- a/src/libraries/Microsoft.Win32.SystemEvents/tests/SystemEvents.CreateTimer.cs +++ b/src/libraries/Microsoft.Win32.SystemEvents/tests/SystemEvents.CreateTimer.cs @@ -139,7 +139,7 @@ public void ConcurrentTimers() public void TimerElapsedIsRoughlyEquivalentToInterval(int interval) { const double permittedProportionUnder = -0.1; - const double permittedProportionOver = 0.5; + const double permittedProportionOver = 5.0; var elapsed = new AutoResetEvent(false); IntPtr timer = IntPtr.Zero; var stopwatch = new Stopwatch(); From 739c53e737e25a47df3d75e39d167463e6da0688 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 11 Aug 2020 13:21:02 -0700 Subject: [PATCH 405/755] Update README.md --- src/coreclr/src/tools/ILVerify/README.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/coreclr/src/tools/ILVerify/README.md b/src/coreclr/src/tools/ILVerify/README.md index a3c0001a6456..7f61e432569b 100644 --- a/src/coreclr/src/tools/ILVerify/README.md +++ b/src/coreclr/src/tools/ILVerify/README.md @@ -92,17 +92,7 @@ The methods are automatically fed into appropriate XUnit theories based on the n You can run the tests either in Visual Studio (in Test Explorer) or with the ```dotnet test ``` command from the command line. ## How to contribute -All ILVerify issues are labeled with [area-ILVerification](https://github.com/search?utf8=%E2%9C%93&q=label%3Aarea-ILVerification&type=). - -ILVerify basically runs through the IL commands in an assembly and does all the verification steps that are specified in ECMA-335. - -Currently every IL command falls into one of these categories: - - - Not implemented: the implementation is completely missing. The easiest way is to pick one of them (look for NotImplentedException in the code) and implement it. First you should 100% understand the spec. (see [ECMA-335](https://www.ecma-international.org/publications/standards/Ecma-335.htm)), then try to port an existing implementation (sources below). - - Partially implemented: These are typically methods with TODOs in it. As the first phase we want to make sure that for every command the stack is correctly maintained, therefore for some commands we either have no verification or we have only a not complete verification. You can also pick one of these and finish it. - - Implemented: find and fix bugs ;) . - -Another option to contribute is to write tests (see Tests section). +All ILVerify issues are labeled with [area-ILVerification](https://github.com/search?utf8=%E2%9C%93&q=label%3Aarea-ILVerification&type=). You can also look and fix TODOs in the source code. Useful sources: - [PEVerify source code](https://github.com/lewischeng-ms/sscli/blob/master/clr/src/jit64/newverify.cpp) From db2c30f3254fbd01e214a48a8459dfa2f50c7674 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 11 Aug 2020 13:44:20 -0700 Subject: [PATCH 406/755] Fix virtual slot indices in VSD botr example (#40174) --- docs/design/coreclr/botr/virtual-stub-dispatch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/coreclr/botr/virtual-stub-dispatch.md b/docs/design/coreclr/botr/virtual-stub-dispatch.md index af80f0a84c96..bf67c5895bcb 100644 --- a/docs/design/coreclr/botr/virtual-stub-dispatch.md +++ b/docs/design/coreclr/botr/virtual-stub-dispatch.md @@ -91,7 +91,7 @@ The following is a small class structure (modeled in C#), and what the resulting ![Figure 1](images/virtualstubdispatch-fig1.png) -Thus, looking at this map, we see that the first column of the sub-maps of the slot maps correspond to the slot number in the classic virtual table view (remember that System.Object contributes four virtual methods of its own, which are omitted for clarity). Searches for method implementations are always bottom-up. Thus, if I had an object of type _B_ and I wished to invoke _I.Foo_, I would look for a mapping of _I.Foo_ starting at _B_'s slot map. Not finding it there, I would look in _A_'s slot map and find it there. It states that virtual slot 0 of _I_ (corresponding to _I.Foo_) is implemented by virtual slot 0. Then I return to _B_'s slot map and search for an implementation for slot 0, and find that it is implemented by slot 1 in its own implementation table. +Thus, looking at this map, we see that the first column of the sub-maps of the slot maps correspond to the slot number in the classic virtual table view (remember that System.Object contributes four virtual methods of its own, which are omitted for clarity). Searches for method implementations are always bottom-up. Thus, if I had an object of type _B_ and I wished to invoke _I.Foo_, I would look for a mapping of _I.Foo_ starting at _B_'s slot map. Not finding it there, I would look in _A_'s slot map and find it there. It states that virtual slot 0 of _I_ (corresponding to _I.Foo_) is implemented by virtual slot 4. Then I return to _B_'s slot map and search for an implementation for virtual slot 4, and find that it is implemented by slot 1 in its own implementation table. ### Additional Uses From ead2cd50799ecc523e23f50e50b54d8a30d0aa4f Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Tue, 11 Aug 2020 13:54:08 -0700 Subject: [PATCH 407/755] Remove unused locals in System.Net.* (#39575) * Remove unused locals in System.Net.HttpListener * Remove unused local in System.Net.Requests * Remove unused locals and methods in System.Net.Security --- .../src/System/Net/Windows/HttpListener.Windows.cs | 1 - .../WebSockets/WebSocketProtocolComponent.cs | 1 - .../tests/GetContextHelper.cs | 2 +- .../tests/HttpListenerAuthenticationTests.cs | 8 ++++---- .../tests/HttpListenerContextTests.cs | 1 - .../tests/HttpListenerPrefixCollectionTests.cs | 1 - .../tests/HttpListenerResponseTests.cs | 1 - .../tests/HttpListenerTests.cs | 2 +- .../tests/HttpListenerTimeoutManagerTests.cs | 5 +---- .../tests/HttpResponseStreamTests.cs | 6 +++--- .../tests/FileWebRequestTest.cs | 1 - .../System.Net.Requests/tests/FtpWebRequestTest.cs | 2 +- .../tests/HttpWebRequestTest.cs | 8 +++----- .../tests/HttpWebResponseHeaderTest.cs | 8 +------- .../System.Net.Requests/tests/RequestStreamTest.cs | 10 +++++----- .../System.Net.Requests/tests/WebRequestTest.cs | 2 +- .../System/Net/CertificateValidationPal.Unix.cs | 2 +- .../src/System/Net/Security/TlsFrameHelper.cs | 1 - .../Fakes/FakeSslStream.Implementation.cs | 14 -------------- 19 files changed, 22 insertions(+), 54 deletions(-) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs index d92f4368b408..75be134af2ab 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs @@ -682,7 +682,6 @@ internal HttpListenerContext HandleAuthentication(HttpListenerSession session, R stoleBlob = false; // Some things we need right away. Lift them out now while it's convenient. - string verb = Interop.HttpApi.GetVerb(memoryBlob.RequestBlob); string authorizationHeader = Interop.HttpApi.GetKnownHeader(memoryBlob.RequestBlob, (int)HttpRequestHeader.Authorization); ulong connectionId = memoryBlob.RequestBlob->ConnectionId; ulong requestId = memoryBlob.RequestBlob->RequestId; diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/WebSockets/WebSocketProtocolComponent.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/WebSockets/WebSocketProtocolComponent.cs index a7c24f2ad4c2..72f9f4702ffa 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/WebSockets/WebSocketProtocolComponent.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/WebSockets/WebSocketProtocolComponent.cs @@ -248,7 +248,6 @@ internal static void WebSocketCreateServerHandle(Interop.WebSocket.Property[] pr ThrowOnError(errorCode); - Interop.WebSocket.HttpHeader[] responseHeaders = MarshalHttpHeaders(responseHeadersPtr, (int)responseHeaderCount); errorCode = Interop.WebSocket.WebSocketEndServerHandshake(webSocketHandle); ThrowOnError(errorCode); diff --git a/src/libraries/System.Net.HttpListener/tests/GetContextHelper.cs b/src/libraries/System.Net.HttpListener/tests/GetContextHelper.cs index 5f6586b05528..440f726a333e 100644 --- a/src/libraries/System.Net.HttpListener/tests/GetContextHelper.cs +++ b/src/libraries/System.Net.HttpListener/tests/GetContextHelper.cs @@ -24,7 +24,7 @@ public GetContextHelper(HttpListener listener, string listeningUrl) public async Task GetResponse() { // We need to create a mock request to give the HttpListener a context. - Task clientTask = _client.GetStringAsync(_listeningUrl); + _ = _client.GetStringAsync(_listeningUrl); HttpListenerContext context = await _listener.GetContextAsync(); return context.Response; } diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs index 96c5990785a1..51c1e3361fab 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs @@ -269,7 +269,7 @@ public async Task AuthenticationSchemeSelectorDelegate_ThrowsException_SendsInte using (var client = new HttpClient()) { - HttpResponseMessage response = await AuthenticationFailure(client, HttpStatusCode.InternalServerError); + await AuthenticationFailure(client, HttpStatusCode.InternalServerError); } } @@ -281,7 +281,7 @@ public void AuthenticationSchemeSelectorDelegate_ThrowsOutOfMemoryException_Reth using (var client = new HttpClient()) { - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); Assert.Throws(() => _listener.GetContext()); } } @@ -450,7 +450,7 @@ private async Task ValidateNullUser() Basic, Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", TestUser, TestPassword)))); - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); HttpListenerContext listenerContext = await serverContextTask; Assert.Null(listenerContext.User); @@ -469,7 +469,7 @@ private async Task ValidateValidUser(string authHeader, string expectedUsername, Basic, Convert.ToBase64String(Encoding.ASCII.GetBytes(authHeader))); - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); HttpListenerContext listenerContext = await serverContextTask; Assert.Equal(expectedUsername, listenerContext.User.Identity.Name); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerContextTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerContextTests.cs index 5c06f4658177..964a188923bb 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerContextTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerContextTests.cs @@ -108,7 +108,6 @@ public async Task AcceptWebSocketAsync_AuthorizationInHeaders_ThrowsNotImplement Assert.Equal("user", context.User.Identity.Name); HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null); - IPrincipal user = webSocketContext.User; // Should be copied as User gets disposed when HttpListenerContext is closed. Assert.NotSame(context.User, webSocketContext.User); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs index ce7af21486c0..b1f7d3eaa64d 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs @@ -272,7 +272,6 @@ public void Add_SamePortDifferentPathDifferentListenerNotStarted_Works(string ho { using (var factory1 = new HttpListenerFactory(host, path: string.Empty)) { - HttpListener listener1 = factory1.GetListener(); using (var listener2 = new HttpListener()) { string prefixWithSubPath = $"{factory1.ListeningUrl}sub_path/"; diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs index 5b7fd28d1bbd..dce9cf701069 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs @@ -410,7 +410,6 @@ public async Task CloseResponseEntity_SendMoreThanContentLength_ThrowsInvalidOpe public async Task CloseResponseEntity_SendToClosedConnection_DoesNotThrow(bool willBlock) { const string Text = "Some-String"; - byte[] buffer = Encoding.UTF8.GetBytes(Text); using (HttpListenerFactory factory = new HttpListenerFactory()) using (Socket client = factory.GetConnectedSocket()) diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerTests.cs index 845eed6836b2..c4ec07664961 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerTests.cs @@ -148,7 +148,7 @@ public void EndGetContext_AlreadyCalled_ThrowsInvalidOperationException() HttpListener listener = listenerFactory.GetListener(); listener.Start(); - Task clientTask = client.GetStringAsync(listenerFactory.ListeningUrl); + _ = client.GetStringAsync(listenerFactory.ListeningUrl); IAsyncResult beginGetContextResult = listener.BeginGetContext(null, null); listener.EndGetContext(beginGetContextResult); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerTimeoutManagerTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerTimeoutManagerTests.cs index 961dab466a57..9767c21daec0 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerTimeoutManagerTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerTimeoutManagerTests.cs @@ -369,10 +369,7 @@ private unsafe uint GetServerTimeout(HttpListener _listener, HTTP_TIMEOUT_TYPE t private unsafe void GetUrlGroupProperty(ulong urlGroupId, HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize) { - uint statusCode = 0; - - statusCode = HttpQueryUrlGroupProperty(urlGroupId, HTTP_SERVER_PROPERTY.HttpServerTimeoutsProperty, info, infosize, IntPtr.Zero); - + uint statusCode = HttpQueryUrlGroupProperty(urlGroupId, HTTP_SERVER_PROPERTY.HttpServerTimeoutsProperty, info, infosize, IntPtr.Zero); if (statusCode != 0) { throw new Exception("HttpQueryUrlGroupProperty failed with " + (int)statusCode); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs index f831be2382fd..59bbc82af42f 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs @@ -302,7 +302,7 @@ public async Task Write_TooMuch_ThrowsProtocolViolationException() { using (HttpClient client = new HttpClient()) { - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); HttpListenerContext serverContext = await _listener.GetContextAsync(); using (HttpListenerResponse response = serverContext.Response) @@ -330,7 +330,7 @@ public async Task Write_TooLittleAsynchronouslyAndClose_ThrowsInvalidOperationEx { using (HttpClient client = new HttpClient()) { - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); HttpListenerContext serverContext = await _listener.GetContextAsync(); using (HttpListenerResponse response = serverContext.Response) @@ -356,7 +356,7 @@ public async Task Write_TooLittleSynchronouslyAndClose_ThrowsInvalidOperationExc { using (HttpClient client = new HttpClient()) { - Task clientTask = client.GetStringAsync(_factory.ListeningUrl); + _ = client.GetStringAsync(_factory.ListeningUrl); HttpListenerContext serverContext = await _listener.GetContextAsync(); using (HttpListenerResponse response = serverContext.Response) diff --git a/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs b/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs index 833e1be25f7e..505aa4bf4760 100644 --- a/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs @@ -188,7 +188,6 @@ public async Task RequestAfterResponse_throws() string path = Path.GetTempFileName(); try { - var data = new byte[1024]; WebRequest request = WebRequest.Create("file://" + path); request.Method = WebRequestMethods.File.UploadFile; using (WebResponse response = await GetResponseAsync(request)) diff --git a/src/libraries/System.Net.Requests/tests/FtpWebRequestTest.cs b/src/libraries/System.Net.Requests/tests/FtpWebRequestTest.cs index 7ac66f26d8d4..ff439513b116 100644 --- a/src/libraries/System.Net.Requests/tests/FtpWebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/FtpWebRequestTest.cs @@ -61,7 +61,7 @@ public void GetResponse_ServerNameNotInDns_ThrowsWebException() { string serverUrl = string.Format("ftp://www.{0}.com/", Guid.NewGuid().ToString()); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUrl); - WebException ex = Assert.Throws(() => request.GetResponse()); + Assert.Throws(() => request.GetResponse()); } [OuterLoop] diff --git a/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs b/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs index 32903adbbe87..e4b24c96b5c3 100644 --- a/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs @@ -1164,7 +1164,7 @@ public void BeginGetRequestStream_CreatePostRequestThenCallTwice_ThrowsInvalidOp HttpWebRequest request = HttpWebRequest.CreateHttp(remoteServer); request.Method = "POST"; - IAsyncResult asyncResult = request.BeginGetRequestStream(null, null); + request.BeginGetRequestStream(null, null); Assert.Throws(() => { request.BeginGetRequestStream(null, null); @@ -1178,7 +1178,7 @@ await LoopbackServer.CreateServerAsync((server, url) => { HttpWebRequest request = HttpWebRequest.CreateHttp(url); - IAsyncResult asyncResult = request.BeginGetResponse(null, null); + request.BeginGetResponse(null, null); Assert.Throws(() => { request.BeginGetRequestStream(null, null); @@ -1194,7 +1194,7 @@ public async Task BeginGetResponse_CreateRequestThenCallTwice_ThrowsInvalidOpera await LoopbackServer.CreateServerAsync((server, url) => { HttpWebRequest request = WebRequest.CreateHttp(url); - IAsyncResult asyncResult = request.BeginGetResponse(null, null); + request.BeginGetResponse(null, null); Assert.Throws(() => request.BeginGetResponse(null, null)); return Task.FromResult(null); }); @@ -1324,7 +1324,6 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => public void CookieContainer_Count_Add(Uri remoteServer) { HttpWebRequest request = WebRequest.CreateHttp(remoteServer); - DateTime now = DateTime.UtcNow; request.CookieContainer = new CookieContainer(); request.CookieContainer.Add(remoteServer, new Cookie("1", "cookie1")); request.CookieContainer.Add(remoteServer, new Cookie("2", "cookie2")); @@ -1457,7 +1456,6 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => request.ContentType = HeadersPartialContent; using WebResponse response = await GetResponseAsync(request); - string headersString = response.Headers.ToString(); Assert.Equal(HeadersPartialContent, response.Headers[HttpResponseHeader.ContentType]); }, async server => { diff --git a/src/libraries/System.Net.Requests/tests/HttpWebResponseHeaderTest.cs b/src/libraries/System.Net.Requests/tests/HttpWebResponseHeaderTest.cs index bdec87a62140..6a1ea2eb3b7c 100644 --- a/src/libraries/System.Net.Requests/tests/HttpWebResponseHeaderTest.cs +++ b/src/libraries/System.Net.Requests/tests/HttpWebResponseHeaderTest.cs @@ -28,8 +28,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) => request.Method = HttpMethod.Get.Method; HttpContinueDelegate continueDelegate = new HttpContinueDelegate(HttpContinueMethod); request.ContinueDelegate = continueDelegate; - Task getResponse = request.GetResponseAsync(); - DateTimeOffset utcNow = DateTimeOffset.UtcNow; + _ = request.GetResponseAsync(); await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.OK, "Content-Type: application/json;charset=UTF-8\r\n", "12345"); Assert.Equal(continueDelegate, request.ContinueDelegate); }); @@ -44,7 +43,6 @@ await LoopbackServer.CreateServerAsync(async (server, url) => HttpWebRequest request = WebRequest.CreateHttp(url); request.Method = HttpMethod.Get.Method; Task getResponse = request.GetResponseAsync(); - DateTimeOffset utcNow = DateTimeOffset.UtcNow; await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.OK, "Content-Type: application/json;charset=UTF-8\r\n", "12345"); using (WebResponse response = await getResponse) @@ -71,7 +69,6 @@ await LoopbackServer.CreateServerAsync(async (server, url) => HttpWebRequest request = WebRequest.CreateHttp(url); request.Method = HttpMethod.Get.Method; Task getResponse = request.GetResponseAsync(); - DateTimeOffset utcNow = DateTimeOffset.UtcNow; await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.OK, "Content-Type: application/json;charset=UTF-8\r\n", "12345"); WebResponse response = await getResponse; HttpWebResponse httpResponse = (HttpWebResponse)response; @@ -104,7 +101,6 @@ await LoopbackServer.CreateServerAsync(async (server, url) => [Fact] public async Task LastModified_InvalidDate_Throws() { - DateTime expected = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(2018, 4, 10, 3, 4, 5, DateTimeKind.Utc), TimeZoneInfo.Local); await LoopbackServer.CreateServerAsync(async (server, url) => { HttpWebRequest request = WebRequest.CreateHttp(url); @@ -126,12 +122,10 @@ await LoopbackServer.CreateServerAsync(async (server, url) => HttpWebRequest request = WebRequest.CreateHttp(url); request.Method = HttpMethod.Get.Method; Task getResponse = request.GetResponseAsync(); - DateTimeOffset utcNow = DateTimeOffset.UtcNow; await server.AcceptConnectionSendResponseAndCloseAsync(); using (WebResponse response = await getResponse) { - HttpWebResponse httpResponse = (HttpWebResponse)response; using (MemoryStream fs = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); diff --git a/src/libraries/System.Net.Requests/tests/RequestStreamTest.cs b/src/libraries/System.Net.Requests/tests/RequestStreamTest.cs index 9b6ac07a7d62..f4f48ffe1c43 100644 --- a/src/libraries/System.Net.Requests/tests/RequestStreamTest.cs +++ b/src/libraries/System.Net.Requests/tests/RequestStreamTest.cs @@ -70,7 +70,7 @@ public async Task WriteAsync_BufferIsNull_ThrowsArgumentNullException() { await GetRequestStream((stream) => { - AssertExtensions.Throws("buffer", () => { Task t = stream.WriteAsync(null, 0, 1); }); + AssertExtensions.Throws("buffer", () => { stream.WriteAsync(null, 0, 1); }); }); } @@ -79,7 +79,7 @@ public async Task WriteAsync_OffsetIsNegative_ThrowsArgumentOutOfRangeException( { await GetRequestStream((stream) => { - AssertExtensions.Throws("offset", () => { Task t = stream.WriteAsync(buffer, -1, buffer.Length); }); + AssertExtensions.Throws("offset", () => { stream.WriteAsync(buffer, -1, buffer.Length); }); }); } @@ -88,7 +88,7 @@ public async Task WriteAsync_CountIsNegative_ThrowsArgumentOutOfRangeException() { await GetRequestStream((stream) => { - AssertExtensions.Throws("count", "size", () => { Task t = stream.WriteAsync(buffer, 0, -1); }); + AssertExtensions.Throws("count", "size", () => { stream.WriteAsync(buffer, 0, -1); }); }); } @@ -97,7 +97,7 @@ public async Task WriteAsync_OffsetPlusCountExceedsBufferLength_ThrowsArgumentEx { await GetRequestStream((stream) => { - AssertExtensions.Throws("count", "size", () => { Task t = stream.WriteAsync(buffer, 0, buffer.Length + 1); }); + AssertExtensions.Throws("count", "size", () => { stream.WriteAsync(buffer, 0, buffer.Length + 1); }); }); } @@ -106,7 +106,7 @@ public async Task WriteAsync_OffsetPlusCountMaxValueExceedsBufferLength_Throws() { await GetRequestStream((stream) => { - AssertExtensions.Throws("offset", () => { Task t = stream.WriteAsync(buffer, int.MaxValue, int.MaxValue); }); + AssertExtensions.Throws("offset", () => { stream.WriteAsync(buffer, int.MaxValue, int.MaxValue); }); }); } diff --git a/src/libraries/System.Net.Requests/tests/WebRequestTest.cs b/src/libraries/System.Net.Requests/tests/WebRequestTest.cs index e1fc0df5b5f3..a6746fc33f21 100644 --- a/src/libraries/System.Net.Requests/tests/WebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/WebRequestTest.cs @@ -82,7 +82,7 @@ public void DefaultWebProxy_SetCredentialsToExplicitCredentialsThenGet_ValuesMat public void Create_ValidWebRequestUriScheme_Success(string scheme) { var uri = new Uri($"{scheme}://example.com/folder/resource.txt"); - WebRequest request = WebRequest.Create(uri); + WebRequest.Create(uri); } [Theory] diff --git a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs index 4b7d9e7bd88e..34386aec2631 100644 --- a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs @@ -56,7 +56,7 @@ internal static SslPolicyErrors VerifyCertificateProperties( SafeFreeCertContext? remoteContext = null; try { - int errorCode = QueryContextRemoteCertificate(securityContext, out remoteContext); + QueryContextRemoteCertificate(securityContext, out remoteContext); if (remoteContext != null && !remoteContext.IsInvalid) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs index 7140fea2cf55..29fc55ad5c51 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs @@ -561,7 +561,6 @@ private static bool TryGetSniFromServerNameList(ReadOnlySpan serverNameLis } // Following can underflow but it is ok due to equality check below - int hostNameStructLength = BinaryPrimitives.ReadUInt16BigEndian(serverName) - sizeof(NameType); NameType nameType = (NameType)serverName[NameTypeOffset]; ReadOnlySpan hostNameStruct = serverName.Slice(HostNameStructOffset); if (nameType != NameType.HostName) diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs index 7139118b9101..9b74d718878b 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs @@ -49,22 +49,8 @@ private ValueTask WriteAsyncInternal(TWriteAdapter writeAdapter, private ValueTask ReadAsyncInternal(TReadAdapter adapter, Memory buffer) => default; - private Task CheckEnqueueWriteAsync() => default; - - private void CheckEnqueueWrite() - { - } - - private ValueTask CheckEnqueueReadAsync(Memory buffer) => default; - - private int CheckEnqueueRead(Memory buffer) => default; - private bool RemoteCertRequired => default; - private void CheckThrow(bool authSuccessCheck, bool shutdownCheck = false) - { - } - private void CloseInternal() { } From c47a92d88c22cee081c053d864cac5e2edabca4b Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 11 Aug 2020 14:54:08 -0700 Subject: [PATCH 408/755] Fix handling of collectible thread statics and GC (#40671) - NonGc Thread statics helper returns a ByRef, not a pointer for collectible statics - Add test coverage for collectible statics - Remove test coverage for converting thread static variable into byref and using that to keep alive the static data as it wasn't fully safe itself --- src/coreclr/src/jit/flowgraph.cpp | 2 +- src/coreclr/tests/issues.targets | 3 + .../ByRefLocals/ByRefLocals.cs | 29 ----- .../ByRefLocals/Unloaded.cs | 11 -- .../CollectibleAssemblies/Statics/Accessor.cs | 12 ++ .../Statics/Accessor.csproj | 11 ++ .../Statics/CollectibleStatics.cs | 54 +++++++++ .../Statics/CollectibleStatics.csproj | 13 ++ .../CollectibleAssemblies/Statics/Unloaded.cs | 113 ++++++++++++++++++ .../Statics/Unloaded.csproj | 12 ++ 10 files changed, 219 insertions(+), 41 deletions(-) create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/Accessor.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/Accessor.csproj create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.csproj create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.cs create mode 100644 src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.csproj diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 242a4c56791e..48f3273e38ea 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -7401,6 +7401,7 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS: case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE: case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS: + case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS: // type = TYP_BYREF; break; @@ -7414,7 +7415,6 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE: case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE: - case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS: case CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS: type = TYP_I_IMPL; break; diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 246f85c958f8..c3001db132ac 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -961,6 +961,9 @@ https://github.com/dotnet/runtime/issues/40394 + + https://github.com/dotnet/runtime/issues/40394 + Handling for Copy constructors isn't present in mono interop diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs index 834bc472497f..fb2bd1077182 100644 --- a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/ByRefLocals.cs @@ -40,15 +40,6 @@ static int Main(string[] args) [MethodImpl(MethodImplOptions.NoInlining)] static int HoldAssembliesAliveThroughByRefFields(out GCHandle gch1, out GCHandle gch2) { - // ThreadStatic lifetime check. Here we don't require the actual assembly to remain loaded, but we do require the field to remain accessible - var spanThreadStatic = LoadAssemblyThreadStatic(out GCHandle gchThreadStatic); - GC.Collect(2); - GC.WaitForPendingFinalizers(); - GC.Collect(2); - GC.WaitForPendingFinalizers(); - GC.Collect(2); - GC.WaitForPendingFinalizers(); - var span1 = LoadAssembly(out gch1); GC.Collect(2); GC.WaitForPendingFinalizers(); @@ -61,7 +52,6 @@ static int HoldAssembliesAliveThroughByRefFields(out GCHandle gch1, out GCHandle { Console.WriteLine(span1[0]); Console.WriteLine(span2[0]); - Console.WriteLine(spanThreadStatic[0]); GC.Collect(2); GC.WaitForPendingFinalizers(); if (gch1.Target == null) @@ -72,11 +62,6 @@ static int HoldAssembliesAliveThroughByRefFields(out GCHandle gch1, out GCHandle { return 2; } - if (spanThreadStatic[0] != 7) - { - Console.WriteLine($"spanThreadStatic[0] = {spanThreadStatic[0]}"); - return 5; - } } return 100; @@ -96,20 +81,6 @@ private static ReadOnlySpan LoadAssembly(out GCHandle gchToAssembly) return spanAccessor.GetSpan(); } - [MethodImpl(MethodImplOptions.NoInlining)] - private static ReadOnlySpan LoadAssemblyThreadStatic(out GCHandle gchToAssembly) - { - var alc = new AssemblyLoadContext("test", isCollectible: true); - var a = alc.LoadFromAssemblyPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Unloaded.dll")); - gchToAssembly = GCHandle.Alloc(a, GCHandleType.WeakTrackResurrection); - - var spanAccessor = (IReturnSpan)Activator.CreateInstance(a.GetType("ThreadStaticSpanAccessor")); - - alc.Unload(); - - return spanAccessor.GetSpan(); - } - [MethodImpl(MethodImplOptions.NoInlining)] private static ReadOnlySpan CreateAssemblyDynamically(out GCHandle gchToAssembly) { diff --git a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs index 3f2615e99a02..0a326df79126 100644 --- a/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs +++ b/src/tests/Loader/CollectibleAssemblies/ByRefLocals/Unloaded.cs @@ -13,14 +13,3 @@ public ReadOnlySpan GetSpan() return RawData; } } - -public class ThreadStaticSpanAccessor : IReturnSpan -{ - [ThreadStatic] - public static byte ThreadStaticByte = 7; - - public unsafe ReadOnlySpan GetSpan() - { - return new ReadOnlySpan(Unsafe.AsPointer(ref ThreadStaticByte), 1); - } -} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.cs b/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.cs new file mode 100644 index 000000000000..69343ada3384 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public interface IStaticTest +{ + void SetStatic(int val, int val2, int val3, int val4, int val5); + void GetStatic(out int val1, out int val2, out int val3, out int val4, out int val5); + void SetStaticObject(object val, object val2, object val3, object val4, object val5); + void GetStaticObject(out object val1, out object val2, out object val3, out object val4, out object val5); +} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.csproj b/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.csproj new file mode 100644 index 000000000000..528466d13598 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/Accessor.csproj @@ -0,0 +1,11 @@ + + + true + Library + BuildOnly + 0 + + + + + \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs new file mode 100644 index 000000000000..16cbb15ce67b --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs @@ -0,0 +1,54 @@ +// 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.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Loader; + +class Program +{ + static int Main(string[] args) + { + var alc = new AssemblyLoadContext("test", isCollectible: true); + var a = alc.LoadFromAssemblyPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Unloaded.dll")); + + var accessor = (IStaticTest)Activator.CreateInstance(a.GetType("StaticTest")); + accessor.SetStatic(12759, 548739, 5468, 8518, 9995); + accessor.GetStatic(out int val1, out int val2, out int val3, out int val4, out int val5); + if (val1 != 12759) + return 1; + if (val2 != 548739) + return 2; + if (val3 != 5468) + return 3; + if (val4 != 8518) + return 4; + if (val5 != 9995) + return 5; + + object obj1 = new object(); + object obj2 = new object(); + object obj3 = new object(); + object obj4 = new object(); + object obj5 = new object(); + accessor.SetStaticObject(obj1, obj2, obj3, obj4, obj5); + accessor.GetStaticObject(out object val1Obj, out object val2Obj, out object val3Obj, out object val4Obj, out object val5Obj); + if (val1Obj != obj1) + return 11; + if (val2Obj != obj2) + return 12; + if (val3Obj != obj3) + return 13; + if (val4Obj != obj4) + return 14; + if (val5Obj != obj5) + return 15; + + GC.KeepAlive(accessor); + return 100; + } +} \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.csproj b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.csproj new file mode 100644 index 000000000000..27b8b2a9ebd8 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.csproj @@ -0,0 +1,13 @@ + + + true + Exe + BuildAndRun + 0 + + + + + + + \ No newline at end of file diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.cs b/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.cs new file mode 100644 index 000000000000..447b8d9a42e2 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.cs @@ -0,0 +1,113 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +// Use multiple classes to trigger multiple statics allocation events +public class StaticTest2 +{ + [ThreadStatic] + public static int ThreadStaticValue; + public static int StaticValue; +} + +public class StaticTest3 +{ + public static int StaticValue; +} + +public class StaticTest4 +{ + [ThreadStatic] + public static object ThreadStaticValue; + public static object StaticValue; +} +public class StaticTest5 +{ + [ThreadStatic] + public static object ThreadStaticValue; + public static object StaticValue; +} +public class StaticTest6 +{ + public static object StaticValue; +} + + +public class StaticTest : IStaticTest +{ + [ThreadStatic] + public static int ThreadStaticValue; + public static int StaticValue; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SetValues(out int valTargetA, int valA + , out int valTargetB, int valB + , out int valTargetC, int valC + , out int valTargetD, int valD + , out int valTargetE, int valE + ) + { + valTargetA = valA; + valTargetB = valB; + valTargetC = valC; + valTargetD = valD; + valTargetE = valE; + } + + public void SetStatic(int val, int val2, int val3, int val4, int val5) + { + // Use this odd pathway to increase the chance that in the presence of GCStress issues will be found + SetValues(out ThreadStaticValue, val + , out StaticValue, val2 + , out StaticTest2.StaticValue, val3 + , out StaticTest2.ThreadStaticValue, val4 + , out StaticTest3.StaticValue, val5 + ); + } + + public void GetStatic(out int val1, out int val2, out int val3, out int val4, out int val5) + { + val1 = ThreadStaticValue; + val2 = StaticValue; + val3 = StaticTest2.StaticValue; + val4 = StaticTest2.ThreadStaticValue; + val5 = StaticTest3.StaticValue; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SetValuesObject(out object valTargetA, object valA + , out object valTargetB, object valB + , out object valTargetC, object valC + , out object valTargetD, object valD + , out object valTargetE, object valE + ) + { + valTargetA = valA; + valTargetB = valB; + valTargetC = valC; + valTargetD = valD; + valTargetE = valE; + } + + public void SetStaticObject(object val, object val2, object val3, object val4, object val5) + { + // Use this odd pathway to increase the chance that in the presence of GCStress issues will be found + SetValuesObject(out StaticTest4.ThreadStaticValue, val + , out StaticTest4.StaticValue, val2 + , out StaticTest5.StaticValue, val3 + , out StaticTest5.ThreadStaticValue, val4 + , out StaticTest6.StaticValue, val5 + ); + } + + public void GetStaticObject(out object val1, out object val2, out object val3, out object val4, out object val5) + { + val1 = StaticTest4.ThreadStaticValue; + val2 = StaticTest4.StaticValue; + val3 = StaticTest5.StaticValue; + val4 = StaticTest5.ThreadStaticValue; + val5 = StaticTest6.StaticValue; + } +} diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.csproj b/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.csproj new file mode 100644 index 000000000000..4d5f1d847c54 --- /dev/null +++ b/src/tests/Loader/CollectibleAssemblies/Statics/Unloaded.csproj @@ -0,0 +1,12 @@ + + + true + Library + BuildOnly + 0 + + + + + + \ No newline at end of file From 7c9db601b7a4d220fbb24783d2fa93f2e2cc6d2d Mon Sep 17 00:00:00 2001 From: lindexi Date: Wed, 12 Aug 2020 06:18:21 +0800 Subject: [PATCH 409/755] Add logger to cache entry to catch exception (#37292) --- .../src/CacheEntry.cs | 15 ++++++++++++--- .../src/MemoryCache.cs | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs index 96c1ffa772d2..7c28f19487fa 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Primitives; namespace Microsoft.Extensions.Caching.Memory @@ -18,6 +19,7 @@ internal class CacheEntry : ICacheEntry private IList _expirationTokenRegistrations; private IList _postEvictionCallbacks; private bool _isExpired; + private readonly ILogger _logger; internal IList _expirationTokens; internal DateTimeOffset? _absoluteExpiration; @@ -31,7 +33,8 @@ internal class CacheEntry : ICacheEntry internal CacheEntry( object key, Action notifyCacheEntryDisposed, - Action notifyCacheOfExpiration) + Action notifyCacheOfExpiration, + ILogger logger) { if (key == null) { @@ -48,11 +51,17 @@ internal CacheEntry( throw new ArgumentNullException(nameof(notifyCacheOfExpiration)); } + if (logger == null) + { + throw new ArgumentNullException(nameof(logger)); + } + Key = key; _notifyCacheEntryDisposed = notifyCacheEntryDisposed; _notifyCacheOfExpiration = notifyCacheOfExpiration; _scope = CacheEntryHelper.EnterScope(this); + _logger = logger; } /// @@ -317,10 +326,10 @@ private static void InvokeCallbacks(CacheEntry entry) { registration.EvictionCallback?.Invoke(entry.Key, entry.Value, entry.EvictionReason, registration.State); } - catch (Exception) + catch (Exception e) { // This will be invoked on a background thread, don't let it throw. - // TODO: LOG + entry._logger.LogError(e, "EvictionCallback invoked failed"); } } } diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs index 5bbfb4acf241..9d3c38c06aa9 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs @@ -103,7 +103,8 @@ public ICacheEntry CreateEntry(object key) return new CacheEntry( key, _setEntry, - _entryExpirationNotification + _entryExpirationNotification, + _logger ); } From 8bc5dbd1e5b9fb38bd0b5f3e53409865f93bda3d Mon Sep 17 00:00:00 2001 From: Edison Henrique Andreassy Date: Tue, 11 Aug 2020 20:34:01 -0300 Subject: [PATCH 410/755] [VisualBasic] Fix TypeName for COM objects (#40584) * Initial try of TypeName for ComObjects on Windows * Implemented TypeNameOfCOMObject to use in Versioned.TypeName * Separated tests of the TypeName for COM objects * Utils.VBFriendlyName now matches reference source * Moved TypeName for COM objects tests to VersionedTests * Added ILLinkTrim.xml as a temporary solution as comented on #35937 * UnsafeNativeMethods are only available on Windows * Test refactoration * Skip COM interop test on Mono * Explicit types in ILLinkTrim.xml * Call GetTypeFromProgID with throwOnError true * Disabled TypeName_ComObject test on Windows Nano --- .../src/ILLinkTrim.xml | 8 + .../CompilerServices/Utils.LateBinder.vb | 4 + .../VisualBasic/CompilerServices/Versioned.vb | 8 + .../Helpers/UnsafeNativeMethods.vb | 243 ++++++++++++++++++ .../src/Microsoft/VisualBasic/Information.vb | 79 ++++++ .../tests/CompilerServices/VersionedTests.cs | 17 ++ 6 files changed, 359 insertions(+) create mode 100644 src/libraries/Microsoft.VisualBasic.Core/src/ILLinkTrim.xml diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/ILLinkTrim.xml b/src/libraries/Microsoft.VisualBasic.Core/src/ILLinkTrim.xml new file mode 100644 index 000000000000..0b03152865f9 --- /dev/null +++ b/src/libraries/Microsoft.VisualBasic.Core/src/ILLinkTrim.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Utils.LateBinder.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Utils.LateBinder.vb index 60b60d57f03c..d2c97225bf88 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Utils.LateBinder.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Utils.LateBinder.vb @@ -343,6 +343,10 @@ GetSpecialValue: End Function Friend Shared Function VBFriendlyName(ByVal typ As System.Type, ByVal o As Object) As String + If typ.IsCOMObject AndAlso (typ.FullName = "System.__ComObject") Then + Return TypeNameOfCOMObject(o, False) + End If + Return VBFriendlyNameOfType(typ) End Function diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Versioned.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Versioned.vb index 3d54d11a9826..ec2405ea0089 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Versioned.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Versioned.vb @@ -110,7 +110,15 @@ Namespace Microsoft.VisualBasic.CompilerServices End If typ = Expression.GetType() +#If TARGET_WINDOWS Then + If (typ.IsCOMObject AndAlso (System.String.CompareOrdinal(typ.Name, COMObjectName) = 0)) Then + Result = TypeNameOfCOMObject(Expression, True) + Else + Result = VBFriendlyNameOfType(typ) + End If +#Else Result = VBFriendlyNameOfType(typ) +#End If Return Result End Function diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb index 551571b3dd17..e021b542552b 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb @@ -60,6 +60,249 @@ Namespace Microsoft.VisualBasic.CompilerServices Friend Shared Function GetLogicalDrives() As Integer End Function + Public Const LCID_US_ENGLISH As Integer = &H409 + + + Public Enum tagSYSKIND + SYS_WIN16 = 0 + SYS_MAC = 2 + End Enum + + ' REVIEW : - c# version was class, does it make a difference? + ' [StructLayout(LayoutKind.Sequential)] + ' Public class tagTLIBATTR { + + Public Structure tagTLIBATTR + Public guid As Guid + Public lcid As Integer + Public syskind As tagSYSKIND + Public wMajorVerNum As Short + Public wMinorVerNum As Short + Public wLibFlags As Short + End Structure + + + Public Interface ITypeComp + + + Sub RemoteBind( + <[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal szName As String, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal lHashVal As Integer, + <[In](), MarshalAs(UnmanagedType.U2)> ByVal wFlags As Short, + ByVal ppTInfo As ITypeInfo(), + ByVal pDescKind As ComTypes.DESCKIND(), + ByVal ppFuncDesc As ComTypes.FUNCDESC(), + ByVal ppVarDesc As ComTypes.VARDESC(), + ByVal ppTypeComp As ITypeComp(), + ByVal pDummy As Integer()) + + Sub RemoteBindType( + <[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal szName As String, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal lHashVal As Integer, + ByVal ppTInfo As ITypeInfo()) + End Interface + + + Public Interface IDispatch + + + + Function GetTypeInfoCount() As Integer + + + Function GetTypeInfo( + <[In]()> ByVal index As Integer, + <[In]()> ByVal lcid As Integer, + <[Out](), MarshalAs(UnmanagedType.Interface)> ByRef pTypeInfo As ITypeInfo) As Integer + + ' WARNING : - This api NOT COMPLETELY DEFINED, DO NOT CALL! + + Function GetIDsOfNames() As Integer + + ' WARNING : - This api NOT COMPLETELY DEFINED, DO NOT CALL! + + Function Invoke() As Integer + End Interface + + + Public Interface ITypeInfo + + Function GetTypeAttr( + ByRef pTypeAttr As IntPtr) As Integer + + + Function GetTypeComp( + ByRef pTComp As ITypeComp) As Integer + + + + Function GetFuncDesc( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByRef pFuncDesc As IntPtr) As Integer + + + Function GetVarDesc( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByRef pVarDesc As IntPtr) As Integer + + + Function GetNames( + <[In]()> ByVal memid As Integer, + ByVal rgBstrNames As String(), + <[In](), MarshalAs(UnmanagedType.U4)> ByVal cMaxNames As Integer, + ByRef cNames As Integer) As Integer + + + + Function GetRefTypeOfImplType( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByRef pRefType As Integer) As Integer + + + + Function GetImplTypeFlags( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByVal pImplTypeFlags As Integer) As Integer + + + Function GetIDsOfNames( + <[In]()> ByVal rgszNames As IntPtr, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal cNames As Integer, + ByRef pMemId As IntPtr) As Integer + + + + Function Invoke() As Integer + + + Function GetDocumentation( + <[In]()> ByVal memid As Integer, + ByRef pBstrName As String, + ByRef pBstrDocString As String, + ByRef pdwHelpContext As Integer, + ByRef pBstrHelpFile As String) As Integer + + + + Function GetDllEntry( + <[In]()> ByVal memid As Integer, + <[In]()> ByVal invkind As ComTypes.INVOKEKIND, + ByVal pBstrDllName As String, + ByVal pBstrName As String, + ByVal pwOrdinal As Short) As Integer + + + Function GetRefTypeInfo( + <[In]()> ByVal hreftype As IntPtr, + ByRef pTypeInfo As ITypeInfo) As Integer + + + + Function AddressOfMember() As Integer + + + + Function CreateInstance( + <[In]()> ByRef pUnkOuter As IntPtr, + <[In]()> ByRef riid As Guid, + ByVal ppvObj As Object) As Integer + + + + Function GetMops( + <[In]()> ByVal memid As Integer, + ByVal pBstrMops As String) As Integer + + + Function GetContainingTypeLib( + ByVal ppTLib As ITypeLib(), + ByVal pIndex As Integer()) As Integer + + + Sub ReleaseTypeAttr(ByVal typeAttr As IntPtr) + + + Sub ReleaseFuncDesc(ByVal funcDesc As IntPtr) + + + Sub ReleaseVarDesc(ByVal varDesc As IntPtr) + End Interface + + + Public Interface IProvideClassInfo + Function GetClassInfo() As ITypeInfo + End Interface + + + Public Interface ITypeLib + + Sub RemoteGetTypeInfoCount( + ByVal pcTInfo As Integer()) + + Sub GetTypeInfo( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByVal ppTInfo As ITypeInfo()) + + Sub GetTypeInfoType( + <[In](), MarshalAs(UnmanagedType.U4)> ByVal index As Integer, + ByVal pTKind As ComTypes.TYPEKIND()) + + Sub GetTypeInfoOfGuid( + <[In]()> ByRef guid As Guid, + ByVal ppTInfo As ITypeInfo()) + + + Sub RemoteGetLibAttr( + ByVal ppTLibAttr As tagTLIBATTR(), + ByVal pDummy As Integer()) + + Sub GetTypeComp( + ByVal ppTComp As ITypeComp()) + + + Sub RemoteGetDocumentation( + ByVal index As Integer, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal refPtrFlags As Integer, + ByVal pBstrName As String(), + ByVal pBstrDocString As String(), + ByVal pdwHelpContext As Integer(), + ByVal pBstrHelpFile As String()) + + + Sub RemoteIsName( + <[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal szNameBuf As String, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal lHashVal As Integer, + ByVal pfName As IntPtr(), + ByVal pBstrLibName As String()) + + + Sub RemoteFindName( + <[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal szNameBuf As String, + <[In](), MarshalAs(UnmanagedType.U4)> ByVal lHashVal As Integer, + ByVal ppTInfo As ITypeInfo(), + ByVal rgMemId As Integer(), + <[In](), Out(), MarshalAs(UnmanagedType.LPArray)> ByVal pcFound As Short(), + ByVal pBstrLibName As String()) + + + Sub LocalReleaseTLibAttr() + End Interface + ''' ''' Frees memory allocated from the local heap. i.e. frees memory allocated ''' by LocalAlloc or LocalReAlloc.n diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Information.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Information.vb index ad351998d9ef..4c85fc225ead 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Information.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/Information.vb @@ -156,6 +156,64 @@ Namespace Microsoft.VisualBasic End Function + Friend Function TypeNameOfCOMObject(ByVal VarName As Object, ByVal bThrowException As Boolean) As String + + Dim Result As String = COMObjectName + +#If TARGET_WINDOWS Then + Dim pTypeInfo As UnsafeNativeMethods.ITypeInfo = Nothing + Dim hr As Integer + Dim ClassName As String = Nothing + Dim DocString As String = Nothing + Dim HelpContext As Integer + Dim HelpFile As String = Nothing + + + Do + Dim pProvideClassInfo As UnsafeNativeMethods.IProvideClassInfo = TryCast(VarName, UnsafeNativeMethods.IProvideClassInfo) + + If pProvideClassInfo IsNot Nothing Then + Try + pTypeInfo = pProvideClassInfo.GetClassInfo() + hr = pTypeInfo.GetDocumentation(-1, ClassName, DocString, HelpContext, HelpFile) + If hr >= 0 Then + Result = ClassName + Exit Do + End If + pTypeInfo = Nothing + Catch ex As StackOverflowException + Throw ex + Catch ex As OutOfMemoryException + Throw ex + Catch + 'Ignore the error + End Try + End If + + Dim pDispatch As UnsafeNativeMethods.IDispatch = TryCast(VarName, UnsafeNativeMethods.IDispatch) + + If pDispatch IsNot Nothing Then + ' Try using IDispatch + hr = pDispatch.GetTypeInfo(0, UnsafeNativeMethods.LCID_US_ENGLISH, pTypeInfo) + If hr >= 0 Then + hr = pTypeInfo.GetDocumentation(-1, ClassName, DocString, HelpContext, HelpFile) + If hr >= 0 Then + Result = ClassName + Exit Do + End If + End If + End If + + Loop While (False) +#End If + + + If Result.Chars(0) = "_"c Then + Result = Result.Substring(1) + End If + + Return Result + End Function Public Function QBColor(ByVal Color As Integer) As Integer If (Color And &HFFF0I) <> 0 Then @@ -498,6 +556,27 @@ UnmangleName: Dim Result As String = COMObjectName +#If TARGET_WINDOWS Then + Dim pTypeInfo As UnsafeNativeMethods.ITypeInfo = Nothing + Dim hr As Integer + Dim ClassName As String = Nothing + Dim DocString As String = Nothing + Dim HelpContext As Integer + Dim HelpFile As String = Nothing + + Dim pDispatch As UnsafeNativeMethods.IDispatch = TryCast(VarName, UnsafeNativeMethods.IDispatch) + + If pDispatch IsNot Nothing Then + hr = pDispatch.GetTypeInfo(0, UnsafeNativeMethods.LCID_US_ENGLISH, pTypeInfo) + If hr >= 0 Then + hr = pTypeInfo.GetDocumentation(-1, ClassName, DocString, HelpContext, HelpFile) + If hr >= 0 Then + Result = ClassName + End If + End If + End If +#End If + If Result.Chars(0) = "_"c Then Result = Result.Substring(1) End If diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs index 56b85919578d..c2a930cf9d00 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs @@ -106,6 +106,16 @@ public void TypeName(object expression, string expected) Assert.Equal(expected, Versioned.TypeName(expression)); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.IsNotWindowsNanoServer))] + [MemberData(nameof(TypeName_ComObject_TestData))] + [SkipOnMono("COM Interop not supported on Mono")] + public void TypeName_ComObject(string progId, string expected) + { + Type type = Type.GetTypeFromProgID(progId, true); + object expression = Activator.CreateInstance(type); + Assert.Equal(expected, Versioned.TypeName(expression)); + } + public static IEnumerable TypeName_TestData() { yield return new object[] { null, "Nothing" }; @@ -132,6 +142,13 @@ public static IEnumerable TypeName_TestData() yield return new object[] { (int?)0, "Integer" }; } + public static IEnumerable TypeName_ComObject_TestData() + { + yield return new object[] { "ADODB.Stream", "Stream" }; + yield return new object[] { "MSXML2.DOMDocument", "DOMDocument" }; + yield return new object[] { "Scripting.Dictionary", "Dictionary" }; + } + [Theory] [InlineData(null, null)] [InlineData("System.Object", "Object")] From c0d2bfcd8b0af1d8559049ccb2a8d80eb5a9ccdd Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 11 Aug 2020 17:04:46 -0700 Subject: [PATCH 411/755] add macOS 11 with arm64 to RID graph (#40644) --- .../runtime.compatibility.json | 67 +++++++++++++++++++ .../Microsoft.NETCore.Platforms/runtime.json | 40 +++++++++++ .../runtimeGroups.props | 6 ++ 3 files changed, 113 insertions(+) diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json index 23364664048f..c425623dbd66 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json @@ -3661,6 +3661,14 @@ "any", "base" ], + "osx-arm64": [ + "osx-arm64", + "osx", + "unix-arm64", + "unix", + "any", + "base" + ], "osx-x64": [ "osx-x64", "osx", @@ -3816,6 +3824,65 @@ "any", "base" ], + "osx.11": [ + "osx.11", + "osx", + "unix", + "any", + "base" + ], + "osx.11-arm64": [ + "osx.11-arm64", + "osx.11", + "osx-arm64", + "osx", + "unix-arm64", + "unix", + "any", + "base" + ], + "osx.11-x64": [ + "osx.11-x64", + "osx.11", + "osx-x64", + "osx", + "unix-x64", + "unix", + "any", + "base" + ], + "osx.11.0": [ + "osx.11.0", + "osx.11", + "osx", + "unix", + "any", + "base" + ], + "osx.11.0-arm64": [ + "osx.11.0-arm64", + "osx.11.0", + "osx.11-arm64", + "osx.11", + "osx-arm64", + "osx", + "unix-arm64", + "unix", + "any", + "base" + ], + "osx.11.0-x64": [ + "osx.11.0-x64", + "osx.11.0", + "osx.11-x64", + "osx.11", + "osx-x64", + "osx", + "unix-x64", + "unix", + "any", + "base" + ], "rhel": [ "rhel", "linux", diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json index 194291526c90..1a7e4c320a50 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json @@ -1571,6 +1571,12 @@ "unix" ] }, + "osx-arm64": { + "#import": [ + "osx", + "unix-arm64" + ] + }, "osx-x64": { "#import": [ "osx", @@ -1643,6 +1649,40 @@ "osx.10.14-x64" ] }, + "osx.11": { + "#import": [ + "osx" + ] + }, + "osx.11-arm64": { + "#import": [ + "osx.11", + "osx-arm64" + ] + }, + "osx.11-x64": { + "#import": [ + "osx.11", + "osx-x64" + ] + }, + "osx.11.0": { + "#import": [ + "osx.11" + ] + }, + "osx.11.0-arm64": { + "#import": [ + "osx.11.0", + "osx.11-arm64" + ] + }, + "osx.11.0-x64": { + "#import": [ + "osx.11.0", + "osx.11-x64" + ] + }, "rhel": { "#import": [ "linux" diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props index 761fd98479f8..76b491cbb381 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props @@ -124,6 +124,12 @@ 10.10;10.11;10.12;10.13;10.14;10.15 + + unix + x64;arm64 + 11;11.0 + + unix x64 From 9f0826200b6b97b9ae1a0d184c938dc70bf55ea2 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 11 Aug 2020 17:50:06 -0700 Subject: [PATCH 412/755] Re-enable tracelogging test for crossgen2 (#40685) It works now, and appears to have been fixed by a infra fix some time ago --- src/coreclr/tests/issues.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index c3001db132ac..7bdde0d4b33a 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -941,9 +941,6 @@ https://github.com/dotnet/runtime/issues/38290 - - https://github.com/dotnet/runtime/issues/32728 - + + From 1972ba770c9691a51c6eb5f2e3fc88730f5e33e4 Mon Sep 17 00:00:00 2001 From: Maoni Stephens Date: Wed, 12 Aug 2020 12:57:19 -0700 Subject: [PATCH 435/755] card mark stealing fix (#40646) When we are doing card mark stealing, different GC threads will be updating n_eph/n_gen and whichever thread happens to mark the heap last will overwrite previous n_eph/n_gen with its calculation. We need to accumulate updates from all threads that work on a heap. --- src/coreclr/src/gc/gc.cpp | 81 +++++++++++++++++++++++++++++------ src/coreclr/src/gc/gcconfig.h | 3 +- src/coreclr/src/gc/gcpriv.h | 16 ++++++- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index e20daab80ed2..7203ab7cabc2 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -53,6 +53,9 @@ BOOL bgc_heap_walk_for_etw_p = FALSE; #define MAX_PTR ((uint8_t*)(~(ptrdiff_t)0)) #define commit_min_th (16*OS_PAGE_SIZE) +#define MIN_SOH_CROSS_GEN_REFS (400) +#define MIN_LOH_CROSS_GEN_REFS (800) + static size_t smoothed_desired_per_heap = 0; #ifdef SERVER_GC @@ -2182,6 +2185,8 @@ size_t gc_heap::current_total_committed_bookkeeping = 0; double gc_heap::short_plugs_pad_ratio = 0; #endif //SHORT_PLUGS +int gc_heap::generation_skip_ratio_threshold = 0; + uint64_t gc_heap::suspended_start_time = 0; uint64_t gc_heap::end_gc_time = 0; uint64_t gc_heap::total_suspended_time = 0; @@ -2271,6 +2276,12 @@ uint32_t gc_heap::fgn_maxgen_percent = 0; size_t gc_heap::fgn_last_alloc = 0; int gc_heap::generation_skip_ratio = 100; +#ifdef FEATURE_CARD_MARKING_STEALING +VOLATILE(size_t) gc_heap::n_eph_soh = 0; +VOLATILE(size_t) gc_heap::n_gen_soh = 0; +VOLATILE(size_t) gc_heap::n_eph_loh = 0; +VOLATILE(size_t) gc_heap::n_gen_loh = 0; +#endif //FEATURE_CARD_MARKING_STEALING uint64_t gc_heap::loh_alloc_since_cg = 0; @@ -3039,7 +3050,7 @@ gc_heap::dt_low_card_table_efficiency_p (gc_tuning_point tp) /* promote into max-generation if the card table has too many * generation faults besides the n -> 0 */ - ret = (generation_skip_ratio < 30); + ret = (generation_skip_ratio < generation_skip_ratio_threshold); break; } @@ -10564,6 +10575,8 @@ gc_heap::init_semi_shared() short_plugs_pad_ratio = (double)DESIRED_PLUG_LENGTH / (double)(DESIRED_PLUG_LENGTH - Align (min_obj_size)); #endif //SHORT_PLUGS + generation_skip_ratio_threshold = (int)GCConfig::GetGCLowSkipRatio(); + ret = 1; cleanup: @@ -10805,6 +10818,12 @@ gc_heap::init_gc_heap (int h_number) generation_skip_ratio = 100; +#ifdef FEATURE_CARD_MARKING_STEALING + n_eph_soh = 0; + n_gen_soh = 0; + n_eph_loh = 0; + n_gen_loh = 0; +#endif //FEATURE_CARD_MARKING_STEALING mark_stack_tos = 0; mark_stack_bos = 0; @@ -20514,6 +20533,13 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p) if (!full_p) { +#ifdef FEATURE_CARD_MARKING_STEALING + n_eph_soh = 0; + n_gen_soh = 0; + n_eph_loh = 0; + n_gen_loh = 0; +#endif //FEATURE_CARD_MARKING_STEALING + #ifdef CARD_BUNDLE #ifdef MULTIPLE_HEAPS if (gc_t_join.r_join(this, gc_r_join_update_card_bundle)) @@ -20656,6 +20682,18 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p) #ifdef FEATURE_CARD_MARKING_STEALING reset_card_marking_enumerators(); + + if (!full_p) + { + int generation_skip_ratio_soh = ((n_eph_soh > MIN_SOH_CROSS_GEN_REFS) ? + (int)(((float)n_gen_soh / (float)n_eph_soh) * 100) : 100); + int generation_skip_ratio_loh = ((n_eph_loh > MIN_LOH_CROSS_GEN_REFS) ? + (int)(((float)n_gen_loh / (float)n_eph_loh) * 100) : 100); + + generation_skip_ratio = min (generation_skip_ratio_soh, generation_skip_ratio_loh); + dprintf (2, ("h%d skip ratio soh: %d, loh: %d", heap_number, + generation_skip_ratio_soh, generation_skip_ratio_loh)); + } #endif // FEATURE_CARD_MARKING_STEALING // null out the target of short weakref that were not promoted. @@ -29470,7 +29508,6 @@ gc_heap::compute_next_boundary (int gen_number, assert (gen_number > settings.condemned_generation); return generation_allocation_start (generation_of (gen_number - 1 )); } - } inline void @@ -29545,7 +29582,6 @@ gc_heap::mark_through_cards_helper (uint8_t** poo, size_t& n_gen, cg_pointers_found ++; dprintf (4, ("cg pointer %Ix found, %Id so far", (size_t)*poo, cg_pointers_found )); - } } @@ -30013,9 +30049,20 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating CARD_ // compute the efficiency ratio of the card table if (!relocating) { - generation_skip_ratio = ((n_eph > 400)? (int)(((float)n_gen / (float)n_eph) * 100) : 100); - dprintf (3, ("Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d", - n_eph, n_gen , n_card_set, total_cards_cleared, generation_skip_ratio)); +#ifdef FEATURE_CARD_MARKING_STEALING + Interlocked::ExchangeAddPtr(&n_eph_soh, n_eph); + Interlocked::ExchangeAddPtr(&n_gen_soh, n_gen); + dprintf (3, ("h%d marking h%d Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d", + hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared, + (n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0))); + dprintf (3, ("h%d marking h%d Msoh: total cross %Id, useful: %Id, running ratio: %d", + hpt->heap_number, heap_number, n_eph_soh, n_gen_soh, + (n_eph_soh ? (int)(((float)n_gen_soh / (float)n_eph_soh) * 100) : 0))); +#else + generation_skip_ratio = ((n_eph > MIN_SOH_CROSS_GEN_REFS) ? (int)(((float)n_gen / (float)n_eph) * 100) : 100); + dprintf (3, ("marking h%d Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d", + heap_number, n_eph, n_gen, n_card_set, total_cards_cleared, generation_skip_ratio)); +#endif //FEATURE_CARD_MARKING_STEALING } else { @@ -34149,12 +34196,22 @@ void gc_heap::mark_through_cards_for_uoh_objects (card_fn fn, // compute the efficiency ratio of the card table if (!relocating) { - generation_skip_ratio = min (((n_eph > 800) ? - (int)(((float)n_gen / (float)n_eph) * 100) : 100), - generation_skip_ratio); - - dprintf (3, ("Mloh: cross: %Id, useful: %Id, cards cleared: %Id, cards set: %Id, ratio: %d", - n_eph, n_gen, total_cards_cleared, n_card_set, generation_skip_ratio)); +#ifdef FEATURE_CARD_MARKING_STEALING + Interlocked::ExchangeAddPtr(&n_eph_loh, n_eph); + Interlocked::ExchangeAddPtr(&n_gen_loh, n_gen); + dprintf (3, ("h%d marking h%d Mloh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d", + hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared, + (n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0))); + dprintf (3, ("h%d marking h%d Mloh: total cross %Id, useful: %Id, running ratio: %d", + hpt->heap_number, heap_number, n_eph_loh, n_gen_loh, + (n_eph_loh ? (int)(((float)n_gen_loh / (float)n_eph_loh) * 100) : 0))); +#else + generation_skip_ratio = min (((n_eph > MIN_LOH_CROSS_GEN_REFS) ? + (int)(((float)n_gen / (float)n_eph) * 100) : 100), + generation_skip_ratio); + dprintf (3, ("marking h%d Mloh: cross: %Id, useful: %Id, cards cleared: %Id, cards set: %Id, ratio: %d", + heap_number, n_eph, n_gen, total_cards_cleared, n_card_set, generation_skip_ratio)); +#endif //FEATURE_CARD_MARKING_STEALING } else { diff --git a/src/coreclr/src/gc/gcconfig.h b/src/coreclr/src/gc/gcconfig.h index 7d667b6a15ea..62ea34f3659e 100644 --- a/src/coreclr/src/gc/gcconfig.h +++ b/src/coreclr/src/gc/gcconfig.h @@ -83,7 +83,7 @@ class GCConfigStringHolder INT_CONFIG (BGCSpinCount, "BGCSpinCount", NULL, 140, "Specifies the bgc spin count") \ INT_CONFIG (BGCSpin, "BGCSpin", NULL, 2, "Specifies the bgc spin time") \ INT_CONFIG (HeapCount, "GCHeapCount", "System.GC.HeapCount", 0, "Specifies the number of server GC heaps") \ - INT_CONFIG (Gen0Size, "GCgen0size", NULL, 0, "Specifies the smallest gen0 size") \ + INT_CONFIG (Gen0Size, "GCgen0size", NULL, 0, "Specifies the smallest gen0 budget") \ INT_CONFIG (SegmentSize, "GCSegmentSize", NULL, 0, "Specifies the managed heap segment size") \ INT_CONFIG (LatencyMode, "GCLatencyMode", NULL, -1, "Specifies the GC latency mode - batch, interactive or low latency (note that the same " \ "thing can be specified via API which is the supported way") \ @@ -98,6 +98,7 @@ class GCConfigStringHolder INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \ INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \ INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \ + INT_CONFIG (GCLowSkipRatio, "GCLowSkipRatio", NULL, 30, "Specifies the low generation skip ratio") \ INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \ INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \ INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \ diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index 0606b57d7279..4db27dc3896a 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -233,7 +233,7 @@ const int policy_expand = 2; #ifdef SIMPLE_DPRINTF void GCLog (const char *fmt, ... ); -#define dprintf(l,x) {if ((l <= 1) || (l == GTC_LOG)) {GCLog x;}} +#define dprintf(l,x) {if ((l == 1) || (l == GTC_LOG)) {GCLog x;}} #else //SIMPLE_DPRINTF // Nobody used the logging mechanism that used to be here. If we find ourselves // wanting to inspect GC logs on unmodified builds, we can use this define here @@ -4039,6 +4039,20 @@ class gc_heap PER_HEAP int generation_skip_ratio;//in % +#ifdef FEATURE_CARD_MARKING_STEALING + PER_HEAP + VOLATILE(size_t) n_eph_soh; + PER_HEAP + VOLATILE(size_t) n_gen_soh; + PER_HEAP + VOLATILE(size_t) n_eph_loh; + PER_HEAP + VOLATILE(size_t) n_gen_loh; +#endif //FEATURE_CARD_MARKING_STEALING + + PER_HEAP_ISOLATED + int generation_skip_ratio_threshold; + PER_HEAP BOOL gen0_bricks_cleared; PER_HEAP From f9dffea57540192174060bbeff0a9c499e1d71af Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 12 Aug 2020 18:33:24 -0400 Subject: [PATCH 436/755] Correctly handle a cached CRL with no NextUpdate on Linux Treat a CRL with no nextUpdate as cachable for 3 days, then we'll recheck it. This only seems to (legitimately) happen when the associated CA is nearing end-of-validity. Either macOS doesn't really support this, or it's just part of their general downplay of CRL, but the tests are disabled there. --- .../X509Certificates/CertificateAuthority.cs | 11 +++- .../Cryptography/Pal.Unix/CrlCache.cs | 26 +++++++++- .../RevocationTests/DynamicRevocationTests.cs | 50 +++++++++++++++++++ 3 files changed, 83 insertions(+), 4 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 84a2607e002e..a2227ddd1a44 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs @@ -96,6 +96,7 @@ internal sealed class CertificateAuthority : IDisposable internal bool CorruptRevocationSignature { get; set; } internal DateTimeOffset? RevocationExpiration { get; set; } internal bool CorruptRevocationIssuerName { get; set; } + internal bool OmitNextUpdateInCrl { get; set; } // All keys created in this method are smaller than recommended, // but they only live for a few seconds (at most), @@ -343,7 +344,10 @@ internal byte[] GetCrl() writer.WriteUtcTime(_cert.NotBefore); // nextUpdate - writer.WriteUtcTime(RevocationExpiration.Value); + if (!OmitNextUpdateInCrl) + { + writer.WriteUtcTime(RevocationExpiration.Value); + } } else { @@ -351,7 +355,10 @@ internal byte[] GetCrl() writer.WriteUtcTime(now); // nextUpdate - writer.WriteUtcTime(newExpiry); + if (!OmitNextUpdateInCrl) + { + writer.WriteUtcTime(newExpiry); + } } // revokedCertificates (don't write down if empty) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs index 83d2e75adbf2..16e2dc5e2600 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs @@ -96,8 +96,30 @@ private static bool AddCachedCrl(string crlFileName, SafeX509StoreHandle store, // at least it can fail without using the network. // // If crl.NextUpdate is in the past, try downloading a newer version. - DateTime nextUpdate = OpenSslX509CertificateReader.ExtractValidityDateTime( - Interop.Crypto.GetX509CrlNextUpdate(crl)); + IntPtr nextUpdatePtr = Interop.Crypto.GetX509CrlNextUpdate(crl); + DateTime nextUpdate; + + // If there is no crl.NextUpdate, this indicates that the CA is not providing + // any more updates to the CRL, or they made a mistake not providing a NextUpdate. + // We'll cache it for a few days to cover the case it was a mistake. + if (nextUpdatePtr == IntPtr.Zero) + { + try + { + nextUpdate = File.GetLastWriteTime(crlFile).AddDays(3); + } + catch + { + // We couldn't determine when the CRL was last written to, + // so consider it expired. + Debug.Fail("Failed to get the last write time of the CRL file"); + return false; + } + } + else + { + nextUpdate = OpenSslX509CertificateReader.ExtractValidityDateTime(nextUpdatePtr); + } // OpenSSL is going to convert our input time to universal, so we should be in Local or // Unspecified (local-assumed). 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 514698aab0b2..045561935d92 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs @@ -940,6 +940,56 @@ public static void CheckIntermediateWithExpiredRevocation(PkiOptions pkiOptions) }); } + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] + public static void TestRevocationWithNoNextUpdate_NotRevoked() + { + SimpleTest( + PkiOptions.CrlEverywhere, + (root, intermediate, endEntity, holder) => + { + intermediate.OmitNextUpdateInCrl = true; + + // Build a chain once to get the no NextUpdate in the CRL + // cache. We don't care about the build result. + holder.Chain.Build(endEntity); + + SimpleRevocationBody( + holder, + endEntity, + rootRevoked: false, + issrRevoked: false, + leafRevoked: false); + }); + } + + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] + public static void TestRevocationWithNoNextUpdate_Revoked() + { + SimpleTest( + PkiOptions.CrlEverywhere, + (root, intermediate, endEntity, holder) => + { + intermediate.OmitNextUpdateInCrl = true; + + DateTimeOffset now = DateTimeOffset.UtcNow; + intermediate.Revoke(endEntity, now); + holder.Chain.ChainPolicy.VerificationTime = now.AddSeconds(1).UtcDateTime; + + // Build a chain once to get the no NextUpdate in the CRL + // cache. We don't care about the build result. + holder.Chain.Build(endEntity); + + SimpleRevocationBody( + holder, + endEntity, + rootRevoked: false, + issrRevoked: false, + leafRevoked: true); + }); + } + private static void RevokeEndEntityWithInvalidRevocation( ChainHolder holder, CertificateAuthority intermediate, From 58bfab58278037d12dbce03a173ce0c9e9c4c828 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 13 Aug 2020 01:40:09 +0300 Subject: [PATCH 437/755] [interp] Rework OBJREF and fix a GC issue (#40710) * [interp] Remove unnecessary uses of OBJREF No checkpoints are possible before the returned object is stored on interp stack. * [interp] Don't rely on scanning C stack in wasm In order to keep object references alive we were doing a volatile store to the address of a stack local. This would determine the compiler to store to the C stack, which we can scan on wasm. While I didn't see proof that this is not the case, this mechanism seems rather magical and fragile. This commit replaces this mechanism of keeping C locals alive with an explicit store into a handle that we allocate whenever we enter the interpreter. Since we don't require this too frequently (the interp stack is usually enough to keep required objects alive), a single handle is enough. The added benefit of this is that we can stop scanning the C stack/registers altogether on desktop interpreter in coop mode. This mode replicates the behavior of wasm, uncovering GC bugs that show up there while using desktop interpreter. * [interp] Make sure exception object is not collected during EH Most of the time, the exception object comes from a function call in the runtime so it is not kept alive by interp stack. --- src/mono/mono/mini/interp/interp-internals.h | 49 +++------------ src/mono/mono/mini/interp/interp.c | 63 ++++++++++++++------ 2 files changed, 51 insertions(+), 61 deletions(-) diff --git a/src/mono/mono/mini/interp/interp-internals.h b/src/mono/mono/mini/interp/interp-internals.h index e3f3e04c8c9e..a08467100ee3 100644 --- a/src/mono/mono/mini/interp/interp-internals.h +++ b/src/mono/mono/mini/interp/interp-internals.h @@ -51,50 +51,10 @@ typedef gint64 mono_i; #define MINT_TYPE_I MINT_TYPE_I8 #endif - -/* - * GC SAFETY: - * - * The interpreter executes in gc unsafe (non-preempt) mode. On wasm, the C stack is - * scannable but the wasm stack is not, so to make the code GC safe, the following rules - * should be followed: - * - every objref handled by the code needs to either be stored volatile or stored - * into a volatile; volatile stores are stack packable, volatile values are not. - * Use either OBJREF or stackval->data.o. - * This will ensure the objects are pinned. A volatile local - * is on the stack and not in registers. Volatile stores ditto. - * - minimize the number of MonoObject* locals/arguments (or make them volatile). - * - * Volatile on a type/local forces all reads and writes to go to memory/stack, - * and each such local to have a unique address. - * - * Volatile absence on a type/local allows multiple locals to share storage, - * if their lifetimes do not overlap. This is called "stack packing". - * - * Volatile absence on a type/local allows the variable to live in - * both stack and register, for fast reads and "write through". - */ #ifdef TARGET_WASM - -#define WASM_VOLATILE volatile - -static inline MonoObject * WASM_VOLATILE * -mono_interp_objref (MonoObject **o) -{ - return o; -} - -#define OBJREF(x) (*mono_interp_objref (&x)) - -#else - -#define WASM_VOLATILE /* nothing */ - -#define OBJREF(x) x - +#define INTERP_NO_STACK_SCAN 1 #endif - /* * Value types are represented on the eval stack as pointers to the * actual storage. A value type cannot be larger than 16 MB. @@ -109,7 +69,12 @@ typedef struct { } pair; float f_r4; double f; - MonoObject * WASM_VOLATILE o; +#ifdef INTERP_NO_STACK_SCAN + /* Ensure objref is always flushed to interp stack */ + MonoObject * volatile o; +#else + MonoObject *o; +#endif /* native size integer and pointer types */ gpointer p; mono_u nati; diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 53d20e1997c8..445da6d4e786 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1080,9 +1080,15 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con g_assert (context->has_resume_state); } +// We conservatively pin exception object here to avoid tweaking the +// numerous call sites of this macro, even though, in a few cases, +// this is not needed. #define THROW_EX_GENERAL(exception,ex_ip, rethrow) \ do { \ - interp_throw (context, (exception), (frame), (ex_ip), (rethrow)); \ + MonoException *__ex = (exception); \ + MONO_HANDLE_ASSIGN_RAW (tmp_handle, (MonoObject*)__ex); \ + interp_throw (context, __ex, (frame), (ex_ip), (rethrow)); \ + MONO_HANDLE_ASSIGN_RAW (tmp_handle, (MonoObject*)NULL); \ goto resume; \ } while (0) @@ -3264,11 +3270,10 @@ mono_interp_box_nullable (InterpFrame* frame, const guint16* ip, stackval* sp, M } static int -mono_interp_box_vt (InterpFrame* frame, const guint16* ip, stackval* sp) +mono_interp_box_vt (InterpFrame* frame, const guint16* ip, stackval* sp, MonoObjectHandle tmp_handle) { InterpMethod* const imethod = frame->imethod; - MonoObject* o; // See the comment about GC safety. MonoVTable * const vtable = (MonoVTable*)imethod->data_items [ip [1]]; MonoClass* const c = vtable->klass; @@ -3277,26 +3282,27 @@ mono_interp_box_vt (InterpFrame* frame, const guint16* ip, stackval* sp) guint16 offset = ip [2]; guint16 pop_vt_sp = !ip [3]; - OBJREF (o) = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); + MonoObject* o = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); + MONO_HANDLE_ASSIGN_RAW (tmp_handle, o); mono_value_copy_internal (mono_object_get_data (o), sp [-1 - offset].data.p, c); + MONO_HANDLE_ASSIGN_RAW (tmp_handle, NULL); - sp [-1 - offset].data.p = o; + sp [-1 - offset].data.o = o; return pop_vt_sp ? ALIGN_TO (size, MINT_VT_ALIGNMENT) : 0; } static void -mono_interp_box (InterpFrame* frame, const guint16* ip, stackval* sp) +mono_interp_box (InterpFrame* frame, const guint16* ip, stackval* sp, MonoObjectHandle tmp_handle) { - MonoObject *o; // See the comment about GC safety. MonoVTable * const vtable = (MonoVTable*)frame->imethod->data_items [ip [1]]; - - OBJREF (o) = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); - guint16 const offset = ip [2]; + MonoObject *o = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); + MONO_HANDLE_ASSIGN_RAW (tmp_handle, o); stackval_to_data (m_class_get_byval_arg (vtable->klass), &sp [-1 - offset], mono_object_get_data (o), FALSE); + MONO_HANDLE_ASSIGN_RAW (tmp_handle, NULL); - sp [-1 - offset].data.p = o; + sp [-1 - offset].data.o = o; } static int @@ -3436,6 +3442,24 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs }; #endif + HANDLE_FUNCTION_ENTER (); + /* + * GC SAFETY: + * + * The interpreter executes in gc unsafe (non-preempt) mode. On wasm, we cannot rely on + * scanning the stack or any registers. In order to make the code GC safe, every objref + * handled by the code needs to be kept alive and pinned in any of the following ways: + * - the object needs to be stored on the interpreter stack. In order to make sure the + * object actually gets stored on the interp stack and the store is not optimized out, + * the store/variable should be volatile. + * - if the execution of an opcode requires an object not coming from interp stack to be + * kept alive, the tmp_handle below can be used. This handle will keep only one object + * pinned by the GC. Ideally, once this object is no longer needed, the handle should be + * cleared. If we will need to have more objects pinned simultaneously, additional handles + * can be reserved here. + */ + MonoObjectHandle tmp_handle = MONO_HANDLE_NEW (MonoObject, NULL); + if (method_entry (context, frame, #if DEBUG_INTERP &tracing, @@ -5123,7 +5147,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs MINT_IN_CASE(MINT_NEWOBJ_FAST) { MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [ip [3]]; INIT_VTABLE (vtable); - MonoObject *o; // See the comment about GC safety. guint16 param_count; guint16 imethod_index = ip [1]; @@ -5137,7 +5160,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs memmove (sp + 2, sp, param_count * sizeof (stackval)); } - OBJREF (o) = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); + MonoObject *o = mono_gc_alloc_obj (vtable, m_class_get_instance_size (vtable->klass)); if (G_UNLIKELY (!o)) { mono_error_set_out_of_memory (error, "Could not allocate %i bytes", m_class_get_instance_size (vtable->klass)); THROW_EX (mono_error_convert_to_exception (error), ip); @@ -5241,13 +5264,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs THROW_EX (exc, ip); } error_init_reuse (error); - MonoObject* o = NULL; // See the comment about GC safety. - OBJREF (o) = mono_object_new_checked (domain, newobj_class, error); + MonoObject* o = mono_object_new_checked (domain, newobj_class, error); + sp [0].data.o = o; // return value + sp [1].data.o = o; // first parameter + mono_error_cleanup (error); // FIXME: do not swallow the error error_init_reuse (error); EXCEPTION_CHECKPOINT; - sp [0].data.o = o; // return value - sp [1].data.o = o; // first parameter #ifndef DISABLE_REMOTING if (mono_object_is_transparent_proxy (o)) { MonoMethod *remoting_invoke_method = mono_marshal_get_remoting_invoke_with_check (cmethod->method, error); @@ -5946,12 +5969,12 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs MINT_IN_BREAK; } MINT_IN_CASE(MINT_BOX) { - mono_interp_box (frame, ip, sp); + mono_interp_box (frame, ip, sp, tmp_handle); ip += 3; MINT_IN_BREAK; } MINT_IN_CASE(MINT_BOX_VT) { - vt_sp -= mono_interp_box_vt (frame, ip, sp); + vt_sp -= mono_interp_box_vt (frame, ip, sp, tmp_handle); ip += 4; MINT_IN_BREAK; } @@ -7381,6 +7404,8 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs context->stack_pointer = (guchar*)frame->stack; DEBUG_LEAVE (); + + HANDLE_FUNCTION_RETURN (); } static void From 0db8ecbea291c09cfd84d7f33ea049f5c0cec94f Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 13 Aug 2020 02:20:29 +0300 Subject: [PATCH 438/755] [mono][Browser] Update ICU (#40387) --- eng/Version.Details.xml | 4 +- eng/Versions.props | 2 +- .../Common/tests/Tests/System/StringTests.cs | 40 ++++++++++++++----- .../tests/Normalization/NormalizationAll.cs | 14 ++++--- .../Normalization/StringNormalizationTests.cs | 33 ++++++++++----- .../System/Globalization/RegionInfoTests.cs | 28 +++++++++---- .../System/Globalization/Normalization.Icu.cs | 7 ++++ 7 files changed, 92 insertions(+), 36 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ea4afb6ae2ad..78762c50759b 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 - f58ab86d7e07a66ea189859f298843ccf41a0914 + 8bd04d98c75cc7d8ac9026eab2c63e50294b0552 diff --git a/eng/Versions.props b/eng/Versions.props index 02bd975b4fa1..807c2382cec7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -147,7 +147,7 @@ 5.0.0-preview.3.20403.5 - 5.0.0-preview.8.20403.1 + 5.0.0-preview.8.20404.1 9.0.1-alpha.1.20403.1 9.0.1-alpha.1.20403.1 diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index 74ceefc4cc6a..8ea5bbac4b0c 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -7312,8 +7312,13 @@ public static void InternalTestAotSubset() Assert.False(s.IsNormalized(), "String should be not normalized when checking with the default which same as FormC"); Assert.False(s.IsNormalized(NormalizationForm.FormC), "String should be not normalized when checking with FormC"); Assert.False(s.IsNormalized(NormalizationForm.FormD), "String should be not normalized when checking with FormD"); - Assert.False(s.IsNormalized(NormalizationForm.FormKC), "String should be not normalized when checking with FormKC"); - Assert.False(s.IsNormalized(NormalizationForm.FormKD), "String should be not normalized when checking with FormKD"); + + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't support FormKC and FormKD + Assert.False(s.IsNormalized(NormalizationForm.FormKC), "String should be not normalized when checking with FormKC"); + Assert.False(s.IsNormalized(NormalizationForm.FormKD), "String should be not normalized when checking with FormKD"); + } string normalized = s.Normalize(); // FormC Assert.True(normalized.IsNormalized(), "Expected to have the normalized string with default form FormC"); @@ -7326,23 +7331,38 @@ public static void InternalTestAotSubset() normalized = s.Normalize(NormalizationForm.FormD); Assert.True(normalized.IsNormalized(NormalizationForm.FormD), "Expected to have the normalized string with FormD"); - normalized = s.Normalize(NormalizationForm.FormKC); - Assert.True(normalized.IsNormalized(NormalizationForm.FormKC), "Expected to have the normalized string with FormKC"); + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't support FormKC and FormKD + normalized = s.Normalize(NormalizationForm.FormKC); + Assert.True(normalized.IsNormalized(NormalizationForm.FormKC), "Expected to have the normalized string with FormKC"); - normalized = s.Normalize(NormalizationForm.FormKD); - Assert.True(normalized.IsNormalized(NormalizationForm.FormKD), "Expected to have the normalized string with FormKD"); + normalized = s.Normalize(NormalizationForm.FormKD); + Assert.True(normalized.IsNormalized(NormalizationForm.FormKD), "Expected to have the normalized string with FormKD"); + } s = "hello"; Assert.True(s.IsNormalized()); Assert.True(s.IsNormalized(NormalizationForm.FormC)); Assert.True(s.IsNormalized(NormalizationForm.FormD)); - Assert.True(s.IsNormalized(NormalizationForm.FormKC)); - Assert.True(s.IsNormalized(NormalizationForm.FormKD)); + + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't support FormKC and FormKD + Assert.True(s.IsNormalized(NormalizationForm.FormKC)); + Assert.True(s.IsNormalized(NormalizationForm.FormKD)); + } + Assert.Same(s, s.Normalize()); Assert.Same(s, s.Normalize(NormalizationForm.FormC)); Assert.Same(s, s.Normalize(NormalizationForm.FormD)); - Assert.Same(s, s.Normalize(NormalizationForm.FormKC)); - Assert.Same(s, s.Normalize(NormalizationForm.FormKD)); + + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't support FormKC and FormKD + Assert.Same(s, s.Normalize(NormalizationForm.FormKC)); + Assert.Same(s, s.Normalize(NormalizationForm.FormKD)); + } } [Fact] diff --git a/src/libraries/System.Globalization.Extensions/tests/Normalization/NormalizationAll.cs b/src/libraries/System.Globalization.Extensions/tests/Normalization/NormalizationAll.cs index 1968f762149f..e62dfd81f93b 100644 --- a/src/libraries/System.Globalization.Extensions/tests/Normalization/NormalizationAll.cs +++ b/src/libraries/System.Globalization.Extensions/tests/Normalization/NormalizationAll.cs @@ -51,11 +51,15 @@ public void Normalize() // Form D VerifyConformanceInvariant(NormalizationForm.FormD, part0, part1, part2, part3, part4); - // Form KC - VerifyConformanceInvariant(NormalizationForm.FormKC, part0, part1, part2, part3, part4); - - // Form KD - VerifyConformanceInvariant(NormalizationForm.FormKD, part0, part1, part2, part3, part4); + // Browser's ICU doesn't support FormKC and FormKD + if (PlatformDetection.IsNotBrowser) + { + // Form KC + VerifyConformanceInvariant(NormalizationForm.FormKC, part0, part1, part2, part3, part4); + + // Form KD + VerifyConformanceInvariant(NormalizationForm.FormKD, part0, part1, part2, part3, part4); + } } } } diff --git a/src/libraries/System.Globalization.Extensions/tests/Normalization/StringNormalizationTests.cs b/src/libraries/System.Globalization.Extensions/tests/Normalization/StringNormalizationTests.cs index 210914c2a5e1..3ac46a8bd754 100644 --- a/src/libraries/System.Globalization.Extensions/tests/Normalization/StringNormalizationTests.cs +++ b/src/libraries/System.Globalization.Extensions/tests/Normalization/StringNormalizationTests.cs @@ -4,6 +4,7 @@ using System; using System.Text; using Xunit; +using System.Collections.Generic; namespace System.Globalization.Tests { @@ -38,18 +39,28 @@ public void IsNormalized_Null() AssertExtensions.Throws("strInput", () => StringNormalizationExtensions.IsNormalized(null)); } + public static IEnumerable NormalizeTestData() + { + yield return new object[] { "", NormalizationForm.FormC, "" }; + yield return new object[] { "\u00C4\u00C7", NormalizationForm.FormD, "A\u0308C\u0327" }; + yield return new object[] { "A\u0308C\u0327", NormalizationForm.FormC, "\u00C4\u00C7" }; + yield return new object[] { "\uFB01", NormalizationForm.FormC, "\uFB01" }; + yield return new object[] { "\uFB01", NormalizationForm.FormD, "\uFB01" }; + yield return new object[] { "\u1E9b\u0323", NormalizationForm.FormC, "\u1E9b\u0323" }; + yield return new object[] { "\u1E9b\u0323", NormalizationForm.FormD, "\u017f\u0323\u0307" }; + + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't support FormKC and FormKD + yield return new object[] { "\uFB01", NormalizationForm.FormKC, "fi" }; + yield return new object[] { "\uFB01", NormalizationForm.FormKD, "fi" }; + yield return new object[] { "\u1E9b\u0323", NormalizationForm.FormKC, "\u1E69" }; + yield return new object[] { "\u1E9b\u0323", NormalizationForm.FormKD, "\u0073\u0323\u0307" }; + } + } + [Theory] - [InlineData("", NormalizationForm.FormC, "")] - [InlineData("\u00C4\u00C7", NormalizationForm.FormD, "A\u0308C\u0327")] - [InlineData("A\u0308C\u0327", NormalizationForm.FormC, "\u00C4\u00C7")] - [InlineData("\uFB01", NormalizationForm.FormC, "\uFB01")] - [InlineData("\uFB01", NormalizationForm.FormD, "\uFB01")] - [InlineData("\uFB01", NormalizationForm.FormKC, "fi")] - [InlineData("\uFB01", NormalizationForm.FormKD, "fi")] - [InlineData("\u1E9b\u0323", NormalizationForm.FormC, "\u1E9b\u0323")] - [InlineData("\u1E9b\u0323", NormalizationForm.FormD, "\u017f\u0323\u0307")] - [InlineData("\u1E9b\u0323", NormalizationForm.FormKC, "\u1E69")] - [InlineData("\u1E9b\u0323", NormalizationForm.FormKD, "\u0073\u0323\u0307")] + [MemberData(nameof(NormalizeTestData))] public void Normalize(string value, NormalizationForm normalizationForm, string expected) { if (normalizationForm == NormalizationForm.FormC) diff --git a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs index 84cc05e35627..bf04230564b5 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs @@ -177,13 +177,18 @@ public void ISOCurrencySymbol(string name, string expected) Assert.Equal(expected, new RegionInfo(name).ISOCurrencySymbol); } - [Theory] - [InlineData("en-US", new string[] { "$" })] - [InlineData("zh-CN", new string[] { "\u00A5", "\uffe5" })] // \u00A5 is Latin-1 Supplement(Windows), \uffe5 is Halfwidth and Fullwidth Forms(ICU) - public void CurrencySymbol(string name, string[] expected) + [Fact] + public void CurrencySymbol() { - string result = new RegionInfo(name).CurrencySymbol; - Assert.Contains(result, expected); + Assert.Equal("$", new RegionInfo("en-US").CurrencySymbol); + if (PlatformDetection.IsNotBrowser) + { + Assert.Contains(new RegionInfo("zh-CN").CurrencySymbol, new string[] { "\u00A5", "\uffe5" }); + } + else + { + Assert.Equal("CN¥", new RegionInfo("zh-CN").CurrencySymbol); + } } [Theory] @@ -218,7 +223,16 @@ public void MiscTest(int lcid, int geoId, string currencyEnglishName, string alt Assert.Equal(geoId, ri.GeoId); Assert.True(currencyEnglishName.Equals(ri.CurrencyEnglishName) || alternativeCurrencyEnglishName.Equals(ri.CurrencyEnglishName), "Wrong currency English Name"); - Assert.Equal(currencyNativeName, ri.CurrencyNativeName); + + if (PlatformDetection.IsBrowser) + { + // Browser's ICU doesn't support CurrencyNativeName + Assert.Equal(currencyEnglishName, ri.CurrencyNativeName); + } + else + { + Assert.Equal(currencyNativeName, ri.CurrencyNativeName); + } Assert.Equal(threeLetterISORegionName, ri.ThreeLetterISORegionName); Assert.Equal(threeLetterWindowsRegionName, ri.ThreeLetterWindowsRegionName); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs index 5cd1f1d93ea9..cfe698fabcd9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs @@ -100,6 +100,13 @@ private static void ValidateArguments(string strInput, NormalizationForm normali { Debug.Assert(strInput != null); + + if (OperatingSystem.IsBrowser() && (normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD)) + { + // Browser's ICU doesn't contain data needed for FormKC and FormKD + throw new PlatformNotSupportedException(); + } + if (normalizationForm != NormalizationForm.FormC && normalizationForm != NormalizationForm.FormD && normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD) { From 316ac21c27791bce48712c1b1a6e6ad5fb1b8e28 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Wed, 12 Aug 2020 20:58:59 -0300 Subject: [PATCH 439/755] [wasm] Remove unnecessary console messages. (#40728) * Changing some console.log to console.debug to not pollute the console. Changing printf to DEBUG_PRINTF to follow the debug level chosen by user. Remove unnecessary console.log. * Removing one more message. --- src/mono/mono/mini/mini-wasm-debugger.c | 6 +++--- src/mono/wasm/runtime/library_mono.js | 15 ++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 66608a7a56bc..baef84e824cb 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -256,7 +256,7 @@ typedef struct { static void* create_breakpoint_events (GPtrArray *ss_reqs, GPtrArray *bp_reqs, MonoJitInfo *ji, EventKind kind) { - printf ("ss_reqs %d bp_reqs %d\n", ss_reqs->len, bp_reqs->len); + DEBUG_PRINTF (1, "ss_reqs %d bp_reqs %d\n", ss_reqs->len, bp_reqs->len); if ((ss_reqs && ss_reqs->len) || (bp_reqs && bp_reqs->len)) { BpEvents *evts = g_new0 (BpEvents, 1); //just a non-null value to make sure we can raise it on process_breakpoint_events evts->is_ss = (ss_reqs && ss_reqs->len); @@ -283,7 +283,7 @@ no_seq_points_found (MonoMethod *method, int offset) /* * This can happen in full-aot mode with assemblies AOTed without the 'soft-debug' option to save space. */ - printf ("Unable to find seq points for method '%s', offset 0x%x.\n", mono_method_full_name (method, TRUE), offset); + DEBUG_PRINTF (1, "Unable to find seq points for method '%s', offset 0x%x.\n", mono_method_full_name (method, TRUE), offset); } #define DBG_NOT_SUSPENDED 1 @@ -291,7 +291,7 @@ no_seq_points_found (MonoMethod *method, int offset) static int ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *ss_args) { - printf ("ss_create_init_args\n"); + DEBUG_PRINTF (1, "ss_create_init_args\n"); int dummy = 0; ss_req->start_sp = ss_req->last_sp = &dummy; compute_frames (); diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 14e191e79cd1..ad0c854f570b 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -697,7 +697,7 @@ var MonoSupportLib = { }, mono_wasm_start_single_stepping: function (kind) { - console.log (">> mono_wasm_start_single_stepping " + kind); + console.debug (">> mono_wasm_start_single_stepping " + kind); if (!this.mono_wasm_setup_single_step) this.mono_wasm_setup_single_step = Module.cwrap ("mono_wasm_setup_single_step", 'number', [ 'number']); @@ -869,7 +869,7 @@ var MonoSupportLib = { if (ENVIRONMENT_IS_NODE) { var fs = require('fs'); return function (asset) { - console.log ("MONO_WASM: Loading... " + asset); + console.debug ("MONO_WASM: Loading... " + asset); var binary = fs.readFileSync (asset); var resolve_func2 = function (resolve, reject) { resolve (new Uint8Array (binary)); @@ -901,8 +901,6 @@ var MonoSupportLib = { var bytes = new Uint8Array (blob); if (ctx.tracing) console.log ("MONO_WASM: Loaded:", asset.name, "size", bytes.length, "from", url); - else - console.log ("MONO_WASM: Loaded:", asset.name); var virtualName = asset.virtual_path || asset.name; var offset = null; @@ -1079,7 +1077,7 @@ var MonoSupportLib = { var load_runtime = Module.cwrap ('mono_wasm_load_runtime', null, ['string', 'number']); - console.log ("MONO_WASM: Initializing mono runtime"); + console.debug ("MONO_WASM: Initializing mono runtime"); this.mono_wasm_globalization_init (args.globalization_mode); @@ -1189,7 +1187,7 @@ var MonoSupportLib = { (asset.name.match (/\.pdb$/) && MONO.mono_wasm_ignore_pdb_load_errors); if (isOk) - console.log (msg); + console.debug (msg); else { console.error (msg); throw new Error (msg); @@ -1248,9 +1246,9 @@ var MonoSupportLib = { if (!invariantMode) { if (this.num_icu_assets_loaded_successfully > 0) { - console.log ("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode"); + console.debug ("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode"); } else if (globalization_mode !== "icu") { - console.log ("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode"); + console.debug ("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode"); invariantMode = true; } else { var msg = "invariant globalization mode is inactive and no ICU data archives were loaded"; @@ -1754,7 +1752,6 @@ var MonoSupportLib = { }, mono_wasm_fire_bp: function () { - console.log ("mono_wasm_fire_bp"); // eslint-disable-next-line no-debugger debugger; }, From fab6cd35fc65f173ecd689b1fa4474eaa3f42435 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 12 Aug 2020 20:02:36 -0400 Subject: [PATCH 440/755] [aot] Fix an assert which is hit for generic instances with a lot of arguments. (#40736) The c# compiler generates these for anonymous types. Fixes https://github.com/xamarin/xamarin-macios/issues/9289. Co-authored-by: vargaz --- src/mono/mono/mini/aot-compiler.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 63f6d12930b7..4cb352e86808 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -3424,12 +3424,14 @@ get_shared_ginst_ref (MonoAotCompile *acfg, MonoGenericInst *ginst) guint32 offset = GPOINTER_TO_UINT (g_hash_table_lookup (acfg->ginst_blob_hash, ginst)); if (!offset) { guint8 *buf2, *p2; + int len; - buf2 = (guint8 *)g_malloc (1024); + len = 1024 + (ginst->type_argc * 32); + buf2 = (guint8 *)g_malloc (len); p2 = buf2; encode_ginst (acfg, ginst, p2, &p2); - g_assert (p2 - buf2 < 1024); + g_assert (p2 - buf2 < len); offset = add_to_blob (acfg, buf2, p2 - buf2); g_free (buf2); From 494cfe7dcaa8ee603902b26af5e1d8177cf8fc41 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Thu, 13 Aug 2020 12:34:47 +1200 Subject: [PATCH 441/755] Sync HPackDecoder with ASP.NET Core changes (#40689) * Sync HPackDecoder with ASP.NET Core changes --- .../aspnetcore/Http2/Hpack/HPackDecoder.cs | 65 +++++++++++++------ .../Net/aspnetcore/Http2/HPackDecoderTest.cs | 30 +++++++-- .../Http/SocketsHttpHandler/Http2Stream.cs | 6 +- .../UnitTests/HPack/HPackRoundtripTests.cs | 5 +- 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs index bb9b988e8968..8899104eb18d 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs @@ -92,6 +92,7 @@ private enum State : byte private State _state = State.Ready; private byte[]? _headerName; + private int _headerStaticIndex; private int _stringIndex; private int _stringLength; private int _headerNameLength; @@ -492,23 +493,36 @@ private void CheckIncompleteHeaderBlock(bool endHeaders) private void ProcessHeaderValue(ReadOnlySpan data, IHttpHeadersHandler handler) { - ReadOnlySpan headerNameSpan = _headerNameRange == null - ? new Span(_headerName, 0, _headerNameLength) - : data.Slice(_headerNameRange.GetValueOrDefault().start, _headerNameRange.GetValueOrDefault().length); - ReadOnlySpan headerValueSpan = _headerValueRange == null - ? new Span(_headerValueOctets, 0, _headerValueLength) + ? _headerValueOctets.AsSpan(0, _headerValueLength) : data.Slice(_headerValueRange.GetValueOrDefault().start, _headerValueRange.GetValueOrDefault().length); - handler.OnHeader(headerNameSpan, headerValueSpan); - - _headerNameRange = null; - _headerValueRange = null; + if (_headerStaticIndex > 0) + { + handler.OnStaticIndexedHeader(_headerStaticIndex, headerValueSpan); - if (_index) + if (_index) + { + _dynamicTable.Insert(H2StaticTable.Get(_headerStaticIndex - 1).Name, headerValueSpan); + } + } + else { - _dynamicTable.Insert(headerNameSpan, headerValueSpan); + ReadOnlySpan headerNameSpan = _headerNameRange == null + ? _headerName.AsSpan(0, _headerNameLength) + : data.Slice(_headerNameRange.GetValueOrDefault().start, _headerNameRange.GetValueOrDefault().length); + + handler.OnHeader(headerNameSpan, headerValueSpan); + + if (_index) + { + _dynamicTable.Insert(headerNameSpan, headerValueSpan); + } } + + _headerStaticIndex = 0; + _headerNameRange = null; + _headerValueRange = null; } public void CompleteDecode() @@ -522,15 +536,30 @@ public void CompleteDecode() private void OnIndexedHeaderField(int index, IHttpHeadersHandler handler) { - ref readonly HeaderField header = ref GetHeader(index); - handler.OnHeader(header.Name, header.Value); + if (index <= H2StaticTable.Count) + { + handler.OnStaticIndexedHeader(index); + } + else + { + ref readonly HeaderField header = ref GetDynamicHeader(index); + handler.OnHeader(header.Name, header.Value); + } + _state = State.Ready; } private void OnIndexedHeaderName(int index) { - _headerName = GetHeader(index).Name; - _headerNameLength = _headerName.Length; + if (index <= H2StaticTable.Count) + { + _headerStaticIndex = index; + } + else + { + _headerName = GetDynamicHeader(index).Name; + _headerNameLength = _headerName.Length; + } _state = State.HeaderValueLength; } @@ -615,13 +644,11 @@ private static bool IsHuffmanEncoded(byte b) return (b & HuffmanMask) != 0; } - private ref readonly HeaderField GetHeader(int index) + private ref readonly HeaderField GetDynamicHeader(int index) { try { - return ref index <= H2StaticTable.Count - ? ref H2StaticTable.Get(index - 1) - : ref _dynamicTable[index - H2StaticTable.Count - 1]; + return ref _dynamicTable[index - H2StaticTable.Count - 1]; } catch (IndexOutOfRangeException) { diff --git a/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HPackDecoderTest.cs b/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HPackDecoderTest.cs index 40221b8b8e80..6c84993d3fae 100644 --- a/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HPackDecoderTest.cs +++ b/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HPackDecoderTest.cs @@ -104,10 +104,27 @@ private static (DynamicTable, HPackDecoder) CreateDecoderAndTable() } [Fact] - public void DecodesIndexedHeaderField_StaticTable() + public void DecodesIndexedHeaderField_StaticTableWithValue() { _decoder.Decode(_indexedHeaderStatic, endHeaders: true, handler: _handler); Assert.Equal("GET", _handler.DecodedHeaders[":method"]); + + Assert.Equal(":method", _handler.DecodedStaticHeaders[H2StaticTable.MethodGet].Key); + Assert.Equal("GET", _handler.DecodedStaticHeaders[H2StaticTable.MethodGet].Value); + } + + [Fact] + public void DecodesIndexedHeaderField_StaticTableWithoutValue() + { + byte[] encoded = _literalHeaderFieldWithIndexingIndexedName + .Concat(_headerValue) + .ToArray(); + + _decoder.Decode(encoded, endHeaders: true, handler: _handler); + Assert.Equal(_headerValueString, _handler.DecodedHeaders[_userAgentString]); + + Assert.Equal(_userAgentString, _handler.DecodedStaticHeaders[H2StaticTable.UserAgent].Key); + Assert.Equal(_headerValueString, _handler.DecodedStaticHeaders[H2StaticTable.UserAgent].Value); } [Fact] @@ -707,6 +724,7 @@ private static void TestDecode(byte[] encoded, string expectedHeaderName, string public class TestHttpHeadersHandler : IHttpHeadersHandler { public Dictionary DecodedHeaders { get; } = new Dictionary(); + public Dictionary> DecodedStaticHeaders { get; } = new Dictionary>(); void IHttpHeadersHandler.OnHeader(ReadOnlySpan name, ReadOnlySpan value) { @@ -718,14 +736,16 @@ void IHttpHeadersHandler.OnHeader(ReadOnlySpan name, ReadOnlySpan va void IHttpHeadersHandler.OnStaticIndexedHeader(int index) { - // Not yet implemented for HPACK. - throw new NotImplementedException(); + ref readonly HeaderField entry = ref H2StaticTable.Get(index - 1); + ((IHttpHeadersHandler)this).OnHeader(entry.Name, entry.Value); + DecodedStaticHeaders[index] = new KeyValuePair(Encoding.ASCII.GetString(entry.Name), Encoding.ASCII.GetString(entry.Value)); } void IHttpHeadersHandler.OnStaticIndexedHeader(int index, ReadOnlySpan value) { - // Not yet implemented for HPACK. - throw new NotImplementedException(); + byte[] name = H2StaticTable.Get(index - 1).Name; + ((IHttpHeadersHandler)this).OnHeader(name, value); + DecodedStaticHeaders[index] = new KeyValuePair(Encoding.ASCII.GetString(name), Encoding.ASCII.GetString(value)); } void IHttpHeadersHandler.OnHeadersComplete(bool endStream) { } 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 8671947e4cae..c019cd416409 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 @@ -6,6 +6,7 @@ using System.Diagnostics; using System.IO; using System.Net.Http.Headers; +using System.Net.Http.HPack; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Text; @@ -440,13 +441,14 @@ public void OnWindowUpdate(int amount) void IHttpHeadersHandler.OnStaticIndexedHeader(int index) { // TODO: https://github.com/dotnet/runtime/issues/1505 - Debug.Fail("Currently unused by HPACK, this should never be called."); + ref readonly HeaderField entry = ref H2StaticTable.Get(index - 1); + OnHeader(entry.Name, entry.Value); } void IHttpHeadersHandler.OnStaticIndexedHeader(int index, ReadOnlySpan value) { // TODO: https://github.com/dotnet/runtime/issues/1505 - Debug.Fail("Currently unused by HPACK, this should never be called."); + OnHeader(H2StaticTable.Get(index - 1).Name, value); } public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs b/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs index 3fd84d6a4abb..03f801e39b26 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/HPack/HPackRoundtripTests.cs @@ -177,12 +177,13 @@ public void OnHeadersComplete(bool endStream) public void OnStaticIndexedHeader(int index) { - throw new NotImplementedException(); + ref readonly HeaderField entry = ref H2StaticTable.Get(index - 1); + OnHeader(entry.Name, entry.Value); } public void OnStaticIndexedHeader(int index, ReadOnlySpan value) { - throw new NotImplementedException(); + OnHeader(H2StaticTable.Get(index - 1).Name, value); } } } From 3873bf5c11512433c97d88c0cc1279354d70d682 Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Thu, 13 Aug 2020 03:19:51 +0200 Subject: [PATCH 442/755] Attempt to fix GC stress bugs caused by provisional gen 2 GCs. (#40719) --- src/coreclr/src/gc/gc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 7203ab7cabc2..f4e5adb0aba5 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -23387,7 +23387,8 @@ void gc_heap::plan_phase (int condemned_gen_number) } } - if (maxgen_size_inc_p && provisional_mode_triggered) + if (maxgen_size_inc_p && provisional_mode_triggered && + !(background_running_p() || (current_bgc_state == bgc_initialized))) { pm_trigger_full_gc = true; dprintf (GTC_LOG, ("in PM: maxgen size inc, doing a sweeping gen1 and trigger NGC2")); @@ -23498,7 +23499,8 @@ void gc_heap::plan_phase (int condemned_gen_number) rearrange_uoh_segments (); } - if (maxgen_size_inc_p && provisional_mode_triggered) + if (maxgen_size_inc_p && provisional_mode_triggered && + !(background_running_p() || (current_bgc_state == bgc_initialized))) { pm_trigger_full_gc = true; dprintf (GTC_LOG, ("in PM: maxgen size inc, doing a sweeping gen1 and trigger NGC2")); @@ -23535,7 +23537,8 @@ void gc_heap::plan_phase (int condemned_gen_number) if (!pm_trigger_full_gc && pm_stress_on && provisional_mode_triggered) { if ((settings.condemned_generation == (max_generation - 1)) && - ((settings.gc_index % 5) == 0)) + ((settings.gc_index % 5) == 0) && + !(background_running_p() || (current_bgc_state == bgc_initialized))) { pm_trigger_full_gc = true; } From 4a436e3313f07b7b4097c8948f84a2161f8c6e39 Mon Sep 17 00:00:00 2001 From: Jan Jahoda Date: Thu, 13 Aug 2020 08:51:29 +0200 Subject: [PATCH 443/755] Configure ping in HTTP2 (#40257) --- .../System/Net/Http/HttpHandlerDefaults.cs | 2 +- .../tests/System/Net/Http/Http2Frames.cs | 10 +- .../Net/Http/Http2LoopbackConnection.cs | 40 +++++- .../src/System.Net.Http.WinHttpHandler.csproj | 8 +- .../System.Net.Http/ref/System.Net.Http.cs | 8 ++ .../src/Resources/Strings.resx | 57 +++++---- .../src/System.Net.Http.csproj | 3 + .../BrowserHttpHandler/SocketsHttpHandler.cs | 19 +++ .../System/Net/Http/HttpHandlerDefaults.cs | 17 +++ .../SocketsHttpHandler/Http2Connection.cs | 119 ++++++++++++++++-- .../SocketsHttpHandler/HttpConnectionPool.cs | 13 ++ .../HttpConnectionPoolManager.cs | 32 ++++- .../HttpConnectionSettings.cs | 6 + .../HttpKeepAlivePingPolicy.cs | 18 +++ .../SocketsHttpHandler/SocketsHttpHandler.cs | 64 ++++++++++ .../HttpClientHandlerTest.Http2.cs | 111 ++++++++++++++++ .../FunctionalTests/SocketsHttpHandlerTest.cs | 47 +++++-- .../System.Net.Http.Unit.Tests.csproj | 4 + 18 files changed, 517 insertions(+), 61 deletions(-) create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/HttpHandlerDefaults.cs create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpKeepAlivePingPolicy.cs diff --git a/src/libraries/Common/src/System/Net/Http/HttpHandlerDefaults.cs b/src/libraries/Common/src/System/Net/Http/HttpHandlerDefaults.cs index d42462f6f856..537519288734 100644 --- a/src/libraries/Common/src/System/Net/Http/HttpHandlerDefaults.cs +++ b/src/libraries/Common/src/System/Net/Http/HttpHandlerDefaults.cs @@ -9,7 +9,7 @@ namespace System.Net.Http /// Central repository for default values used in http handler settings. Not all settings are relevant /// to or configurable by all handlers. /// - internal static class HttpHandlerDefaults + internal static partial class HttpHandlerDefaults { public const int DefaultMaxAutomaticRedirections = 50; public const int DefaultMaxConnectionsPerServer = int.MaxValue; diff --git a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs index 3195e239438b..214dab635061 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs @@ -344,9 +344,9 @@ public override string ToString() public class PingFrame : Frame { - public byte[] Data; + public long Data; - public PingFrame(byte[] data, FrameFlags flags, int streamId) : + public PingFrame(long data, FrameFlags flags, int streamId) : base(8, FrameType.Ping, flags, streamId) { Data = data; @@ -354,7 +354,7 @@ public PingFrame(byte[] data, FrameFlags flags, int streamId) : public static PingFrame ReadFrom(Frame header, ReadOnlySpan buffer) { - byte[] data = buffer.ToArray(); + long data = BinaryPrimitives.ReadInt64BigEndian(buffer); return new PingFrame(data, header.Flags, header.StreamId); } @@ -364,12 +364,12 @@ public override void WriteTo(Span buffer) base.WriteTo(buffer); buffer = buffer.Slice(Frame.FrameHeaderLength, 8); - Data.CopyTo(buffer); + BinaryPrimitives.WriteInt64BigEndian(buffer, Data); } public override string ToString() { - return base.ToString() + $"\nOpaque Data: {string.Join(", ", Data)}"; + return base.ToString() + $"\nOpaque Data: {Data:X16}"; } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 846e2acc74e6..08eee1084e20 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -24,6 +24,7 @@ public class Http2LoopbackConnection : GenericLoopbackConnection private Stream _connectionStream; private TaskCompletionSource _ignoredSettingsAckPromise; private bool _ignoreWindowUpdates; + private TaskCompletionSource _expectPingFrame; private readonly TimeSpan _timeout; private int _lastStreamId; @@ -186,6 +187,13 @@ private async Task ReadFrameAsync(CancellationToken cancellationToken) return await ReadFrameAsync(cancellationToken).ConfigureAwait(false); } + if (_expectPingFrame != null && header.Type == FrameType.Ping) + { + _expectPingFrame.SetResult(PingFrame.ReadFrom(header, data)); + _expectPingFrame = null; + return await ReadFrameAsync(cancellationToken).ConfigureAwait(false); + } + // Construct the correct frame type and return it. switch (header.Type) { @@ -245,6 +253,15 @@ public void IgnoreWindowUpdates() _ignoreWindowUpdates = true; } + // Set up loopback server to expect PING frames among other frames. + // Once PING frame is read in ReadFrameAsync, the returned task is completed. + // The returned task is canceled in ReadPingAsync if no PING frame has been read so far. + public Task ExpectPingFrameAsync() + { + _expectPingFrame ??= new TaskCompletionSource(); + return _expectPingFrame.Task; + } + public async Task ReadRstStreamAsync(int streamId) { Frame frame = await ReadFrameAsync(_timeout); @@ -663,7 +680,7 @@ public async Task SendGoAway(int lastStreamId, ProtocolErrors errorCode = Protoc public async Task PingPong() { - byte[] pingData = new byte[8] { 1, 2, 3, 4, 50, 60, 70, 80 }; + long pingData = BitConverter.ToInt64(new byte[8] { 1, 2, 3, 4, 50, 60, 70, 80 }, 0); PingFrame ping = new PingFrame(pingData, FrameFlags.None, 0); await WriteFrameAsync(ping).ConfigureAwait(false); PingFrame pingAck = (PingFrame)await ReadFrameAsync(_timeout).ConfigureAwait(false); @@ -675,6 +692,27 @@ public async Task PingPong() Assert.Equal(pingData, pingAck.Data); } + public async Task ReadPingAsync(TimeSpan timeout) + { + _expectPingFrame?.TrySetCanceled(); + _expectPingFrame = null; + + Frame frame = await ReadFrameAsync(timeout).ConfigureAwait(false); + Assert.NotNull(frame); + Assert.Equal(FrameType.Ping, frame.Type); + Assert.Equal(0, frame.StreamId); + Assert.False(frame.AckFlag); + Assert.Equal(8, frame.Length); + + return Assert.IsAssignableFrom(frame); + } + + public async Task SendPingAckAsync(long payload) + { + PingFrame pingAck = new PingFrame(payload, FrameFlags.Ack, 0); + await WriteFrameAsync(pingAck).ConfigureAwait(false); + } + public async Task SendDefaultResponseHeadersAsync(int streamId) { byte[] headers = new byte[] { 0x88 }; // Encoding for ":status: 200" diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index 71f4b005c6b4..1a499a9c2b10 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -34,9 +34,9 @@ + Link="Common\Interop\Windows\Crypt32\Interop.certificates.cs" /> + Link="Common\Interop\Windows\Kernel32\Interop.FormatMessage.cs" /> + Link="Common\System\Net\HttpKnownHeaderNames.TryGetHeaderName.cs" /> + Link="Common\System\Threading\Tasks\RendezvousAwaitable.cs" /> diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index dbf127857b1b..6a7cf68cc12a 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -347,6 +347,9 @@ public SocketsHttpHandler() { } public System.Net.ICredentials? Credentials { get { throw null; } set { } } public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } } public System.TimeSpan Expect100ContinueTimeout { get { throw null; } set { } } + public System.TimeSpan KeepAlivePingDelay { get { throw null; } set { } } + public System.TimeSpan KeepAlivePingTimeout { get { throw null; } set { } } + public HttpKeepAlivePingPolicy KeepAlivePingPolicy { get { throw null; } set { } } public int MaxAutomaticRedirections { get { throw null; } set { } } public int MaxConnectionsPerServer { get { throw null; } set { } } public int MaxResponseDrainSize { get { throw null; } set { } } @@ -369,6 +372,11 @@ protected override void Dispose(bool disposing) { } protected internal override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } public bool EnableMultipleHttp2Connections { get { throw null; } set { } } } + public enum HttpKeepAlivePingPolicy + { + WithActiveRequests, + Always + } public partial class StreamContent : System.Net.Http.HttpContent { public StreamContent(System.IO.Stream content) { } diff --git a/src/libraries/System.Net.Http/src/Resources/Strings.resx b/src/libraries/System.Net.Http/src/Resources/Strings.resx index 61b45be26fdd..84bc59ad8750 100644 --- a/src/libraries/System.Net.Http/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http/src/Resources/Strings.resx @@ -1,17 +1,17 @@  - @@ -264,6 +264,9 @@ The specified value must be greater than {0}. + + The specified value '{0}' must be greater than or equal to '{1}'. + An invalid character was found in the mail header: '{0}'. 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 f7d8e23d571e..ec91aeb408c9 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -131,6 +131,7 @@ + @@ -168,6 +169,7 @@ + @@ -670,6 +672,7 @@ Link="Common\System\Text\ValueStringBuilder.cs" /> + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs index 2a1d63d35b15..214f5621415e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs @@ -130,6 +130,25 @@ public TimeSpan Expect100ContinueTimeout set => throw new PlatformNotSupportedException(); } + public TimeSpan KeepAlivePingDelay + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public TimeSpan KeepAlivePingTimeout + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + + public HttpKeepAlivePingPolicy KeepAlivePingPolicy + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public ConnectionFactory? ConnectionFactory { get => throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpHandlerDefaults.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpHandlerDefaults.cs new file mode 100644 index 000000000000..21cc00a74444 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpHandlerDefaults.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; + +namespace System.Net.Http +{ + /// + /// Additional default values used used only in this assembly. + /// + internal static partial class HttpHandlerDefaults + { + public static readonly TimeSpan DefaultKeepAlivePingTimeout = TimeSpan.FromSeconds(20); + public static readonly TimeSpan DefaultKeepAlivePingDelay = Timeout.InfiniteTimeSpan; + public const HttpKeepAlivePingPolicy DefaultKeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always; + } +} 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 289fd7a1cb77..3aae8a9357d8 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 @@ -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; using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; @@ -96,6 +97,20 @@ internal sealed partial class Http2Connection : HttpConnectionBase, IDisposable // Channel options for creating _writeChannel private static readonly UnboundedChannelOptions s_channelOptions = new UnboundedChannelOptions() { SingleReader = true }; + internal enum KeepAliveState + { + None, + PingSent + } + + private readonly long _keepAlivePingDelay; + private readonly long _keepAlivePingTimeout; + private readonly HttpKeepAlivePingPolicy _keepAlivePingPolicy; + private long _keepAlivePingPayload; + private long _nextPingRequestTimestamp; + private long _keepAlivePingTimeoutTimestamp; + private volatile KeepAliveState _keepAliveState; + public Http2Connection(HttpConnectionPool pool, Connection connection) { _pool = pool; @@ -119,7 +134,18 @@ public Http2Connection(HttpConnectionPool pool, Connection connection) _pendingWindowUpdate = 0; _idleSinceTickCount = Environment.TickCount64; + + _keepAlivePingDelay = TimeSpanToMs(_pool.Settings._keepAlivePingDelay); + _keepAlivePingTimeout = TimeSpanToMs(_pool.Settings._keepAlivePingTimeout); + _nextPingRequestTimestamp = Environment.TickCount64 + _keepAlivePingDelay; + _keepAlivePingPolicy = _pool.Settings._keepAlivePingPolicy; + if (NetEventSource.Log.IsEnabled()) TraceConnection(_stream); + + static long TimeSpanToMs(TimeSpan value) { + double milliseconds = value.TotalMilliseconds; + return (long)(milliseconds > int.MaxValue ? int.MaxValue : milliseconds); + } } private object SyncObject => _httpStreams; @@ -298,6 +324,8 @@ private async Task ProcessIncomingFramesAsync() frameHeader = await ReadFrameAsync().ConfigureAwait(false); if (NetEventSource.Log.IsEnabled()) Trace($"Frame {frameNum}: {frameHeader}."); + RefreshPingTimestamp(); + // Process the frame. switch (frameHeader.Type) { @@ -667,12 +695,6 @@ private void ProcessPingFrame(FrameHeader frameHeader) ThrowProtocolError(); } - if (frameHeader.AckFlag) - { - // We never send PING, so an ACK indicates a protocol error - ThrowProtocolError(); - } - if (frameHeader.PayloadLength != FrameHeader.PingLength) { ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); @@ -685,8 +707,14 @@ private void ProcessPingFrame(FrameHeader frameHeader) ReadOnlySpan pingContent = _incomingBuffer.ActiveSpan.Slice(0, FrameHeader.PingLength); long pingContentLong = BinaryPrimitives.ReadInt64BigEndian(pingContent); - LogExceptions(SendPingAckAsync(pingContentLong)); - + if (frameHeader.AckFlag) + { + ProcessPingAck(pingContentLong); + } + else + { + LogExceptions(SendPingAsync(pingContentLong, isAck: true)); + } _incomingBuffer.Discard(frameHeader.PayloadLength); } @@ -936,15 +964,16 @@ 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), static (state, writeBuffer) => + /// Determine whether the frame is ping or ping ack. + private Task SendPingAsync(long pingContent, bool isAck = false) => + PerformWriteAsync(FrameHeader.Size + FrameHeader.PingLength, (thisRef: this, pingContent, isAck), static (state, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) state.thisRef.Trace("Started writing."); Debug.Assert(sizeof(long) == FrameHeader.PingLength); Span span = writeBuffer.Span; - FrameHeader.WriteTo(span, FrameHeader.PingLength, FrameType.Ping, FrameFlags.Ack, streamId: 0); + FrameHeader.WriteTo(span, FrameHeader.PingLength, FrameType.Ping, state.isAck ? FrameFlags.Ack: FrameFlags.None, streamId: 0); BinaryPrimitives.WriteInt64BigEndian(span.Slice(FrameHeader.Size), state.pingContent); return true; @@ -962,6 +991,24 @@ private Task SendRstStreamAsync(int streamId, Http2ProtocolErrorCode errorCode) return true; }); + + internal void HeartBeat() + { + if (_disposed) + return; + + try + { + VerifyKeepAlive(); + } + catch (Exception e) + { + if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(HeartBeat)}: {e.Message}"); + + Abort(e); + } + } + private static (ReadOnlyMemory first, ReadOnlyMemory rest) SplitBuffer(ReadOnlyMemory buffer, int maxSize) => buffer.Length > maxSize ? (buffer.Slice(0, maxSize), buffer.Slice(maxSize)) : @@ -1849,6 +1896,56 @@ private void RemoveStream(Http2Stream http2Stream) _concurrentStreams.AdjustCredit(1); } + private void RefreshPingTimestamp() + { + _nextPingRequestTimestamp = Environment.TickCount64 + _keepAlivePingDelay; + } + + private void ProcessPingAck(long payload) + { + if (_keepAliveState != KeepAliveState.PingSent) + ThrowProtocolError(); + if (Interlocked.Read(ref _keepAlivePingPayload) != payload) + ThrowProtocolError(); + _keepAliveState = KeepAliveState.None; + } + + private void VerifyKeepAlive() + { + if (_keepAlivePingPolicy == HttpKeepAlivePingPolicy.WithActiveRequests) + { + lock (SyncObject) + { + if (_httpStreams.Count == 0) return; + } + } + + long now = Environment.TickCount64; + switch (_keepAliveState) + { + case KeepAliveState.None: + // Check whether keep alive delay has passed since last frame received + if (now > _nextPingRequestTimestamp) + { + // Set the status directly to ping sent and set the timestamp + _keepAliveState = KeepAliveState.PingSent; + _keepAlivePingTimeoutTimestamp = now + _keepAlivePingTimeout; + + long pingPayload = Interlocked.Increment(ref _keepAlivePingPayload); + SendPingAsync(pingPayload); + return; + } + break; + case KeepAliveState.PingSent: + if (now > _keepAlivePingTimeoutTimestamp) + ThrowProtocolError(); + break; + default: + Debug.Fail($"Unexpected keep alive state ({_keepAliveState})"); + break; + } + } + public sealed override string ToString() => $"{nameof(Http2Connection)}({_pool})"; // Description for diagnostic purposes public override void Trace(string message, [CallerMemberName] string? memberName = null) => 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 c74f32a10755..33a93b075501 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 @@ -1774,6 +1774,19 @@ private static bool GetIsWindows7Or2008R2() return false; } + internal void HeartBeat() + { + Http2Connection[]? localHttp2Connections = _http2Connections; + if (localHttp2Connections != null) + { + foreach (Http2Connection http2Connection in localHttp2Connections) + { + http2Connection.HeartBeat(); + } + } + } + + // For diagnostic purposes public override string ToString() => $"{nameof(HttpConnectionPool)} " + 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 601b5833b549..290d2952fe87 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 @@ -36,6 +36,8 @@ internal sealed class HttpConnectionPoolManager : IDisposable private readonly ConcurrentDictionary _pools; /// Timer used to initiate cleaning of the pools. private readonly Timer? _cleaningTimer; + /// Heart beat timer currently used for Http2 ping only. + private readonly Timer? _heartBeatTimer; /// The maximum number of connections allowed per pool. indicates unlimited. private readonly int _maxConnectionsPerServer; // Temporary @@ -102,6 +104,8 @@ 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). + var thisRef = new WeakReference(this); + _cleaningTimer = new Timer(static s => { var wr = (WeakReference)s!; @@ -109,7 +113,23 @@ public HttpConnectionPoolManager(HttpConnectionSettings settings) { thisRef.RemoveStalePools(); } - }, new WeakReference(this), Timeout.Infinite, Timeout.Infinite); + }, thisRef, Timeout.Infinite, Timeout.Infinite); + + + // For now heart beat is used only for ping functionality. + if (_settings._keepAlivePingDelay != Timeout.InfiniteTimeSpan) + { + long heartBeatInterval = (long)Math.Max(1000, Math.Min(_settings._keepAlivePingDelay.TotalMilliseconds, _settings._keepAlivePingTimeout.TotalMilliseconds) / 4); + + _heartBeatTimer = new Timer(static state => + { + var wr = (WeakReference)state!; + if (wr.TryGetTarget(out HttpConnectionPoolManager? thisRef)) + { + thisRef.HeartBeat(); + } + }, thisRef, heartBeatInterval, heartBeatInterval); + } } finally { @@ -455,7 +475,7 @@ private async ValueTask SendAsyncMultiProxy(HttpRequestMess public void Dispose() { _cleaningTimer?.Dispose(); - + _heartBeatTimer?.Dispose(); foreach (KeyValuePair pool in _pools) { pool.Value.Dispose(); @@ -519,6 +539,14 @@ private void RemoveStalePools() // be returned to pools they weren't associated with. } + private void HeartBeat() + { + foreach (KeyValuePair pool in _pools) + { + pool.Value.HeartBeat(); + } + } + private static string GetIdentityIfDefaultCredentialsUsed(bool defaultCredentialsUsed) { return defaultCredentialsUsed ? CurrentUserIdentityProvider.GetIdentity() : string.Empty; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index e3231b1c820a..3eefbd35f300 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -42,6 +42,9 @@ internal sealed class HttpConnectionSettings internal TimeSpan _pooledConnectionLifetime = HttpHandlerDefaults.DefaultPooledConnectionLifetime; internal TimeSpan _pooledConnectionIdleTimeout = HttpHandlerDefaults.DefaultPooledConnectionIdleTimeout; internal TimeSpan _expect100ContinueTimeout = HttpHandlerDefaults.DefaultExpect100ContinueTimeout; + internal TimeSpan _keepAlivePingTimeout = HttpHandlerDefaults.DefaultKeepAlivePingTimeout; + internal TimeSpan _keepAlivePingDelay = HttpHandlerDefaults.DefaultKeepAlivePingDelay; + internal HttpKeepAlivePingPolicy _keepAlivePingPolicy = HttpHandlerDefaults.DefaultKeepAlivePingPolicy; internal TimeSpan _connectTimeout = HttpHandlerDefaults.DefaultConnectTimeout; internal HeaderEncodingSelector? _requestHeaderEncodingSelector; @@ -103,6 +106,9 @@ public HttpConnectionSettings CloneAndNormalize() _sslOptions = _sslOptions?.ShallowClone(), // shallow clone the options for basic prevention of mutation issues while processing _useCookies = _useCookies, _useProxy = _useProxy, + _keepAlivePingTimeout = _keepAlivePingTimeout, + _keepAlivePingDelay = _keepAlivePingDelay, + _keepAlivePingPolicy = _keepAlivePingPolicy, _requestHeaderEncodingSelector = _requestHeaderEncodingSelector, _responseHeaderEncodingSelector = _responseHeaderEncodingSelector, _enableMultipleHttp2Connections = _enableMultipleHttp2Connections, diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpKeepAlivePingPolicy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpKeepAlivePingPolicy.cs new file mode 100644 index 000000000000..7eb9f45226ac --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpKeepAlivePingPolicy.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Net.Http +{ + public enum HttpKeepAlivePingPolicy + { + /// + /// Sends keep alive ping for only when there are active streams on the connection. + /// + WithActiveRequests, + + /// + /// Sends keep alive ping for whole connection lifetime. + /// + Always + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 6a8a3d5f0392..fbe84c6a4a66 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -280,6 +280,70 @@ public TimeSpan Expect100ContinueTimeout } } + /// + /// Gets or sets the keep alive ping delay. The client will send a keep alive ping to the server if it + /// doesn't receive any frames on a connection for this period of time. This property is used together with + /// to close broken connections. + /// + /// Delay value must be greater than or equal to 1 second. Set to to + /// disable the keep alive ping. + /// Defaults to . + /// + /// + public TimeSpan KeepAlivePingDelay + { + get => _settings._keepAlivePingDelay; + set + { + if (value.Ticks < TimeSpan.TicksPerSecond && value != Timeout.InfiniteTimeSpan) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(SR.net_http_value_must_be_greater_than_or_equal, value, TimeSpan.FromSeconds(1))); + } + + CheckDisposedOrStarted(); + _settings._keepAlivePingDelay = value; + } + } + + /// + /// Gets or sets the keep alive ping timeout. Keep alive pings are sent when a period of inactivity exceeds + /// the configured value. The client will close the connection if it + /// doesn't receive any frames within the timeout. + /// + /// Timeout must be greater than or equal to 1 second. Set to to + /// disable the keep alive ping timeout. + /// Defaults to 20 seconds. + /// + /// + public TimeSpan KeepAlivePingTimeout + { + get => _settings._keepAlivePingTimeout; + set + { + if (value.Ticks < TimeSpan.TicksPerSecond && value != Timeout.InfiniteTimeSpan) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(SR.net_http_value_must_be_greater_than_or_equal, value, TimeSpan.FromSeconds(1))); + } + + CheckDisposedOrStarted(); + _settings._keepAlivePingTimeout = value; + } + } + + /// + /// Gets or sets the keep alive ping behaviour. Keep alive pings are sent when a period of inactivity exceeds + /// the configured value. + /// + public HttpKeepAlivePingPolicy KeepAlivePingPolicy + { + get => _settings._keepAlivePingPolicy; + set + { + CheckDisposedOrStarted(); + _settings._keepAlivePingPolicy = value; + } + } + /// /// Gets or sets a value that indicates whether additional HTTP/2 connections can be established to the same server /// when the maximum of concurrent streams is reached on all existing connections. diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index 7b62dcc0cba2..46b39fcb0488 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -1451,6 +1451,117 @@ public async Task Http2_InitialWindowSize_ClientDoesNotExceedWindows() } } + public static IEnumerable KeepAliveTestDataSource() + { + yield return new object[] { Timeout.InfiniteTimeSpan, HttpKeepAlivePingPolicy.Always, false }; + yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.WithActiveRequests, false }; + yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.Always, false }; + yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.WithActiveRequests, true }; + } + + [OuterLoop("Significant delay.")] + [MemberData(nameof(KeepAliveTestDataSource))] + [ConditionalTheory(nameof(SupportsAlpn))] + public async Task Http2_PingKeepAlive(TimeSpan keepAlivePingDelay, HttpKeepAlivePingPolicy keepAlivePingPolicy, bool expectRequestFail) + { + TimeSpan pingTimeout = TimeSpan.FromSeconds(5); + // Simulate failure by delaying the pong, otherwise send it immediately. + TimeSpan pongDelay = expectRequestFail ? pingTimeout * 2 : TimeSpan.Zero; + // Pings are send only if KeepAlivePingDelay is not infinite. + bool expectStreamPing = keepAlivePingDelay != Timeout.InfiniteTimeSpan; + // Pings (regardless ongoing communication) are send only if sending is on and policy is set to always. + bool expectPingWithoutStream = expectStreamPing && keepAlivePingPolicy == HttpKeepAlivePingPolicy.Always; + + TaskCompletionSource serverFinished = new TaskCompletionSource(); + + await Http2LoopbackServer.CreateClientAndServerAsync( + async uri => + { + SocketsHttpHandler handler = new SocketsHttpHandler() + { + KeepAlivePingTimeout = pingTimeout, + KeepAlivePingPolicy = keepAlivePingPolicy, + KeepAlivePingDelay = keepAlivePingDelay + }; + handler.SslOptions.RemoteCertificateValidationCallback = delegate { return true; }; + + using HttpClient client = new HttpClient(handler); + client.DefaultRequestVersion = HttpVersion.Version20; + + // Warmup request to create connection. + await client.GetStringAsync(uri); + // Request under the test scope. + if (expectRequestFail) + { + await Assert.ThrowsAsync(() => client.GetStringAsync(uri)); + // As stream is closed we don't want to continue with sending data. + return; + } + else + { + await client.GetStringAsync(uri); + } + + // Let connection live until server finishes. + await serverFinished.Task.TimeoutAfter(pingTimeout * 2); + }, + async server => + { + using Http2LoopbackConnection connection = await server.EstablishConnectionAsync(); + + Task receivePingTask = expectStreamPing ? connection.ExpectPingFrameAsync() : null; + + // Warmup the connection. + int streamId1 = await connection.ReadRequestHeaderAsync(); + await connection.SendDefaultResponseAsync(streamId1); + + // Request under the test scope. + int streamId2 = await connection.ReadRequestHeaderAsync(); + + // Test ping with active stream. + if (!expectStreamPing) + { + await Assert.ThrowsAsync(() => connection.ReadPingAsync(pingTimeout)); + } + else + { + PingFrame ping; + if (receivePingTask != null && receivePingTask.IsCompleted) + { + ping = await receivePingTask; + } + else + { + ping = await connection.ReadPingAsync(pingTimeout); + } + await Task.Delay(pongDelay); + + await connection.SendPingAckAsync(ping.Data); + } + + // Send response and close the stream. + if (expectRequestFail) + { + await Assert.ThrowsAsync(() => connection.SendDefaultResponseAsync(streamId2)); + // As stream is closed we don't want to continue with sending data. + return; + } + await connection.SendDefaultResponseAsync(streamId2); + // Test ping with no active stream. + if (expectPingWithoutStream) + { + PingFrame ping = await connection.ReadPingAsync(pingTimeout); + await connection.SendPingAckAsync(ping.Data); + } + else + { + await Assert.ThrowsAsync(() => connection.ReadPingAsync(pingTimeout)); + } + serverFinished.SetResult(); + await connection.WaitForClientDisconnectAsync(true); + }); + } + [OuterLoop("Uses Task.Delay")] [ConditionalFact(nameof(SupportsAlpn))] public async Task Http2_MaxConcurrentStreams_LimitEnforced() diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index b58fc6bc788c..49266bd125ff 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -136,7 +136,7 @@ public async Task CustomConnectionFactory_AsyncRequest_Success() { using HttpClientHandler handler = CreateHttpClientHandler(); handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; - + var socketsHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); socketsHandler.ConnectionFactory = connectionFactory; @@ -872,7 +872,7 @@ public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); // Additional trailing header frame. - await connection.SendResponseHeadersAsync(streamId, isTrailingHeader:true, headers: TrailingHeaders, endStream : true); + await connection.SendResponseHeadersAsync(streamId, isTrailingHeader: true, headers: TrailingHeaders, endStream: true); HttpResponseMessage response = await sendTask; Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -898,7 +898,7 @@ public async Task Http2GetAsync_TrailerHeaders_TrailingPseudoHeadersThrow() await connection.SendDefaultResponseHeadersAsync(streamId); await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); // Additional trailing header frame with pseudo-headers again.. - await connection.SendResponseHeadersAsync(streamId, isTrailingHeader:false, headers: TrailingHeaders, endStream : true); + await connection.SendResponseHeadersAsync(streamId, isTrailingHeader: false, headers: TrailingHeaders, endStream: true); await Assert.ThrowsAsync(() => sendTask); } @@ -937,10 +937,10 @@ public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Availab // Finish data stream and write out trailing headers. await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); - await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader:true, headers: TrailingHeaders); + await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader: true, headers: TrailingHeaders); // Read data until EOF is reached - while (stream.Read(data, 0, data.Length) != 0); + while (stream.Read(data, 0, data.Length) != 0) ; Assert.Equal(TrailingHeaders.Count, response.TrailingHeaders.Count()); Assert.Contains("amazingtrailer", response.TrailingHeaders.GetValues("MyCoolTrailerHeader")); @@ -962,7 +962,7 @@ public async Task Http2GetAsync_TrailerHeaders_TrailingHeaderNoBody() // Response header. await connection.SendDefaultResponseHeadersAsync(streamId); - await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader:true, headers: TrailingHeaders); + await connection.SendResponseHeadersAsync(streamId, endStream: true, isTrailingHeader: true, headers: TrailingHeaders); HttpResponseMessage response = await sendTask; Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -1302,14 +1302,14 @@ public async Task MultipleIterativeRequests_SameConnectionReused() using (var serverStream = new NetworkStream(server, ownsSocket: false)) using (var serverReader = new StreamReader(serverStream)) { - while (!string.IsNullOrWhiteSpace(await serverReader.ReadLineAsync())); + while (!string.IsNullOrWhiteSpace(await serverReader.ReadLineAsync())) ; await server.SendAsync(new ArraySegment(Encoding.ASCII.GetBytes(responseBody)), SocketFlags.None); await firstRequest; Task secondAccept = listener.AcceptAsync(); // shouldn't complete Task additionalRequest = client.GetStringAsync(uri); - while (!string.IsNullOrWhiteSpace(await serverReader.ReadLineAsync())); + while (!string.IsNullOrWhiteSpace(await serverReader.ReadLineAsync())) ; await server.SendAsync(new ArraySegment(Encoding.ASCII.GetBytes(responseBody)), SocketFlags.None); await additionalRequest; @@ -1584,7 +1584,7 @@ public async Task ProxyAuth_SameConnection_Succeeds() "Content-Length: 0\r\n" + "\r\n"; - using (var handler = new HttpClientHandler()) + using (var handler = new HttpClientHandler()) { handler.Proxy = new UseSpecifiedUriWebProxy(proxyUrl, new NetworkCredential("abc", "password")); @@ -1597,7 +1597,7 @@ await proxyServer.AcceptConnectionAsync(async connection => // Get first request, no body for GET. await connection.ReadRequestHeaderAndSendCustomResponseAsync(responseBody).ConfigureAwait(false); // Client should send another request after being rejected with 407. - await connection.ReadRequestHeaderAndSendResponseAsync(content:"OK").ConfigureAwait(false); + await connection.ReadRequestHeaderAndSendResponseAsync(content: "OK").ConfigureAwait(false); }); string response = await request; @@ -1684,6 +1684,30 @@ public void DefaultProxyCredentials_GetSet_Roundtrips() } } + [Fact] + public void KeepAlivePing_GetSet_Roundtrips() + { + using var handler = new SocketsHttpHandler(); + + var testTimeSpanValue = TimeSpan.FromSeconds(5); + var invalidTimeSpanValue = TimeSpan.FromTicks(TimeSpan.TicksPerSecond - 1); + + Assert.Equal(TimeSpan.FromSeconds(20), handler.KeepAlivePingTimeout); + handler.KeepAlivePingTimeout = testTimeSpanValue; + Assert.Equal(testTimeSpanValue, handler.KeepAlivePingTimeout); + + Assert.Equal(Timeout.InfiniteTimeSpan, handler.KeepAlivePingDelay); + handler.KeepAlivePingDelay = testTimeSpanValue; + Assert.Equal(testTimeSpanValue, handler.KeepAlivePingDelay); + + Assert.Equal(HttpKeepAlivePingPolicy.Always, handler.KeepAlivePingPolicy); + handler.KeepAlivePingPolicy = HttpKeepAlivePingPolicy.WithActiveRequests; + Assert.Equal(HttpKeepAlivePingPolicy.WithActiveRequests, handler.KeepAlivePingPolicy); + + Assert.Throws(() => handler.KeepAlivePingTimeout = invalidTimeSpanValue); + Assert.Throws(() => handler.KeepAlivePingDelay = invalidTimeSpanValue); + } + [Fact] public void MaxAutomaticRedirections_GetSet_Roundtrips() { @@ -1930,6 +1954,9 @@ await Assert.ThrowsAnyAsync(() => Assert.Throws(expectedExceptionType, () => handler.SslOptions = new SslClientAuthenticationOptions()); Assert.Throws(expectedExceptionType, () => handler.UseCookies = false); Assert.Throws(expectedExceptionType, () => handler.UseProxy = false); + Assert.Throws(expectedExceptionType, () => handler.KeepAlivePingTimeout = TimeSpan.FromSeconds(5)); + Assert.Throws(expectedExceptionType, () => handler.KeepAlivePingDelay = TimeSpan.FromSeconds(5)); + Assert.Throws(expectedExceptionType, () => handler.KeepAlivePingPolicy = HttpKeepAlivePingPolicy.WithActiveRequests); } } } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index ea67ef0b9c7c..0af91c2ddd99 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -70,6 +70,8 @@ Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" /> + + Date: Thu, 13 Aug 2020 08:09:50 +0000 Subject: [PATCH 444/755] [master] Update dependencies from dotnet/arcade mono/linker dotnet/llvm-project dotnet/xharness dotnet/icu (#40376) [master] Update dependencies from dotnet/arcade mono/linker dotnet/llvm-project dotnet/xharness dotnet/icu - Updates: - Microsoft.NET.ILLink.Tasks: from 5.0.0-preview.3.20403.5 to 5.0.0-preview.3.20412.1 - Updates: - Microsoft.NETCore.Runtime.ICU.Transport: from 5.0.0-preview.8.20403.1 to 5.0.0-preview.8.20410.1 - Updates: - Microsoft.DotNet.XUnitExtensions: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.GenFacades: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.Build.Tasks.Feed: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.Build.Tasks.Packaging: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.CodeAnalysis: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.GenAPI: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.XUnitConsoleRunner: from 2.5.1-beta.20374.1 to 2.5.1-beta.20407.3 - Microsoft.DotNet.Arcade.Sdk: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.Helix.Sdk: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.RemoteExecutor: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.VersionTools.Tasks: from 5.0.0-beta.20374.1 to 5.0.0-beta.20407.3 - Microsoft.DotNet.ApiCompat: from 5.0.0-beta.20381.6 to 5.0.0-beta.20407.3 - Updates: - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: from 9.0.1-alpha.1.20403.1 to 9.0.1-alpha.1.20410.1 - Updates: - Microsoft.DotNet.XHarness.CLI: from 1.0.0-prerelease.20403.2 to 1.0.0-prerelease.20411.1 - Microsoft.DotNet.XHarness.TestRunners.Xunit: from 1.0.0-prerelease.20403.2 to 1.0.0-prerelease.20411.1 - Merge branch 'master' into darc-master-cf92596d-90a4-4e3c-8692-fff33361f7e0 - Merge branch 'master' into darc-master-cf92596d-90a4-4e3c-8692-fff33361f7e0 --- eng/Version.Details.xml | 104 +++++++++--------- eng/Versions.props | 44 ++++---- eng/common/SetupNugetSources.ps1 | 17 +++ eng/common/SetupNugetSources.sh | 23 +++- eng/common/cross/arm64/tizen-fetch.sh | 2 +- eng/common/cross/armel/tizen-fetch.sh | 7 +- eng/common/cross/toolchain.cmake | 2 +- eng/common/performance/microbenchmarks.proj | 2 +- eng/common/performance/performance-setup.sh | 6 +- .../templates/steps/perf-send-to-helix.yml | 4 +- global.json | 8 +- 11 files changed, 125 insertions(+), 94 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 78762c50759b..8742e9ff0da4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,67 +4,67 @@ https://github.com/dotnet/standard cfe95a23647c7de1fe1a349343115bd7720d6949 - + https://github.com/dotnet/icu - 8bd04d98c75cc7d8ac9026eab2c63e50294b0552 + 0f49268ddfd3331ca090f1c51d2baa2f75f6c6c0 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - 39c3b73c4b2b79981405e865e5a4fa096662f13a + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - f6192d1e284a08ac05041d05fa6e60dec74b24f5 + ea8f37e8982dc22022b33c5e151081ad04d923a6 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -122,37 +122,37 @@ https://github.com/dotnet/runtime-assets 4d5781485294568e51a4673719c8ae5ae8955e70 - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb - + https://github.com/dotnet/llvm-project - 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf + 9cdff1ac4ccaf70a9172139fbd3e41dbb6a9d6bb https://github.com/dotnet/runtime @@ -182,17 +182,17 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 8f32ed57a05eeb0bae3790c4db75b316c3da76c7 + fc5e4aa86ad543ab3a730e0e0e8dacc6a379d4a5 - + https://github.com/dotnet/xharness - abc6d581ce00214ef763fb8510d1ba0aa54e7717 + 3cecc1a18c6063eeabc63984215c1cfb23018a63 - + https://github.com/dotnet/xharness - abc6d581ce00214ef763fb8510d1ba0aa54e7717 + 3cecc1a18c6063eeabc63984215c1cfb23018a63 diff --git a/eng/Versions.props b/eng/Versions.props index 807c2382cec7..b4a1f5e067be 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -51,16 +51,16 @@ - 5.0.0-beta.20381.6 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 - 2.5.1-beta.20374.1 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 - 5.0.0-beta.20374.1 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 2.5.1-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 + 5.0.0-beta.20407.3 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 @@ -133,8 +133,8 @@ 4.9.4 16.8.0-preview-20200730-03 - 1.0.0-prerelease.20403.2 - 1.0.0-prerelease.20403.2 + 1.0.0-prerelease.20411.1 + 1.0.0-prerelease.20411.1 2.4.1 2.4.2 1.3.0 @@ -145,18 +145,18 @@ 3.0.0-preview-20200715.1 - 5.0.0-preview.3.20403.5 + 5.0.0-preview.3.20412.1 - 5.0.0-preview.8.20404.1 + 5.0.0-preview.8.20410.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 - 9.0.1-alpha.1.20403.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 + 9.0.1-alpha.1.20410.1 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index dc22178125a6..bb3617133f09 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -11,6 +11,8 @@ # See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` # from the AzureDevOps-Artifact-Feeds-Pats variable group. # +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing +# # - task: PowerShell@2 # displayName: Setup Private Feeds Credentials # condition: eq(variables['Agent.OS'], 'Windows_NT') @@ -94,6 +96,14 @@ function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Passw } } +function EnablePrivatePackageSources($DisabledPackageSources) { + $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]") + ForEach ($DisabledPackageSource in $maestroPrivateSources) { + Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled" + $DisabledPackageSource.SetAttribute("value", "false") + } +} + if (!(Test-Path $ConfigFile -PathType Leaf)) { Write-PipelineTelemetryError -Category 'Build' -Message "Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile" ExitWithExitCode 1 @@ -123,6 +133,13 @@ if ($creds -eq $null) { $doc.DocumentElement.AppendChild($creds) | Out-Null } +# Check for disabledPackageSources; we'll enable any darc-int ones we find there +$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources") +if ($disabledSources -ne $null) { + Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node" + EnablePrivatePackageSources -DisabledPackageSources $disabledSources +} + $userName = "dn-bot" # Insert credential nodes for Maestro's private feeds diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index f33e37711e72..ef33382954cf 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -13,6 +13,8 @@ # See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` # from the AzureDevOps-Artifact-Feeds-Pats variable group. # +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing. +# # - task: Bash@3 # displayName: Setup Private Feeds Credentials # inputs: @@ -63,7 +65,7 @@ if [ "$?" != "0" ]; then ConfigNodeHeader="" PackageSourcesTemplate="${TB}${NL}${TB}" - sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" NuGet.config + sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile fi # Ensure there is a ... section. @@ -74,7 +76,7 @@ if [ "$?" != "0" ]; then PackageSourcesNodeFooter="" PackageSourceCredentialsTemplate="${TB}${NL}${TB}" - sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" NuGet.config + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile fi PackageSources=() @@ -146,3 +148,20 @@ for FeedName in ${PackageSources[@]} ; do sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile fi done + +# Re-enable any entries in disabledPackageSources where the feed name contains darc-int +grep -i "" $ConfigFile +if [ "$?" == "0" ]; then + DisabledDarcIntSources=() + echo "Re-enabling any disabled \"darc-int\" package sources in $ConfigFile" + DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' $ConfigFile | tr -d '"') + for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do + if [[ $DisabledSourceName == darc-int* ]] + then + OldDisableValue="add key=\"$DisabledSourceName\" value=\"true\"" + NewDisableValue="add key=\"$DisabledSourceName\" value=\"false\"" + sed -i.bak "s|$OldDisableValue|$NewDisableValue|" $ConfigFile + echo "Neutralized disablePackageSources entry for '$DisabledSourceName'" + fi + done +fi diff --git a/eng/common/cross/arm64/tizen-fetch.sh b/eng/common/cross/arm64/tizen-fetch.sh index 338d1c3bf3c7..a48a6f51c49d 100644 --- a/eng/common/cross/arm64/tizen-fetch.sh +++ b/eng/common/cross/arm64/tizen-fetch.sh @@ -161,7 +161,7 @@ fetch_tizen_pkgs aarch64 gcc glibc glibc-devel libicu libicu-devel libatomic lin Inform "fetch coreclr packages" fetch_tizen_pkgs aarch64 lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu Inform "fetch corefx packages" -fetch_tizen_pkgs aarch64 libcom_err libcom_err-devel zlib zlib-devel libopenssl libopenssl1.1-devel krb5 krb5-devel +fetch_tizen_pkgs aarch64 libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel Inform "Initialize standard unified" fetch_tizen_pkgs_init standard unified diff --git a/eng/common/cross/armel/tizen-fetch.sh b/eng/common/cross/armel/tizen-fetch.sh index ed70e0a86ebd..2776cbba4e46 100755 --- a/eng/common/cross/armel/tizen-fetch.sh +++ b/eng/common/cross/armel/tizen-fetch.sh @@ -51,7 +51,7 @@ if [ ! -d $TMPDIR ]; then mkdir -p $TMPDIR fi -TIZEN_URL=http://download.tizen.org/releases/milestone/tizen +TIZEN_URL=http://download.tizen.org/snapshots/tizen BUILD_XML=build.xml REPOMD_XML=repomd.xml PRIMARY_XML=primary.xml @@ -157,12 +157,11 @@ fetch_tizen_pkgs() Inform "Initialize arm base" fetch_tizen_pkgs_init standard base Inform "fetch common packages" -fetch_tizen_pkgs armv7l gcc glibc glibc-devel libicu libicu-devel libatomic -fetch_tizen_pkgs noarch linux-glibc-devel +fetch_tizen_pkgs armv7l gcc glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel Inform "fetch coreclr packages" fetch_tizen_pkgs armv7l lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu Inform "fetch corefx packages" -fetch_tizen_pkgs armv7l libcom_err libcom_err-devel zlib zlib-devel libopenssl libopenssl-devel krb5 krb5-devel libcurl libcurl-devel +fetch_tizen_pkgs armv7l libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel Inform "Initialize standard unified" fetch_tizen_pkgs_init standard unified diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index b9fe796f0da7..2566707997b0 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -15,7 +15,7 @@ if(TARGET_ARCH_NAME STREQUAL "armel") set(CMAKE_SYSTEM_PROCESSOR armv7l) set(TOOLCHAIN "arm-linux-gnueabi") if("$ENV{__DistroRid}" MATCHES "tizen.*") - set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/6.2.1") + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0") endif() elseif(TARGET_ARCH_NAME STREQUAL "arm") set(CMAKE_SYSTEM_PROCESSOR armv7l) diff --git a/eng/common/performance/microbenchmarks.proj b/eng/common/performance/microbenchmarks.proj index 71114b074e1b..5c95ef458ee0 100644 --- a/eng/common/performance/microbenchmarks.proj +++ b/eng/common/performance/microbenchmarks.proj @@ -69,7 +69,7 @@ - 12:30 + 2:30 0:15 diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh index 66f63a397a0f..fd26bdb1735f 100755 --- a/eng/common/performance/performance-setup.sh +++ b/eng/common/performance/performance-setup.sh @@ -136,7 +136,7 @@ while (($# > 0)); do echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\"" echo " --internal If the benchmarks are running as an official job." echo " --monodotnet Pass the path to the mono dotnet for mono performance testing." - echo " --wasm Path to the unpacled wasm runtime pack." + echo " --wasm Path to the unpacked wasm runtime pack." echo "" exit 0 ;; @@ -230,13 +230,9 @@ fi if [[ "$wasm_runtime_loc" != "" ]]; then using_wasm=true - wasm_dotnet_path=$payload_directory/dotnet-wasm - mv $wasm_runtime_loc $wasm_dotnet_path - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmMainJS \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm/runtime-test.js --wasmEngine /home/helixbot/.jsvu/v8 --customRuntimePack \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm" - fi if [[ "$mono_dotnet" != "" ]]; then diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml index 1e3bed764cfa..e003fe2ef29e 100644 --- a/eng/common/templates/steps/perf-send-to-helix.yml +++ b/eng/common/templates/steps/perf-send-to-helix.yml @@ -4,8 +4,8 @@ parameters: HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list 0of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group HelixPreCommands: '' # optional -- commands to run before Helix work item execution HelixPostCommands: '' # optional -- commands to run after Helix work item execution WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects diff --git a/global.json b/global.json index 5d4b27ae61c0..8032e3ebeede 100644 --- a/global.json +++ b/global.json @@ -12,10 +12,10 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20374.1", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20374.1", - "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20374.1", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20374.1", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20407.3", + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20407.3", + "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20407.3", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20407.3", "Microsoft.FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", "Microsoft.NET.Sdk.IL": "5.0.0-preview.8.20359.4", "Microsoft.Build.NoTargets": "1.0.53", From 3c29684ba59cb7999aab0223648e66eb3a3e079a Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 13 Aug 2020 11:32:09 +0200 Subject: [PATCH 445/755] add Process.Start(string fileName, IEnumerable arguments) overload (#40661) * add Process.Start(string fileName, IEnumerable arguments) overload, fixes #371 --- .../ref/System.Diagnostics.Process.cs | 1 + .../src/System/Diagnostics/Process.cs | 20 ++++++++++ .../tests/ProcessTests.cs | 37 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index 74fa2a149c4d..e2c682735fce 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -116,6 +116,7 @@ public void Refresh() { } public static System.Diagnostics.Process? Start(System.Diagnostics.ProcessStartInfo startInfo) { throw null; } public static System.Diagnostics.Process Start(string fileName) { throw null; } public static System.Diagnostics.Process Start(string fileName, string arguments) { throw null; } + public static System.Diagnostics.Process Start(string fileName, System.Collections.Generic.IEnumerable arguments) { throw null; } [System.CLSCompliantAttribute(false)] [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static System.Diagnostics.Process? Start(string fileName, string userName, System.Security.SecureString password, string domain) { throw null; } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index 7349b3112e40..d6acb3de5ae0 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using System.Runtime.Versioning; +using System.Collections.Generic; namespace System.Diagnostics { @@ -1262,6 +1263,25 @@ public static Process Start(string fileName, string arguments) return Start(new ProcessStartInfo(fileName, arguments))!; } + /// + /// Starts a process resource by specifying the name of an application and a set of command line arguments + /// + public static Process Start(string fileName, IEnumerable arguments) + { + if (fileName == null) + throw new ArgumentNullException(nameof(fileName)); + if (arguments == null) + throw new ArgumentNullException(nameof(arguments)); + + var startInfo = new ProcessStartInfo(fileName); + foreach (string argument in arguments) + { + startInfo.ArgumentList.Add(argument); + } + + return Start(startInfo)!; + } + /// /// /// Starts a process resource specified by the process start diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index badc169a4331..5fa900d1883d 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -2269,6 +2269,43 @@ await Helpers.RetryWithBackoff(() => } } + [Fact] + public void Start_ThrowsArgumentNullExceptionForNullFileName() + { + Assert.Throws("fileName", () => Process.Start(null, Enumerable.Repeat("notNull", 1))); + } + + [Fact] + public void Start_ThrowsArgumentNullExceptionForNullArgumentsList() + { + IEnumerable @null = null; + Assert.Throws("arguments", () => Process.Start("notNull", @null)); + } + + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] // cmd.exe is available only on Windows + public void Start_PassesArgumentsList_WhichGetsEscaped() + { + string folderNameWithSpaces = "folder name with spaces"; // this needs escaping + string fullPath = Path.Combine(TestDirectory, folderNameWithSpaces); + string[] arguments = new string[] { "/c", "mkdir", "-p", fullPath }; + + if (Directory.Exists(fullPath)) + { + Directory.Delete(fullPath); + } + + using (Process mkdir = Process.Start("cmd.exe", arguments)) + { + Assert.Equal(arguments, mkdir.StartInfo.ArgumentList); + + mkdir.WaitForExit(WaitInMS); + + Assert.True(Directory.Exists(fullPath)); + Directory.Delete(fullPath); + } + } + private IReadOnlyList CreateProcessTree() { (Process Value, string Message) rootResult = ListenForAnonymousPipeMessage(rootPipeHandleString => From 2fd135f1b14bfc7ee0d715c37809f1fbdc41739f Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Thu, 13 Aug 2020 12:09:49 +0200 Subject: [PATCH 446/755] Optimize vectorized sorting - reduce code size, improve speed for large heaps (#40613) * Improved vectorized sort - smaller bitonic sorters, dynamic packing/unpacking. There are two optimizations in this PR: - reduction of code size in the bitonic sorters: by limiting the amount of inlining in this code, we can reduce overall code size in coreclr.dll by about 180 kB. - dynamic packing: during sorting, we can switch to 32-bit sorting as soon as the address range in a partition is less 32 GB. This will only have an impact on large heaps or machines with many processors, because we already have a similar, but static optimization where we use 32-bit sorting if the overall address range in the ephemeral region is less than 32 GB. So this additional optimization will give improvements if the overall address range is greater than 32 GB initially, but becomes less during the sort. In this case, we get about a 1.6x improvement in sorting speed. --- src/coreclr/src/gc/CMakeLists.txt | 1 + src/coreclr/src/gc/gc.cpp | 40 +- src/coreclr/src/gc/sample/CMakeLists.txt | 1 + src/coreclr/src/gc/vxsort/alignment.h | 2 - src/coreclr/src/gc/vxsort/defs.h | 41 ++ src/coreclr/src/gc/vxsort/do_vxsort.h | 12 +- src/coreclr/src/gc/vxsort/do_vxsort_avx2.cpp | 77 +--- .../src/gc/vxsort/do_vxsort_avx512.cpp | 67 +-- src/coreclr/src/gc/vxsort/isa_detection.cpp | 13 +- .../src/gc/vxsort/machine_traits.avx2.cpp | 2 - .../src/gc/vxsort/machine_traits.avx2.h | 203 +++------ .../src/gc/vxsort/machine_traits.avx512.h | 246 ++++------- src/coreclr/src/gc/vxsort/machine_traits.h | 53 ++- src/coreclr/src/gc/vxsort/packer.h | 403 ++++++++++-------- .../smallsort/avx2_load_mask_tables.cpp | 41 ++ .../bitonic_sort.AVX2.int32_t.generated.cpp | 39 +- .../bitonic_sort.AVX2.int32_t.generated.h | 192 +++++---- .../bitonic_sort.AVX2.int64_t.generated.cpp | 39 +- .../bitonic_sort.AVX2.int64_t.generated.h | 192 +++++---- .../bitonic_sort.AVX512.int32_t.generated.cpp | 39 +- .../bitonic_sort.AVX512.int32_t.generated.h | 220 ++++++---- .../bitonic_sort.AVX512.int64_t.generated.cpp | 39 +- .../bitonic_sort.AVX512.int64_t.generated.h | 220 ++++++---- .../src/gc/vxsort/smallsort/bitonic_sort.h | 25 +- .../src/gc/vxsort/smallsort/codegen/avx2.py | 113 ++++- .../src/gc/vxsort/smallsort/codegen/avx512.py | 98 ++++- .../vxsort/smallsort/codegen/bitonic_gen.py | 7 +- src/coreclr/src/gc/vxsort/vxsort.h | 142 +++--- .../gc/vxsort/vxsort_targets_enable_avx512.h | 4 +- src/coreclr/src/vm/CMakeLists.txt | 1 + 30 files changed, 1435 insertions(+), 1137 deletions(-) create mode 100644 src/coreclr/src/gc/vxsort/smallsort/avx2_load_mask_tables.cpp diff --git a/src/coreclr/src/gc/CMakeLists.txt b/src/coreclr/src/gc/CMakeLists.txt index c46f46fdfbae..a34567e1910a 100644 --- a/src/coreclr/src/gc/CMakeLists.txt +++ b/src/coreclr/src/gc/CMakeLists.txt @@ -50,6 +50,7 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp + vxsort/smallsort/avx2_load_mask_tables.cpp ) endif (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index f4e5adb0aba5..8862c75a211e 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -8293,44 +8293,16 @@ static void do_vxsort (uint8_t** item_array, ptrdiff_t item_count, uint8_t* rang if (IsSupportedInstructionSet (InstructionSet::AVX2) && (item_count > AVX2_THRESHOLD_SIZE)) { - // is the range small enough for a 32-bit sort? - // the 32-bit sort is almost twice as fast - ptrdiff_t range = range_high - range_low; - assert(sizeof(uint8_t*) == (1 << 3)); - ptrdiff_t scaled_range = range >> 3; - if ((uint32_t)scaled_range == scaled_range) - { - dprintf (3, ("Sorting mark lists as 32-bit offsets")); - - do_pack_avx2 (item_array, item_count, range_low); - - int32_t* item_array_32 = (int32_t*)item_array; - - // use AVX512F only if the list is large enough to pay for downclocking impact - if (IsSupportedInstructionSet (InstructionSet::AVX512F) && (item_count > AVX512F_THRESHOLD_SIZE)) - { - do_vxsort_avx512 (item_array_32, &item_array_32[item_count - 1]); - } - else - { - do_vxsort_avx2 (item_array_32, &item_array_32[item_count - 1]); - } + dprintf(3, ("Sorting mark lists")); - do_unpack_avx2 (item_array_32, item_count, range_low); + // use AVX512F only if the list is large enough to pay for downclocking impact + if (IsSupportedInstructionSet (InstructionSet::AVX512F) && (item_count > AVX512F_THRESHOLD_SIZE)) + { + do_vxsort_avx512 (item_array, &item_array[item_count - 1], range_low, range_high); } else { - dprintf(3, ("Sorting mark lists")); - - // use AVX512F only if the list is large enough to pay for downclocking impact - if (IsSupportedInstructionSet (InstructionSet::AVX512F) && (item_count > AVX512F_THRESHOLD_SIZE)) - { - do_vxsort_avx512 (item_array, &item_array[item_count - 1]); - } - else - { - do_vxsort_avx2 (item_array, &item_array[item_count - 1]); - } + do_vxsort_avx2 (item_array, &item_array[item_count - 1], range_low, range_high); } } else diff --git a/src/coreclr/src/gc/sample/CMakeLists.txt b/src/coreclr/src/gc/sample/CMakeLists.txt index 40bb0b5dcd54..e7849c88d9d1 100644 --- a/src/coreclr/src/gc/sample/CMakeLists.txt +++ b/src/coreclr/src/gc/sample/CMakeLists.txt @@ -35,6 +35,7 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) ../vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp ../vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp ../vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp + ../vxsort/smallsort/avx2_load_mask_tables.cpp ) endif (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/src/gc/vxsort/alignment.h b/src/coreclr/src/gc/vxsort/alignment.h index df61c3a30f41..a32261be951f 100644 --- a/src/coreclr/src/gc/vxsort/alignment.h +++ b/src/coreclr/src/gc/vxsort/alignment.h @@ -4,8 +4,6 @@ #ifndef VXSORT_ALIGNNMENT_H #define VXSORT_ALIGNNMENT_H -//#include - namespace vxsort { using namespace std; diff --git a/src/coreclr/src/gc/vxsort/defs.h b/src/coreclr/src/gc/vxsort/defs.h index 628315e5110a..0cc72b23fa24 100644 --- a/src/coreclr/src/gc/vxsort/defs.h +++ b/src/coreclr/src/gc/vxsort/defs.h @@ -45,4 +45,45 @@ #define NOINLINE __attribute__((noinline)) #endif +namespace std { +template +class numeric_limits { + public: + static constexpr _Ty Max() { static_assert(sizeof(_Ty) != sizeof(_Ty), "func must be specialized!"); return _Ty(); } + static constexpr _Ty Min() { static_assert(sizeof(_Ty) != sizeof(_Ty), "func must be specialized!"); return _Ty(); } +}; + +template <> +class numeric_limits { +public: + static constexpr int32_t Max() { return 0x7fffffff; } + static constexpr int32_t Min() { return -0x7fffffff - 1; } +}; + +template <> +class numeric_limits { +public: + static constexpr uint32_t Max() { return 0xffffffff; } + static constexpr uint32_t Min() { return 0; } +}; + +template <> +class numeric_limits { + public: + static constexpr int64_t Max() { return 0x7fffffffffffffffi64; } + + static constexpr int64_t Min() { return -0x7fffffffffffffffi64 - 1; } +}; +} // namespace std + +#ifndef max +template +T max(T a, T b) { + if (a > b) + return a; + else + return b; +} +#endif + #endif // VXSORT_DEFS_H diff --git a/src/coreclr/src/gc/vxsort/do_vxsort.h b/src/coreclr/src/gc/vxsort/do_vxsort.h index 50a5e1ef77a7..edd803f310f4 100644 --- a/src/coreclr/src/gc/vxsort/do_vxsort.h +++ b/src/coreclr/src/gc/vxsort/do_vxsort.h @@ -11,14 +11,6 @@ enum class InstructionSet void InitSupportedInstructionSet (int32_t configSetting); bool IsSupportedInstructionSet (InstructionSet instructionSet); -void do_vxsort_avx2 (uint8_t** low, uint8_t** high); -void do_vxsort_avx2 (int32_t* low, int32_t* high); +void do_vxsort_avx2 (uint8_t** low, uint8_t** high, uint8_t *range_low, uint8_t *range_high); -void do_pack_avx2 (uint8_t** mem, size_t len, uint8_t* base); -void do_unpack_avx2 (int32_t* mem, size_t len, uint8_t* base); - -void do_vxsort_avx512 (uint8_t** low, uint8_t** high); -void do_vxsort_avx512 (int32_t* low, int32_t* high); - -void do_pack_avx512 (uint8_t** mem, size_t len, uint8_t* base); -void do_unpack_avx512 (int32_t* mem, size_t len, uint8_t* base); +void do_vxsort_avx512 (uint8_t** low, uint8_t** high, uint8_t* range_low, uint8_t* range_high); diff --git a/src/coreclr/src/gc/vxsort/do_vxsort_avx2.cpp b/src/coreclr/src/gc/vxsort/do_vxsort_avx2.cpp index 3e4fd10d15f4..1f097ede355d 100644 --- a/src/coreclr/src/gc/vxsort/do_vxsort_avx2.cpp +++ b/src/coreclr/src/gc/vxsort/do_vxsort_avx2.cpp @@ -5,82 +5,15 @@ #include "vxsort_targets_enable_avx2.h" -namespace std -{ - template - class numeric_limits - { - public: - static _Ty Max() - { - return _Ty(); - } - static _Ty Min() - { - return _Ty(); - } - }; - template <> - class numeric_limits - { - public: - static int32_t Max() - { - return 0x7fffffff; - } - static int32_t Min() - { - return -0x7fffffff-1; - } - }; - template <> - class numeric_limits - { - public: - static int64_t Max() - { - return 0x7fffffffffffffffi64; - } - - static int64_t Min() - { - return -0x7fffffffffffffffi64-1; - } - }; -} - -#ifndef max -template -T max (T a, T b) -{ - if (a > b) return a; else return b; -} -#endif #include "vxsort.h" #include "machine_traits.avx2.h" #include "packer.h" -void do_vxsort_avx2 (uint8_t** low, uint8_t** high) -{ - auto sorter = vxsort::vxsort(); - sorter.sort ((int64_t*)low, (int64_t*)high); -} - -void do_vxsort_avx2 (int32_t* low, int32_t* high) -{ - auto sorter = vxsort::vxsort(); - sorter.sort (low, high); -} - -void do_pack_avx2 (uint8_t** mem, size_t len, uint8_t* base) -{ - auto packer = vxsort::packer(); - packer.pack ((int64_t*)mem, len, (int64_t)base); -} - -void do_unpack_avx2 (int32_t* mem, size_t len, uint8_t* base) +void do_vxsort_avx2 (uint8_t** low, uint8_t** high, uint8_t* range_low, uint8_t* range_high) { - auto packer = vxsort::packer(); - packer.unpack (mem, len, (int64_t)base); + const int shift = 3; + assert((1 << shift) == sizeof(size_t)); + auto sorter = vxsort::vxsort(); + sorter.sort ((int64_t*)low, (int64_t*)high, (int64_t)range_low, (int64_t)(range_high+sizeof(uint8_t*))); } #include "vxsort_targets_disable.h" diff --git a/src/coreclr/src/gc/vxsort/do_vxsort_avx512.cpp b/src/coreclr/src/gc/vxsort/do_vxsort_avx512.cpp index aa0a8f99442e..792492046fd9 100644 --- a/src/coreclr/src/gc/vxsort/do_vxsort_avx512.cpp +++ b/src/coreclr/src/gc/vxsort/do_vxsort_avx512.cpp @@ -5,71 +5,14 @@ #include "vxsort_targets_enable_avx512.h" -namespace std -{ - template - class numeric_limits - { - public: - static _Ty Max() - { - return _Ty(); - } - static _Ty Min() - { - return _Ty(); - } - }; - template <> - class numeric_limits - { - public: - static int32_t Max() - { - return 0x7fffffff; - } - static int32_t Min() - { - return -0x7fffffff - 1; - } - }; - template <> - class numeric_limits - { - public: - static int64_t Max() - { - return 0x7fffffffffffffffi64; - } - - static int64_t Min() - { - return -0x7fffffffffffffffi64 - 1; - } - }; -} - -#ifndef max -template -T max (T a, T b) -{ - if (a > b) return a; else return b; -} -#endif - #include "vxsort.h" #include "machine_traits.avx512.h" -void do_vxsort_avx512 (uint8_t** low, uint8_t** high) +void do_vxsort_avx512 (uint8_t** low, uint8_t** high, uint8_t* range_low, uint8_t* range_high) { - auto sorter = vxsort::vxsort(); - sorter.sort ((int64_t*)low, (int64_t*)high); + const int shift = 3; + assert((1 << shift) == sizeof(size_t)); + auto sorter = vxsort::vxsort(); + sorter.sort ((int64_t*)low, (int64_t*)high, (int64_t)range_low, (int64_t)(range_high+sizeof(uint8_t*))); } - -void do_vxsort_avx512 (int32_t* low, int32_t* high) -{ - auto sorter = vxsort::vxsort(); - sorter.sort (low, high); -} - #include "vxsort_targets_disable.h" diff --git a/src/coreclr/src/gc/vxsort/isa_detection.cpp b/src/coreclr/src/gc/vxsort/isa_detection.cpp index ac469a615dde..770c34f7b2e9 100644 --- a/src/coreclr/src/gc/vxsort/isa_detection.cpp +++ b/src/coreclr/src/gc/vxsort/isa_detection.cpp @@ -54,10 +54,11 @@ SupportedISA DetermineSupportedISA() // bit definitions to make code more readable enum bits { - OCXSAVE = 1<<27, - AVX = 1<<28, - AVX2 = 1<<5, - AVX512F=1<<16, + OCXSAVE = 1<<27, + AVX = 1<<28, + AVX2 = 1<< 5, + AVX512F = 1<<16, + AVX512DQ = 1<<17, }; int reg[COUNT]; @@ -80,8 +81,8 @@ SupportedISA DetermineSupportedISA() // get processor extended feature flag info __cpuid(reg, 7); - // check if both AVX2 and AVX512F are supported by both processor and OS - if ((reg[EBX] & (AVX2 | AVX512F)) == (AVX2 | AVX512F) && + // check if all of AVX2, AVX512F and AVX512DQ are supported by both processor and OS + if ((reg[EBX] & (AVX2 | AVX512F | AVX512DQ)) == (AVX2 | AVX512F | AVX512DQ) && (xcr0 & 0xe6) == 0xe6 && (FeatureMask & (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)) == (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)) { diff --git a/src/coreclr/src/gc/vxsort/machine_traits.avx2.cpp b/src/coreclr/src/gc/vxsort/machine_traits.avx2.cpp index d693d08ea414..e4e86d4b239c 100644 --- a/src/coreclr/src/gc/vxsort/machine_traits.avx2.cpp +++ b/src/coreclr/src/gc/vxsort/machine_traits.avx2.cpp @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. #include "common.h" -//#include - #include "machine_traits.avx2.h" namespace vxsort { diff --git a/src/coreclr/src/gc/vxsort/machine_traits.avx2.h b/src/coreclr/src/gc/vxsort/machine_traits.avx2.h index 1944b57a18f1..3720e78668e4 100644 --- a/src/coreclr/src/gc/vxsort/machine_traits.avx2.h +++ b/src/coreclr/src/gc/vxsort/machine_traits.avx2.h @@ -11,9 +11,8 @@ #include "vxsort_targets_enable_avx2.h" #include -//#include #include - +#include #include "defs.h" #include "machine_traits.h" @@ -37,16 +36,24 @@ static void not_supported() // in _DEBUG, we #define return to be something more complicated, // containing a statement, so #define away constexpr for _DEBUG #define constexpr -#endif //_DEBUG +#endif //_DEBUG template <> class vxsort_machine_traits { public: + typedef int32_t T; typedef __m256i TV; typedef uint32_t TMASK; + typedef int32_t TPACK; + typedef typename std::make_unsigned::type TU; static constexpr bool supports_compress_writes() { return false; } + static constexpr bool supports_packing() { return false; } + + template + static constexpr bool can_pack(T span) { return false; } + static INLINE TV load_vec(TV* p) { return _mm256_lddqu_si256(p); } static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_si256(ptr, v); } @@ -56,7 +63,7 @@ class vxsort_machine_traits { static INLINE TV partition_vector(TV v, int mask) { assert(mask >= 0); assert(mask <= 255); - return s2i(_mm256_permutevar8x32_ps(i2s(v), _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)(perm_table_32 + mask * 8))))); + return s2i(_mm256_permutevar8x32_ps(i2s(v), _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(perm_table_32 + mask * 8))))); } static INLINE TV broadcast(int32_t pivot) { return _mm256_set1_epi32(pivot); } @@ -67,82 +74,47 @@ class vxsort_machine_traits { static INLINE TV add(TV a, TV b) { return _mm256_add_epi32(a, b); } static INLINE TV sub(TV a, TV b) { return _mm256_sub_epi32(a, b); }; -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m256i TV; - typedef uint32_t TMASK; - - static constexpr bool supports_compress_writes() { return false; } - - static INLINE TV load_vec(TV* p) { return _mm256_lddqu_si256(p); } - static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_si256(ptr, v); } - - static void store_compress_vec(TV* ptr, TV v, TMASK mask) { not_supported(); } + static INLINE TV pack_ordered(TV a, TV b) { return a; } + static INLINE TV pack_unordered(TV a, TV b) { return a; } + static INLINE void unpack_ordered(TV p, TV& u1, TV& u2) { } - static INLINE TV partition_vector(TV v, int mask) { - assert(mask >= 0); - assert(mask <= 255); - return s2i(_mm256_permutevar8x32_ps(i2s(v), _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)(perm_table_32 + mask * 8))))); + template + static T shift_n_sub(T v, T sub) { + if (Shift > 0) + v >>= Shift; + v -= sub; + return v; } - static INLINE TV broadcast(uint32_t pivot) { return _mm256_set1_epi32(pivot); } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - __m256i top_bit = _mm256_set1_epi32(1U << 31); - return _mm256_movemask_ps(i2s(_mm256_cmpgt_epi32(_mm256_xor_si256(top_bit, a), _mm256_xor_si256(top_bit, b)))); + template + static T unshift_and_add(TPACK from, T add) { + add += from; + if (Shift > 0) + add = (T) (((TU) add) << Shift); + return add; } - - static TV shift_right(TV v, int i) { return _mm256_srli_epi32(v, i); } - static TV shift_left(TV v, int i) { return _mm256_slli_epi32(v, i); } - - static INLINE TV add(TV a, TV b) { return _mm256_add_epi32(a, b); } - static INLINE TV sub(TV a, TV b) { return _mm256_sub_epi32(a, b); }; }; template <> -class vxsort_machine_traits { +class vxsort_machine_traits { public: - typedef __m256 TV; + typedef int64_t T; + typedef __m256i TV; typedef uint32_t TMASK; + typedef int32_t TPACK; + typedef typename std::make_unsigned::type TU; static constexpr bool supports_compress_writes() { return false; } - static INLINE TV load_vec(TV* p) { return _mm256_loadu_ps((float*)p); } + static constexpr bool supports_packing() { return true; } - static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_ps((float*)ptr, v); } - - static void store_compress_vec(TV* ptr, TV v, TMASK mask) { not_supported(); } - - static INLINE TV partition_vector(TV v, int mask) { - assert(mask >= 0); - assert(mask <= 255); - return _mm256_permutevar8x32_ps(v, _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)(perm_table_32 + mask * 8)))); - } - - static INLINE TV broadcast(float pivot) { return _mm256_set1_ps(pivot); } - - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - /// 0x0E: Greater-than (ordered, signaling) \n - /// 0x1E: Greater-than (ordered, non-signaling) - return _mm256_movemask_ps(_mm256_cmp_ps(a, b, _CMP_GT_OS)); + template + static constexpr bool can_pack(T span) { + const auto PACK_LIMIT = (((TU) std::numeric_limits::Max() + 1)) << Shift; + return ((TU) span) < PACK_LIMIT; } - static INLINE TV add(TV a, TV b) { return _mm256_add_ps(a, b); } - static INLINE TV sub(TV a, TV b) { return _mm256_sub_ps(a, b); }; - -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m256i TV; - typedef uint32_t TMASK; - - static constexpr bool supports_compress_writes() { return false; } - static INLINE TV load_vec(TV* p) { return _mm256_lddqu_si256(p); } static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_si256(ptr, v); } @@ -164,8 +136,6 @@ class vxsort_machine_traits { static INLINE TV add(TV a, TV b) { return _mm256_add_epi64(a, b); } static INLINE TV sub(TV a, TV b) { return _mm256_sub_epi64(a, b); }; - - static INLINE TV pack_ordered(TV a, TV b) { a = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(a, _MM_PERM_DBCA), _MM_PERM_DBCA); b = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(b, _MM_PERM_DBCA), _MM_PERM_CADB); @@ -177,106 +147,31 @@ class vxsort_machine_traits { return _mm256_blend_epi32(a, b, 0b10101010); } - static INLINE void unpack_ordered_signed(TV p, TV& u1, TV& u2) { + static INLINE void unpack_ordered(TV p, TV& u1, TV& u2) { auto p01 = _mm256_extracti128_si256(p, 0); auto p02 = _mm256_extracti128_si256(p, 1); u1 = _mm256_cvtepi32_epi64(p01); u2 = _mm256_cvtepi32_epi64(p02); - - } - - static INLINE void unpack_ordered_unsigned(TV p, TV& u1, TV& u2) { - auto p01 = _mm256_extracti128_si256(p, 0); - auto p02 = _mm256_extracti128_si256(p, 1); - - u1 = _mm256_cvtepu32_epi64(p01); - u2 = _mm256_cvtepu32_epi64(p02); - } -/* - template<> - static INLINE TV pack_ordered(TV a, TV b) { - a = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(a, _MM_PERM_DBCA), _MM_PERM_DBCA); - b = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(b, _MM_PERM_DBCA), _MM_PERM_CADB); - return _mm256_blend_epi32(a, b, 0b11110000); + template + static T shift_n_sub(T v, T sub) { + if (Shift > 0) + v >>= Shift; + v -= sub; + return v; } - template<> - static INLINE typename vxsort_machine_traits::TV pack_unordered(TV a, TV b) { - b = _mm256_shuffle_epi32(b, _MM_PERM_CDAB); - return _mm256_blend_epi32(a, b, 0b10101010); + template + static T unshift_and_add(TPACK from, T add) { + add += from; + if (Shift > 0) + add = (T) (((TU) add) << Shift); + return add; } - - */ - - - }; -template <> -class vxsort_machine_traits { - public: - typedef __m256i TV; - typedef uint32_t TMASK; - - static constexpr bool supports_compress_writes() { return false; } - - static INLINE TV load_vec(TV* p) { return _mm256_lddqu_si256(p); } - - static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_si256(ptr, v); } - - static void store_compress_vec(TV* ptr, TV v, TMASK mask) { not_supported(); } - - static INLINE TV partition_vector(TV v, int mask) { - assert(mask >= 0); - assert(mask <= 15); - return s2i(_mm256_permutevar8x32_ps(i2s(v), _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)(perm_table_64 + mask * 8))))); - } - static INLINE TV broadcast(int64_t pivot) { return _mm256_set1_epi64x(pivot); } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - __m256i top_bit = _mm256_set1_epi64x(1LLU << 63); - return _mm256_movemask_pd(i2d(_mm256_cmpgt_epi64(_mm256_xor_si256(top_bit, a), _mm256_xor_si256(top_bit, b)))); - } - - static INLINE TV shift_right(TV v, int i) { return _mm256_srli_epi64(v, i); } - static INLINE TV shift_left(TV v, int i) { return _mm256_slli_epi64(v, i); } - - static INLINE TV add(TV a, TV b) { return _mm256_add_epi64(a, b); } - static INLINE TV sub(TV a, TV b) { return _mm256_sub_epi64(a, b); }; -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m256d TV; - typedef uint32_t TMASK; - - static constexpr bool supports_compress_writes() { return false; } - - static INLINE TV load_vec(TV* p) { return _mm256_loadu_pd((double*)p); } - - static INLINE void store_vec(TV* ptr, TV v) { _mm256_storeu_pd((double*)ptr, v); } - - static void store_compress_vec(TV* ptr, TV v, TMASK mask) { not_supported(); } - - static INLINE TV partition_vector(TV v, int mask) { - assert(mask >= 0); - assert(mask <= 15); - return s2d(_mm256_permutevar8x32_ps(d2s(v), _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)(perm_table_64 + mask * 8))))); - } - - static INLINE TV broadcast(double pivot) { return _mm256_set1_pd(pivot); } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - /// 0x0E: Greater-than (ordered, signaling) \n - /// 0x1E: Greater-than (ordered, non-signaling) - return _mm256_movemask_pd(_mm256_cmp_pd(a, b, _CMP_GT_OS)); - } - - static INLINE TV add(TV a, TV b) { return _mm256_add_pd(a, b); } - static INLINE TV sub(TV a, TV b) { return _mm256_sub_pd(a, b); }; -}; } diff --git a/src/coreclr/src/gc/vxsort/machine_traits.avx512.h b/src/coreclr/src/gc/vxsort/machine_traits.avx512.h index 443654a39b60..8df8660aa13a 100644 --- a/src/coreclr/src/gc/vxsort/machine_traits.avx512.h +++ b/src/coreclr/src/gc/vxsort/machine_traits.avx512.h @@ -18,205 +18,137 @@ // in _DEBUG, we #define return to be something more complicated, // containing a statement, so #define away constexpr for _DEBUG #define constexpr -#endif //_DEBUG +#endif //_DEBUG namespace vxsort { template <> class vxsort_machine_traits { - public: - typedef __m512i TV; - typedef __mmask16 TMASK; - - static constexpr bool supports_compress_writes() { return true; } + public: + typedef int32_t T; + typedef __m512i TV; + typedef __mmask16 TMASK; + typedef int32_t TPACK; + typedef typename std::make_unsigned::type TU; - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_si512(p); - } + static constexpr bool supports_compress_writes() { return true; } - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_si512(ptr, v); - } + static constexpr bool supports_packing() { return false; } - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } + template + static constexpr bool can_pack(T span) { return false; } + static INLINE TV load_vec(TV* p) { return _mm512_loadu_si512(p); } - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_epi32(ptr, mask, v); - } + static INLINE void store_vec(TV* ptr, TV v) { _mm512_storeu_si512(ptr, v); } - static INLINE TV broadcast(int32_t pivot) { - return _mm512_set1_epi32(pivot); - } + // Will never be called + static INLINE TV partition_vector(TV v, int mask) { return v; } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_epi32_mask(a, b, _MM_CMPINT_GT); - } -}; + static void store_compress_vec(TV* ptr, TV v, TMASK mask) { _mm512_mask_compressstoreu_epi32(ptr, mask, v); } -template <> -class vxsort_machine_traits { - public: - typedef __m512i TV; - typedef __mmask16 TMASK; + static INLINE TV broadcast(int32_t pivot) { return _mm512_set1_epi32(pivot); } - static constexpr bool supports_compress_writes() { return true; } + static INLINE TMASK get_cmpgt_mask(TV a, TV b) { return _mm512_cmp_epi32_mask(a, b, _MM_CMPINT_GT); } - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_si512(p); - } + static TV shift_right(TV v, int i) { return _mm512_srli_epi32(v, i); } + static TV shift_left(TV v, int i) { return _mm512_slli_epi32(v, i); } - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_si512(ptr, v); - } + static INLINE TV add(TV a, TV b) { return _mm512_add_epi32(a, b); } + static INLINE TV sub(TV a, TV b) { return _mm512_sub_epi32(a, b); }; - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } + static INLINE TV pack_ordered(TV a, TV b) { return a; } + static INLINE TV pack_unordered(TV a, TV b) { return a; } + static INLINE void unpack_ordered(TV p, TV& u1, TV& u2) { } + template + static T shift_n_sub(T v, T sub) { + if (Shift > 0) + v >>= Shift; + v -= sub; + return v; + } - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_epi32(ptr, mask, v); - } - - static INLINE TV broadcast(uint32_t pivot) { - return _mm512_set1_epi32(pivot); - } - - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_epu32_mask(a, b, _MM_CMPINT_GT); - } -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m512 TV; - typedef __mmask16 TMASK; - - static constexpr bool supports_compress_writes() { return true; } - - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_ps(p); - } - - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_ps(ptr, v); - } - - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } - - - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_ps(ptr, mask, v); - } - - static INLINE TV broadcast(float pivot) { - return _mm512_set1_ps(pivot); - } - - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_ps_mask(a, b, _CMP_GT_OS); - } + template + static T unshift_and_add(TPACK from, T add) { + add += from; + if (Shift > 0) + add = (T) (((TU) add) << Shift); + return add; + } }; template <> class vxsort_machine_traits { - public: - typedef __m512i TV; - typedef __mmask8 TMASK; - - static bool supports_compress_writes() { return true; } + public: + typedef int64_t T; + typedef __m512i TV; + typedef __mmask8 TMASK; + typedef int32_t TPACK; + typedef typename std::make_unsigned::type TU; - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_si512(p); - } + static constexpr bool supports_compress_writes() { return true; } - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_si512(ptr, v); - } + static constexpr bool supports_packing() { return true; } - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } + template + static constexpr bool can_pack(T span) { + const auto PACK_LIMIT = (((TU) std::numeric_limits::Max() + 1)) << Shift; + return ((TU) span) < PACK_LIMIT; + } + static INLINE TV load_vec(TV* p) { return _mm512_loadu_si512(p); } - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_epi64(ptr, mask, v); - } + static INLINE void store_vec(TV* ptr, TV v) { _mm512_storeu_si512(ptr, v); } - static INLINE TV broadcast(int64_t pivot) { - return _mm512_set1_epi64(pivot); - } + // Will never be called + static INLINE TV partition_vector(TV v, int mask) { return v; } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_epi64_mask(a, b, _MM_CMPINT_GT); - } -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m512i TV; - typedef __mmask8 TMASK; + static void store_compress_vec(TV* ptr, TV v, TMASK mask) { _mm512_mask_compressstoreu_epi64(ptr, mask, v); } - static constexpr bool supports_compress_writes() { return true; } + static INLINE TV broadcast(int64_t pivot) { return _mm512_set1_epi64(pivot); } - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_si512(p); - } + static INLINE TMASK get_cmpgt_mask(TV a, TV b) { return _mm512_cmp_epi64_mask(a, b, _MM_CMPINT_GT); } - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_si512(ptr, v); - } + static TV shift_right(TV v, int i) { return _mm512_srli_epi64(v, i); } + static TV shift_left(TV v, int i) { return _mm512_slli_epi64(v, i); } - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } + static INLINE TV add(TV a, TV b) { return _mm512_add_epi64(a, b); } + static INLINE TV sub(TV a, TV b) { return _mm512_sub_epi64(a, b); }; + static INLINE TV pack_ordered(TV a, TV b) { + a = _mm512_permutex_epi64(_mm512_shuffle_epi32(a, _MM_PERM_DBCA), _MM_PERM_DBCA); + b = _mm512_permutex_epi64(_mm512_shuffle_epi32(b, _MM_PERM_DBCA), _MM_PERM_CADB); + return _mm512_shuffle_i64x2(a, b, _MM_PERM_DBCA); + } - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_epi64(ptr, mask, v); - } - - static INLINE TV broadcast(uint64_t pivot) { - return _mm512_set1_epi64(pivot); - } - - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_epu64_mask(a, b, _MM_CMPINT_GT); - } -}; - -template <> -class vxsort_machine_traits { - public: - typedef __m512d TV; - typedef __mmask8 TMASK; - - static constexpr bool supports_compress_writes() { return true; } + static INLINE TV pack_unordered(TV a, TV b) { return _mm512_mask_shuffle_epi32(a, 0b1010101010101010, b, _MM_PERM_CDAB); } - static INLINE TV load_vec(TV* p) { - return _mm512_loadu_pd(p); - } + static INLINE void unpack_ordered(TV p, TV& u1, TV& u2) { + auto p01 = _mm512_extracti32x8_epi32(p, 0); + auto p02 = _mm512_extracti32x8_epi32(p, 1); - static INLINE void store_vec(TV* ptr, TV v) { - _mm512_storeu_pd(ptr, v); - } + u1 = _mm512_cvtepi32_epi64(p01); + u2 = _mm512_cvtepi32_epi64(p02); + } - // Will never be called - static INLINE TV partition_vector(TV v, int mask) { return v; } + template + static T shift_n_sub(T v, T sub) { + if (Shift > 0) + v >>= Shift; + v -= sub; + return v; + } + template + static T unshift_and_add(TPACK from, T add) { + add += from; - static void store_compress_vec(TV *ptr, TV v, TMASK mask) { - _mm512_mask_compressstoreu_pd(ptr, mask, v); - } + if (Shift > 0) + add = (T) (((TU) add) << Shift); - static INLINE TV broadcast(double pivot) { - return _mm512_set1_pd(pivot); - } + return add; + } - static INLINE TMASK get_cmpgt_mask(TV a, TV b) { - return _mm512_cmp_pd_mask(a, b, _CMP_GT_OS); - } }; } diff --git a/src/coreclr/src/gc/vxsort/machine_traits.h b/src/coreclr/src/gc/vxsort/machine_traits.h index cd31ed365777..7862d4b0d9ea 100644 --- a/src/coreclr/src/gc/vxsort/machine_traits.h +++ b/src/coreclr/src/gc/vxsort/machine_traits.h @@ -8,8 +8,6 @@ #ifndef VXSORT_MACHINE_TRAITS_H #define VXSORT_MACHINE_TRAITS_H -//#include - namespace vxsort { enum vector_machine { @@ -22,14 +20,35 @@ enum vector_machine { template struct vxsort_machine_traits { public: - typedef int TV; - typedef int TMASK; + typedef T TV; + typedef T TMASK; + typedef T TPACK; + + static constexpr bool supports_compress_writes() { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + return false; + } + + static constexpr bool supports_packing() { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + return false; + } - static constexpr bool supports_compress_writes(); + template + static constexpr bool can_pack(T span) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + return false; + } - static TV load_vec(TV* ptr); - static void store_vec(TV* ptr, TV v); - static void store_compress_vec(TV* ptr, TV v, TMASK mask); + static TV load_vec(TV* ptr) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + } + static void store_vec(TV* ptr, TV v) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + } + static void store_compress_vec(TV* ptr, TV v, TMASK mask) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + } static TV partition_vector(TV v, int mask); static TV broadcast(T pivot); static TMASK get_cmpgt_mask(TV a, TV b); @@ -43,11 +62,25 @@ struct vxsort_machine_traits { static TV pack_ordered(TV a, TV b); static TV pack_unordered(TV a, TV b); - static void unpack_ordered_signed(TV p, TV& u1, TV& u2); - static void unpack_ordered_unsigned(TV p, TV& u1, TV& u2); + static void unpack_ordered(TV p, TV& u1, TV& u2) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + } + template + static T shift_n_sub(T v, T sub) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + return v; + } + template + static T unshift_and_add(TPACK from, T add) { + static_assert(sizeof(TV) != sizeof(TV), "func must be specialized!"); + return add; + } }; + } + + #endif // VXSORT_MACHINE_TRAITS_H diff --git a/src/coreclr/src/gc/vxsort/packer.h b/src/coreclr/src/gc/vxsort/packer.h index 4c7257a58f17..be50b7d5fb41 100644 --- a/src/coreclr/src/gc/vxsort/packer.h +++ b/src/coreclr/src/gc/vxsort/packer.h @@ -4,196 +4,259 @@ #ifndef VXSORT_PACKER_H #define VXSORT_PACKER_H -#include "vxsort_targets_enable_avx2.h" - -//#include -//#include -//#include -#//include +#include "defs.h" #include "alignment.h" #include "machine_traits.h" -#include "machine_traits.avx2.h" -#include "machine_traits.avx512.h" #include -//#include namespace vxsort { -template +template class packer { - static_assert(Shift <= 31, "Shift must be in the range 0..31"); - using MT = vxsort_machine_traits; - typedef typename MT::TV TV; - typedef typename std::make_unsigned::type TU; - static const int N = sizeof(TV) / sizeof(TFrom); - typedef alignment_hint AH; - - static const size_t ALIGN = AH::ALIGN; - static const size_t ALIGN_MASK = ALIGN - 1; - - static INLINE void pack_scalar(const TFrom offset, TFrom*& mem_read, TTo*& mem_write) { - auto d = *(mem_read++); - if (Shift > 0) - d >>= Shift; - d -= offset; - *(mem_write++) = (TTo) d; - } - - static INLINE void unpack_scalar(const TFrom offset, TTo*& mem_read, TFrom*& mem_write) { - TFrom d = *(--mem_read); - - d += offset; - - if (Shift > 0) - d = (TFrom) (((TU) d) << Shift); - - *(--mem_write) = d; - } - - public: - - static void pack(TFrom *mem, size_t len, TFrom base) { - TFrom offset = (base >> Shift) - std::numeric_limits::Min(); - auto baseVec = MT::broadcast(offset); - - auto pre_aligned_mem = reinterpret_cast(reinterpret_cast(mem) & ~ALIGN_MASK); - - auto mem_read = mem; - auto mem_write = (TTo *) mem; - - // Include a "special" pass to handle very short scalar - // passes - if (MinLength < N && len < N) { - while (len--) { - pack_scalar(offset, mem_read, mem_write); - } - return; + static_assert(Shift <= 31, "Shift must be in the range 0..31"); + static_assert(Unroll >= 1, "Unroll can be in the range 1..4"); + static_assert(Unroll <= 4, "Unroll can be in the range 1..4"); + + using MT = vxsort_machine_traits; + typedef typename MT::TV TV; + static const int N = sizeof(TV) / sizeof(TFrom); + typedef alignment_hint AH; + + static const size_t ALIGN = AH::ALIGN; + static const size_t ALIGN_MASK = ALIGN - 1; + + + static INLINE TV pack_vectorized(const TV baseVec, TV d01, TV d02) { + if (Shift > 0) { // This is statically compiled in/out + d01 = MT::shift_right(d01, Shift); + d02 = MT::shift_right(d02, Shift); + } + d01 = MT::sub(d01, baseVec); + d02 = MT::sub(d02, baseVec); + + auto packed_data = RespectPackingOrder ? + MT::pack_ordered(d01, d02) : + MT::pack_unordered(d01, d02); + return packed_data; } - // We have at least - // one vector worth of data to handle - // Let's try to align to vector size first - - if (pre_aligned_mem < mem) { - const auto alignment_point = pre_aligned_mem + N; - len -= (alignment_point - mem_read); - while (mem_read < alignment_point) { - pack_scalar(offset, mem_read, mem_write); - } - } - - assert(AH::is_aligned(mem_read)); - - auto memv_read = (TV *) mem_read; - auto memv_write = (TV *) mem_write; + static NOINLINE void unpack_vectorized(const TV baseVec, TV d01, TV& u01, TV& u02) { + MT::unpack_ordered(d01, u01, u02); - auto lenv = len / N; - len -= (lenv * N); + u01 = MT::add(u01, baseVec); + u02 = MT::add(u02, baseVec); - while (lenv >= 2) { - assert(memv_read >= memv_write); - - auto d01 = MT::load_vec(memv_read); - auto d02 = MT::load_vec(memv_read + 1); - if (Shift > 0) { // This is statically compiled in/out - d01 = MT::shift_right(d01, Shift); - d02 = MT::shift_right(d02, Shift); - } - d01 = MT::sub(d01, baseVec); - d02 = MT::sub(d02, baseVec); - - auto packed_data = RespectPackingOrder ? - MT::pack_ordered(d01, d02) : - MT::pack_unordered(d01, d02); - - MT::store_vec(memv_write, packed_data); - - memv_read += 2; - memv_write++; - lenv -= 2; + if (Shift > 0) { // This is statically compiled in/out + u01 = MT::shift_left(u01, Shift); + u02 = MT::shift_left(u02, Shift); + } } - len += lenv * N; - - mem_read = (TFrom *) memv_read; - mem_write = (TTo *) memv_write; - - while (len-- > 0) { - pack_scalar(offset, mem_read, mem_write); - } - } - - static void unpack(TTo *mem, size_t len, TFrom base) { - TFrom offset = (base >> Shift) - std::numeric_limits::Min(); - auto baseVec = MT::broadcast(offset); - - auto mem_read = mem + len; - auto mem_write = ((TFrom *) mem) + len; - - - // Include a "special" pass to handle very short scalar - // passers - if (MinLength < 2*N && len < 2*N) { - while (len--) { - unpack_scalar(offset, mem_read, mem_write); - } - return; - } - - auto pre_aligned_mem = reinterpret_cast(reinterpret_cast(mem_read) & ~ALIGN_MASK); - - if (pre_aligned_mem < mem_read) { - len -= (mem_read - pre_aligned_mem); - while (mem_read > pre_aligned_mem) { - unpack_scalar(offset, mem_read, mem_write); - } - } - - assert(AH::is_aligned(mem_read)); - - auto lenv = len / (N*2); - auto memv_read = ((TV *) mem_read) - 1; - auto memv_write = ((TV *) mem_write) - 2; - len -= lenv * N * 2; - - while (lenv > 0) { - assert(memv_read <= memv_write); - TV d01, d02; - - if (std::numeric_limits::Min() < 0) - MT::unpack_ordered_signed(MT::load_vec(memv_read), d01, d02); - else - MT::unpack_ordered_unsigned(MT::load_vec(memv_read), d01, d02); - - d01 = MT::add(d01, baseVec); - d02 = MT::add(d02, baseVec); - - if (Shift > 0) { // This is statically compiled in/out - d01 = MT::shift_left(d01, Shift); - d02 = MT::shift_left(d02, Shift); - } - - MT::store_vec(memv_write, d01); - MT::store_vec(memv_write + 1, d02); - - memv_read -= 1; - memv_write -= 2; - lenv--; + public: + + static void pack(TFrom *mem, size_t len, TFrom base) { + TFrom offset = MT::template shift_n_sub(base, (TFrom) std::numeric_limits::Min()); + auto baseVec = MT::broadcast(offset); + + auto pre_aligned_mem = reinterpret_cast(reinterpret_cast(mem) & ~ALIGN_MASK); + + auto mem_read = mem; + auto mem_write = (TTo *) mem; + + // Include a "special" pass to handle very short scalar + // passes + if (MinLength < N && len < N) { + while (len--) { + *(mem_write++) = (TTo) MT::template shift_n_sub(*(mem_read++), offset); + } + return; + } + + // We have at least + // one vector worth of data to handle + // Let's try to align to vector size first + + if (pre_aligned_mem < mem) { + const auto alignment_point = pre_aligned_mem + N; + len -= (alignment_point - mem_read); + while (mem_read < alignment_point) { + *(mem_write++) = (TTo) MT::template shift_n_sub(*(mem_read++), offset); + } + } + + assert(AH::is_aligned(mem_read)); + + auto memv_read = (TV *) mem_read; + auto memv_write = (TV *) mem_write; + + auto lenv = len / N; + len -= (lenv * N); + + while (lenv >= 2 * Unroll) { + assert(memv_read >= memv_write); + + TV d01, d02, d03, d04, d05, d06, d07, d08; + + do { + d01 = MT::load_vec(memv_read + 0); + d02 = MT::load_vec(memv_read + 1); + if (Unroll == 1) break; + d03 = MT::load_vec(memv_read + 2); + d04 = MT::load_vec(memv_read + 3); + if (Unroll == 2) break; + d05 = MT::load_vec(memv_read + 4); + d06 = MT::load_vec(memv_read + 5); + if (Unroll == 3) break; + d07 = MT::load_vec(memv_read + 6); + d08 = MT::load_vec(memv_read + 7); + break; + } while (true); + + do { + MT::store_vec(memv_write + 0, pack_vectorized(baseVec, d01, d02)); + if (Unroll == 1) break; + MT::store_vec(memv_write + 1, pack_vectorized(baseVec, d03, d04)); + if (Unroll == 2) break; + MT::store_vec(memv_write + 2, pack_vectorized(baseVec, d05, d06)); + if (Unroll == 3) break; + MT::store_vec(memv_write + 3, pack_vectorized(baseVec, d07, d08)); + break; + } while(true); + + memv_read += 2*Unroll; + memv_write += Unroll; + lenv -= 2*Unroll; + } + + if (Unroll > 1) { + while (lenv >= 2) { + assert(memv_read >= memv_write); + TV d01, d02; + + d01 = MT::load_vec(memv_read + 0); + d02 = MT::load_vec(memv_read + 1); + + MT::store_vec(memv_write + 0, pack_vectorized(baseVec, d01, d02)); + memv_read += 2; + memv_write++; + lenv -= 2; + } + } + + len += lenv * N; + + mem_read = (TFrom *) memv_read; + mem_write = (TTo *) memv_write; + + while (len-- > 0) { + *(mem_write++) = (TTo) MT::template shift_n_sub(*(mem_read++), offset); + } } - mem_read = (TTo *) (memv_read + 1); - mem_write = (TFrom *) (memv_write + 2); - while (len-- > 0) { - unpack_scalar(offset, mem_read, mem_write); + static void unpack(TTo *mem, size_t len, TFrom base) { + TFrom offset = MT::template shift_n_sub(base, (TFrom) std::numeric_limits::Min()); + auto baseVec = MT::broadcast(offset); + + auto mem_read = mem + len; + auto mem_write = ((TFrom *) mem) + len; + + + // Include a "special" pass to handle very short scalar + // passers + if (MinLength < 2 * N && len < 2 * N) { + while (len--) { + *(--mem_write) = MT::template unshift_and_add(*(--mem_read), offset); + } + return; + } + + auto pre_aligned_mem = reinterpret_cast(reinterpret_cast(mem_read) & ~ALIGN_MASK); + + if (pre_aligned_mem < mem_read) { + len -= (mem_read - pre_aligned_mem); + while (mem_read > pre_aligned_mem) { + *(--mem_write) = MT::template unshift_and_add(*(--mem_read), offset); + } + } + + assert(AH::is_aligned(mem_read)); + + auto lenv = len / (N * 2); + auto memv_read = ((TV *) mem_read) - 1; + auto memv_write = ((TV *) mem_write) - 2; + len -= lenv * N * 2; + + while (lenv >= Unroll) { + assert(memv_read <= memv_write); + + TV d01, d02, d03, d04; + TV u01, u02, u03, u04, u05, u06, u07, u08; + + do { + d01 = MT::load_vec(memv_read + 0); + if (Unroll == 1) break; + d02 = MT::load_vec(memv_read - 1); + if (Unroll == 2) break; + d03 = MT::load_vec(memv_read - 2); + if (Unroll == 3) break; + d04 = MT::load_vec(memv_read - 3); + break; + } while(true); + + do { + unpack_vectorized(baseVec, d01, u01, u02); + MT::store_vec(memv_write + 0, u01); + MT::store_vec(memv_write + 1, u02); + if (Unroll == 1) break; + unpack_vectorized(baseVec, d02, u03, u04); + MT::store_vec(memv_write - 2, u03); + MT::store_vec(memv_write - 1, u04); + if (Unroll == 2) break; + unpack_vectorized(baseVec, d03, u05, u06); + MT::store_vec(memv_write - 4, u05); + MT::store_vec(memv_write - 3, u06); + if (Unroll == 3) break; + unpack_vectorized(baseVec, d04, u07, u08); + MT::store_vec(memv_write - 6, u07); + MT::store_vec(memv_write - 5, u08); + break; + } while(true); + + memv_read -= Unroll; + memv_write -= 2 * Unroll; + lenv -= Unroll; + } + + if (Unroll > 1) { + while (lenv >= 1) { + assert(memv_read <= memv_write); + + TV d01; + TV u01, u02; + + d01 = MT::load_vec(memv_read + 0); + + unpack_vectorized(baseVec, d01, u01, u02); + MT::store_vec(memv_write + 0, u01); + MT::store_vec(memv_write + 1, u02); + + memv_read--; + memv_write -= 2; + lenv--; + } + } + + mem_read = (TTo *) (memv_read + 1); + mem_write = (TFrom *) (memv_write + 2); + + while (len-- > 0) { + *(--mem_write) = MT::template unshift_and_add(*(--mem_read), offset); + } } - } }; - } -#include "vxsort_targets_disable.h" - #endif // VXSORT_PACKER_H diff --git a/src/coreclr/src/gc/vxsort/smallsort/avx2_load_mask_tables.cpp b/src/coreclr/src/gc/vxsort/smallsort/avx2_load_mask_tables.cpp new file mode 100644 index 000000000000..8f2f24f7d5c1 --- /dev/null +++ b/src/coreclr/src/gc/vxsort/smallsort/avx2_load_mask_tables.cpp @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" + +#include "bitonic_sort.h" + +namespace vxsort { + namespace smallsort { + + extern "C" alignas(16) const uint8_t mask_table_4[M4_SIZE] = { + 0xFF, 0xFF, 0xFF, 0xFF, // 0b0000 (0) + 0xFF, 0x00, 0x00, 0x00, // 0b0001 (1) + 0xFF, 0xFF, 0x00, 0x00, // 0b0011 (3) + 0xFF, 0xFF, 0xFF, 0x00, // 0b0111 (7) + #if defined(__has_feature) + #if __has_feature(address_sanitizer) + 0xCC, 0xCC, 0xCC, 0xCC, // Garbage to make ASAN happy + 0xCC, 0xCC, 0xCC, 0xCC, // Garbage to make ASAN happy + 0xCC, 0xCC, 0xCC, 0xCC, // Garbage to make ASAN happy + #endif + #endif + }; + + extern "C" alignas(128) const uint8_t mask_table_8[M8_SIZE] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0b00000000 ( 0) + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0b00000001 ( 1) + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0b00000011 ( 3) + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 0b00000111 ( 7) + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // 0b00001111 ( 15) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, // 0b00011111 ( 31) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, // 0b00111111 ( 63) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, // 0b01111111 (127) + #if defined(__has_feature) + #if __has_feature(address_sanitizer) + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // Garbage to make ASAN happy + #endif + #endif + }; + } +} diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp index 17ddcd815057..b72cecf4536c 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp @@ -7,24 +7,25 @@ using namespace vxsort; void vxsort::smallsort::bitonic::sort(int32_t *ptr, size_t length) { - const int N = 8; - - switch(length / N) { - case 1: sort_01v(ptr); break; - case 2: sort_02v(ptr); break; - case 3: sort_03v(ptr); break; - case 4: sort_04v(ptr); break; - case 5: sort_05v(ptr); break; - case 6: sort_06v(ptr); break; - case 7: sort_07v(ptr); break; - case 8: sort_08v(ptr); break; - case 9: sort_09v(ptr); break; - case 10: sort_10v(ptr); break; - case 11: sort_11v(ptr); break; - case 12: sort_12v(ptr); break; - case 13: sort_13v(ptr); break; - case 14: sort_14v(ptr); break; - case 15: sort_15v(ptr); break; - case 16: sort_16v(ptr); break; + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) { + case 1: sort_01v_alt(ptr, remainder); break; + case 2: sort_02v_alt(ptr, remainder); break; + case 3: sort_03v_alt(ptr, remainder); break; + case 4: sort_04v_alt(ptr, remainder); break; + case 5: sort_05v_alt(ptr, remainder); break; + case 6: sort_06v_alt(ptr, remainder); break; + case 7: sort_07v_alt(ptr, remainder); break; + case 8: sort_08v_alt(ptr, remainder); break; + case 9: sort_09v_alt(ptr, remainder); break; + case 10: sort_10v_alt(ptr, remainder); break; + case 11: sort_11v_alt(ptr, remainder); break; + case 12: sort_12v_alt(ptr, remainder); break; + case 13: sort_13v_alt(ptr, remainder); break; + case 14: sort_14v_alt(ptr, remainder); break; + case 15: sort_15v_alt(ptr, remainder); break; + case 16: sort_16v_alt(ptr, remainder); break; } } diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.h b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.h index 79bdbcc870d4..8557cf462033 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.h +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.h @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////////////// //// -// This file was auto-generated by a tool at 2020-06-22 05:27:48 +// This file was auto-generated by a tool at 2020-07-21 14:05:39 // // It is recommended you DO NOT directly edit this file but instead edit // the code-generator that generated this source file instead. @@ -33,7 +33,13 @@ namespace vxsort { namespace smallsort { + +extern "C" const uint8_t mask_table_4[16]; +extern "C" const uint8_t mask_table_8[64]; + template<> struct bitonic { + static const int N = 8; + static constexpr int32_t MAX = std::numeric_limits::Max(); public: static INLINE void sort_01v_ascending(__m256i& d01) { @@ -252,7 +258,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_01v_merge_descending(d03); } - static INLINE void sort_04v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp; sort_02v_ascending(d01, d02); @@ -271,7 +277,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp; sort_02v_descending(d01, d02); @@ -290,7 +296,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_02v_merge_descending(d03, d04); } - static INLINE void sort_04v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp; tmp = d01; @@ -308,7 +314,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp; tmp = d01; @@ -548,7 +554,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_03v_merge_descending(d05, d06, d07); } - static INLINE void sort_08v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp; sort_04v_ascending(d01, d02, d03, d04); @@ -577,7 +583,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp; sort_04v_descending(d01, d02, d03, d04); @@ -606,7 +612,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_04v_merge_descending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp; tmp = d01; @@ -636,7 +642,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp; tmp = d01; @@ -780,7 +786,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_03v_merge_descending(d09, d10, d11); } - static INLINE void sort_12v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { + static NOINLINE void sort_12v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { __m256i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -809,7 +815,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_04v_merge_ascending(d09, d10, d11, d12); } - static INLINE void sort_12v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { + static NOINLINE void sort_12v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { __m256i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1072,7 +1078,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_07v_merge_descending(d09, d10, d11, d12, d13, d14, d15); } - static INLINE void sort_16v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { + static NOINLINE void sort_16v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { __m256i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1121,7 +1127,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_08v_merge_ascending(d09, d10, d11, d12, d13, d14, d15, d16); } - static INLINE void sort_16v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { + static NOINLINE void sort_16v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { __m256i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1171,80 +1177,94 @@ template<> struct bitonic { sort_08v_merge_descending(d09, d10, d11, d12, d13, d14, d15, d16); } - static NOINLINE void sort_01v(int32_t *ptr) { - __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; + static NOINLINE void sort_01v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); + + __m256i d01 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 0), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_01v_ascending(d01); - _mm256_storeu_si256((__m256i *) ptr + 0, d01); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 0), mask, d01); + } + + static NOINLINE void sort_02v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_02v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; - __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; + __m256i d02 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 1), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_02v_ascending(d01, d02); _mm256_storeu_si256((__m256i *) ptr + 0, d01); - _mm256_storeu_si256((__m256i *) ptr + 1, d02); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 1), mask, d02); + } + + static NOINLINE void sort_03v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_03v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; - __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; + __m256i d03 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 2), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_03v_ascending(d01, d02, d03); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); - _mm256_storeu_si256((__m256i *) ptr + 2, d03); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 2), mask, d03); + } + + static NOINLINE void sort_04v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_04v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; - __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; + __m256i d04 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 3), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_04v_ascending(d01, d02, d03, d04); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); - _mm256_storeu_si256((__m256i *) ptr + 3, d04); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 3), mask, d04); + } + + static NOINLINE void sort_05v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_05v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; - __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; + __m256i d05 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 4), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_05v_ascending(d01, d02, d03, d04, d05); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); _mm256_storeu_si256((__m256i *) ptr + 3, d04); - _mm256_storeu_si256((__m256i *) ptr + 4, d05); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 4), mask, d05); + } + + static NOINLINE void sort_06v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_06v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; - __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; + __m256i d06 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 5), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_06v_ascending(d01, d02, d03, d04, d05, d06); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); _mm256_storeu_si256((__m256i *) ptr + 3, d04); _mm256_storeu_si256((__m256i *) ptr + 4, d05); - _mm256_storeu_si256((__m256i *) ptr + 5, d06); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 5), mask, d06); + } + + static NOINLINE void sort_07v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_07v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; - __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; + __m256i d07 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 6), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_07v_ascending(d01, d02, d03, d04, d05, d06, d07); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1252,10 +1272,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 3, d04); _mm256_storeu_si256((__m256i *) ptr + 4, d05); _mm256_storeu_si256((__m256i *) ptr + 5, d06); - _mm256_storeu_si256((__m256i *) ptr + 6, d07); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 6), mask, d07); + } + + static NOINLINE void sort_08v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_08v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1263,7 +1285,7 @@ template<> struct bitonic { __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; - __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; + __m256i d08 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 7), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1272,10 +1294,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 4, d05); _mm256_storeu_si256((__m256i *) ptr + 5, d06); _mm256_storeu_si256((__m256i *) ptr + 6, d07); - _mm256_storeu_si256((__m256i *) ptr + 7, d08); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 7), mask, d08); + } + + static NOINLINE void sort_09v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_09v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1284,7 +1308,7 @@ template<> struct bitonic { __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; - __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; + __m256i d09 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 8), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_09v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1294,10 +1318,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 5, d06); _mm256_storeu_si256((__m256i *) ptr + 6, d07); _mm256_storeu_si256((__m256i *) ptr + 7, d08); - _mm256_storeu_si256((__m256i *) ptr + 8, d09); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 8), mask, d09); + } + + static NOINLINE void sort_10v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_10v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1307,7 +1333,7 @@ template<> struct bitonic { __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; - __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; + __m256i d10 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 9), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_10v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1318,10 +1344,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 6, d07); _mm256_storeu_si256((__m256i *) ptr + 7, d08); _mm256_storeu_si256((__m256i *) ptr + 8, d09); - _mm256_storeu_si256((__m256i *) ptr + 9, d10); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 9), mask, d10); + } + + static NOINLINE void sort_11v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_11v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1332,7 +1360,7 @@ template<> struct bitonic { __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; - __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; + __m256i d11 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 10), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_11v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1344,10 +1372,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 7, d08); _mm256_storeu_si256((__m256i *) ptr + 8, d09); _mm256_storeu_si256((__m256i *) ptr + 9, d10); - _mm256_storeu_si256((__m256i *) ptr + 10, d11); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 10), mask, d11); + } + + static NOINLINE void sort_12v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_12v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1359,7 +1389,7 @@ template<> struct bitonic { __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; - __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; + __m256i d12 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 11), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_12v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1372,10 +1402,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 8, d09); _mm256_storeu_si256((__m256i *) ptr + 9, d10); _mm256_storeu_si256((__m256i *) ptr + 10, d11); - _mm256_storeu_si256((__m256i *) ptr + 11, d12); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 11), mask, d12); + } + + static NOINLINE void sort_13v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_13v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1388,7 +1420,7 @@ template<> struct bitonic { __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; - __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; + __m256i d13 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 12), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_13v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1402,10 +1434,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 9, d10); _mm256_storeu_si256((__m256i *) ptr + 10, d11); _mm256_storeu_si256((__m256i *) ptr + 11, d12); - _mm256_storeu_si256((__m256i *) ptr + 12, d13); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 12), mask, d13); + } + + static NOINLINE void sort_14v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_14v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1419,7 +1453,7 @@ template<> struct bitonic { __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; - __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; + __m256i d14 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 13), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_14v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1434,10 +1468,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 10, d11); _mm256_storeu_si256((__m256i *) ptr + 11, d12); _mm256_storeu_si256((__m256i *) ptr + 12, d13); - _mm256_storeu_si256((__m256i *) ptr + 13, d14); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 13), mask, d14); + } + + static NOINLINE void sort_15v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_15v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1452,7 +1488,7 @@ template<> struct bitonic { __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; - __m256i d15 = _mm256_lddqu_si256((__m256i const *) ptr + 14);; + __m256i d15 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 14), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_15v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1468,10 +1504,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 11, d12); _mm256_storeu_si256((__m256i *) ptr + 12, d13); _mm256_storeu_si256((__m256i *) ptr + 13, d14); - _mm256_storeu_si256((__m256i *) ptr + 14, d15); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 14), mask, d15); + } + + static NOINLINE void sort_16v_alt(int32_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N))); - static NOINLINE void sort_16v(int32_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1487,7 +1525,7 @@ template<> struct bitonic { __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; __m256i d15 = _mm256_lddqu_si256((__m256i const *) ptr + 14);; - __m256i d16 = _mm256_lddqu_si256((__m256i const *) ptr + 15);; + __m256i d16 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 15), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX))); sort_16v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15, d16); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1504,8 +1542,8 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 12, d13); _mm256_storeu_si256((__m256i *) ptr + 13, d14); _mm256_storeu_si256((__m256i *) ptr + 14, d15); - _mm256_storeu_si256((__m256i *) ptr + 15, d16); -} + _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 15), mask, d16); + } static void sort(int32_t *ptr, size_t length); }; diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.cpp b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.cpp index 00360ae70f0c..b74e0d5c2671 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.cpp +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.cpp @@ -7,24 +7,25 @@ using namespace vxsort; void vxsort::smallsort::bitonic::sort(int64_t *ptr, size_t length) { - const int N = 4; - - switch(length / N) { - case 1: sort_01v(ptr); break; - case 2: sort_02v(ptr); break; - case 3: sort_03v(ptr); break; - case 4: sort_04v(ptr); break; - case 5: sort_05v(ptr); break; - case 6: sort_06v(ptr); break; - case 7: sort_07v(ptr); break; - case 8: sort_08v(ptr); break; - case 9: sort_09v(ptr); break; - case 10: sort_10v(ptr); break; - case 11: sort_11v(ptr); break; - case 12: sort_12v(ptr); break; - case 13: sort_13v(ptr); break; - case 14: sort_14v(ptr); break; - case 15: sort_15v(ptr); break; - case 16: sort_16v(ptr); break; + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) { + case 1: sort_01v_alt(ptr, remainder); break; + case 2: sort_02v_alt(ptr, remainder); break; + case 3: sort_03v_alt(ptr, remainder); break; + case 4: sort_04v_alt(ptr, remainder); break; + case 5: sort_05v_alt(ptr, remainder); break; + case 6: sort_06v_alt(ptr, remainder); break; + case 7: sort_07v_alt(ptr, remainder); break; + case 8: sort_08v_alt(ptr, remainder); break; + case 9: sort_09v_alt(ptr, remainder); break; + case 10: sort_10v_alt(ptr, remainder); break; + case 11: sort_11v_alt(ptr, remainder); break; + case 12: sort_12v_alt(ptr, remainder); break; + case 13: sort_13v_alt(ptr, remainder); break; + case 14: sort_14v_alt(ptr, remainder); break; + case 15: sort_15v_alt(ptr, remainder); break; + case 16: sort_16v_alt(ptr, remainder); break; } } diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.h b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.h index 5e9d2fea0dcf..475fac681b1b 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.h +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.h @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////////////// //// -// This file was auto-generated by a tool at 2020-06-22 05:27:48 +// This file was auto-generated by a tool at 2020-07-21 14:05:39 // // It is recommended you DO NOT directly edit this file but instead edit // the code-generator that generated this source file instead. @@ -33,7 +33,13 @@ namespace vxsort { namespace smallsort { + +extern "C" const uint8_t mask_table_4[16]; +extern "C" const uint8_t mask_table_8[64]; + template<> struct bitonic { + static const int N = 4; + static constexpr int64_t MAX = std::numeric_limits::Max(); public: static INLINE void sort_01v_ascending(__m256i& d01) { @@ -212,7 +218,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_01v_merge_descending(d03); } - static INLINE void sort_04v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp, cmp; sort_02v_ascending(d01, d02); @@ -231,7 +237,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp, cmp; sort_02v_descending(d01, d02); @@ -250,7 +256,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_02v_merge_descending(d03, d04); } - static INLINE void sort_04v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp, cmp; tmp = d01; @@ -268,7 +274,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { + static NOINLINE void sort_04v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) { __m256i tmp, cmp; tmp = d01; @@ -508,7 +514,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_03v_merge_descending(d05, d06, d07); } - static INLINE void sort_08v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp, cmp; sort_04v_ascending(d01, d02, d03, d04); @@ -537,7 +543,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp, cmp; sort_04v_descending(d01, d02, d03, d04); @@ -566,7 +572,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_04v_merge_descending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp, cmp; tmp = d01; @@ -596,7 +602,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { + static NOINLINE void sort_08v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) { __m256i tmp, cmp; tmp = d01; @@ -740,7 +746,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_03v_merge_descending(d09, d10, d11); } - static INLINE void sort_12v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { + static NOINLINE void sort_12v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { __m256i tmp, cmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -769,7 +775,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_04v_merge_ascending(d09, d10, d11, d12); } - static INLINE void sort_12v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { + static NOINLINE void sort_12v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) { __m256i tmp, cmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1032,7 +1038,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_07v_merge_descending(d09, d10, d11, d12, d13, d14, d15); } - static INLINE void sort_16v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { + static NOINLINE void sort_16v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { __m256i tmp, cmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1081,7 +1087,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_08v_merge_ascending(d09, d10, d11, d12, d13, d14, d15, d16); } - static INLINE void sort_16v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { + static NOINLINE void sort_16v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) { __m256i tmp, cmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1131,80 +1137,94 @@ template<> struct bitonic { sort_08v_merge_descending(d09, d10, d11, d12, d13, d14, d15, d16); } - static NOINLINE void sort_01v(int64_t *ptr) { - __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; + static NOINLINE void sort_01v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); + + __m256i d01 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 0), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_01v_ascending(d01); - _mm256_storeu_si256((__m256i *) ptr + 0, d01); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 0), mask, d01); + } + + static NOINLINE void sort_02v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_02v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; - __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; + __m256i d02 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 1), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_02v_ascending(d01, d02); _mm256_storeu_si256((__m256i *) ptr + 0, d01); - _mm256_storeu_si256((__m256i *) ptr + 1, d02); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 1), mask, d02); + } + + static NOINLINE void sort_03v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_03v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; - __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; + __m256i d03 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 2), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_03v_ascending(d01, d02, d03); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); - _mm256_storeu_si256((__m256i *) ptr + 2, d03); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 2), mask, d03); + } + + static NOINLINE void sort_04v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_04v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; - __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; + __m256i d04 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 3), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_04v_ascending(d01, d02, d03, d04); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); - _mm256_storeu_si256((__m256i *) ptr + 3, d04); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 3), mask, d04); + } + + static NOINLINE void sort_05v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_05v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; - __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; + __m256i d05 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 4), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_05v_ascending(d01, d02, d03, d04, d05); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); _mm256_storeu_si256((__m256i *) ptr + 3, d04); - _mm256_storeu_si256((__m256i *) ptr + 4, d05); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 4), mask, d05); + } + + static NOINLINE void sort_06v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_06v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; - __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; + __m256i d06 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 5), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_06v_ascending(d01, d02, d03, d04, d05, d06); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); _mm256_storeu_si256((__m256i *) ptr + 2, d03); _mm256_storeu_si256((__m256i *) ptr + 3, d04); _mm256_storeu_si256((__m256i *) ptr + 4, d05); - _mm256_storeu_si256((__m256i *) ptr + 5, d06); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 5), mask, d06); + } + + static NOINLINE void sort_07v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_07v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);; __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; - __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; + __m256i d07 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 6), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_07v_ascending(d01, d02, d03, d04, d05, d06, d07); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1212,10 +1232,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 3, d04); _mm256_storeu_si256((__m256i *) ptr + 4, d05); _mm256_storeu_si256((__m256i *) ptr + 5, d06); - _mm256_storeu_si256((__m256i *) ptr + 6, d07); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 6), mask, d07); + } + + static NOINLINE void sort_08v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_08v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1223,7 +1245,7 @@ template<> struct bitonic { __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);; __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; - __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; + __m256i d08 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 7), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1232,10 +1254,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 4, d05); _mm256_storeu_si256((__m256i *) ptr + 5, d06); _mm256_storeu_si256((__m256i *) ptr + 6, d07); - _mm256_storeu_si256((__m256i *) ptr + 7, d08); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 7), mask, d08); + } + + static NOINLINE void sort_09v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_09v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1244,7 +1268,7 @@ template<> struct bitonic { __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);; __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; - __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; + __m256i d09 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 8), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_09v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1254,10 +1278,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 5, d06); _mm256_storeu_si256((__m256i *) ptr + 6, d07); _mm256_storeu_si256((__m256i *) ptr + 7, d08); - _mm256_storeu_si256((__m256i *) ptr + 8, d09); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 8), mask, d09); + } + + static NOINLINE void sort_10v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_10v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1267,7 +1293,7 @@ template<> struct bitonic { __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);; __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; - __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; + __m256i d10 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 9), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_10v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1278,10 +1304,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 6, d07); _mm256_storeu_si256((__m256i *) ptr + 7, d08); _mm256_storeu_si256((__m256i *) ptr + 8, d09); - _mm256_storeu_si256((__m256i *) ptr + 9, d10); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 9), mask, d10); + } + + static NOINLINE void sort_11v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_11v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1292,7 +1320,7 @@ template<> struct bitonic { __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);; __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; - __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; + __m256i d11 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 10), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_11v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1304,10 +1332,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 7, d08); _mm256_storeu_si256((__m256i *) ptr + 8, d09); _mm256_storeu_si256((__m256i *) ptr + 9, d10); - _mm256_storeu_si256((__m256i *) ptr + 10, d11); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 10), mask, d11); + } + + static NOINLINE void sort_12v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_12v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1319,7 +1349,7 @@ template<> struct bitonic { __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);; __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; - __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; + __m256i d12 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 11), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_12v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1332,10 +1362,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 8, d09); _mm256_storeu_si256((__m256i *) ptr + 9, d10); _mm256_storeu_si256((__m256i *) ptr + 10, d11); - _mm256_storeu_si256((__m256i *) ptr + 11, d12); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 11), mask, d12); + } + + static NOINLINE void sort_13v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_13v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1348,7 +1380,7 @@ template<> struct bitonic { __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);; __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; - __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; + __m256i d13 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 12), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_13v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1362,10 +1394,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 9, d10); _mm256_storeu_si256((__m256i *) ptr + 10, d11); _mm256_storeu_si256((__m256i *) ptr + 11, d12); - _mm256_storeu_si256((__m256i *) ptr + 12, d13); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 12), mask, d13); + } + + static NOINLINE void sort_14v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_14v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1379,7 +1413,7 @@ template<> struct bitonic { __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);; __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; - __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; + __m256i d14 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 13), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_14v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1394,10 +1428,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 10, d11); _mm256_storeu_si256((__m256i *) ptr + 11, d12); _mm256_storeu_si256((__m256i *) ptr + 12, d13); - _mm256_storeu_si256((__m256i *) ptr + 13, d14); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 13), mask, d14); + } + + static NOINLINE void sort_15v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_15v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1412,7 +1448,7 @@ template<> struct bitonic { __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);; __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; - __m256i d15 = _mm256_lddqu_si256((__m256i const *) ptr + 14);; + __m256i d15 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 14), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_15v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1428,10 +1464,12 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 11, d12); _mm256_storeu_si256((__m256i *) ptr + 12, d13); _mm256_storeu_si256((__m256i *) ptr + 13, d14); - _mm256_storeu_si256((__m256i *) ptr + 14, d15); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 14), mask, d15); + } + + static NOINLINE void sort_16v_alt(int64_t *ptr, int remainder) { + const auto mask = _mm256_cvtepi8_epi64(_mm_loadu_si128((__m128i*)(mask_table_4 + remainder * N))); - static NOINLINE void sort_16v(int64_t *ptr) { __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);; __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);; __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);; @@ -1447,7 +1485,7 @@ template<> struct bitonic { __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);; __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);; __m256i d15 = _mm256_lddqu_si256((__m256i const *) ptr + 14);; - __m256i d16 = _mm256_lddqu_si256((__m256i const *) ptr + 15);; + __m256i d16 = _mm256_or_si256(_mm256_maskload_epi64((long long const *) ((__m256i const *) ptr + 15), mask), _mm256_andnot_si256(mask, _mm256_set1_epi64x(MAX))); sort_16v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15, d16); _mm256_storeu_si256((__m256i *) ptr + 0, d01); _mm256_storeu_si256((__m256i *) ptr + 1, d02); @@ -1464,8 +1502,8 @@ template<> struct bitonic { _mm256_storeu_si256((__m256i *) ptr + 12, d13); _mm256_storeu_si256((__m256i *) ptr + 13, d14); _mm256_storeu_si256((__m256i *) ptr + 14, d15); - _mm256_storeu_si256((__m256i *) ptr + 15, d16); -} + _mm256_maskstore_epi64((long long *) ((__m256i *) ptr + 15), mask, d16); + } static void sort(int64_t *ptr, size_t length); }; diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp index 9efdf598ea49..28c2ee4b807c 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp @@ -7,24 +7,25 @@ using namespace vxsort; void vxsort::smallsort::bitonic::sort(int32_t *ptr, size_t length) { - const int N = 16; - - switch(length / N) { - case 1: sort_01v(ptr); break; - case 2: sort_02v(ptr); break; - case 3: sort_03v(ptr); break; - case 4: sort_04v(ptr); break; - case 5: sort_05v(ptr); break; - case 6: sort_06v(ptr); break; - case 7: sort_07v(ptr); break; - case 8: sort_08v(ptr); break; - case 9: sort_09v(ptr); break; - case 10: sort_10v(ptr); break; - case 11: sort_11v(ptr); break; - case 12: sort_12v(ptr); break; - case 13: sort_13v(ptr); break; - case 14: sort_14v(ptr); break; - case 15: sort_15v(ptr); break; - case 16: sort_16v(ptr); break; + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) { + case 1: sort_01v_alt(ptr, remainder); break; + case 2: sort_02v_alt(ptr, remainder); break; + case 3: sort_03v_alt(ptr, remainder); break; + case 4: sort_04v_alt(ptr, remainder); break; + case 5: sort_05v_alt(ptr, remainder); break; + case 6: sort_06v_alt(ptr, remainder); break; + case 7: sort_07v_alt(ptr, remainder); break; + case 8: sort_08v_alt(ptr, remainder); break; + case 9: sort_09v_alt(ptr, remainder); break; + case 10: sort_10v_alt(ptr, remainder); break; + case 11: sort_11v_alt(ptr, remainder); break; + case 12: sort_12v_alt(ptr, remainder); break; + case 13: sort_13v_alt(ptr, remainder); break; + case 14: sort_14v_alt(ptr, remainder); break; + case 15: sort_15v_alt(ptr, remainder); break; + case 16: sort_16v_alt(ptr, remainder); break; } } diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.h b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.h index 21c992c3e0df..1b1843ec093c 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.h +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.h @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////////////// //// -// This file was auto-generated by a tool at 2020-06-22 05:27:48 +// This file was auto-generated by a tool at 2020-07-21 14:05:39 // // It is recommended you DO NOT directly edit this file but instead edit // the code-generator that generated this source file instead. @@ -35,6 +35,8 @@ namespace vxsort { namespace smallsort { template<> struct bitonic { + static const int N = 16; + static constexpr int32_t MAX = std::numeric_limits::Max(); public: static INLINE void sort_01v_ascending(__m512i& d01) { @@ -253,7 +255,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_01v_merge_descending(d03); } - static INLINE void sort_04v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; sort_02v_ascending(d01, d02); @@ -270,7 +272,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; sort_02v_descending(d01, d02); @@ -287,7 +289,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_02v_merge_descending(d03, d04); } - static INLINE void sort_04v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; tmp = d01; @@ -301,7 +303,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; tmp = d01; @@ -501,7 +503,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_03v_merge_descending(d05, d06, d07); } - static INLINE void sort_08v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; sort_04v_ascending(d01, d02, d03, d04); @@ -526,7 +528,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; sort_04v_descending(d01, d02, d03, d04); @@ -551,7 +553,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_04v_merge_descending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; tmp = d01; @@ -573,7 +575,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; tmp = d01; @@ -697,7 +699,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_03v_merge_descending(d09, d10, d11); } - static INLINE void sort_12v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { + static NOINLINE void sort_12v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { __m512i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -722,7 +724,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_04v_merge_ascending(d09, d10, d11, d12); } - static INLINE void sort_12v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { + static NOINLINE void sort_12v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { __m512i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -945,7 +947,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_07v_merge_descending(d09, d10, d11, d12, d13, d14, d15); } - static INLINE void sort_16v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { + static NOINLINE void sort_16v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { __m512i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -986,7 +988,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_08v_merge_ascending(d09, d10, d11, d12, d13, d14, d15, d16); } - static INLINE void sort_16v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { + static NOINLINE void sort_16v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { __m512i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -1028,80 +1030,108 @@ template<> struct bitonic { sort_08v_merge_descending(d09, d10, d11, d12, d13, d14, d15, d16); } - static NOINLINE void sort_01v(int32_t *ptr) { - __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; + static NOINLINE void sort_01v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); + + __m512i d01 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 0)); sort_01v_ascending(d01); - _mm512_storeu_si512((__m512i *) ptr + 0, d01); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 0, mask, d01); + } + + static NOINLINE void sort_02v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_02v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; - __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; + __m512i d02 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 1)); sort_02v_ascending(d01, d02); _mm512_storeu_si512((__m512i *) ptr + 0, d01); - _mm512_storeu_si512((__m512i *) ptr + 1, d02); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 1, mask, d02); + } + + static NOINLINE void sort_03v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_03v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; - __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; + __m512i d03 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 2)); sort_03v_ascending(d01, d02, d03); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); - _mm512_storeu_si512((__m512i *) ptr + 2, d03); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 2, mask, d03); + } + + static NOINLINE void sort_04v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_04v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; - __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; + __m512i d04 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 3)); sort_04v_ascending(d01, d02, d03, d04); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); - _mm512_storeu_si512((__m512i *) ptr + 3, d04); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 3, mask, d04); + } + + static NOINLINE void sort_05v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_05v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; - __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; + __m512i d05 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 4)); sort_05v_ascending(d01, d02, d03, d04, d05); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); _mm512_storeu_si512((__m512i *) ptr + 3, d04); - _mm512_storeu_si512((__m512i *) ptr + 4, d05); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 4, mask, d05); + } + + static NOINLINE void sort_06v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_06v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; - __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; + __m512i d06 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 5)); sort_06v_ascending(d01, d02, d03, d04, d05, d06); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); _mm512_storeu_si512((__m512i *) ptr + 3, d04); _mm512_storeu_si512((__m512i *) ptr + 4, d05); - _mm512_storeu_si512((__m512i *) ptr + 5, d06); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 5, mask, d06); + } + + static NOINLINE void sort_07v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_07v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; - __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; + __m512i d07 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 6)); sort_07v_ascending(d01, d02, d03, d04, d05, d06, d07); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1109,10 +1139,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 3, d04); _mm512_storeu_si512((__m512i *) ptr + 4, d05); _mm512_storeu_si512((__m512i *) ptr + 5, d06); - _mm512_storeu_si512((__m512i *) ptr + 6, d07); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 6, mask, d07); + } + + static NOINLINE void sort_08v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_08v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1120,7 +1152,9 @@ template<> struct bitonic { __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; - __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; + __m512i d08 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 7)); sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1129,10 +1163,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 4, d05); _mm512_storeu_si512((__m512i *) ptr + 5, d06); _mm512_storeu_si512((__m512i *) ptr + 6, d07); - _mm512_storeu_si512((__m512i *) ptr + 7, d08); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 7, mask, d08); + } + + static NOINLINE void sort_09v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_09v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1141,7 +1177,9 @@ template<> struct bitonic { __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; - __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; + __m512i d09 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 8)); sort_09v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1151,10 +1189,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 5, d06); _mm512_storeu_si512((__m512i *) ptr + 6, d07); _mm512_storeu_si512((__m512i *) ptr + 7, d08); - _mm512_storeu_si512((__m512i *) ptr + 8, d09); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 8, mask, d09); + } + + static NOINLINE void sort_10v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_10v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1164,7 +1204,9 @@ template<> struct bitonic { __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; - __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; + __m512i d10 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 9)); sort_10v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1175,10 +1217,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 6, d07); _mm512_storeu_si512((__m512i *) ptr + 7, d08); _mm512_storeu_si512((__m512i *) ptr + 8, d09); - _mm512_storeu_si512((__m512i *) ptr + 9, d10); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 9, mask, d10); + } + + static NOINLINE void sort_11v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_11v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1189,7 +1233,9 @@ template<> struct bitonic { __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; - __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; + __m512i d11 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 10)); sort_11v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1201,10 +1247,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 7, d08); _mm512_storeu_si512((__m512i *) ptr + 8, d09); _mm512_storeu_si512((__m512i *) ptr + 9, d10); - _mm512_storeu_si512((__m512i *) ptr + 10, d11); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 10, mask, d11); + } + + static NOINLINE void sort_12v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_12v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1216,7 +1264,9 @@ template<> struct bitonic { __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; - __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; + __m512i d12 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 11)); sort_12v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1229,10 +1279,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 8, d09); _mm512_storeu_si512((__m512i *) ptr + 9, d10); _mm512_storeu_si512((__m512i *) ptr + 10, d11); - _mm512_storeu_si512((__m512i *) ptr + 11, d12); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 11, mask, d12); + } + + static NOINLINE void sort_13v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_13v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1245,7 +1297,9 @@ template<> struct bitonic { __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; - __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; + __m512i d13 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 12)); sort_13v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1259,10 +1313,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 9, d10); _mm512_storeu_si512((__m512i *) ptr + 10, d11); _mm512_storeu_si512((__m512i *) ptr + 11, d12); - _mm512_storeu_si512((__m512i *) ptr + 12, d13); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 12, mask, d13); + } + + static NOINLINE void sort_14v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_14v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1276,7 +1332,9 @@ template<> struct bitonic { __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; - __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; + __m512i d14 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 13)); sort_14v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1291,10 +1349,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 10, d11); _mm512_storeu_si512((__m512i *) ptr + 11, d12); _mm512_storeu_si512((__m512i *) ptr + 12, d13); - _mm512_storeu_si512((__m512i *) ptr + 13, d14); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 13, mask, d14); + } + + static NOINLINE void sort_15v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_15v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1309,7 +1369,9 @@ template<> struct bitonic { __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; - __m512i d15 = _mm512_loadu_si512((__m512i const *) ptr + 14);; + __m512i d15 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 14)); sort_15v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1325,10 +1387,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 11, d12); _mm512_storeu_si512((__m512i *) ptr + 12, d13); _mm512_storeu_si512((__m512i *) ptr + 13, d14); - _mm512_storeu_si512((__m512i *) ptr + 14, d15); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 14, mask, d15); + } + + static NOINLINE void sort_16v_alt(int32_t *ptr, int remainder) { + const auto mask = 0xFFFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_16v(int32_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1344,7 +1408,9 @@ template<> struct bitonic { __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; __m512i d15 = _mm512_loadu_si512((__m512i const *) ptr + 14);; - __m512i d16 = _mm512_loadu_si512((__m512i const *) ptr + 15);; + __m512i d16 = _mm512_mask_loadu_epi32(_mm512_set1_epi32(MAX), + mask, + (int32_t const *) ((__m512i const *) ptr + 15)); sort_16v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15, d16); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1361,8 +1427,8 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 12, d13); _mm512_storeu_si512((__m512i *) ptr + 13, d14); _mm512_storeu_si512((__m512i *) ptr + 14, d15); - _mm512_storeu_si512((__m512i *) ptr + 15, d16); -} + _mm512_mask_storeu_epi32((__m512i *) ptr + 15, mask, d16); + } static void sort(int32_t *ptr, size_t length); }; diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp index cf8b62809b36..20648e786d11 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp @@ -7,24 +7,25 @@ using namespace vxsort; void vxsort::smallsort::bitonic::sort(int64_t *ptr, size_t length) { - const int N = 8; - - switch(length / N) { - case 1: sort_01v(ptr); break; - case 2: sort_02v(ptr); break; - case 3: sort_03v(ptr); break; - case 4: sort_04v(ptr); break; - case 5: sort_05v(ptr); break; - case 6: sort_06v(ptr); break; - case 7: sort_07v(ptr); break; - case 8: sort_08v(ptr); break; - case 9: sort_09v(ptr); break; - case 10: sort_10v(ptr); break; - case 11: sort_11v(ptr); break; - case 12: sort_12v(ptr); break; - case 13: sort_13v(ptr); break; - case 14: sort_14v(ptr); break; - case 15: sort_15v(ptr); break; - case 16: sort_16v(ptr); break; + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) { + case 1: sort_01v_alt(ptr, remainder); break; + case 2: sort_02v_alt(ptr, remainder); break; + case 3: sort_03v_alt(ptr, remainder); break; + case 4: sort_04v_alt(ptr, remainder); break; + case 5: sort_05v_alt(ptr, remainder); break; + case 6: sort_06v_alt(ptr, remainder); break; + case 7: sort_07v_alt(ptr, remainder); break; + case 8: sort_08v_alt(ptr, remainder); break; + case 9: sort_09v_alt(ptr, remainder); break; + case 10: sort_10v_alt(ptr, remainder); break; + case 11: sort_11v_alt(ptr, remainder); break; + case 12: sort_12v_alt(ptr, remainder); break; + case 13: sort_13v_alt(ptr, remainder); break; + case 14: sort_14v_alt(ptr, remainder); break; + case 15: sort_15v_alt(ptr, remainder); break; + case 16: sort_16v_alt(ptr, remainder); break; } } diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.h b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.h index 483cf5a1e158..b7f16d607373 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.h +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.h @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////////////// //// -// This file was auto-generated by a tool at 2020-06-22 05:27:48 +// This file was auto-generated by a tool at 2020-07-21 14:05:39 // // It is recommended you DO NOT directly edit this file but instead edit // the code-generator that generated this source file instead. @@ -35,6 +35,8 @@ namespace vxsort { namespace smallsort { template<> struct bitonic { + static const int N = 8; + static constexpr int64_t MAX = std::numeric_limits::Max(); public: static INLINE void sort_01v_ascending(__m512i& d01) { @@ -213,7 +215,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_01v_merge_descending(d03); } - static INLINE void sort_04v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; sort_02v_ascending(d01, d02); @@ -230,7 +232,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; sort_02v_descending(d01, d02); @@ -247,7 +249,7 @@ template<> struct bitonic { sort_02v_merge_descending(d01, d02); sort_02v_merge_descending(d03, d04); } - static INLINE void sort_04v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; tmp = d01; @@ -261,7 +263,7 @@ template<> struct bitonic { sort_02v_merge_ascending(d01, d02); sort_02v_merge_ascending(d03, d04); } - static INLINE void sort_04v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { + static NOINLINE void sort_04v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04) { __m512i tmp; tmp = d01; @@ -461,7 +463,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_03v_merge_descending(d05, d06, d07); } - static INLINE void sort_08v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; sort_04v_ascending(d01, d02, d03, d04); @@ -486,7 +488,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; sort_04v_descending(d01, d02, d03, d04); @@ -511,7 +513,7 @@ template<> struct bitonic { sort_04v_merge_descending(d01, d02, d03, d04); sort_04v_merge_descending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_merge_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; tmp = d01; @@ -533,7 +535,7 @@ template<> struct bitonic { sort_04v_merge_ascending(d01, d02, d03, d04); sort_04v_merge_ascending(d05, d06, d07, d08); } - static INLINE void sort_08v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { + static NOINLINE void sort_08v_merge_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08) { __m512i tmp; tmp = d01; @@ -657,7 +659,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_03v_merge_descending(d09, d10, d11); } - static INLINE void sort_12v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { + static NOINLINE void sort_12v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { __m512i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -682,7 +684,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_04v_merge_ascending(d09, d10, d11, d12); } - static INLINE void sort_12v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { + static NOINLINE void sort_12v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12) { __m512i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -905,7 +907,7 @@ template<> struct bitonic { sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08); sort_07v_merge_descending(d09, d10, d11, d12, d13, d14, d15); } - static INLINE void sort_16v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { + static NOINLINE void sort_16v_ascending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { __m512i tmp; sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -946,7 +948,7 @@ template<> struct bitonic { sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08); sort_08v_merge_ascending(d09, d10, d11, d12, d13, d14, d15, d16); } - static INLINE void sort_16v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { + static NOINLINE void sort_16v_descending(__m512i& d01, __m512i& d02, __m512i& d03, __m512i& d04, __m512i& d05, __m512i& d06, __m512i& d07, __m512i& d08, __m512i& d09, __m512i& d10, __m512i& d11, __m512i& d12, __m512i& d13, __m512i& d14, __m512i& d15, __m512i& d16) { __m512i tmp; sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08); @@ -988,80 +990,108 @@ template<> struct bitonic { sort_08v_merge_descending(d09, d10, d11, d12, d13, d14, d15, d16); } - static NOINLINE void sort_01v(int64_t *ptr) { - __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; + static NOINLINE void sort_01v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); + + __m512i d01 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 0)); sort_01v_ascending(d01); - _mm512_storeu_si512((__m512i *) ptr + 0, d01); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 0, mask, d01); + } + + static NOINLINE void sort_02v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_02v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; - __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; + __m512i d02 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 1)); sort_02v_ascending(d01, d02); _mm512_storeu_si512((__m512i *) ptr + 0, d01); - _mm512_storeu_si512((__m512i *) ptr + 1, d02); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 1, mask, d02); + } + + static NOINLINE void sort_03v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_03v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; - __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; + __m512i d03 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 2)); sort_03v_ascending(d01, d02, d03); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); - _mm512_storeu_si512((__m512i *) ptr + 2, d03); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 2, mask, d03); + } + + static NOINLINE void sort_04v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_04v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; - __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; + __m512i d04 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 3)); sort_04v_ascending(d01, d02, d03, d04); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); - _mm512_storeu_si512((__m512i *) ptr + 3, d04); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 3, mask, d04); + } + + static NOINLINE void sort_05v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_05v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; - __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; + __m512i d05 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 4)); sort_05v_ascending(d01, d02, d03, d04, d05); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); _mm512_storeu_si512((__m512i *) ptr + 3, d04); - _mm512_storeu_si512((__m512i *) ptr + 4, d05); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 4, mask, d05); + } + + static NOINLINE void sort_06v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_06v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; - __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; + __m512i d06 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 5)); sort_06v_ascending(d01, d02, d03, d04, d05, d06); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); _mm512_storeu_si512((__m512i *) ptr + 2, d03); _mm512_storeu_si512((__m512i *) ptr + 3, d04); _mm512_storeu_si512((__m512i *) ptr + 4, d05); - _mm512_storeu_si512((__m512i *) ptr + 5, d06); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 5, mask, d06); + } + + static NOINLINE void sort_07v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_07v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; __m512i d04 = _mm512_loadu_si512((__m512i const *) ptr + 3);; __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; - __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; + __m512i d07 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 6)); sort_07v_ascending(d01, d02, d03, d04, d05, d06, d07); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1069,10 +1099,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 3, d04); _mm512_storeu_si512((__m512i *) ptr + 4, d05); _mm512_storeu_si512((__m512i *) ptr + 5, d06); - _mm512_storeu_si512((__m512i *) ptr + 6, d07); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 6, mask, d07); + } + + static NOINLINE void sort_08v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_08v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1080,7 +1112,9 @@ template<> struct bitonic { __m512i d05 = _mm512_loadu_si512((__m512i const *) ptr + 4);; __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; - __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; + __m512i d08 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 7)); sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1089,10 +1123,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 4, d05); _mm512_storeu_si512((__m512i *) ptr + 5, d06); _mm512_storeu_si512((__m512i *) ptr + 6, d07); - _mm512_storeu_si512((__m512i *) ptr + 7, d08); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 7, mask, d08); + } + + static NOINLINE void sort_09v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_09v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1101,7 +1137,9 @@ template<> struct bitonic { __m512i d06 = _mm512_loadu_si512((__m512i const *) ptr + 5);; __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; - __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; + __m512i d09 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 8)); sort_09v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1111,10 +1149,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 5, d06); _mm512_storeu_si512((__m512i *) ptr + 6, d07); _mm512_storeu_si512((__m512i *) ptr + 7, d08); - _mm512_storeu_si512((__m512i *) ptr + 8, d09); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 8, mask, d09); + } + + static NOINLINE void sort_10v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_10v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1124,7 +1164,9 @@ template<> struct bitonic { __m512i d07 = _mm512_loadu_si512((__m512i const *) ptr + 6);; __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; - __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; + __m512i d10 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 9)); sort_10v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1135,10 +1177,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 6, d07); _mm512_storeu_si512((__m512i *) ptr + 7, d08); _mm512_storeu_si512((__m512i *) ptr + 8, d09); - _mm512_storeu_si512((__m512i *) ptr + 9, d10); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 9, mask, d10); + } + + static NOINLINE void sort_11v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_11v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1149,7 +1193,9 @@ template<> struct bitonic { __m512i d08 = _mm512_loadu_si512((__m512i const *) ptr + 7);; __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; - __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; + __m512i d11 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 10)); sort_11v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1161,10 +1207,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 7, d08); _mm512_storeu_si512((__m512i *) ptr + 8, d09); _mm512_storeu_si512((__m512i *) ptr + 9, d10); - _mm512_storeu_si512((__m512i *) ptr + 10, d11); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 10, mask, d11); + } + + static NOINLINE void sort_12v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_12v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1176,7 +1224,9 @@ template<> struct bitonic { __m512i d09 = _mm512_loadu_si512((__m512i const *) ptr + 8);; __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; - __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; + __m512i d12 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 11)); sort_12v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1189,10 +1239,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 8, d09); _mm512_storeu_si512((__m512i *) ptr + 9, d10); _mm512_storeu_si512((__m512i *) ptr + 10, d11); - _mm512_storeu_si512((__m512i *) ptr + 11, d12); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 11, mask, d12); + } + + static NOINLINE void sort_13v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_13v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1205,7 +1257,9 @@ template<> struct bitonic { __m512i d10 = _mm512_loadu_si512((__m512i const *) ptr + 9);; __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; - __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; + __m512i d13 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 12)); sort_13v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1219,10 +1273,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 9, d10); _mm512_storeu_si512((__m512i *) ptr + 10, d11); _mm512_storeu_si512((__m512i *) ptr + 11, d12); - _mm512_storeu_si512((__m512i *) ptr + 12, d13); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 12, mask, d13); + } + + static NOINLINE void sort_14v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_14v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1236,7 +1292,9 @@ template<> struct bitonic { __m512i d11 = _mm512_loadu_si512((__m512i const *) ptr + 10);; __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; - __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; + __m512i d14 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 13)); sort_14v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1251,10 +1309,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 10, d11); _mm512_storeu_si512((__m512i *) ptr + 11, d12); _mm512_storeu_si512((__m512i *) ptr + 12, d13); - _mm512_storeu_si512((__m512i *) ptr + 13, d14); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 13, mask, d14); + } + + static NOINLINE void sort_15v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_15v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1269,7 +1329,9 @@ template<> struct bitonic { __m512i d12 = _mm512_loadu_si512((__m512i const *) ptr + 11);; __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; - __m512i d15 = _mm512_loadu_si512((__m512i const *) ptr + 14);; + __m512i d15 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 14)); sort_15v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1285,10 +1347,12 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 11, d12); _mm512_storeu_si512((__m512i *) ptr + 12, d13); _mm512_storeu_si512((__m512i *) ptr + 13, d14); - _mm512_storeu_si512((__m512i *) ptr + 14, d15); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 14, mask, d15); + } + + static NOINLINE void sort_16v_alt(int64_t *ptr, int remainder) { + const auto mask = 0xFF >> ((N - remainder) & (N-1)); - static NOINLINE void sort_16v(int64_t *ptr) { __m512i d01 = _mm512_loadu_si512((__m512i const *) ptr + 0);; __m512i d02 = _mm512_loadu_si512((__m512i const *) ptr + 1);; __m512i d03 = _mm512_loadu_si512((__m512i const *) ptr + 2);; @@ -1304,7 +1368,9 @@ template<> struct bitonic { __m512i d13 = _mm512_loadu_si512((__m512i const *) ptr + 12);; __m512i d14 = _mm512_loadu_si512((__m512i const *) ptr + 13);; __m512i d15 = _mm512_loadu_si512((__m512i const *) ptr + 14);; - __m512i d16 = _mm512_loadu_si512((__m512i const *) ptr + 15);; + __m512i d16 = _mm512_mask_loadu_epi64(_mm512_set1_epi64(MAX), + mask, + (int64_t const *) ((__m512i const *) ptr + 15)); sort_16v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15, d16); _mm512_storeu_si512((__m512i *) ptr + 0, d01); _mm512_storeu_si512((__m512i *) ptr + 1, d02); @@ -1321,8 +1387,8 @@ template<> struct bitonic { _mm512_storeu_si512((__m512i *) ptr + 12, d13); _mm512_storeu_si512((__m512i *) ptr + 13, d14); _mm512_storeu_si512((__m512i *) ptr + 14, d15); - _mm512_storeu_si512((__m512i *) ptr + 15, d16); -} + _mm512_mask_storeu_epi64((__m512i *) ptr + 15, mask, d16); + } static void sort(int64_t *ptr, size_t length); }; diff --git a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.h b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.h index 0e87b3742266..ba5635d4d945 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.h +++ b/src/coreclr/src/gc/vxsort/smallsort/bitonic_sort.h @@ -4,16 +4,39 @@ #ifndef BITONIC_SORT_H #define BITONIC_SORT_H -#include #include "../defs.h" #include "../machine_traits.h" namespace vxsort { namespace smallsort { +using namespace std; + +// * We might read the last 4 bytes into a 128-bit vector for 64-bit element masking +// * We might read the last 8 bytes into a 128-bit vector for 32-bit element masking +// This mostly applies to debug mode, since without optimizations, most compilers +// actually execute the instruction stream _mm256_cvtepi8_epiNN + _mm_loadu_si128 as they are given. +// In contract, release/optimizing compilers, turn that very specific instruction pair to +// a more reasonable: vpmovsxbq ymm0, dword [rax*4 + mask_table_4], eliminating the 128-bit +// load completely and effectively reading 4/8 (depending if the instruction is vpmovsxb[q,d] +#if !defined(__has_feature) +#define __has_feature(a) (0) +#endif +#if !__has_feature(address_sanitizer) +const int M4_SIZE = 16; +const int M8_SIZE = 64; +#else +const int M4_SIZE = 16 + 12; +const int M8_SIZE = 64 + 8; +#endif + +extern "C" const uint8_t mask_table_4[M4_SIZE]; +extern "C" const uint8_t mask_table_8[M8_SIZE]; + template struct bitonic { public: static void sort(T* ptr, size_t length); + static void sort_alt(T* ptr, size_t length); }; } // namespace smallsort } // namespace gcsort diff --git a/src/coreclr/src/gc/vxsort/smallsort/codegen/avx2.py b/src/coreclr/src/gc/vxsort/smallsort/codegen/avx2.py index 5f941d37ff1e..7bf5b86f0413 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/codegen/avx2.py +++ b/src/coreclr/src/gc/vxsort/smallsort/codegen/avx2.py @@ -201,6 +201,33 @@ def get_load_intrinsic(self, v, offset): return f"_mm256_loadu_ps(({t} const *) ((__m256 const *) {v} + {offset}))" return f"_mm256_lddqu_si256((__m256i const *) {v} + {offset});" + def get_mask_load_intrinsic(self, v, offset, mask): + t = self.type + + if self.vector_size() == 4: + int_suffix = "epi64" + max_value = f"_mm256_andnot_si256({mask}, _mm256_set1_epi64x(MAX))" + elif self.vector_size() == 8: + int_suffix = "epi32" + max_value = f"_mm256_andnot_si256({mask}, _mm256_set1_epi32(MAX))" + + if t == "double": + max_value = f"_mm256_andnot_pd(i2d(mask), _mm256_set1_pd(MAX))" + load = f"_mm256_maskload_pd(({t} const *) ((__m256d const *) {v} + {offset}), {mask})" + return f"_mm256_or_pd({load}, {max_value})" + if t == "float": + max_value = f"_mm256_andnot_ps(i2s(mask), _mm256_set1_ps(MAX))" + load = f"_mm256_maskload_ps(({t} const *) ((__m256 const *) {v} + {offset}), {mask})" + return f"_mm256_or_ps({load}, {max_value})" + + + if t == "int64_t" or t == "uint64_t": + it = "long long" + else: + it = t[1:] if t[0] == 'u' else t + + load = f"_mm256_maskload_{int_suffix}(({it} const *) ((__m256i const *) {v} + {offset}), {mask})" + return f"_mm256_or_si256({load}, {max_value})" def get_store_intrinsic(self, ptr, offset, value): t = self.type @@ -210,6 +237,26 @@ def get_store_intrinsic(self, ptr, offset, value): return f"_mm256_storeu_ps(({t} *) ((__m256 *) {ptr} + {offset}), {value})" return f"_mm256_storeu_si256((__m256i *) {ptr} + {offset}, {value})" + def get_mask_store_intrinsic(self, ptr, offset, value, mask): + t = self.type + + if self.vector_size() == 4: + int_suffix = "epi64" + elif self.vector_size() == 8: + int_suffix = "epi32" + + if t == "double": + return f"_mm256_maskstore_pd(({t} *) ((__m256d *) {ptr} + {offset}), {mask}, {value})" + if t == "float": + return f"_mm256_maskstore_ps(({t} *) ((__m256 *) {ptr} + {offset}), {mask}, {value})" + + if t == "int64_t" or t == "uint64_t": + it = "long long" + else: + it = t[1:] if t[0] == 'u' else t; + return f"_mm256_maskstore_{int_suffix}(({it} *) ((__m256i *) {ptr} + {offset}), {mask}, {value})" + + def autogenerated_blabber(self): return f"""///////////////////////////////////////////////////////////////////////////// //// @@ -235,6 +282,7 @@ def generate_prologue(self, f): #endif #endif +#include #include #include "bitonic_sort.h" @@ -247,7 +295,13 @@ def generate_prologue(self, f): namespace vxsort {{ namespace smallsort {{ + +extern "C" const uint8_t mask_table_4[16]; +extern "C" const uint8_t mask_table_8[64]; + template<> struct bitonic<{t}, AVX2> {{ + static const int N = {self.vector_size()}; + static constexpr {t} MAX = std::numeric_limits<{t}>::max(); public: """ print(s, file=f) @@ -416,7 +470,7 @@ def generate_compounded_merger(self, f, width, ascending, inline): suffix = "ascending" if ascending else "descending" rev_suffix = "descending" if ascending else "ascending" - + inl = "INLINE" if inline else "NOINLINE" s = f""" static {inl} void sort_{width:02d}v_merge_{suffix}({g.generate_param_def_list(width)}) {{ @@ -440,12 +494,12 @@ def generate_compounded_merger(self, f, width, ascending, inline): print(" }", file=f) - def generate_entry_points(self, f): + def generate_entry_points_old(self, f): type = self.type g = self for m in range(1, g.max_bitonic_sort_vectors() + 1): s = f""" - static NOINLINE void sort_{m:02d}v({type} *ptr) {{""" + static NOINLINE void sort_{m:02d}v_old({type} *ptr) {{""" print(s, file=f) for l in range(0, m): @@ -459,7 +513,34 @@ def generate_entry_points(self, f): s = f" {g.get_store_intrinsic('ptr', l, f'd{l + 1:02d}')};" print(s, file=f) - print("}", file=f) + print(" }", file=f) + + def generate_entry_points(self, f): + type = self.type + g = self + for m in range(1, g.max_bitonic_sort_vectors() + 1): + s = f""" + static NOINLINE void sort_{m:02d}v_alt({type} *ptr, int remainder) {{ + const auto mask = _mm256_cvtepi8_epi{int(256 / self.vector_size())}(_mm_loadu_si128((__m128i*)(mask_table_{self.vector_size()} + remainder * N))); +""" + print(s, file=f) + + for l in range(0, m-1): + s = f" {g.vector_type()} d{l + 1:02d} = {g.get_load_intrinsic('ptr', l)};" + print(s, file=f) + s = f" {g.vector_type()} d{m:02d} = {g.get_mask_load_intrinsic('ptr', m - 1, 'mask')};" + print(s, file=f) + + s = f" sort_{m:02d}v_ascending({g.generate_param_list(1, m)});" + print(s, file=f) + + for l in range(0, m-1): + s = f" {g.get_store_intrinsic('ptr', l, f'd{l + 1:02d}')};" + print(s, file=f) + s = f" {g.get_mask_store_intrinsic('ptr', m - 1, f'd{m:02d}', 'mask')};" + print(s, file=f) + + print(" }", file=f) def generate_master_entry_point(self, f_header, f_src): @@ -473,18 +554,34 @@ def generate_master_entry_point(self, f_header, f_src): t = self.type g = self + # s = f""" static void sort_old({t} *ptr, size_t length);""" + # print(s, file=f_header) + s = f""" static void sort({t} *ptr, size_t length);""" print(s, file=f_header) - s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX2 >::sort({t} *ptr, size_t length) {{ - const int N = {g.vector_size()}; - switch(length / N) {{""" + # s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX2 >::sort({t} *ptr, size_t length) {{ + # switch(length / N) {{""" + # print(s, file=f_src) + # + # for m in range(1, self.max_bitonic_sort_vectors() + 1): + # s = f" case {m}: sort_{m:02d}v(ptr); break;" + # print(s, file=f_src) + # print(" }", file=f_src) + # print("}", file=f_src) + + s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX2 >::sort({t} *ptr, size_t length) {{ + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) {{""" print(s, file=f_src) for m in range(1, self.max_bitonic_sort_vectors() + 1): - s = f" case {m}: sort_{m:02d}v(ptr); break;" + s = f" case {m}: sort_{m:02d}v_alt(ptr, remainder); break;" print(s, file=f_src) print(" }", file=f_src) print("}", file=f_src) + pass diff --git a/src/coreclr/src/gc/vxsort/smallsort/codegen/avx512.py b/src/coreclr/src/gc/vxsort/smallsort/codegen/avx512.py index f08fda8a4445..6cb6e9048356 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/codegen/avx512.py +++ b/src/coreclr/src/gc/vxsort/smallsort/codegen/avx512.py @@ -210,6 +210,29 @@ def get_load_intrinsic(self, v, offset): return f"_mm512_loadu_ps(({t} const *) ((__m512 const *) {v} + {offset}))" return f"_mm512_loadu_si512((__m512i const *) {v} + {offset});" + def get_mask_load_intrinsic(self, v, offset, mask): + t = self.type + + if self.vector_size() == 8: + int_suffix = "epi64" + max_value = f"_mm512_set1_epi64(MAX)" + elif self.vector_size() == 16: + int_suffix = "epi32" + max_value = f"_mm512_set1_epi32(MAX)" + + if t == "double": + return f"""_mm512_mask_loadu_pd(_mm512_set1_pd(MAX), + {mask}, + ({t} const *) ((__m512d const *) {v} + {offset}))""" + elif t == "float": + return f"""_mm512_mask_loadu_ps(_mm512_set1_ps(MAX), + {mask}, + ({t} const *) ((__m512 const *) {v} + {offset}))""" + + return f"""_mm512_mask_loadu_{int_suffix}({max_value}, + {mask}, + ({t} const *) ((__m512i const *) {v} + {offset}))""" + def get_store_intrinsic(self, ptr, offset, value): t = self.type @@ -219,6 +242,20 @@ def get_store_intrinsic(self, ptr, offset, value): return f"_mm512_storeu_ps(({t} *) ((__m512 *) {ptr} + {offset}), {value})" return f"_mm512_storeu_si512((__m512i *) {ptr} + {offset}, {value})" + def get_mask_store_intrinsic(self, ptr, offset, value, mask): + t = self.type + + if self.vector_size() == 8: + int_suffix = "epi64" + elif self.vector_size() == 16: + int_suffix = "epi32" + + if t == "double": + return f"_mm512_mask_storeu_pd(({t} *) ((__m512d *) {ptr} + {offset}), {mask}, {value})" + if t == "float": + return f"_mm512_mask_storeu_ps(({t} *) ((__m512 *) {ptr} + {offset}), {mask}, {value})" + return f"_mm512_mask_storeu_{int_suffix}((__m512i *) {ptr} + {offset}, {mask}, {value})" + def autogenerated_blabber(self): return f"""///////////////////////////////////////////////////////////////////////////// //// @@ -245,6 +282,7 @@ def generate_prologue(self, f): #endif #endif +#include #include #include "bitonic_sort.h" @@ -258,6 +296,8 @@ def generate_prologue(self, f): namespace vxsort {{ namespace smallsort {{ template<> struct bitonic<{t}, AVX512> {{ + static const int N = {self.vector_size()}; + static constexpr {t} MAX = std::numeric_limits<{t}>::max(); public: """ print(s, file=f) @@ -440,12 +480,12 @@ def generate_compounded_merger(self, f, width, ascending, inline): print(" }", file=f) - def generate_entry_points(self, f): + def generate_entry_points_old(self, f): type = self.type g = self for m in range(1, g.max_bitonic_sort_vectors() + 1): s = f""" - static NOINLINE void sort_{m:02d}v({type} *ptr) {{""" + static NOINLINE void sort_{m:02d}v_old({type} *ptr) {{""" print(s, file=f) for l in range(0, m): @@ -459,7 +499,34 @@ def generate_entry_points(self, f): s = f" {g.get_store_intrinsic('ptr', l, f'd{l + 1:02d}')};" print(s, file=f) - print("}", file=f) + print(" }", file=f) + + def generate_entry_points(self, f): + type = self.type + g = self + for m in range(1, g.max_bitonic_sort_vectors() + 1): + s = f""" + static NOINLINE void sort_{m:02d}v_alt({type} *ptr, int remainder) {{ + const auto mask = 0x{((1 << self.vector_size()) - 1):X} >> ((N - remainder) & (N-1)); +""" + print(s, file=f) + + for l in range(0, m-1): + s = f" {g.vector_type()} d{l + 1:02d} = {g.get_load_intrinsic('ptr', l)};" + print(s, file=f) + s = f" {g.vector_type()} d{m:02d} = {g.get_mask_load_intrinsic('ptr', m - 1, 'mask')};" + print(s, file=f) + + s = f" sort_{m:02d}v_ascending({g.generate_param_list(1, m)});" + print(s, file=f) + + for l in range(0, m-1): + s = f" {g.get_store_intrinsic('ptr', l, f'd{l + 1:02d}')};" + print(s, file=f) + s = f" {g.get_mask_store_intrinsic('ptr', m - 1, f'd{m:02d}', 'mask')};" + print(s, file=f) + + print(" }", file=f) def generate_master_entry_point(self, f_header, f_src): @@ -473,18 +540,35 @@ def generate_master_entry_point(self, f_header, f_src): t = self.type g = self + # s = f""" static void sort_old({t} *ptr, size_t length);""" + # print(s, file=f_header) + s = f""" static void sort({t} *ptr, size_t length);""" print(s, file=f_header) - s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX512 >::sort({t} *ptr, size_t length) {{ - const int N = {g.vector_size()}; - switch(length / N) {{""" + # s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX512 >::sort_old({t} *ptr, size_t length) {{ + # switch(length / N) {{""" + # print(s, file=f_src) + # + # for m in range(1, self.max_bitonic_sort_vectors() + 1): + # s = f" case {m}: sort_{m:02d}v(ptr); break;" + # print(s, file=f_src) + # print(" }", file=f_src) + # print("}", file=f_src) + + + s = f"""void vxsort::smallsort::bitonic<{t}, vector_machine::AVX512 >::sort({t} *ptr, size_t length) {{ + const auto fullvlength = length / N; + const int remainder = (int) (length - fullvlength * N); + const auto v = fullvlength + ((remainder > 0) ? 1 : 0); + switch(v) {{""" print(s, file=f_src) for m in range(1, self.max_bitonic_sort_vectors() + 1): - s = f" case {m}: sort_{m:02d}v(ptr); break;" + s = f" case {m}: sort_{m:02d}v_alt(ptr, remainder); break;" print(s, file=f_src) print(" }", file=f_src) + print("}", file=f_src) pass diff --git a/src/coreclr/src/gc/vxsort/smallsort/codegen/bitonic_gen.py b/src/coreclr/src/gc/vxsort/smallsort/codegen/bitonic_gen.py index 4681e4986c3f..55ef7bbc0f4c 100644 --- a/src/coreclr/src/gc/vxsort/smallsort/codegen/bitonic_gen.py +++ b/src/coreclr/src/gc/vxsort/smallsort/codegen/bitonic_gen.py @@ -10,8 +10,8 @@ # usage: bitonic_gen.py [-h] [--vector-isa VECTOR_ISA [VECTOR_ISA ...]] # [--break-inline BREAK_INLINE] [--output-dir OUTPUT_DIR] # -# the files in src/coreclr/src/gc/vxsort/smallsort checked in can be generated with: -# python bitonic_gen.py --output-dir c:\temp --vector-isa AVX2 AVX512 +# the files in src/coreclr/src/gc/vxsort/smallsort that are currently checked in can be generated with: +# python bitonic_gen.py --output-dir c:\temp --vector-isa AVX2 AVX512 --break-inline 4 # import argparse import os @@ -55,7 +55,7 @@ def generate_per_type(f_header, f_src, type, vector_isa, break_inline): for width in range(2, g.max_bitonic_sort_vectors() + 1): # Allow breaking the inline chain once in a while (configurable) - if break_inline == 0 or width & break_inline != 0: + if break_inline == 0 or width % break_inline != 0: inline = True else: inline = False @@ -65,6 +65,7 @@ def generate_per_type(f_header, f_src, type, vector_isa, break_inline): g.generate_compounded_merger(f_header, width, ascending=True, inline=inline) g.generate_compounded_merger(f_header, width, ascending=False, inline=inline) + #g.generate_entry_points_old(f_header) g.generate_entry_points(f_header) g.generate_master_entry_point(f_header, f_src) g.generate_epilogue(f_header) diff --git a/src/coreclr/src/gc/vxsort/vxsort.h b/src/coreclr/src/gc/vxsort/vxsort.h index 35812d9356f3..b8eaac51f421 100644 --- a/src/coreclr/src/gc/vxsort/vxsort.h +++ b/src/coreclr/src/gc/vxsort/vxsort.h @@ -17,22 +17,28 @@ #include #include - #include "defs.h" -//#include "isa_detection.h" #include "alignment.h" #include "machine_traits.h" +#ifdef VXSORT_STATS +#include "vxsort_stats.h" +#endif //VXSORT_STATS +#include "packer.h" #include "smallsort/bitonic_sort.h" -//#include -//#include -//#include - namespace vxsort { using vxsort::smallsort::bitonic; - -template +/** + * sort primitives, quickly + * @tparam T The primitive type being sorted + * @tparam M The vector machine model/ISA (e.g. AVX2, AVX512 etc.) + * @tparam Unroll The unroll factor, controls to some extent, the code-bloat/speedup ration at the call site + * Defaults to 1 + * @tparam Shift Optional; specify how many LSB bits are known to be zero in the original input. Can be used + * to further speed up sorting. + */ +template class vxsort { static_assert(Unroll >= 1, "Unroll can be in the range 1..12"); static_assert(Unroll <= 12, "Unroll can be in the range 1..12"); @@ -40,6 +46,7 @@ class vxsort { private: using MT = vxsort_machine_traits; typedef typename MT::TV TV; + typedef typename MT::TPACK TPACK; typedef alignment_hint AH; static const int ELEMENT_ALIGN = sizeof(T) - 1; @@ -64,6 +71,18 @@ class vxsort { static const int PARTITION_TMP_SIZE_IN_ELEMENTS = (2 * SLACK_PER_SIDE_IN_ELEMENTS + N + 4*N); + void reset(T* start, T* end) { + _depth = 0; + _startPtr = start; + _endPtr = end; + } + + T* _startPtr = nullptr; + T* _endPtr = nullptr; + + T _temp[PARTITION_TMP_SIZE_IN_ELEMENTS]; + int _depth = 0; + static int floor_log2_plus_one(size_t n) { auto result = 0; while (n >= 1) { @@ -83,18 +102,6 @@ class vxsort { swap(left, right); } - static void insertion_sort(T* lo, T* hi) { - for (auto i = lo + 1; i <= hi; i++) { - auto j = i; - auto t = *i; - while ((j > lo) && (t < *(j - 1))) { - *j = *(j - 1); - j--; - } - *j = t; - } - } - static void heap_sort(T* lo, T* hi) { size_t n = hi - lo + 1; for (size_t i = n / 2; i >= 1; i--) { @@ -122,18 +129,6 @@ class vxsort { *(lo + i - 1) = d; } - void reset(T* start, T* end) { - _depth = 0; - _startPtr = start; - _endPtr = end; - } - - T* _startPtr = nullptr; - T* _endPtr = nullptr; - - T _temp[PARTITION_TMP_SIZE_IN_ELEMENTS]; - int _depth = 0; - NOINLINE T* align_left_scalar_uncommon(T* read_left, T pivot, T*& tmp_left, T*& tmp_right) { @@ -172,8 +167,8 @@ class vxsort { return readRight; } - void sort(T* left, T* right, AH realignHint, - int depthLimit) { + void sort(T* left, T* right, T left_hint, T right_hint, AH realignHint, + int depth_limit) { auto length = (size_t)(right - left + 1); T* mid; @@ -194,16 +189,11 @@ class vxsort { // Go to insertion sort below this threshold if (length <= SMALL_SORT_THRESHOLD_ELEMENTS) { - - auto nextLength = (length & (N-1)) > 0 ? (length + N) & ~(N-1) : length; - - auto extraSpaceNeeded = nextLength - length; - auto fakeLeft = left - extraSpaceNeeded; - if (fakeLeft >= _startPtr) { - bitonic::sort(fakeLeft, nextLength); - } else { - insertion_sort(left, right); - } +#ifdef VXSORT_STATS + vxsort_stats::bump_small_sorts(); + vxsort_stats::record_small_sort_size(length); +#endif + bitonic::sort(left, length); return; } @@ -211,12 +201,24 @@ class vxsort { // will not do well: // 1. Reverse sorted array // 2. High degree of repeated values (dutch flag problem, one value) - if (depthLimit == 0) { + if (depth_limit == 0) { heap_sort(left, right); _depth--; return; } - depthLimit--; + + depth_limit--; + + + if (MT::supports_packing()) { + if (MT::template can_pack(right_hint - left_hint)) { + packer::pack(left, length, left_hint); + auto packed_sorter = vxsort(); + packed_sorter.sort((TPACK *) left, ((TPACK *) left) + length - 1); + packer::unpack((TPACK *) left, length, left_hint); + return; + } + } // This is going to be a bit weird: // Pre/Post alignment calculations happen here: we prepare hints to the @@ -274,11 +276,9 @@ class vxsort { vectorized_partition(left, right, realignHint) : vectorized_partition(left, right, realignHint); - - _depth++; - sort(left, sep - 2, realignHint.realign_right(), depthLimit); - sort(sep, right, realignHint.realign_left(), depthLimit); + sort(left, sep - 2, left_hint, *sep, realignHint.realign_right(), depth_limit); + sort(sep, right, *(sep - 2), right_hint, realignHint.realign_left(), depth_limit); _depth--; } @@ -287,6 +287,10 @@ class vxsort { const TV& P, T*& left, T*& right) { +#ifdef VXSORT_STATS + vxsort_stats::bump_vec_loads(); + vxsort_stats::bump_vec_stores(2); +#endif if (MT::supports_compress_writes()) { partition_block_with_compress(dataVec, P, left, right); } else { @@ -298,6 +302,9 @@ class vxsort { const TV& P, T*& left, T*& right) { +#ifdef VXSORT_STATS + vxsort_stats::bump_perms(); +#endif auto mask = MT::get_cmpgt_mask(dataVec, P); dataVec = MT::partition_vector(dataVec, mask); MT::store_vec(reinterpret_cast(left), dataVec); @@ -325,6 +332,10 @@ class vxsort { assert((reinterpret_cast(left) & ELEMENT_ALIGN) == 0); assert((reinterpret_cast(right) & ELEMENT_ALIGN) == 0); +#ifdef VXSORT_STATS + vxsort_stats::bump_partitions((right - left) + 1); +#endif + // Vectorized double-pumped (dual-sided) partitioning: // We start with picking a pivot using the media-of-3 "method" // Once we have sensible pivot stored as the last element of the array @@ -505,7 +516,7 @@ class vxsort { *writeLeft++ = pivot; assert(writeLeft > left); - assert(writeLeft <= right); + assert(writeLeft <= right+1); return writeLeft; } @@ -526,6 +537,11 @@ class vxsort { const auto preAlignedLeft = (TV*) (left + leftAlign); const auto preAlignedRight = (TV*) (right + rightAlign - N); +#ifdef VXSORT_STATS + vxsort_stats::bump_vec_loads(2); + vxsort_stats::bump_vec_stores(4); +#endif + // Alignment with vectorization is tricky, so read carefully before changing code: // 1. We load data, which we might need to align, if the alignment hints // mean pre-alignment (or overlapping alignment) @@ -565,6 +581,9 @@ class vxsort { tmpStartRight -= rightAlign & rai; } else { +#ifdef VXSORT_STATS + vxsort_stats::bump_perms(2); +#endif RT0 = MT::partition_vector(RT0, rtMask); LT0 = MT::partition_vector(LT0, ltMask); MT::store_vec((TV*) tmpRight, RT0); @@ -588,10 +607,27 @@ class vxsort { } public: - NOINLINE void sort(T* left, T* right) { + /** + * Sort a given range + * @param left The left edge of the range, including + * @param right The right edge of the range, including + * @param left_hint Optional; A hint, Use to speed up the sorting operation, describing a single value that is known to be + * smaller-than, or equalt to all values contained within the provided array. + * @param right_hint Optional; A hint, Use to speed up the sorting operation, describing a single value that is known to be + * larger-than than all values contained within the provided array. + */ + NOINLINE void sort(T* left, T* right, + T left_hint = std::numeric_limits::Min(), + T right_hint = std::numeric_limits::Max()) + { +// init_isa_detection(); + +#ifdef VXSORT_STATS + vxsort_stats::bump_sorts((right - left) + 1); +#endif reset(left, right); auto depthLimit = 2 * floor_log2_plus_one(right + 1 - left); - sort(left, right, AH(), depthLimit); + sort(left, right, left_hint, right_hint, AH(), depthLimit); } }; diff --git a/src/coreclr/src/gc/vxsort/vxsort_targets_enable_avx512.h b/src/coreclr/src/gc/vxsort/vxsort_targets_enable_avx512.h index c5bfe4998a8f..38b0728d4217 100644 --- a/src/coreclr/src/gc/vxsort/vxsort_targets_enable_avx512.h +++ b/src/coreclr/src/gc/vxsort/vxsort_targets_enable_avx512.h @@ -3,9 +3,9 @@ #ifdef __GNUC__ #ifdef __clang__ -#pragma clang attribute push (__attribute__((target("avx512f"))), apply_to = any(function)) +#pragma clang attribute push (__attribute__((target("avx512f,avx512dq"))), apply_to = any(function)) #else #pragma GCC push_options -#pragma GCC target("avx512f") +#pragma GCC target("avx512f,avx512dq") #endif #endif diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index 83ebd3c3576e..6c97ca4ee013 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -557,6 +557,7 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) ../gc/vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp ../gc/vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp ../gc/vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp + ../gc/vxsort/smallsort/avx2_load_mask_tables.cpp ) endif (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32) From 219c60e19d19f673e141639381022c1d6b4e70ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C5=A5a=20Tauer?= Date: Thu, 13 Aug 2020 14:38:24 +0200 Subject: [PATCH 447/755] Added support for CFB This change brings the Cipher Feedback (CFB) mode to .NET 5 with the same behaviors as .NET Framework around the non-standard application of PKCS#7 padding based on the feedback block size and decryption the data be algorithm blocksize-aligned. * AES: CFB8 and CFB128 * TripleDES: CFB8 and CFB64 * DES: CFB8 * RC2: Not supported Additionally, due to a lack of support in CNG, CFB is not supported on Windows 7. --- .../Cryptography/BasicSymmetricCipher.cs | 4 +- .../BasicSymmetricCipherBCrypt.cs | 8 +- .../src/Internal/Cryptography/Helpers.cs | 11 + .../Cryptography/UniversalCryptoDecryptor.cs | 2 +- .../Cryptography/UniversalCryptoEncryptor.cs | 8 +- .../Cryptography/UniversalCryptoTransform.cs | 10 +- .../Interop.Symmetric.cs | 2 + .../Interop.EVP.Cipher.cs | 27 + .../Interop/Windows/BCrypt/AesBCryptModes.cs | 34 +- .../Common/src/Interop/Windows/BCrypt/Cng.cs | 11 + .../Interop/Windows/BCrypt/DESBCryptModes.cs | 32 +- .../BCrypt/Interop.BCryptChainingModes.cs | 1 + .../BCrypt/Interop.BCryptPropertyStrings.cs | 1 + .../Windows/BCrypt/TripleDesBCryptModes.cs | 36 +- .../AES/AesCipherTests.cs | 502 +++++++++++++++++- .../AES/AesContractTests.cs | 59 ++ .../AES/AesModeTests.cs | 14 +- .../DES/DESCipherTests.cs | 294 ++++++++++ .../DES/DESContractTests.cs | 123 +++++ .../RC2/RC2CipherTests.cs | 61 +++ .../RC2/RC2ContractTests.cs | 59 ++ .../TripleDES/TripleDESCipherTests.cs | 450 ++++++++++++++++ .../TripleDES/TripleDESContractTests.cs | 121 +++++ .../pal_symmetric.c | 4 +- .../pal_symmetric.h | 2 + .../opensslshim.h | 18 + .../pal_evp_cipher.c | 45 ++ .../pal_evp_cipher.h | 72 +++ .../Cryptography/AesImplementation.OSX.cs | 6 +- .../Cryptography/AesImplementation.Unix.cs | 41 +- .../Cryptography/AesImplementation.Windows.cs | 6 +- .../Cryptography/AesImplementation.cs | 16 +- .../Internal/Cryptography/AppleCCCryptor.cs | 81 ++- .../Cryptography/DesImplementation.OSX.cs | 6 +- .../Cryptography/DesImplementation.Unix.cs | 14 +- .../Cryptography/DesImplementation.Windows.cs | 6 +- .../Cryptography/DesImplementation.cs | 16 +- .../Internal/Cryptography/OpenSslCipher.cs | 8 +- .../Cryptography/RC2Implementation.OSX.cs | 6 +- .../Cryptography/RC2Implementation.Unix.cs | 4 +- .../Cryptography/RC2Implementation.Windows.cs | 4 +- .../Cryptography/RC2Implementation.cs | 18 +- .../TripleDesImplementation.OSX.cs | 6 +- .../TripleDesImplementation.Unix.cs | 16 +- .../TripleDesImplementation.Windows.cs | 6 +- .../Cryptography/TripleDesImplementation.cs | 16 +- .../src/Resources/Strings.resx | 3 + .../Security/Cryptography/AesCcm.Windows.cs | 2 +- .../Security/Cryptography/AesGcm.Windows.cs | 2 +- ...urity.Cryptography.Algorithms.Tests.csproj | 6 + .../BasicSymmetricCipherNCrypt.cs | 11 +- .../Cryptography/CngSymmetricAlgorithmCore.cs | 4 +- .../Cryptography/ICngSymmetricAlgorithm.cs | 2 + .../System/Security/Cryptography/AesCng.cs | 14 +- .../Security/Cryptography/TripleDESCng.cs | 7 +- .../Cryptography/BasicSymmetricCipherCsp.cs | 12 +- .../Cryptography/CapiHelper.Windows.cs | 2 - .../DESCryptoServiceProvider.Windows.cs | 2 +- .../RC2CryptoServiceProvider.Windows.cs | 2 +- .../Security/Cryptography/CipherMode.cs | 3 +- .../Cryptography/SymmetricAlgorithm.cs | 2 +- 61 files changed, 2231 insertions(+), 130 deletions(-) create mode 100644 src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESContractTests.cs create mode 100644 src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2ContractTests.cs create mode 100644 src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESContractTests.cs diff --git a/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipher.cs b/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipher.cs index df3ae1f7af96..10bbb3317044 100644 --- a/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipher.cs +++ b/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipher.cs @@ -22,10 +22,11 @@ namespace Internal.Cryptography // internal abstract class BasicSymmetricCipher : IDisposable { - protected BasicSymmetricCipher(byte[]? iv, int blockSizeInBytes) + protected BasicSymmetricCipher(byte[]? iv, int blockSizeInBytes, int paddingSizeInBytes) { IV = iv; BlockSizeInBytes = blockSizeInBytes; + PaddingSizeInBytes = paddingSizeInBytes > 0 ? paddingSizeInBytes : blockSizeInBytes; } public abstract int Transform(ReadOnlySpan input, Span output); @@ -33,6 +34,7 @@ protected BasicSymmetricCipher(byte[]? iv, int blockSizeInBytes) public abstract int TransformFinal(ReadOnlySpan input, Span output); public int BlockSizeInBytes { get; private set; } + public int PaddingSizeInBytes { get; private set; } public void Dispose() { diff --git a/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipherBCrypt.cs b/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipherBCrypt.cs index 2deb97cbd5b1..75b748ae8f27 100644 --- a/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipherBCrypt.cs +++ b/src/libraries/Common/src/Internal/Cryptography/BasicSymmetricCipherBCrypt.cs @@ -16,8 +16,8 @@ internal sealed class BasicSymmetricCipherBCrypt : BasicSymmetricCipher private byte[]? _currentIv; // CNG mutates this with the updated IV for the next stage on each Encrypt/Decrypt call. // The base IV holds a copy of the original IV for Reset(), until it is cleared by Dispose(). - public BasicSymmetricCipherBCrypt(SafeAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, bool ownsParentHandle, byte[]? iv, bool encrypting) - : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) + public BasicSymmetricCipherBCrypt(SafeAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, int paddingSizeInBytes, byte[] key, bool ownsParentHandle, byte[]? iv, bool encrypting) + : base(cipherMode.GetCipherIv(iv), blockSizeInBytes, paddingSizeInBytes) { Debug.Assert(algorithm != null); @@ -63,7 +63,7 @@ protected override void Dispose(bool disposing) public override int Transform(ReadOnlySpan input, Span output) { Debug.Assert(input.Length > 0); - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten; @@ -89,7 +89,7 @@ public override int Transform(ReadOnlySpan input, Span output) public override int TransformFinal(ReadOnlySpan input, Span output) { - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten = 0; diff --git a/src/libraries/Common/src/Internal/Cryptography/Helpers.cs b/src/libraries/Common/src/Internal/Cryptography/Helpers.cs index d33c9c232a7e..a825f5de4f37 100644 --- a/src/libraries/Common/src/Internal/Cryptography/Helpers.cs +++ b/src/libraries/Common/src/Internal/Cryptography/Helpers.cs @@ -4,6 +4,7 @@ #nullable enable using System; using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; namespace Internal.Cryptography { @@ -20,6 +21,16 @@ internal static partial class Helpers return (byte[])(src.Clone()); } + public static int GetPaddingSize(this SymmetricAlgorithm algorithm) + { + // CFB8 does not require any padding at all + // otherwise, it is always required to pad for block size + if (algorithm.Mode == CipherMode.CFB && algorithm.FeedbackSize == 8) + return 1; + + return algorithm.BlockSize / 8; + } + internal static bool TryCopyToDestination(ReadOnlySpan source, Span destination, out int bytesWritten) { if (source.TryCopyTo(destination)) diff --git a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs index 754dbc08eb21..2167ca787f03 100644 --- a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs +++ b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs @@ -68,7 +68,7 @@ protected override int UncheckedTransformBlock(ReadOnlySpan inputBuffer, S protected override unsafe int UncheckedTransformFinalBlock(ReadOnlySpan inputBuffer, Span outputBuffer) { // We can't complete decryption on a partial block - if (inputBuffer.Length % InputBlockSize != 0) + if (inputBuffer.Length % PaddingSizeBytes != 0) throw new CryptographicException(SR.Cryptography_PartialBlock); // diff --git a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs index 2bf431a7c0de..e89baaa8ee2e 100644 --- a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs +++ b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs @@ -61,7 +61,7 @@ private int GetCiphertextLength(int plaintextLength) Debug.Assert(plaintextLength >= 0); //divisor and factor are same and won't overflow. - int wholeBlocks = Math.DivRem(plaintextLength, InputBlockSize, out int remainder) * InputBlockSize; + int wholeBlocks = Math.DivRem(plaintextLength, PaddingSizeBytes, out int remainder) * PaddingSizeBytes; switch (PaddingMode) { @@ -74,7 +74,7 @@ private int GetCiphertextLength(int plaintextLength) case PaddingMode.PKCS7: case PaddingMode.ANSIX923: case PaddingMode.ISO10126: - return checked(wholeBlocks + InputBlockSize); + return checked(wholeBlocks + PaddingSizeBytes); default: Debug.Fail($"Unknown padding mode {PaddingMode}."); throw new CryptographicException(SR.Cryptography_UnknownPaddingMode); @@ -84,8 +84,8 @@ private int GetCiphertextLength(int plaintextLength) private int PadBlock(ReadOnlySpan block, Span destination) { int count = block.Length; - int paddingRemainder = count % InputBlockSize; - int padBytes = InputBlockSize - paddingRemainder; + int paddingRemainder = count % PaddingSizeBytes; + int padBytes = PaddingSizeBytes - paddingRemainder; switch (PaddingMode) { diff --git a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoTransform.cs b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoTransform.cs index b4406e502cf1..23966df29693 100644 --- a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoTransform.cs +++ b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoTransform.cs @@ -17,7 +17,10 @@ namespace Internal.Cryptography // internal abstract class UniversalCryptoTransform : ICryptoTransform { - public static ICryptoTransform Create(PaddingMode paddingMode, BasicSymmetricCipher cipher, bool encrypting) + public static ICryptoTransform Create( + PaddingMode paddingMode, + BasicSymmetricCipher cipher, + bool encrypting) { if (encrypting) return new UniversalCryptoEncryptor(paddingMode, cipher); @@ -41,6 +44,11 @@ public bool CanTransformMultipleBlocks get { return true; } } + protected int PaddingSizeBytes + { + get { return BasicSymmetricCipher.PaddingSizeInBytes; } + } + public int InputBlockSize { get { return BasicSymmetricCipher.BlockSizeInBytes; } diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs index c32ba1dd2da2..2b55500b4ab3 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs @@ -33,6 +33,8 @@ internal enum PAL_ChainingMode { ECB = 1, CBC = 2, + CFB = 3, + CFB8 = 10, } internal enum PAL_SymmetricOptions diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs index 637311663c1a..fe2790b1ac12 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs @@ -208,6 +208,12 @@ internal static void EvpCipherSetCcmTagLength(SafeEvpCipherCtxHandle ctx, int ta [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128Gcm")] internal static extern IntPtr EvpAes128Gcm(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128Cfb8")] + internal static extern IntPtr EvpAes128Cfb8(); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128Cfb128")] + internal static extern IntPtr EvpAes128Cfb128(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128Ccm")] internal static extern IntPtr EvpAes128Ccm(); @@ -220,6 +226,12 @@ internal static void EvpCipherSetCcmTagLength(SafeEvpCipherCtxHandle ctx, int ta [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Gcm")] internal static extern IntPtr EvpAes192Gcm(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Cfb8")] + internal static extern IntPtr EvpAes192Cfb8(); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Cfb128")] + internal static extern IntPtr EvpAes192Cfb128(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Ccm")] internal static extern IntPtr EvpAes192Ccm(); @@ -232,6 +244,12 @@ internal static void EvpCipherSetCcmTagLength(SafeEvpCipherCtxHandle ctx, int ta [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Gcm")] internal static extern IntPtr EvpAes256Gcm(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Cfb128")] + internal static extern IntPtr EvpAes256Cfb128(); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Cfb8")] + internal static extern IntPtr EvpAes256Cfb8(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Ccm")] internal static extern IntPtr EvpAes256Ccm(); @@ -241,12 +259,21 @@ internal static void EvpCipherSetCcmTagLength(SafeEvpCipherCtxHandle ctx, int ta [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDesEcb")] internal static extern IntPtr EvpDesEcb(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDesCfb8")] + internal static extern IntPtr EvpDesCfb8(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDes3Cbc")] internal static extern IntPtr EvpDes3Cbc(); [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDes3Ecb")] internal static extern IntPtr EvpDes3Ecb(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDes3Cfb8")] + internal static extern IntPtr EvpDes3Cfb8(); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDes3Cfb64")] + internal static extern IntPtr EvpDes3Cfb64(); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpRC2Cbc")] internal static extern IntPtr EvpRC2Cbc(); diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/AesBCryptModes.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/AesBCryptModes.cs index 96da1670201b..ad685bc57833 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/AesBCryptModes.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/AesBCryptModes.cs @@ -9,25 +9,39 @@ namespace Internal.Cryptography { internal static class AesBCryptModes { - private static readonly SafeAlgorithmHandle s_hAlgCbc = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); - private static readonly SafeAlgorithmHandle s_hAlgEcb = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + private static readonly Lazy s_hAlgCbc = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); + private static readonly Lazy s_hAlgEcb = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + private static readonly Lazy s_hAlgCfb128 = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CFB, 16); + private static readonly Lazy s_hAlgCfb8 = OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CFB, 1); - internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode) => + internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode, int feedback) => // Windows 8 added support to set the CipherMode value on a key, // but Windows 7 requires that it be set on the algorithm before key creation. - cipherMode switch + (cipherMode, feedback) switch { - CipherMode.CBC => s_hAlgCbc, - CipherMode.ECB => s_hAlgEcb, + (CipherMode.CBC, _) => s_hAlgCbc.Value, + (CipherMode.ECB, _) => s_hAlgEcb.Value, + (CipherMode.CFB, 16) => s_hAlgCfb128.Value, + (CipherMode.CFB, 1) => s_hAlgCfb8.Value, _ => throw new NotSupportedException(), }; - internal static SafeAlgorithmHandle OpenAesAlgorithm(string cipherMode) + internal static Lazy OpenAesAlgorithm(string cipherMode, int feedback = 0) { - SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_AES_ALGORITHM, null, Cng.OpenAlgorithmProviderFlags.NONE); - hAlg.SetCipherMode(cipherMode); + return new Lazy(() => + { + SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_AES_ALGORITHM, null, + Cng.OpenAlgorithmProviderFlags.NONE); + hAlg.SetCipherMode(cipherMode); + + // feedback is in bytes! + if (feedback > 0) + { + hAlg.SetFeedbackSize(feedback); + } - return hAlg; + return hAlg; + }); } } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Cng.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Cng.cs index a0cf90596e0a..078288ade264 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Cng.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Cng.cs @@ -66,6 +66,7 @@ public enum OpenAlgorithmProviderFlags : int public const string BCRYPT_CHAIN_MODE_CBC = "ChainingModeCBC"; public const string BCRYPT_CHAIN_MODE_ECB = "ChainingModeECB"; public const string BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM"; + public const string BCRYPT_CHAIN_MODE_CFB = "ChainingModeCFB"; public const string BCRYPT_CHAIN_MODE_CCM = "ChainingModeCCM"; public static SafeAlgorithmHandle BCryptOpenAlgorithmProvider(string pszAlgId, string? pszImplementation, OpenAlgorithmProviderFlags dwFlags) @@ -77,6 +78,16 @@ public static SafeAlgorithmHandle BCryptOpenAlgorithmProvider(string pszAlgId, s return hAlgorithm; } + public static void SetFeedbackSize(this SafeAlgorithmHandle hAlg, int dwFeedbackSize) + { + NTSTATUS ntStatus = Interop.BCryptSetIntProperty(hAlg, BCryptPropertyStrings.BCRYPT_MESSAGE_BLOCK_LENGTH, ref dwFeedbackSize, 0); + + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + throw CreateCryptographicException(ntStatus); + } + } + public static void SetCipherMode(this SafeAlgorithmHandle hAlg, string cipherMode) { NTSTATUS ntStatus = Interop.BCryptSetProperty(hAlg, BCryptPropertyStrings.BCRYPT_CHAINING_MODE, cipherMode, (cipherMode.Length + 1) * 2, 0); diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/DESBCryptModes.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/DESBCryptModes.cs index f4fd13e6c778..85f9b65f1809 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/DESBCryptModes.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/DESBCryptModes.cs @@ -9,25 +9,37 @@ namespace Internal.Cryptography { internal static class DesBCryptModes { - private static readonly SafeAlgorithmHandle s_hAlgCbc = OpenDesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); - private static readonly SafeAlgorithmHandle s_hAlgEcb = OpenDesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + private static readonly Lazy s_hAlgCbc = OpenDesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); + private static readonly Lazy s_hAlgEcb = OpenDesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + private static readonly Lazy s_hAlgCfb8 = OpenDesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CFB, 1); - internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode) => + internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode, int feedback) => // Windows 8 added support to set the CipherMode value on a key, // but Windows 7 requires that it be set on the algorithm before key creation. - cipherMode switch + (cipherMode, feedback) switch { - CipherMode.CBC => s_hAlgCbc, - CipherMode.ECB => s_hAlgEcb, + (CipherMode.CBC, _) => s_hAlgCbc.Value, + (CipherMode.ECB, _) => s_hAlgEcb.Value, + (CipherMode.CFB, 1) => s_hAlgCfb8.Value, _ => throw new NotSupportedException(), }; - private static SafeAlgorithmHandle OpenDesAlgorithm(string cipherMode) + private static Lazy OpenDesAlgorithm(string cipherMode, int feedback = 0) { - SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_DES_ALGORITHM, null, Cng.OpenAlgorithmProviderFlags.NONE); - hAlg.SetCipherMode(cipherMode); + return new Lazy(() => + { + SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_DES_ALGORITHM, + null, + Cng.OpenAlgorithmProviderFlags.NONE); + hAlg.SetCipherMode(cipherMode); + + if (feedback > 0) + { + hAlg.SetFeedbackSize(feedback); + } - return hAlg; + return hAlg; + }); } } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptChainingModes.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptChainingModes.cs index a5448570c5ce..6c4b9f1c4f54 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptChainingModes.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptChainingModes.cs @@ -11,5 +11,6 @@ internal partial class BCrypt { internal const string BCRYPT_CHAIN_MODE_CBC = "ChainingModeCBC"; internal const string BCRYPT_CHAIN_MODE_ECB = "ChainingModeECB"; + internal const string BCRYPT_CHAIN_MODE_CFB = "ChainingModeCFB"; } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptPropertyStrings.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptPropertyStrings.cs index bcba9b2a2913..6b29607172cd 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptPropertyStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptPropertyStrings.cs @@ -11,6 +11,7 @@ internal static class BCryptPropertyStrings internal const string BCRYPT_ECC_PARAMETERS = "ECCParameters"; internal const string BCRYPT_EFFECTIVE_KEY_LENGTH = "EffectiveKeyLength"; internal const string BCRYPT_HASH_LENGTH = "HashDigestLength"; + internal const string BCRYPT_MESSAGE_BLOCK_LENGTH = "MessageBlockLength"; } } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/TripleDesBCryptModes.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/TripleDesBCryptModes.cs index dcffc3b7d5d4..c20b04040a74 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/TripleDesBCryptModes.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/TripleDesBCryptModes.cs @@ -10,26 +10,42 @@ namespace Internal.Cryptography internal static class TripleDesBCryptModes { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "We are providing the implementation for TripleDES, not consuming it")] - private static readonly SafeAlgorithmHandle s_hAlgCbc = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); + private static readonly Lazy s_hAlgCbc = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CBC); [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "We are providing the implementation for TripleDES, not consuming it")] - private static readonly SafeAlgorithmHandle s_hAlgEcb = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + private static readonly Lazy s_hAlgEcb = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_ECB); + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "We are providing the implementation for TripleDES, not consuming it")] + private static readonly Lazy s_hAlgCfb8 = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CFB, 1); + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "We are providing the implementation for TripleDES, not consuming it")] + private static readonly Lazy s_hAlgCfb64 = Open3DesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CFB, 8); - internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode) => + internal static SafeAlgorithmHandle GetSharedHandle(CipherMode cipherMode, int feedback) => // Windows 8 added support to set the CipherMode value on a key, // but Windows 7 requires that it be set on the algorithm before key creation. - cipherMode switch + (cipherMode, feedback) switch { - CipherMode.CBC => s_hAlgCbc, - CipherMode.ECB => s_hAlgEcb, + (CipherMode.CBC, _) => s_hAlgCbc.Value, + (CipherMode.ECB, _) => s_hAlgEcb.Value, + (CipherMode.CFB, 1) => s_hAlgCfb8.Value, + (CipherMode.CFB, 8) => s_hAlgCfb64.Value, _ => throw new NotSupportedException(), }; - private static SafeAlgorithmHandle Open3DesAlgorithm(string cipherMode) + private static Lazy Open3DesAlgorithm(string cipherMode, int feedback = 0) { - SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_3DES_ALGORITHM, null, Cng.OpenAlgorithmProviderFlags.NONE); - hAlg.SetCipherMode(cipherMode); + return new Lazy(() => + { + SafeAlgorithmHandle hAlg = Cng.BCryptOpenAlgorithmProvider(Cng.BCRYPT_3DES_ALGORITHM, null, + Cng.OpenAlgorithmProviderFlags.NONE); + hAlg.SetCipherMode(cipherMode); + + if (feedback > 0) + { + // feedback is in bytes! + hAlg.SetFeedbackSize(feedback); + } - return hAlg; + return hAlg; + }); } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesCipherTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesCipherTests.cs index 9d7d3e2439d9..67a44f8749a3 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesCipherTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesCipherTests.cs @@ -77,6 +77,28 @@ public static void DecryptKnownCBC256() TestAesDecrypt(CipherMode.CBC, s_aes256Key, s_aes256CbcIv, encryptedBytes, s_multiBlockBytes); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void DecryptKnownCFB128_256() + { + byte[] encryptedBytes = new byte[] + { + 0x71, 0x67, 0xD7, 0x86, 0xAA, 0xF8, 0xD9, 0x1A, + 0x3A, 0xFB, 0xA5, 0x9E, 0x41, 0xCA, 0x39, 0x32, + 0x6A, 0x42, 0xA4, 0xD2, 0x26, 0x32, 0x85, 0x05, + 0x5A, 0x98, 0xE4, 0x3A, 0xDA, 0xD7, 0x1B, 0x1A, + 0x47, 0x08, 0xF7, 0x7F, 0xC7, 0x08, 0xBF, 0x7C, + 0x57, 0xE9, 0x13, 0xD5, 0x4F, 0x8F, 0x23, 0x76, + 0xAA, 0xB5, 0x83, 0xE1, 0x5C, 0x48, 0x8A, 0x0D, + 0x4A, 0xFD, 0x10, 0x7C, 0xF1, 0x1B, 0x86, 0xA8, + 0xAB, 0x9D, 0x5B, 0x49, 0x9D, 0xA4, 0x9C, 0x9B, + 0x2B, 0xD1, 0xEC, 0xFF, 0xEB, 0xF7, 0x3B, 0x69, + 0x80, 0x0F, 0xA6, 0x26, 0x3E, 0xD9, 0x72, 0xB9, + 0x72, 0x22, 0x85, 0x50, 0x95, 0x59, 0xFA, 0x5F + }; + + TestAesDecrypt(CipherMode.CFB, s_aes256Key, s_aes256CbcIv, encryptedBytes, s_multiBlockBytes, 128); + } + [Fact] public static void DecryptKnownECB192() { @@ -99,6 +121,50 @@ public static void DecryptKnownECB192() TestAesDecrypt(CipherMode.ECB, s_aes192Key, null, encryptedBytes, s_multiBlockBytes); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void DecryptKnownCFB128_192() + { + byte[] encryptedBytes = new byte[] + { + 0x7C, 0xC6, 0xEE, 0xD8, 0xED, 0xB5, 0x3F, 0x8A, + 0x90, 0x95, 0x12, 0xD2, 0xBC, 0x9A, 0x96, 0x1E, + 0x4E, 0xC4, 0xD1, 0x15, 0xA4, 0x7F, 0x32, 0xA4, + 0xD1, 0xFD, 0x8E, 0x02, 0x45, 0xE8, 0x93, 0x3C, + 0x3C, 0x91, 0x3F, 0xA4, 0x7F, 0x99, 0xF7, 0x3A, + 0x53, 0x0C, 0x0B, 0xFD, 0x01, 0xC5, 0xBD, 0x76, + 0xB7, 0xCF, 0x2B, 0x52, 0x34, 0xB1, 0xA6, 0xA4, + 0x29, 0x2F, 0x7D, 0x1C, 0x97, 0x3A, 0xE2, 0x75, + 0x3E, 0xEB, 0xFC, 0xB7, 0xBB, 0x7A, 0xC0, 0x66, + 0x34, 0x25, 0xCF, 0x2D, 0xE2, 0x7E, 0x23, 0x06, + 0x10, 0xFE, 0xEA, 0xB3, 0x0F, 0x1D, 0x2C, 0xDD, + 0x72, 0x64, 0x51, 0x78, 0x1D, 0x75, 0xD2, 0x17 + }; + + TestAesDecrypt(CipherMode.CFB, s_aes192Key, s_aes256CbcIv, encryptedBytes, s_multiBlockBytes, 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void DecryptKnownCFB128_128() + { + byte[] encryptedBytes = new byte[] + { + 0x5B, 0x63, 0x3D, 0x1C, 0x0C, 0x8E, 0xD4, 0xF4, + 0xE5, 0x5F, 0xA0, 0xAF, 0x2F, 0xF5, 0xAE, 0x59, + 0xB9, 0xC4, 0xFA, 0x02, 0x11, 0x37, 0xEB, 0x38, + 0x5B, 0x2F, 0x1D, 0xF5, 0x03, 0xD1, 0xFD, 0x85, + 0x4B, 0xAA, 0x4F, 0x29, 0x94, 0x09, 0x31, 0x4C, + 0x4D, 0xD6, 0x99, 0xE3, 0x4D, 0xC4, 0x3A, 0x40, + 0x97, 0x58, 0xA5, 0x26, 0x80, 0xA8, 0xCA, 0xFA, + 0x6D, 0x19, 0x3B, 0x6B, 0x6F, 0x75, 0x76, 0x83, + 0x90, 0x31, 0x07, 0x86, 0x35, 0xD6, 0xAB, 0xB4, + 0x65, 0x07, 0x0A, 0x0A, 0xA3, 0x7A, 0xD7, 0x16, + 0xE2, 0xC5, 0x3B, 0xE0, 0x42, 0x5F, 0xFA, 0xEF, + 0xE1, 0x2E, 0x40, 0x84, 0x36, 0x66, 0xB1, 0xBA + }; + + TestAesDecrypt(CipherMode.CFB, s_aes128Key, s_aes256CbcIv, encryptedBytes, s_multiBlockBytes, 128); + } + [Fact] public static void VerifyInPlaceEncryption() { @@ -276,6 +342,32 @@ public static void VerifyKnownTransform_ECB192_NoPadding_2() cipherBytes: new byte[] { 0x6C, 0xD0, 0x25, 0x13, 0xE8, 0xD4, 0xDC, 0x98, 0x6B, 0x4A, 0xFE, 0x08, 0x7A, 0x60, 0xBD, 0x0C }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_8_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12 }, + iv: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + plainBytes: new byte[] { 0x50, 0x68, 0x12, 0xA4, 0x5F, 0x08, 0xC8, 0x89, 0xB9, 0x7F, 0x59, 0x80, 0x03, 0x8B, 0x83, 0x59 }, + cipherBytes: new byte[] { 0xD5, 0x47, 0xC5, 0x23, 0xCF, 0x5D, 0xFF, 0x67, 0x4C, 0xB4, 0xDB, 0x03, 0x96, 0xA3, 0xEB, 0xCF }, + 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12 }, + iv: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + plainBytes: new byte[] { 0x50, 0x68, 0x12, 0xA4, 0x5F, 0x08, 0xC8, 0x89, 0xB9, 0x7F, 0x59, 0x80, 0x03, 0x8B, 0x83, 0x59 }, + cipherBytes: new byte[] { 0xD5, 0x91, 0xEE, 0x44, 0xF7, 0xC4, 0x31, 0xFB, 0x40, 0x20, 0x2F, 0x03, 0x6C, 0x14, 0x7C, 0xAC }, + 128); + } + [Fact] public static void VerifyKnownTransform_CBC128_NoPadding() { @@ -300,6 +392,32 @@ public static void VerifyKnownTransform_CBC256_NoPadding() cipherBytes: new byte[] { 0x19, 0x46, 0xDA, 0xBF, 0x6A, 0x03, 0xA2, 0xA2, 0xC3, 0xD0, 0xB0, 0x50, 0x80, 0xAE, 0xD6, 0xFC }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_256_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1B, 0x1C, 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26 }, + iv: new byte[] { 0x83, 0x4E, 0xAD, 0xFC, 0xCA, 0xC7, 0xE1, 0xB3, 0x06, 0x64, 0xB1, 0xAB, 0xA4, 0x48, 0x15, 0xAB }, + plainBytes: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + cipherBytes: new byte[] { 0x19, 0x46, 0xDA, 0xBF, 0x6A, 0x03, 0xA2, 0xA2, 0xC3, 0xD0, 0xB0, 0x50, 0x80, 0xAE, 0xD6, 0xFC }, + 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_256_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1B, 0x1C, 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26 }, + iv: new byte[] { 0x83, 0x4E, 0xAD, 0xFC, 0xCA, 0xC7, 0xE1, 0xB3, 0x06, 0x64, 0xB1, 0xAB, 0xA4, 0x48, 0x15, 0xAB }, + plainBytes: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + cipherBytes: new byte[] { 0x19, 0x38, 0x0A, 0x23, 0x92, 0x37, 0xC2, 0x7A, 0xBA, 0xD1, 0x82, 0x62, 0xE0, 0x36, 0x83, 0x0C }, + 8); + } + [Fact] public static void VerifyKnownTransform_CBC128_NoPadding_2() { @@ -312,6 +430,19 @@ public static void VerifyKnownTransform_CBC128_NoPadding_2() cipherBytes: new byte[] { 0x0E, 0xDD, 0x33, 0xD3, 0xC6, 0x21, 0xE5, 0x46, 0x45, 0x5B, 0xD8, 0xBA, 0x14, 0x18, 0xBE, 0xC8 }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding_2() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + iv: new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 }, + plainBytes: new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 }, + cipherBytes: new byte[] { 0xC0, 0xB7, 0x81, 0xC8, 0xC9, 0x80, 0x5A, 0x87, 0x61, 0x0E, 0xB4, 0x36, 0x6D, 0xAC, 0xA1, 0x2E }, + 128); + } + [Fact] public static void VerifyKnownTransform_CBC128_NoPadding_3() { @@ -324,6 +455,19 @@ public static void VerifyKnownTransform_CBC128_NoPadding_3() cipherBytes: new byte[] { 0x3A, 0xD7, 0x8E, 0x72, 0x6C, 0x1E, 0xC0, 0x2B, 0x7E, 0xBF, 0xE9, 0x2B, 0x23, 0xD9, 0xEC, 0x34 }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding_3() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + iv: new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 }, + plainBytes: new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 }, + cipherBytes: new byte[] { 0xC0, 0xB7, 0x81, 0xC8, 0xC9, 0x80, 0x5A, 0x87, 0x61, 0x0E, 0xB4, 0x36, 0x6D, 0xAC, 0xA1, 0x2E }, + 128); + } + [Fact] public static void VerifyKnownTransform_CBC192_NoPadding() { @@ -336,6 +480,32 @@ public static void VerifyKnownTransform_CBC192_NoPadding() cipherBytes: new byte[] { 0xDE, 0x88, 0x5D, 0xC8, 0x7F, 0x5A, 0x92, 0x59, 0x40, 0x82, 0xD0, 0x2C, 0xC1, 0xE1, 0xB4, 0x2C }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_192_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + iv: new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + plainBytes: new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + cipherBytes: new byte[] { 0xE9, 0x6E, 0xA7, 0xDA, 0x76, 0x90, 0xCB, 0x98, 0x56, 0x54, 0xE8, 0xFB, 0x86, 0xA3, 0xEB, 0x95 }, + 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_192_NoPadding() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + iv: new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + plainBytes: new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + cipherBytes: new byte[] { 0xE9, 0x3E, 0xE5, 0xBF, 0x29, 0xFF, 0x95, 0x6E, 0x6B, 0xD6, 0xE8, 0x6F, 0x9F, 0x6A, 0x05, 0x62 }, + 8); + } + [Fact] public static void VerifyKnownTransform_CBC192_NoPadding_2() { @@ -348,6 +518,19 @@ public static void VerifyKnownTransform_CBC192_NoPadding_2() cipherBytes: new byte[] { 0x6C, 0xD0, 0x25, 0x13, 0xE8, 0xD4, 0xDC, 0x98, 0x6B, 0x4A, 0xFE, 0x08, 0x7A, 0x60, 0xBD, 0x0C }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_192_NoPadding_2() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + iv: new byte[] { 0x81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + plainBytes: new byte[] { 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + cipherBytes: new byte[] { 0xAA, 0xB9, 0xD1, 0x9F, 0x4A, 0x66, 0xEF, 0x3A, 0x9A, 0x60, 0xAF, 0x10, 0xD8, 0x3D, 0x84, 0x10 }, + 128); + } + [Fact] public static void WrongKeyFailDecrypt() { @@ -442,6 +625,307 @@ public static void WrongKeyFailDecrypt_2() } } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_128_NoPadding_4() + { + // NIST CAVP AESMMT.ZIP CFB8MMT128.rsp, [ENCRYPT] COUNT=4 + // plaintext not extended + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "5d5e7f20e0a66d3e09e0e5a9912f8a46".HexToByteArray(), + iv: "052d7ea0ad1f2956a23b27afe1d87b6b".HexToByteArray(), + plainBytes: "b84a90fc6d".HexToByteArray(), + cipherBytes: "1a9a61c307".HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding_4_Fails() + { + Assert.Throws(() => + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "5d5e7f20e0a66d3e09e0e5a9912f8a46".HexToByteArray(), + iv: "052d7ea0ad1f2956a23b27afe1d87b6b".HexToByteArray(), + plainBytes: "b84a90fc6d".HexToByteArray(), + cipherBytes: "1a9a61c307".HexToByteArray(), + feedbackSize: 128) + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_PKCS7_4() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.PKCS7, + key: "5d5e7f20e0a66d3e09e0e5a9912f8a46".HexToByteArray(), + iv: "052d7ea0ad1f2956a23b27afe1d87b6b".HexToByteArray(), + plainBytes: "b84a90fc6d".HexToByteArray(), + cipherBytes: "1aae9ac4cd4742f28ed593b48efce7cd".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_128_PKCS7_4() + { + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.PKCS7, + key: "5d5e7f20e0a66d3e09e0e5a9912f8a46".HexToByteArray(), + iv: "052d7ea0ad1f2956a23b27afe1d87b6b".HexToByteArray(), + plainBytes: "b84a90fc6d".HexToByteArray(), + cipherBytes: "1a9a61c307a4".HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_128_NoPadding_0_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT128.rsp, [ENCRYPT] COUNT=0 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "c57d699d89df7cfbef71c080a6b10ac3".HexToByteArray(), + iv: "fcb2bc4c006b87483978796a2ae2c42e".HexToByteArray(), + plainBytes: ("61" + "000000000000000000000000000000").HexToByteArray(), + cipherBytes: ("24" + "D89FE413C3D37172D6B577E2F94997").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_128_NoPadding_9_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT128.rsp, [ENCRYPT] COUNT=9 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "3a6f9159263fa6cef2a075caface5817".HexToByteArray(), + iv: "0fc23662b7dbf73827f0c7de321ca36e".HexToByteArray(), + plainBytes: ("87efeb8d559ed3367728" + "000000000000").HexToByteArray(), + cipherBytes: ("8e9c50425614d540ce11" + "7DD85E93D8E0").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_192_NoPadding_0_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT192.rsp, [ENCRYPT] COUNT=0 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "32a1b0e3da368db563d7316b9779d3327e53d9a6d287ed97".HexToByteArray(), + iv: "3dd0e7e21f09d5842f3a699da9b57346".HexToByteArray(), + plainBytes: ("54" + "000000000000000000000000000000").HexToByteArray(), + cipherBytes: ("6d" + "B3F513638A136D73873517AF1A770F").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_192_NoPadding_9_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT192.rsp, [ENCRYPT] COUNT=9 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "537e7bf661fd4024a024613f15b13690f7d0c847c1e18965".HexToByteArray(), + iv: "3a81f9d9d3c155b0caad5d73349476fc".HexToByteArray(), + plainBytes: ("d3d8b9b984adc24237ee" + "000000000000").HexToByteArray(), + cipherBytes: ("3879fea72ac99929e53a" + "39552A575D73").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_256_NoPadding_0_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT256.rsp, [ENCRYPT] COUNT=0 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "34e8091cee09f1bd3ebf1e8f05f51bfbd4899ef2ae006a3a0f7875052cdd46c8".HexToByteArray(), + iv: "43eb4dcc4b04a80216a20e4a09a7abb5".HexToByteArray(), + plainBytes: ("f9" + "000000000000000000000000000000").HexToByteArray(), + cipherBytes: ("28" + "26199F76D20BE53AB4D146CFC6D281").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_256_NoPadding_9_Extended() + { + // NIST CAVP AESMMT.ZIP CFB8MMT256.rsp, [ENCRYPT] COUNT=9 + // plaintext zero-extended to a full block, cipherBytes extended value + // provided by .NET Framework + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "ebbb4566b5e182e0f072466b0b311df38f9175bc0213a5530bce2ec4d74f400d".HexToByteArray(), + iv: "0956a48e01002c9e16376d6e308dbad1".HexToByteArray(), + plainBytes: ("b0fe25ac8d3d28a2f471" + "000000000000").HexToByteArray(), + cipherBytes: ("638c6823e7256fb5626e" + "5EE5C1D7FA17").HexToByteArray(), + feedbackSize: 8); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding_0() + { + // NIST CAVP AESMMT.ZIP CFB128MMT128.rsp, [ENCRYPT] COUNT=0 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "085b8af6788fa6bc1a0b47dcf50fbd35".HexToByteArray(), + iv: "58cb2b12bb52c6f14b56da9210524864".HexToByteArray(), + plainBytes: "4b5a872260293312eea1a570fd39c788".HexToByteArray(), + cipherBytes: "e92c80e0cfb6d8b1c27fd58bc3708b16".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_128_NoPadding_1_Extended() + { + // NIST CAVP AESMMT.ZIP CFB128MMT128.rsp, [ENCRYPT] COUNT=1 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "701ccc4c0e36e512ce077f5af6ccb957".HexToByteArray(), + iv: "5337ddeaf89a00dd4d58d860de968469".HexToByteArray(), + plainBytes: "cc1172f2f80866d0768b25f70fcf6361aab7c627c8488f97525d7d88949beeea".HexToByteArray(), + cipherBytes: "cdcf093bb7840df225683b58a479b00d5de5553a7e85eae4b70bf46dc729dd31".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_192_NoPadding_0_Extended() + { + // NIST CAVP AESMMT.ZIP CFB128MMT192.rsp, [ENCRYPT] COUNT=0 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "1bbb30016d3a908827693352ece9833415433618b1d97595".HexToByteArray(), + iv: "b2b48e8d60240bf2d9fa05cc2f90c161".HexToByteArray(), + plainBytes: "b4e499de51e646fad80030da9dc5e7e2".HexToByteArray(), + cipherBytes: "8b7ba98982063a55fca3492269bbe437".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_192_NoPadding_1_Extended() + { + // NIST CAVP AESMMT.ZIP CFB128MMT192.rsp, [ENCRYPT] COUNT=1 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "69f9d29885743826d7c5afc53637e6b1fa9512a10eea9ca9".HexToByteArray(), + iv: "3743793c7144a755768437f4ef5a33c8".HexToByteArray(), + plainBytes: "f84ebf42a758971c369949e288f775c9cf6a82ab51b286576b45652cd68c3ce6".HexToByteArray(), + cipherBytes: "a3bd28bb817bdb3f6492827f2aa3e6e134c254129d8f20dbc92389b7d89702d6".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 128)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.ECB, 0)] + public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); + + using (Aes aes = AesFactory.Create()) + { + aes.Mode = cipherMode; + + if (feedbackSize > 0) + { + aes.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = aes.CreateEncryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 128)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.ECB, 0)] + public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "2981761d979bb1765a28b2dd19125b54".HexToByteArray(); + var key = "e1c6e6884eee69552dbfee21f22ca92685d5d08ef0e3f37e5b338c533bb8d72c".HexToByteArray(); + var iv = "cea9f23ae87a637ab0cda6381ecc1202".HexToByteArray(); + + using (Aes aes = AesFactory.Create()) + { + aes.Mode = cipherMode; + aes.Key = key; + aes.IV = iv; + aes.Padding = PaddingMode.None; + + if (feedbackSize > 0) + { + aes.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = aes.CreateDecryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_256_NoPadding_0_Extended() + { + // NIST CAVP AESMMT.ZIP CFB128MMT256.rsp, [ENCRYPT] COUNT=0 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "e1c6e6884eee69552dbfee21f22ca92685d5d08ef0e3f37e5b338c533bb8d72c".HexToByteArray(), + iv: "cea9f23ae87a637ab0cda6381ecc1202".HexToByteArray(), + plainBytes: "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(), + cipherBytes: "2981761d979bb1765a28b2dd19125b54".HexToByteArray(), + feedbackSize: 128); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB128_256_NoPadding_1_Extended() + { + // NIST CAVP AESMMT.ZIP CFB128MMT256.rsp, [ENCRYPT] COUNT=1 + TestAesTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "ae59254c66d8f533e7f5002ced480c33984a421d7816e27be66c34c19bfbc2a8".HexToByteArray(), + iv: "821dd21653ece3af675cd25d26017ae3".HexToByteArray(), + plainBytes: "3cb4f17e775c2d6d06dd60f15d6c3a103e5131727f9c6cb80d13e00f316eb904".HexToByteArray(), + cipherBytes: "ae375db9f28148c460f6c6b6665fcc2ff6b50b8eaf82c64bba8c649efd4731bc".HexToByteArray(), + feedbackSize: 128); + } + [Fact] public static void AesZeroPad() { @@ -555,7 +1039,8 @@ private static void TestAesDecrypt( byte[] key, byte[] iv, byte[] encryptedBytes, - byte[] expectedAnswer) + byte[] expectedAnswer, + int? feedbackSize = default) { byte[] decryptedBytes; @@ -563,6 +1048,11 @@ private static void TestAesDecrypt( { aes.Mode = mode; aes.Key = key; + + if (feedbackSize.HasValue) + { + aes.FeedbackSize = feedbackSize.Value; + } if (iv != null) { @@ -588,7 +1078,8 @@ private static void TestAesTransformDirectKey( byte[] key, byte[] iv, byte[] plainBytes, - byte[] cipherBytes) + byte[] cipherBytes, + int? feedbackSize = default) { byte[] liveEncryptBytes; byte[] liveDecryptBytes; @@ -598,12 +1089,17 @@ private static void TestAesTransformDirectKey( aes.Mode = cipherMode; aes.Padding = paddingMode; + if (feedbackSize.HasValue) + { + aes.FeedbackSize = feedbackSize.Value; + } + liveEncryptBytes = AesEncryptDirectKey(aes, key, iv, plainBytes); liveDecryptBytes = AesDecryptDirectKey(aes, key, iv, cipherBytes); } - Assert.Equal(plainBytes, liveDecryptBytes); Assert.Equal(cipherBytes, liveEncryptBytes); + Assert.Equal(plainBytes, liveDecryptBytes); } private static byte[] AesEncryptDirectKey(Aes aes, byte[] key, byte[] iv, byte[] plainBytes) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesContractTests.cs index 2cab256ad661..8e430d44cd46 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesContractTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesContractTests.cs @@ -93,6 +93,65 @@ public static void InvalidKeySizes(int invalidKeySize, bool skipOnNetfx) } } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(64, false)] + [InlineData(256, true)] + [InlineData(127, true)] + public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) + { + using (Aes aes = AesFactory.Create()) + { + aes.GenerateKey(); + aes.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.Throws(() => + { + aes.FeedbackSize = feedbackSize; + }); + } + else + { + aes.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual AES instantiation. + + Assert.Throws(() => aes.CreateDecryptor()); + Assert.Throws(() => aes.CreateEncryptor()); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(8)] + [InlineData(128)] + public static void ValidCFBFeedbackSizes(int feedbackSize) + { + using (Aes aes = AesFactory.Create()) + { + aes.GenerateKey(); + aes.Mode = CipherMode.CFB; + + aes.FeedbackSize = feedbackSize; + + using var decryptor = aes.CreateDecryptor(); + using var encryptor = aes.CreateEncryptor(); + Assert.NotNull(decryptor); + Assert.NotNull(encryptor); + } + } + [Theory] [InlineData(64, false)] // smaller than default BlockSize [InlineData(129, false)] // larger than default BlockSize diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesModeTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesModeTests.cs index 34fa904e58f0..e52bf61ac307 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesModeTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesModeTests.cs @@ -21,6 +21,18 @@ public static void SupportsECB() SupportsMode(CipherMode.ECB); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void SupportsCFB() + { + SupportsMode(CipherMode.CFB); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows7))] + public static void Windows7DoesNotSupportCFB() + { + DoesNotSupportMode(CipherMode.CFB); + } + [Fact] public static void DoesNotSupportCTS() { @@ -50,7 +62,7 @@ private static void DoesNotSupportMode(CipherMode mode) // aes.CreateEncryptor() (with an invalid Mode value) // transform.Transform[Final]Block() (with an invalid Mode value) - Assert.Throws( + Assert.ThrowsAny( () => { aes.Mode = mode; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESCipherTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESCipherTests.cs index dcfd8ddcd64d..bb13c39c0f93 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESCipherTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESCipherTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.IO; using System.Text; using Test.Cryptography; using Xunit; @@ -252,6 +253,299 @@ public static void EncryptWithLargeOutputBuffer(bool blockAlignedOutput) } } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_0() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=0 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "fb978a0b6dc2c467".HexToByteArray(), + iv: "8b97579ea5ac300f".HexToByteArray(), + plainBytes: "80".HexToByteArray(), + cipherBytes: "82".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_1() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=1 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "9b04c86dd31a8a58".HexToByteArray(), + iv: "52cd77d49fc72347".HexToByteArray(), + plainBytes: "2fef".HexToByteArray(), + cipherBytes: "0fe4".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_2() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=2 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "fbb667e340586b5b".HexToByteArray(), + iv: "459e8b8736715791".HexToByteArray(), + plainBytes: "061704".HexToByteArray(), + cipherBytes: "8e9071".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.ECB, 0)] + public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); + + using (DES des = DESFactory.Create()) + { + des.Mode = cipherMode; + + if (feedbackSize > 0) + { + des.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = des.CreateEncryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.ECB, 0)] + public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "4e6f77206973207468652074696d6520666f7220616c6c20".HexToByteArray(); + var key = "4a575d02515d40b0".HexToByteArray(); + var iv = "ab27e9f02affa532".HexToByteArray(); + + using (DES des = DESFactory.Create()) + { + des.Mode = cipherMode; + des.Key = key; + des.IV = iv; + des.Padding = PaddingMode.None; + + if (feedbackSize > 0) + { + des.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = des.CreateDecryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_3() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=3 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "4a575d02515d40b0".HexToByteArray(), + iv: "ab27e9f02affa532".HexToByteArray(), + plainBytes: "55f75b95".HexToByteArray(), + cipherBytes: "34aa8679".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_PKCS7_3() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=3 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.PKCS7, + key: "4a575d02515d40b0".HexToByteArray(), + iv: "ab27e9f02affa532".HexToByteArray(), + plainBytes: "55f75b95".HexToByteArray(), + cipherBytes: "34aa8679ca".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_4() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=4 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "91a834855e6bab31".HexToByteArray(), + iv: "7838aaad4e64640b".HexToByteArray(), + plainBytes: "c3851c0ab4".HexToByteArray(), + cipherBytes: "84844450f0".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_5() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=5 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "04d923abd9291c3e".HexToByteArray(), + iv: "191f8794944e601c".HexToByteArray(), + plainBytes: "6fe8f67d2af1".HexToByteArray(), + cipherBytes: "6012c9171bb8".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_6() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=6 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "a7799e7f5dfe54ce".HexToByteArray(), + iv: "370184c749d04a20".HexToByteArray(), + plainBytes: "2b4228b769795b".HexToByteArray(), + cipherBytes: "58d3de76687976".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_7() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=7 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "6bfe3d3df8c1e0d3".HexToByteArray(), + iv: "51e4c5c29e858da6".HexToByteArray(), + plainBytes: "4cb3554fd0b9ec82".HexToByteArray(), + cipherBytes: "16b3595259693776".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_8() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=8 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "e0264aec13e63db9".HexToByteArray(), + iv: "bd8795dba79930d6".HexToByteArray(), + plainBytes: "79068e2943f02914af".HexToByteArray(), + cipherBytes: "fe78cb95ce9e4cac2f".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_9() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=9 + // used only key1, cipherBytes computed using openssl + TestDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "7ca28938ba6bec1f".HexToByteArray(), + iv: "953896586e49d38f".HexToByteArray(), + plainBytes: "2ea956d4a211db6859b7".HexToByteArray(), + cipherBytes: "81b850bf481db5df0437".HexToByteArray(), + feedbackSize: 8 + ); + } + + private static void TestDESTransformDirectKey( + CipherMode cipherMode, + PaddingMode paddingMode, + byte[] key, + byte[] iv, + byte[] plainBytes, + byte[] cipherBytes, + int? feedbackSize = default) + { + byte[] liveEncryptBytes; + byte[] liveDecryptBytes; + + using (DES des = DESFactory.Create()) + { + des.Mode = cipherMode; + des.Padding = paddingMode; + + if (feedbackSize.HasValue) + { + des.FeedbackSize = feedbackSize.Value; + } + + liveEncryptBytes = DESEncryptDirectKey(des, key, iv, plainBytes); + liveDecryptBytes = DESDecryptDirectKey(des, key, iv, cipherBytes); + } + + Assert.Equal(cipherBytes, liveEncryptBytes); + Assert.Equal(plainBytes, liveDecryptBytes); + } + + private static byte[] DESEncryptDirectKey(DES des, byte[] key, byte[] iv, byte[] plainBytes) + { + using (MemoryStream output = new MemoryStream()) + using (CryptoStream cryptoStream = new CryptoStream(output, des.CreateEncryptor(key, iv), CryptoStreamMode.Write)) + { + cryptoStream.Write(plainBytes, 0, plainBytes.Length); + cryptoStream.FlushFinalBlock(); + + return output.ToArray(); + } + } + + private static byte[] DESDecryptDirectKey(DES des, byte[] key, byte[] iv, byte[] cipherBytes) + { + using (MemoryStream output = new MemoryStream()) + using (CryptoStream cryptoStream = new CryptoStream(output, des.CreateDecryptor(key, iv), CryptoStreamMode.Write)) + { + cryptoStream.Write(cipherBytes, 0, cipherBytes.Length); + cryptoStream.FlushFinalBlock(); + + return output.ToArray(); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESContractTests.cs new file mode 100644 index 000000000000..4fe0e86cb5f2 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DES/DESContractTests.cs @@ -0,0 +1,123 @@ +// 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.Collections.Generic; +using System.IO; +using System.Text; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Encryption.Des.Tests +{ + public static class DesContractTests + { + // cfb not available on windows 7 + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows7))] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(8, false)] + [InlineData(64, false)] + [InlineData(256, true)] + [InlineData(128, true)] + [InlineData(127, true)] + public static void Windows7DoesNotSupportCFB(int feedbackSize, bool discoverableInSetter) + { + using (DES des = DESFactory.Create()) + { + des.GenerateKey(); + des.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.ThrowsAny(() => + { + des.FeedbackSize = feedbackSize; + }); + } + else + { + des.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual DES instantiation. + + Assert.ThrowsAny(() => + { + return des.CreateDecryptor(); + }); + Assert.ThrowsAny(() => + { + return des.CreateEncryptor(); + }); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(64, false)] + [InlineData(256, true)] + [InlineData(128, true)] + [InlineData(127, true)] + public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) + { + using (DES des = DESFactory.Create()) + { + des.GenerateKey(); + des.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.Throws(() => + { + des.FeedbackSize = feedbackSize; + }); + } + else + { + des.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual DES instantiation. + + Assert.Throws(() => des.CreateDecryptor()); + Assert.Throws(() => des.CreateEncryptor()); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(8)] + public static void ValidCFBFeedbackSizes(int feedbackSize) + { + using (DES des = DESFactory.Create()) + { + des.GenerateKey(); + des.Mode = CipherMode.CFB; + + des.FeedbackSize = feedbackSize; + + using var decryptor = des.CreateDecryptor(); + using var encryptor = des.CreateEncryptor(); + Assert.NotNull(decryptor); + Assert.NotNull(encryptor); + } + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2CipherTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2CipherTests.cs index 5e62fc945b8c..02e89924d07a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2CipherTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2CipherTests.cs @@ -162,6 +162,67 @@ public static void RC2RoundTrip(CipherMode cipherMode, PaddingMode paddingMode, } } + [Theory] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.ECB, 0)] + public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); + + using (RC2 rc2 = RC2Factory.Create()) + { + rc2.Mode = cipherMode; + + if (feedbackSize > 0) + { + rc2.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = rc2.CreateEncryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [Theory] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.ECB, 0)] + public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "896072ab28e5fdfc".HexToByteArray(); + var key = "3000000000000000".HexToByteArray(); + var iv = "3000000000000000".HexToByteArray(); + + using (RC2 rc2 = RC2Factory.Create()) + { + rc2.Mode = cipherMode; + rc2.Key = key; + rc2.IV = iv; + rc2.Padding = PaddingMode.None; + + if (feedbackSize > 0) + { + rc2.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = rc2.CreateDecryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + [Fact] public static void RC2ReuseEncryptorDecryptor() { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2ContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2ContractTests.cs new file mode 100644 index 000000000000..05550742344d --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RC2/RC2ContractTests.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using System.Text; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Encryption.RC2.Tests +{ + using RC2 = System.Security.Cryptography.RC2; + + public static class RC2ContractTests + { + [Theory] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(8, false)] + [InlineData(64, false)] + [InlineData(256, true)] + [InlineData(128, true)] + [InlineData(127, true)] + public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) + { + using (RC2 rc2 = RC2Factory.Create()) + { + rc2.GenerateKey(); + rc2.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.Throws(() => + { + rc2.FeedbackSize = feedbackSize; + }); + } + else + { + rc2.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual RC2 instantiation. + + Assert.Throws(() => rc2.CreateDecryptor()); + Assert.Throws(() => rc2.CreateEncryptor()); + } + } + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESCipherTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESCipherTests.cs index 520a991af7de..cff95ea56103 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESCipherTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESCipherTests.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.IO; using System.Text; using Test.Cryptography; using Xunit; @@ -40,6 +41,455 @@ public static void TripleDESInvalidKeySizes() } } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_0() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=0 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "fb978a0b6dc2c467e3cb52329de95161fb978a0b6dc2c467".HexToByteArray(), + iv: "8b97579ea5ac300f".HexToByteArray(), + plainBytes: "80".HexToByteArray(), + cipherBytes: "05".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_1() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=1 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "9b04c86dd31a8a589876101549d6e0109b04c86dd31a8a58".HexToByteArray(), + iv: "52cd77d49fc72347".HexToByteArray(), + plainBytes: "2fef".HexToByteArray(), + cipherBytes: "5818".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_2() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=2 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "fbb667e340586b5b5ef7c87049b93257fbb667e340586b5b".HexToByteArray(), + iv: "459e8b8736715791".HexToByteArray(), + plainBytes: "061704".HexToByteArray(), + cipherBytes: "93b378".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_PKCS7_2() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=2 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.PKCS7, + key: "fbb667e340586b5b5ef7c87049b93257fbb667e340586b5b".HexToByteArray(), + iv: "459e8b8736715791".HexToByteArray(), + plainBytes: "061704".HexToByteArray(), + cipherBytes: "93b37808".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_PKCS7_2() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=2 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.PKCS7, + key: "fbb667e340586b5b5ef7c87049b93257fbb667e340586b5b".HexToByteArray(), + iv: "459e8b8736715791".HexToByteArray(), + plainBytes: "061704".HexToByteArray(), + cipherBytes: "931f41eccdab4f99".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_3() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=3 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "4a575d02515d40b0a40d830bd9b315134a575d02515d40b0".HexToByteArray(), + iv: "ab27e9f02affa532".HexToByteArray(), + plainBytes: "55f75b95".HexToByteArray(), + cipherBytes: "2ef5dddc".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_4() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=4 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "91a834855e6bab31c7fd6be657ceb9ec91a834855e6bab31".HexToByteArray(), + iv: "7838aaad4e64640b".HexToByteArray(), + plainBytes: "c3851c0ab4".HexToByteArray(), + cipherBytes: "fe451f35f1".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_5() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=5 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "04d923abd9291c3e4954a8b52fdabcc804d923abd9291c3e".HexToByteArray(), + iv: "191f8794944e601c".HexToByteArray(), + plainBytes: "6fe8f67d2af1".HexToByteArray(), + cipherBytes: "3bd78a8d24ad".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_6() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=6 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "a7799e7f5dfe54ce13376401e96de075a7799e7f5dfe54ce".HexToByteArray(), + iv: "370184c749d04a20".HexToByteArray(), + plainBytes: "2b4228b769795b".HexToByteArray(), + cipherBytes: "6f32e4495e4259".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_7() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=7 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "6bfe3d3df8c1e0d34ffe0dbf854c940e6bfe3d3df8c1e0d3".HexToByteArray(), + iv: "51e4c5c29e858da6".HexToByteArray(), + plainBytes: "4cb3554fd0b9ec82".HexToByteArray(), + cipherBytes: "72e1738d80d285e2".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_8() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=8 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "e0264aec13e63db991f8c120c4b9b6dae0264aec13e63db9".HexToByteArray(), + iv: "bd8795dba79930d6".HexToByteArray(), + plainBytes: "79068e2943f02914af".HexToByteArray(), + cipherBytes: "9b78c5636c5965f88e".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB8_NoPadding_9() + { + // NIST CAVS TDESMMT.ZIP TCFB8MMT2.rsp, [DECRYPT] COUNT=9 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "7ca28938ba6bec1ffec78f7cd69761947ca28938ba6bec1f".HexToByteArray(), + iv: "953896586e49d38f".HexToByteArray(), + plainBytes: "2ea956d4a211db6859b7".HexToByteArray(), + cipherBytes: "f20e536674a66fa73805".HexToByteArray(), + feedbackSize: 8 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_0() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=0 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "9ee0b59b25865154588551341c4fef9e9ee0b59b25865154".HexToByteArray(), + iv: "6e37d197376db595".HexToByteArray(), + plainBytes: "dcd3cf9746d6e42b".HexToByteArray(), + cipherBytes: "63cad52260e0a1cd".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.CFB, 64)] + [InlineData(CipherMode.ECB, 0)] + public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); + + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.Mode = cipherMode; + + if (feedbackSize > 0) + { + tdes.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = tdes.CreateEncryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(CipherMode.CBC, 0)] + [InlineData(CipherMode.CFB, 8)] + [InlineData(CipherMode.CFB, 64)] + [InlineData(CipherMode.ECB, 0)] + public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) + { + // AppleCCCryptor does not allow calling Reset on CFB cipher. + // this test validates that the behavior is taken into consideration. + var input = "896072ab28e5fdfc9e8b3610627bf27a".HexToByteArray(); + var key = "c179d0fdd073a1910e51f1d5fe70047ac179d0fdd073a191".HexToByteArray(); + var iv = "b956d5426d02b247".HexToByteArray(); + + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.Mode = cipherMode; + tdes.Key = key; + tdes.IV = iv; + tdes.Padding = PaddingMode.None; + + if (feedbackSize > 0) + { + tdes.FeedbackSize = feedbackSize; + } + + using (ICryptoTransform transform = tdes.CreateDecryptor()) + { + byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); + byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); + + Assert.Equal(output1, output2); + } + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_1() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=1 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "c179d0fdd073a1910e51f1d5fe70047ac179d0fdd073a191".HexToByteArray(), + iv: "b956d5426d02b247".HexToByteArray(), + plainBytes: "32bd529065e26a27643097925e3a726b".HexToByteArray(), + cipherBytes: "896072ab28e5fdfc9e8b3610627bf27a".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_2() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=2 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "a8084a04495bfb45b3575ee03d732967a8084a04495bfb45".HexToByteArray(), + iv: "00fd7b4fdb4b3382".HexToByteArray(), + plainBytes: "c20c7041007a67de7b4355be7406095496923b75dfb98080".HexToByteArray(), + cipherBytes: "9198c138edb037de25d0bcdebe7b9be10ebd7e7ea103edae".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_3() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=3 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "c1497fdf67cecbab80d543f16d13c8d5c1497fdf67cecbab".HexToByteArray(), + iv: "a1241ca0fe9378cd".HexToByteArray(), + plainBytes: "157dcfa7ad6758335e561fa7dd7f98dca592e9128e7be30ccd1af7dc5a4536d5".HexToByteArray(), + cipherBytes: "08fcace492f82282fb3255884a64a231dd438069ffbcb432bd7ec446f5b8adfd".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_4() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=4 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "fd0e3262ec38fe5710389d0779c2fb43fd0e3262ec38fe57".HexToByteArray(), + iv: "33c9e4adfb4634ac".HexToByteArray(), + plainBytes: "37536dda516aab8a992131004134ce48c56fee05261164aae0a88db0f43410617f105e20940cf3e9".HexToByteArray(), + cipherBytes: "80e8a96c3fe83857fc738ac7b6639f0d8c28bfa617c56a60fd1b8fbdc36afe9ce3151e161fa5e3a7".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_5() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=5 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "ae32253be61040157a7c10b6011fcde3ae32253be6104015".HexToByteArray(), + iv: "47be2286dbccdfe6".HexToByteArray(), + plainBytes: "e579282129c123c914c700ad8c099b593fe83fdef7be7e5ffb36add9c6b91644cc79c1e457212017488963e16198c528".HexToByteArray(), + cipherBytes: "7185c5800ca4d5432b50f5b7920e26296c2913e7e3f847a1ef639e156ba4f9ec6e4b36ded885601d2b9d22f19dc3829f".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_6() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=6 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "df83498cec83084acb7aaef26e58f1e0df83498cec83084a".HexToByteArray(), + iv: "158d2ca6e70b18f6".HexToByteArray(), + plainBytes: "4fb7cf2a244ff20beddf8719b2d9c78ab0710703036f804f08bc1f7927ea9906ba1ef57afd1553c5304c0b72694cd88bb6cb1289772dfff0".HexToByteArray(), + cipherBytes: "158b396cd1969a07042e808d0c875d74166ce77291df233fe300c29c5a30b1946575ec02042093537dae3f8d51ed96906e601d9da6e34e14".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_7() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=7 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "ce31cd2067c157199bfb3b8ad9ef9223ce31cd2067c15719".HexToByteArray(), + iv: "d31741512b6a7471".HexToByteArray(), + plainBytes: "a0447f5abebf8623db81b600699ce8373353442908fefe8c63f5e29e22ba1057f759635505ed0ac059887def2d31f6996128d4fbe2df6534429744d7f6496768".HexToByteArray(), + cipherBytes: "b3a791b128f003bc28cd17bbb5c68990faec73f88c10b664f1349b045f3fba24c5f51bbb10259c41a72492c2377bb331b6dd34fea25c2eea8adc461bd0c78d6b".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_8() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=8 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "5bbc3423bf67e05262d65740708019f15bbc3423bf67e052".HexToByteArray(), + iv: "14544ea4813c49d9".HexToByteArray(), + plainBytes: "a21f26496f74fd8a93aa5423e2a4fc76facbff015db2f4ef14f08b8c13a29d0561e4e57d04b0b00211f8fba46d025a9c0727c8aebb7d25f27f1606321909ba50e660fa25358c63f9".HexToByteArray(), + cipherBytes: "c3acc89b9b6037effc65eacdc23b36c38d0e609566d360eba594e4481108983b4a67a5d9647c776ad5fcc4639116ca95734bd8a3df800fb9a6526a7b29a9fc3cc29079715f44f865".HexToByteArray(), + feedbackSize: 64 + ); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + public static void VerifyKnownTransform_CFB64_NoPadding_9() + { + // NIST CAVS TDESMMT.ZIP TCFB64MMT2.rsp, [DECRYPT] COUNT=9 + TestTripleDESTransformDirectKey( + CipherMode.CFB, + PaddingMode.None, + key: "197c738cfb6e0bc2fee57ffb1ca72675197c738cfb6e0bc2".HexToByteArray(), + iv: "f1a42447a333caa3".HexToByteArray(), + plainBytes: "6f914b6996ee8e7ea625b2fddd7677b4384320be0aba3af81d1210965ac37983f340d5698ddf35d45dfccbf783a50c6eed1a730b5c98675cb6b7645fc8374e10d8b340c44b0eae988c1ef635fab913da".HexToByteArray(), + cipherBytes: "8aabb83216e4bd5a3dd20586e598bb8e956dcbf7d09cde17a2cf8b7a788ecb853503ae5981004dfa644300b115f8d1ae0c7f30f25e70e86c4adc51620fd6c71301325c9bdc8dca16588eac08fe6aedfd".HexToByteArray(), + feedbackSize: 64 + ); + } + + private static byte[] TripleDESEncryptDirectKey(TripleDES tdes, byte[] key, byte[] iv, byte[] plainBytes) + { + using (MemoryStream output = new MemoryStream()) + using (CryptoStream cryptoStream = new CryptoStream(output, tdes.CreateEncryptor(key, iv), CryptoStreamMode.Write)) + { + cryptoStream.Write(plainBytes, 0, plainBytes.Length); + cryptoStream.FlushFinalBlock(); + + return output.ToArray(); + } + } + + private static byte[] TripleDESDecryptDirectKey(TripleDES tdes, byte[] key, byte[] iv, byte[] cipherBytes) + { + using (MemoryStream output = new MemoryStream()) + using (CryptoStream cryptoStream = new CryptoStream(output, tdes.CreateDecryptor(key, iv), CryptoStreamMode.Write)) + { + cryptoStream.Write(cipherBytes, 0, cipherBytes.Length); + cryptoStream.FlushFinalBlock(); + + return output.ToArray(); + } + } + + private static void TestTripleDESTransformDirectKey( + CipherMode cipherMode, + PaddingMode paddingMode, + byte[] key, + byte[] iv, + byte[] plainBytes, + byte[] cipherBytes, + int? feedbackSize = default) + { + byte[] liveEncryptBytes; + byte[] liveDecryptBytes; + + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.Mode = cipherMode; + tdes.Padding = paddingMode; + + if (feedbackSize.HasValue) + { + tdes.FeedbackSize = feedbackSize.Value; + } + + liveEncryptBytes = TripleDESEncryptDirectKey(tdes, key, iv, plainBytes); + liveDecryptBytes = TripleDESDecryptDirectKey(tdes, key, iv, cipherBytes); + } + + Assert.Equal(cipherBytes, liveEncryptBytes); + Assert.Equal(plainBytes, liveDecryptBytes); + } + [Theory] [InlineData(192, "e56f72478c7479d169d54c0548b744af5b53efb1cdd26037", "c5629363d957054eba793093b83739bb78711db221a82379")] [InlineData(128, "1387b981dbb40f34b915c4ed89fd681a740d3b4869c0b575", "c5629363d957054eba793093b83739bb")] diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESContractTests.cs new file mode 100644 index 000000000000..91e44797e2c6 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESContractTests.cs @@ -0,0 +1,121 @@ +// 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.Text; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Encryption.TripleDes.Tests +{ + public static class TripleDESContractTests + { + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows7))] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(8, false)] + [InlineData(64, false)] + [InlineData(256, true)] + [InlineData(128, true)] + [InlineData(127, true)] + public static void Windows7DoesNotSupportCFB(int feedbackSize, bool discoverableInSetter) + { + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.GenerateKey(); + tdes.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.ThrowsAny(() => + { + tdes.FeedbackSize = feedbackSize; + }); + } + else + { + tdes.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual AES instantiation. + + Assert.ThrowsAny(() => + { + return tdes.CreateDecryptor(); + }); + Assert.ThrowsAny(() => + { + return tdes.CreateEncryptor(); + }); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(0, true)] + [InlineData(1, true)] + [InlineData(7, true)] + [InlineData(9, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, true)] + [InlineData(256, true)] + [InlineData(128, true)] + [InlineData(127, true)] + public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) + { + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.GenerateKey(); + tdes.Mode = CipherMode.CFB; + + if (discoverableInSetter) + { + // there are some key sizes that are invalid for any of the modes, + // so the exception is thrown in the setter + Assert.Throws(() => + { + tdes.FeedbackSize = feedbackSize; + }); + } + else + { + tdes.FeedbackSize = feedbackSize; + + // however, for CFB only few sizes are valid. Those should throw in the + // actual AES instantiation. + + Assert.Throws(() => tdes.CreateDecryptor()); + Assert.Throws(() => tdes.CreateEncryptor()); + } + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] + [InlineData(8)] + [InlineData(64)] + public static void ValidCFBFeedbackSizes(int feedbackSize) + { + using (TripleDES tdes = TripleDESFactory.Create()) + { + tdes.GenerateKey(); + tdes.Mode = CipherMode.CFB; + + tdes.FeedbackSize = feedbackSize; + + using var decryptor = tdes.CreateDecryptor(); + using var encryptor = tdes.CreateEncryptor(); + Assert.NotNull(decryptor); + Assert.NotNull(encryptor); + } + } + } +} diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.c index 278ed6b3e548..3bf564695203 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.c @@ -16,6 +16,8 @@ c_static_assert(PAL_AlgorithmRC2 == kCCAlgorithmRC2); c_static_assert(PAL_ChainingModeECB == kCCModeECB); c_static_assert(PAL_ChainingModeCBC == kCCModeCBC); +c_static_assert(PAL_ChainingModeCFB == kCCModeCFB); +c_static_assert(PAL_ChainingModeCFB8 == kCCModeCFB8); c_static_assert(PAL_PaddingModeNone == ccNoPadding); c_static_assert(PAL_PaddingModePkcs7 == ccPKCS7Padding); @@ -55,7 +57,7 @@ int32_t AppleCryptoNative_CryptorCreate(PAL_SymmetricOperation operation, assert(operation == PAL_OperationEncrypt || operation == PAL_OperationDecrypt); assert(algorithm == PAL_AlgorithmAES || algorithm == PAL_AlgorithmDES || algorithm == PAL_Algorithm3DES || algorithm == PAL_AlgorithmRC2); - assert(chainingMode == PAL_ChainingModeECB || chainingMode == PAL_ChainingModeCBC); + assert(chainingMode == PAL_ChainingModeECB || chainingMode == PAL_ChainingModeCBC || chainingMode == PAL_ChainingModeCFB || chainingMode == PAL_ChainingModeCFB8); assert(paddingMode == PAL_PaddingModeNone || paddingMode == PAL_PaddingModePkcs7); assert(options == 0); diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.h index 018e86ddac82..0238635dc2d6 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_symmetric.h @@ -29,6 +29,8 @@ enum { PAL_ChainingModeECB = 1, PAL_ChainingModeCBC = 2, + PAL_ChainingModeCFB = 3, + PAL_ChainingModeCFB8 = 10, }; typedef uint32_t PAL_ChainingMode; diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index 825c8845838a..6533de0a46c6 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -311,14 +311,20 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi REQUIRED_FUNCTION(ERR_reason_error_string) \ REQUIRED_FUNCTION(EVP_aes_128_cbc) \ REQUIRED_FUNCTION(EVP_aes_128_ccm) \ + REQUIRED_FUNCTION(EVP_aes_128_cfb128) \ + REQUIRED_FUNCTION(EVP_aes_128_cfb8) \ REQUIRED_FUNCTION(EVP_aes_128_ecb) \ REQUIRED_FUNCTION(EVP_aes_128_gcm) \ REQUIRED_FUNCTION(EVP_aes_192_cbc) \ REQUIRED_FUNCTION(EVP_aes_192_ccm) \ + REQUIRED_FUNCTION(EVP_aes_192_cfb128) \ + REQUIRED_FUNCTION(EVP_aes_192_cfb8) \ REQUIRED_FUNCTION(EVP_aes_192_ecb) \ REQUIRED_FUNCTION(EVP_aes_192_gcm) \ REQUIRED_FUNCTION(EVP_aes_256_cbc) \ REQUIRED_FUNCTION(EVP_aes_256_ccm) \ + REQUIRED_FUNCTION(EVP_aes_256_cfb128) \ + REQUIRED_FUNCTION(EVP_aes_256_cfb8) \ REQUIRED_FUNCTION(EVP_aes_256_ecb) \ REQUIRED_FUNCTION(EVP_aes_256_gcm) \ LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \ @@ -333,9 +339,12 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi REQUIRED_FUNCTION(EVP_CipherInit_ex) \ REQUIRED_FUNCTION(EVP_CipherUpdate) \ REQUIRED_FUNCTION(EVP_des_cbc) \ + REQUIRED_FUNCTION(EVP_des_cfb8) \ REQUIRED_FUNCTION(EVP_des_ecb) \ REQUIRED_FUNCTION(EVP_des_ede3) \ REQUIRED_FUNCTION(EVP_des_ede3_cbc) \ + REQUIRED_FUNCTION(EVP_des_ede3_cfb8) \ + REQUIRED_FUNCTION(EVP_des_ede3_cfb64) \ REQUIRED_FUNCTION(EVP_DigestFinal_ex) \ REQUIRED_FUNCTION(EVP_DigestInit_ex) \ REQUIRED_FUNCTION(EVP_DigestUpdate) \ @@ -704,14 +713,20 @@ FOR_ALL_OPENSSL_FUNCTIONS #define ERR_put_error ERR_put_error_ptr #define ERR_reason_error_string ERR_reason_error_string_ptr #define EVP_aes_128_cbc EVP_aes_128_cbc_ptr +#define EVP_aes_128_cfb8 EVP_aes_128_cfb8_ptr +#define EVP_aes_128_cfb128 EVP_aes_128_cfb128_ptr #define EVP_aes_128_ecb EVP_aes_128_ecb_ptr #define EVP_aes_128_gcm EVP_aes_128_gcm_ptr #define EVP_aes_128_ccm EVP_aes_128_ccm_ptr #define EVP_aes_192_cbc EVP_aes_192_cbc_ptr +#define EVP_aes_192_cfb8 EVP_aes_192_cfb8_ptr +#define EVP_aes_192_cfb128 EVP_aes_192_cfb128_ptr #define EVP_aes_192_ecb EVP_aes_192_ecb_ptr #define EVP_aes_192_gcm EVP_aes_192_gcm_ptr #define EVP_aes_192_ccm EVP_aes_192_ccm_ptr #define EVP_aes_256_cbc EVP_aes_256_cbc_ptr +#define EVP_aes_256_cfb8 EVP_aes_256_cfb8_ptr +#define EVP_aes_256_cfb128 EVP_aes_256_cfb128_ptr #define EVP_aes_256_ecb EVP_aes_256_ecb_ptr #define EVP_aes_256_gcm EVP_aes_256_gcm_ptr #define EVP_aes_256_ccm EVP_aes_256_ccm_ptr @@ -727,8 +742,11 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_CipherInit_ex EVP_CipherInit_ex_ptr #define EVP_CipherUpdate EVP_CipherUpdate_ptr #define EVP_des_cbc EVP_des_cbc_ptr +#define EVP_des_cfb8 EVP_des_cfb8_ptr #define EVP_des_ecb EVP_des_ecb_ptr #define EVP_des_ede3 EVP_des_ede3_ptr +#define EVP_des_ede3_cfb8 EVP_des_ede3_cfb8_ptr +#define EVP_des_ede3_cfb64 EVP_des_ede3_cfb64_ptr #define EVP_des_ede3_cbc EVP_des_ede3_cbc_ptr #define EVP_DigestFinal_ex EVP_DigestFinal_ex_ptr #define EVP_DigestInit_ex EVP_DigestInit_ex_ptr diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c index fa9b56c3a07c..40df23d96562 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c @@ -195,6 +195,16 @@ const EVP_CIPHER* CryptoNative_EvpAes128Gcm() return EVP_aes_128_gcm(); } +const EVP_CIPHER* CryptoNative_EvpAes128Cfb128() +{ + return EVP_aes_128_cfb128(); +} + +const EVP_CIPHER* CryptoNative_EvpAes128Cfb8() +{ + return EVP_aes_128_cfb8(); +} + const EVP_CIPHER* CryptoNative_EvpAes128Ccm() { return EVP_aes_128_ccm(); @@ -205,6 +215,16 @@ const EVP_CIPHER* CryptoNative_EvpAes192Ecb() return EVP_aes_192_ecb(); } +const EVP_CIPHER* CryptoNative_EvpAes192Cfb128() +{ + return EVP_aes_192_cfb128(); +} + +const EVP_CIPHER* CryptoNative_EvpAes192Cfb8() +{ + return EVP_aes_192_cfb8(); +} + const EVP_CIPHER* CryptoNative_EvpAes192Cbc() { return EVP_aes_192_cbc(); @@ -225,6 +245,16 @@ const EVP_CIPHER* CryptoNative_EvpAes256Ecb() return EVP_aes_256_ecb(); } +const EVP_CIPHER* CryptoNative_EvpAes256Cfb128() +{ + return EVP_aes_256_cfb128(); +} + +const EVP_CIPHER* CryptoNative_EvpAes256Cfb8() +{ + return EVP_aes_256_cfb8(); +} + const EVP_CIPHER* CryptoNative_EvpAes256Cbc() { return EVP_aes_256_cbc(); @@ -245,6 +275,11 @@ const EVP_CIPHER* CryptoNative_EvpDesEcb() return EVP_des_ecb(); } +const EVP_CIPHER* CryptoNative_EvpDesCfb8() +{ + return EVP_des_cfb8(); +} + const EVP_CIPHER* CryptoNative_EvpDesCbc() { return EVP_des_cbc(); @@ -255,6 +290,16 @@ const EVP_CIPHER* CryptoNative_EvpDes3Ecb() return EVP_des_ede3(); } +const EVP_CIPHER* CryptoNative_EvpDes3Cfb8() +{ + return EVP_des_ede3_cfb8(); +} + +const EVP_CIPHER* CryptoNative_EvpDes3Cfb64() +{ + return EVP_des_ede3_cfb64(); +} + const EVP_CIPHER* CryptoNative_EvpDes3Cbc() { return EVP_des_ede3_cbc(); diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.h index 4441b066f620..a48c0dde3833 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.h @@ -110,6 +110,22 @@ Direct shim to EVP_aes_128_cbc. */ PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes128Cbc(void); +/* +Function: +EvpAes128Cfb8 + +Direct shim to EVP_aes_128_cfb8. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes128Cfb8(void); + +/* +Function: +EvpAes128Cfb128 + +Direct shim to EVP_aes_128_cfb128. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes128Cfb128(void); + /* Function: EvpAes128Gcm @@ -142,6 +158,22 @@ Direct shim to EVP_aes_192_cbc. */ PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes192Cbc(void); +/* +Function: +EvpAes192Cfb8 + +Direct shim to EVP_aes_192_cfb8. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes192Cfb8(void); + +/* +Function: +EvpAes192Cfb128 + +Direct shim to EVP_aes_192_cfb128. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes192Cfb128(void); + /* Function: EvpAes192Gcm @@ -174,6 +206,22 @@ Direct shim to EVP_aes_256_cbc. */ PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes256Cbc(void); +/* +Function: +EvpAes256Cfb8 + +Direct shim to EVP_aes_256_cfb8. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes256Cfb8(void); + +/* +Function: +EvpAes256Cfb128 + +Direct shim to EVP_aes_256_cfb128. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes256Cfb128(void); + /* Function: EvpAes256Gcm @@ -206,6 +254,22 @@ Direct shim to EVP_des_ede3_cbc. */ PALEXPORT const EVP_CIPHER* CryptoNative_EvpDes3Cbc(void); +/* +Function: +EvpDes3Cfb8 + +Direct shim to EVP_des_ede3_cfb8. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpDes3Cfb8(void); + +/* +Function: +EvpDes3Cfb64 + +Direct shim to EVP_des_ede3_cfb64. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpDes3Cfb64(void); + /* Function: EvpDesEcb @@ -214,6 +278,14 @@ Direct shim to EVP_des_ecb. */ PALEXPORT const EVP_CIPHER* CryptoNative_EvpDesEcb(void); +/* +Function: +EvpDesCfb8 + +Direct shim to EVP_des_cfb8. +*/ +PALEXPORT const EVP_CIPHER* CryptoNative_EvpDesCfb8(void); + /* Function: EvpDesCbc diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.OSX.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.OSX.cs index 6df9fa501b20..042a5f6efc7a 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.OSX.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.OSX.cs @@ -13,6 +13,8 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedbackSizeInBytes, bool encrypting) { BasicSymmetricCipher cipher = new AppleCCCryptor( @@ -21,7 +23,9 @@ private static ICryptoTransform CreateTransformCore( blockSize, key, iv, - encrypting); + encrypting, + feedbackSizeInBytes, + paddingSize); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Unix.cs index 04279171ec68..1e4b413130dd 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Unix.cs @@ -14,43 +14,50 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedback, bool encrypting) { // The algorithm pointer is a static pointer, so not having any cleanup code is correct. - IntPtr algorithm = GetAlgorithm(key.Length * 8, cipherMode); + IntPtr algorithm = GetAlgorithm(key.Length * 8, feedback * 8, cipherMode); - BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, 0, iv, encrypting); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, paddingSize, key, 0, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } - private static readonly Tuple>[] s_algorithmInitializers = + private static readonly Tuple>[] s_algorithmInitializers = { // Neither OpenSSL nor Cng Aes support CTS mode. - // Cng Aes doesn't seem to support CFB mode, and that would - // require passing in the feedback size. Since Windows doesn't support it, - // we can skip it here, too. - Tuple.Create(128, CipherMode.CBC, (Func)Interop.Crypto.EvpAes128Cbc), - Tuple.Create(128, CipherMode.ECB, (Func)Interop.Crypto.EvpAes128Ecb), + // second parameter is feedback size (required only for CFB). - Tuple.Create(192, CipherMode.CBC, (Func)Interop.Crypto.EvpAes192Cbc), - Tuple.Create(192, CipherMode.ECB, (Func)Interop.Crypto.EvpAes192Ecb), + Tuple.Create(128, 0, CipherMode.CBC, (Func)Interop.Crypto.EvpAes128Cbc), + Tuple.Create(128, 0, CipherMode.ECB, (Func)Interop.Crypto.EvpAes128Ecb), + Tuple.Create(128, 8, CipherMode.CFB, (Func)Interop.Crypto.EvpAes128Cfb8), + Tuple.Create(128, 128, CipherMode.CFB, (Func)Interop.Crypto.EvpAes128Cfb128), - Tuple.Create(256, CipherMode.CBC, (Func)Interop.Crypto.EvpAes256Cbc), - Tuple.Create(256, CipherMode.ECB, (Func)Interop.Crypto.EvpAes256Ecb), + Tuple.Create(192, 0, CipherMode.CBC, (Func)Interop.Crypto.EvpAes192Cbc), + Tuple.Create(192, 0, CipherMode.ECB, (Func)Interop.Crypto.EvpAes192Ecb), + Tuple.Create(192, 8, CipherMode.CFB, (Func)Interop.Crypto.EvpAes192Cfb8), + Tuple.Create(192, 128, CipherMode.CFB, (Func)Interop.Crypto.EvpAes192Cfb128), + + Tuple.Create(256, 0, CipherMode.CBC, (Func)Interop.Crypto.EvpAes256Cbc), + Tuple.Create(256, 0, CipherMode.ECB, (Func)Interop.Crypto.EvpAes256Ecb), + Tuple.Create(256, 8, CipherMode.CFB, (Func)Interop.Crypto.EvpAes256Cfb8), + Tuple.Create(256, 128, CipherMode.CFB, (Func)Interop.Crypto.EvpAes256Cfb128), }; - private static IntPtr GetAlgorithm(int keySize, CipherMode cipherMode) + private static IntPtr GetAlgorithm(int keySize, int feedback, CipherMode cipherMode) { bool foundKeysize = false; - foreach (var triplet in s_algorithmInitializers) + foreach (var tuple in s_algorithmInitializers) { - if (triplet.Item1 == keySize && triplet.Item2 == cipherMode) + if (tuple.Item1 == keySize && (tuple.Item2 == 0 || tuple.Item2 == feedback) && tuple.Item3 == cipherMode) { - return triplet.Item3(); + return tuple.Item4(); } - if (triplet.Item1 == keySize) + if (tuple.Item1 == keySize) { foundKeysize = true; } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Windows.cs index 550d5e0121af..f08ecbb6780a 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.Windows.cs @@ -14,11 +14,13 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedbackSize, bool encrypting) { - SafeAlgorithmHandle algorithm = AesBCryptModes.GetSharedHandle(cipherMode); + SafeAlgorithmHandle algorithm = AesBCryptModes.GetSharedHandle(cipherMode, feedbackSize); - BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, key, false, iv, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, paddingSize, key, false, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.cs index cb1752d5126e..67303b6f2d9f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AesImplementation.cs @@ -65,7 +65,21 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr throw new ArgumentException(SR.Cryptography_InvalidIVSize, nameof(rgbIV)); } - return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, encrypting); + if (Mode == CipherMode.CFB) + { + ValidateCFBFeedbackSize(FeedbackSize); + } + + return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, this.GetPaddingSize(), FeedbackSize / BitsPerByte, encrypting); + } + + private static void ValidateCFBFeedbackSize(int feedback) + { + // only 8bits/128bits feedback would be valid. + if (feedback != 8 && feedback != 128) + { + throw new CryptographicException(string.Format(SR.Cryptography_CipherModeFeedbackNotSupported, feedback, CipherMode.CFB)); + } } private const int BitsPerByte = 8; diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs index a584e1d96b21..0400c5c5c1c3 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; +using Internal.Cryptography; namespace Internal.Cryptography { @@ -13,18 +14,36 @@ internal sealed class AppleCCCryptor : BasicSymmetricCipher private readonly bool _encrypting; private SafeAppleCryptorHandle _cryptor; + // Reset operation is not supported on stream cipher + private readonly bool _supportsReset; + + private Interop.AppleCrypto.PAL_SymmetricAlgorithm _algorithm; + private CipherMode _cipherMode; + private byte[] _key; + private int _feedbackSizeInBytes; + public AppleCCCryptor( Interop.AppleCrypto.PAL_SymmetricAlgorithm algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, byte[]? iv, - bool encrypting) - : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) + bool encrypting, + int feedbackSizeInBytes, + int paddingSizeInBytes) + : base(cipherMode.GetCipherIv(iv), blockSizeInBytes, paddingSizeInBytes) { _encrypting = encrypting; - OpenCryptor(algorithm, cipherMode, key); + // CFB is streaming cipher, calling CCCryptorReset is not implemented (and is effectively noop) + _supportsReset = cipherMode != CipherMode.CFB; + + _algorithm = algorithm; + _cipherMode = cipherMode; + _key = key; + _feedbackSizeInBytes = feedbackSizeInBytes; + + OpenCryptor(); } protected override void Dispose(bool disposing) @@ -41,14 +60,14 @@ protected override void Dispose(bool disposing) public override int Transform(ReadOnlySpan input, Span output) { Debug.Assert(input.Length > 0); - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); return CipherUpdate(input, output); } public override int TransformFinal(ReadOnlySpan input, Span output) { - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); Debug.Assert(input.Length <= output.Length); int written = ProcessFinalBlock(input, output); @@ -119,28 +138,25 @@ private unsafe int CipherUpdate(ReadOnlySpan input, Span output) } [MemberNotNull(nameof(_cryptor))] - private unsafe void OpenCryptor( - Interop.AppleCrypto.PAL_SymmetricAlgorithm algorithm, - CipherMode cipherMode, - byte[] key) + private unsafe void OpenCryptor() { int ret; int ccStatus; byte[]? iv = IV; - fixed (byte* pbKey = key) + fixed (byte* pbKey = _key) fixed (byte* pbIv = iv) { ret = Interop.AppleCrypto.CryptorCreate( _encrypting ? Interop.AppleCrypto.PAL_SymmetricOperation.Encrypt : Interop.AppleCrypto.PAL_SymmetricOperation.Decrypt, - algorithm, - GetPalChainMode(cipherMode), + _algorithm, + GetPalChainMode(_algorithm, _cipherMode, _feedbackSizeInBytes), Interop.AppleCrypto.PAL_PaddingMode.None, pbKey, - key.Length, + _key.Length, pbIv, Interop.AppleCrypto.PAL_SymmetricOptions.None, out _cryptor, @@ -150,7 +166,7 @@ private unsafe void OpenCryptor( ProcessInteropError(ret, ccStatus); } - private Interop.AppleCrypto.PAL_ChainingMode GetPalChainMode(CipherMode cipherMode) + private Interop.AppleCrypto.PAL_ChainingMode GetPalChainMode(Interop.AppleCrypto.PAL_SymmetricAlgorithm algorithm, CipherMode cipherMode, int feedbackSizeInBytes) { switch (cipherMode) { @@ -158,6 +174,17 @@ private Interop.AppleCrypto.PAL_ChainingMode GetPalChainMode(CipherMode cipherMo return Interop.AppleCrypto.PAL_ChainingMode.CBC; case CipherMode.ECB: return Interop.AppleCrypto.PAL_ChainingMode.ECB; + case CipherMode.CFB: + if (feedbackSizeInBytes == 1) + { + return Interop.AppleCrypto.PAL_ChainingMode.CFB8; + } + + Debug.Assert( + (algorithm == Interop.AppleCrypto.PAL_SymmetricAlgorithm.AES && feedbackSizeInBytes == 16) || + (algorithm == Interop.AppleCrypto.PAL_SymmetricAlgorithm.TripleDES && feedbackSizeInBytes == 8)); + + return Interop.AppleCrypto.PAL_ChainingMode.CFB; default: throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CipherModeNotSupported, cipherMode)); } @@ -165,17 +192,27 @@ private Interop.AppleCrypto.PAL_ChainingMode GetPalChainMode(CipherMode cipherMo private unsafe void Reset() { - int ret; - int ccStatus; - - byte[]? iv = IV; - - fixed (byte* pbIv = iv) + if (!_supportsReset) { - ret = Interop.AppleCrypto.CryptorReset(_cryptor, pbIv, out ccStatus); + // when CryptorReset is not supported, + // dispose & reopen + _cryptor?.Dispose(); + OpenCryptor(); } + else + { + int ret; + int ccStatus; - ProcessInteropError(ret, ccStatus); + byte[]? iv = IV; + + fixed (byte* pbIv = iv) + { + ret = Interop.AppleCrypto.CryptorReset(_cryptor, pbIv, out ccStatus); + } + + ProcessInteropError(ret, ccStatus); + } } private static void ProcessInteropError(int functionReturnCode, int ccStatus) diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.OSX.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.OSX.cs index 0ffda38368b1..fc88b0a4431c 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.OSX.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.OSX.cs @@ -13,6 +13,8 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int feedbackSizeInBytes, + int paddingSize, bool encrypting) { BasicSymmetricCipher cipher = new AppleCCCryptor( @@ -21,7 +23,9 @@ private static ICryptoTransform CreateTransformCore( blockSize, key, iv, - encrypting); + encrypting, + feedbackSizeInBytes, + paddingSize); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs index cc4ecd5b4451..7bf051e669df 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; using System.Security.Cryptography; namespace Internal.Cryptography @@ -14,10 +15,13 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int feedbackSize, + int paddingSize, bool encrypting) { // The algorithm pointer is a static pointer, so not having any cleanup code is correct. - IntPtr algorithm; + IntPtr algorithm = IntPtr.Zero; + switch (cipherMode) { case CipherMode.CBC: @@ -25,12 +29,18 @@ private static ICryptoTransform CreateTransformCore( break; case CipherMode.ECB: algorithm = Interop.Crypto.EvpDesEcb(); + break; + case CipherMode.CFB: + + Debug.Assert(feedbackSize == 1, "TripleDES with CFB should have FeedbackSize set to 1"); + algorithm = Interop.Crypto.EvpDesCfb8(); + break; default: throw new NotSupportedException(); } - BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, 0, iv, encrypting); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, paddingSize, key, 0, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Windows.cs index 75a9900559dd..a6d53c6e8879 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Windows.cs @@ -14,11 +14,13 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int feedbackSize, + int paddingSize, bool encrypting) { - SafeAlgorithmHandle algorithm = DesBCryptModes.GetSharedHandle(cipherMode); + SafeAlgorithmHandle algorithm = DesBCryptModes.GetSharedHandle(cipherMode, feedbackSize); - BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, key, false, iv, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, paddingSize, key, false, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.cs index f0557c0738b6..b6ddbc78584a 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.cs @@ -73,7 +73,21 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr throw new ArgumentException(SR.Cryptography_InvalidIVSize, nameof(rgbIV)); } - return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, encrypting); + if (Mode == CipherMode.CFB) + { + ValidateCFBFeedbackSize(FeedbackSize); + } + + return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, FeedbackSize / BitsPerByte, this.GetPaddingSize(), encrypting); + } + + private static void ValidateCFBFeedbackSize(int feedback) + { + // only 8bits feedback is available on all platforms + if (feedback != 8) + { + throw new CryptographicException(string.Format(SR.Cryptography_CipherModeFeedbackNotSupported, feedback, CipherMode.CFB)); + } } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs index 49dc42d37111..6adbec36bb8f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs @@ -16,8 +16,8 @@ internal class OpenSslCipher : BasicSymmetricCipher private readonly bool _encrypting; private SafeEvpCipherCtxHandle _ctx; - public OpenSslCipher(IntPtr algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, byte[]? iv, bool encrypting) - : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) + public OpenSslCipher(IntPtr algorithm, CipherMode cipherMode, int blockSizeInBytes, int paddingSizeInBytes, byte[] key, int effectiveKeyLength, byte[]? iv, bool encrypting) + : base(cipherMode.GetCipherIv(iv), blockSizeInBytes, paddingSizeInBytes) { Debug.Assert(algorithm != IntPtr.Zero); @@ -43,7 +43,7 @@ protected override void Dispose(bool disposing) public override unsafe int Transform(ReadOnlySpan input, Span output) { Debug.Assert(input.Length > 0); - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); // OpenSSL 1.1 does not allow partial overlap. if (input.Overlaps(output, out int overlapOffset) && overlapOffset != 0) @@ -69,7 +69,7 @@ public override unsafe int Transform(ReadOnlySpan input, Span output public override int TransformFinal(ReadOnlySpan input, Span output) { - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); Debug.Assert(input.Length <= output.Length); int written = ProcessFinalBlock(input, output); diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.OSX.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.OSX.cs index 757b8851d313..dad0dce87c8f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.OSX.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.OSX.cs @@ -14,6 +14,8 @@ private static ICryptoTransform CreateTransformCore( int effectiveKeyLength, byte[]? iv, int blockSize, + int feedbackSizeInBytes, + int paddingSize, bool encrypting) { BasicSymmetricCipher cipher = new AppleCCCryptor( @@ -22,7 +24,9 @@ private static ICryptoTransform CreateTransformCore( blockSize, key, iv, - encrypting); + encrypting, + feedbackSizeInBytes, + paddingSize); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs index d6a55935ac74..3e2a12794cee 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs @@ -16,6 +16,8 @@ private static ICryptoTransform CreateTransformCore( int effectiveKeyLength, byte[]? iv, int blockSize, + int feedbackSize, + int paddingSize, bool encrypting) { // The algorithm pointer is a static pointer, so not having any cleanup code is correct. @@ -32,7 +34,7 @@ private static ICryptoTransform CreateTransformCore( throw new NotSupportedException(); } - BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, effectiveKeyLength, iv, encrypting); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, paddingSize, key, effectiveKeyLength, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Windows.cs index 616c1e92ad0e..0c6139a3f36d 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Windows.cs @@ -16,12 +16,14 @@ private static ICryptoTransform CreateTransformCore( int effectiveKeyLength, byte[]? iv, int blockSize, + int feedbackSize, + int paddingSize, bool encrypting) { using (SafeAlgorithmHandle algorithm = RC2BCryptModes.GetHandle(cipherMode, effectiveKeyLength)) { // The BasicSymmetricCipherBCrypt ctor will increase algorithm reference count and take ownership. - BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, key, true, iv, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, paddingSize, key, true, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.cs index c01d68933ca9..876eb24038e6 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.cs @@ -76,8 +76,24 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr throw new ArgumentException(SR.Cryptography_InvalidIVSize, nameof(rgbIV)); } + if (Mode == CipherMode.CFB) + { + ValidateCFBFeedbackSize(FeedbackSize); + } + int effectiveKeySize = EffectiveKeySizeValue == 0 ? (int)keySize : EffectiveKeySize; - return CreateTransformCore(Mode, Padding, rgbKey, effectiveKeySize, rgbIV, BlockSize / BitsPerByte, encrypting); + return CreateTransformCore(Mode, Padding, rgbKey, effectiveKeySize, rgbIV, BlockSize / BitsPerByte, FeedbackSize / BitsPerByte, GetPaddingSize(), encrypting); + } + + private static void ValidateCFBFeedbackSize(int feedback) + { + // CFB not supported at all + throw new CryptographicException(string.Format(SR.Cryptography_CipherModeFeedbackNotSupported, feedback, CipherMode.CFB)); + } + + private int GetPaddingSize() + { + return BlockSize / BitsPerByte; } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.OSX.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.OSX.cs index 2600f09ec711..1284943c323c 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.OSX.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.OSX.cs @@ -13,6 +13,8 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedbackSizeInBytes, bool encrypting) { BasicSymmetricCipher cipher = new AppleCCCryptor( @@ -21,7 +23,9 @@ private static ICryptoTransform CreateTransformCore( blockSize, key, iv, - encrypting); + encrypting, + feedbackSizeInBytes, + paddingSize); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Unix.cs index 7987cb6b11b7..2efa80141eb8 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Unix.cs @@ -14,23 +14,31 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedbackSize, bool encrypting) { // The algorithm pointer is a static pointer, so not having any cleanup code is correct. IntPtr algorithm; - switch (cipherMode) + switch ((cipherMode, feedbackSize)) { - case CipherMode.CBC: + case (CipherMode.CBC, _): algorithm = Interop.Crypto.EvpDes3Cbc(); break; - case CipherMode.ECB: + case (CipherMode.ECB, _): algorithm = Interop.Crypto.EvpDes3Ecb(); break; + case (CipherMode.CFB, 1): + algorithm = Interop.Crypto.EvpDes3Cfb8(); + break; + case (CipherMode.CFB, 8): + algorithm = Interop.Crypto.EvpDes3Cfb64(); + break; default: throw new NotSupportedException(); } - BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, 0, iv, encrypting); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, paddingSize, key, 0, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Windows.cs index 1fa355e18350..331162e7ea8f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.Windows.cs @@ -14,11 +14,13 @@ private static ICryptoTransform CreateTransformCore( byte[] key, byte[]? iv, int blockSize, + int paddingSize, + int feedbackSize, bool encrypting) { - SafeAlgorithmHandle algorithm = TripleDesBCryptModes.GetSharedHandle(cipherMode); + SafeAlgorithmHandle algorithm = TripleDesBCryptModes.GetSharedHandle(cipherMode, feedbackSize); - BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, key, false, iv, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(algorithm, cipherMode, blockSize, paddingSize, key, false, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.cs index 38a37106bce7..f5a81eeaf940 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.cs @@ -73,7 +73,21 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr rgbKey = newkey; } - return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, encrypting); + if (Mode == CipherMode.CFB) + { + ValidateCFBFeedbackSize(FeedbackSize); + } + + return CreateTransformCore(Mode, Padding, rgbKey, rgbIV, BlockSize / BitsPerByte, this.GetPaddingSize(), FeedbackSize / BitsPerByte, encrypting); + } + + private static void ValidateCFBFeedbackSize(int feedback) + { + // only 8bits/64bits feedback would be valid. + if (feedback != 8 && feedback != 64) + { + throw new CryptographicException(string.Format(SR.Cryptography_CipherModeFeedbackNotSupported, feedback, CipherMode.CFB)); + } } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx index 9ca47b53977f..162f1ab3b7b4 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx @@ -303,6 +303,9 @@ Attempt to transform beyond end of buffer. + + The specified feedback size '{0}' for CipherMode '{1}' is not supported. + The specified CipherMode '{0}' is not supported. diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs index 09a011adb1a4..f858454edd2a 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs @@ -9,7 +9,7 @@ namespace System.Security.Cryptography { public sealed partial class AesCcm { - private static readonly SafeAlgorithmHandle s_aesCcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CCM); + private static readonly SafeAlgorithmHandle s_aesCcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CCM).Value; private SafeKeyHandle _keyHandle; [MemberNotNull(nameof(_keyHandle))] diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs index a86f7130e314..7798787e5b5f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs @@ -9,7 +9,7 @@ namespace System.Security.Cryptography { public partial class AesGcm { - private static readonly SafeAlgorithmHandle s_aesGcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_GCM); + private static readonly SafeAlgorithmHandle s_aesGcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_GCM).Value; private SafeKeyHandle _keyHandle; [MemberNotNull(nameof(_keyHandle))] diff --git a/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj b/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj index c10e46d86206..37aaf30246b3 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Algorithms/tests/System.Security.Cryptography.Algorithms.Tests.csproj @@ -61,6 +61,8 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\TestData.cs" /> + + + cngKeyFactory, CipherMode cipherMode, int blockSizeInBytes, byte[] iv, bool encrypting) - : base(iv, blockSizeInBytes) + public BasicSymmetricCipherNCrypt(Func cngKeyFactory, CipherMode cipherMode, int blockSizeInBytes, byte[] iv, bool encrypting, int feedbackSizeInBytes, int paddingSize) + : base(iv, blockSizeInBytes, paddingSize) { _encrypting = encrypting; _cngKey = cngKeyFactory(); @@ -30,6 +30,7 @@ public BasicSymmetricCipherNCrypt(Func cngKeyFactory, CipherMode cipherM { CipherMode.ECB => s_ECBMode, CipherMode.CBC => s_CBCMode, + CipherMode.CFB => s_CFBMode, _ => throw new CryptographicException(SR.Cryptography_InvalidCipherMode), }; _cngKey.SetProperty(chainingModeProperty); @@ -40,7 +41,7 @@ public BasicSymmetricCipherNCrypt(Func cngKeyFactory, CipherMode cipherM public sealed override int Transform(ReadOnlySpan input, Span output) { Debug.Assert(input.Length > 0); - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten; ErrorCode errorCode; @@ -71,7 +72,7 @@ public sealed override int Transform(ReadOnlySpan input, Span output public sealed override int TransformFinal(ReadOnlySpan input, Span output) { - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten = 0; @@ -115,5 +116,7 @@ private void Reset() new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_ECB + "\0"), CngPropertyOptions.None); private static readonly CngProperty s_CBCMode = new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CBC + "\0"), CngPropertyOptions.None); + private static readonly CngProperty s_CFBMode = + new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CFB + "\0"), CngPropertyOptions.None); } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs index 22ac9bcac3d1..6aa654e1eeab 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs @@ -164,6 +164,7 @@ private ICryptoTransform CreateEphemeralCryptoTransformCore(byte[] key, byte[]? algorithmModeHandle, _outer.Mode, blockSizeInBytes, + _outer.GetPaddingSize(), key, false, iv, @@ -177,7 +178,8 @@ private ICryptoTransform CreatePersistedCryptoTransformCore(Func cngKeyF // note: iv is guaranteed to be cloned before this method, so no need to clone it again int blockSizeInBytes = _outer.BlockSize.BitSizeToByteSize(); - BasicSymmetricCipher cipher = new BasicSymmetricCipherNCrypt(cngKeyFactory, _outer.Mode, blockSizeInBytes, iv, encrypting); + int feedbackSizeInBytes = _outer.FeedbackSize; + BasicSymmetricCipher cipher = new BasicSymmetricCipherNCrypt(cngKeyFactory, _outer.Mode, blockSizeInBytes, iv, encrypting, feedbackSizeInBytes, _outer.GetPaddingSize()); return UniversalCryptoTransform.Create(_outer.Padding, cipher, encrypting); } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs index 105b146eb327..8fdf656d87c7 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs @@ -16,6 +16,7 @@ internal interface ICngSymmetricAlgorithm { // SymmetricAlgorithm members used by the core. int BlockSize { get; } + int FeedbackSize { get; } CipherMode Mode { get; } PaddingMode Padding { get; } byte[] IV { get; set; } @@ -30,5 +31,6 @@ internal interface ICngSymmetricAlgorithm SafeAlgorithmHandle GetEphemeralModeHandle(); string GetNCryptAlgorithmIdentifier(); byte[] PreprocessKey(byte[] key); + int GetPaddingSize(); } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs index 82f679c47401..44553eaeeb72 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs @@ -105,9 +105,21 @@ bool ICngSymmetricAlgorithm.IsWeakKey(byte[] key) return false; } + int ICngSymmetricAlgorithm.GetPaddingSize() + { + return this.GetPaddingSize(); + } + SafeAlgorithmHandle ICngSymmetricAlgorithm.GetEphemeralModeHandle() { - return AesBCryptModes.GetSharedHandle(Mode); + try + { + return AesBCryptModes.GetSharedHandle(Mode, FeedbackSize / 8); + } + catch (NotSupportedException) + { + throw new CryptographicException(SR.Cryptography_InvalidCipherMode); + } } string ICngSymmetricAlgorithm.GetNCryptAlgorithmIdentifier() diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs index c1dff10d108b..708acee372ad 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs +++ b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs @@ -106,9 +106,14 @@ bool ICngSymmetricAlgorithm.IsWeakKey(byte[] key) return TripleDES.IsWeakKey(key); } + int ICngSymmetricAlgorithm.GetPaddingSize() + { + return this.GetPaddingSize(); + } + SafeAlgorithmHandle ICngSymmetricAlgorithm.GetEphemeralModeHandle() { - return TripleDesBCryptModes.GetSharedHandle(Mode); + return TripleDesBCryptModes.GetSharedHandle(Mode, FeedbackSize / 8); } string ICngSymmetricAlgorithm.GetNCryptAlgorithmIdentifier() diff --git a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs b/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs index 75864f801f9f..892df2169b88 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs @@ -16,8 +16,8 @@ internal sealed class BasicSymmetricCipherCsp : BasicSymmetricCipher private SafeProvHandle _hProvider; private SafeKeyHandle _hKey; - public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, bool addNoSaltFlag, byte[]? iv, bool encrypting) - : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) + public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, bool addNoSaltFlag, byte[]? iv, bool encrypting, int feedbackSize, int paddingSizeInBytes) + : base(cipherMode.GetCipherIv(iv), blockSizeInBytes, paddingSizeInBytes) { _encrypting = encrypting; @@ -25,6 +25,10 @@ public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeIn _hKey = ImportCspBlob(_hProvider, algId, key, addNoSaltFlag); SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_MODE, (int)cipherMode); + if (cipherMode == CipherMode.CFB) + { + SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_MODE_BITS, feedbackSize); + } byte[]? currentIv = cipherMode.GetCipherIv(iv); if (currentIv != null) @@ -67,7 +71,7 @@ public override int Transform(ReadOnlySpan input, Span output) public override int TransformFinal(ReadOnlySpan input, Span output) { - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten = 0; @@ -91,7 +95,7 @@ private void Reset() private int Transform(ReadOnlySpan input, Span output, bool isFinal) { Debug.Assert(input.Length > 0); - Debug.Assert((input.Length % BlockSizeInBytes) == 0); + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); int numBytesWritten; if (_encrypting) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs index ea59376c1531..d724958c2c16 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs @@ -910,7 +910,6 @@ internal static int EncryptData( bool isFinal) { VerifyValidHandle(hKey); - Debug.Assert((input.Length % 8) == 0); // Figure out how big the encrypted data will be int cbEncryptedData = input.Length; @@ -949,7 +948,6 @@ internal static int DecryptData( Span output) { VerifyValidHandle(hKey); - Debug.Assert((input.Length % 8) == 0); byte[] dataToBeDecrypted = new byte[input.Length]; input.CopyTo(dataToBeDecrypted); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs index 9d74b5d5e42c..236503fb3108 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs @@ -97,7 +97,7 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr throw new CryptographicException(SR.Cryptography_InvalidIVSize); } - BasicSymmetricCipher cipher = new BasicSymmetricCipherCsp(CapiHelper.CALG_DES, Mode, BlockSize / BitsPerByte, rgbKey, 0, false, rgbIV, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherCsp(CapiHelper.CALG_DES, Mode, BlockSize / BitsPerByte, rgbKey, 0, false, rgbIV, encrypting, FeedbackSize, this.GetPaddingSize()); return UniversalCryptoTransform.Create(Padding, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs index d4760f31946e..abdcab7eb0da 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs @@ -106,7 +106,7 @@ private ICryptoTransform CreateTransform(byte[] rgbKey, byte[]? rgbIV, bool encr } int effectiveKeySize = EffectiveKeySizeValue == 0 ? (int)keySize : EffectiveKeySize; - BasicSymmetricCipher cipher = new BasicSymmetricCipherCsp(CapiHelper.CALG_RC2, Mode, BlockSize / BitsPerByte, rgbKey, effectiveKeySize, !UseSalt, rgbIV, encrypting); + BasicSymmetricCipher cipher = new BasicSymmetricCipherCsp(CapiHelper.CALG_RC2, Mode, BlockSize / BitsPerByte, rgbKey, effectiveKeySize, !UseSalt, rgbIV, encrypting, 0, 0); return UniversalCryptoTransform.Create(Padding, cipher, encrypting); } } diff --git a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CipherMode.cs b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CipherMode.cs index e56874a6633e..97be08609623 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CipherMode.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CipherMode.cs @@ -8,6 +8,7 @@ namespace System.Security.Cryptography // This enum represents supported cipher chaining modes: // cipher block chaining (CBC), // electronic code book (ECB), + // cipher feedback (CFB), // ciphertext-stealing (CTS). // Not all implementations will support all modes. public enum CipherMode @@ -15,7 +16,7 @@ public enum CipherMode CBC = 1, ECB = 2, [EditorBrowsable(EditorBrowsableState.Never)] OFB = 3, - [EditorBrowsable(EditorBrowsableState.Never)] CFB = 4, + CFB = 4, CTS = 5 } } diff --git a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/SymmetricAlgorithm.cs b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/SymmetricAlgorithm.cs index 8e16664690e1..9ad7b01d7b6c 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/SymmetricAlgorithm.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/SymmetricAlgorithm.cs @@ -146,7 +146,7 @@ public virtual CipherMode Mode set { - if (!(value == CipherMode.CBC || value == CipherMode.ECB)) + if (!(value == CipherMode.CBC || value == CipherMode.ECB || value == CipherMode.CFB)) throw new CryptographicException(SR.Cryptography_InvalidCipherMode); ModeValue = value; From d2c0ed643eef5189d5d9373a7973b6242128a72e Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 13 Aug 2020 15:31:45 +0200 Subject: [PATCH 448/755] update System.Console manual test instructions for macOS (#40773) --- src/libraries/System.Console/tests/ManualTests/Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Console/tests/ManualTests/Readme.md b/src/libraries/System.Console/tests/ManualTests/Readme.md index 7d77e7fe3e1e..0b6819734d40 100644 --- a/src/libraries/System.Console/tests/ManualTests/Readme.md +++ b/src/libraries/System.Console/tests/ManualTests/Readme.md @@ -22,5 +22,4 @@ And then copy and execute the commands logged under the `To repro directly:` sec ## Instructions for MacOS testers By default, Alt-Key does not work on the MacOS terminal. -Before running the tests, navigate to `Terminal > Preferences > Settings > Keyboard` -and check "Use option as meta key" at the bottom. +Before running the tests, navigate to `Terminal > Preferences > Settings > Keyboard` or `Terminal > Preferences > Profiles > Basic > Keyboard` (depending on your macOS version) and check "Use option as meta key" at the bottom. From 6e89ae86dedf18a7d61c0db271c9de3e9005bfa1 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 13 Aug 2020 06:35:32 -0700 Subject: [PATCH 449/755] Updating ClaimsPrincipal.Current to default back to Thread.CurrentPrincipal, as was done on .NET Framework (#40623) * Updating ClaimsPrincipal.Current to default back to Thread.CurrentPrincipal, as was done on .NET Framework * Add test that ClaimsPrincipal.Current falls back to Thread.CurrentPrincipal to match .NET Framework. Co-authored-by: Eric Erhardt --- .../src/System.Security.Claims.csproj | 1 + .../System/Security/Claims/ClaimsPrincipal.cs | 13 ++++---- .../tests/ClaimsPrincipalTests.cs | 31 +++++++++++++++++++ .../tests/System.Security.Claims.Tests.csproj | 1 + 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj index ca146c46b5db..ca4bd80a6eb1 100644 --- a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj +++ b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj @@ -17,5 +17,6 @@ + diff --git a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs index f7e4aa88989d..6762cdd23fb9 100644 --- a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs +++ b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs @@ -5,6 +5,7 @@ using System.IO; using System.Runtime.Serialization; using System.Security.Principal; +using System.Threading; namespace System.Security.Claims { @@ -26,6 +27,11 @@ private enum SerializationMask private static Func, ClaimsIdentity?> s_identitySelector = SelectPrimaryIdentity; private static Func s_principalSelector = ClaimsPrincipalSelector; + private static ClaimsPrincipal SelectClaimsPrincipal() + { + return (Thread.CurrentPrincipal is ClaimsPrincipal claimsPrincipal) ? claimsPrincipal : new ClaimsPrincipal(Thread.CurrentPrincipal!); + } + protected ClaimsPrincipal(SerializationInfo info, StreamingContext context) { throw new PlatformNotSupportedException(); @@ -280,12 +286,7 @@ public static ClaimsPrincipal? Current // just accesses the current selected principal selector, doesn't set get { - if (s_principalSelector != null) - { - return s_principalSelector(); - } - - return null; + return s_principalSelector is not null ? s_principalSelector() : SelectClaimsPrincipal(); } } diff --git a/src/libraries/System.Security.Claims/tests/ClaimsPrincipalTests.cs b/src/libraries/System.Security.Claims/tests/ClaimsPrincipalTests.cs index 81f3420047dc..c28b7709e349 100644 --- a/src/libraries/System.Security.Claims/tests/ClaimsPrincipalTests.cs +++ b/src/libraries/System.Security.Claims/tests/ClaimsPrincipalTests.cs @@ -5,6 +5,8 @@ using System.IO; using System.Linq; using System.Security.Principal; +using System.Threading; +using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.Security.Claims @@ -200,6 +202,35 @@ public void Ctor_ArgumentValidation() AssertExtensions.Throws("reader", () => new ClaimsPrincipal((BinaryReader)null)); } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void Current_FallsBackToThread() + { + RemoteExecutor.Invoke(() => + { + ClaimsPrincipal principal1 = new ClaimsPrincipal(); + ClaimsPrincipal principal2 = new ClaimsPrincipal(); + + Thread.CurrentPrincipal = principal1; + Assert.Same(principal1, ClaimsPrincipal.Current); + + Thread.CurrentPrincipal = principal2; + Assert.Same(principal2, ClaimsPrincipal.Current); + + NonClaimsIdentity id = new NonClaimsIdentity() { Name = "NonClaimsIdentity_Name" }; + NonClaimsPrincipal nonClaimsPrincipal = new NonClaimsPrincipal() { Identity = id }; + + Thread.CurrentPrincipal = nonClaimsPrincipal; + + ClaimsPrincipal current = ClaimsPrincipal.Current; + Assert.NotNull(current); + Assert.Equal("NonClaimsIdentity_Name", current.Identity.Name); + + // match .NET Framework behavior by throwing ArgumentNullException when Thread.CurrentPrincipal is null + Thread.CurrentPrincipal = null; + Assert.Throws(() => ClaimsPrincipal.Current); + }).Dispose(); + } + private class NonClaimsPrincipal : IPrincipal { public IIdentity Identity { get; set; } diff --git a/src/libraries/System.Security.Claims/tests/System.Security.Claims.Tests.csproj b/src/libraries/System.Security.Claims/tests/System.Security.Claims.Tests.csproj index cbdc50956be1..74dc03796cf4 100644 --- a/src/libraries/System.Security.Claims/tests/System.Security.Claims.Tests.csproj +++ b/src/libraries/System.Security.Claims/tests/System.Security.Claims.Tests.csproj @@ -1,5 +1,6 @@ + true $(NetCoreAppCurrent) From 6cfc044a32d2c06dbf7075b490200d18ddd7125b Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 13 Aug 2020 07:18:49 -0700 Subject: [PATCH 450/755] Ensure that no exception is thrown when static properties on the Activity type are passed to EventListener (#40549) --- .../DiagnosticSourceEventSource.cs | 6 ++++ .../DiagnosticSourceEventSourceBridgeTests.cs | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs index 408cf3cf6b8d..fdfbd90c7239 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -948,6 +948,12 @@ public static PropertyFetch FetcherForProperty(Type? type, string propertyName) Logger.Message($"Property {propertyName} not found on {type}"); return new PropertyFetch(type); } + // Delegate creation below is incompatible with static properties. + else if (propertyInfo.GetMethod?.IsStatic == true || propertyInfo.SetMethod?.IsStatic == true) + { + Logger.Message($"Property {propertyName} is static."); + return new PropertyFetch(type); + } Type typedPropertyFetcher = typeInfo.IsValueType ? typeof(ValueTypedFetchProperty<,>) : typeof(RefTypedFetchProperty<,>); Type instantiatedTypedPropertyFetcher = typedPropertyFetcher.GetTypeInfo().MakeGenericType( diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs index 4f20f3e0ae9a..83fddd0e48f5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs @@ -859,6 +859,39 @@ private void AssertActivityMatchesEvent(Activity a, DiagnosticSourceEvent e, boo } Assert.Equal(string.Join(',', a.Tags), e.Arguments["ActivityTags"]); } + + [Fact] + public void NoExceptionThrownWhenProcessingStaticActivityProperties() + { + // Ensures that no exception is thrown when static properties on the Activity type are passed to EventListener. + + using (var eventListener = new TestDiagnosticSourceEventListener()) + using (var diagnosticListener = new DiagnosticListener("MySource")) + { + string activityProps = + "-DummyProp" + + ";ActivityEvents=*Activity.DefaultIdFormat" + + ";ActivityBaggage=*Activity.Current" + + ";ActivityContext=*Activity.ForceDefaultIdFormat"; + eventListener.Enable( + "MySource/TestActivity1.Start@Activity1Start:" + activityProps + "\r\n" + + "MySource/TestActivity1.Stop@Activity1Stop:" + activityProps + "\r\n" + + "MySource/TestActivity2.Start@Activity2Start:" + activityProps + "\r\n" + + "MySource/TestActivity2.Stop@Activity2Stop:" + activityProps + "\r\n" + ); + + Activity activity1 = new Activity("TestActivity1"); + activity1.SetIdFormat(ActivityIdFormat.W3C); + activity1.TraceStateString = "hi_there"; + activity1.AddTag("one", "1"); + activity1.AddTag("two", "2"); + + var obj = new { DummyProp = "val" }; + + diagnosticListener.StartActivity(activity1, obj); + Assert.Equal(1, eventListener.EventCount); + } + } } /****************************************************************************/ From ff94c801083aae2bb9aa9fd8f57443a9606c585e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 13 Aug 2020 10:56:19 -0400 Subject: [PATCH 451/755] Remove pinned MicrosoftNetCompilersToolsetVersion from Version.props (#40760) --- eng/Versions.props | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index b4a1f5e067be..42b0bd0ca954 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -16,8 +16,6 @@ release true - - 3.8.0-2.20379.3 true false true From c33bfc70f5fc15b08e932d46def77b340a29d20e Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 13 Aug 2020 08:15:48 -0700 Subject: [PATCH 452/755] remove CheckForOverflowUnderflow from eventsource redist (#40757) --- .../src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj index 902e31dfc78c..debefca06167 100644 --- a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj +++ b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj @@ -8,7 +8,6 @@ true - true From b08047db36139770bba66664acb2aee39479e625 Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Thu, 13 Aug 2020 17:20:47 +0200 Subject: [PATCH 453/755] Improvements to allocation performance on machines with many processors (#32539) * Improvements to allocation performance on machines with many processors. In particular: - Make sure we reserve memory on the correct NUMA node. Otherwise the OS will pick a NUMA node for us on first touch, which is sometimes correct, sometimes not. - Only look at a subset of the available heaps in balance_heaps. Look at a different subset each time, and look both at heaps inside and outside the allocating processor's NUMA node, but give preference to heaps within the allocating processor's NUMA node and in particular, the heap associated with the allocating processor. - Fix issue where our logic assumed that NUMA node numbers are non-decreasing as the processor numbers increase, but this doesn't hold true on all machines. - Fix issue where we decreased the number of heaps to 1 in the special case of using large pages with the size for the pinned object heap set to 0. Results for a pure allocation test on a 4 socket NUMA machine (128 cores, 256 processors) showed improvements ranging from 18 to 28%. A 2 socket Intel machine (56 cores, 56 processors) showed results ranging from a 3% regression to an 8% improvement. --- src/coreclr/src/gc/env/gcenv.os.h | 2 +- src/coreclr/src/gc/gc.cpp | 703 +++++++++++++------ src/coreclr/src/gc/gcpriv.h | 2 +- src/coreclr/src/gc/unix/gcenv.unix.cpp | 4 +- src/coreclr/src/gc/windows/gcenv.windows.cpp | 15 +- src/coreclr/src/vm/gcenv.os.cpp | 17 +- 6 files changed, 513 insertions(+), 230 deletions(-) diff --git a/src/coreclr/src/gc/env/gcenv.os.h b/src/coreclr/src/gc/env/gcenv.os.h index 3dee37ad8e54..f8724fc8687a 100644 --- a/src/coreclr/src/gc/env/gcenv.os.h +++ b/src/coreclr/src/gc/env/gcenv.os.h @@ -290,7 +290,7 @@ class GCToOSInterface // size - size of the virtual memory range // Return: // Address of the allocated memory - static void* VirtualReserveAndCommitLargePages(size_t size); + static void* VirtualReserveAndCommitLargePages(size_t size, uint16_t node = NUMA_NODE_UNDEFINED); // Decomit virtual memory range. // Parameters: diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 8862c75a211e..f6910c0b2464 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -448,7 +448,7 @@ void log_va_msg(const char *fmt, va_list args) { gc_log_lock.Enter(); - const int BUFFERSIZE = 512; + const int BUFFERSIZE = 4096; static char rgchBuffer[BUFFERSIZE]; char * pBuffer = &rgchBuffer[0]; @@ -2092,7 +2092,7 @@ void qsort1(uint8_t** low, uint8_t** high, unsigned int depth); #endif //USE_INTROSORT void* virtual_alloc (size_t size); -void* virtual_alloc (size_t size, bool use_large_pages_p); +void* virtual_alloc (size_t size, bool use_large_pages_p, uint16_t numa_node = NUMA_NODE_UNDEFINED); /* per heap static initialization */ #if defined(BACKGROUND_GC) && !defined(MULTIPLE_HEAPS) @@ -3925,6 +3925,14 @@ struct imemory_data uint8_t* memory_base; }; +struct numa_reserved_block +{ + uint8_t* memory_base; + size_t block_size; + + numa_reserved_block() : memory_base(nullptr), block_size(0) { } +}; + struct initial_memory_details { imemory_data *initial_memory; @@ -3946,7 +3954,8 @@ struct initial_memory_details ALLATONCE = 1, EACH_GENERATION, EACH_BLOCK, - ALLATONCE_SEPARATED_POH + ALLATONCE_SEPARATED_POH, + EACH_NUMA_NODE }; size_t allocation_pattern; @@ -3988,11 +3997,13 @@ struct initial_memory_details } }; + int numa_reserved_block_count; + numa_reserved_block* numa_reserved_block_table; }; initial_memory_details memory_details; -BOOL gc_heap::reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p, bool separated_poh_p) +BOOL gc_heap::reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p, bool separated_poh_p, uint16_t* heap_no_to_numa_node) { BOOL reserve_success = FALSE; @@ -4036,127 +4047,286 @@ BOOL gc_heap::reserve_initial_memory (size_t normal_size, size_t large_size, siz return FALSE; } - size_t temp_pinned_size = (separated_poh_p ? 0 : pinned_size); - size_t separate_pinned_size = memory_details.block_count * pinned_size; - size_t requestedMemory = memory_details.block_count * (normal_size + large_size + temp_pinned_size); - - uint8_t* allatonce_block = (uint8_t*)virtual_alloc (requestedMemory, use_large_pages_p); - uint8_t* separated_poh_block = nullptr; - if (allatonce_block && separated_poh_p) + // figure out number of NUMA nodes and allocate additional table for NUMA local reservation + memory_details.numa_reserved_block_count = 0; + memory_details.numa_reserved_block_table = nullptr; + int numa_node_count = 0; + if (heap_no_to_numa_node != nullptr) { - separated_poh_block = (uint8_t*)virtual_alloc (separate_pinned_size, false); - if (!separated_poh_block) + uint16_t highest_numa_node = 0; + + // figure out the highest NUMA node + for (int heap_no = 0; heap_no < num_heaps; heap_no++) { - virtual_free (allatonce_block, requestedMemory); - allatonce_block = nullptr; + uint16_t heap_numa_node = heap_no_to_numa_node[heap_no]; + highest_numa_node = max (highest_numa_node, heap_numa_node); } - } - if (allatonce_block) - { - if (separated_poh_p) + + assert (highest_numa_node < MAX_SUPPORTED_CPUS); + + numa_node_count = highest_numa_node + 1; + memory_details.numa_reserved_block_count = numa_node_count * (1 + separated_poh_p); + memory_details.numa_reserved_block_table = new (nothrow) numa_reserved_block[memory_details.numa_reserved_block_count]; + if (memory_details.numa_reserved_block_table == nullptr) { - g_gc_lowest_address = min (allatonce_block, separated_poh_block); - g_gc_highest_address = max ((allatonce_block + requestedMemory), (separated_poh_block + separate_pinned_size)); - memory_details.allocation_pattern = initial_memory_details::ALLATONCE_SEPARATED_POH; + // we couldn't get the memory - continue as if doing the non-NUMA case + dprintf(2, ("failed to reserve %Id bytes for numa_reserved_block data", memory_details.numa_reserved_block_count * sizeof(numa_reserved_block))); + memory_details.numa_reserved_block_count = 0; } - else + } + + if (memory_details.numa_reserved_block_table != nullptr) + { + // figure out how much to reserve on each NUMA node + // note this can be very different between NUMA nodes, depending on + // which processors our heaps are associated with + size_t merged_pinned_size = separated_poh_p ? 0 : pinned_size; + for (int heap_no = 0; heap_no < num_heaps; heap_no++) { - g_gc_lowest_address = allatonce_block; - g_gc_highest_address = allatonce_block + requestedMemory; - memory_details.allocation_pattern = initial_memory_details::ALLATONCE; + uint16_t heap_numa_node = heap_no_to_numa_node[heap_no]; + + numa_reserved_block * block = &memory_details.numa_reserved_block_table[heap_numa_node]; + + // add the size required for this heap + block->block_size += normal_size + large_size + merged_pinned_size; + + if (separated_poh_p) + { + numa_reserved_block* pinned_block = &memory_details.numa_reserved_block_table[numa_node_count + heap_numa_node]; + + // add the pinned size required for this heap + pinned_block->block_size += pinned_size; + } } - for (int i = 0; i < memory_details.block_count; i++) + // reserve the appropriate size on each NUMA node + bool failure = false; + for (int block_index = 0; block_index < memory_details.numa_reserved_block_count; block_index++) { - memory_details.initial_normal_heap[i].memory_base = allatonce_block + - (i * normal_size); - memory_details.initial_large_heap[i].memory_base = allatonce_block + - (memory_details.block_count * normal_size) + (i * large_size); - if (separated_poh_p) + numa_reserved_block * block = &memory_details.numa_reserved_block_table[block_index]; + + if (block->block_size == 0) + continue; + + int numa_node = block_index % numa_node_count; + bool pinned_block = block_index >= numa_node_count; + block->memory_base = (uint8_t*)virtual_alloc (block->block_size, use_large_pages_p && !pinned_block, numa_node); + if (block->memory_base == nullptr) { - memory_details.initial_pinned_heap[i].memory_base = separated_poh_block + - (i * pinned_size); + dprintf(2, ("failed to reserve %Id bytes for on NUMA node %u", block->block_size, numa_node)); + failure = true; + break; } else { - memory_details.initial_pinned_heap[i].memory_base = allatonce_block + - (memory_details.block_count * (normal_size + large_size)) + (i * pinned_size); + g_gc_lowest_address = min(g_gc_lowest_address, block->memory_base); + g_gc_highest_address = max(g_gc_highest_address, block->memory_base + block->block_size); + } + } + + if (failure) + { + // if we had any failures, undo the work done so far + // we will instead use one of the other allocation patterns + // we could try to use what we did succeed to reserve, but that gets complicated + for (int block_index = 0; block_index < memory_details.numa_reserved_block_count; block_index++) + { + numa_reserved_block * block = &memory_details.numa_reserved_block_table[block_index]; + + if (block->memory_base != nullptr) + { + virtual_free(block->memory_base, block->block_size); + block->memory_base = nullptr; + } } + delete [] memory_details.numa_reserved_block_table; + memory_details.numa_reserved_block_table = nullptr; + memory_details.numa_reserved_block_count = 0; + } + else + { + // for each NUMA node, give out the memory to its heaps + for (uint16_t numa_node = 0; numa_node < numa_node_count; numa_node++) + { + numa_reserved_block * block = &memory_details.numa_reserved_block_table[numa_node]; + + numa_reserved_block* pinned_block = separated_poh_p ? &memory_details.numa_reserved_block_table[numa_node_count + numa_node] : nullptr; + + // if the block's size is 0, there can be no heaps on this NUMA node + if (block->block_size == 0) + { + assert((pinned_block == nullptr) || (pinned_block->block_size == 0)); + continue; + } + + uint8_t* memory_base = block->memory_base; + uint8_t* pinned_memory_base = ((pinned_block == nullptr) ? nullptr : pinned_block->memory_base); + for (int heap_no = 0; heap_no < num_heaps; heap_no++) + { + uint16_t heap_numa_node = heap_no_to_numa_node[heap_no]; + if (heap_numa_node != numa_node) + { + // this heap is on another NUMA node + continue; + } + + memory_details.initial_normal_heap[heap_no].memory_base = memory_base; + memory_base += normal_size; + + memory_details.initial_large_heap[heap_no].memory_base = memory_base; + memory_base += large_size; + + if (separated_poh_p) + { + memory_details.initial_pinned_heap[heap_no].memory_base = pinned_memory_base; + pinned_memory_base += pinned_size; + } + else + { + memory_details.initial_pinned_heap[heap_no].memory_base = memory_base; + memory_base += pinned_size; + } + } + // sanity check - we should be at the end of the memory block for this NUMA node + assert (memory_base == block->memory_base + block->block_size); + assert ((pinned_block == nullptr) || (pinned_memory_base == pinned_block->memory_base + pinned_block->block_size)); + } + memory_details.allocation_pattern = initial_memory_details::EACH_NUMA_NODE; reserve_success = TRUE; } } - else + + if (!reserve_success) { - // try to allocate 3 blocks - uint8_t* b1 = (uint8_t*)virtual_alloc (memory_details.block_count * normal_size, use_large_pages_p); - uint8_t* b2 = (uint8_t*)virtual_alloc (memory_details.block_count * large_size, use_large_pages_p); - uint8_t* b3 = (uint8_t*)virtual_alloc (memory_details.block_count * pinned_size, use_large_pages_p && !separated_poh_p); + size_t temp_pinned_size = (separated_poh_p ? 0 : pinned_size); + size_t separate_pinned_size = memory_details.block_count * pinned_size; + size_t requestedMemory = memory_details.block_count * (normal_size + large_size + temp_pinned_size); - if (b1 && b2 && b3) + uint8_t* allatonce_block = (uint8_t*)virtual_alloc(requestedMemory, use_large_pages_p); + uint8_t* separated_poh_block = nullptr; + if (allatonce_block && separated_poh_p) { - memory_details.allocation_pattern = initial_memory_details::EACH_GENERATION; - g_gc_lowest_address = min (b1, min(b2, b3)); - g_gc_highest_address = max (b1 + memory_details.block_count * normal_size, - max (b2 + memory_details.block_count * large_size, - b3 + memory_details.block_count * pinned_size)); + separated_poh_block = (uint8_t*)virtual_alloc(separate_pinned_size, false); + if (!separated_poh_block) + { + virtual_free(allatonce_block, requestedMemory); + allatonce_block = nullptr; + } + } + if (allatonce_block) + { + if (separated_poh_p) + { + g_gc_lowest_address = min(allatonce_block, separated_poh_block); + g_gc_highest_address = max((allatonce_block + requestedMemory), (separated_poh_block + separate_pinned_size)); + memory_details.allocation_pattern = initial_memory_details::ALLATONCE_SEPARATED_POH; + } + else + { + g_gc_lowest_address = allatonce_block; + g_gc_highest_address = allatonce_block + requestedMemory; + memory_details.allocation_pattern = initial_memory_details::ALLATONCE; + } for (int i = 0; i < memory_details.block_count; i++) { - memory_details.initial_normal_heap[i].memory_base = b1 + (i * normal_size); - memory_details.initial_large_heap[i].memory_base = b2 + (i * large_size); - memory_details.initial_pinned_heap[i].memory_base = b3 + (i * pinned_size); + memory_details.initial_normal_heap[i].memory_base = allatonce_block + + (i * normal_size); + memory_details.initial_large_heap[i].memory_base = allatonce_block + + (memory_details.block_count * normal_size) + (i * large_size); + if (separated_poh_p) + { + memory_details.initial_pinned_heap[i].memory_base = separated_poh_block + + (i * pinned_size); + } + else + { + memory_details.initial_pinned_heap[i].memory_base = allatonce_block + + (memory_details.block_count * (normal_size + large_size)) + (i * pinned_size); + } } - reserve_success = TRUE; } else { - // allocation failed, we'll go on to try allocating each block. - // We could preserve the b1 alloc, but code complexity increases - if (b1) - virtual_free (b1, memory_details.block_count * normal_size); - if (b2) - virtual_free (b2, memory_details.block_count * large_size); - if (b3) - virtual_free (b3, memory_details.block_count * pinned_size); - } + // try to allocate 3 blocks + uint8_t* b1 = (uint8_t*)virtual_alloc(memory_details.block_count * normal_size, use_large_pages_p); + uint8_t* b2 = (uint8_t*)virtual_alloc(memory_details.block_count * large_size, use_large_pages_p); + uint8_t* b3 = (uint8_t*)virtual_alloc(memory_details.block_count * pinned_size, use_large_pages_p && !separated_poh_p); - if ((b2 == NULL) && (memory_details.block_count > 1)) - { - memory_details.allocation_pattern = initial_memory_details::EACH_BLOCK; + if (b1 && b2 && b3) + { + memory_details.allocation_pattern = initial_memory_details::EACH_GENERATION; + g_gc_lowest_address = min(b1, min(b2, b3)); + g_gc_highest_address = max(b1 + memory_details.block_count * normal_size, + max(b2 + memory_details.block_count * large_size, + b3 + memory_details.block_count * pinned_size)); - imemory_data* current_block = memory_details.initial_memory; - for (int i = 0; i < (memory_details.block_count * (total_generation_count - ephemeral_generation_count)); i++, current_block++) + for (int i = 0; i < memory_details.block_count; i++) + { + memory_details.initial_normal_heap[i].memory_base = b1 + (i * normal_size); + memory_details.initial_large_heap[i].memory_base = b2 + (i * large_size); + memory_details.initial_pinned_heap[i].memory_base = b3 + (i * pinned_size); + } + + reserve_success = TRUE; + } + else { - size_t block_size = memory_details.block_size (i); - current_block->memory_base = - (uint8_t*)virtual_alloc (block_size, use_large_pages_p); - if (current_block->memory_base == 0) - { - // Free the blocks that we've allocated so far - current_block = memory_details.initial_memory; - for (int j = 0; j < i; j++, current_block++) { - if (current_block->memory_base != 0) { - block_size = memory_details.block_size (i); - virtual_free (current_block->memory_base, block_size); + // allocation failed, we'll go on to try allocating each block. + // We could preserve the b1 alloc, but code complexity increases + if (b1) + virtual_free(b1, memory_details.block_count * normal_size); + if (b2) + virtual_free(b2, memory_details.block_count * large_size); + if (b3) + virtual_free(b3, memory_details.block_count * pinned_size); + } + + if ((b2 == NULL) && (memory_details.block_count > 1)) + { + memory_details.allocation_pattern = initial_memory_details::EACH_BLOCK; + + imemory_data* current_block = memory_details.initial_memory; + for (int i = 0; i < (memory_details.block_count * (total_generation_count - ephemeral_generation_count)); i++, current_block++) + { + size_t block_size = memory_details.block_size(i); + uint16_t numa_node = NUMA_NODE_UNDEFINED; + if (heap_no_to_numa_node != nullptr) + { + int heap_no = i % memory_details.block_count; + numa_node = heap_no_to_numa_node[heap_no]; + } + current_block->memory_base = + (uint8_t*)virtual_alloc(block_size, use_large_pages_p, numa_node); + if (current_block->memory_base == 0) + { + // Free the blocks that we've allocated so far + current_block = memory_details.initial_memory; + for (int j = 0; j < i; j++, current_block++) { + if (current_block->memory_base != 0) { + block_size = memory_details.block_size(i); + virtual_free(current_block->memory_base, block_size); + } } + reserve_success = FALSE; + break; } - reserve_success = FALSE; - break; - } - else - { - if (current_block->memory_base < g_gc_lowest_address) - g_gc_lowest_address = current_block->memory_base; - if (((uint8_t*)current_block->memory_base + block_size) > g_gc_highest_address) - g_gc_highest_address = (current_block->memory_base + block_size); + else + { + if (current_block->memory_base < g_gc_lowest_address) + g_gc_lowest_address = current_block->memory_base; + if (((uint8_t*)current_block->memory_base + block_size) > g_gc_highest_address) + g_gc_highest_address = (current_block->memory_base + block_size); + } + reserve_success = TRUE; } - reserve_success = TRUE; } } } + return reserve_success; } @@ -4164,36 +4334,37 @@ void gc_heap::destroy_initial_memory() { if (memory_details.initial_memory != NULL) { - if (memory_details.allocation_pattern == initial_memory_details::ALLATONCE) + switch (memory_details.allocation_pattern) { - virtual_free(memory_details.initial_memory[0].memory_base, + case initial_memory_details::ALLATONCE: + virtual_free (memory_details.initial_memory[0].memory_base, memory_details.block_count*(memory_details.block_size_normal + memory_details.block_size_large + memory_details.block_size_pinned)); - } - else if (memory_details.allocation_pattern == initial_memory_details::ALLATONCE_SEPARATED_POH) - { + break; + + case initial_memory_details::ALLATONCE_SEPARATED_POH: virtual_free(memory_details.initial_memory[0].memory_base, - memory_details.block_count*(memory_details.block_size_normal + - memory_details.block_size_large)); + memory_details.block_count * (memory_details.block_size_normal + + memory_details.block_size_large)); virtual_free(memory_details.initial_pinned_heap[0].memory_base, - memory_details.block_count*(memory_details.block_size_pinned)); - } - else if (memory_details.allocation_pattern == initial_memory_details::EACH_GENERATION) - { + memory_details.block_count * (memory_details.block_size_pinned)); + break; + + case initial_memory_details::EACH_GENERATION: virtual_free (memory_details.initial_normal_heap[0].memory_base, memory_details.block_count*memory_details.block_size_normal); virtual_free (memory_details.initial_large_heap[0].memory_base, memory_details.block_count*memory_details.block_size_large); - virtual_free (memory_details.initial_pinned_heap[0].memory_base, + virtual_free (memory_details.initial_pinned_heap[0].memory_base, memory_details.block_count*memory_details.block_size_pinned); - } - else + break; + + case initial_memory_details::EACH_BLOCK: { - assert (memory_details.allocation_pattern == initial_memory_details::EACH_BLOCK); - imemory_data *current_block = memory_details.initial_memory; - for (int i = 0; i < (memory_details.block_count*(total_generation_count - ephemeral_generation_count)); i++, current_block++) + imemory_data* current_block = memory_details.initial_memory; + for (int i = 0; i < (memory_details.block_count * (total_generation_count - ephemeral_generation_count)); i++, current_block++) { size_t block_size = memory_details.block_size (i); if (current_block->memory_base != NULL) @@ -4201,6 +4372,24 @@ void gc_heap::destroy_initial_memory() virtual_free (current_block->memory_base, block_size); } } + break; + } + case initial_memory_details::EACH_NUMA_NODE: + for (int block_index = 0; block_index < memory_details.numa_reserved_block_count; block_index++) + { + numa_reserved_block * block = &memory_details.numa_reserved_block_table[block_index]; + + if (block->memory_base != nullptr) + { + virtual_free (block->memory_base, block->block_size); + } + } + delete [] memory_details.numa_reserved_block_table; + break; + + default: + assert (!"unexpected allocation_pattern"); + break; } delete [] memory_details.initial_memory; @@ -4226,7 +4415,7 @@ void* virtual_alloc (size_t size) return virtual_alloc(size, false); } -void* virtual_alloc (size_t size, bool use_large_pages_p) +void* virtual_alloc (size_t size, bool use_large_pages_p, uint16_t numa_node) { size_t requested_size = size; @@ -4249,8 +4438,8 @@ void* virtual_alloc (size_t size, bool use_large_pages_p) #endif // !FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP void* prgmem = use_large_pages_p ? - GCToOSInterface::VirtualReserveAndCommitLargePages(requested_size) : - GCToOSInterface::VirtualReserve(requested_size, card_size * card_word_width, flags); + GCToOSInterface::VirtualReserveAndCommitLargePages(requested_size, numa_node) : + GCToOSInterface::VirtualReserve(requested_size, card_size * card_word_width, flags, numa_node); void *aligned_mem = prgmem; // We don't want (prgmem + size) to be right at the end of the address space @@ -4828,10 +5017,45 @@ class heap_select memset(sniff_buffer, 0, sniff_buf_size*sizeof(uint8_t)); } - //can not enable gc numa aware, force all heaps to be in - //one numa node by filling the array with all 0s - if (!GCToOSInterface::CanEnableGCNumaAware()) - memset(heap_no_to_numa_node, 0, sizeof (heap_no_to_numa_node)); + bool do_numa = GCToOSInterface::CanEnableGCNumaAware(); + + // we want to assign heap indices such that there is a contiguous + // range of heap numbers for each numa node + + // we do this in two passes: + // 1. gather processor numbers and numa node numbers for all heaps + // 2. assign heap numbers for each numa node + + // Pass 1: gather processor numbers and numa node numbers + uint16_t proc_no[MAX_SUPPORTED_CPUS]; + uint16_t node_no[MAX_SUPPORTED_CPUS]; + uint16_t max_node_no = 0; + for (int i = 0; i < n_heaps; i++) + { + if (!GCToOSInterface::GetProcessorForHeap (i, &proc_no[i], &node_no[i])) + break; + if (!do_numa || node_no[i] == NUMA_NODE_UNDEFINED) + node_no[i] = 0; + max_node_no = max(max_node_no, node_no[i]); + } + + // Pass 2: assign heap numbers by numa node + int cur_heap_no = 0; + for (uint16_t cur_node_no = 0; cur_node_no <= max_node_no; cur_node_no++) + { + for (int i = 0; i < n_heaps; i++) + { + if (node_no[i] != cur_node_no) + continue; + + // we found a heap on cur_node_no + heap_no_to_proc_no[cur_heap_no] = proc_no[i]; + heap_no_to_numa_node[cur_heap_no] = cur_node_no; + proc_no_to_numa_node[proc_no[i]] = cur_node_no; + + cur_heap_no++; + } + } return TRUE; } @@ -5032,6 +5256,9 @@ class heap_select uint16_t numa_node = heap_no_to_numa_node[hn]; *start = (int)numa_node_to_heap_map[numa_node]; *end = (int)(numa_node_to_heap_map[numa_node+1]); +#ifdef HEAP_BALANCE_INSTRUMENTATION + dprintf(HEAP_BALANCE_TEMP_LOG, ("TEMPget_heap_range: %d is in numa node %d, start = %d, end = %d", hn, numa_node, *start, *end)); +#endif //HEAP_BALANCE_INSTRUMENTATION } // This gets the next valid numa node index starting at current_index+1. @@ -5217,7 +5444,7 @@ void add_to_hb_numa ( (hb_info_proc->index)++; } -const int hb_log_buffer_size = 1024; +const int hb_log_buffer_size = 4096; static char hb_log_buffer[hb_log_buffer_size]; int last_hb_recorded_gc_index = -1; #endif //HEAP_BALANCE_INSTRUMENTATION @@ -5432,24 +5659,6 @@ void gc_heap::destroy_thread_support () } } -bool get_proc_and_numa_for_heap (int heap_number) -{ - uint16_t proc_no; - uint16_t node_no; - - bool res = GCToOSInterface::GetProcessorForHeap (heap_number, &proc_no, &node_no); - if (res) - { - heap_select::set_proc_no_for_heap (heap_number, proc_no); - if (node_no != NUMA_NODE_UNDEFINED) - { - heap_select::set_numa_node_for_heap_and_proc (heap_number, proc_no, node_no); - } - } - - return res; -} - void set_thread_affinity_for_heap (int heap_number, uint16_t proc_no) { if (!GCToOSInterface::SetThreadAffinity (proc_no)) @@ -5633,7 +5842,7 @@ bool gc_heap::virtual_commit (void* address, size_t size, gc_oh_num oh, int h_nu check_commit_cs.Enter(); bool exceeded_p = false; - if (heap_hard_limit_oh[0] != 0) + if (heap_hard_limit_oh[soh] != 0) { if ((oh != gc_oh_num::none) && (committed_by_oh[oh] + size) > heap_hard_limit_oh[oh]) { @@ -10235,8 +10444,13 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size, reserved_memory = 0; size_t initial_heap_size = soh_segment_size + loh_segment_size + poh_segment_size; + uint16_t* heap_no_to_numa_node = nullptr; #ifdef MULTIPLE_HEAPS reserved_memory_limit = initial_heap_size * number_of_heaps; + if (!heap_select::init(number_of_heaps)) + return E_OUTOFMEMORY; + if (GCToOSInterface::CanEnableGCNumaAware()) + heap_no_to_numa_node = heap_select::heap_no_to_numa_node; #else //MULTIPLE_HEAPS reserved_memory_limit = initial_heap_size; int number_of_heaps = 1; @@ -10247,8 +10461,8 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size, check_commit_cs.Initialize(); } - bool separated_poh_p = use_large_pages_p && heap_hard_limit_oh[0] && (GCConfig::GetGCHeapHardLimitPOH() == 0) && (GCConfig::GetGCHeapHardLimitPOHPercent() == 0); - if (!reserve_initial_memory (soh_segment_size, loh_segment_size, poh_segment_size, number_of_heaps, use_large_pages_p, separated_poh_p)) + bool separated_poh_p = use_large_pages_p && heap_hard_limit_oh[soh] && (GCConfig::GetGCHeapHardLimitPOH() == 0) && (GCConfig::GetGCHeapHardLimitPOHPercent() == 0); + if (!reserve_initial_memory (soh_segment_size, loh_segment_size, poh_segment_size, number_of_heaps, use_large_pages_p, separated_poh_p, heap_no_to_numa_node)) return E_OUTOFMEMORY; #ifdef CARD_BUNDLE @@ -10316,9 +10530,6 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size, if (!create_thread_support (number_of_heaps)) return E_OUTOFMEMORY; - if (!heap_select::init (number_of_heaps)) - return E_OUTOFMEMORY; - #endif //MULTIPLE_HEAPS #ifdef MULTIPLE_HEAPS @@ -11023,7 +11234,6 @@ gc_heap::init_gc_heap (int h_number) } #ifdef MULTIPLE_HEAPS - get_proc_and_numa_for_heap (heap_number); if (!create_gc_thread ()) return 0; @@ -13853,7 +14063,7 @@ void gc_heap::balance_heaps (alloc_context* acontext) home_hp = acontext->get_home_heap ()->pGenGCHeap; proc_hp_num = heap_select::select_heap (acontext); - if (acontext->get_home_heap () != GCHeap::GetHeap (proc_hp_num)) + if (home_hp != gc_heap::g_heaps[proc_hp_num]) { #ifdef HEAP_BALANCE_INSTRUMENTATION alloc_count_p = false; @@ -13862,10 +14072,6 @@ void gc_heap::balance_heaps (alloc_context* acontext) } else if ((acontext->alloc_count & 15) == 0) set_home_heap = TRUE; - - if (set_home_heap) - { - } } else { @@ -13917,84 +14123,153 @@ void gc_heap::balance_heaps (alloc_context* acontext) return; } +#ifdef HEAP_BALANCE_INSTRUMENTATION + proc_no = GCToOSInterface::GetCurrentProcessorNumber (); + if (proc_no != last_proc_no) + { + dprintf (HEAP_BALANCE_TEMP_LOG, ("TEMPSP: %d->%d", last_proc_no, proc_no)); + multiple_procs_p = true; + last_proc_no = proc_no; + } + + int new_home_hp_num = heap_select::proc_no_to_heap_no[proc_no]; +#else + int new_home_hp_num = heap_select::select_heap(acontext); +#endif //HEAP_BALANCE_INSTRUMENTATION + gc_heap* new_home_hp = gc_heap::g_heaps[new_home_hp_num]; + acontext->set_home_heap (new_home_hp->vm_heap); + int start, end, finish; - heap_select::get_heap_range_for_heap (org_hp->heap_number, &start, &end); + heap_select::get_heap_range_for_heap (new_home_hp_num, &start, &end); finish = start + n_heaps; -try_again: - gc_heap* new_home_hp = 0; - do { max_hp = org_hp; max_hp_num = org_hp_num; max_size = org_size + delta; -#ifdef HEAP_BALANCE_INSTRUMENTATION - proc_no = GCToOSInterface::GetCurrentProcessorNumber (); - if (proc_no != last_proc_no) - { - dprintf (HEAP_BALANCE_TEMP_LOG, ("TEMPSP: %d->%d", last_proc_no, proc_no)); - multiple_procs_p = true; - last_proc_no = proc_no; - } - - int current_hp_num = heap_select::proc_no_to_heap_no[proc_no]; - acontext->set_home_heap (GCHeap::GetHeap (current_hp_num)); -#else - acontext->set_home_heap (GCHeap::GetHeap (heap_select::select_heap (acontext))); -#endif //HEAP_BALANCE_INSTRUMENTATION - new_home_hp = acontext->get_home_heap ()->pGenGCHeap; + org_alloc_context_count = org_hp->alloc_context_count; + max_alloc_context_count = org_alloc_context_count; if (org_hp == new_home_hp) max_size = max_size + delta; - org_alloc_context_count = org_hp->alloc_context_count; - max_alloc_context_count = org_alloc_context_count; if (max_alloc_context_count > 1) max_size /= max_alloc_context_count; - int actual_start = start; - int actual_end = (end - 1); - - for (int i = start; i < end; i++) + // check if the new home heap has more space + if (org_hp != new_home_hp) { - gc_heap* hp = GCHeap::GetHeap (i % n_heaps)->pGenGCHeap; - dd = hp->dynamic_data_of (0); - ptrdiff_t size = dd_new_allocation (dd); + dd = new_home_hp->dynamic_data_of(0); + ptrdiff_t size = dd_new_allocation(dd); - if (hp == new_home_hp) - { - size = size + delta; - } - int hp_alloc_context_count = hp->alloc_context_count; + // favor new home heap over org heap + size += delta * 2; + + int new_home_hp_alloc_context_count = new_home_hp->alloc_context_count; + if (new_home_hp_alloc_context_count > 0) + size /= (new_home_hp_alloc_context_count + 1); - if (hp_alloc_context_count > 0) - { - size /= (hp_alloc_context_count + 1); - } if (size > max_size) { #ifdef HEAP_BALANCE_INSTRUMENTATION - dprintf (HEAP_BALANCE_TEMP_LOG, ("TEMPorg h%d(%dmb), m h%d(%dmb)", + dprintf(HEAP_BALANCE_TEMP_LOG, ("TEMPorg h%d(%dmb), m h%d(%dmb)", org_hp_num, (max_size / 1024 / 1024), - hp->heap_number, (size / 1024 / 1024))); + new_home_hp_num, (size / 1024 / 1024))); #endif //HEAP_BALANCE_INSTRUMENTATION - max_hp = hp; + max_hp = new_home_hp; max_size = size; - max_hp_num = max_hp->heap_number; - max_alloc_context_count = hp_alloc_context_count; + max_hp_num = new_home_hp_num; + max_alloc_context_count = new_home_hp_alloc_context_count; } } - } - while (org_alloc_context_count != org_hp->alloc_context_count || - max_alloc_context_count != max_hp->alloc_context_count); - if ((max_hp == org_hp) && (end < finish)) - { - start = end; end = finish; - delta = local_delta * 2; // Make it twice as hard to balance to remote nodes on NUMA. - goto try_again; + // consider heaps both inside our local NUMA node, + // and outside, but with different thresholds + enum + { + LOCAL_NUMA_NODE, + REMOTE_NUMA_NODE + }; + + for (int pass = LOCAL_NUMA_NODE; pass <= REMOTE_NUMA_NODE; pass++) + { + int count = end - start; + int max_tries = min(count, 4); + + // we will consider max_tries consecutive (in a circular sense) + // other heaps from a semi random starting point + + // alloc_count often increases by multiples of 16 (due to logic at top of routine), + // and we want to advance the starting point by 4 between successive calls, + // therefore the shift right by 2 bits + int heap_num = start + ((acontext->alloc_count >> 2) + new_home_hp_num) % count; + +#ifdef HEAP_BALANCE_INSTRUMENTATION + dprintf(HEAP_BALANCE_TEMP_LOG, ("TEMP starting at h%d (home_heap_num = %d, alloc_count = %d)", heap_num, new_home_hp_num, acontext->alloc_count)); +#endif //HEAP_BALANCE_INSTRUMENTATION + + for (int tries = max_tries; --tries >= 0; heap_num++) + { + // wrap around if we hit the end of our range + if (heap_num >= end) + heap_num -= count; + // wrap around if we hit the end of the heap numbers + if (heap_num >= n_heaps) + heap_num -= n_heaps; + + assert (heap_num < n_heaps); + gc_heap* hp = gc_heap::g_heaps[heap_num]; + dd = hp->dynamic_data_of(0); + ptrdiff_t size = dd_new_allocation(dd); + +#ifdef HEAP_BALANCE_INSTRUMENTATION + dprintf(HEAP_BALANCE_TEMP_LOG, ("TEMP looking at h%d(%dmb)", + heap_num, (size / 1024 / 1024))); +#endif //HEAP_BALANCE_INSTRUMENTATION + // if the size is not bigger than what we already have, + // give up immediately, as it can't be a winner... + // this is a micro-optimization to avoid fetching the + // alloc_context_count and possibly dividing by it + if (size <= max_size) + continue; + + int hp_alloc_context_count = hp->alloc_context_count; + + if (hp_alloc_context_count > 0) + { + size /= (hp_alloc_context_count + 1); + } + + if (size > max_size) + { +#ifdef HEAP_BALANCE_INSTRUMENTATION + dprintf(HEAP_BALANCE_TEMP_LOG, ("TEMPorg h%d(%dmb), m h%d(%dmb)", + org_hp_num, (max_size / 1024 / 1024), + hp->heap_number, (size / 1024 / 1024))); +#endif //HEAP_BALANCE_INSTRUMENTATION + + max_hp = hp; + max_size = size; + max_hp_num = max_hp->heap_number; + max_alloc_context_count = hp_alloc_context_count; + } + } + + if ((max_hp == org_hp) && (end < finish)) + { + start = end; end = finish; + delta = local_delta * 2; // Make it twice as hard to balance to remote nodes on NUMA. + } + else + { + // we already found a better heap, or there are no remote NUMA nodes + break; + } + } } + while (org_alloc_context_count != org_hp->alloc_context_count || + max_alloc_context_count != max_hp->alloc_context_count); #ifdef HEAP_BALANCE_INSTRUMENTATION uint16_t ideal_proc_no_before_set_ideal = 0; @@ -35471,25 +35746,21 @@ HRESULT GCHeap::Initialize() #ifdef HOST_64BIT gc_heap::heap_hard_limit = (size_t)GCConfig::GetGCHeapHardLimit(); - gc_heap::heap_hard_limit_oh[0] = (size_t)GCConfig::GetGCHeapHardLimitSOH(); - gc_heap::heap_hard_limit_oh[1] = (size_t)GCConfig::GetGCHeapHardLimitLOH(); - gc_heap::heap_hard_limit_oh[2] = (size_t)GCConfig::GetGCHeapHardLimitPOH(); + gc_heap::heap_hard_limit_oh[soh] = (size_t)GCConfig::GetGCHeapHardLimitSOH(); + gc_heap::heap_hard_limit_oh[loh] = (size_t)GCConfig::GetGCHeapHardLimitLOH(); + gc_heap::heap_hard_limit_oh[poh] = (size_t)GCConfig::GetGCHeapHardLimitPOH(); - if (gc_heap::heap_hard_limit_oh[0] || gc_heap::heap_hard_limit_oh[1] || gc_heap::heap_hard_limit_oh[2]) + if (gc_heap::heap_hard_limit_oh[soh] || gc_heap::heap_hard_limit_oh[loh] || gc_heap::heap_hard_limit_oh[poh]) { - if (!gc_heap::heap_hard_limit_oh[0]) + if (!gc_heap::heap_hard_limit_oh[soh]) { return E_INVALIDARG; } - if (!gc_heap::heap_hard_limit_oh[1]) + if (!gc_heap::heap_hard_limit_oh[loh]) { return E_INVALIDARG; } - if (gc_heap::heap_hard_limit_oh[2] < min_segment_size_hard_limit) - { - gc_heap::heap_hard_limit_oh[2] = min_segment_size_hard_limit; - } - gc_heap::heap_hard_limit = gc_heap::heap_hard_limit_oh[0] + gc_heap::heap_hard_limit_oh[1] + gc_heap::heap_hard_limit_oh[2]; + gc_heap::heap_hard_limit = gc_heap::heap_hard_limit_oh[soh] + gc_heap::heap_hard_limit_oh[loh] + gc_heap::heap_hard_limit_oh[poh]; } else { @@ -35514,17 +35785,10 @@ HRESULT GCHeap::Initialize() { return E_INVALIDARG; } - gc_heap::heap_hard_limit_oh[0] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_soh / (uint64_t)100); - gc_heap::heap_hard_limit_oh[1] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_loh / (uint64_t)100); - if (percent_of_mem_poh == 0) - { - gc_heap::heap_hard_limit_oh[2] = min_segment_size_hard_limit; - } - else - { - gc_heap::heap_hard_limit_oh[2] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_poh / (uint64_t)100); - } - gc_heap::heap_hard_limit = gc_heap::heap_hard_limit_oh[0] + gc_heap::heap_hard_limit_oh[1] + gc_heap::heap_hard_limit_oh[2]; + gc_heap::heap_hard_limit_oh[soh] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_soh / (uint64_t)100); + gc_heap::heap_hard_limit_oh[loh] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_loh / (uint64_t)100); + gc_heap::heap_hard_limit_oh[poh] = (size_t)(gc_heap::total_physical_mem * (uint64_t)percent_of_mem_poh / (uint64_t)100); + gc_heap::heap_hard_limit = gc_heap::heap_hard_limit_oh[soh] + gc_heap::heap_hard_limit_oh[loh] + gc_heap::heap_hard_limit_oh[poh]; } } @@ -35618,13 +35882,18 @@ HRESULT GCHeap::Initialize() if (gc_heap::heap_hard_limit) { gc_heap::use_large_pages_p = GCConfig::GetGCLargePages(); - if (gc_heap::heap_hard_limit_oh[0]) + if (gc_heap::heap_hard_limit_oh[soh]) { #ifdef MULTIPLE_HEAPS if (nhp_from_config == 0) { for (int i = 0; i < (total_oh_count - 1); i++) { + if (i == poh && gc_heap::heap_hard_limit_oh[poh] == 0) + { + // if size 0 was specified for POH, ignore it for the nhp computation + continue; + } uint32_t nhp_oh = (uint32_t)(gc_heap::heap_hard_limit_oh[i] / min_segment_size_hard_limit); nhp = min (nhp, nhp_oh); } @@ -35634,9 +35903,9 @@ HRESULT GCHeap::Initialize() } } #endif - seg_size = gc_heap::heap_hard_limit_oh[0] / nhp; - large_seg_size = gc_heap::heap_hard_limit_oh[1] / nhp; - pin_seg_size = gc_heap::heap_hard_limit_oh[2] / nhp; + seg_size = gc_heap::heap_hard_limit_oh[soh] / nhp; + large_seg_size = gc_heap::heap_hard_limit_oh[loh] / nhp; + pin_seg_size = (gc_heap::heap_hard_limit_oh[poh] != 0) ? (gc_heap::heap_hard_limit_oh[2] / nhp) : min_segment_size_hard_limit; size_t aligned_seg_size = align_on_segment_hard_limit (seg_size); size_t aligned_large_seg_size = align_on_segment_hard_limit (large_seg_size); diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index 4db27dc3896a..fb82ea41d77a 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -1318,7 +1318,7 @@ class gc_heap protected: PER_HEAP_ISOLATED - BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p, bool separated_poh_p); + BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p, bool separated_poh_p, uint16_t* heap_no_to_numa_node); PER_HEAP_ISOLATED void destroy_initial_memory(); diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index 76a9efaf36e5..8bcc98a3526a 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -646,7 +646,7 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size) // size - size of the virtual memory range // Return: // Starting virtual address of the committed range -void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) +void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size, uint16_t node) { #if HAVE_MAP_HUGETLB uint32_t largePagesFlag = MAP_HUGETLB; @@ -657,7 +657,7 @@ void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) #endif void* pRetVal = VirtualReserveInner(size, OS_PAGE_SIZE, 0, largePagesFlag); - if (VirtualCommit(pRetVal, size, NUMA_NODE_UNDEFINED)) + if (VirtualCommit(pRetVal, size, node)) { return pRetVal; } diff --git a/src/coreclr/src/gc/windows/gcenv.windows.cpp b/src/coreclr/src/gc/windows/gcenv.windows.cpp index 4b44ca9e8d5b..53b868df6820 100644 --- a/src/coreclr/src/gc/windows/gcenv.windows.cpp +++ b/src/coreclr/src/gc/windows/gcenv.windows.cpp @@ -692,14 +692,14 @@ void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t fl assert((alignment & (alignment - 1)) == 0); assert(alignment <= 0x10000); + DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE; if (node == NUMA_NODE_UNDEFINED) { - DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE; return ::VirtualAlloc (nullptr, size, memFlags, PAGE_READWRITE); } else { - return ::VirtualAllocExNuma (::GetCurrentProcess (), NULL, size, MEM_RESERVE, PAGE_READWRITE, node); + return ::VirtualAllocExNuma (::GetCurrentProcess (), NULL, size, memFlags, PAGE_READWRITE, node); } } @@ -719,7 +719,7 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size) // size - size of the virtual memory range // Return: // Starting virtual address of the committed range -void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) +void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size, uint16_t node) { void* pRetVal = nullptr; @@ -736,7 +736,14 @@ void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) SIZE_T largePageMinimum = GetLargePageMinimum(); size = (size + (largePageMinimum - 1)) & ~(largePageMinimum - 1); - return ::VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (node == NUMA_NODE_UNDEFINED) + { + return ::VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + } + else + { + return ::VirtualAllocExNuma(::GetCurrentProcess(), NULL, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE, node); + } } // Commit virtual memory range. It must be part of a range reserved using VirtualReserve. diff --git a/src/coreclr/src/vm/gcenv.os.cpp b/src/coreclr/src/vm/gcenv.os.cpp index dfb7463296f1..2567e0fb1071 100644 --- a/src/coreclr/src/vm/gcenv.os.cpp +++ b/src/coreclr/src/vm/gcenv.os.cpp @@ -330,10 +330,10 @@ void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t fl { LIMITED_METHOD_CONTRACT; + DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE; + if (node == NUMA_NODE_UNDEFINED) { - DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE; - // This is not strictly necessary for a correctness standpoint. Windows already guarantees // allocation granularity alignment when using MEM_RESERVE, so aligning the size here has no effect. // However, ClrVirtualAlloc does expect the size to be aligned to the allocation granularity. @@ -349,7 +349,7 @@ void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t fl } else { - return NumaNodeInfo::VirtualAllocExNuma (::GetCurrentProcess (), NULL, size, MEM_RESERVE, PAGE_READWRITE, node); + return NumaNodeInfo::VirtualAllocExNuma (::GetCurrentProcess (), NULL, size, memFlags, PAGE_READWRITE, node); } } @@ -372,7 +372,7 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size) // size - size of the virtual memory range // Return: // Starting virtual address of the committed range -void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) +void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size, uint16_t node) { LIMITED_METHOD_CONTRACT; @@ -391,7 +391,14 @@ void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) size = (size + (largePageMinimum - 1)) & ~(largePageMinimum - 1); #endif - return ::ClrVirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (node == NUMA_NODE_UNDEFINED) + { + return ::ClrVirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + } + else + { + return NumaNodeInfo::VirtualAllocExNuma(::GetCurrentProcess(), nullptr, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE, node); + } } // Commit virtual memory range. It must be part of a range reserved using VirtualReserve. From 795acbb7a2d4fbf0beac91096330ce9d34c97ae3 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Thu, 13 Aug 2020 17:28:05 +0200 Subject: [PATCH 454/755] Enable Http2.0 tests for Http telemetry (#40763) --- .../src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs | 6 +++++- .../System.Net.Http/tests/FunctionalTests/TelemetryTest.cs | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) 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 c019cd416409..bc65f04c7cc3 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 @@ -352,7 +352,11 @@ private void Complete() _creditWaiter = null; } - if (HttpTelemetry.Log.IsEnabled()) _request.OnStopped(); + if (HttpTelemetry.Log.IsEnabled()) + { + bool aborted = _requestCompletionState == StreamCompletionState.Failed || _responseCompletionState == StreamCompletionState.Failed; + _request.OnStopped(aborted); + } } private void Cancel() diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs index 89dc6ac70622..ea9df9b0c0d9 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs @@ -20,6 +20,8 @@ public TelemetryTest_Http11(ITestOutputHelper output) : base(output) { } public sealed class TelemetryTest_Http20 : TelemetryTest { + protected override Version UseVersion => HttpVersion.Version20; + public TelemetryTest_Http20(ITestOutputHelper output) : base(output) { } } @@ -135,7 +137,7 @@ private static void ValidateStartEventPayload(EventWrittenEventArgs startEvent) Assert.Equal("RequestStart", startEvent.EventName); Assert.Equal(6, startEvent.Payload.Count); - Assert.Equal("http", (string)startEvent.Payload[0]); + Assert.StartsWith("http", (string)startEvent.Payload[0]); Assert.NotEmpty((string)startEvent.Payload[1]); // host Assert.True(startEvent.Payload[2] is int port && port >= 0 && port <= 65535); Assert.NotEmpty((string)startEvent.Payload[3]); // pathAndQuery From d7d36b132f940abdf6e99e91690f19debc40578b Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 13 Aug 2020 12:52:22 -0400 Subject: [PATCH 455/755] [wasm][tests] Support running tests with a browser (#40173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [wasm][tests] Support running tests with a browser - WasmAppBuilder will generate an `index.html` which will be used to run the tests - runtime-test.js: For the browser case, a simple `exit` doesn't end the script execution, so we explicitly `return` in the code, to stop. * Update tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs Co-authored-by: Santiago Fernandez Madero * [wasm] runtime-test.js: correctly load js files in the browser case * [wasm][tests] runtime-test.js: Add a special element on exit, which the .. `wasm test-browser` command can watch for. * Update src/mono/wasm/runtime-test.js Co-authored-by: Alexander Köplinger * runtime-test.js: Correctly handle the case of no arguments. * runtime-test.js: Ensure `arguments` is not undefined Co-authored-by: Santiago Fernandez Madero Co-authored-by: Alexander Köplinger --- src/mono/wasm/runtime-test.js | 58 ++++++++++++++----- .../WasmAppBuilder/WasmAppBuilder.cs | 3 + 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 74f6a664d212..21b3f118abf0 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -74,6 +74,10 @@ try { } } catch (e) { } + +if (arguments === undefined) + arguments = []; + //end of all the nice shell glue code. // set up a global variable to be accessed in App.init @@ -81,9 +85,13 @@ var testArguments = arguments; function test_exit (exit_code) { if (is_browser) { - // Notify the puppeteer script + // Notify the selenium script Module.exit_code = exit_code; print ("WASM EXIT " + exit_code); + var tests_done_elem = document.createElement ("label"); + tests_done_elem.id = "tests_done"; + tests_done_elem.innerHTML = exit_code.toString (); + document.body.appendChild (tests_done_elem); } else { Module.wasm_exit (exit_code); } @@ -111,7 +119,7 @@ setenv = {}; runtime_args = []; enable_gc = true; enable_zoneinfo = false; -while (true) { +while (args !== undefined && args.length > 0) { if (args [0].startsWith ("--profile=")) { var arg = args [0].substring ("--profile=".length); @@ -145,8 +153,18 @@ function writeContentToFile(content, path) FS.close(stream); } -if (typeof window == "undefined") - load ("mono-config.js"); +function loadScript (url) +{ + if (is_browser) { + var script = document.createElement ("script"); + script.src = url; + document.head.appendChild (script); + } else { + load (url); + } +} + +loadScript ("mono-config.js"); var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -219,8 +237,7 @@ var Module = { }, }; -if (typeof window == "undefined") - load ("dotnet.js"); +loadScript ("dotnet.js"); const IGNORE_PARAM_COUNT = -1; @@ -248,6 +265,11 @@ var App = { init (""); } + if (args.length == 0) { + fail_exec ("Missing required --run argument"); + return; + } + if (args[0] == "--regression") { var exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) @@ -272,14 +294,20 @@ var App = { if (args[0] == "--run") { // Run an exe - if (args.length == 1) + if (args.length == 1) { fail_exec ("Error: Missing main executable argument."); + return; + } main_assembly = assembly_load (args[1]); - if (main_assembly == 0) + if (main_assembly == 0) { fail_exec ("Error: Unable to load main executable '" + args[1] + "'"); + return; + } main_method = assembly_get_entry_point (main_assembly); - if (main_method == 0) + if (main_method == 0) { fail_exec ("Error: Main (string[]) method not found."); + return; + } var app_args = string_array_new (args.length - 2); for (var i = 2; i < args.length; ++i) { @@ -307,14 +335,15 @@ var App = { if (eh_res != 0) { print ("Exception:" + string_get_utf8 (res)); test_exit (1); + return; } var exit_code = unbox_int (res); - if (exit_code != 0) - test_exit (exit_code); + test_exit (exit_code); } catch (ex) { print ("JS exception: " + ex); print (ex.stack); test_exit (1); + return; } /* @@ -331,15 +360,12 @@ var App = { } */ - if (is_browser) - test_exit (0); - return; } else { - fail_exec ("Unhanded argument: " + args [0]); + fail_exec ("Unhandled argument: " + args [0]); } }, call_test_method: function (method_name, args) { return BINDING.call_static_method("[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name, args); } -}; \ No newline at end of file +}; diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 4ca72c5e61b1..87b343eecf8b 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -138,6 +138,9 @@ public override bool Execute () File.Copy(Path.Join (MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true); File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true); + var html = @""; + File.WriteAllText(Path.Join(AppDir, "index.html"), html); + foreach (var assembly in _assemblies.Values) { config.Assets.Add(new AssemblyEntry (Path.GetFileName(assembly.Location))); if (DebugLevel > 0) { From 7a7c9e0739bb98b0816a3fc47e1532ab2fb5bb59 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Thu, 13 Aug 2020 09:53:08 -0700 Subject: [PATCH 456/755] ensure we can cancel a write operation while we are waiting for a write on the HTTP2 connection to complete (#39654) Co-authored-by: Geoffrey Kizer --- .../SocketsHttpHandler/Http2Connection.cs | 33 ++++++++------- .../HttpClientHandlerTest.Http2.cs | 40 +++++++++++++++++++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 3aae8a9357d8..e77e2f5ea61b 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 @@ -889,28 +889,32 @@ private async Task ProcessOutgoingFramesAsync() { while (_writeChannel.Reader.TryRead(out WriteQueueEntry? writeEntry)) { - if (writeEntry.TryDisableCancellation()) + if (_abortException is not null) { - if (_abortException is not null) + if (writeEntry.TryDisableCancellation()) { writeEntry.SetException(_abortException); } - else - { - int writeBytes = writeEntry.WriteBytes; + } + else + { + int writeBytes = writeEntry.WriteBytes; - // If the buffer has already grown to 32k, does not have room for the next request, - // and is non-empty, flush the current contents to the wire. - int totalBufferLength = _outgoingBuffer.Capacity; - if (totalBufferLength >= UnflushedOutgoingBufferSize) + // If the buffer has already grown to 32k, does not have room for the next request, + // and is non-empty, flush the current contents to the wire. + int totalBufferLength = _outgoingBuffer.Capacity; + if (totalBufferLength >= UnflushedOutgoingBufferSize) + { + int activeBufferLength = _outgoingBuffer.ActiveLength; + if (writeBytes >= totalBufferLength - activeBufferLength) { - int activeBufferLength = _outgoingBuffer.ActiveLength; - if (writeBytes >= totalBufferLength - activeBufferLength) - { - await FlushOutgoingBytesAsync().ConfigureAwait(false); - } + await FlushOutgoingBytesAsync().ConfigureAwait(false); } + } + // We are ready to process the write, so disable write cancellation now. + if (writeEntry.TryDisableCancellation()) + { _outgoingBuffer.EnsureAvailableSpace(writeBytes); try @@ -930,7 +934,6 @@ private async Task ProcessOutgoingFramesAsync() writeEntry.SetException(e); } } - } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index 46b39fcb0488..837e079fe125 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -3227,6 +3227,46 @@ await Http2LoopbackServer.CreateClientAndServerAsync( }); } + [Fact] + [OuterLoop("Uses Task.Delay")] + public async Task SocketSendQueueFull_RequestCanceled_ThrowsOperationCanceled() + { + TaskCompletionSource clientComplete = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + await Http2LoopbackServer.CreateClientAndServerAsync( + async uri => + { + CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + + using HttpClient client = CreateHttpClient(); + + // Post a large request, large enough to fill the socket send buffer + Task postTask = client.PostAsync(uri, new StringContent(new string('a', 16 * 1024 * 1024)), cancellationTokenSource.Token); + + // Wait a while to hopefully ensure that the send buffer has been completely filled + await Task.Delay(3000); + + Assert.False(postTask.IsCompleted); + + // Ensure that the request can be cancelled + cancellationTokenSource.Cancel(); + await Assert.ThrowsAnyAsync(() => postTask); + + // Allow server to exit + clientComplete.SetResult(); + }, + async server => + { + // Establish the connection and ensure client is not blocked on windows + Http2LoopbackConnection connection = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.InitialWindowSize, Value = 128 * 1024 * 1024 }); + await connection.WriteFrameAsync(new WindowUpdateFrame(128 * 1024 * 1024, 0)); + + // Now, don't process any frames. Let the client's send buffer fill up. + // When the client is done, it will signal us. + await clientComplete.Task; + }); + } + [Theory] [InlineData(true)] [InlineData(false)] From 196fd1804dcc36fc6a398bcc318e07a171a0fc9c Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Thu, 13 Aug 2020 19:55:30 +0300 Subject: [PATCH 457/755] [browser] Mark APIs as unsupported on browser (#40612) * Mark System.Security.Cryptography.OpenSsl as unsupported on browser * Mark other System.Security.Cryptography APIs as unsupported on browser * Mark System.Data.Odbc.* as unsupported on browser * Mark System.DirectoryServices.Protocols APIs as unsupported on browser * Mark System.Drawing.Common APIs as unsupported on browser * Mark System.IO.Ports as unsupported on browser --- eng/versioning.targets | 15 ++++++++++----- .../System.Data.Odbc/Directory.Build.props | 2 ++ .../Directory.Build.props | 2 ++ .../System.Drawing.Common/Directory.Build.props | 2 ++ .../System.IO.Ports/Directory.Build.props | 2 ++ .../Directory.Build.props | 1 + .../Directory.Build.props | 2 ++ .../Directory.Build.props | 2 +- .../Directory.Build.props | 2 ++ .../Directory.Build.props | 2 ++ .../Directory.Build.props | 1 + .../Directory.Build.props | 2 ++ 12 files changed, 29 insertions(+), 6 deletions(-) diff --git a/eng/versioning.targets b/eng/versioning.targets index 2a2f10dbcafb..efb7af48b76c 100644 --- a/eng/versioning.targets +++ b/eng/versioning.targets @@ -29,13 +29,18 @@ - - - - <_Parameter1>$(UnsupportedOSPlatform) - + + <_unsupportedOSPlatforms Include="$(UnsupportedOSPlatforms)" /> + + + + <_Parameter1>%(_unsupportedOSPlatforms.Identity) + + + + diff --git a/src/libraries/System.Data.Odbc/Directory.Build.props b/src/libraries/System.Data.Odbc/Directory.Build.props index bdcfca3b543c..4784967b7f86 100644 --- a/src/libraries/System.Data.Odbc/Directory.Build.props +++ b/src/libraries/System.Data.Odbc/Directory.Build.props @@ -2,5 +2,7 @@ Open + true + browser \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props b/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props index 131fb6770cd1..cad73bcaafa1 100644 --- a/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props +++ b/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props @@ -6,5 +6,7 @@ to a different assembly. --> 4.0.0.0 Microsoft + true + browser \ No newline at end of file diff --git a/src/libraries/System.Drawing.Common/Directory.Build.props b/src/libraries/System.Drawing.Common/Directory.Build.props index bdcfca3b543c..4784967b7f86 100644 --- a/src/libraries/System.Drawing.Common/Directory.Build.props +++ b/src/libraries/System.Drawing.Common/Directory.Build.props @@ -2,5 +2,7 @@ Open + true + browser \ No newline at end of file diff --git a/src/libraries/System.IO.Ports/Directory.Build.props b/src/libraries/System.IO.Ports/Directory.Build.props index bdcfca3b543c..4784967b7f86 100644 --- a/src/libraries/System.IO.Ports/Directory.Build.props +++ b/src/libraries/System.IO.Ports/Directory.Build.props @@ -2,5 +2,7 @@ Open + true + browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props b/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props index d68d22c1b917..ce244cbea561 100644 --- a/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Csp/Directory.Build.props @@ -3,5 +3,6 @@ Microsoft true + browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props b/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props index 63f02a0f817e..ce244cbea561 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Encoding/Directory.Build.props @@ -2,5 +2,7 @@ Microsoft + true + browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props index 34e587248074..05ae3c4dc8f2 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.OpenSsl/Directory.Build.props @@ -3,6 +3,6 @@ Microsoft true - windows + windows;browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Pkcs/Directory.Build.props b/src/libraries/System.Security.Cryptography.Pkcs/Directory.Build.props index e8d65546d0c8..1f799d605feb 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Pkcs/Directory.Build.props @@ -2,5 +2,7 @@ Microsoft + true + browser diff --git a/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props b/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props index 63f02a0f817e..ce244cbea561 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Primitives/Directory.Build.props @@ -2,5 +2,7 @@ Microsoft + true + browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props b/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props index d68d22c1b917..ce244cbea561 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.X509Certificates/Directory.Build.props @@ -3,5 +3,6 @@ Microsoft true + browser \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Xml/Directory.Build.props b/src/libraries/System.Security.Cryptography.Xml/Directory.Build.props index bdcfca3b543c..4784967b7f86 100644 --- a/src/libraries/System.Security.Cryptography.Xml/Directory.Build.props +++ b/src/libraries/System.Security.Cryptography.Xml/Directory.Build.props @@ -2,5 +2,7 @@ Open + true + browser \ No newline at end of file From a24db1ceb73e436eab32da43ae069832a04ce3dd Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 13 Aug 2020 13:30:42 -0400 Subject: [PATCH 458/755] Make Linux fetch timeout behavior for chain building more consistent with Windows Change the UrlRetrievalTimeout behavior on Linux to match Windows' existing behavior of using a per-operation timeout rather than cumulative. Windows 8.1 and Windows 10 seem to have different upper limits for the UrlRetrievalTimeout. Linux matches the Windows 10 version (which is lower: 1 minute). --- .../X509Certificates/RevocationResponder.cs | 30 ++ .../Pal.Unix/CertificateAssetDownloader.cs | 21 +- .../Cryptography/Pal.Unix/ChainPal.cs | 17 +- .../Cryptography/Pal.Unix/CrlCache.cs | 13 +- .../Pal.Unix/OpenSslX509ChainProcessor.cs | 24 +- .../tests/RevocationTests/TimeoutTests.cs | 300 ++++++++++++++++++ ...Cryptography.X509Certificates.Tests.csproj | 1 + 7 files changed, 368 insertions(+), 38 deletions(-) create mode 100644 src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/TimeoutTests.cs diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs index aa3df4cf8e27..cd59fde64434 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs @@ -30,6 +30,9 @@ private readonly Dictionary _crlPaths public bool RespondEmpty { get; set; } + public TimeSpan ResponseDelay { get; set; } + public DelayedActionsFlag DelayedActions { get; set; } + private RevocationResponder(HttpListener listener, string uriPrefix) { _listener = listener; @@ -160,6 +163,12 @@ private void HandleRequest(HttpListenerContext context, ref bool responded) if (_aiaPaths.TryGetValue(url, out authority)) { + if (DelayedActions.HasFlag(DelayedActionsFlag.Aia)) + { + Trace($"Delaying response by {ResponseDelay}."); + Thread.Sleep(ResponseDelay); + } + byte[] certData = RespondEmpty ? Array.Empty() : authority.GetCertData(); responded = true; @@ -172,6 +181,12 @@ private void HandleRequest(HttpListenerContext context, ref bool responded) if (_crlPaths.TryGetValue(url, out authority)) { + if (DelayedActions.HasFlag(DelayedActionsFlag.Crl)) + { + Trace($"Delaying response by {ResponseDelay}."); + Thread.Sleep(ResponseDelay); + } + byte[] crl = RespondEmpty ? Array.Empty() : authority.GetCrl(); responded = true; @@ -211,6 +226,12 @@ private void HandleRequest(HttpListenerContext context, ref bool responded) byte[] ocspResponse = RespondEmpty ? Array.Empty() : authority.BuildOcspResponse(certId, nonce); + if (DelayedActions.HasFlag(DelayedActionsFlag.Ocsp)) + { + Trace($"Delaying response by {ResponseDelay}."); + Thread.Sleep(ResponseDelay); + } + responded = true; context.Response.StatusCode = 200; context.Response.StatusDescription = "OK"; @@ -352,5 +373,14 @@ private static void Trace(string trace) Console.WriteLine(trace); } } + + internal enum DelayedActionsFlag : byte + { + None = 0, + Ocsp = 0b1, + Crl = 0b10, + Aia = 0b100, + All = 0b11111111 + } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs index 7b0b166c8d12..c6b9fef9e115 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs @@ -18,9 +18,9 @@ internal static class CertificateAssetDownloader { private static readonly Func? s_downloadBytes = CreateDownloadBytesFunc(); - internal static X509Certificate2? DownloadCertificate(string uri, ref TimeSpan remainingDownloadTime) + internal static X509Certificate2? DownloadCertificate(string uri, TimeSpan downloadTimeout) { - byte[]? data = DownloadAsset(uri, ref remainingDownloadTime); + byte[]? data = DownloadAsset(uri, downloadTimeout); if (data == null || data.Length == 0) { @@ -39,9 +39,9 @@ internal static class CertificateAssetDownloader } } - internal static SafeX509CrlHandle? DownloadCrl(string uri, ref TimeSpan remainingDownloadTime) + internal static SafeX509CrlHandle? DownloadCrl(string uri, TimeSpan downloadTimeout) { - byte[]? data = DownloadAsset(uri, ref remainingDownloadTime); + byte[]? data = DownloadAsset(uri, downloadTimeout); if (data == null) { @@ -77,9 +77,9 @@ internal static class CertificateAssetDownloader return null; } - internal static SafeOcspResponseHandle? DownloadOcspGet(string uri, ref TimeSpan remainingDownloadTime) + internal static SafeOcspResponseHandle? DownloadOcspGet(string uri, TimeSpan downloadTimeout) { - byte[]? data = DownloadAsset(uri, ref remainingDownloadTime); + byte[]? data = DownloadAsset(uri, downloadTimeout); if (data == null) { @@ -100,12 +100,11 @@ internal static class CertificateAssetDownloader return resp; } - private static byte[]? DownloadAsset(string uri, ref TimeSpan remainingDownloadTime) + private static byte[]? DownloadAsset(string uri, TimeSpan downloadTimeout) { - if (s_downloadBytes != null && remainingDownloadTime > TimeSpan.Zero) + if (s_downloadBytes != null && downloadTimeout > TimeSpan.Zero) { - long totalMillis = (long)remainingDownloadTime.TotalMilliseconds; - Stopwatch stopwatch = Stopwatch.StartNew(); + long totalMillis = (long)downloadTimeout.TotalMilliseconds; CancellationTokenSource? cts = totalMillis > int.MaxValue ? null : new CancellationTokenSource((int)totalMillis); try @@ -115,8 +114,6 @@ internal static class CertificateAssetDownloader catch { } finally { - // TimeSpan.Zero isn't a worrisome value on the subtraction, it only means "no limit" on the original input. - remainingDownloadTime -= stopwatch.Elapsed; cts?.Dispose(); } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs index 5e37365827e6..d32d8b58c837 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs @@ -11,6 +11,8 @@ namespace Internal.Cryptography.Pal { internal sealed partial class ChainPal { + private static readonly TimeSpan s_maxUrlRetrievalTimeout = TimeSpan.FromMinutes(1); + public static IChainPal FromHandle(IntPtr chainContext) { throw new PlatformNotSupportedException(); @@ -35,10 +37,17 @@ public static IChainPal BuildChain( TimeSpan timeout, bool disableAia) { - // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { - timeout = TimeSpan.MaxValue; + // An input value of 0 on the timeout is treated as 15 seconds, to match Windows. + timeout = TimeSpan.FromSeconds(15); + } + else if (timeout > s_maxUrlRetrievalTimeout || timeout < TimeSpan.Zero) + { + // Windows has a max timeout of 1 minute, so we'll match. Windows also treats + // the timeout as unsigned, so a negative value gets treated as a large positive + // value that is also clamped. + timeout = s_maxUrlRetrievalTimeout; } // Let Unspecified mean Local, so only convert if the source was UTC. @@ -55,14 +64,14 @@ public static IChainPal BuildChain( { } - TimeSpan remainingDownloadTime = timeout; + TimeSpan downloadTimeout = timeout; OpenSslX509ChainProcessor chainPal = OpenSslX509ChainProcessor.InitiateChain( ((OpenSslX509CertificateReader)cert).SafeHandle, customTrustStore, trustMode, verificationTime, - remainingDownloadTime); + downloadTimeout); Interop.Crypto.X509VerifyStatusCode status = chainPal.FindFirstChain(extraStore); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs index 16e2dc5e2600..d1c6aa7cbe44 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs @@ -36,7 +36,7 @@ public static void AddCrlForCertificate( SafeX509StoreHandle store, X509RevocationMode revocationMode, DateTime verificationTime, - ref TimeSpan remainingDownloadTime) + TimeSpan downloadTimeout) { // In Offline mode, accept any cached CRL we have. // "CRL is Expired" is a better match for Offline than "Could not find CRL" @@ -59,14 +59,13 @@ public static void AddCrlForCertificate( return; } - // Don't do any work if we're over limit or prohibited from fetching new CRLs - if (remainingDownloadTime <= TimeSpan.Zero || - revocationMode != X509RevocationMode.Online) + // Don't do any work if we're prohibited from fetching new CRLs + if (revocationMode != X509RevocationMode.Online) { return; } - DownloadAndAddCrl(url, crlFileName, store, ref remainingDownloadTime); + DownloadAndAddCrl(url, crlFileName, store, downloadTimeout); } private static bool AddCachedCrl(string crlFileName, SafeX509StoreHandle store, DateTime verificationTime) @@ -156,11 +155,11 @@ private static void DownloadAndAddCrl( string url, string crlFileName, SafeX509StoreHandle store, - ref TimeSpan remainingDownloadTime) + TimeSpan downloadTimeout) { // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still // dispose our copy. - using (SafeX509CrlHandle? crl = CertificateAssetDownloader.DownloadCrl(url, ref remainingDownloadTime)) + using (SafeX509CrlHandle? crl = CertificateAssetDownloader.DownloadCrl(url, downloadTimeout)) { // null is a valid return (e.g. no remainingDownloadTime) if (crl != null && !crl.IsInvalid) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs index a41997057ee7..8fd228dfe9eb 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs @@ -43,7 +43,7 @@ internal sealed class OpenSslX509ChainProcessor : IChainPal private readonly SafeX509StackHandle _untrustedLookup; private readonly SafeX509StoreCtxHandle _storeCtx; private readonly DateTime _verificationTime; - private TimeSpan _remainingDownloadTime; + private readonly TimeSpan _downloadTimeout; private WorkingChain? _workingChain; private OpenSslX509ChainProcessor( @@ -52,14 +52,14 @@ private OpenSslX509ChainProcessor( SafeX509StackHandle untrusted, SafeX509StoreCtxHandle storeCtx, DateTime verificationTime, - TimeSpan remainingDownloadTime) + TimeSpan downloadTimeout) { _leafHandle = leafHandle; _store = store; _untrustedLookup = untrusted; _storeCtx = storeCtx; _verificationTime = verificationTime; - _remainingDownloadTime = remainingDownloadTime; + _downloadTimeout = downloadTimeout; } public void Dispose() @@ -236,7 +236,7 @@ internal Interop.Crypto.X509VerifyStatusCode FindChainViaAia( X509Certificate2? downloaded = DownloadCertificate( authorityInformationAccess, - ref _remainingDownloadTime); + _downloadTimeout); // The AIA record is contained in a public structure, so no need to clear it. CryptoPool.Return(authorityInformationAccess.Array!, clearSize: 0); @@ -366,7 +366,7 @@ internal void ProcessRevocation( _store, revocationMode, _verificationTime, - ref _remainingDownloadTime); + _downloadTimeout); } } } @@ -655,7 +655,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp( return status; } - if (revocationMode != X509RevocationMode.Online || _remainingDownloadTime <= TimeSpan.Zero) + if (revocationMode != X509RevocationMode.Online) { return Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL; } @@ -690,7 +690,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp( // // So, for now, only try GET. SafeOcspResponseHandle? resp = - CertificateAssetDownloader.DownloadOcspGet(requestUrl, ref _remainingDownloadTime); + CertificateAssetDownloader.DownloadOcspGet(requestUrl, _downloadTimeout); using (resp) { @@ -1072,14 +1072,8 @@ private static X509ChainStatusFlags MapVerifyErrorToChainStatus(Interop.Crypto.X private static X509Certificate2? DownloadCertificate( ReadOnlyMemory authorityInformationAccess, - ref TimeSpan remainingDownloadTime) + TimeSpan downloadTimeout) { - // Don't do any work if we're over limit. - if (remainingDownloadTime <= TimeSpan.Zero) - { - return null; - } - string? uri = FindHttpAiaRecord(authorityInformationAccess, Oids.CertificateAuthorityIssuers); if (uri == null) @@ -1087,7 +1081,7 @@ private static X509ChainStatusFlags MapVerifyErrorToChainStatus(Interop.Crypto.X return null; } - return CertificateAssetDownloader.DownloadCertificate(uri, ref remainingDownloadTime); + return CertificateAssetDownloader.DownloadCertificate(uri, downloadTimeout); } private static string? GetOcspEndpoint(SafeX509Handle cert) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/TimeoutTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/TimeoutTests.cs new file mode 100644 index 000000000000..57deca86d979 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/TimeoutTests.cs @@ -0,0 +1,300 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Security.Cryptography.X509Certificates.Tests.Common; +using System.Linq; +using Xunit; + +namespace System.Security.Cryptography.X509Certificates.Tests.RevocationTests +{ + [OuterLoop("These tests exercise timeout properties which take a lot of time.")] + public static class TimeoutTests + { + [Theory] + [InlineData(PkiOptions.OcspEverywhere)] + [InlineData(PkiOptions.CrlEverywhere)] + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)] + public static void RevocationCheckingDelayed(PkiOptions pkiOptions) + { + CertificateAuthority.BuildPrivatePki( + pkiOptions, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(RevocationCheckingDelayed)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + TimeSpan delay = TimeSpan.FromSeconds(3); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + // This needs to be greater than delay, but less than 2x delay to ensure + // that the time is a timeout for individual fetches, not a running total. + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(5); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.ExtraStore.Add(intermediateCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; + + chain.ChainPolicy.DisableCertificateDownloads = true; + + Stopwatch watch = Stopwatch.StartNew(); + Assert.True(chain.Build(endEntityCert)); + watch.Stop(); + + // There should be two network fetches, OCSP/CRL to intermediate to get leaf status, + // OCSP/CRL to root to get intermediate statuses. It should take at least 2x the delay + // plus other non-network time, so we can at least ensure it took as long as + // the delay for each fetch. + Assert.True(watch.Elapsed >= delay * 2); + } + } + + [Theory] + [InlineData(PkiOptions.OcspEverywhere)] + [InlineData(PkiOptions.CrlEverywhere)] + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)] + public static void RevocationCheckingTimeout(PkiOptions pkiOptions) + { + CertificateAuthority.BuildPrivatePki( + pkiOptions, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(RevocationCheckingTimeout)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + TimeSpan delay = TimeSpan.FromSeconds(3); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(1); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.ExtraStore.Add(intermediateCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; + + chain.ChainPolicy.DisableCertificateDownloads = true; + + Assert.False(chain.Build(endEntityCert)); + + const X509ChainStatusFlags ExpectedFlags = + X509ChainStatusFlags.RevocationStatusUnknown | + X509ChainStatusFlags.OfflineRevocation; + + X509ChainStatusFlags eeFlags = GetFlags(chain, endEntityCert.Thumbprint); + X509ChainStatusFlags intermediateFlags = GetFlags(chain, intermediateCert.Thumbprint); + Assert.Equal(ExpectedFlags, eeFlags); + Assert.Equal(ExpectedFlags, intermediateFlags); + } + } + + [Theory] + [InlineData(PkiOptions.OcspEverywhere)] + [InlineData(PkiOptions.CrlEverywhere)] + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)] + public static void RevocationCheckingMaximum(PkiOptions pkiOptions) + { + // Windows 10 has a different maximum from previous versions of Windows. + // We are primarily testing that Linux behavior matches some behavior of + // Windows, so we won't test except on Windows 10. + if (PlatformDetection.WindowsVersion < 10) + { + return; + } + + CertificateAuthority.BuildPrivatePki( + pkiOptions, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(RevocationCheckingMaximum)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + TimeSpan delay = TimeSpan.FromMinutes(1.5); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromMinutes(2); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.ExtraStore.Add(intermediateCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly; + + chain.ChainPolicy.DisableCertificateDownloads = true; + + // Even though UrlRetrievalTimeout is more than the delay, it should + // get clamped to 1 minute, and thus less than the actual delay. + Assert.False(chain.Build(endEntityCert)); + + const X509ChainStatusFlags ExpectedFlags = + X509ChainStatusFlags.RevocationStatusUnknown | + X509ChainStatusFlags.OfflineRevocation; + + X509ChainStatusFlags eeFlags = GetFlags(chain, endEntityCert.Thumbprint); + Assert.Equal(ExpectedFlags, eeFlags); + } + } + + [Theory] + [InlineData(PkiOptions.OcspEverywhere)] + [InlineData(PkiOptions.CrlEverywhere)] + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)] + public static void RevocationCheckingNegativeTimeout(PkiOptions pkiOptions) + { + CertificateAuthority.BuildPrivatePki( + pkiOptions, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(RevocationCheckingNegativeTimeout)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + // Delay is more than the 15 second default. + TimeSpan delay = TimeSpan.FromSeconds(25); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromMinutes(-1); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.ExtraStore.Add(intermediateCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly; + + chain.ChainPolicy.DisableCertificateDownloads = true; + + Assert.True(chain.Build(endEntityCert)); + } + } + + [Fact] + [PlatformSpecific(TestPlatforms.Linux)] + public static void AiaFetchDelayed() + { + CertificateAuthority.BuildPrivatePki( + PkiOptions.OcspEverywhere, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(AiaFetchDelayed)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + TimeSpan delay = TimeSpan.FromSeconds(1); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(5); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + Stopwatch watch = Stopwatch.StartNew(); + Assert.True(chain.Build(endEntityCert), GetFlags(chain, endEntityCert.Thumbprint).ToString()); + watch.Stop(); + + Assert.True(watch.Elapsed >= delay); + } + } + + [Fact] + [PlatformSpecific(TestPlatforms.Linux)] + public static void AiaFetchTimeout() + { + CertificateAuthority.BuildPrivatePki( + PkiOptions.AllRevocation, + out RevocationResponder responder, + out CertificateAuthority rootAuthority, + out CertificateAuthority intermediateAuthority, + out X509Certificate2 endEntityCert, + nameof(AiaFetchTimeout)); + + using (responder) + using (rootAuthority) + using (intermediateAuthority) + using (endEntityCert) + using (ChainHolder holder = new ChainHolder()) + using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert()) + using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert()) + { + TimeSpan delay = TimeSpan.FromSeconds(3); + + X509Chain chain = holder.Chain; + responder.ResponseDelay = delay; + responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All; + + chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(2); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + Assert.False(chain.Build(endEntityCert)); + + const X509ChainStatusFlags ExpectedFlags = + X509ChainStatusFlags.PartialChain; + + X509ChainStatusFlags eeFlags = GetFlags(chain, endEntityCert.Thumbprint); + Assert.Equal(ExpectedFlags, eeFlags); + } + } + + private static X509ChainStatusFlags GetFlags(X509Chain chain, string thumbprint) => + chain.ChainElements.OfType(). + Single(e => e.Certificate.Thumbprint == thumbprint). + ChainElementStatus.Aggregate((X509ChainStatusFlags)0, (a, e) => a | e.Status); + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj index c666f2f3e54c..7d818904df24 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj @@ -58,6 +58,7 @@ + From edebfbd48a915b4cf32cd66639a1c83400b19a6e Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Thu, 13 Aug 2020 10:35:00 -0700 Subject: [PATCH 459/755] Improve perf of hash one-shots on Win10 --- .../Internal/Cryptography/HashProviderCng.cs | 13 +-- .../Windows/BCrypt/BCryptAlgorithmCache.cs | 36 +++++- .../Windows/BCrypt/Interop.BCryptHash.cs | 15 ++- .../HashProviderDispenser.Windows.cs | 105 ++++++++++++------ 4 files changed, 117 insertions(+), 52 deletions(-) diff --git a/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs b/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs index 8df69d9439d1..36f42e1ee99e 100644 --- a/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs +++ b/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs @@ -34,7 +34,7 @@ internal HashProviderCng(string hashAlgId, ReadOnlySpan key, bool isHmac) dwFlags |= BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG; } - _hAlgorithm = Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgId, dwFlags); + _hAlgorithm = Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgId, dwFlags, out _hashSize); // Win7 won't set hHash, Win8+ will; and both will set _hHash. // So keep hHash trapped in this scope to prevent (mis-)use of it. @@ -57,17 +57,6 @@ internal HashProviderCng(string hashAlgId, ReadOnlySpan key, bool isHmac) _reusable = true; } } - - unsafe - { - int cbSizeOfHashSize; - int hashSize; - Debug.Assert(_hHash != null); - NTSTATUS ntStatus = Interop.BCrypt.BCryptGetProperty(_hHash, Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH, &hashSize, sizeof(int), out cbSizeOfHashSize, 0); - if (ntStatus != NTSTATUS.STATUS_SUCCESS) - throw Interop.BCrypt.CreateCryptographicException(ntStatus); - _hashSize = hashSize; - } } public sealed override unsafe void AppendHashData(ReadOnlySpan source) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs index d7524e23f8f0..e495659bd0f9 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs @@ -17,7 +17,7 @@ internal static class BCryptAlgorithmCache /// /// Return a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it! /// - public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags) + public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, out int hashSizeInBytes) { // There aren't that many hash algorithms around so rather than use a LowLevelDictionary and guard it with a lock, // we'll use a simple list. To avoid locking, we'll recreate the entire list each time an entry is added and replace it atomically. @@ -29,7 +29,10 @@ public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string ha foreach (Entry entry in cache) { if (entry.HashAlgorithmId == hashAlgorithmId && entry.Flags == flags) + { + hashSizeInBytes = entry.HashSizeInBytes; return entry.Handle; + } } SafeBCryptAlgorithmHandle safeBCryptAlgorithmHandle; @@ -37,14 +40,15 @@ public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string ha if (ntStatus != NTSTATUS.STATUS_SUCCESS) throw Interop.BCrypt.CreateCryptographicException(ntStatus); - Entry[] newCache = new Entry[cache.Length + 1]; + Array.Resize(ref cache, cache.Length + 1); Entry newEntry = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle); - Array.Copy(cache, newCache, cache.Length); - newCache[newCache.Length - 1] = newEntry; + cache[^1] = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle); // Atomically overwrite the cache with our new cache. It's possible some other thread raced to add a new entry with us - if so, one of the new entries // will be lost and the next request will have to allocate it again. That's considered acceptable collateral damage. - _cache = newCache; + _cache = cache; + + hashSizeInBytes = newEntry.HashSizeInBytes; return newEntry.Handle; } @@ -52,17 +56,37 @@ public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string ha private struct Entry { - public Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, SafeBCryptAlgorithmHandle handle) + public unsafe Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, SafeBCryptAlgorithmHandle handle) : this() { HashAlgorithmId = hashAlgorithmId; Flags = flags; Handle = handle; + + int hashSize; + NTSTATUS ntStatus = Interop.BCrypt.BCryptGetProperty( + handle, + Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH, + &hashSize, + sizeof(int), + out int cbHashSize, + 0); + + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + throw Interop.BCrypt.CreateCryptographicException(ntStatus); + } + + Debug.Assert(cbHashSize == sizeof(int)); + Debug.Assert(hashSize > 0); + + HashSizeInBytes = hashSize; } public string HashAlgorithmId { get; private set; } public BCryptOpenAlgorithmProviderFlags Flags { get; private set; } public SafeBCryptAlgorithmHandle Handle { get; private set; } + public int HashSizeInBytes { get; private set; } } } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptHash.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptHash.cs index f7384436f694..9de166a66fb3 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptHash.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptHash.cs @@ -4,13 +4,22 @@ using System; using System.Runtime.InteropServices; -using Microsoft.Win32.SafeHandles; - internal partial class Interop { internal partial class BCrypt { [DllImport(Libraries.BCrypt, CharSet = CharSet.Unicode)] - internal static unsafe extern NTSTATUS BCryptHash(SafeBCryptAlgorithmHandle hAlgorithm, byte* pbSecret, int cbSecret, byte* pbInput, int cbInput, byte* pbOutput, int cbOutput); + internal static unsafe extern NTSTATUS BCryptHash(nuint hAlgorithm, byte* pbSecret, int cbSecret, byte* pbInput, int cbInput, byte* pbOutput, int cbOutput); + + // Pseudo-handles, as defined in bcrypt.h + // TODO: This really should be backed by 'nuint' (see https://github.com/dotnet/roslyn/issues/44651) + public enum BCryptAlgPseudoHandle : uint + { + BCRYPT_MD5_ALG_HANDLE = 0x00000021, + BCRYPT_SHA1_ALG_HANDLE = 0x00000031, + BCRYPT_SHA256_ALG_HANDLE = 0x00000041, + BCRYPT_SHA384_ALG_HANDLE = 0x00000051, + BCRYPT_SHA512_ALG_HANDLE = 0x00000061, + } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Windows.cs index 8592dd145476..d7b710be50cc 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Windows.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Runtime.InteropServices; using System.Security.Cryptography; using Microsoft.Win32.SafeHandles; using NTSTATUS = Interop.BCrypt.NTSTATUS; @@ -33,58 +34,100 @@ public static class OneShotHashProvider public static unsafe int HashData(string hashAlgorithmId, ReadOnlySpan source, Span destination) { - // Shared handle, no using or dispose. + int hashSize; // in bytes + + // Try using a pseudo-handle if available. + if (!s_useCompatOneShot) + { + if (HashDataUsingPseudoHandle(hashAlgorithmId, source, destination, out hashSize)) + { + return hashSize; + } + } + + // Pseudo-handle not available or a precondition check failed. + // Fall back to a shared handle with no using or dispose. SafeBCryptAlgorithmHandle cachedAlgorithmHandle = BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle( hashAlgorithmId, - BCryptOpenAlgorithmProviderFlags.None); + BCryptOpenAlgorithmProviderFlags.None, + out hashSize); + + if (destination.Length < hashSize) + { + throw new CryptographicException(); + } - int hashSize; + HashUpdateAndFinish(cachedAlgorithmHandle, hashSize, source, destination); - NTSTATUS ntStatus = Interop.BCrypt.BCryptGetProperty( - cachedAlgorithmHandle, - Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH, - &hashSize, - sizeof(int), - out _, - 0); + return hashSize; + } - if (ntStatus != NTSTATUS.STATUS_SUCCESS) + private static unsafe bool HashDataUsingPseudoHandle(string hashAlgorithmId, ReadOnlySpan source, Span destination, out int hashSize) + { + hashSize = default; + + Interop.BCrypt.BCryptAlgPseudoHandle algHandle; + int digestSizeInBytes; + + if (hashAlgorithmId == HashAlgorithmNames.MD5) { - throw Interop.BCrypt.CreateCryptographicException(ntStatus); + algHandle = Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_MD5_ALG_HANDLE; + digestSizeInBytes = 128 / 8; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA1) + { + algHandle = Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA1_ALG_HANDLE; + digestSizeInBytes = 160 / 8; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA256) + { + algHandle = Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA256_ALG_HANDLE; + digestSizeInBytes = 256 / 8; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA384) + { + algHandle = Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA384_ALG_HANDLE; + digestSizeInBytes = 384 / 8; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA512) + { + algHandle = Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA512_ALG_HANDLE; + digestSizeInBytes = 512 / 8; + } + else + { + Debug.Fail("Unknown hash algorithm."); + return false; } - if (destination.Length < hashSize) + if (destination.Length < digestSizeInBytes) { - throw new CryptographicException(); + Debug.Fail("Caller should have checked length."); + return false; } - if (!s_useCompatOneShot) + NTSTATUS ntStatus; + fixed (byte* pSrc = &MemoryMarshal.GetReference(source)) + fixed (byte* pDest = &MemoryMarshal.GetReference(destination)) { try { - fixed (byte* pSource = source) - fixed (byte* pDestination = destination) - { - ntStatus = Interop.BCrypt.BCryptHash(cachedAlgorithmHandle, null, 0, pSource, source.Length, pDestination, hashSize); - - if (ntStatus != NTSTATUS.STATUS_SUCCESS) - { - throw Interop.BCrypt.CreateCryptographicException(ntStatus); - } - } - - return hashSize; + ntStatus = Interop.BCrypt.BCryptHash((uint)algHandle, pbSecret: null, cbSecret: 0, pSrc, source.Length, pDest, digestSizeInBytes); } catch (EntryPointNotFoundException) { - s_useCompatOneShot = true; + s_useCompatOneShot = true; // this OS doesn't support BCryptHash with pseudohandles + return false; } } - Debug.Assert(s_useCompatOneShot); - HashUpdateAndFinish(cachedAlgorithmHandle, hashSize, source, destination); + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + throw Interop.BCrypt.CreateCryptographicException(ntStatus); + } - return hashSize; + hashSize = digestSizeInBytes; + return true; // success! } private static void HashUpdateAndFinish( From 258dac81c64308a3f9d396389771a81b96576847 Mon Sep 17 00:00:00 2001 From: symphony Date: Fri, 14 Aug 2020 01:36:58 +0800 Subject: [PATCH 460/755] Misspelling for "sitations" (#40749) * Path change for ryujit-overview.md * Update src/coreclr/src/jit/compiler.cpp * Misspelling for "situations" * Misspelling for "situations" Co-authored-by: Jan Kotas --- src/coreclr/src/jit/inline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/inline.h b/src/coreclr/src/jit/inline.h index 1019341de999..c8b58802d0ee 100644 --- a/src/coreclr/src/jit/inline.h +++ b/src/coreclr/src/jit/inline.h @@ -27,7 +27,7 @@ // // Enums are used throughout to provide various descriptions. // -// There are 4 sitations where inline candidacy is evaluated. In each +// There are 4 situations where inline candidacy is evaluated. In each // case an InlineResult is allocated on the stack to collect // information about the inline candidate. Each InlineResult refers // to an InlinePolicy. From 6fb6750c5615279a3773f40ee2360abdcbb988d5 Mon Sep 17 00:00:00 2001 From: Karel Zikmund Date: Thu, 13 Aug 2020 19:51:45 +0200 Subject: [PATCH 461/755] Add link to @msftbot configuration for admins (#40789) Add link to configuration of msftbot notifications for easier access for admins. --- 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 210243387b0c..4e24d8326413 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -4,7 +4,7 @@ If you need to tag folks on an issue or PR, you will generally want to tag the o ## Areas -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`, `@marek-safar`, `@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. +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`, `@marek-safar`, `@ericstj`, or `@karelz`, they have permissions to update [`msftbot` configuration](https://fabric-cp.azurewebsites.net/bot/?repo=dotnet/runtime). 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 8b036be4c3856de3539dbee79059de8e7abc0633 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 13 Aug 2020 11:47:05 -0700 Subject: [PATCH 462/755] JS api for creating GC roots to store temporary object references in (#40645) Our current JS is not GC safe and as a result if a GC happens at the wrong time, objects being used by JS can get collected. This PR is a partial solution for the issue that introduces an API for allocating root buffers where you can store GC object references while JS code is manipulating them. Two convenience APIs are layered on top for creating single temporary roots. The PR updates some of the existing bindings APIs to make use of temporary roots when manipulating managed objects. --- src/mono/wasm/runtime/binding_support.js | 106 +++++++++----- src/mono/wasm/runtime/driver.c | 22 +++ src/mono/wasm/runtime/library_mono.js | 171 +++++++++++++++++++++++ 3 files changed, 267 insertions(+), 32 deletions(-) diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index b9a1dae6ec1c..5131c7f678dc 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -143,16 +143,22 @@ var BindingSupportLib = { mono_array_to_js_array: function (mono_array) { if (mono_array == 0) return null; + + let [arrayRoot, elemRoot] = MONO.mono_wasm_new_roots ([mono_array, 0]); - var res = []; - var len = this.mono_array_length (mono_array); - for (var i = 0; i < len; ++i) - { - var ele = this.mono_array_get (mono_array, i); - if (this.is_nested_array(ele)) - res.push(this.mono_array_to_js_array(ele)); - else - res.push (this.unbox_mono_obj (ele)); + try { + var res = []; + var len = this.mono_array_length (arrayRoot.value); + for (var i = 0; i < len; ++i) + { + elemRoot.value = this.mono_array_get (arrayRoot.value, i); + if (this.is_nested_array (elemRoot.value)) + res.push (this.mono_array_to_js_array (elemRoot.value)); + else + res.push (this._unbox_mono_obj_rooted (elemRoot)); + } + } finally { + MONO.mono_wasm_release_roots (arrayRoot, elemRoot); } return res; @@ -160,15 +166,37 @@ var BindingSupportLib = { js_array_to_mono_array: function (js_array) { var mono_array = this.mono_obj_array_new (js_array.length); - for (var i = 0; i < js_array.length; ++i) { - this.mono_obj_array_set (mono_array, i, this.js_to_mono_obj (js_array [i])); + let [arrayRoot, elemRoot] = MONO.mono_wasm_new_roots ([mono_array, 0]); + + try { + for (var i = 0; i < js_array.length; ++i) { + elemRoot.value = this.js_to_mono_obj (js_array [i]); + this.mono_obj_array_set (arrayRoot.value, i, elemRoot.value); + } + + return mono_array; + } finally { + MONO.mono_wasm_release_roots (arrayRoot, elemRoot); } - return mono_array; }, unbox_mono_obj: function (mono_obj) { - if (mono_obj == 0) + if (mono_obj === 0) return undefined; + + var root = MONO.mono_wasm_new_root (mono_obj); + try { + return this._unbox_mono_obj_rooted (root); + } finally { + root.release(); + } + }, + + _unbox_mono_obj_rooted: function (root) { + var mono_obj = root.value; + if (mono_obj === 0) + return undefined; + var type = this.mono_get_obj_type (mono_obj); //See MARSHAL_TYPE_ defines in driver.c switch (type) { @@ -183,6 +211,7 @@ var BindingSupportLib = { case 5: { // delegate var obj = this.extract_js_obj (mono_obj); obj.__mono_delegate_alive__ = true; + // FIXME: Should we root the object as long as this function has not been GCd? return function () { return BINDING.invoke_delegate (obj, arguments); }; @@ -250,6 +279,7 @@ var BindingSupportLib = { case 23: // clr .NET SafeHandle var addRef = true; var js_handle = this.call_method(this.safehandle_get_handle, null, "mii", [ mono_obj, addRef ]); + // FIXME: Is this a GC object that needs to be rooted? var requiredObject = BINDING.mono_wasm_require_handle (js_handle); if (addRef) { @@ -260,7 +290,7 @@ var BindingSupportLib = { } return requiredObject; default: - throw new Error ("no idea on how to unbox object kind " + type); + throw new Error ("no idea on how to unbox object kind " + type + " at offset " + mono_obj); } }, @@ -322,6 +352,7 @@ var BindingSupportLib = { var the_task = this.try_extract_mono_obj (js_obj); if (the_task) return the_task; + // FIXME: We need to root tcs for an appropriate timespan var tcs = this.create_task_completion_source (); js_obj.then (function (result) { BINDING.set_task_result (tcs, result); @@ -349,6 +380,8 @@ var BindingSupportLib = { return this.extract_mono_obj (js_obj); } }, + + // FIXME: Audit all callers, this method returns an unrooted object js_typed_array_to_array : function (js_obj) { // JavaScript typed arrays are array-like objects and provide a mechanism for accessing @@ -503,12 +536,17 @@ var BindingSupportLib = { if (js_obj === null || typeof js_obj === "undefined") return 0; - - var monoObj = this.js_to_mono_obj(js_obj); - // Check enum contract - var monoEnum = this.call_method(this.object_to_enum, null, "iimm", [ method, parmIdx, monoObj ]) - // return the unboxed enum value. - return this.mono_unbox_enum(monoEnum); + + var monoObj, monoEnum; + try { + monoObj = MONO.mono_wasm_new_root (this.js_to_mono_obj (js_obj)); + // Check enum contract + monoEnum = MONO.mono_wasm_new_root (this.call_method (this.object_to_enum, null, "iimm", [ method, parmIdx, monoObj.value ])) + // return the unboxed enum value. + return this.mono_unbox_enum (monoEnum.value); + } finally { + MONO.mono_wasm_release_roots (monoObj, monoEnum); + } }, wasm_binding_obj_new: function (js_obj_id, ownsHandle, type) { @@ -695,22 +733,26 @@ var BindingSupportLib = { Module.setValue (exception_out, 0, "*"); - var res = this.invoke_method (method, this_arg, args_start, exception_out); - var eh_res = Module.getValue (exception_out, "*"); + var res = MONO.mono_wasm_new_root (this.invoke_method (method, this_arg, args_start, exception_out)); + try { + var eh_res = Module.getValue (exception_out, "*"); - Module._free (buffer); + Module._free (buffer); - if (eh_res != 0) { - var msg = this.conv_string (res); - throw new Error (msg); //the convention is that invoke_method ToString () any outgoing exception - } + if (eh_res != 0) { + var msg = this.conv_string (res.value); + throw new Error (msg); //the convention is that invoke_method ToString () any outgoing exception + } - if (has_args_marshal && has_args) { - if (args_marshal.length >= args.length && args_marshal [args.length] === "m") - return res; - } + if (has_args_marshal && has_args) { + if (args_marshal.length >= args.length && args_marshal [args.length] === "m") + return res.value; + } - return this.unbox_mono_obj (res); + return this._unbox_mono_obj_rooted (res); + } finally { + res.release (); + } }, invoke_delegate: function (delegate_obj, js_args) { diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 2d4498c8955a..264a5b9d7eb6 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -12,6 +12,9 @@ #include #include #include +#include +// FIXME: unavailable in emscripten +// #include #include #include #include @@ -31,6 +34,9 @@ extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, Mo void mono_wasm_enable_debugging (int); +int mono_wasm_register_root (char *start, size_t size, const char *name); +void mono_wasm_deregister_root (char *addr); + void mono_ee_interp_init (const char *opts); void mono_marshal_ilgen_init (void); void mono_method_builder_ilgen_init (void); @@ -139,6 +145,22 @@ wasm_logger (const char *log_domain, const char *log_level, const char *message, }, log_level, message, fatal, log_domain); } +typedef uint32_t target_mword; +typedef target_mword SgenDescriptor; +typedef SgenDescriptor MonoGCDescriptor; +MONO_API int mono_gc_register_root (char *start, size_t size, MonoGCDescriptor descr, MonoGCRootSource source, void *key, const char *msg); +void mono_gc_deregister_root (char* addr); + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_register_root (char *start, size_t size, const char *name) { + return mono_gc_register_root (start, size, NULL, MONO_ROOT_SOURCE_EXTERNAL, NULL, name ? name : "mono_wasm_register_root"); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_deregister_root (char *addr) { + mono_gc_deregister_root (addr); +} + #ifdef DRIVER_GEN #include "driver-gen.c" #endif diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index ad0c854f570b..d046a77c92dd 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -43,6 +43,177 @@ var MonoSupportLib = { module ["mono_wasm_load_icu_data"] = MONO.mono_wasm_load_icu_data; module ["mono_wasm_globalization_init"] = MONO.mono_wasm_globalization_init; module ["mono_wasm_get_loaded_files"] = MONO.mono_wasm_get_loaded_files; + module ["mono_wasm_new_root_buffer"] = MONO.mono_wasm_new_root_buffer; + module ["mono_wasm_new_root"] = MONO.mono_wasm_new_root; + module ["mono_wasm_new_roots"] = MONO.mono_wasm_new_roots; + module ["mono_wasm_release_roots"] = MONO.mono_wasm_release_roots; + }, + + _mono_wasm_root_buffer_prototype: { + get: function (index) { + return Module.HEAP32[this.__offset32 + index]; + }, + set: function (index, value) { + var absoluteOffset = this.__offset32 + index; + Module.HEAP32[absoluteOffset] = value; + return value; + }, + release: function () { + if (this.__offset) { + MONO.mono_wasm_deregister_root (this.__offset); + MONO._fill_region (this.__offset, this.__count * 4, 0); + Module.free (this.__offset); + } + + this.__handle = this.__offset = this.__count = this.__offset32 = undefined; + }, + }, + + _scratch_root_buffer: null, + _scratch_root_free_indices: null, + + _mono_wasm_root_prototype: { + get: function () { + var result = this.__buffer.get (this.__index); + return result; + }, + set: function (value) { + this.__buffer.set (this.__index, value); + return value; + }, + valueOf: function () { + return this.get (); + }, + release: function () { + MONO._mono_wasm_release_scratch_index (this.__index); + this.__buffer = undefined; + this.__index = undefined; + } + }, + + _mono_wasm_release_scratch_index: function (index) { + if (index === undefined) + return; + + this._scratch_root_buffer.set (index, 0); + this._scratch_root_free_indices.push (index); + }, + + _mono_wasm_claim_scratch_index: function () { + if (!this._scratch_root_buffer) { + const maxScratchRoots = 8192; + this._scratch_root_buffer = this.mono_wasm_new_root_buffer (maxScratchRoots, "js roots"); + + this._scratch_root_free_indices = new Array (maxScratchRoots); + for (var i = 0; i < maxScratchRoots; i++) + this._scratch_root_free_indices[i] = i; + this._scratch_root_free_indices.reverse (); + + Object.defineProperty (MONO._mono_wasm_root_prototype, "value", { + get: MONO._mono_wasm_root_prototype.get, + set: MONO._mono_wasm_root_prototype.set, + configurable: false + }); + } + + if (this._scratch_root_free_indices.length < 1) + throw new Error ("Out of scratch root space"); + + var result = this._scratch_root_free_indices.pop (); + return result; + }, + + _zero_region: function (byteOffset, sizeBytes, value) { + (new Uint8Array (Module.HEAPU8.buffer, byteOffset, sizeBytes)).fill (0); + }, + + // Allocates a block of memory that can safely contain pointers into the managed heap. + // The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers. + // Once you are done using the root buffer, you must call its release() method. + // For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead. + mono_wasm_new_root_buffer: function (capacity, msg) { + if (!MONO.mono_wasm_register_root || !MONO.mono_wasm_deregister_root) { + MONO.mono_wasm_register_root = Module.cwrap ("mono_wasm_register_root", "number", ["number", "number", "string"]); + MONO.mono_wasm_deregister_root = Module.cwrap ("mono_wasm_deregister_root", null, ["number"]); + } + + if (capacity <= 0) + throw new Error ("capacity >= 1"); + + var capacityBytes = capacity * 4; + var offset = Module._malloc (capacityBytes); + if ((offset % 4) !== 0) + throw new Error ("Malloc returned an unaligned offset"); + + this._zero_region (offset, capacityBytes, 0); + + var result = Object.create (MONO._mono_wasm_root_buffer_prototype); + result.__offset = offset; + result.__offset32 = offset / 4; + result.__count = capacity; + result.__handle = MONO.mono_wasm_register_root (offset, capacityBytes, msg || 0); + + return result; + }, + + // Allocates temporary storage for a pointer into the managed heap. + // Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected. + // If you already have a managed pointer you can pass it as an argument to initialize the temporary storage. + // The result object has get() and set(value) methods, along with a .value property. + // When you are done using the root you must call its .release() method. + mono_wasm_new_root: function (value) { + var index = this._mono_wasm_claim_scratch_index (); + var buffer = this._scratch_root_buffer; + + var result = Object.create (MONO._mono_wasm_root_prototype); + result.__buffer = buffer; + result.__index = index; + + if (value !== undefined) { + if (typeof (value) !== "number") + throw new Error ("value must be an address in the managed heap"); + + result.set (value); + } else { + result.set (0); + } + + return result; + }, + + // Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers. + // mono_wasm_new_roots(n): returns an array of N zero-initialized roots. + // mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element. + // Each root must be released with its release method, or using the mono_wasm_release_roots API. + mono_wasm_new_roots: function (count_or_values) { + var result; + + if (Array.isArray (count_or_values)) { + result = new Array (count_or_values.length); + for (var i = 0; i < result.length; i++) + result[i] = this.mono_wasm_new_root (count_or_values[i]); + } else if ((count_or_values | 0) > 0) { + result = new Array (count_or_values); + for (var i = 0; i < result.length; i++) + result[i] = this.mono_wasm_new_root (); + } else { + throw new Error ("count_or_values must be either an array or a number greater than 0"); + } + + return result; + }, + + // Releases 1 or more root or root buffer objects. + // Multiple objects may be passed on the argument list. + // 'undefined' may be passed as an argument so it is safe to call this method from finally blocks + // even if you are not sure all of your roots have been created yet. + mono_wasm_release_roots: function () { + for (var i = 0; i < arguments.length; i++) { + if (!arguments[i]) + continue; + + arguments[i].release (); + } }, mono_text_decoder: undefined, From a72389ed7ed0a5786db0651f90c68872f8e0579a Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Thu, 13 Aug 2020 12:00:23 -0700 Subject: [PATCH 463/755] do not include libnethost.lib in shared folder (#40754) * do not include libnethost.lib in shared folder * Do not include nethost.lib either * PR feedback --- .../netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj b/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj index f1aab81eb8a4..e2905a88d370 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj +++ b/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj @@ -56,14 +56,15 @@ - - + + + From b21f0e5cfe925d18df6eac3d45f3bdd4553a5a67 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 13 Aug 2020 12:30:03 -0700 Subject: [PATCH 464/755] Set default timeout to 120 for OSX build pools (#40783) --- eng/pipelines/common/global-build-job.yml | 8 +------- eng/pipelines/common/xplat-setup.yml | 3 +++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 3f22f762be8c..221f8d366262 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -26,16 +26,10 @@ jobs: pool: ${{ parameters.pool }} container: ${{ parameters.container }} condition: and(succeeded(), ${{ parameters.condition }}) + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} workspace: clean: all - # macOS hosted pool machines are slower so we need to give a greater timeout for global-build - # which builds multiple subsets. - ${{ if and(contains(parameters.pool.vmImage, 'macOS'), eq(parameters.timeoutInMinutes, '')) }}: - timeoutInMinutes: 120 - ${{ if or(not(contains(parameters.pool.vmImage, 'macOS')), ne(parameters.timeoutInMinutes, '')) }}: - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - variables: - name: _osParameter value: -os ${{ parameters.osGroup }} diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index f6a5ee11f4ec..9c025864515f 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -136,6 +136,9 @@ jobs: ${{ if eq(parameters.helixQueuesTemplate, '') }}: + # macOS hosted pool machines are slower so we need to give a greater timeout than the 60 mins default. + ${{ if and(eq(parameters.jobParameters.timeoutInMinutes, ''), in(parameters.osGroup, 'OSX', 'iOS', 'tvOS')) }}: + timeoutInMinutes: 120 ${{ insert }}: ${{ parameters.jobParameters }} ${{ if ne(parameters.helixQueuesTemplate, '') }}: jobTemplate: ${{ parameters.jobTemplate }} From 80962c8fc3149234646a536cbfb34e3cd39d496f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Thu, 13 Aug 2020 22:16:51 +0200 Subject: [PATCH 465/755] Fix initialization of DelayMethodCallThunksSection (#40734) This is a per-native-image, not a per-component section, therefore we must fetch it from the composite header. As JanV discovered, this was the cause of the biggest runtime failure bucket in composite CG2 runs in GC stress mode. Thanks Tomas --- src/coreclr/src/vm/readytoruninfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/readytoruninfo.cpp b/src/coreclr/src/vm/readytoruninfo.cpp index 72a559ab5091..781530a0b5d5 100644 --- a/src/coreclr/src/vm/readytoruninfo.cpp +++ b/src/coreclr/src/vm/readytoruninfo.cpp @@ -683,7 +683,7 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT m_methodDefEntryPoints = NativeArray(&m_nativeReader, pEntryPointsDir->VirtualAddress); } - m_pSectionDelayLoadMethodCallThunks = m_component.FindSection(ReadyToRunSectionType::DelayLoadMethodCallThunks); + m_pSectionDelayLoadMethodCallThunks = m_pComposite->FindSection(ReadyToRunSectionType::DelayLoadMethodCallThunks); IMAGE_DATA_DIRECTORY * pinstMethodsDir = m_pComposite->FindSection(ReadyToRunSectionType::InstanceMethodEntryPoints); if (pinstMethodsDir != NULL) From 6dad3b449b238db3ed0b49ee8f1d3134d6fbf549 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 13 Aug 2020 13:28:28 -0700 Subject: [PATCH 466/755] System.Diagnostics.Activity Perf Improvement Part 2 (#40544) --- .../src/System/Diagnostics/Activity.cs | 19 +++++------ .../tests/ActivityTests.cs | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index a97c22223d59..87c882023b40 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -255,9 +255,6 @@ public string? RootId /// public IEnumerable> TagObjects { -#if ALLOW_PARTIALLY_TRUSTED_CALLERS - [System.Security.SecuritySafeCriticalAttribute] -#endif get => _tags ?? s_emptyTagObjects; } @@ -1284,9 +1281,10 @@ public void Add(T value) } } + // Note: Some customers use this GetEnumerator dynamically to avoid allocations. public Enumerator GetEnumerator() => new Enumerator(_first); - IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); - IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } private class TagsLinkedList : IEnumerable> @@ -1419,9 +1417,10 @@ public void Set(KeyValuePair value) } } + // Note: Some customers use this GetEnumerator dynamically to avoid allocations. public Enumerator> GetEnumerator() => new Enumerator>(_first); - IEnumerator> IEnumerable>.GetEnumerator() => new Enumerator>(_first); - IEnumerator IEnumerable.GetEnumerator() => new Enumerator>(_first); + IEnumerator> IEnumerable>.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public IEnumerable> EnumerateStringValues() { @@ -1439,15 +1438,15 @@ public void Set(KeyValuePair value) } } + // Note: Some customers use this Enumerator dynamically to avoid allocations. private struct Enumerator : IEnumerator { - private readonly LinkedListNode? _head; private LinkedListNode? _nextNode; [AllowNull, MaybeNull] private T _currentItem; public Enumerator(LinkedListNode? head) { - _nextNode = _head = head; + _nextNode = head; _currentItem = default; } @@ -1468,7 +1467,7 @@ public bool MoveNext() return true; } - public void Reset() => _nextNode = _head; + public void Reset() => throw new NotSupportedException(); public void Dispose() { diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs index a085d3103bdb..cdd6f15f5682 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs @@ -1508,6 +1508,40 @@ public void TestInsertingFirstTag(string key, object value, bool add, int result Assert.Equal(resultCount, a.TagObjects.Count()); } + [Fact] + public void StructEnumerator_TagsLinkedList() + { + // Note: This test verifies the presence of the struct Enumerator on TagsLinkedList used by customers dynamically to avoid allocations. + + Activity a = new Activity("TestActivity"); + a.AddTag("Tag1", true); + + IEnumerable> enumerable = a.TagObjects; + + MethodInfo method = enumerable.GetType().GetMethod("GetEnumerator", BindingFlags.Instance | BindingFlags.Public); + + Assert.NotNull(method); + Assert.False(method.ReturnType.IsInterface); + Assert.True(method.ReturnType.IsValueType); + } + + [Fact] + public void StructEnumerator_GenericLinkedList() + { + // Note: This test verifies the presence of the struct Enumerator on LinkedList used by customers dynamically to avoid allocations. + + Activity a = new Activity("TestActivity"); + a.AddEvent(new ActivityEvent()); + + IEnumerable enumerable = a.Events; + + MethodInfo method = enumerable.GetType().GetMethod("GetEnumerator", BindingFlags.Instance | BindingFlags.Public); + + Assert.NotNull(method); + Assert.False(method.ReturnType.IsInterface); + Assert.True(method.ReturnType.IsValueType); + } + public void Dispose() { Activity.Current = null; From a41137ce8119964b23d94b249dfdd5bc9324718a Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 13 Aug 2020 16:06:53 -0500 Subject: [PATCH 467/755] Remove disabled test since original issue will not be fixed (#40795) --- .../tests/TypeBuilder/TypeBuilderSetParent.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderSetParent.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderSetParent.cs index 4012d45d437e..8a4e5ace9ec8 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderSetParent.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderSetParent.cs @@ -38,17 +38,6 @@ public void SetParent_TypeCreated_ThrowsInvalidOperationException() Assert.Throws(() => type.SetParent(typeof(string))); } - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/19478")] - public void SetParent_This_LoopsForever() - { - TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic); - type.SetParent(type.AsType()); - Assert.Equal(type.AsType(), type.BaseType); - - Assert.ThrowsAny(() => type.CreateTypeInfo()); - } - [Fact] public void SetParent_ThisIsInterface_ThrowsTypeLoadExceptionOnLoad() { From a5c1d4226ad66311e4c0ac2711f3da8ca3ab1b93 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 13 Aug 2020 14:09:33 -0700 Subject: [PATCH 468/755] Unconditionally expand some of the Vector128 methods on x86/x64 in zapinfo.cpp (#40688) --- src/coreclr/src/zap/zapinfo.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index ff12d9631621..90b047b80e7e 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -2176,6 +2176,30 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic && (strncmp(className, "Vector64", _countof("Vector64") - 1) != 0) && (strncmp(className, "Vector128", _countof("Vector128") - 1) != 0); + +#elif defined(TARGET_X86) || defined(TARGET_AMD64) + // The following methods should be safe to expand unconditionally, since JIT either + // 1) does not generate code for them (e.g. for Vector128.AsByte() or get_Count) or + // 2) uses instructions that belong to Sse or Sse2 (these are required baseline ISAs). + static const char* vector128MethodsSafeToExpand[] = { "As", "AsByte", "AsDouble", "AsInt16", "AsInt32", "AsInt64", "AsSByte", + "AsSingle", "AsUInt16", "AsUInt32", "AsUInt64", "Create", "CreateScalarUnsafe", "ToScalar", "get_Count", "get_Zero" }; + + if (!fIsPlatformHWIntrinsic && fIsHWIntrinsic) + { + fTreatAsRegularMethodCall = true; + + if (strncmp(className, "Vector128", _countof("Vector128") - 1) == 0) + { + for (size_t i = 0; i < _countof(vector128MethodsSafeToExpand); i++) + { + if (strcmp(methodName, vector128MethodsSafeToExpand[i]) == 0) + { + fTreatAsRegularMethodCall = false; + break; + } + } + } + } #else fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic; #endif From c6eac1f2d523ee90f536ad9ed1bcb520025401f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 13 Aug 2020 23:13:51 +0200 Subject: [PATCH 469/755] Cleanup old corefx/coreclr GitHub issue links (#40286) Replace them with the current URL after the redirect. Similar to https://github.com/dotnet/runtime/pull/2063. Co-authored-by: Steve Pfister --- docs/area-owners.md | 8 ++-- docs/coding-guidelines/coding-style.md | 2 +- .../coreclr/jit/GuardedDevirtualization.md | 4 +- .../coreclr/jit/JitOptimizerTodoAssessment.md | 22 +++++------ .../design/coreclr/jit/first-class-structs.md | 38 +++++++++---------- .../coreclr/jit/object-stack-allocation.md | 4 +- docs/design/coreclr/jit/variabletracking.md | 4 +- docs/design/features/COM-activation.md | 2 +- docs/design/features/PinnedHeap.md | 4 +- docs/design/features/arm64-intrinsics.md | 2 +- docs/design/features/hw-intrinsics.md | 6 +-- docs/design/specs/Ecma-335-Augments.md | 2 +- docs/project/glossary.md | 2 +- docs/project/profiling-api-status.md | 2 +- .../building/coreclr/freebsd-instructions.md | 6 +-- .../building/libraries/cross-building.md | 2 +- docs/workflow/ci/coreclr-ci-health.md | 2 +- eng/native/configurecompiler.cmake | 2 +- eng/packaging.targets | 6 +-- src/coreclr/crossgen-corelib.cmd | 2 +- .../src/System/ArgIterator.cs | 18 ++++----- .../System.Private.CoreLib/src/System/GC.cs | 2 +- .../src/System/MulticastDelegate.cs | 4 +- .../src/System/Reflection/CustomAttribute.cs | 2 +- .../src/classlibnative/bcltype/system.cpp | 2 +- .../src/classlibnative/float/floatdouble.cpp | 4 +- .../src/classlibnative/float/floatsingle.cpp | 2 +- src/coreclr/src/gc/CMakeLists.txt | 8 ++-- .../hosts/unixcoreruncommon/coreruncommon.cpp | 2 +- src/coreclr/src/ilasm/CMakeLists.txt | 2 +- src/coreclr/src/ilasm/main.cpp | 2 +- src/coreclr/src/jit/codegenarm64.cpp | 2 +- src/coreclr/src/jit/emit.h | 2 +- src/coreclr/src/jit/gentree.cpp | 4 +- src/coreclr/src/jit/lower.cpp | 2 +- src/coreclr/src/jit/lowerxarch.cpp | 4 +- src/coreclr/src/jit/morph.cpp | 4 +- src/coreclr/src/pal/src/include/pal/mutex.hpp | 2 +- .../src/pal/tests/palsuite/DisabledTests.txt | 2 +- .../threading/NamedMutex/test1/namedmutex.cpp | 2 +- src/coreclr/src/palrt/unicode.cpp | 2 +- .../ReadyToRun/ArgIterator.cs | 2 +- .../ReadyToRunReader.cs | 4 +- src/coreclr/src/tools/r2rdump/README.md | 8 ++-- src/coreclr/src/vm/amd64/jithelpers_fast.S | 2 +- .../src/vm/amd64/virtualcallstubcpu.hpp | 2 +- src/coreclr/src/vm/argdestination.h | 2 +- src/coreclr/src/vm/ceemain.cpp | 2 +- src/coreclr/src/vm/comwaithandle.cpp | 2 +- src/coreclr/src/vm/jitinterface.cpp | 2 +- src/coreclr/src/vm/methodtablebuilder.cpp | 2 +- src/coreclr/src/vm/stackwalk.cpp | 2 +- src/coreclr/tests/runtest.py | 4 +- src/installer/tests/TestUtils/FileUtils.cs | 2 +- .../ParameterDefaultValue.cs | 4 +- src/libraries/Directory.Build.targets | 2 +- .../src/ArrayBufferWriter.cs | 2 +- .../src/UnifiedJsonReader.Utf8JsonReader.cs | 2 +- .../VisualBasic/CompilerServices/Operators.vb | 2 +- .../src/System/IO/FileSystem.Unix.cs | 2 +- .../System.Net.Http.WinHttpHandler.pkgproj | 2 +- .../src/System/Net/Mail/SmtpConnection.cs | 2 +- .../Tracing/EventPipeMetadataGenerator.cs | 2 +- .../System.Runtime.CompilerServices.Unsafe.il | 2 +- .../System.Text.Encoding.CodePages.pkgproj | 2 +- .../pkg/System.Text.Encodings.Web.pkgproj | 2 +- .../docs/ReferenceHandling_spec.md | 2 +- .../docs/SerializerProgrammingModel.md | 2 +- .../System.Text.Json/roadmap/README.md | 2 +- .../tests/Serialization/Object.WriteTests.cs | 2 +- .../netstandard2.1/settings.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- .../netcoreapp1.0/workaroundDowngrade.targets | 2 +- ...patBaseline.netcoreapp.netfx461.ignore.txt | 16 ++++---- src/mono/mono/tests/Makefile.am | 2 +- src/mono/mono/utils/mono-threads-windows.c | 2 +- .../src/System/RuntimeTypeHandle.cs | 2 +- .../SimpleStruct/SimpleStructManaged.cs | 2 +- src/tests/JIT/Directed/RVAInit/simplearg.il | 2 +- .../Unsafe/AccessInvalidFieldOffset.cs | 2 +- .../Unsafe/ReadDoubleFromIntOffset.cs | 2 +- .../Unsafe/ReadStructAsAnotherType.cs | 2 +- .../HardwareIntrinsics/X86/Avx/Avx_r.csproj | 2 +- .../HardwareIntrinsics/X86/Avx2/Avx2_r.csproj | 2 +- .../HardwareIntrinsics/X86/Sse2/Sse2_r.csproj | 2 +- .../X86/Sse41/Sse41_r.csproj | 2 +- .../systemvbringup/structpinvoketests.cs | 24 ++++++------ .../CodeQuality/Inlining/InlineGCStruct.cs | 2 +- .../CodeQuality/Layout/SearchLoops.cs | 2 +- .../Performance/CodeQuality/Span/SpanBench.cs | 2 +- .../JitBlue/GitHub_7508/Vector3Test.cs | 2 +- src/tests/JIT/SIMD/Vector3GetHash.cs | 6 +-- .../opt/FastTailCall/StructPassingSimple.cs | 2 +- .../ObjectStackAllocationTests.cs | 2 +- src/tests/JIT/opt/Structs/structpop.cs | 2 +- src/tests/JIT/opt/Structs/structpop2.cs | 2 +- src/tests/JIT/superpmi/superpmicollect.csproj | 2 +- .../threading/waithandle/waitall/nullarray.cs | 2 +- .../coreroot_determinism.csproj | 2 +- .../determinism/crossgen2determinism.csproj | 2 +- .../eventsourcetrace/eventsourcetrace.csproj | 2 +- .../inducedgc/inducedgc.csproj | 2 +- .../jittingstarted/JittingStarted.csproj | 2 +- .../tracevalidation/rundown/rundown.csproj | 2 +- 116 files changed, 199 insertions(+), 199 deletions(-) diff --git a/docs/area-owners.md b/docs/area-owners.md index 4e24d8326413..65bbfc47fa66 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -47,9 +47,9 @@ Note: Editing this file doesn't update the mapping used by the `@msftbot` issue | area-Interop-coreclr | @jeffschwMSFT | @jeffschwMSFT @AaronRobinsonMSFT | | | area-Interop-mono | @marek-safar | @lambdageek | | | area-Meta | @ericstj | @joperezr | Issues without clear association to any specific API/contract, e.g.
  • new contract proposals
  • cross-cutting code/test pattern changes (e.g. FxCop failures)
  • project-wide docs

| -| area-Microsoft.CSharp | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#33170](https://github.com/dotnet/corefx/issues/33170)) | +| area-Microsoft.CSharp | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-Microsoft.Extensions | @ericstj | @maryamariyan | | -| area-Microsoft.VisualBasic | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#33170](https://github.com/dotnet/corefx/issues/33170)) | +| area-Microsoft.VisualBasic | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-Microsoft.Win32 | @ericstj | @maryamariyan @Anipik | Including System.Windows.Extensions | | area-PAL-coreclr | @mangod9 | @janvorli | | | area-Performance-mono | @SamMonoRT | @SamMonoRT | | @@ -77,13 +77,13 @@ Note: Editing this file doesn't update the mapping used by the `@msftbot` issue | area-System.Diagnostics.Tracing | @tommcdon | @noahfalk @tommcdon @tarekgh @Anipik | Packages:
  • System.Diagnostics.DiagnosticSource
  • System.Diagnostics.PerformanceCounter - [@Anipik](https://github.com/Anipik)
  • System.Diagnostics.Tracing
  • System.Diagnostics.TraceSource - [@Anipik](https://github.com/Anipik)

| | area-System.DirectoryServices | @tquerec | @tquerec @josephisenhour @joperezr | | | area-System.Drawing | @jeffhandley | @safern @tannergooding | | -| area-System.Dynamic.Runtime | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#33170](https://github.com/dotnet/corefx/issues/33170)) | +| area-System.Dynamic.Runtime | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-System.Globalization | @ericstj | @safern @tarekgh @krwq | | | area-System.IO | @jeffhandley | @carlossanlop @jozkee | | | area-System.IO.Compression | @jeffhandley | @carlossanlop @ericstj |
  • Also includes System.IO.Packaging
| | area-System.IO.Pipelines | @kevinpi | @davidfowl @halter73 @jkotalik | | | area-System.Linq | @jeffhandley | @eiriktsarpalis @adamsitnik | | -| area-System.Linq.Expressions | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#33170](https://github.com/dotnet/corefx/issues/33170)) | +| area-System.Linq.Expressions | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-System.Linq.Parallel | @ericstj | @tarekgh @kouvel | | | area-System.Management | @ericstj | @Anipik | WMI | | area-System.Memory | @jeffhandley | @GrabYourPitchforks @adamsitnik | | diff --git a/docs/coding-guidelines/coding-style.md b/docs/coding-guidelines/coding-style.md index 6686ac7702df..1a0936bb56f5 100644 --- a/docs/coding-guidelines/coding-style.md +++ b/docs/coding-guidelines/coding-style.md @@ -24,7 +24,7 @@ The general rule we follow is "use Visual Studio defaults". 9. If a file happens to differ in style from these guidelines (e.g. private members are named `m_member` rather than `_member`), the existing style in that file takes precedence. 10. We only use `var` when it's obvious what the variable type is (e.g. `var stream = new FileStream(...)` not `var stream = OpenStandardInput()`). -11. We use language keywords instead of BCL types (e.g. `int, string, float` instead of `Int32, String, Single`, etc) for both type references as well as method calls (e.g. `int.Parse` instead of `Int32.Parse`). See issue [391](https://github.com/dotnet/corefx/issues/391) for examples. +11. We use language keywords instead of BCL types (e.g. `int, string, float` instead of `Int32, String, Single`, etc) for both type references as well as method calls (e.g. `int.Parse` instead of `Int32.Parse`). See issue [#13976](https://github.com/dotnet/runtime/issues/13976) for examples. 12. We use PascalCasing to name all our constant local variables and fields. The only exception is for interop code where the constant value should exactly match the name and value of the code you are calling via interop. 13. We use ```nameof(...)``` instead of ```"..."``` whenever possible and relevant. 14. Fields should be specified at the top within type declarations. diff --git a/docs/design/coreclr/jit/GuardedDevirtualization.md b/docs/design/coreclr/jit/GuardedDevirtualization.md index 95b3caa65364..84eeaa085f72 100644 --- a/docs/design/coreclr/jit/GuardedDevirtualization.md +++ b/docs/design/coreclr/jit/GuardedDevirtualization.md @@ -28,7 +28,7 @@ happens quite early (during importation) and there is only minimal ability to do data flow analysis at this stage. So for current devirtualization the source of the type information and the consumption must be fairly close in the code. A more detailed accounting of some of the shortcomings can be found in -[CoreCLR#9908](https://github.com/dotnet/coreclr/issues/9908). +[#7541](https://github.com/dotnet/runtime/issues/7541). Resolution of these issues will improve the ability of the JIT to devirtualize, but even the best analysis possible will still miss out on many cases. Some call @@ -277,7 +277,7 @@ setup, may be able to optimize away the null check, and opens the door for inlining. So it should be slightly cheaper on average and significantly cheaper in some cases. -(Note [CoreCLR#1422](https://github.com/dotnet/coreclr/issues/14222) indicates +(Note [#9027](https://github.com/dotnet/runtime/issues/9027) indicates we should be able to optimize away the null check in any case). If the guarded tests fails we've filtered out one method table the dispatch cell diff --git a/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md b/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md index 7799abdabf6c..1c1eec65a4b6 100644 --- a/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md +++ b/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md @@ -72,8 +72,8 @@ high priority. We haven't been targeting benchmarks that spend a lot of time doing computations in an inner loop. Pursuing loop optimizations for the peanut butter effect would seem odd. So this simply hasn't bubbled up in priority yet, though it's -bound to eventually. Obvious candidates include [IV widening](https://github.com/dotnet/coreclr/issues/9179), -[unrolling](https://github.com/dotnet/coreclr/issues/11606), load/store motion, +bound to eventually. Obvious candidates include [IV widening](https://github.com/dotnet/runtime/issues/7312), +[unrolling](https://github.com/dotnet/runtime/issues/8107), load/store motion, and strength reduction. @@ -112,7 +112,7 @@ handle SSA renames. We've made note of the prevalence of async/await in modern code (and particularly in web server code such as TechEmpower), and have some opportunities listed in -[#7914](https://github.com/dotnet/coreclr/issues/7914). Some sort of study of +[#6916](https://github.com/dotnet/runtime/issues/6916). Some sort of study of async peanut butter to find more opportunities is probably in order, but what would that look like? @@ -120,7 +120,7 @@ would that look like? ### If-Conversion (cmov formation) This hits big in microbenchmarks where it hits. There's some work in flight -on this (see [#7447](https://github.com/dotnet/coreclr/issues/7447) and +on this (see [#6749](https://github.com/dotnet/runtime/issues/6749) and [#10861](https://github.com/dotnet/coreclr/pull/10861)). @@ -149,7 +149,7 @@ helpers that are known not to trash them, but the information about which helpers trash which registers is spread across a few places in the codebase, and has some puzzling quirks like separate "GC" and "NoGC" kill sets for the same helper. Unifying the information sources and then refining the recorded -kill sets would help avoid more stack traffic. See [#12940](https://github.com/dotnet/coreclr/issues/12940). +kill sets would help avoid more stack traffic. See [#8605](https://github.com/dotnet/runtime/issues/8605). Low-Hanging Fruit ----------------- @@ -160,8 +160,8 @@ The MSIL `switch` instruction is actually encoded as a jump table, so (for better or worse) intelligent optimization of source-level switch statements largely falls to the MSIL generator (e.g. Roslyn), since encoding sparse switches as jump tables in MSIL would be impractical. That said, when the MSIL -has a switch of just a few cases (as in [#12868](https://github.com/dotnet/coreclr/issues/12868)), -or just a few distinct cases that can be efficiently checked (as in [#12477](https://github.com/dotnet/coreclr/issues/12477)), +has a switch of just a few cases (as in [#8573](https://github.com/dotnet/runtime/issues/8573)), +or just a few distinct cases that can be efficiently checked (as in [#8418](https://github.com/dotnet/runtime/issues/8418)), the JIT needn't blindly emit these as jump tables in the native code. Work is underway to address the latter case in [#12552](https://github.com/dotnet/coreclr/pull/12552). @@ -170,7 +170,7 @@ underway to address the latter case in [#12552](https://github.com/dotnet/corecl A number of suggestions have been made for having the JIT recognize certain patterns and emit specialized write barriers that avoid various overheads -- -see [#13006](https://github.com/dotnet/coreclr/issues/13006) and [#12812](https://github.com/dotnet/coreclr/issues/12812). +see [#8627](https://github.com/dotnet/runtime/issues/8627) and [#8547](https://github.com/dotnet/runtime/issues/8547). ### Byref-Exposed Store/Load Value Propagation @@ -178,8 +178,8 @@ see [#13006](https://github.com/dotnet/coreclr/issues/13006) and [#12812](https: There are a few tweaks to our value-numbering for byref-exposed loads and stores to share some of the machinery we use for heap loads and stores that would allow better propagation through byref-exposed locals and out parameters -- -see [#13457](https://github.com/dotnet/coreclr/issues/13457) and -[#13458](https://github.com/dotnet/coreclr/issues/13458). +see [#8767](https://github.com/dotnet/runtime/issues/8767) and +[#8768](https://github.com/dotnet/runtime/issues/8768). Miscellaneous ------------- @@ -199,4 +199,4 @@ Maybe it's worth reconsidering the priority based on throughput? RyuJIT has an implementation that handles the valuable cases (see [analysis](https://gist.github.com/JosephTremoulet/c1246b17ea2803e93e203b9969ee5a25#file-mulshift-md) and [follow-up](https://github.com/dotnet/coreclr/pull/13128) for details). The current implementation is split across Morph and CodeGen; ideally it would -be moved to Lower, which is tracked by [#13150](https://github.com/dotnet/coreclr/issues/13150). +be moved to Lower, which is tracked by [#8668](https://github.com/dotnet/runtime/issues/8668). diff --git a/docs/design/coreclr/jit/first-class-structs.md b/docs/design/coreclr/jit/first-class-structs.md index 2153b8cb96aa..e24596b653ec 100644 --- a/docs/design/coreclr/jit/first-class-structs.md +++ b/docs/design/coreclr/jit/first-class-structs.md @@ -213,7 +213,7 @@ This would be done in multiple phases: for a general idea of the kinds of VM changes that may be required. * Defer retyping of struct return types (`Compiler::impFixupStructReturnType()` and `Compiler::impFixupCallStructReturn()`) - * This is probably the "right" way to fix [#26491](https://github.com/dotnet/coreclr/issues/26491). + * This is probably the "right" way to fix [#13355](https://github.com/dotnet/runtime/issues/13355). * Next, eliminate the "pessimizations". * For cases where `GT_LCL_FLD` is currently used to "retype" the struct, change it to use *either* `GT_LCL_FLD`, if it is already address-taken, or to use a `GT_BITCAST` otherwise. @@ -230,7 +230,7 @@ This would be done in multiple phases: * The removal of each of these pessimizations should result in improved code generation in cases where previously disabled optimizations are now enabled. * Other ABI-related issues: - * [#8289](https://github.com/dotnet/coreclr/issues/8289) - code generation for x86 promoted struct args. + * [#7048](https://github.com/dotnet/runtime/issues/7048) - code generation for x86 promoted struct args. Related issues: #1133 (maybe), #4766, #23675, #23129 @@ -262,14 +262,14 @@ This would be enabled first by [Defer ABI-specific transformations to Lowering]( (#10019, #9594, #7313) * Support partial struct promotion when some fields are more frequently accessed. * Aggressively promote lclVar struct incoming or outgoing args or returns whose fields match the ABI requirements. - * This should address [\#26710](https://github.com/dotnet/coreclr/issues/26710). + * This should address [\#13417](https://github.com/dotnet/runtime/issues/13417). * Aggressively promote pointer-sized fields of structs used as args or returns * Allow struct promotion of locals that are passed or returned in a way that doesn't match the field types. * Investigate whether it would be useful to re-type single-field structs, rather than creating new lclVars. This would complicate type analysis when copied, passed or returned, but would avoid unnecessarily expanding the lclVar data structures. - * Allow promotion of 32-byte SIMD on 16-byte alignment [\#24368](https://github.com/dotnet/coreclr/issues/24368) + * Allow promotion of 32-byte SIMD on 16-byte alignment [\#12623](https://github.com/dotnet/runtime/issues/12623) * Related: #6839, #9477, #16887 * Also, #11888, which suggests adding a struct promotion stress mode. @@ -294,7 +294,7 @@ Struct-Related Issues in RyuJIT The following issues illustrate some of the motivation for improving the handling of value types (structs) in RyuJIT: -* [\#11407 [RyuJIT] Fully enregister structs that fit into a single register when profitable](https://github.com/dotnet/coreclr/issues/11407), also VSO Bug 98404: .NET JIT x86 - poor code generated for value type initialization +* [\#8016 [RyuJIT] Fully enregister structs that fit into a single register when profitable](https://github.com/dotnet/runtime/issues/8016), also VSO Bug 98404: .NET JIT x86 - poor code generated for value type initialization * This is a simple test case that should generate simply `xor eax; ret` on x86 and x64, but instead generates many unnecessary copies. It is addressed by full enregistration of structs that fit into a register. See [Support Full Enregistration of Struct Types](#support-full-enregistration-of-struct-types): @@ -304,7 +304,7 @@ struct foo { public byte b1, b2, b3, b4; } static foo getfoo() { return new foo(); } ``` -* [\#1133 JIT: Excessive copies when inlining](https://github.com/dotnet/coreclr/issues/1133) +* [\#4308 JIT: Excessive copies when inlining](https://github.com/dotnet/runtime/issues/4308) * The scenario given in this issue involves a struct that is larger than 8 bytes, so it is not impacted by the fixed-size types. However, by enabling value numbering and assertion propagation for struct types (which, in turn is made easier by using normal assignments), the @@ -314,54 +314,54 @@ static foo getfoo() { return new foo(); } in the first place. * This case may now be handled; needs verification -* [\#1161 RyuJIT properly optimizes structs with a single field if the field type is int but not if it is double](https://github.com/dotnet/coreclr/issues/1161) +* [\#4323 RyuJIT properly optimizes structs with a single field if the field type is int but not if it is double](https://github.com/dotnet/runtime/issues/4323) * This issue arises because we never promote a struct with a single double field, due to the fact that such a struct may be passed or returned in a general purpose register. This issue could be addressed independently, but should "fall out" of improved heuristics for when to promote and enregister structs. - * Related: [\#8828](https://github.com/dotnet/coreclr/issues/8828) + * Related: [\#7200](https://github.com/dotnet/runtime/issues/7200) * [\#1636 Add optimization to avoid copying a struct if passed by reference and there are no - writes to and no reads after passed to a callee](https://github.com/dotnet/coreclr/issues/1636). + writes to and no reads after passed to a callee](https://github.com/dotnet/runtime/issues/4524). * This issue is related to #1133, except that in this case the desire is to eliminate unneeded copies locally (i.e. not just due to inlining), in the case where the struct may or may not be passed or returned directly. * Unfortunately, there is not currently a scenario or test case for this issue. -* [\#19425 Unix: Unnecessary struct copy while passsing struct of size <=16](https://github.com/dotnet/coreclr/issues/19425) -* [\#16619 [RyuJIT] Eliminate unecessary copies when passing structs](https://github.com/dotnet/coreclr/issues/16619) +* [\#10879 Unix: Unnecessary struct copy while passsing struct of size <=16](https://github.com/dotnet/runtime/issues/10879) +* [\#9839 [RyuJIT] Eliminate unecessary copies when passing structs](https://github.com/dotnet/runtime/issues/9839) * These require changing both the callsite and the callee to avoid copying the parameter onto the stack. -* [\#3144 Avoid marking tmp as DoNotEnregister in tmp=GT_CALL() where call returns a - enregisterable struct in two return registers](https://github.com/dotnet/coreclr/issues/3144) +* [\#5112 Avoid marking tmp as DoNotEnregister in tmp=GT_CALL() where call returns a + enregisterable struct in two return registers](https://github.com/dotnet/runtime/issues/5112) * This issue could be addressed without First Class Structs. However, it should be done along with the streamlining of the handling of ABI-specific struct passing and return values. -* [\#4766 Pi-Digits: Extra Struct copies of BigInteger](https://github.com/dotnet/coreclr/issues/4766) +* [\#5785 Pi-Digits: Extra Struct copies of BigInteger](https://github.com/dotnet/runtime/issues/5785) * In addition to suffering from the same issue as #1133, this has a struct that is promoted even though it is passed (by reference) to its non-inlined constructor. This means that any copy to/from this struct will be field-by-field. -* [\#11816 Extra zeroing with structs and inlining](https://github.com/dotnet/coreclr/issues/11816) +* [\#8186 Extra zeroing with structs and inlining](https://github.com/dotnet/runtime/issues/8186) * This issue illustrates the failure of the JIT to eliminate zero-initialization of structs that are subsequently fully defined. It is a related but somewhat different manifestation of the issue in #1133, i.e. that structs are not fully supported in value numbering and optimization. -* [\#12865 JIT: inefficient codegen for calls returning 16-byte structs on Linux x64](https://github.com/dotnet/coreclr/issues/12865) +* [\#8571 JIT: inefficient codegen for calls returning 16-byte structs on Linux x64](https://github.com/dotnet/runtime/issues/8571) * This is related to #3144, and requires supporting the assignment of a multi-reg call return into a promoted local variable, and enabling subsequent elimination of any redundant copies. -* [\#22445](https://github.com/dotnet/coreclr/issues/22445) and [\#22319](https://github.com/dotnet/coreclr/issues/22319) +* [\#11992](https://github.com/dotnet/runtime/issues/11992) and [\#11940](https://github.com/dotnet/runtime/issues/11940) * These are both cases where we introduce a `GT_LCL_FLD` to retype a value that needs to be passed in a register. ## Other Struct-related Issues -* [\#17207](https://github.com/dotnet/coreclr/issues/17207) +* [\#10029](https://github.com/dotnet/runtime/issues/10029) * This suffers from pessimization due to poor handling of conversion (`Unsafe.As`) from `Quaternion` to `Vector4`. It's not immediately clear what's the best way to improve this. -* [#7740](https://github.com/dotnet/coreclr/issues/7740) +* [#6858](https://github.com/dotnet/runtime/issues/6858) * Addressing mode expression optimization for struct fields Sample IR diff --git a/docs/design/coreclr/jit/object-stack-allocation.md b/docs/design/coreclr/jit/object-stack-allocation.md index ec6fe14b3d64..914013878000 100644 --- a/docs/design/coreclr/jit/object-stack-allocation.md +++ b/docs/design/coreclr/jit/object-stack-allocation.md @@ -21,7 +21,7 @@ various Java runtimes. This optimization is more important for Java since it do [roslyn #2104](https://github.com/dotnet/roslyn/issues/2104) Compiler should optimize "alloc temporary small object" to "alloc on stack" -[coreclr #1784](https://github.com/dotnet/coreclr/issues/1784) CLR/JIT should optimize "alloc temporary small object" to "alloc on stack" automatically +[runtime #4584](https://github.com/dotnet/runtime/issues/4584) CLR/JIT should optimize "alloc temporary small object" to "alloc on stack" automatically ## Escape Analysis @@ -157,7 +157,7 @@ So the upper bound from this experiment is 22.2%. @AndyAyersMS recently resurrected @echesakovMSFT work and used it to [prototype stack allocation of a simple delegate that's directly invoked](https://github.com/dotnet/coreclr/compare/master...AndyAyersMS:NonNullPlusStackAlloc). It exposed a number of things that need to be done in the jit to generate better code for stack-allocated objects. The details are in comments of -[coreclr #1784](https://github.com/dotnet/coreclr/issues/1784). +[runtime #4584](https://github.com/dotnet/runtime/issues/4584). We did some analysis of Roslyn csc self-build to see where this optimization may be beneficial. One hot place was found in [GreenNode.WriteTo](https://github.com/dotnet/roslyn/blob/fab7134296816fc80019c60b0f5bef7400cf23ea/src/Compilers/Core/Portable/Syntax/GreenNode.cs#L647). This object allocation accounts for 8.17% of all object allocations in this scenario. The number is not as impressive as a percentage diff --git a/docs/design/coreclr/jit/variabletracking.md b/docs/design/coreclr/jit/variabletracking.md index e37dd8b54f4a..c4f86a6cd56d 100644 --- a/docs/design/coreclr/jit/variabletracking.md +++ b/docs/design/coreclr/jit/variabletracking.md @@ -338,7 +338,7 @@ There are many things we can do to improve optimized debugging: Currently we don't have the IL offset of them. And this is broadly used to improve code performance. -- [Promoted structs](https://github.com/dotnet/coreclr/issues/23542): There is no debug support for fields of promoted structs, we just report the struct itself. +- [Promoted structs](https://github.com/dotnet/runtime/issues/12369): There is no debug support for fields of promoted structs, we just report the struct itself. -- [Reduce space used for VariableLiveDescriptor](https://github.com/dotnet/coreclr/issues/23544): we are currently using a `jitstd::list`, which is a double linked list. +- [Reduce space used for VariableLiveDescriptor](https://github.com/dotnet/runtime/issues/12371): we are currently using a `jitstd::list`, which is a double linked list. We could use a simple single linked list with push_back(), head(), tail(), size() operations and an iterator and we would be saving memory. diff --git a/docs/design/features/COM-activation.md b/docs/design/features/COM-activation.md index c4302e53f2b1..409d950f045a 100644 --- a/docs/design/features/COM-activation.md +++ b/docs/design/features/COM-activation.md @@ -105,7 +105,7 @@ When `DllGetClassObject()` is called in a COM activation scenario, the following ``` Note this API is not exposed outside of `System.Private.CoreLib` and is subject to change at any time. * The loading of the assembly will take place in a new [`AssemblyLoadContext`](https://docs.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext) for dependency isolation. Each assembly path will get a seperate `AssemblyLoadContext`. This means that if an assembly provides multiple COM servers all of the servers from that assembly will reside in the same `AssemblyLoadContext`. - * The created `AssemblyLoadContext` will use an [`AssemblyDependencyResolver`](https://github.com/dotnet/corefx/issues/33165) that was supplied with the path to the assembly to load assemblies. + * The created `AssemblyLoadContext` will use an [`AssemblyDependencyResolver`](https://github.com/dotnet/runtime/issues/27787) that was supplied with the path to the assembly to load assemblies. 1) The `IClassFactory` instance is returned to the caller of `DllGetClassObject()` to attempt class activation. The `DllCanUnloadNow()` function will always return `S_FALSE` indicating the shim is never able to be unloaded. This matches .NET Framework semantics but may be adjusted in the future if needed. diff --git a/docs/design/features/PinnedHeap.md b/docs/design/features/PinnedHeap.md index d9d2ffa30047..81c76e620804 100644 --- a/docs/design/features/PinnedHeap.md +++ b/docs/design/features/PinnedHeap.md @@ -42,7 +42,7 @@ An object allocated on the pinned heap can be referenced by other objects normal ## API - allocating an array on the pinned heap -For users who want to allocate their objects pinned, we provide [a new API](https://github.com/dotnet/corefx/issues/31787) to allocate such an object. The API declaration is the following: +For users who want to allocate their objects pinned, we provide [a new API](https://github.com/dotnet/runtime/issues/27146) to allocate such an object. The API declaration is the following: ```csharp class GC @@ -154,7 +154,7 @@ It might make sense to provide an additional API to allocate an array of these o **Alignment support** -However, there is another scenario for high perf that could warrant a generational pinned heap which is objects with a specified alignment mostly [for SIMD operations](https://github.com/dotnet/corefx/issues/22790) or aligning on cache lines to avoid false sharing. This scenario doesn’t imply the object always needs to be pinned, however being pinned does mean they would be convenient for interop. For example, matrix multiplication with SIMD where the matrix is also used in native code. It also isn’t clear the object is necessarily long lived, however we do make the assumption that the amount of memory occupied by pinned objects should be small compared to non pinned objects so treating all of them as part of gen2 is acceptable. A different design option would be to allocate these on the normal heap but keep their alignment when compacting but this makes compaction slower. +However, there is another scenario for high perf that could warrant a generational pinned heap which is objects with a specified alignment mostly [for SIMD operations](https://github.com/dotnet/runtime/issues/22990) or aligning on cache lines to avoid false sharing. This scenario doesn’t imply the object always needs to be pinned, however being pinned does mean they would be convenient for interop. For example, matrix multiplication with SIMD where the matrix is also used in native code. It also isn’t clear the object is necessarily long lived, however we do make the assumption that the amount of memory occupied by pinned objects should be small compared to non pinned objects so treating all of them as part of gen2 is acceptable. A different design option would be to allocate these on the normal heap but keep their alignment when compacting but this makes compaction slower. For alignment support, we can also limit it to a few specific alignments if it makes the implementation noticeably easier – 16, 32, 64, 128 bytes, and possibly page size (unclear if this is really needed). diff --git a/docs/design/features/arm64-intrinsics.md b/docs/design/features/arm64-intrinsics.md index 67aff026878d..e814833ad126 100644 --- a/docs/design/features/arm64-intrinsics.md +++ b/docs/design/features/arm64-intrinsics.md @@ -289,7 +289,7 @@ This document will refer to half precision floating point as `Half`. + CoreCLR and `CIL` in general do not have general support for a `Half` type + There is an open request to expose `Half` intrinsics + There is an outstanding proposal to add `System.Half` to support this request -https://github.com/dotnet/corefx/issues/25702 +https://github.com/dotnet/runtime/issues/936 + Implementation of `Half` features will be adjusted based on + Implementation of the `System.Half` proposal + Availability of supporting hardware (extensions) diff --git a/docs/design/features/hw-intrinsics.md b/docs/design/features/hw-intrinsics.md index fb1287c42185..0abddc147cae 100644 --- a/docs/design/features/hw-intrinsics.md +++ b/docs/design/features/hw-intrinsics.md @@ -30,7 +30,7 @@ The vector types supported by one or more target ISAs are supported across platf * `Vector256` - A 256-bit vector of type `T` * `Vector256` intrinsics are supported only on x86 (and x64). -Note that these are generic types, which distinguishes these from native intrinsic vector types. It also somewhat complicates interop, as the runtime currently doesn't support interop for generic types. See https://github.com/dotnet/coreclr/issues/1685 +Note that these are generic types, which distinguishes these from native intrinsic vector types. It also somewhat complicates interop, as the runtime currently doesn't support interop for generic types. See https://github.com/dotnet/runtime/issues/4547 Not all intrinsics defined on these types support all primitive type parameters. When not supported, they are expected to throw `NotSupportedException`. This is generally handled by the C# implementation code, though for the most part this is a non-issue, as the ISA-specific intrinsics are declared over all supported concrete types (e.g. `Vector128` rather than `Vector128`). @@ -69,7 +69,7 @@ Currently, the JIT determines in the importer whether it will: * Generate a call (e.g. if it is a recognized intrinsic but an operand is not immediate as it is expected to be). The `mustExpand` option, which is returned by the VM as an "out" parameter to the `getIntrinsicID` method, must be false in this case. * Throw `PlatformNotSupportedException` if it is not a recognized and supported intrinsic for the current platform. -There is some room for improvement here. For example, it may be that an argument that appears to be non-constant could later be determined to be a constant value (https://github.com/dotnet/coreclr/issues/17108). +There is some room for improvement here. For example, it may be that an argument that appears to be non-constant could later be determined to be a constant value (https://github.com/dotnet/runtime/issues/9989). ### Hardware Intrinsics Table @@ -114,7 +114,7 @@ The only thing that makes the hardware intrinsics different in the area of instr The encodings are largely specified by `coreclr\src\jit\instrs{arch}.h`, and most of the target-specific code is in the `emit{arch}.*` files. -This is an area of the JIT that could use some redesign and refactoring (https://github.com/dotnet/coreclr/issues/23006 and https://github.com/dotnet/coreclr/issues/21441 among others). +This is an area of the JIT that could use some redesign and refactoring (https://github.com/dotnet/runtime/issues/12178 and https://github.com/dotnet/runtime/issues/11631 among others). ## Testing diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md index 1d42a5e4c909..5d3e99f19a8b 100644 --- a/docs/design/specs/Ecma-335-Augments.md +++ b/docs/design/specs/Ecma-335-Augments.md @@ -147,7 +147,7 @@ error with a suitable message rather than a stack overflow. Related issues: * https://github.com/dotnet/roslyn/issues/7971 -* https://github.com/dotnet/coreclr/issues/2674 +* https://github.com/dotnet/runtime/issues/4945 #### Proposed specification change diff --git a/docs/project/glossary.md b/docs/project/glossary.md index f69d3749938b..c1b6b687354b 100644 --- a/docs/project/glossary.md +++ b/docs/project/glossary.md @@ -24,7 +24,7 @@ terminology. | JIT | [Just-in-Time](https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/jit/ryujit-overview.md) compiler. RyuJIT is the code name for the next generation Just-in-Time(aka "JIT") for the .NET runtime. | | LCG | Lightweight Code Generation. An early name for [dynamic methods](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs). | | MD | MetaData. | -| MDA | Managed Debugging Assistant - see [details](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants) (Note: Not in .NET Core, equivalent diagnostic functionality is made available on a case-by-case basis, e.g. [#15465](https://github.com/dotnet/coreclr/issues/15465)) | +| MDA | Managed Debugging Assistant - see [details](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants) (Note: Not in .NET Core, equivalent diagnostic functionality is made available on a case-by-case basis, e.g. [#9418](https://github.com/dotnet/runtime/issues/9418)) | | NGen | Native Image Generator. | | NYI | Not Yet Implemented. | | PAL | [Platform Adaptation Layer](http://archive.oreilly.com/pub/a/dotnet/2002/03/04/rotor.html). Provides an abstraction layer between the runtime and the operating system. | diff --git a/docs/project/profiling-api-status.md b/docs/project/profiling-api-status.md index a9279b69d428..5e649414cea8 100644 --- a/docs/project/profiling-api-status.md +++ b/docs/project/profiling-api-status.md @@ -20,7 +20,7 @@ ReJIT feature is only available on x86/x64 for now. ### Profiler Attach/Detach -We only support launch at the moment, see https://github.com/dotnet/coreclr/issues/16796 +We only support launch at the moment, see https://github.com/dotnet/runtime/issues/9886 ### Any issues we missed? diff --git a/docs/workflow/building/coreclr/freebsd-instructions.md b/docs/workflow/building/coreclr/freebsd-instructions.md index 49c29f49deff..ef31a0b4d215 100644 --- a/docs/workflow/building/coreclr/freebsd-instructions.md +++ b/docs/workflow/building/coreclr/freebsd-instructions.md @@ -10,7 +10,7 @@ These instructions are written assuming FreeBSD 10.1-RELEASE, since that's the r These instructions assume you use the binary package tool `pkg` (analog to `apt-get` or `yum` on Linux) to install the environment. Compiling the dependencies from source using the ports tree might work too, but is untested. -Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs ([Issue 536](https://github.com/dotnet/coreclr/issues/536)). +Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs ([Issue 4069](https://github.com/dotnet/runtime/issues/4069)). Toolchain Setup --------------- @@ -166,7 +166,7 @@ Download NuGet Packages With Mono and NuGet in hand, you can use NuGet to get the required dependencies. -Make a `packages.config` file with the following text. These are the required dependencies of this particular app. Different apps will have different dependencies and require a different `packages.config` - see [Issue #480](https://github.com/dotnet/coreclr/issues/480). +Make a `packages.config` file with the following text. These are the required dependencies of this particular app. Different apps will have different dependencies and require a different `packages.config` - see [Issue #4053](https://github.com/dotnet/runtime/issues/4053). ```xml @@ -198,7 +198,7 @@ And restore your packages.config file: janhenke@freebsd-frankfurt:~/coreclr-demo/packages % mono nuget.exe restore -Source https://www.myget.org/F/dotnet-corefx/ -PackagesDirectory . ``` -NOTE: This assumes you already installed the default CA certs. If you have problems downloading the packages please see [Issue #602](https://github.com/dotnet/coreclr/issues/602#issuecomment-88203778). The command for FreeBSD is: +NOTE: This assumes you already installed the default CA certs. If you have problems downloading the packages please see [Issue #4089](https://github.com/dotnet/runtime/issues/4089#issuecomment-88203778). The command for FreeBSD is: ```sh janhenke@freebsd-frankfurt:~/coreclr-demo/packages % mozroots --import --sync diff --git a/docs/workflow/building/libraries/cross-building.md b/docs/workflow/building/libraries/cross-building.md index c7b0fe1fda42..24393ba5cf73 100644 --- a/docs/workflow/building/libraries/cross-building.md +++ b/docs/workflow/building/libraries/cross-building.md @@ -90,7 +90,7 @@ The output is at `artifacts/bin/[BuildSettings]` where `BuildSettings` looks som Building corefx for Linux ARM Emulator ======================================= -It is possible to build corefx binaries (native and managed) for the Linux ARM Emulator (latest version provided here: [#3805](https://github.com/dotnet/coreclr/issues/3805)). +It is possible to build corefx binaries (native and managed) for the Linux ARM Emulator (latest version provided here: [#5394](https://github.com/dotnet/runtime/issues/5394)). The `scripts/arm32_ci_script.sh` script does this. The following instructions assume that: diff --git a/docs/workflow/ci/coreclr-ci-health.md b/docs/workflow/ci/coreclr-ci-health.md index 5e095b6af444..021ad7d7fc7f 100644 --- a/docs/workflow/ci/coreclr-ci-health.md +++ b/docs/workflow/ci/coreclr-ci-health.md @@ -4,7 +4,7 @@ Note that this document focuses on coreclr testing in `dotnet/runtime`. -https://github.com/dotnet/coreclr/issues/27231 was opened as a way to simply view in one place all issues that are affecting `dotnet/runtime`'s CI. +https://github.com/dotnet/runtime/issues/702 was opened as a way to simply view in one place all issues that are affecting `dotnet/runtime`'s CI. ## TOC diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 02611fa19272..006a180fa0aa 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -359,7 +359,7 @@ if (CLR_CMAKE_HOST_UNIX) endif() # Some architectures (e.g., ARM) assume char type is unsigned while CoreCLR assumes char is signed - # as x64 does. It has been causing issues in ARM (https://github.com/dotnet/coreclr/issues/4746) + # as x64 does. It has been causing issues in ARM (https://github.com/dotnet/runtime/issues/5778) add_compile_options(-fsigned-char) # We mark the function which needs exporting with DLLEXPORT diff --git a/eng/packaging.targets b/eng/packaging.targets index 0891a5a2f9f4..47484ae1f4e8 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -2,9 +2,9 @@ + - https://github.com/dotnet/runtime/issues/27470 -> Why reference assets were removed from the package + - https://github.com/dotnet/aspnetcore/issues/11206 -> Why ASP.NET required a ref to be added back for netcoreapp + - https://github.com/dotnet/runtime/issues/29966 -> Issue tracking to work of readding a ref to netcoreapp --> diff --git a/src/coreclr/crossgen-corelib.cmd b/src/coreclr/crossgen-corelib.cmd index f47aa1799093..64957d7757e8 100644 --- a/src/coreclr/crossgen-corelib.cmd +++ b/src/coreclr/crossgen-corelib.cmd @@ -182,7 +182,7 @@ if %__PgoInstrument% EQU 1 ( goto ExitWithError ) - REM HACK: Workaround for [dotnet/coreclr#13970](https://github.com/dotnet/coreclr/issues/13970) + REM HACK: Workaround for [dotnet/runtime#8929](https://github.com/dotnet/runtime/issues/8929) set __PgoRtPath= for /f "tokens=*" %%f in ('where pgort*.dll') do ( if not defined __PgoRtPath set "__PgoRtPath=%%~f" diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs b/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs index d9ed61c6c103..10ede24a6573 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs @@ -134,50 +134,50 @@ public override bool Equals(object? o) #else public ArgIterator(RuntimeArgumentHandle arglist) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } [CLSCompliant(false)] public unsafe ArgIterator(RuntimeArgumentHandle arglist, void* ptr) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } public void End() { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } public override bool Equals(object? o) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } public override int GetHashCode() { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } [CLSCompliant(false)] public System.TypedReference GetNextArg() { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } [CLSCompliant(false)] public System.TypedReference GetNextArg(System.RuntimeTypeHandle rth) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } public unsafe System.RuntimeTypeHandle GetNextArgType() { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } public int GetRemainingCount() { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/runtime/issues/7317 } #endif // TARGET_WINDOWS } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs index cb011de2ef2b..d932d18d9fc9 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs @@ -685,7 +685,7 @@ public static T[] AllocateUninitializedArray(int length, bool pinned = false) // kept outside of the small arrays hot path to have inlining without big size growth return AllocateNewUninitializedArray(length, pinned); - // remove the local function when https://github.com/dotnet/coreclr/issues/5329 is implemented + // remove the local function when https://github.com/dotnet/runtime/issues/5973 is implemented static T[] AllocateNewUninitializedArray(int length, bool pinned) { GC_ALLOC_FLAGS flags = GC_ALLOC_FLAGS.GC_ALLOC_ZEROING_OPTIONAL; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/src/System.Private.CoreLib/src/System/MulticastDelegate.cs index a2598bd7779a..fc3ef65f74b5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -437,7 +437,7 @@ public sealed override Delegate[] GetInvocationList() // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/coreclr/issues/914 + // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 return (d1 is null) ? true : false; } @@ -454,7 +454,7 @@ public sealed override Delegate[] GetInvocationList() // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/coreclr/issues/914 + // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 return (d1 is null) ? false : true; } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs index a7625465c0e8..aa21a11492e6 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs @@ -1336,7 +1336,7 @@ private static bool FilterCustomAttributeRecord( if (ctorHasParameters) { // Resolve method ctor token found in decorated decoratedModule scope - // See https://github.com/dotnet/coreclr/issues/21456 for why we fast-path non-generics here (fewer allocations) + // See https://github.com/dotnet/runtime/issues/11637 for why we fast-path non-generics here (fewer allocations) if (attributeType.IsGenericType) { ctorWithParameters = decoratedModule.ResolveMethod(caCtorToken, attributeType.GenericTypeArguments, null)!.MethodHandle.GetMethodInfo(); diff --git a/src/coreclr/src/classlibnative/bcltype/system.cpp b/src/coreclr/src/classlibnative/bcltype/system.cpp index 6bd072f13ea8..74623125fdf4 100644 --- a/src/coreclr/src/classlibnative/bcltype/system.cpp +++ b/src/coreclr/src/classlibnative/bcltype/system.cpp @@ -46,7 +46,7 @@ void WINAPI InitializeGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { // GetSystemTimePreciseAsFileTime exists and we'd like to use it. However, on // misconfigured systems, it's possible for the "precise" time to be inaccurate: - // https://github.com/dotnet/coreclr/issues/14187 + // https://github.com/dotnet/runtime/issues/9014 // If it's inaccurate, though, we expect it to be wildly inaccurate, so as a // workaround/heuristic, we get both the "normal" and "precise" times, and as // long as they're close, we use the precise one. This workaround can be removed diff --git a/src/coreclr/src/classlibnative/float/floatdouble.cpp b/src/coreclr/src/classlibnative/float/floatdouble.cpp index d3ef36c66a61..a2a00b0628bd 100644 --- a/src/coreclr/src/classlibnative/float/floatdouble.cpp +++ b/src/coreclr/src/classlibnative/float/floatdouble.cpp @@ -125,7 +125,7 @@ FCIMPLEND #if defined(_MSC_VER) && defined(TARGET_AMD64) // The /fp:fast form of `ceil` for AMD64 does not correctly handle: `-1.0 < value <= -0.0` -// https://github.com/dotnet/coreclr/issues/19739 +// https://github.com/dotnet/runtime/issues/11003 #pragma float_control(push) #pragma float_control(precise, on) #endif @@ -172,7 +172,7 @@ FCIMPLEND #if defined(_MSC_VER) && defined(TARGET_X86) // The /fp:fast form of `floor` for x86 does not correctly handle: `-0.0` -// https://github.com/dotnet/coreclr/issues/19739 +// https://github.com/dotnet/runtime/issues/11003 #pragma float_control(push) #pragma float_control(precise, on) #endif diff --git a/src/coreclr/src/classlibnative/float/floatsingle.cpp b/src/coreclr/src/classlibnative/float/floatsingle.cpp index 781badfc1f8a..9972e17c6901 100644 --- a/src/coreclr/src/classlibnative/float/floatsingle.cpp +++ b/src/coreclr/src/classlibnative/float/floatsingle.cpp @@ -123,7 +123,7 @@ FCIMPLEND #if defined(_MSC_VER) && defined(TARGET_AMD64) // The /fp:fast form of `ceilf` for AMD64 does not correctly handle: `-1.0 < value <= -0.0` -// https://github.com/dotnet/coreclr/issues/19739 +// https://github.com/dotnet/runtime/issues/11003 #pragma float_control(push) #pragma float_control(precise, on) #endif diff --git a/src/coreclr/src/gc/CMakeLists.txt b/src/coreclr/src/gc/CMakeLists.txt index a34567e1910a..b802602d2b4f 100644 --- a/src/coreclr/src/gc/CMakeLists.txt +++ b/src/coreclr/src/gc/CMakeLists.txt @@ -1,11 +1,11 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Local GC meta-issue: https://github.com/dotnet/coreclr/issues/11518 +# Local GC meta-issue: https://github.com/dotnet/runtime/issues/8061 -# https://github.com/dotnet/coreclr/issues/11516 +# https://github.com/dotnet/runtime/issues/8059 remove_definitions(-DSTRESS_HEAP) -# https://github.com/dotnet/coreclr/issues/11519 +# https://github.com/dotnet/runtime/issues/8062 remove_definitions(-DWRITE_BARRIER_CHECK) set( GC_SOURCES @@ -113,7 +113,7 @@ target_link_libraries(clrgc ${GC_LINK_LIBRARIES}) install_clr(TARGETS clrgc) if(CLR_CMAKE_HOST_UNIX) - # dprintf causes many warnings (https://github.com/dotnet/coreclr/issues/13367) + # dprintf causes many warnings (https://github.com/dotnet/runtime/issues/8737) add_compile_options(-Wno-format) endif(CLR_CMAKE_HOST_UNIX) diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp index b95903062f37..5971175804d9 100644 --- a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp +++ b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp @@ -365,7 +365,7 @@ int ExecuteManagedAssembly( // libunwind library is used to unwind stack frame, but libunwind for ARM // does not support ARM vfpv3/NEON registers in DWARF format correctly. // Therefore let's disable stack unwinding using DWARF information - // See https://github.com/dotnet/coreclr/issues/6698 + // See https://github.com/dotnet/runtime/issues/6479 // // libunwind use following methods to unwind stack frame. // UNW_ARM_METHOD_ALL 0xFF diff --git a/src/coreclr/src/ilasm/CMakeLists.txt b/src/coreclr/src/ilasm/CMakeLists.txt index 13e7467e0b1e..3e6c15b657ab 100644 --- a/src/coreclr/src/ilasm/CMakeLists.txt +++ b/src/coreclr/src/ilasm/CMakeLists.txt @@ -48,7 +48,7 @@ endif(CLR_CMAKE_TARGET_WIN32) if(CLR_CMAKE_HOST_UNIX) # Need generate a right form of asmparse.cpp to avoid the following options. # Clang also produces a bad-codegen on this prebuilt file with optimization. - # https://github.com/dotnet/coreclr/issues/2305 + # https://github.com/dotnet/runtime/issues/4776 add_compile_options("$<$:-Wno-register>") add_compile_options(-Wno-array-bounds) add_compile_options(-Wno-unused-label) diff --git a/src/coreclr/src/ilasm/main.cpp b/src/coreclr/src/ilasm/main.cpp index 9eec9a853277..342720ff8534 100644 --- a/src/coreclr/src/ilasm/main.cpp +++ b/src/coreclr/src/ilasm/main.cpp @@ -639,7 +639,7 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv) if (bGeneratePdb && CLASSIC == pdbFormat) { // Classic PDB format is not supported on CoreCLR - // https://github.com/dotnet/coreclr/issues/2982 + // https://github.com/dotnet/runtime/issues/5051 printf("WARNING: Classic PDB format is not supported on CoreCLR.\n"); printf("Use '/PDBFMT=PORTABLE' option in order to generate portable PDB format. \n"); diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index a85e2ce06bf9..a9dbcef15ec5 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -2976,7 +2976,7 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode) gcInfo.gcMarkRegPtrVal(addrReg, addr->TypeGet()); // TODO-ARM64-CQ Use ARMv8.1 atomics if available - // https://github.com/dotnet/coreclr/issues/11881 + // https://github.com/dotnet/runtime/issues/8225 // Emit code like this: // retry: diff --git a/src/coreclr/src/jit/emit.h b/src/coreclr/src/jit/emit.h index 2c7f0b073b5d..e9b428928299 100644 --- a/src/coreclr/src/jit/emit.h +++ b/src/coreclr/src/jit/emit.h @@ -870,7 +870,7 @@ class emitter // return value more than 15 that doesn't fit in 4 bits _idCodeSize. // If somehow we generate instruction that needs more than 15 bytes we // will fail on another assert in emit.cpp: noway_assert(id->idCodeSize() >= csz). - // Issue https://github.com/dotnet/coreclr/issues/25050. + // Issue https://github.com/dotnet/runtime/issues/12840. sz = 15; } assert(sz <= 15); // Intel decoder limit. diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 2e0e96a0e9a6..3c1c1446e928 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -2482,7 +2482,7 @@ unsigned Compiler::gtSetListOrder(GenTree* list, bool isListCallArgs, bool callA // TODO: Do we have to compute costs differently for argument lists and // all other lists? - // https://github.com/dotnet/coreclr/issues/7095 + // https://github.com/dotnet/runtime/issues/6622 unsigned costSz = (isListCallArgs || (next == nullptr)) ? 0 : 1; unsigned costEx = (isListCallArgs || (next == nullptr)) ? 0 : 1; @@ -2514,7 +2514,7 @@ unsigned Compiler::gtSetListOrder(GenTree* list, bool isListCallArgs, bool callA // TODO: Do we have to compute levels differently for argument lists and // all other lists? - // https://github.com/dotnet/coreclr/issues/7095 + // https://github.com/dotnet/runtime/issues/6622 if (isListCallArgs) { if (level < lvl) diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index a401a843dd0a..2867a7bacbb4 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -585,7 +585,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // I think this is due to the fact that we use absolute addressing // instead of relative. But in CoreRT is used as a rule relative // addressing when we generate an executable. - // See also https://github.com/dotnet/coreclr/issues/13194 + // See also https://github.com/dotnet/runtime/issues/8683 // Also https://github.com/dotnet/coreclr/pull/13197 useJumpSequence = useJumpSequence || comp->IsTargetAbi(CORINFO_CORERT_ABI); #endif // defined(TARGET_UNIX) && defined(TARGET_ARM) diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 5266da117cf8..89ae55b003e8 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -5352,7 +5352,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) op2->SetRegOptional(); // TODO-XArch-CQ: For commutative nodes, either operand can be reg-optional. - // https://github.com/dotnet/coreclr/issues/6361 + // https://github.com/dotnet/runtime/issues/6358 } break; } @@ -5538,7 +5538,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) // TODO-XArch-CQ: Technically any one of the three operands can // be reg-optional. With a limitation on op1 where // it can only be so if CopyUpperBits is off. - // https://github.com/dotnet/coreclr/issues/6361 + // https://github.com/dotnet/runtime/issues/6358 // 213 form: op1 = (op2 * op1) + op3 op3->SetRegOptional(); diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 6ec078e450fc..ea30779946ef 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -6629,13 +6629,13 @@ void Compiler::fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result) // 1) If the callee has structs which cannot be enregistered it will be // reported as cannot fast tail call. This is an implementation limitation // where the callee only is checked for non enregisterable structs. This is -// tracked with https://github.com/dotnet/coreclr/issues/12644. +// tracked with https://github.com/dotnet/runtime/issues/8492. // // 2) If the caller or callee has stack arguments and the callee has more // arguments then the caller it will be reported as cannot fast tail call. // This is due to a bug in LowerFastTailCall which assumes that // nCalleeArgs <= nCallerArgs, which is always true on Windows Amd64. This -// is tracked with https://github.com/dotnet/coreclr/issues/12468. +// is tracked with https://github.com/dotnet/runtime/issues/8413. // // 3) If the callee has a 9 to 16 byte struct argument and the callee has // stack arguments, the decision will be to not fast tail call. This is diff --git a/src/coreclr/src/pal/src/include/pal/mutex.hpp b/src/coreclr/src/pal/src/include/pal/mutex.hpp index c0227ff88d06..cdf308c4dc53 100644 --- a/src/coreclr/src/pal/src/include/pal/mutex.hpp +++ b/src/coreclr/src/pal/src/include/pal/mutex.hpp @@ -67,7 +67,7 @@ DWORD SPINLOCKTryAcquire (LONG * lock); // Named mutex // Temporarily disabling usage of pthread process-shared mutexes on ARM/ARM64 due to functional issues that cannot easily be -// detected with code due to hangs. See https://github.com/dotnet/coreclr/issues/5456. +// detected with code due to hangs. See https://github.com/dotnet/runtime/issues/6014. #if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && !(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__)) #define NAMED_MUTEX_USE_PTHREAD_MUTEX 1 #else diff --git a/src/coreclr/src/pal/tests/palsuite/DisabledTests.txt b/src/coreclr/src/pal/tests/palsuite/DisabledTests.txt index babd443380fe..0f7094c4a8e8 100644 --- a/src/coreclr/src/pal/tests/palsuite/DisabledTests.txt +++ b/src/coreclr/src/pal/tests/palsuite/DisabledTests.txt @@ -48,4 +48,4 @@ This test case should be run manually. Requires user input. filemapping_memmgt\MapViewOfFile\test1 ======================================= -Refer this github issue https://github.com/dotnet/coreclr/issues/5176 +Refer this github issue https://github.com/dotnet/runtime/issues/5924 diff --git a/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp b/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp index 89e9e85a86c4..c2793f732ef5 100644 --- a/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp +++ b/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp @@ -841,7 +841,7 @@ DWORD AbandonTests_Child_AbruptExit(void *arg = nullptr) // This child process acquires the mutex lock, creates another child process (to ensure that file locks are not inherited), and // abandons the mutex abruptly. The second child process detects the abandonment and abandons the mutex again for the parent to -// detect. Issue: https://github.com/dotnet/coreclr/issues/21455 +// detect. Issue: https://github.com/dotnet/runtime/issues/11636 DWORD AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit(void *arg = nullptr) { const char *testName = "AbandonTests"; diff --git a/src/coreclr/src/palrt/unicode.cpp b/src/coreclr/src/palrt/unicode.cpp index 1d8372642ec0..9def01dc63de 100644 --- a/src/coreclr/src/palrt/unicode.cpp +++ b/src/coreclr/src/palrt/unicode.cpp @@ -5,7 +5,7 @@ #include "common.h" // This is a simplified implementation of IsTextUnicode. -// https://github.com/dotnet/coreclr/issues/2307 +// https://github.com/dotnet/runtime/issues/4778 BOOL IsTextUnicode(CONST VOID* lpv, int iSize, LPINT lpiResult) { *lpiResult = 0; diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs index 9c56ff338e8a..6fcf05aaa184 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs @@ -308,7 +308,7 @@ private int GetStructGenRegDestinationAddress() // fieldBytes - size of the structure internal void ReportPointersFromStructInRegisters(TypeDesc type, int delta, CORCOMPILE_GCREFMAP_TOKENS[] frame) { - // SPAN-TODO: GC reporting - https://github.com/dotnet/coreclr/issues/8517 + // SPAN-TODO: GC reporting - https://github.com/dotnet/runtime/issues/7103 Debug.Assert(IsStructPassedInRegs()); diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 3fdb03f6724b..5bb297bc2ae4 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -672,12 +672,12 @@ private unsafe void EnsureExceptionInfo() public bool InputArchitectureSupported() { - return Machine != Machine.ArmThumb2; // CoreDisTools often fails to decode when disassembling ARM images (see https://github.com/dotnet/coreclr/issues/19637) + return Machine != Machine.ArmThumb2; // CoreDisTools often fails to decode when disassembling ARM images (see https://github.com/dotnet/runtime/issues/10959) } // TODO: Fix R2RDump issue where an R2R image cannot be dissassembled with the x86 CoreDisTools // For the short term, we want to error out with a decent message explaining the unexpected error - // Issue https://github.com/dotnet/coreclr/issues/19564 + // Issue https://github.com/dotnet/runtime/issues/10928 public bool DisassemblerArchitectureSupported() { System.Runtime.InteropServices.Architecture val = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture; diff --git a/src/coreclr/src/tools/r2rdump/README.md b/src/coreclr/src/tools/r2rdump/README.md index 364cbc3ad581..c515c43ae805 100644 --- a/src/coreclr/src/tools/r2rdump/README.md +++ b/src/coreclr/src/tools/r2rdump/README.md @@ -130,12 +130,12 @@ In x64/Arm/Arm64, GcTransitions are grouped into chunks where each chunk covers ## Todo -* Support R2RDump on ARM and ARM64 (https://github.com/dotnet/coreclr/issues/19089) +* Support R2RDump on ARM and ARM64 (https://github.com/dotnet/runtime/issues/10753) -* Parse R2RSections: READYTORUN_SECTION_EXCEPTION_INFO, READYTORUN_SECTION_DEBUG_INFO, READYTORUN_SECTION_DELAYLOAD_METHODCALL_THUNKS, READYTORUN_SECTION_INLINING_INFO, READYTORUN_SECTION_PROFILEDATA_INFO (https://github.com/dotnet/coreclr/issues/19616) +* Parse R2RSections: READYTORUN_SECTION_EXCEPTION_INFO, READYTORUN_SECTION_DEBUG_INFO, READYTORUN_SECTION_DELAYLOAD_METHODCALL_THUNKS, READYTORUN_SECTION_INLINING_INFO, READYTORUN_SECTION_PROFILEDATA_INFO (https://github.com/dotnet/runtime/issues/10948) * Reenable R2RDumpTests after making it less fragile -* Fix issues with disasm on Arm (https://github.com/dotnet/coreclr/issues/19637) and disasm using x86 coredistools (https://github.com/dotnet/coreclr/issues/19564) +* Fix issues with disasm on Arm (https://github.com/dotnet/runtime/issues/10959) and disasm using x86 coredistools (https://github.com/dotnet/runtime/issues/10928) -* Test R2RDump on more test cases to make sure it runs reliably and verify that the output is accurate (list of failing inputs: https://github.com/dotnet/coreclr/issues/19642) +* Test R2RDump on more test cases to make sure it runs reliably and verify that the output is accurate (list of failing inputs: https://github.com/dotnet/runtime/issues/10961) diff --git a/src/coreclr/src/vm/amd64/jithelpers_fast.S b/src/coreclr/src/vm/amd64/jithelpers_fast.S index 3076a633fe98..a1788a37afea 100644 --- a/src/coreclr/src/vm/amd64/jithelpers_fast.S +++ b/src/coreclr/src/vm/amd64/jithelpers_fast.S @@ -423,7 +423,7 @@ LEAF_END JIT_WriteBarrier_Callable, _TEXT // NOTE: On Linux we must advance the stack pointer as we probe - it is not allowed to access 65535 bytes below rsp. // Since this helper will modify a value of rsp - it must establish the frame pointer. // -// See also https://github.com/dotnet/coreclr/issues/16827#issue-303331518 for more information. +// See also https://github.com/dotnet/runtime/issues/9899#issue-303331518 for more information. #define PAGE_SIZE 0x1000 diff --git a/src/coreclr/src/vm/amd64/virtualcallstubcpu.hpp b/src/coreclr/src/vm/amd64/virtualcallstubcpu.hpp index 3e6cabe5c09c..d4035966a52e 100644 --- a/src/coreclr/src/vm/amd64/virtualcallstubcpu.hpp +++ b/src/coreclr/src/vm/amd64/virtualcallstubcpu.hpp @@ -596,7 +596,7 @@ void DispatchHolder::InitializeStatic() static_assert_no_msg(((sizeof(DispatchStub) + sizeof(DispatchStubShort)) % sizeof(void*)) == 0); static_assert_no_msg(((sizeof(DispatchStub) + sizeof(DispatchStubLong)) % sizeof(void*)) == 0); // TODO: This should be a static_assert_no_msg(), but there were reports of build failure with VS 2019 due to the expression - // not being a compile-time constant, see https://github.com/dotnet/coreclr/issues/22103 + // not being a compile-time constant, see https://github.com/dotnet/runtime/issues/11858 _ASSERTE((DispatchStubLong_offsetof_failLabel - DispatchStubLong_offsetof_failDisplBase) < INT8_MAX); // Common dispatch stub initialization diff --git a/src/coreclr/src/vm/argdestination.h b/src/coreclr/src/vm/argdestination.h index cc55fbeffe08..d4db4b6d4427 100644 --- a/src/coreclr/src/vm/argdestination.h +++ b/src/coreclr/src/vm/argdestination.h @@ -217,7 +217,7 @@ class ArgDestination { LIMITED_METHOD_CONTRACT; - // SPAN-TODO: GC reporting - https://github.com/dotnet/coreclr/issues/8517 + // SPAN-TODO: GC reporting - https://github.com/dotnet/runtime/issues/7103 _ASSERTE(IsStructPassedInRegs()); diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 962ba0d2298a..75bb51cca491 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -1372,7 +1372,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) // NOTE: We haven't stopped other threads at this point and nothing is stopping // callbacks from coming into the profiler even after Shutdown() has been called. - // See https://github.com/dotnet/coreclr/issues/22176 for an example of how that + // See https://github.com/dotnet/runtime/issues/11885 for an example of how that // happens. // // To prevent issues when profilers are attached we intentionally skip freeing the diff --git a/src/coreclr/src/vm/comwaithandle.cpp b/src/coreclr/src/vm/comwaithandle.cpp index 1756687fd32c..d43693e1d3b1 100644 --- a/src/coreclr/src/vm/comwaithandle.cpp +++ b/src/coreclr/src/vm/comwaithandle.cpp @@ -46,7 +46,7 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, HANDLE *handleArray, INT #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT // There are some issues with wait-all from an STA thread - // - https://github.com/dotnet/coreclr/issues/17787#issuecomment-385117537 + // - https://github.com/dotnet/runtime/issues/10243#issuecomment-385117537 if (waitForAll && numHandles > 1 && pThread->GetApartment() == Thread::AS_InSTA) { COMPlusThrow(kNotSupportedException, W("NotSupported_WaitAllSTAThread")); diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 9dc409db9ad5..dbf4ec793bf0 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -8942,7 +8942,7 @@ CORINFO_METHOD_HANDLE CEEInfo::resolveVirtualMethodHelper(CORINFO_METHOD_HANDLE // If we devirtualized into a default interface method on a generic type, we should actually return an // instantiating stub but this is not happening. - // Making this work is tracked by https://github.com/dotnet/coreclr/issues/15977 + // Making this work is tracked by https://github.com/dotnet/runtime/issues/9588 if (pDevirtMD->GetMethodTable()->IsInterface() && pDevirtMD->HasClassInstantiation()) { return nullptr; diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 666bb3bf2526..5e4dcf86ad5f 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -9588,7 +9588,7 @@ void MethodTableBuilder::CheckForSystemTypes() #ifdef CROSSGEN_COMPILE // Disable AOT compiling for the SIMD hardware intrinsic types. These types require special // ABI handling as they represent fundamental data types (__m64, __m128, and __m256) and not - // aggregate or union types. See https://github.com/dotnet/coreclr/issues/15943 + // aggregate or union types. See https://github.com/dotnet/runtime/issues/9578 // // Once they are properly handled according to the ABI requirements, we can remove this check // and allow them to be used in crossgen/AOT scenarios. diff --git a/src/coreclr/src/vm/stackwalk.cpp b/src/coreclr/src/vm/stackwalk.cpp index dcd2cb97e034..a13127e3c656 100644 --- a/src/coreclr/src/vm/stackwalk.cpp +++ b/src/coreclr/src/vm/stackwalk.cpp @@ -1507,7 +1507,7 @@ BOOL StackFrameIterator::IsValid(void) // and RedirectedThreadFrame on Windows] concurrently with GC stackwalking. // In normal case (no GCStress), after p/invoke, IL_STUB will check if GC is in progress and synchronize. // NOTE: This condition needs to be evaluated after the previous one to prevent a subtle race condition - // (https://github.com/dotnet/coreclr/issues/21581) + // (https://github.com/dotnet/runtime/issues/11678) bIsRealStartFrameUnchanged = bIsRealStartFrameUnchanged || ((GCStress::IsEnabled()) && (m_pRealStartFrame != NULL) && diff --git a/src/coreclr/tests/runtest.py b/src/coreclr/tests/runtest.py index 5914b332f8b8..76faa30edcf7 100755 --- a/src/coreclr/tests/runtest.py +++ b/src/coreclr/tests/runtest.py @@ -967,8 +967,8 @@ def run_tests(args, # Ideally, this code should be removed when we find a more robust way of running Xunit tests. # # References: - # * https://github.com/dotnet/coreclr/issues/20392 - # * https://github.com/dotnet/coreclr/issues/20594 + # * https://github.com/dotnet/runtime/issues/11232 + # * https://github.com/dotnet/runtime/issues/11320 # * https://github.com/xunit/xunit/issues/1842 # * https://github.com/xunit/xunit/pull/1846 # diff --git a/src/installer/tests/TestUtils/FileUtils.cs b/src/installer/tests/TestUtils/FileUtils.cs index f606fe3812db..8da68f684734 100644 --- a/src/installer/tests/TestUtils/FileUtils.cs +++ b/src/installer/tests/TestUtils/FileUtils.cs @@ -44,7 +44,7 @@ public static void DeleteFileIfPossible(string filePath) /// /// This is a drop-in replacement for File.Copy usages that rely on non-Windows platforms /// allowing a directory as a target path. This behavior was corrected in CoreFX: - /// https://github.com/dotnet/corefx/issues/36713 + /// https://github.com/dotnet/runtime/issues/29204 ///
public static void CopyIntoDirectory(string filePath, string directoryPath) { diff --git a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs index 45e8a6aea1d0..3e925778f570 100644 --- a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs +++ b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs @@ -25,7 +25,7 @@ public static bool TryGetDefaultValue(ParameterInfo parameter, out object? defau } catch (FormatException) when (parameter.ParameterType == typeof(DateTime)) { - // Workaround for https://github.com/dotnet/corefx/issues/12338 + // Workaround for https://github.com/dotnet/runtime/issues/18844 // If HasDefaultValue throws FormatException for DateTime // we expect it to have default value hasDefaultValue = true; @@ -39,7 +39,7 @@ public static bool TryGetDefaultValue(ParameterInfo parameter, out object? defau defaultValue = parameter.DefaultValue; } - // Workaround for https://github.com/dotnet/corefx/issues/11797 + // Workaround for https://github.com/dotnet/runtime/issues/18599 if (defaultValue == null && parameter.ParameterType.IsValueType) { defaultValue = CreateValueType(parameter.ParameterType); diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 83a2e140326c..068faae2a5dc 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -58,7 +58,7 @@ true + https://github.com/dotnet/runtime/issues/19584 is tracking cleaning this up --> true true diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/ArrayBufferWriter.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/ArrayBufferWriter.cs index 66229de0a1e5..c4511fdb6c3c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/ArrayBufferWriter.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/ArrayBufferWriter.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.DependencyModel { - // TODO: Remove once we have https://github.com/dotnet/corefx/issues/34894 + // TODO: Remove once we have https://github.com/dotnet/runtime/issues/28538 internal class ArrayBufferWriter : IBufferWriter, IDisposable { private byte[] _rentedBuffer; diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/UnifiedJsonReader.Utf8JsonReader.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/UnifiedJsonReader.Utf8JsonReader.cs index be196eb2411d..3d705dc91f3f 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/UnifiedJsonReader.Utf8JsonReader.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/UnifiedJsonReader.Utf8JsonReader.cs @@ -146,7 +146,7 @@ public bool ReadAsBoolean(bool defaultValue) private static Exception CreateUnexpectedException(ref Utf8JsonReader reader, string expected) { - // Replace with public API once https://github.com/dotnet/corefx/issues/34768 is fixed + // Replace with public API once https://github.com/dotnet/runtime/issues/28482 is fixed object boxedState = reader.CurrentState; long lineNumber = (long)(typeof(JsonReaderState).GetField("_lineNumber", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(boxedState) ?? -1); long bytePositionInLine = (long)(typeof(JsonReaderState).GetField("_bytePositionInLine", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(boxedState) ?? -1); diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Operators.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Operators.vb index 1db75e323aab..7de3b309d293 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Operators.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Operators.vb @@ -4570,7 +4570,7 @@ Namespace Microsoft.VisualBasic.CompilerServices Throw GetNoValidOperatorException(UserDefinedOperator.Modulus, Left, Right) End Function - ' To work around https://github.com/dotnet/coreclr/issues/8648 + ' To work around https://github.com/dotnet/runtime/issues/7141 Private Shared Function ModSByte(ByVal left As SByte, ByVal right As SByte) As Object Return left Mod right End Function diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs index df790a51b8d9..8801753992d6 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs @@ -233,7 +233,7 @@ public static void DeleteFile(string fullPath) case Interop.Error.EROFS: // EROFS means the file system is read-only // Need to manually check file existence - // github.com/dotnet/corefx/issues/21273 + // https://github.com/dotnet/runtime/issues/22382 Interop.ErrorInfo fileExistsError; // Input allows trailing separators in order to match Windows behavior diff --git a/src/libraries/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj b/src/libraries/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj index 4f1b286568d9..ecad955acd0f 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj @@ -12,7 +12,7 @@ + generate the right binding redirects when targeting Desktop. https://github.com/dotnet/runtime/issues/27470 --> true diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs index f8e8aa529e2c..bd90d0cc4bb0 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs @@ -160,7 +160,7 @@ private void ShutdownConnection(bool isAbort) } catch (ObjectDisposedException) { - // See https://github.com/dotnet/corefx/issues/40711, and potentially + // See https://github.com/dotnet/runtime/issues/30732, and potentially // catch additional exception types here if need demonstrates. } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs index 973ff1dc3b5b..65ac1d7aeecd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs @@ -652,7 +652,7 @@ private static uint GetMetadataLengthForProperty(PropertyAnalysis property) private static TypeCode GetTypeCodeExtended(Type parameterType) { // Guid is not part of TypeCode, we decided to use 17 to represent it, as it's the "free slot" - // see https://github.com/dotnet/coreclr/issues/16105#issuecomment-361749750 for more + // see https://github.com/dotnet/runtime/issues/9629#issuecomment-361749750 for more const TypeCode GuidTypeCode = (TypeCode)17; if (parameterType == typeof(Guid)) // Guid is not a part of TypeCode enum diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index fe3df674c114..a414c1c9d107 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -273,7 +273,7 @@ { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) // For .NET Core the roundtrip via a local is no longer needed see: -// https://github.com/dotnet/coreclr/issues/13341 +// https://github.com/dotnet/runtime/issues/8730 // and // https://github.com/dotnet/coreclr/pull/11218 #ifdef netcoreapp diff --git a/src/libraries/System.Text.Encoding.CodePages/pkg/System.Text.Encoding.CodePages.pkgproj b/src/libraries/System.Text.Encoding.CodePages/pkg/System.Text.Encoding.CodePages.pkgproj index 242238e9b455..5df72d916f2a 100644 --- a/src/libraries/System.Text.Encoding.CodePages/pkg/System.Text.Encoding.CodePages.pkgproj +++ b/src/libraries/System.Text.Encoding.CodePages/pkg/System.Text.Encoding.CodePages.pkgproj @@ -29,7 +29,7 @@ + generate the right binding redirects when targeting Desktop. https://github.com/dotnet/runtime/issues/27470 --> true diff --git a/src/libraries/System.Text.Encodings.Web/pkg/System.Text.Encodings.Web.pkgproj b/src/libraries/System.Text.Encodings.Web/pkg/System.Text.Encodings.Web.pkgproj index 0a2deb4ded6d..9cc15ac1ac7c 100644 --- a/src/libraries/System.Text.Encodings.Web/pkg/System.Text.Encodings.Web.pkgproj +++ b/src/libraries/System.Text.Encodings.Web/pkg/System.Text.Encodings.Web.pkgproj @@ -19,7 +19,7 @@ + generate the right binding redirects when targeting Desktop. https://github.com/dotnet/runtime/issues/27470 --> true diff --git a/src/libraries/System.Text.Json/docs/ReferenceHandling_spec.md b/src/libraries/System.Text.Json/docs/ReferenceHandling_spec.md index 9bfc8895f69b..869162cfba4c 100644 --- a/src/libraries/System.Text.Json/docs/ReferenceHandling_spec.md +++ b/src/libraries/System.Text.Json/docs/ReferenceHandling_spec.md @@ -359,7 +359,7 @@ Now, to read back those references, you have to use `MetadataPropertyHandling.De * This could break existing converters. For example, an array converter may expect the first token to be "[" but a preserved array starts with "{". * perhaps converters are more feasible with the JSON path implementation. * We will now accept that an array comes in valid format when starts with a curly brace "{"; below issue is related to guard against NRE when this happens: - * https://github.com/dotnet/corefx/issues/41839 + * https://github.com/dotnet/runtime/issues/31192 ## dojo toolkit (JavaScript framework) https://dojotoolkit.org/reference-guide/1.10/dojox/json/ref.html diff --git a/src/libraries/System.Text.Json/docs/SerializerProgrammingModel.md b/src/libraries/System.Text.Json/docs/SerializerProgrammingModel.md index 79ada33e5c06..503fbc3014f3 100644 --- a/src/libraries/System.Text.Json/docs/SerializerProgrammingModel.md +++ b/src/libraries/System.Text.Json/docs/SerializerProgrammingModel.md @@ -163,7 +163,7 @@ The `JsonSerializerOptions.PropertyNameCaseInsensitive` property specifies that Note that Json.NET is case-insensitive by default. ## Date Support -Dates are not part of JSON, so an internal converter is supplied. Dates are typically JSON strings. Currently there is an internal `DateTime` and `DateTimeOffset` converter that currently supports ISO 8601 formats. See https://github.com/dotnet/corefx/issues/34690 for more information. +Dates are not part of JSON, so an internal converter is supplied. Dates are typically JSON strings. Currently there is an internal `DateTime` and `DateTimeOffset` converter that currently supports ISO 8601 formats. See https://github.com/dotnet/runtime/issues/28459 for more information. If the internal converter is not sufficient, such as when the format has a custom format or is not ISO 8601 compatible, then a developer will be able to add a new value converter. diff --git a/src/libraries/System.Text.Json/roadmap/README.md b/src/libraries/System.Text.Json/roadmap/README.md index 55d415784fa4..b4283ce52cc4 100644 --- a/src/libraries/System.Text.Json/roadmap/README.md +++ b/src/libraries/System.Text.Json/roadmap/README.md @@ -83,7 +83,7 @@ coming from a `Pipe` (from within an async context) as a sequence of segments and pass that along. Like streams, providing a higher-level type can help with making the end-to-end usage easier for the user when dealing with pipes. -* A [stream <-> pipe adapter](https://github.com/dotnet/corefx/issues/27246) will help with the interoperability of these types +* A [stream <-> pipe adapter](https://github.com/dotnet/runtime/issues/25087) will help with the interoperability of these types in general. ## Out of Current Scope & Future Considerations diff --git a/src/libraries/System.Text.Json/tests/Serialization/Object.WriteTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Object.WriteTests.cs index 09a263c267d1..923440627a04 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Object.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Object.WriteTests.cs @@ -127,7 +127,7 @@ private class Polymorphic public object P3 => ""; } - // https://github.com/dotnet/corefx/issues/40979 + // https://github.com/dotnet/runtime/issues/30814 [Fact] public static void EscapingShouldntStackOverflow() { diff --git a/src/libraries/pkg/test/frameworkSettings/netstandard2.1/settings.targets b/src/libraries/pkg/test/frameworkSettings/netstandard2.1/settings.targets index 815786db5c51..1fbde1af9ed9 100644 --- a/src/libraries/pkg/test/frameworkSettings/netstandard2.1/settings.targets +++ b/src/libraries/pkg/test/frameworkSettings/netstandard2.1/settings.targets @@ -1,5 +1,5 @@ - + diff --git a/src/libraries/pkg/test/packageSettings/System.Buffers/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Buffers/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Buffers/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Buffers/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Diagnostics.DiagnosticSource/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Diagnostics.DiagnosticSource/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Diagnostics.DiagnosticSource/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Diagnostics.DiagnosticSource/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.IO.Packaging/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.IO.Packaging/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.IO.Packaging/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.IO.Packaging/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.ILGeneration/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.ILGeneration/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.ILGeneration/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.ILGeneration/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.Lightweight/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.Lightweight/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.Lightweight/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit.Lightweight/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Reflection.Emit/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Reflection.Emit/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Reflection.TypeExtensions/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Reflection.TypeExtensions/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Reflection.TypeExtensions/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Reflection.TypeExtensions/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Runtime.CompilerServices.Unsafe/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Runtime.CompilerServices.Unsafe/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Runtime.CompilerServices.Unsafe/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Runtime.CompilerServices.Unsafe/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Runtime.WindowsRuntime/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Runtime.WindowsRuntime/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Runtime.WindowsRuntime/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Runtime.WindowsRuntime/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Cng/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Cng/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Cng/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Cng/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.OpenSsl/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.OpenSsl/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.OpenSsl/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.OpenSsl/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Pkcs/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Pkcs/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Pkcs/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Security.Cryptography.Pkcs/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Security.Principal.Windows/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Security.Principal.Windows/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Security.Principal.Windows/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Security.Principal.Windows/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/pkg/test/packageSettings/System.Threading.Tasks.Extensions/netcoreapp1.0/workaroundDowngrade.targets b/src/libraries/pkg/test/packageSettings/System.Threading.Tasks.Extensions/netcoreapp1.0/workaroundDowngrade.targets index 183497464be9..2f4f96679a9c 100644 --- a/src/libraries/pkg/test/packageSettings/System.Threading.Tasks.Extensions/netcoreapp1.0/workaroundDowngrade.targets +++ b/src/libraries/pkg/test/packageSettings/System.Threading.Tasks.Extensions/netcoreapp1.0/workaroundDowngrade.targets @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/libraries/shims/ApiCompatBaseline.netcoreapp.netfx461.ignore.txt b/src/libraries/shims/ApiCompatBaseline.netcoreapp.netfx461.ignore.txt index 32abe286f9e8..b964c733e301 100644 --- a/src/libraries/shims/ApiCompatBaseline.netcoreapp.netfx461.ignore.txt +++ b/src/libraries/shims/ApiCompatBaseline.netcoreapp.netfx461.ignore.txt @@ -8,7 +8,7 @@ CannotMakeTypeAbstract : Type 'System.Runtime.InteropServices.RuntimeEnvironment CannotSealType : Type 'System.Runtime.InteropServices.RuntimeEnvironment' is sealed in the implementation but not sealed in the contract. MembersMustExist : Member 'System.Runtime.InteropServices.RuntimeEnvironment..ctor()' does not exist in the implementation but it does exist in the contract. -// Activator changed to static class intentionally. See here: https://github.com/dotnet/corefx/issues/11869 +// Activator changed to static class intentionally. See here: https://github.com/dotnet/runtime/issues/18630 CannotMakeTypeAbstract : Type 'System.Activator' is abstract in the implementation but is not abstract in the contract. // System.Drawing types changed to static intentionally. Change is source and binary compatible. https://github.com/dotnet/corefx/commit/ad215be2fa28a7d2f19a90c1ba04c50c3b677253 @@ -21,7 +21,7 @@ CannotMakeTypeAbstract : Type 'System.Drawing.SystemIcons' is abstract in the im CannotMakeTypeAbstract : Type 'System.Drawing.SystemPens' is abstract in the implementation but is not abstract in the contract. CannotMakeTypeAbstract : Type 'System.Drawing.BufferedGraphicsManager' is abstract in the implementation but is not abstract in the contract. -// Won't came back into netcoreapp. See here: https://github.com/dotnet/corefx/issues/18075 +// Won't came back into netcoreapp. See here: https://github.com/dotnet/runtime/issues/20974 MembersMustExist : Member 'System.ComponentModel.DataAnnotations.ValidationContext.ServiceContainer.get()' does not exist in the implementation but it does exist in the contract. // Debugger changed to static class intentionally. See here: https://github.com/dotnet/standard/commit/d5fbcbeeeb7f15102fdac111bc8d7d5d72c32036#diff-2856a41639a1f4feb4e95ae667e069b7R10012 @@ -36,10 +36,10 @@ TypesMustExist : Type 'System.Runtime.Remoting.Messaging.IRemotingFormatter' doe TypesMustExist : Type 'System.Xml.Serialization.SchemaImporter' does not exist in the implementation but it does exist in the contract. CannotRemoveBaseTypeOrInterface : Type 'System.Xml.Serialization.XmlSchemaImporter' does not inherit from base type 'System.Xml.Serialization.SchemaImporter' in the implementation but it does in the contract. -// IServiceProvider won't be implemented by SqlClientFactory. See here: https://github.com/dotnet/corefx/issues/17708 +// IServiceProvider won't be implemented by SqlClientFactory. See here: https://github.com/dotnet/runtime/issues/20832 CannotRemoveBaseTypeOrInterface : Type 'System.Data.SqlClient.SqlClientFactory' does not implement interface 'System.IServiceProvider' in the implementation but it does in the contract. -// DynData Win9x only. Not going to be implemented in any netcore versions. See here: https://github.com/dotnet/corefx/issues/15332 +// DynData Win9x only. Not going to be implemented in any netcore versions. See here: https://github.com/dotnet/runtime/issues/19972 MembersMustExist : Member 'Microsoft.Win32.RegistryKey Microsoft.Win32.Registry.DynData' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'Microsoft.Win32.RegistryHive Microsoft.Win32.RegistryHive.DynData' does not exist in the implementation but it does exist in the contract. @@ -63,12 +63,12 @@ MembersMustExist : Member 'System.Threading.Thread.CurrentContext.get()' does no // Debug.Listeners won't be implemented in netstandard20 and netcoreapp20. See here: https://github.com/dotnet/standard/issues/84 MembersMustExist : Member 'System.Diagnostics.Debug.Listeners.get()' does not exist in the implementation but it does exist in the contract. -// IsolatedStorage methods won't be implemented in netstandard20 and netcoreapp20. See here: https://github.com/dotnet/corefx/issues/18071 +// IsolatedStorage methods won't be implemented in netstandard20 and netcoreapp20. See here: https://github.com/dotnet/runtime/issues/20970 MembersMustExist : Member 'System.IO.IsolatedStorage.IsolatedStorage.GetPermission(System.Security.PermissionSet)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.IO.IsolatedStorage.IsolatedStorageFile.GetPermission(System.Security.PermissionSet)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.IO.IsolatedStorage.IsolatedStorageFile.GetStore(System.IO.IsolatedStorage.IsolatedStorageScope, System.Security.Policy.Evidence, System.Type, System.Security.Policy.Evidence, System.Type)' does not exist in the implementation but it does exist in the contract. -// Crypto types and members are sealed in netstandard and netcoreapp because they are sealed in Xamarin. https://github.com/dotnet/corefx/issues/17820 +// Crypto types and members are sealed in netstandard and netcoreapp because they are sealed in Xamarin. https://github.com/dotnet/runtime/issues/20870 CannotSealType : Type 'System.Security.Cryptography.SHA1Managed' is sealed in the implementation but not sealed in the contract. CannotMakeMemberNonVirtual : Member 'System.Security.Cryptography.SHA1Managed.HashCore(System.Byte[], System.Int32, System.Int32)' is non-virtual in the implementation but is virtual in the contract. CannotMakeMemberNonVirtual : Member 'System.Security.Cryptography.SHA1Managed.HashFinal()' is non-virtual in the implementation but is virtual in the contract. @@ -86,7 +86,7 @@ CannotMakeMemberNonVirtual : Member 'System.Security.Cryptography.SHA512Managed. CannotMakeMemberNonVirtual : Member 'System.Security.Cryptography.SHA512Managed.HashFinal()' is non-virtual in the implementation but is virtual in the contract. CannotMakeMemberNonVirtual : Member 'System.Security.Cryptography.SHA512Managed.Initialize()' is non-virtual in the implementation but is virtual in the contract. -// Can't build WindowsIdentities or WindowsPrincipals on non-Windows OSes. https://github.com/dotnet/corefx/issues/18073 +// Can't build WindowsIdentities or WindowsPrincipals on non-Windows OSes. https://github.com/dotnet/runtime/issues/20972 MembersMustExist : Member 'System.Security.Principal.IdentityReferenceCollection.IsReadOnly.get()' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.Security.Principal.WindowsIdentity..ctor(System.Security.Principal.WindowsIdentity)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.Security.Principal.WindowsIdentity..ctor(System.String, System.String)' does not exist in the implementation but it does exist in the contract. @@ -97,7 +97,7 @@ MembersMustExist : Member 'System.Security.Principal.WindowsIdentity.UserClaims. MembersMustExist : Member 'System.Security.Principal.WindowsPrincipal.DeviceClaims.get()' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.Security.Principal.WindowsPrincipal.UserClaims.get()' does not exist in the implementation but it does exist in the contract. -// Reflection.Emit future unclear and won't be implemented till netcoreapp20. See here: https://github.com/dotnet/corefx/issues/18072 +// Reflection.Emit future unclear and won't be implemented till netcoreapp20. See here: https://github.com/dotnet/runtime/issues/20971 MembersMustExist : Member 'System.Reflection.Emit.AssemblyBuilder.AddResourceFile(System.String, System.String)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.Reflection.Emit.AssemblyBuilder.AddResourceFile(System.String, System.String, System.Reflection.ResourceAttributes)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'System.Reflection.Emit.AssemblyBuilder.DefineDynamicModule(System.String, System.Boolean)' does not exist in the implementation but it does exist in the contract. diff --git a/src/mono/mono/tests/Makefile.am b/src/mono/mono/tests/Makefile.am index 6a3af788dfe4..8b689e9eb553 100755 --- a/src/mono/mono/tests/Makefile.am +++ b/src/mono/mono/tests/Makefile.am @@ -1741,7 +1741,7 @@ LLVM = $(filter --llvm, $(MONO_ENV_OPTIONS) $(AOT_BUILD_FLAGS)) # abort-try-holes.exe is flaky due to unwinding failure to the finally block when aborting # appdomain-marshalbyref-assemblyload.exe: https://bugzilla.xamarin.com/show_bug.cgi?id=49308 # threads-init.exe: runs out of system threads -# dim-constrainedcall.exe: fails on dontnet as well (https://github.com/dotnet/coreclr/issues/15353) +# dim-constrainedcall.exe: fails on dontnet as well (https://github.com/dotnet/runtime/issues/9378) # # tailcall-rgctxb.exe # tailcall-member-function-in-valuetype.exe diff --git a/src/mono/mono/utils/mono-threads-windows.c b/src/mono/mono/utils/mono-threads-windows.c index 8e94bf2db258..0ec80177326a 100644 --- a/src/mono/mono/utils/mono-threads-windows.c +++ b/src/mono/mono/utils/mono-threads-windows.c @@ -103,7 +103,7 @@ abort_apc (ULONG_PTR param) // thread is going away meaning that no more IO calls will be issued against the // same resource that was part of the cancelation. Current implementation of // .NET Framework and .NET Core currently don't support the ability to abort a thread -// blocked on sync IO calls, see https://github.com/dotnet/corefx/issues/5749. +// blocked on sync IO calls, see https://github.com/dotnet/runtime/issues/16236. // Since there is no solution covering all scenarios aborting blocking syscall this // will be on best effort and there might still be a slight risk that the blocking call // won't abort (depending on overlapped IO support for current file, socket). diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index 71e1a02fcb12..df4809fa7dc3 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -278,7 +278,7 @@ internal static bool IsTypeDefinition(RuntimeType type) // return false; // return true; - // It's like a workaround mentioned in https://github.com/dotnet/corefx/issues/17345 + // It's like a workaround mentioned in https://github.com/dotnet/runtime/issues/20711 return !type.HasElementType && !type.IsConstructedGenericType && !type.IsGenericParameter; } diff --git a/src/tests/Interop/SimpleStruct/SimpleStructManaged.cs b/src/tests/Interop/SimpleStruct/SimpleStructManaged.cs index 75ebb2d41dcb..1ddd292711c4 100644 --- a/src/tests/Interop/SimpleStruct/SimpleStructManaged.cs +++ b/src/tests/Interop/SimpleStruct/SimpleStructManaged.cs @@ -518,7 +518,7 @@ public static int Main(string[] argv) retVal = retVal && PosTest3(); retVal = retVal && AutoStructNegativeTest(); - // https://github.com/dotnet/coreclr/issues/4193 + // https://github.com/dotnet/runtime/issues/5552 // retVal = retVal && PosTest4(); if (!retVal) diff --git a/src/tests/JIT/Directed/RVAInit/simplearg.il b/src/tests/JIT/Directed/RVAInit/simplearg.il index 64975d7636cb..fe01ac88c314 100644 --- a/src/tests/JIT/Directed/RVAInit/simplearg.il +++ b/src/tests/JIT/Directed/RVAInit/simplearg.il @@ -2,7 +2,7 @@ // Microsoft (R) .NET Framework IL Disassembler. Version 4.7.3071.0 // Copyright (c) Microsoft Corporation. All rights reserved. -// This is a repro case for GitHub issue #15412 ( https://github.com/dotnet/coreclr/issues/15412 ) +// This is a repro case for GitHub issue #9401 ( https://github.com/dotnet/runtime/issues/9401 ) // Metadata version: v4.0.30319 .assembly extern mscorlib diff --git a/src/tests/JIT/Directed/StructPromote/Unsafe/AccessInvalidFieldOffset.cs b/src/tests/JIT/Directed/StructPromote/Unsafe/AccessInvalidFieldOffset.cs index fdb265e665bd..6b6b891160cf 100644 --- a/src/tests/JIT/Directed/StructPromote/Unsafe/AccessInvalidFieldOffset.cs +++ b/src/tests/JIT/Directed/StructPromote/Unsafe/AccessInvalidFieldOffset.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// The test came from https://github.com/dotnet/corefx/issues/20085. +// The test came from https://github.com/dotnet/runtime/issues/21860. // It tries to access field from a promoted struct with an offset that // is not valid for the promoted struct type. diff --git a/src/tests/JIT/Directed/StructPromote/Unsafe/ReadDoubleFromIntOffset.cs b/src/tests/JIT/Directed/StructPromote/Unsafe/ReadDoubleFromIntOffset.cs index 4ecf1afa2f60..03231db21f92 100644 --- a/src/tests/JIT/Directed/StructPromote/Unsafe/ReadDoubleFromIntOffset.cs +++ b/src/tests/JIT/Directed/StructPromote/Unsafe/ReadDoubleFromIntOffset.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// The test came from https://github.com/dotnet/corefx/issues/20085. +// The test came from https://github.com/dotnet/runtime/issues/21860. // It tests that we do access overlapping fields with the correct types. // Espessialy if the stuct was casted by 'Unsafe.As` from a promoted type // and the promoted type had another field on the same offset but with a different type/size. diff --git a/src/tests/JIT/Directed/StructPromote/Unsafe/ReadStructAsAnotherType.cs b/src/tests/JIT/Directed/StructPromote/Unsafe/ReadStructAsAnotherType.cs index fe84e739967b..ce853df7a295 100644 --- a/src/tests/JIT/Directed/StructPromote/Unsafe/ReadStructAsAnotherType.cs +++ b/src/tests/JIT/Directed/StructPromote/Unsafe/ReadStructAsAnotherType.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// The test came from https://github.com/dotnet/corefx/issues/20085. +// The test came from https://github.com/dotnet/runtime/issues/21860. // It tests that we do access overlapping fields with the correct types. // Espessialy if the stuct was casted by 'Unsafe.As` from a promoted type // and the promoted type had another field on the same offset but with a different type/size. diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj index 77183b15b86e..4e5e4f001a69 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj @@ -2,7 +2,7 @@ Exe true - + true diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj index 86f1d21221eb..5fdd9781e49a 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj @@ -4,7 +4,7 @@ true true - + true diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj index 46028d8e749e..e499a930f44d 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj @@ -2,7 +2,7 @@ Exe true - + true diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj index d52ca31f7192..62b615bb6358 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj @@ -2,7 +2,7 @@ Exe true - + true diff --git a/src/tests/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs b/src/tests/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs index 85f1e40f52ae..ac2f6baef3c0 100644 --- a/src/tests/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs +++ b/src/tests/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs @@ -170,7 +170,7 @@ public struct S20 public long z; public long w; } -/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. +/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. [StructLayout(LayoutKind.Sequential)] public struct S28 { @@ -184,7 +184,7 @@ public struct S29 public int x; public object y; } - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ public struct S30 { public long x; @@ -212,10 +212,10 @@ public struct S30 public delegate void MyCallback19(S19 s); public delegate void MyCallback20(S20 s); -/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. +/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. public delegate void MyCallback28(S28 s); public delegate void MyCallback29(S29 s); - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ public delegate void MyCallback30(S30 s1, S30 s2, S30 s3); [DllImport("jitstructtests_lib")] @@ -277,14 +277,14 @@ public struct S30 [DllImport("jitstructtests_lib")] public static extern void InvokeCallback20(MyCallback20 callback, S20 s); -/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. +/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. [DllImport("jitstructtests_lib")] public static extern void InvokeCallback28(MyCallback28 callback, S28 s); [DllImport("jitstructtests_lib")] public static extern void InvokeCallback29(MyCallback29 callback, S29 s); - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ [DllImport("jitstructtests_lib")] public static extern void InvokeCallback30(MyCallback30 callback, S30 s1, S30 s2, S30 s3); @@ -347,14 +347,14 @@ public struct S30 [DllImport("jitstructtests_lib")] public static extern S20 InvokeCallback20R(MyCallback20 callback, S20 s); -/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. +/* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. [DllImport("jitstructtests_lib")] public static extern S28 InvokeCallback28R(MyCallback28 callback, S28 s); [DllImport("jitstructtests_lib")] public static extern S29 InvokeCallback29R(MyCallback29 callback, S29 s); - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ static public int Main1() { Program3 p = new Program3(); @@ -641,7 +641,7 @@ static public int Main1() } }, s20); - /* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. + /* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. TestClass testClass = new TestClass(); S28 s28; s28.x = null; @@ -688,7 +688,7 @@ static public int Main1() throw new System.Exception(); } }, s29); - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ S30 s30; s30.x = 1; s30.y = 2; @@ -989,7 +989,7 @@ static public int Main1() { throw new System.Exception(); } - /* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. + /* These tests are not working on non Windows CoreCLR. Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. s28.x = null; S28 s28r = InvokeCallback28R((par) => { Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y); @@ -1048,7 +1048,7 @@ static public int Main1() { throw new System.Exception(); } - Enable this when https://github.com/dotnet/coreclr/issues/2076 is resolved. */ + Enable this when https://github.com/dotnet/runtime/issues/4680 is resolved. */ } catch (Exception e) { diff --git a/src/tests/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs b/src/tests/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs index e47b88dbf514..60d963d5a6b2 100644 --- a/src/tests/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs +++ b/src/tests/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs @@ -11,7 +11,7 @@ // does not call String.Format. Expectation is that they will have // similar performance. // -// See https://github.com/dotnet/coreclr/issues/7569 for context. +// See https://github.com/dotnet/runtime/issues/6796 for context. using Microsoft.Xunit.Performance; using System; diff --git a/src/tests/JIT/Performance/CodeQuality/Layout/SearchLoops.cs b/src/tests/JIT/Performance/CodeQuality/Layout/SearchLoops.cs index f22748838f3a..c0d059784231 100644 --- a/src/tests/JIT/Performance/CodeQuality/Layout/SearchLoops.cs +++ b/src/tests/JIT/Performance/CodeQuality/Layout/SearchLoops.cs @@ -9,7 +9,7 @@ [assembly: OptimizeForBenchmarks] -// Test code taken directly from https://github.com/dotnet/coreclr/issues/9692 +// Test code taken directly from https://github.com/dotnet/runtime/issues/7474 // Laying the loop's early return path in-line can cost 30% on this micro-benchmark. namespace Layout diff --git a/src/tests/JIT/Performance/CodeQuality/Span/SpanBench.cs b/src/tests/JIT/Performance/CodeQuality/Span/SpanBench.cs index 319e5f8dd4f6..85c96a376bd3 100644 --- a/src/tests/JIT/Performance/CodeQuality/Span/SpanBench.cs +++ b/src/tests/JIT/Performance/CodeQuality/Span/SpanBench.cs @@ -474,7 +474,7 @@ static void TestSpanConstructor(T[] array, int iterationCount, bool untrue) } #endregion -#if false // netcoreapp specific API https://github.com/dotnet/coreclr/issues/16126 +#if false // netcoreapp specific API https://github.com/dotnet/runtime/issues/9635 #region TestSpanCreate [Benchmark(InnerIterationCount = BaseIterations)] [InlineData(100)] diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_7508/Vector3Test.cs b/src/tests/JIT/Regression/JitBlue/GitHub_7508/Vector3Test.cs index 07044cf4e4a9..c222e45164ff 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_7508/Vector3Test.cs +++ b/src/tests/JIT/Regression/JitBlue/GitHub_7508/Vector3Test.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// Since https://github.com/dotnet/coreclr/issues/7508 was a performance issue, +// Since https://github.com/dotnet/runtime/issues/6775 was a performance issue, // there's not really a correctness test for this. // However, this is a very simple test that can be used to compare the code generated // for a non-accelerated vector of 3 floats, a "raw" Vector3 and a Vector3 diff --git a/src/tests/JIT/SIMD/Vector3GetHash.cs b/src/tests/JIT/SIMD/Vector3GetHash.cs index 0c0e25bb65b9..26d45fb97b90 100644 --- a/src/tests/JIT/SIMD/Vector3GetHash.cs +++ b/src/tests/JIT/SIMD/Vector3GetHash.cs @@ -4,9 +4,9 @@ // This was copied from corefx\src\System.Numerics.Vectors\tests\Vector3Tests.cs. // It exposed a bug in morph, in which a SIMD field was being morphed in // a MACK_Ind context, even though it was under a GT_IND(G_ADDR()). -// This was https://github.com/dotnet/corefx/issues/15713, and was "fixed" with -// https://github.com/dotnet/coreclr/issues/9496 and a new issue, -// https://github.com/dotnet/coreclr/issues/9518, has been filed to track the underlying unexpected +// This was https://github.com/dotnet/runtime/issues/20080, and was "fixed" with +// https://github.com/dotnet/coreclr/pull/9496 and a new issue, +// https://github.com/dotnet/runtime/issues/7405, has been filed to track the underlying unexpected // MACK_Ind context, which causes us to mark the Vector3 local as do-not-enregister. using System; diff --git a/src/tests/JIT/opt/FastTailCall/StructPassingSimple.cs b/src/tests/JIT/opt/FastTailCall/StructPassingSimple.cs index 7b070c4bd925..8752035c3670 100644 --- a/src/tests/JIT/opt/FastTailCall/StructPassingSimple.cs +++ b/src/tests/JIT/opt/FastTailCall/StructPassingSimple.cs @@ -13,7 +13,7 @@ public struct A class TailCallStructPassingSimple { // Simple tail call candidate that would be ignored on Arm64 and amd64 Unix - // due to https://github.com/dotnet/coreclr/issues/2666 + // due to https://github.com/dotnet/runtime/issues/4941 public static int ImplicitTailCallTenByteStruct(A a, int count=1000) { if (count-- == 0) diff --git a/src/tests/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.cs b/src/tests/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.cs index 639c44a333cb..0d2c1fb5b745 100644 --- a/src/tests/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.cs +++ b/src/tests/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.cs @@ -145,7 +145,7 @@ public static int Main() // The object is currently allocated on the stack when this method is jitted and on the heap when it's R2R-compiled. // The reason is that we always do the type check via helper in R2R mode, which blocks stack allocation. - // We don't have to use a helper in this case (even for R2R), https://github.com/dotnet/coreclr/issues/22086 tracks fixing that. + // We don't have to use a helper in this case (even for R2R), https://github.com/dotnet/runtime/issues/11850 tracks fixing that. CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckTypeNoHelper, 1, AllocationKind.Undefined); CallTestAndVerifyAllocation(AllocateClassWithGcFieldAndInt, 5, expectedAllocationKind); diff --git a/src/tests/JIT/opt/Structs/structpop.cs b/src/tests/JIT/opt/Structs/structpop.cs index a28a962a8aaf..f2e172cdac4d 100644 --- a/src/tests/JIT/opt/Structs/structpop.cs +++ b/src/tests/JIT/opt/Structs/structpop.cs @@ -4,7 +4,7 @@ // Optimization of pop with struct types // Codegen for TestByRef and TestByPtr should be similar // -// See https://github.com/dotnet/coreclr/issues/18710 +// See https://github.com/dotnet/runtime/issues/10607 using System; using System.Runtime.CompilerServices; diff --git a/src/tests/JIT/opt/Structs/structpop2.cs b/src/tests/JIT/opt/Structs/structpop2.cs index 16f2a2aa19c5..6453177b0e22 100644 --- a/src/tests/JIT/opt/Structs/structpop2.cs +++ b/src/tests/JIT/opt/Structs/structpop2.cs @@ -4,7 +4,7 @@ // Optimization of pop with struct types // Codegen for TestByPtr should be minimal // -// See https://github.com/dotnet/coreclr/issues/18710 +// See https://github.com/dotnet/runtime/issues/10607 using System; using System.Runtime.CompilerServices; diff --git a/src/tests/JIT/superpmi/superpmicollect.csproj b/src/tests/JIT/superpmi/superpmicollect.csproj index 86df61c4e9bc..8900206f9280 100644 --- a/src/tests/JIT/superpmi/superpmicollect.csproj +++ b/src/tests/JIT/superpmi/superpmicollect.csproj @@ -11,7 +11,7 @@ true true - + true diff --git a/src/tests/baseservices/threading/waithandle/waitall/nullarray.cs b/src/tests/baseservices/threading/waithandle/waitall/nullarray.cs index a2e2c3475cb1..b3042b287563 100644 --- a/src/tests/baseservices/threading/waithandle/waitall/nullarray.cs +++ b/src/tests/baseservices/threading/waithandle/waitall/nullarray.cs @@ -12,7 +12,7 @@ static int Main() // Console.WriteLine(Thread.CurrentThread.GetApartmentState()); - // Not supported (https://github.com/dotnet/coreclr/issues/2999) + // Not supported (https://github.com/dotnet/runtime/issues/5059) // AppDomain.CurrentDomain.UnhandledException += Unhandled; WaitHandle[] waitHandles = null; diff --git a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj index cfbf3c95a6e0..4c2276186a1d 100644 --- a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj +++ b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj @@ -5,7 +5,7 @@ 0 true - + true false diff --git a/src/tests/readytorun/determinism/crossgen2determinism.csproj b/src/tests/readytorun/determinism/crossgen2determinism.csproj index 7f1b93d2e203..3a53e327ff66 100644 --- a/src/tests/readytorun/determinism/crossgen2determinism.csproj +++ b/src/tests/readytorun/determinism/crossgen2determinism.csproj @@ -5,7 +5,7 @@ 0 true - + true false diff --git a/src/tests/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj b/src/tests/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj index 433fbf78c775..c8bb050f575b 100644 --- a/src/tests/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj +++ b/src/tests/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj @@ -5,7 +5,7 @@ true true 0 - + True diff --git a/src/tests/tracing/tracevalidation/inducedgc/inducedgc.csproj b/src/tests/tracing/tracevalidation/inducedgc/inducedgc.csproj index 48da17fdcadd..7b0b6f908f60 100644 --- a/src/tests/tracing/tracevalidation/inducedgc/inducedgc.csproj +++ b/src/tests/tracing/tracevalidation/inducedgc/inducedgc.csproj @@ -4,7 +4,7 @@ BuildAndRun 0 true - + true diff --git a/src/tests/tracing/tracevalidation/jittingstarted/JittingStarted.csproj b/src/tests/tracing/tracevalidation/jittingstarted/JittingStarted.csproj index 67b146cdfa92..5659ef2fb3d4 100644 --- a/src/tests/tracing/tracevalidation/jittingstarted/JittingStarted.csproj +++ b/src/tests/tracing/tracevalidation/jittingstarted/JittingStarted.csproj @@ -4,7 +4,7 @@ BuildAndRun 0 true - + true diff --git a/src/tests/tracing/tracevalidation/rundown/rundown.csproj b/src/tests/tracing/tracevalidation/rundown/rundown.csproj index 3a84775b8fef..0e92feee45be 100644 --- a/src/tests/tracing/tracevalidation/rundown/rundown.csproj +++ b/src/tests/tracing/tracevalidation/rundown/rundown.csproj @@ -4,7 +4,7 @@ BuildAndRun 0 true - + true From 1de41bbbc1c558448b9e160a50dcf5f1ec8bd7d7 Mon Sep 17 00:00:00 2001 From: Prashanth Govindarajan Date: Thu, 13 Aug 2020 14:17:00 -0700 Subject: [PATCH 470/755] Get index of first non ascii byte (#39506) * Arm64 intrinsics for GetIndexOfFirstNonAsciiByte * sq * sq * sq * sq * Last bit of formatting * Fix bug * Better naming * Compiler complains * Fix compile error * Address nit * Different variables * sq * Nits --- .../src/System/Text/ASCIIUtility.cs | 198 +++++++++++++++--- 1 file changed, 165 insertions(+), 33 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 0dde692dc68d..6a67e788216b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -42,6 +42,28 @@ private static bool AllCharsInUInt64AreAscii(ulong value) return (value & ~0x007F007F_007F007Ful) == 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int GetIndexOfFirstNonAsciiByteInLane_AdvSimd(Vector128 value, Vector128 bitmask) + { + if (!AdvSimd.Arm64.IsSupported || !BitConverter.IsLittleEndian) + { + throw new PlatformNotSupportedException(); + } + + // extractedBits[i] = (value[i] >> 7) & (1 << (12 * (i % 2))); + Vector128 mostSignificantBitIsSet = AdvSimd.ShiftRightArithmetic(value.AsSByte(), 7).AsByte(); + Vector128 extractedBits = AdvSimd.And(mostSignificantBitIsSet, bitmask); + + // collapse mask to lower bits + extractedBits = AdvSimd.Arm64.AddPairwise(extractedBits, extractedBits); + ulong mask = extractedBits.AsUInt64().ToScalar(); + + // calculate the index + int index = BitOperations.TrailingZeroCount(mask) >> 2; + Debug.Assert((mask != 0) ? index < 16 : index >= 16); + return index; + } + /// /// Given a DWORD which represents two packed chars in machine-endian order, /// iff the first char (in machine-endian order) is ASCII. @@ -67,8 +89,8 @@ public static unsafe nuint GetIndexOfFirstNonAsciiByte(byte* pBuffer, nuint buff // pmovmskb which we know are optimized, and (b) we can avoid downclocking the processor while // this method is running. - return (Sse2.IsSupported) - ? GetIndexOfFirstNonAsciiByte_Sse2(pBuffer, bufferLength) + return (Sse2.IsSupported || AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian) + ? GetIndexOfFirstNonAsciiByte_Intrinsified(pBuffer, bufferLength) : GetIndexOfFirstNonAsciiByte_Default(pBuffer, bufferLength); } @@ -215,17 +237,38 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Default(byte* pBuffer, n goto Finish; } - private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuint bufferLength) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool ContainsNonAsciiByte_Sse2(uint sseMask) + { + Debug.Assert(sseMask != uint.MaxValue); + Debug.Assert(Sse2.IsSupported); + return sseMask != 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool ContainsNonAsciiByte_AdvSimd(uint advSimdIndex) + { + Debug.Assert(advSimdIndex != uint.MaxValue); + Debug.Assert(AdvSimd.IsSupported); + return advSimdIndex < 16; + } + + private static unsafe nuint GetIndexOfFirstNonAsciiByte_Intrinsified(byte* pBuffer, nuint bufferLength) { // JIT turns the below into constants uint SizeOfVector128 = (uint)Unsafe.SizeOf>(); nuint MaskOfAllBitsInVector128 = (nuint)(SizeOfVector128 - 1); - Debug.Assert(Sse2.IsSupported, "Should've been checked by caller."); - Debug.Assert(BitConverter.IsLittleEndian, "SSE2 assumes little-endian."); + Debug.Assert(Sse2.IsSupported || AdvSimd.Arm64.IsSupported, "Sse2 or AdvSimd64 required."); + Debug.Assert(BitConverter.IsLittleEndian, "This SSE2/Arm64 implementation assumes little-endian."); + + Vector128 bitmask = BitConverter.IsLittleEndian ? + Vector128.Create((ushort)0x1001).AsByte() : + Vector128.Create((ushort)0x0110).AsByte(); - uint currentMask, secondMask; + uint currentSseMask = uint.MaxValue, secondSseMask = uint.MaxValue; + uint currentAdvSimdIndex = uint.MaxValue, secondAdvSimdIndex = uint.MaxValue; byte* pOriginalBuffer = pBuffer; // This method is written such that control generally flows top-to-bottom, avoiding @@ -240,11 +283,25 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin // Read the first vector unaligned. - currentMask = (uint)Sse2.MoveMask(Sse2.LoadVector128(pBuffer)); // unaligned load - - if (currentMask != 0) + if (Sse2.IsSupported) { - goto FoundNonAsciiDataInCurrentMask; + currentSseMask = (uint)Sse2.MoveMask(Sse2.LoadVector128(pBuffer)); // unaligned load + if (ContainsNonAsciiByte_Sse2(currentSseMask)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + } + else if (AdvSimd.Arm64.IsSupported) + { + currentAdvSimdIndex = (uint)GetIndexOfFirstNonAsciiByteInLane_AdvSimd(AdvSimd.LoadVector128(pBuffer), bitmask); // unaligned load + if (ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + } + else + { + throw new PlatformNotSupportedException(); } // If we have less than 32 bytes to process, just go straight to the final unaligned @@ -281,15 +338,33 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin do { - Vector128 firstVector = Sse2.LoadAlignedVector128(pBuffer); - Vector128 secondVector = Sse2.LoadAlignedVector128(pBuffer + SizeOfVector128); + if (Sse2.IsSupported) + { + Vector128 firstVector = Sse2.LoadAlignedVector128(pBuffer); + Vector128 secondVector = Sse2.LoadAlignedVector128(pBuffer + SizeOfVector128); - currentMask = (uint)Sse2.MoveMask(firstVector); - secondMask = (uint)Sse2.MoveMask(secondVector); + currentSseMask = (uint)Sse2.MoveMask(firstVector); + secondSseMask = (uint)Sse2.MoveMask(secondVector); + if (ContainsNonAsciiByte_Sse2(currentSseMask | secondSseMask)) + { + goto FoundNonAsciiDataInInnerLoop; + } + } + else if (AdvSimd.Arm64.IsSupported) + { + Vector128 firstVector = AdvSimd.LoadVector128(pBuffer); + Vector128 secondVector = AdvSimd.LoadVector128(pBuffer + SizeOfVector128); - if ((currentMask | secondMask) != 0) + currentAdvSimdIndex = (uint)GetIndexOfFirstNonAsciiByteInLane_AdvSimd(firstVector, bitmask); + secondAdvSimdIndex = (uint)GetIndexOfFirstNonAsciiByteInLane_AdvSimd(secondVector, bitmask); + if (ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex) || ContainsNonAsciiByte_AdvSimd(secondAdvSimdIndex)) + { + goto FoundNonAsciiDataInInnerLoop; + } + } + else { - goto FoundNonAsciiDataInInnerLoop; + throw new PlatformNotSupportedException(); } pBuffer += 2 * SizeOfVector128; @@ -313,10 +388,25 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin // At least one full vector's worth of data remains, so we can safely read it. // Remember, at this point pBuffer is still aligned. - currentMask = (uint)Sse2.MoveMask(Sse2.LoadAlignedVector128(pBuffer)); - if (currentMask != 0) + if (Sse2.IsSupported) { - goto FoundNonAsciiDataInCurrentMask; + currentSseMask = (uint)Sse2.MoveMask(Sse2.LoadAlignedVector128(pBuffer)); + if (ContainsNonAsciiByte_Sse2(currentSseMask)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + } + else if (AdvSimd.Arm64.IsSupported) + { + currentAdvSimdIndex = (uint)GetIndexOfFirstNonAsciiByteInLane_AdvSimd(AdvSimd.LoadVector128(pBuffer), bitmask); + if (ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + } + else + { + throw new PlatformNotSupportedException(); } IncrementCurrentOffsetBeforeFinalUnalignedVectorRead: @@ -332,17 +422,33 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin pBuffer += (bufferLength & MaskOfAllBitsInVector128) - SizeOfVector128; - currentMask = (uint)Sse2.MoveMask(Sse2.LoadVector128(pBuffer)); // unaligned load - if (currentMask != 0) + if (Sse2.IsSupported) { - goto FoundNonAsciiDataInCurrentMask; + currentSseMask = (uint)Sse2.MoveMask(Sse2.LoadVector128(pBuffer)); // unaligned load + if (ContainsNonAsciiByte_Sse2(currentSseMask)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + + } + else if (AdvSimd.Arm64.IsSupported) + { + currentAdvSimdIndex = (uint)GetIndexOfFirstNonAsciiByteInLane_AdvSimd(AdvSimd.LoadVector128(pBuffer), bitmask); // unaligned load + if (ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex)) + { + goto FoundNonAsciiDataInCurrentChunk; + } + + } + else + { + throw new PlatformNotSupportedException(); } pBuffer += SizeOfVector128; } Finish: - return (nuint)pBuffer - (nuint)pOriginalBuffer; // and we're done! FoundNonAsciiDataInInnerLoop: @@ -351,20 +457,46 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin // instead be the second mask. If so, skip the entire first mask and drain ASCII bytes // from the second mask. - if (currentMask == 0) + if (Sse2.IsSupported) { - pBuffer += SizeOfVector128; - currentMask = secondMask; + if (!ContainsNonAsciiByte_Sse2(currentSseMask)) + { + pBuffer += SizeOfVector128; + currentSseMask = secondSseMask; + } } + else if (AdvSimd.IsSupported) + { + if (!ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex)) + { + pBuffer += SizeOfVector128; + currentAdvSimdIndex = secondAdvSimdIndex; + } + } + else + { + throw new PlatformNotSupportedException(); + } + FoundNonAsciiDataInCurrentChunk: - FoundNonAsciiDataInCurrentMask: - - // The mask contains - from the LSB - a 0 for each ASCII byte we saw, and a 1 for each non-ASCII byte. - // Tzcnt is the correct operation to count the number of zero bits quickly. If this instruction isn't - // available, we'll fall back to a normal loop. - Debug.Assert(currentMask != 0, "Shouldn't be here unless we see non-ASCII data."); - pBuffer += (uint)BitOperations.TrailingZeroCount(currentMask); + if (Sse2.IsSupported) + { + // The mask contains - from the LSB - a 0 for each ASCII byte we saw, and a 1 for each non-ASCII byte. + // Tzcnt is the correct operation to count the number of zero bits quickly. If this instruction isn't + // available, we'll fall back to a normal loop. + Debug.Assert(ContainsNonAsciiByte_Sse2(currentSseMask), "Shouldn't be here unless we see non-ASCII data."); + pBuffer += (uint)BitOperations.TrailingZeroCount(currentSseMask); + } + else if (AdvSimd.Arm64.IsSupported) + { + Debug.Assert(ContainsNonAsciiByte_AdvSimd(currentAdvSimdIndex), "Shouldn't be here unless we see non-ASCII data."); + pBuffer += currentAdvSimdIndex; + } + else + { + throw new PlatformNotSupportedException(); + } goto Finish; From f63189de985a24093b2900a537fbb95d68d570ea Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 13 Aug 2020 14:55:47 -0700 Subject: [PATCH 471/755] Baseline API Compat errors due to attributes mismatch (#40787) --- .../ApiCompatBaseline.PreviousNetCoreApp.txt | 134 +++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index 078e32277bdf..6ae5fbcc47ec 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -5,6 +5,138 @@ CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.Diagnostics.ProcessStartInfo.Environment' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' on 'System.Diagnostics.ProcessStartInfo.Verb' changed from '[DefaultValueAttribute(null)]' in the contract to '[DefaultValueAttribute("")]' in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.Diagnostics.ProcessStartInfo.WindowStyle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.MarshalByValueComponent' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Constraint' in the contract but not the implementation. +CannotChangeAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' on 'System.Data.DataColumn.DataType' changed from '[DefaultValueAttribute(typeof(string))]' in the contract to '[DefaultValueAttribute(typeof(String))]' in the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataRelation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataViewSetting' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataColumnMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataTableMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.BooleanSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.TraceSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Includes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAll.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotated.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotation.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAttributeGroup.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaChoice.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.ContentModel' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.Constraints' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.SchemaType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaGroup.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Fields' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Selector' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaImport.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaInclude.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaRedefine.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSequence.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleType.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeList.ItemType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeUnion.BaseTypes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.MarshalByValueComponent' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.BooleanSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.TraceSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.MarshalByValueComponent' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Constraint' in the contract but not the implementation. +CannotChangeAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' on 'System.Data.DataColumn.DataType' changed from '[DefaultValueAttribute(typeof(string))]' in the contract to '[DefaultValueAttribute(typeof(String))]' in the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataRelation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataViewSetting' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataColumnMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataTableMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Constraint' in the contract but not the implementation. +CannotChangeAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' on 'System.Data.DataColumn.DataType' changed from '[DefaultValueAttribute(typeof(string))]' in the contract to '[DefaultValueAttribute(typeof(String))]' in the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataRelation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.DataViewSetting' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataColumnMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Data.Common.DataTableMapping' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.BooleanSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.SwitchLevelAttribute' exists on 'System.Diagnostics.TraceSwitch' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Includes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAll.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotated.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotation.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAttributeGroup.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaChoice.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.ContentModel' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.Constraints' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.SchemaType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaGroup.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Fields' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Selector' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaImport.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaInclude.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaRedefine.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSequence.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleType.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeList.ItemType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeUnion.BaseTypes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Includes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchema.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAll.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotated.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAnnotation.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaAttributeGroup.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaChoice.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentExtension.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexContentRestriction.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.ContentModel' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaComplexType.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.Constraints' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaElement.SchemaType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaGroup.Particle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Fields' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaIdentityConstraint.Selector' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaImport.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaInclude.Annotation' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaRedefine.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSequence.Items' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContent.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentExtension.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Attributes' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleContentRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleType.Content' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeList.ItemType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.BaseType' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeRestriction.Facets' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Xml.Serialization.XmlElementAttribute' exists on 'System.Xml.Schema.XmlSchemaSimpleTypeUnion.BaseTypes' in the contract but not the implementation. Compat issues with assembly System: CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.ComponentModel.BackgroundWorker.WorkerReportsProgress' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.DefaultValueAttribute' exists on 'System.ComponentModel.BackgroundWorker.WorkerSupportsCancellation' in the contract but not the implementation. @@ -35,4 +167,4 @@ CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Te CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonExtensionDataAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonIgnoreAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Text.Json.Serialization.JsonPropertyNameAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]' in the implementation. -Total Issues: 40 +Total Issues: 172 From c7c2a7ca29856fa0512e663345edcc911667fa9a Mon Sep 17 00:00:00 2001 From: Key Kim Date: Fri, 14 Aug 2020 06:58:13 +0900 Subject: [PATCH 472/755] Refactor redundant validating datetime length logic in System.Text.Json (#40759) * Remove redundant datetime length check TryParseDateTimeOffset always called after calling IsValidDateTimeOffsetParseLength function that checks datetime length is more than 10. (yyyy-mm-dd) * Resolve review that adding Assert * Remove duplicated assert from JsonHelpers * Add too short datetime invalid test cases --- .../src/System/Text/Json/JsonHelpers.Date.cs | 9 ++------- .../System.Text.Json/tests/JsonDateTimeTestData.cs | 11 +++++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs index 01cb5343f7ee..a4dc832223df 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs @@ -211,11 +211,8 @@ private static bool TryParseDateTimeOffset(ReadOnlySpan source, out DateTi { parseData = default; - // Source does not have enough characters for YYYY-MM-DD - if (source.Length < 10) - { - return false; - } + // too short datetime + Debug.Assert(source.Length >= 10); // Parse the calendar date // ----------------------- @@ -252,8 +249,6 @@ private static bool TryParseDateTimeOffset(ReadOnlySpan source, out DateTi } // We now have YYYY-MM-DD [dateX] - - Debug.Assert(source.Length >= 10); if (source.Length == 10) { // Just a calendar date diff --git a/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs b/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs index 99dae5a87f93..799f2abd0b40 100644 --- a/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs +++ b/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs @@ -105,6 +105,13 @@ public static IEnumerable ValidISO8601TestsWithUtcOffset() public static IEnumerable InvalidISO8601Tests() { + // Too short + yield return new object[] { "\"1997-07\"" }; + yield return new object[] { "\"1996\"" }; + yield return new object[] { "\"997-07-16\"" }; + yield return new object[] { "\"1997-07-6\"" }; + yield return new object[] { "\"1997-7-06\"" }; + // Invalid YYYY-MM-DD yield return new object[] { "\"0997 07-16\"" }; yield return new object[] { "\"0997-0a-16\"" }; @@ -115,12 +122,8 @@ public static IEnumerable InvalidISO8601Tests() yield return new object[] { "\"0997-07-16,0997-07-16\"" }; yield return new object[] { "\"1997-07-16T19:20abc\"" }; yield return new object[] { "\"1997-07-16T19:20, 123\"" }; - yield return new object[] { "\"997-07-16\"" }; - yield return new object[] { "\"1997-07\"" }; - yield return new object[] { "\"1997-7-06\"" }; yield return new object[] { "\"1997-07-16T\"" }; yield return new object[] { "\"1997-07-16*\"" }; - yield return new object[] { "\"1997-07-6\"" }; yield return new object[] { "\"1997-07-6T01\"" }; yield return new object[] { "\"1997-07-16Z\"" }; yield return new object[] { "\"1997-07-16+01:00\"" }; From 8192a11d93c3fb3cc193a3f61eda53a109d2c279 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Fri, 14 Aug 2020 01:23:07 +0300 Subject: [PATCH 473/755] [Browser] fallback to Invariant mode if mono_wasm_load_icu_data wasn't called (#40765) * don't try to locate icudt.dat automatically if mono_wasm_load_icu_data wasn't called --- .../pal_icushim_static.c | 13 +++++++------ .../Globalization/GlobalizationMode.Unix.cs | 15 +++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c index a2bf312fdee5..391cc43f0c4b 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c @@ -12,6 +12,7 @@ #include static int32_t isLoaded = 0; +static int32_t isDataSet = 0; static void log_icu_error(const char* name, UErrorCode status) { @@ -44,6 +45,7 @@ EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void * pData) //// see https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/tracing.md // utrace_setFunctions(0, 0, 0, icu_trace_data); // utrace_setLevel(UTRACE_VERBOSE); + isDataSet = 1; return 1; } } @@ -51,12 +53,11 @@ EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void * pData) int32_t GlobalizationNative_LoadICU(void) { - const char* icudir = getenv("DOTNET_ICU_DIR"); - if (icudir) - u_setDataDirectory(icudir); - else - ; // default ICU search path behavior will be used, see http://userguide.icu-project.org/icudata - + if (!isDataSet) { + // don't try to locate icudt.dat automatically if mono_wasm_load_icu_data wasn't called + // and fallback to invariant mode + return 0; + } UErrorCode status = 0; UVersionInfo version; // Request the CLDR version to perform basic ICU initialization and find out diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index cf9e9339e6ec..7d91ed4713a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -20,11 +20,18 @@ private static bool GetGlobalizationInvariantMode() { LoadAppLocalIcu(icuSuffixAndVersion); } - else if (Interop.Globalization.LoadICU() == 0) + else { - string message = "Couldn't find a valid ICU package installed on the system. " + - "Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support."; - Environment.FailFast(message); + int loaded = Interop.Globalization.LoadICU(); + if (loaded == 0 && !OperatingSystem.IsBrowser()) + { + string message = "Couldn't find a valid ICU package installed on the system. " + + "Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support."; + Environment.FailFast(message); + } + + // fallback to Invariant mode if LoadICU failed (Browser). + return loaded == 0; } } return invariantEnabled; From 1f36de113b13b899ab3448f885bc4dbb58abcf03 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 13 Aug 2020 16:54:32 -0700 Subject: [PATCH 474/755] Supressing NETStandard.Library package dependency for NET461 dependency groups (#40733) --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- eng/packaging.props | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8742e9ff0da4..7124df35356d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade ea8f37e8982dc22022b33c5e151081ad04d923a6 - + https://github.com/dotnet/arcade - ea8f37e8982dc22022b33c5e151081ad04d923a6 + 3d667df19da5f8d49406e5a00c2c5a95b12bd4fb https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 42b0bd0ca954..ca5a1fa20c2c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -56,7 +56,7 @@ 5.0.0-beta.20407.3 5.0.0-beta.20407.3 2.5.1-beta.20407.3 - 5.0.0-beta.20407.3 + 5.0.0-beta.20412.1 5.0.0-beta.20407.3 5.0.0-beta.20407.3 diff --git a/eng/packaging.props b/eng/packaging.props index 9db71c397b49..d723eddfea5a 100644 --- a/eng/packaging.props +++ b/eng/packaging.props @@ -72,5 +72,8 @@ Include="$(PkgDir)useSharedDesignerContext.txt"> true + + + From baaf591d6a02ef5685d2279897b1ddc6da8597f3 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Thu, 13 Aug 2020 17:35:16 -0700 Subject: [PATCH 475/755] Add matchLength-returning APIs to CompareInfo (#40752) --- .../Common/src/Interop/Interop.Collation.cs | 4 +- .../pal_collation.c | 67 ++++-- .../pal_collation.h | 6 +- .../pal_icushim_internal.h | 2 + .../pal_icushim_internal_android.h | 1 + .../CompareInfo/CompareInfoTests.IndexOf.cs | 227 ++++++++++-------- .../CompareInfo/CompareInfoTests.IsPrefix.cs | 126 ++++++---- .../CompareInfo/CompareInfoTests.IsSuffix.cs | 132 ++++++---- .../CompareInfoTests.LastIndexOf.cs | 186 ++++++++------ .../tests/Invariant/InvariantMode.cs | 108 ++++++++- .../System/Globalization/CompareInfo.Icu.cs | 54 +++-- .../System/Globalization/CompareInfo.Nls.cs | 28 ++- .../src/System/Globalization/CompareInfo.cs | 185 ++++++++++++-- .../src/System/String.Manipulation.cs | 5 +- .../src/System/Text/Utf8Span.Searching.cs | 4 +- .../System.Runtime/ref/System.Runtime.cs | 4 + .../tests/System/StringTests.cs | 5 + 17 files changed, 798 insertions(+), 346 deletions(-) diff --git a/src/libraries/Common/src/Interop/Interop.Collation.cs b/src/libraries/Common/src/Interop/Interop.Collation.cs index e352149d27e0..40e1821d1092 100644 --- a/src/libraries/Common/src/Interop/Interop.Collation.cs +++ b/src/libraries/Common/src/Interop/Interop.Collation.cs @@ -32,11 +32,11 @@ internal static partial class Globalization [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern unsafe bool StartsWith(IntPtr sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options); + internal static extern unsafe bool StartsWith(IntPtr sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options, int* matchedLength); [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern unsafe bool EndsWith(IntPtr sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options); + internal static extern unsafe bool EndsWith(IntPtr sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options, int* matchedLength); [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.c index 6317f1da8d00..c75d68ae9953 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.c @@ -492,7 +492,7 @@ int32_t GlobalizationNative_IndexOf( result = GlobalizationNative_CompareString(pSortHandle, lpTarget, cwTargetLength, lpSource, cwSourceLength, options); if (result == UCOL_EQUAL && pMatchedLength != NULL) { - *pMatchedLength = cwTargetLength; + *pMatchedLength = cwSourceLength; } return (result == UCOL_EQUAL) ? 0 : -1; @@ -551,7 +551,7 @@ int32_t GlobalizationNative_LastIndexOf( result = GlobalizationNative_CompareString(pSortHandle, lpTarget, cwTargetLength, lpSource, cwSourceLength, options); if (result == UCOL_EQUAL && pMatchedLength != NULL) { - *pMatchedLength = cwTargetLength; + *pMatchedLength = cwSourceLength; } return (result == UCOL_EQUAL) ? 0 : -1; @@ -689,13 +689,14 @@ static int32_t GetCollationElementMask(UColAttributeValue strength) } } -static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator, UCollationElements* pSourceIterator, UColAttributeValue strength, int32_t forwardSearch) +static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator, UCollationElements* pSourceIterator, UColAttributeValue strength, int32_t forwardSearch, int32_t* pCapturedOffset) { assert(strength >= UCOL_SECONDARY); UErrorCode errorCode = U_ZERO_ERROR; int32_t movePattern = TRUE, moveSource = TRUE; int32_t patternElement = UCOL_IGNORABLE, sourceElement = UCOL_IGNORABLE; + int32_t capturedOffset = 0; int32_t collationElementMask = GetCollationElementMask(strength); @@ -707,6 +708,10 @@ static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator } if (moveSource) { + if (pCapturedOffset != NULL) + { + capturedOffset = ucol_getOffset(pSourceIterator); // need to capture offset before advancing iterator + } sourceElement = forwardSearch ? ucol_next(pSourceIterator, &errorCode) : ucol_previous(pSourceIterator, &errorCode); } movePattern = TRUE; moveSource = TRUE; @@ -715,11 +720,11 @@ static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator { if (sourceElement == UCOL_NULLORDER) { - return TRUE; // source is equal to pattern, we have reached both ends|beginnings at the same time + goto ReturnTrue; // source is equal to pattern, we have reached both ends|beginnings at the same time } else if (sourceElement == UCOL_IGNORABLE) { - return TRUE; // the next|previous character in source is an ignorable character, an example: "o\u0000".StartsWith("o") + goto ReturnTrue; // the next|previous character in source is an ignorable character, an example: "o\u0000".StartsWith("o") } else if (forwardSearch && ((sourceElement & UCOL_PRIMARYORDERMASK) == 0) && (sourceElement & UCOL_SECONDARYORDERMASK) != 0) { @@ -727,7 +732,7 @@ static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator } else { - return TRUE; + goto ReturnTrue; } } else if (patternElement == UCOL_IGNORABLE) @@ -743,9 +748,16 @@ static int32_t inline SimpleAffix_Iterators(UCollationElements* pPatternIterator return FALSE; } } + +ReturnTrue: + if (pCapturedOffset != NULL) + { + *pCapturedOffset = capturedOffset; + } + return TRUE; } -static int32_t SimpleAffix(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength, int32_t forwardSearch) +static int32_t SimpleAffix(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength, int32_t forwardSearch, int32_t* pMatchedLength) { int32_t result = FALSE; @@ -757,7 +769,15 @@ static int32_t SimpleAffix(const UCollator* pCollator, UErrorCode* pErrorCode, c { UColAttributeValue strength = ucol_getStrength(pCollator); - result = SimpleAffix_Iterators(pPatternIterator, pSourceIterator, strength, forwardSearch); + int32_t capturedOffset = 0; + result = SimpleAffix_Iterators(pPatternIterator, pSourceIterator, strength, forwardSearch, (pMatchedLength != NULL) ? &capturedOffset : NULL); + + if (result && pMatchedLength != NULL) + { + // depending on whether we're searching forward or backward, the matching substring + // is [start of source string .. curIdx] or [curIdx .. end of source string] + *pMatchedLength = (forwardSearch) ? capturedOffset : (textLength - capturedOffset); + } ucol_closeElements(pSourceIterator); } @@ -768,7 +788,7 @@ static int32_t SimpleAffix(const UCollator* pCollator, UErrorCode* pErrorCode, c return result; } -static int32_t ComplexStartsWith(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength) +static int32_t ComplexStartsWith(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength, int32_t* pMatchedLength) { int32_t result = FALSE; @@ -786,6 +806,12 @@ static int32_t ComplexStartsWith(const UCollator* pCollator, UErrorCode* pErrorC { result = CanIgnoreAllCollationElements(pCollator, pText, idx); } + + if (result && pMatchedLength != NULL) + { + // adjust matched length to account for all the elements we implicitly consumed at beginning of string + *pMatchedLength = idx + usearch_getMatchedLength(pSearch); + } } usearch_close(pSearch); @@ -803,9 +829,9 @@ int32_t GlobalizationNative_StartsWith( int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, - int32_t options) + int32_t options, + int32_t* pMatchedLength) { - UErrorCode err = U_ZERO_ERROR; const UCollator* pCollator = GetCollatorFromSortHandle(pSortHandle, options, &err); @@ -815,15 +841,15 @@ int32_t GlobalizationNative_StartsWith( } else if (options > CompareOptionsIgnoreCase) { - return ComplexStartsWith(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength); + return ComplexStartsWith(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, pMatchedLength); } else { - return SimpleAffix(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, TRUE); + return SimpleAffix(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, TRUE, pMatchedLength); } } -static int32_t ComplexEndsWith(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength) +static int32_t ComplexEndsWith(const UCollator* pCollator, UErrorCode* pErrorCode, const UChar* pPattern, int32_t patternLength, const UChar* pText, int32_t textLength, int32_t* pMatchedLength) { int32_t result = FALSE; @@ -846,6 +872,12 @@ static int32_t ComplexEndsWith(const UCollator* pCollator, UErrorCode* pErrorCod result = CanIgnoreAllCollationElements(pCollator, pText + matchEnd, remainingStringLength); } + + if (result && pMatchedLength != NULL) + { + // adjust matched length to account for all the elements we implicitly consumed at end of string + *pMatchedLength = textLength - idx; + } } usearch_close(pSearch); @@ -863,7 +895,8 @@ int32_t GlobalizationNative_EndsWith( int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, - int32_t options) + int32_t options, + int32_t* pMatchedLength) { UErrorCode err = U_ZERO_ERROR; const UCollator* pCollator = GetCollatorFromSortHandle(pSortHandle, options, &err); @@ -874,11 +907,11 @@ int32_t GlobalizationNative_EndsWith( } else if (options > CompareOptionsIgnoreCase) { - return ComplexEndsWith(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength); + return ComplexEndsWith(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, pMatchedLength); } else { - return SimpleAffix(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, FALSE); + return SimpleAffix(pCollator, &err, lpTarget, cwTargetLength, lpSource, cwSourceLength, FALSE, pMatchedLength); } } diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.h index e31a779175cd..64aa8f195342 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.h +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_collation.h @@ -50,14 +50,16 @@ PALEXPORT int32_t GlobalizationNative_StartsWith(SortHandle* pSortHandle, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, - int32_t options); + int32_t options, + int32_t* pMatchedLength); PALEXPORT int32_t GlobalizationNative_EndsWith(SortHandle* pSortHandle, const UChar* lpTarget, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, - int32_t options); + int32_t options, + int32_t* pMatchedLength); PALEXPORT int32_t GlobalizationNative_GetSortKey(SortHandle* pSortHandle, const UChar* lpStr, diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h index 46d8064b2d1a..abe0f38ec0e4 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h @@ -73,6 +73,7 @@ PER_FUNCTION_BLOCK(ucal_set, libicui18n) \ PER_FUNCTION_BLOCK(ucol_close, libicui18n) \ PER_FUNCTION_BLOCK(ucol_closeElements, libicui18n) \ + PER_FUNCTION_BLOCK(ucol_getOffset, libicui18n) \ PER_FUNCTION_BLOCK(ucol_getRules, libicui18n) \ PER_FUNCTION_BLOCK(ucol_getSortKey, libicui18n) \ PER_FUNCTION_BLOCK(ucol_getStrength, libicui18n) \ @@ -199,6 +200,7 @@ FOR_ALL_ICU_FUNCTIONS #define ucal_set(...) ucal_set_ptr(__VA_ARGS__) #define ucol_close(...) ucol_close_ptr(__VA_ARGS__) #define ucol_closeElements(...) ucol_closeElements_ptr(__VA_ARGS__) +#define ucol_getOffset(...) ucol_getOffset_ptr(__VA_ARGS__) #define ucol_getRules(...) ucol_getRules_ptr(__VA_ARGS__) #define ucol_getSortKey(...) ucol_getSortKey_ptr(__VA_ARGS__) #define ucol_getStrength(...) ucol_getStrength_ptr(__VA_ARGS__) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h index b07088537e6f..15ce08db2af6 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h @@ -438,6 +438,7 @@ UCalendar * ucal_open(const UChar * zoneID, int32_t len, const char * locale, UC void ucal_set(UCalendar * cal, UCalendarDateFields field, int32_t value); void ucol_close(UCollator * coll); void ucol_closeElements(UCollationElements * elems); +int32_t ucol_getOffset(const UCollationElements *elems); const UChar * ucol_getRules(const UCollator * coll, int32_t * length); int32_t ucol_getSortKey(const UCollator * coll, const UChar * source, int32_t sourceLength, uint8_t * result, int32_t resultLength); UCollationStrength ucol_getStrength(const UCollator * coll); diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IndexOf.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IndexOf.cs index 9a83e22a2551..ba030eb0d4af 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IndexOf.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IndexOf.cs @@ -12,6 +12,7 @@ public class CompareInfoIndexOfTests { private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; private static CompareInfo s_currentCompare = CultureInfo.CurrentCulture.CompareInfo; + private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; private static CompareInfo s_slovakCompare = new CultureInfo("sk-SK").CompareInfo; @@ -19,102 +20,117 @@ public class CompareInfoIndexOfTests public static IEnumerable IndexOf_TestData() { // Empty string - yield return new object[] { s_invariantCompare, "foo", "", 0, 3, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "foo", "", 2, 1, CompareOptions.None, 2 }; - yield return new object[] { s_invariantCompare, "", "", 0, 0, CompareOptions.None, 0 }; + yield return new object[] { s_invariantCompare, "foo", "", 0, 3, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "foo", "", 2, 1, CompareOptions.None, 2, 0 }; + yield return new object[] { s_invariantCompare, "", "", 0, 0, CompareOptions.None, 0, 0 }; // OrdinalIgnoreCase - yield return new object[] { s_invariantCompare, "Hello", "l", 0, 5, CompareOptions.OrdinalIgnoreCase, 2 }; - yield return new object[] { s_invariantCompare, "Hello", "L", 0, 5, CompareOptions.OrdinalIgnoreCase, 2 }; - yield return new object[] { s_invariantCompare, "Hello", "h", 0, 5, CompareOptions.OrdinalIgnoreCase, 0 }; + yield return new object[] { s_invariantCompare, "Hello", "l", 0, 5, CompareOptions.OrdinalIgnoreCase, 2, 1 }; + yield return new object[] { s_invariantCompare, "Hello", "L", 0, 5, CompareOptions.OrdinalIgnoreCase, 2, 1 }; + yield return new object[] { s_invariantCompare, "Hello", "h", 0, 5, CompareOptions.OrdinalIgnoreCase, 0, 1 }; // Long strings - yield return new object[] { s_invariantCompare, new string('b', 100) + new string('a', 5555), "aaaaaaaaaaaaaaa", 0, 5655, CompareOptions.None, 100 }; - yield return new object[] { s_invariantCompare, new string('b', 101) + new string('a', 5555), new string('a', 5000), 0, 5656, CompareOptions.None, 101 }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", 0, 5555, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, new string('b', 100) + new string('a', 5555), "aaaaaaaaaaaaaaa", 0, 5655, CompareOptions.None, 100, 15 }; + yield return new object[] { s_invariantCompare, new string('b', 101) + new string('a', 5555), new string('a', 5000), 0, 5656, CompareOptions.None, 101, 5000 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", 0, 5555, CompareOptions.None, -1, 0 }; // Hungarian - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.Ordinal, -1 }; + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.Ordinal, -1, 0 }; // Slovak - yield return new object[] { s_slovakCompare, "ch", "h", 0, 2, CompareOptions.None, -1 }; - yield return new object[] { s_slovakCompare, "chodit hore", "HO", 0, 11, CompareOptions.IgnoreCase, 7 }; - yield return new object[] { s_slovakCompare, "chh", "h", 0, 3, CompareOptions.None, 2 }; + yield return new object[] { s_slovakCompare, "ch", "h", 0, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_slovakCompare, "chodit hore", "HO", 0, 11, CompareOptions.IgnoreCase, 7, 2 }; + yield return new object[] { s_slovakCompare, "chh", "h", 0, 3, CompareOptions.None, 2, 1 }; // Turkish - yield return new object[] { s_turkishCompare, "Hi", "I", 0, 2, CompareOptions.None, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "I", 0, 2, CompareOptions.IgnoreCase, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", 0, 2, CompareOptions.None, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", 0, 2, CompareOptions.IgnoreCase, 1 }; - yield return new object[] { s_invariantCompare, "Hi", "I", 0, 2, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Hi", "I", 0, 2, CompareOptions.IgnoreCase, 1 }; - yield return new object[] { s_invariantCompare, "Hi", "\u0130", 0, 2, CompareOptions.IgnoreCase, -1 }; + yield return new object[] { s_turkishCompare, "Hi", "I", 0, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "I", 0, 2, CompareOptions.IgnoreCase, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", 0, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", 0, 2, CompareOptions.IgnoreCase, 1, 1 }; + yield return new object[] { s_invariantCompare, "Hi", "I", 0, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Hi", "I", 0, 2, CompareOptions.IgnoreCase, 1, 1 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", 0, 2, CompareOptions.IgnoreCase, -1, 0 }; // Unicode - yield return new object[] { s_invariantCompare, "Hi", "\u0130", 0, 2, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 0, 9, CompareOptions.None, 8 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 0, 9, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.IgnoreCase, 8 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.OrdinalIgnoreCase, -1 }; - yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 0, 6, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 0, 11, CompareOptions.IgnoreNonSpace, 4 }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", 0, 2, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", 0, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 0, 9, CompareOptions.None, 8, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 0, 9, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.IgnoreCase, 8, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.OrdinalIgnoreCase, -1, 0 }; + yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 0, 6, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 0, 11, CompareOptions.IgnoreNonSpace, 4, 7 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", 0, 2, CompareOptions.None, -1, 0 }; // Weightless characters - yield return new object[] { s_invariantCompare, "", "\u200d", 0, 0, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "hello", "\u200d", 1, 3, CompareOptions.IgnoreCase, 1 }; + yield return new object[] { s_invariantCompare, "", "\u200d", 0, 0, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "hello", "\u200d", 1, 3, CompareOptions.IgnoreCase, 1, 0 }; // Ignore symbols - yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.IgnoreSymbols, 5 }; - yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 0, 13, CompareOptions.None, 2 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.IgnoreSymbols, 5, 6 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 0, 13, CompareOptions.None, 2, 2 }; // Ordinal should be case-sensitive - yield return new object[] { s_currentCompare, "a", "a", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "a", "A", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "abc", "aBc", 0, 3, CompareOptions.Ordinal, -1 }; + yield return new object[] { s_currentCompare, "a", "a", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "a", "A", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "abc", "aBc", 0, 3, CompareOptions.Ordinal, -1, 0 }; // Ordinal with numbers and symbols - yield return new object[] { s_currentCompare, "a", "1", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "1", "1", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "1", "!", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "a", "-", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "-", "-", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "-", "!", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "!", "!", 0, 1, CompareOptions.Ordinal, 0 }; + yield return new object[] { s_currentCompare, "a", "1", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "1", "1", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "1", "!", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "a", "-", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "-", "-", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "-", "!", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "!", "!", 0, 1, CompareOptions.Ordinal, 0, 1 }; // Ordinal with unicode - yield return new object[] { s_currentCompare, "\uFF21", "\uFE57", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\uFE57", "\uFF21", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\uFF21", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\uFE57", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "a", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "a\u0400Bc", "a", 0, 4, CompareOptions.Ordinal, 0 }; + yield return new object[] { s_currentCompare, "\uFF21", "\uFE57", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\uFE57", "\uFF21", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\uFF21", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\uFE57", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "a", "a\u0400Bc", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "a\u0400Bc", "a", 0, 4, CompareOptions.Ordinal, 0, 1 }; // Ordinal with I or i (American and Turkish) - yield return new object[] { s_currentCompare, "I", "i", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "I", "I", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "i", "I", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "i", "i", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "I", "\u0130", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\u0130", "I", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "i", "\u0130", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\u0130", "i", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "I", "\u0131", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\0131", "I", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "i", "\u0131", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\u0131", "i", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\u0130", "\u0130", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "\u0131", "\u0131", 0, 1, CompareOptions.Ordinal, 0 }; - yield return new object[] { s_currentCompare, "\u0130", "\u0131", 0, 1, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_currentCompare, "\u0131", "\u0130", 0, 1, CompareOptions.Ordinal, -1 }; + yield return new object[] { s_currentCompare, "I", "i", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "I", "I", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "i", "I", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "i", "i", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "I", "\u0130", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\u0130", "I", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "i", "\u0130", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\u0130", "i", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "I", "\u0131", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\0131", "I", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "i", "\u0131", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\u0131", "i", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\u0130", "\u0130", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "\u0131", "\u0131", 0, 1, CompareOptions.Ordinal, 0, 1 }; + yield return new object[] { s_currentCompare, "\u0130", "\u0131", 0, 1, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_currentCompare, "\u0131", "\u0130", 0, 1, CompareOptions.Ordinal, -1, 0 }; // Platform differences - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.None, PlatformDetection.IsNlsGlobalization ? 5 : -1}; + if (PlatformDetection.IsNlsGlobalization) + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.None, 5, 7 }; + } + else + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.None, -1, 0 }; + } + + // Inputs where matched length does not equal value string length + yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 0, 8, CompareOptions.IgnoreNonSpace, 3, 2 }; + yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 0, 7, CompareOptions.IgnoreNonSpace, 3, 1 }; + yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 0, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 4, 7 }; + yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 0, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 }; + yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 0, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 4, 6 }; + yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 0, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 }; } public static IEnumerable IndexOf_Aesc_Ligature_TestData() @@ -122,43 +138,43 @@ public static IEnumerable IndexOf_Aesc_Ligature_TestData() bool useNls = PlatformDetection.IsNlsGlobalization; // Searches for the ligature \u00C6 string source1 = "Is AE or ae the same as \u00C6 or \u00E6?"; - yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.None, useNls ? 24 : -1}; - yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.None, useNls ? 9 : -1}; - yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.Ordinal, 9 }; - yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.Ordinal, 24 }; - yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.IgnoreCase, 9 }; - yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.IgnoreCase, 9 }; - yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.IgnoreCase, useNls ? 9 : 24 }; - yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.IgnoreCase, useNls ? 9 : 24 }; + yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.None, useNls ? 24 : -1, useNls ? 1 : 0}; + yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.None, 9 , 2}; + yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.None, useNls ? 9 : -1, useNls ? 2 : 0}; + yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.Ordinal, 9, 2 }; + yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.Ordinal, 24, 1 }; + yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source1, "AE", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; + yield return new object[] { s_invariantCompare, source1, "ae", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; + yield return new object[] { s_invariantCompare, source1, "\u00C6", 8, 18, CompareOptions.IgnoreCase, useNls ? 9 : 24, useNls ? 2 : 1 }; + yield return new object[] { s_invariantCompare, source1, "\u00E6", 8, 18, CompareOptions.IgnoreCase, useNls ? 9 : 24, useNls ? 2 : 1 }; } public static IEnumerable IndexOf_U_WithDiaeresis_TestData() { // Searches for the combining character sequence Latin capital letter U with diaeresis or Latin small letter u with diaeresis. string source = "Is \u0055\u0308 or \u0075\u0308 the same as \u00DC or \u00FC?"; - yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.Ordinal, 9 }; - yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.Ordinal, 24 }; - yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.IgnoreCase, 9 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.IgnoreCase, 9 }; - yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.IgnoreCase, 9 }; - yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.IgnoreCase, 9 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.None, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.None, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.Ordinal, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.Ordinal, 24, 1 }; + yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "\u00DC", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "\u00FC", 8, 18, CompareOptions.IgnoreCase, 9, 2 }; } [Theory] [MemberData(nameof(IndexOf_TestData))] [MemberData(nameof(IndexOf_Aesc_Ligature_TestData))] [MemberData(nameof(IndexOf_U_WithDiaeresis_TestData))] - public void IndexOf_String(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected) + public void IndexOf_String(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected, int expectedMatchLength) { if (value.Length == 1) { @@ -200,9 +216,9 @@ public void IndexOf_String(CompareInfo compareInfo, string source, string value, // Now test the span-based versions - use BoundedMemory to detect buffer overruns - RunSpanIndexOfTest(compareInfo, source.AsSpan(startIndex, count), value, options, (expected < 0) ? expected : expected - startIndex); + RunSpanIndexOfTest(compareInfo, source.AsSpan(startIndex, count), value, options, (expected < 0) ? expected : expected - startIndex, expectedMatchLength); - static void RunSpanIndexOfTest(CompareInfo compareInfo, ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, int expected) + static void RunSpanIndexOfTest(CompareInfo compareInfo, ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, int expected, int expectedMatchLength) { using BoundedMemory sourceBoundedMemory = BoundedMemory.AllocateFromExistingData(source); sourceBoundedMemory.MakeReadonly(); @@ -211,6 +227,8 @@ static void RunSpanIndexOfTest(CompareInfo compareInfo, ReadOnlySpan sourc valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); + Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); if (TryCreateRuneFrom(value, out Rune rune)) { @@ -251,8 +269,9 @@ private static void IndexOf_Char(CompareInfo compareInfo, string source, char va public void IndexOf_UnassignedUnicode() { bool useNls = PlatformDetection.IsNlsGlobalization; - IndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 0, 6, CompareOptions.None, useNls ? 0 : -1); - IndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 0, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1); + int expectedMatchLength = (useNls) ? 6 : 0; + IndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 0, 6, CompareOptions.None, useNls ? 0 : -1, expectedMatchLength); + IndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 0, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1, expectedMatchLength); } [Fact] @@ -292,6 +311,8 @@ public void IndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', CompareOptions.StringSort)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'b', 0, CompareOptions.StringSort)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'c', 0, 2, CompareOptions.StringSort)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.StringSort)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.StringSort, out _)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", 0, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); @@ -299,6 +320,8 @@ public void IndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'b', 0, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'c', 0, 2, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth, out _)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", 0, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); @@ -306,6 +329,8 @@ public void IndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'b', 0, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'c', 0, 2, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth, out _)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", 0, (CompareOptions)(-1))); @@ -313,6 +338,8 @@ public void IndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', 0, (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', 0, 2, (CompareOptions)(-1))); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), (CompareOptions)(-1))); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), (CompareOptions)(-1), out _)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", "Tests", 0, (CompareOptions)0x11111111)); @@ -320,6 +347,8 @@ public void IndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', 0, (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'a', 0, 2, (CompareOptions)0x11111111)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), (CompareOptions)0x11111111)); + AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), (CompareOptions)0x11111111, out _)); // StartIndex < 0 AssertExtensions.Throws("startIndex", () => s_invariantCompare.IndexOf("Test", "Test", -1, CompareOptions.None)); diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs index 4ed168407059..067f1403d918 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsPrefix.cs @@ -10,6 +10,7 @@ namespace System.Globalization.Tests public class CompareInfoIsPrefixTests { private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; + private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; private static CompareInfo s_frenchCompare = new CultureInfo("fr-FR").CompareInfo; @@ -17,81 +18,101 @@ public class CompareInfoIsPrefixTests public static IEnumerable IsPrefix_TestData() { // Empty strings - yield return new object[] { s_invariantCompare, "foo", "", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "", "", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "foo", "", CompareOptions.None, true, 0 }; + yield return new object[] { s_invariantCompare, "", "", CompareOptions.None, true, 0 }; // Long strings - yield return new object[] { s_invariantCompare, new string('a', 5555), "aaaaaaaaaaaaaaa", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000), CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", CompareOptions.None, false }; + yield return new object[] { s_invariantCompare, new string('a', 5555), "aaaaaaaaaaaaaaa", CompareOptions.None, true, 15 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000), CompareOptions.None, true, 5000 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", CompareOptions.None, false, 0 }; // Hungarian - yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false }; - yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "dz", "d", CompareOptions.None, true }; - yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.None, false }; - yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.Ordinal, true }; + yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "dz", "d", CompareOptions.None, true, 1 }; + yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.None, false, 0 }; + yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.Ordinal, true, 1 }; // Turkish - yield return new object[] { s_turkishCompare, "interesting", "I", CompareOptions.None, false }; - yield return new object[] { s_turkishCompare, "interesting", "I", CompareOptions.IgnoreCase, false }; - yield return new object[] { s_turkishCompare, "interesting", "\u0130", CompareOptions.None, false }; - yield return new object[] { s_turkishCompare, "interesting", "\u0130", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "interesting", "I", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "interesting", "I", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "interesting", "\u0130", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "interesting", "\u0130", CompareOptions.IgnoreCase, false }; + yield return new object[] { s_turkishCompare, "interesting", "I", CompareOptions.None, false, 0 }; + yield return new object[] { s_turkishCompare, "interesting", "I", CompareOptions.IgnoreCase, false, 0 }; + yield return new object[] { s_turkishCompare, "interesting", "\u0130", CompareOptions.None, false, 0 }; + yield return new object[] { s_turkishCompare, "interesting", "\u0130", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "interesting", "I", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "interesting", "I", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "interesting", "\u0130", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "interesting", "\u0130", CompareOptions.IgnoreCase, false, 0 }; // Unicode - yield return new object[] { s_invariantCompare, "\u00C0nimal", "A\u0300", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "\u00C0nimal", "A\u0300", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.OrdinalIgnoreCase, false }; - yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, true }; - yield return new object[] { s_invariantCompare, "o\u0000\u0308", "o", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "A\u0300", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "A\u0300", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 }; + yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, true, 1 }; + yield return new object[] { s_invariantCompare, "o\u0000\u0308", "o", CompareOptions.None, true, 1 }; // Weightless comparisons - yield return new object[] { s_invariantCompare, "", "\u200d", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "", "\u200d", CompareOptions.None, true, 0 }; + yield return new object[] { s_invariantCompare, "\u200dxy", "x", CompareOptions.None, true, 2 }; // Surrogates - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.Ordinal, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.OrdinalIgnoreCase, true }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.None, true, 2 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.IgnoreCase, true, 2 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.Ordinal, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.OrdinalIgnoreCase, true, 1 }; // Malformed Unicode - Invalid Surrogates (there is nothing special about them, they don't have a special treatment) - yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 }; // Ignore symbols - yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.IgnoreSymbols, true }; - yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.None, false }; + yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; + yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.None, false, 0 }; // Platform differences bool useNls = PlatformDetection.IsNlsGlobalization; - yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, useNls ? true : false }; - yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, useNls ? true : false }; - yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, useNls ? true : false }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.None, useNls ? true : false }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.IgnoreCase, useNls ? true : false }; + if (useNls) + { + yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, true, 7 }; + yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, true, 7 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.IgnoreCase, true, 1 }; + } + else + { + yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, false, 0 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800", CompareOptions.IgnoreCase, false, 0 }; + } // ICU bugs // UInt16 overflow: https://unicode-org.atlassian.net/browse/ICU-20832 fixed in https://github.com/unicode-org/icu/pull/840 (ICU 65) if (useNls || PlatformDetection.ICUVersion.Major >= 65) { - yield return new object[] { s_frenchCompare, "b", new string('a', UInt16.MaxValue + 1), CompareOptions.None, false }; + yield return new object[] { s_frenchCompare, "b", new string('a', UInt16.MaxValue + 1), CompareOptions.None, false, 0 }; } + + // Prefixes where matched length does not equal value string length + yield return new object[] { s_invariantCompare, "dzxyz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 }; + yield return new object[] { s_invariantCompare, "\u01F3xyz", "dz", CompareOptions.IgnoreNonSpace, true, 1 }; + yield return new object[] { s_germanCompare, "Strasse xyz", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_germanCompare, "Strasse xyz", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; + yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 }; + yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; } [Theory] [MemberData(nameof(IsPrefix_TestData))] - public void IsPrefix(CompareInfo compareInfo, string source, string value, CompareOptions options, bool expected) + public void IsPrefix(CompareInfo compareInfo, string source, string value, CompareOptions options, bool expected, int expectedMatchLength) { if (options == CompareOptions.None) { @@ -115,14 +136,17 @@ public void IsPrefix(CompareInfo compareInfo, string source, string value, Compa valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); + Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); } [Fact] public void IsPrefix_UnassignedUnicode() { bool result = PlatformDetection.IsNlsGlobalization ? true : false; - IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result); - IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result); + int expectedMatchLength = (result) ? 6 : 0; + IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength); + IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength); } [Fact] @@ -147,5 +171,11 @@ public void IsPrefix_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IsPrefix("Test's", "Tests", (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.IsPrefix("Test's", "Tests", (CompareOptions)0x11111111)); } + + [Fact] + public void IsPrefix_WithEmptyPrefix_DoesNotValidateOptions() + { + IsPrefix(s_invariantCompare, "Hello", "", (CompareOptions)(-1), true, 0); + } } } diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs index 361f399f7b12..4c5fe8d6b5c5 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.IsSuffix.cs @@ -10,6 +10,7 @@ namespace System.Globalization.Tests public class CompareInfoIsSuffixTests { private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; + private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; private static CompareInfo s_frenchCompare = new CultureInfo("fr-FR").CompareInfo; @@ -18,82 +19,100 @@ public class CompareInfoIsSuffixTests public static IEnumerable IsSuffix_TestData() { // Empty strings - yield return new object[] { s_invariantCompare, "foo", "", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "", "", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "foo", "", CompareOptions.None, true, 0 }; + yield return new object[] { s_invariantCompare, "", "", CompareOptions.None, true, 0 }; // Long strings - yield return new object[] { s_invariantCompare, new string('a', 5555), "aaaaaaaaaaaaaaa", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000), CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", CompareOptions.None, false }; + yield return new object[] { s_invariantCompare, new string('a', 5555), "aaaaaaaaaaaaaaa", CompareOptions.None, true, 15 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000), CompareOptions.None, true, 5000 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", CompareOptions.None, false, 0 }; // Hungarian - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "dz", "z", CompareOptions.None, true }; - yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.None, false }; - yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.Ordinal, true }; + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "dz", "z", CompareOptions.None, true, 1 }; + yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.None, false, 0 }; + yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.Ordinal, true, 1 }; // Slovak - yield return new object[] { s_slovakCompare, "ch", "h", CompareOptions.None, false }; - yield return new object[] { s_slovakCompare, "velmi chora", "hora", CompareOptions.None, false }; - yield return new object[] { s_slovakCompare, "chh", "H", CompareOptions.IgnoreCase, true }; + yield return new object[] { s_slovakCompare, "ch", "h", CompareOptions.None, false, 0 }; + yield return new object[] { s_slovakCompare, "velmi chora", "hora", CompareOptions.None, false, 0 }; + yield return new object[] { s_slovakCompare, "chh", "H", CompareOptions.IgnoreCase, true, 1 }; // Turkish - yield return new object[] { s_turkishCompare, "Hi", "I", CompareOptions.None, false }; - yield return new object[] { s_turkishCompare, "Hi", "I", CompareOptions.IgnoreCase, false }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", CompareOptions.None, false }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "Hi", "I", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "Hi", "I", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "Hi", "\u0130", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "Hi", "\u0130", CompareOptions.IgnoreCase, false }; + yield return new object[] { s_turkishCompare, "Hi", "I", CompareOptions.None, false, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "I", CompareOptions.IgnoreCase, false, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", CompareOptions.None, false, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "Hi", "I", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "Hi", "I", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", CompareOptions.IgnoreCase, false, 0 }; // Unicode - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, false }; - yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, false }; - yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.Ordinal, true }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.IgnoreCase, true, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 }; + yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, false, 0 }; + yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.Ordinal, true, 1 }; // Weightless comparisons - yield return new object[] { s_invariantCompare, "", "\u200d", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "", "\u200d", CompareOptions.None, true, 0 }; + yield return new object[] { s_invariantCompare, "xy\u200d", "y", CompareOptions.None, true, 2 }; // Surrogates - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.IgnoreCase, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.Ordinal, true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.OrdinalIgnoreCase, true }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.None, true, 2 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uD800\uDC00", CompareOptions.IgnoreCase, true, 2 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.Ordinal, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.OrdinalIgnoreCase, true, 1 }; // Malformed Unicode - Invalid Surrogates (there is nothing special about them, they don't have a special treatment) - yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true }; + yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 }; // Ignore symbols - yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.IgnoreSymbols, true }; - yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.None, false }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.IgnoreSymbols, true, 6 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.None, false, 0 }; // NULL character - yield return new object[] { s_invariantCompare, "a\u0000b", "a\u0000b", CompareOptions.None, true }; - yield return new object[] { s_invariantCompare, "a\u0000b", "b\u0000b", CompareOptions.None, false }; + yield return new object[] { s_invariantCompare, "a\u0000b", "a\u0000b", CompareOptions.None, true, 3 }; + yield return new object[] { s_invariantCompare, "a\u0000b", "b\u0000b", CompareOptions.None, false, 0 }; // Platform differences - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, PlatformDetection.IsIcuGlobalization ? false : true }; - yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, PlatformDetection.IsIcuGlobalization ? false : true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.None, PlatformDetection.IsIcuGlobalization ? false : true }; - yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.IgnoreCase, PlatformDetection.IsIcuGlobalization ? false : true }; + if (PlatformDetection.IsNlsGlobalization) + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, true, 7 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.None, true, 1 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.IgnoreCase, true, 1 }; + } else + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, false, 0 }; + yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.None, false, 0 }; + yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.IgnoreCase, false, 0 }; + } + + // Suffixes where matched length does not equal value string length + yield return new object[] { s_invariantCompare, "xyzdz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 }; + yield return new object[] { s_invariantCompare, "xyz\u01F3", "dz", CompareOptions.IgnoreNonSpace, true, 1 }; + yield return new object[] { s_germanCompare, "xyz Strasse", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 }; + yield return new object[] { s_germanCompare, "xyz Strasse", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; + yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 }; + yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 }; } [Theory] [MemberData(nameof(IsSuffix_TestData))] - public void IsSuffix(CompareInfo compareInfo, string source, string value, CompareOptions options, bool expected) + public void IsSuffix(CompareInfo compareInfo, string source, string value, CompareOptions options, bool expected, int expectedMatchLength) { if (options == CompareOptions.None) { @@ -117,15 +136,18 @@ public void IsSuffix(CompareInfo compareInfo, string source, string value, Compa valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); + Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); } [Fact] public void IsSuffix_UnassignedUnicode() { bool result = PlatformDetection.IsIcuGlobalization ? false : true; + int expectedMatchLength = (result) ? 6 : 0; - IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result); - IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result); + IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength); + IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength); } [Fact] @@ -150,5 +172,11 @@ public void IsSuffix_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.IsSuffix("Test's", "Tests", (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.IsSuffix("Test's", "Tests", (CompareOptions)0x11111111)); } + + [Fact] + public void IsSuffix_WithEmptyPrefix_DoesNotValidateOptions() + { + IsSuffix(s_invariantCompare, "Hello", "", (CompareOptions)(-1), true, 0); + } } } diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.LastIndexOf.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.LastIndexOf.cs index 31d5e5061943..3481c6c3f581 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.LastIndexOf.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.LastIndexOf.cs @@ -11,6 +11,7 @@ namespace System.Globalization.Tests public class CompareInfoLastIndexOfTests { private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; + private static CompareInfo s_germanCompare = new CultureInfo("de-DE").CompareInfo; private static CompareInfo s_hungarianCompare = new CultureInfo("hu-HU").CompareInfo; private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; private static CompareInfo s_slovakCompare = new CultureInfo("sk-SK").CompareInfo; @@ -20,79 +21,93 @@ public static IEnumerable LastIndexOf_TestData() bool useNls = PlatformDetection.IsNlsGlobalization; // Empty strings - yield return new object[] { s_invariantCompare, "foo", "", 2, 3, CompareOptions.None, 3 }; - yield return new object[] { s_invariantCompare, "", "", 0, 0, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "", "a", 0, 0, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "", "", -1, 0, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "", "a", -1, 0, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "", "", 0, -1, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "", "a", 0, -1, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, "foo", "", 2, 3, CompareOptions.None, 3, 0 }; + yield return new object[] { s_invariantCompare, "", "", 0, 0, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "", "a", 0, 0, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "", "", -1, 0, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "", "a", -1, 0, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "", "", 0, -1, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "", "a", 0, -1, CompareOptions.None, -1, 0 }; // Start index = source.Length - yield return new object[] { s_invariantCompare, "Hello", "l", 5, 5, CompareOptions.None, 3 }; - yield return new object[] { s_invariantCompare, "Hello", "b", 5, 5, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Hello", "l", 5, 0, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, "Hello", "l", 5, 5, CompareOptions.None, 3, 1 }; + yield return new object[] { s_invariantCompare, "Hello", "b", 5, 5, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Hello", "l", 5, 0, CompareOptions.None, -1, 0 }; - yield return new object[] { s_invariantCompare, "Hello", "", 5, 5, CompareOptions.None, 5 }; - yield return new object[] { s_invariantCompare, "Hello", "", 5, 0, CompareOptions.None, 5 }; + yield return new object[] { s_invariantCompare, "Hello", "", 5, 5, CompareOptions.None, 5, 0 }; + yield return new object[] { s_invariantCompare, "Hello", "", 5, 0, CompareOptions.None, 5, 0 }; // OrdinalIgnoreCase - yield return new object[] { s_invariantCompare, "Hello", "l", 4, 5, CompareOptions.OrdinalIgnoreCase, 3 }; - yield return new object[] { s_invariantCompare, "Hello", "L", 4, 5, CompareOptions.OrdinalIgnoreCase, 3 }; - yield return new object[] { s_invariantCompare, "Hello", "h", 4, 5, CompareOptions.OrdinalIgnoreCase, 0 }; + yield return new object[] { s_invariantCompare, "Hello", "l", 4, 5, CompareOptions.OrdinalIgnoreCase, 3, 1 }; + yield return new object[] { s_invariantCompare, "Hello", "L", 4, 5, CompareOptions.OrdinalIgnoreCase, 3, 1 }; + yield return new object[] { s_invariantCompare, "Hello", "h", 4, 5, CompareOptions.OrdinalIgnoreCase, 0, 1 }; // Long strings - yield return new object[] { s_invariantCompare, new string('a', 5555) + new string('b', 100), "aaaaaaaaaaaaaaa", 5654, 5655, CompareOptions.None, 5540 }; - yield return new object[] { s_invariantCompare, new string('b', 101) + new string('a', 5555), new string('a', 5000), 5655, 5656, CompareOptions.None, 656 }; - yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", 5554, 5555, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, new string('a', 5555) + new string('b', 100), "aaaaaaaaaaaaaaa", 5654, 5655, CompareOptions.None, 5540, 15 }; + yield return new object[] { s_invariantCompare, new string('b', 101) + new string('a', 5555), new string('a', 5000), 5655, 5656, CompareOptions.None, 656, 5000 }; + yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5000) + "b", 5554, 5555, CompareOptions.None, -1, 0 }; // Hungarian - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.Ordinal, -1 }; + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.Ordinal, -1, 0 }; // Slovak - yield return new object[] { s_slovakCompare, "ch", "h", 0, 1, CompareOptions.None, -1 }; - yield return new object[] { s_slovakCompare, "hore chodit", "HO", 11, 12, CompareOptions.IgnoreCase, 0 }; - yield return new object[] { s_slovakCompare, "chh", "h", 2, 2, CompareOptions.None, 2 }; + yield return new object[] { s_slovakCompare, "ch", "h", 0, 1, CompareOptions.None, -1, 0 }; + yield return new object[] { s_slovakCompare, "hore chodit", "HO", 11, 12, CompareOptions.IgnoreCase, 0, 2 }; + yield return new object[] { s_slovakCompare, "chh", "h", 2, 2, CompareOptions.None, 2, 1 }; // Turkish - yield return new object[] { s_turkishCompare, "Hi", "I", 1, 2, CompareOptions.None, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "I", 1, 2, CompareOptions.IgnoreCase, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", 1, 2, CompareOptions.None, -1 }; - yield return new object[] { s_turkishCompare, "Hi", "\u0130", 1, 2, CompareOptions.IgnoreCase, 1 }; + yield return new object[] { s_turkishCompare, "Hi", "I", 1, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "I", 1, 2, CompareOptions.IgnoreCase, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", 1, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_turkishCompare, "Hi", "\u0130", 1, 2, CompareOptions.IgnoreCase, 1, 1 }; - yield return new object[] { s_invariantCompare, "Hi", "I", 1, 2, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Hi", "I", 1, 2, CompareOptions.IgnoreCase, 1 }; - yield return new object[] { s_invariantCompare, "Hi", "\u0130", 1, 2, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Hi", "\u0130", 1, 2, CompareOptions.IgnoreCase, -1 }; + yield return new object[] { s_invariantCompare, "Hi", "I", 1, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Hi", "I", 1, 2, CompareOptions.IgnoreCase, 1, 1 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", 1, 2, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Hi", "\u0130", 1, 2, CompareOptions.IgnoreCase, -1, 0 }; // Unicode - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 8, 9, CompareOptions.None, 8 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 8, 9, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.IgnoreCase, 8 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.OrdinalIgnoreCase, -1 }; - yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 5, 6, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 10, 11, CompareOptions.IgnoreNonSpace, 4 }; - yield return new object[] { s_invariantCompare, "o\u0308", "o", 1, 2, CompareOptions.None, -1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 8, 9, CompareOptions.None, 8, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "A\u0300", 8, 9, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.IgnoreCase, 8, 1 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.OrdinalIgnoreCase, -1, 0 }; + yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 5, 6, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 10, 11, CompareOptions.IgnoreNonSpace, 4, 7 }; + yield return new object[] { s_invariantCompare, "o\u0308", "o", 1, 2, CompareOptions.None, -1, 0 }; // Weightless characters // NLS matches weightless characters at the end of the string // ICU matches weightless characters at 1 index prior to the end of the string - yield return new object[] { s_invariantCompare, "", "\u200d", 0, 0, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "", "\u200d", -1, 0, CompareOptions.None, 0 }; - yield return new object[] { s_invariantCompare, "hello", "\u200d", 4, 5, CompareOptions.IgnoreCase, useNls ? 5 : 4 }; + yield return new object[] { s_invariantCompare, "", "\u200d", 0, 0, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "", "\u200d", -1, 0, CompareOptions.None, 0, 0 }; + yield return new object[] { s_invariantCompare, "hello", "\u200d", 4, 5, CompareOptions.IgnoreCase, useNls ? 5 : 4 , 0}; // Ignore symbols - yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.IgnoreSymbols, 5 }; - yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.None, -1 }; - yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 12, 13, CompareOptions.None, 10 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.IgnoreSymbols, 5, 6 }; + yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.None, -1, 0 }; + yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 12, 13, CompareOptions.None, 10, 2 }; // Platform differences - yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.None, PlatformDetection.IsNlsGlobalization ? 5 : -1 }; + if (PlatformDetection.IsNlsGlobalization) + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.None, 5, 7 }; + } + else + { + yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", 11, 12, CompareOptions.None, -1, 0 }; + } + // Inputs where matched length does not equal value string length + yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 7, 8, CompareOptions.IgnoreNonSpace, 3, 2 }; + yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 6, 7, CompareOptions.IgnoreNonSpace, 3, 1 }; + yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 22, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 12, 7 }; + yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 22, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 }; + yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 20, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 11, 6 }; + yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 20, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 }; } public static IEnumerable LastIndexOf_Aesc_Ligature_TestData() @@ -101,42 +116,42 @@ public static IEnumerable LastIndexOf_Aesc_Ligature_TestData() // Searches for the ligature \u00C6 string source = "Is AE or ae the same as \u00C6 or \u00E6?"; - yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.None, useNls ? 24 : -1 }; - yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.None, useNls ? 9 : -1 }; - yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.Ordinal, 9 }; - yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.Ordinal, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.IgnoreCase, useNls ? 24 : 9 }; - yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.IgnoreCase, useNls ? 24 : 9 }; - yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.IgnoreCase, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.IgnoreCase, 24 }; + yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.None, useNls ? 24 : -1, useNls ? 1 : 0 }; + yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.None, 9, 2 }; + yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.None, useNls ? 9 : -1, useNls ? 2 : 0 }; + yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.Ordinal, 9, 2 }; + yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.Ordinal, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "AE", 25, 18, CompareOptions.IgnoreCase, useNls ? 24 : 9, useNls ? 1 : 2 }; + yield return new object[] { s_invariantCompare, source, "ae", 25, 18, CompareOptions.IgnoreCase, useNls ? 24 : 9, useNls ? 1 : 2 }; + yield return new object[] { s_invariantCompare, source, '\u00C6', 25, 18, CompareOptions.IgnoreCase, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00E6', 25, 18, CompareOptions.IgnoreCase, 24, 1 }; } public static IEnumerable LastIndexOf_U_WithDiaeresis_TestData() { // Searches for the combining character sequence Latin capital letter U with diaeresis or Latin small letter u with diaeresis. string source = "Is \u0055\u0308 or \u0075\u0308 the same as \u00DC or \u00FC?"; - yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.None, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.None, 9 }; - yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.Ordinal, 9 }; - yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.Ordinal, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.Ordinal, -1 }; - yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.IgnoreCase, 24 }; - yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.IgnoreCase, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.IgnoreCase, 24 }; - yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.IgnoreCase, 24 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.None, 9, 2 }; + yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.None, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.None, 9, 2 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.Ordinal, 9, 2 }; + yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.Ordinal, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.Ordinal, -1, 0 }; + yield return new object[] { s_invariantCompare, source, "U\u0308", 25, 18, CompareOptions.IgnoreCase, 24, 1 }; + yield return new object[] { s_invariantCompare, source, "u\u0308", 25, 18, CompareOptions.IgnoreCase, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00DC', 25, 18, CompareOptions.IgnoreCase, 24, 1 }; + yield return new object[] { s_invariantCompare, source, '\u00FC', 25, 18, CompareOptions.IgnoreCase, 24, 1 }; } [Theory] [MemberData(nameof(LastIndexOf_TestData))] [MemberData(nameof(LastIndexOf_U_WithDiaeresis_TestData))] - public void LastIndexOf_String(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected) + public void LastIndexOf_String(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected, int expectedMatchLength) { if (value.Length == 1) { @@ -206,9 +221,9 @@ public void LastIndexOf_String(CompareInfo compareInfo, string source, string va // Now test the span-based versions - use BoundedMemory to detect buffer overruns - RunSpanLastIndexOfTest(compareInfo, sourceSpan, value, options, expected - adjustmentFactor); + RunSpanLastIndexOfTest(compareInfo, sourceSpan, value, options, expected - adjustmentFactor, expectedMatchLength); - static void RunSpanLastIndexOfTest(CompareInfo compareInfo, ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, int expected) + static void RunSpanLastIndexOfTest(CompareInfo compareInfo, ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, int expected, int expectedMatchLength) { using BoundedMemory sourceBoundedMemory = BoundedMemory.AllocateFromExistingData(source); sourceBoundedMemory.MakeReadonly(); @@ -217,6 +232,8 @@ static void RunSpanLastIndexOfTest(CompareInfo compareInfo, ReadOnlySpan s valueBoundedMemory.MakeReadonly(); Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options)); + Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength)); + Assert.Equal(expectedMatchLength, actualMatchLength); if (TryCreateRuneFrom(value, out Rune rune)) { @@ -255,17 +272,18 @@ private static void LastIndexOf_Char(CompareInfo compareInfo, string source, cha [Theory] [MemberData(nameof(LastIndexOf_Aesc_Ligature_TestData))] - public void LastIndexOf_Aesc_Ligature(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected) + public void LastIndexOf_Aesc_Ligature(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected, int expectedMatchLength) { - LastIndexOf_String(compareInfo, source, value, startIndex, count, options, expected); + LastIndexOf_String(compareInfo, source, value, startIndex, count, options, expected, expectedMatchLength); } [Fact] public void LastIndexOf_UnassignedUnicode() { bool useNls = PlatformDetection.IsNlsGlobalization; - LastIndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 5, 6, CompareOptions.None, useNls ? 0 : -1); - LastIndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 6, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1); + int expectedMatchLength = (useNls) ? 6 : 0; + LastIndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 5, 6, CompareOptions.None, useNls ? 0 : -1, expectedMatchLength); + LastIndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 6, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1, expectedMatchLength); } [Fact] @@ -305,6 +323,8 @@ public void LastIndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', CompareOptions.StringSort)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, CompareOptions.StringSort)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, CompareOptions.StringSort)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.StringSort)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.StringSort, out int matchLength)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", 0, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); @@ -312,6 +332,8 @@ public void LastIndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.Ordinal | CompareOptions.IgnoreWidth, out int matchLength)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", 0, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); @@ -319,6 +341,8 @@ public void LastIndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.OrdinalIgnoreCase | CompareOptions.IgnoreWidth, out int matchLength)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", 0, (CompareOptions)(-1))); @@ -326,6 +350,8 @@ public void LastIndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, (CompareOptions)(-1))); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, (CompareOptions)(-1))); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), (CompareOptions)(-1))); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), (CompareOptions)(-1), out int matchLength)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "Tests", 0, (CompareOptions)0x11111111)); @@ -333,6 +359,8 @@ public void LastIndexOf_Invalid() AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, (CompareOptions)0x11111111)); AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, (CompareOptions)0x11111111)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), (CompareOptions)0x11111111)); + AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), (CompareOptions)0x11111111, out int matchLength)); // StartIndex < 0 AssertExtensions.Throws("startIndex", () => s_invariantCompare.LastIndexOf("Test", "Test", -1, CompareOptions.None)); diff --git a/src/libraries/System.Globalization/tests/Invariant/InvariantMode.cs b/src/libraries/System.Globalization/tests/Invariant/InvariantMode.cs index dccc2db90ded..94ec2003e315 100644 --- a/src/libraries/System.Globalization/tests/Invariant/InvariantMode.cs +++ b/src/libraries/System.Globalization/tests/Invariant/InvariantMode.cs @@ -800,9 +800,44 @@ public void TestIndexOf(string source, string value, int startIndex, int count, { foreach (string cul in s_cultureNames) { - Assert.Equal(result, CultureInfo.GetCultureInfo(cul).CompareInfo.IndexOf(source, value, startIndex, count, options)); + CompareInfo compareInfo = CultureInfo.GetCultureInfo(cul).CompareInfo; + TestCore(compareInfo, source, value, startIndex, count, options, result); + } + + // static test helper method to avoid mutating input args when called in a loop + static void TestCore(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int result) + { + Assert.Equal(result, compareInfo.IndexOf(source, value, startIndex, count, options)); Assert.Equal(result, source.IndexOf(value, startIndex, count, GetStringComparison(options))); - Assert.Equal((result == -1) ? -1 : (result - startIndex), source.AsSpan(startIndex, count).IndexOf(value.AsSpan(), GetStringComparison(options))); + + // Span versions - using BoundedMemory to check for buffer overruns + + using BoundedMemory sourceBoundedMemory = BoundedMemory.AllocateFromExistingData(source.AsSpan(startIndex, count)); + sourceBoundedMemory.MakeReadonly(); + ReadOnlySpan sourceBoundedSpan = sourceBoundedMemory.Span; + + using BoundedMemory valueBoundedMemory = BoundedMemory.AllocateFromExistingData(value); + valueBoundedMemory.MakeReadonly(); + ReadOnlySpan valueBoundedSpan = valueBoundedMemory.Span; + + int offsetResult = result; + if (offsetResult >= 0) + { + offsetResult -= startIndex; // account for span slicing + Assert.True(offsetResult >= 0, "Shouldn't have made an affirmative result go negative."); + } + + Assert.Equal(offsetResult, sourceBoundedSpan.IndexOf(valueBoundedSpan, GetStringComparison(options))); + Assert.Equal(offsetResult, compareInfo.IndexOf(sourceBoundedSpan, valueBoundedSpan, options)); + Assert.Equal(offsetResult, compareInfo.IndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength)); + if (offsetResult >= 0) + { + Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons + } + else + { + Assert.Equal(0, matchLength); // not found + } } } @@ -812,14 +847,21 @@ public void TestLastIndexOf(string source, string value, int startIndex, int cou { foreach (string cul in s_cultureNames) { - Assert.Equal(result, CultureInfo.GetCultureInfo(cul).CompareInfo.LastIndexOf(source, value, startIndex, count, options)); + CompareInfo compareInfo = CultureInfo.GetCultureInfo(cul).CompareInfo; + TestCore(compareInfo, source, value, startIndex, count, options, result); + } + + // static test helper method to avoid mutating input args when called in a loop + static void TestCore(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int result) + { + Assert.Equal(result, compareInfo.LastIndexOf(source, value, startIndex, count, options)); Assert.Equal(result, source.LastIndexOf(value, startIndex, count, GetStringComparison(options))); // Filter differences betweeen string-based and Span-based LastIndexOf // - Empty value handling - https://github.com/dotnet/runtime/issues/13382 // - Negative count if (value.Length == 0 || count < 0) - continue; + return; if (startIndex == source.Length) { @@ -828,7 +870,34 @@ public void TestLastIndexOf(string source, string value, int startIndex, int cou count--; } int leftStartIndex = (startIndex - count + 1); - Assert.Equal((result == -1) ? -1 : (result - leftStartIndex), source.AsSpan(leftStartIndex, count).LastIndexOf(value.AsSpan(), GetStringComparison(options))); + + // Span versions - using BoundedMemory to check for buffer overruns + + using BoundedMemory sourceBoundedMemory = BoundedMemory.AllocateFromExistingData(source.AsSpan(leftStartIndex, count)); + sourceBoundedMemory.MakeReadonly(); + ReadOnlySpan sourceBoundedSpan = sourceBoundedMemory.Span; + + using BoundedMemory valueBoundedMemory = BoundedMemory.AllocateFromExistingData(value); + valueBoundedMemory.MakeReadonly(); + ReadOnlySpan valueBoundedSpan = valueBoundedMemory.Span; + + if (result >= 0) + { + result -= leftStartIndex; // account for span slicing + Assert.True(result >= 0, "Shouldn't have made an affirmative result go negative."); + } + + Assert.Equal(result, sourceBoundedSpan.LastIndexOf(valueBoundedSpan, GetStringComparison(options))); + Assert.Equal(result, compareInfo.LastIndexOf(sourceBoundedSpan, valueBoundedSpan, options)); + Assert.Equal(result, compareInfo.LastIndexOf(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength)); + if (result >= 0) + { + Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons + } + else + { + Assert.Equal(0, matchLength); // not found + } } } @@ -838,7 +907,9 @@ public void TestIsPrefix(string source, string value, CompareOptions options, bo { foreach (string cul in s_cultureNames) { - Assert.Equal(result, CultureInfo.GetCultureInfo(cul).CompareInfo.IsPrefix(source, value, options)); + CompareInfo compareInfo = CultureInfo.GetCultureInfo(cul).CompareInfo; + + Assert.Equal(result, compareInfo.IsPrefix(source, value, options)); Assert.Equal(result, source.StartsWith(value, GetStringComparison(options))); // Span versions - using BoundedMemory to check for buffer overruns @@ -852,6 +923,16 @@ public void TestIsPrefix(string source, string value, CompareOptions options, bo ReadOnlySpan valueBoundedSpan = valueBoundedMemory.Span; Assert.Equal(result, sourceBoundedSpan.StartsWith(valueBoundedSpan, GetStringComparison(options))); + Assert.Equal(result, compareInfo.IsPrefix(sourceBoundedSpan, valueBoundedSpan, options)); + Assert.Equal(result, compareInfo.IsPrefix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength)); + if (result) + { + Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons + } + else + { + Assert.Equal(0, matchLength); // not found + } } } @@ -861,7 +942,9 @@ public void TestIsSuffix(string source, string value, CompareOptions options, bo { foreach (string cul in s_cultureNames) { - Assert.Equal(result, CultureInfo.GetCultureInfo(cul).CompareInfo.IsSuffix(source, value, options)); + CompareInfo compareInfo = CultureInfo.GetCultureInfo(cul).CompareInfo; + + Assert.Equal(result, compareInfo.IsSuffix(source, value, options)); Assert.Equal(result, source.EndsWith(value, GetStringComparison(options))); // Span versions - using BoundedMemory to check for buffer overruns @@ -874,8 +957,17 @@ public void TestIsSuffix(string source, string value, CompareOptions options, bo valueBoundedMemory.MakeReadonly(); ReadOnlySpan valueBoundedSpan = valueBoundedMemory.Span; - Assert.Equal(result, CultureInfo.GetCultureInfo(cul).CompareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options)); Assert.Equal(result, sourceBoundedSpan.EndsWith(valueBoundedSpan, GetStringComparison(options))); + Assert.Equal(result, compareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options)); + Assert.Equal(result, compareInfo.IsSuffix(sourceBoundedSpan, valueBoundedSpan, options, out int matchLength)); + if (result) + { + Assert.Equal(valueBoundedSpan.Length, matchLength); // Invariant mode should perform non-linguistic comparisons + } + else + { + Assert.Equal(0, matchLength); // not found + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index e268c80791dd..3b959d44e0a0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -411,7 +411,8 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan source, ReadOnlySpan< } } - private unsafe bool IcuStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + // this method sets '*matchLengthPtr' (if not nullptr) only on success + private unsafe bool IcuStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); @@ -422,21 +423,21 @@ private unsafe bool IcuStartsWith(ReadOnlySpan source, ReadOnlySpan if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options)) { if ((options & CompareOptions.IgnoreCase) != 0) - return StartsWithOrdinalIgnoreCaseHelper(source, prefix, options); + return StartsWithOrdinalIgnoreCaseHelper(source, prefix, options, matchLengthPtr); else - return StartsWithOrdinalHelper(source, prefix, options); + return StartsWithOrdinalHelper(source, prefix, options, matchLengthPtr); } else { fixed (char* pSource = &MemoryMarshal.GetReference(source)) // could be null (or otherwise unable to be dereferenced) fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) { - return Interop.Globalization.StartsWith(_sortHandle, pPrefix, prefix.Length, pSource, source.Length, options); + return Interop.Globalization.StartsWith(_sortHandle, pPrefix, prefix.Length, pSource, source.Length, options, matchLengthPtr); } } } - private unsafe bool StartsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + private unsafe bool StartsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); @@ -499,14 +500,19 @@ private unsafe bool StartsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, if (*a >= 0x80) goto InteropCall; } + + if (matchLengthPtr != null) + { + *matchLengthPtr = prefix.Length; // non-linguistic match doesn't change UTF-16 length + } return true; InteropCall: - return Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options); + return Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options, matchLengthPtr); } } - private unsafe bool StartsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + private unsafe bool StartsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); @@ -558,14 +564,20 @@ private unsafe bool StartsWithOrdinalHelper(ReadOnlySpan source, ReadOnlyS if (*a >= 0x80) goto InteropCall; } + + if (matchLengthPtr != null) + { + *matchLengthPtr = prefix.Length; // non-linguistic match doesn't change UTF-16 length + } return true; InteropCall: - return Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options); + return Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options, matchLengthPtr); } } - private unsafe bool IcuEndsWith(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options) + // this method sets '*matchLengthPtr' (if not nullptr) only on success + private unsafe bool IcuEndsWith(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); @@ -576,21 +588,21 @@ private unsafe bool IcuEndsWith(ReadOnlySpan source, ReadOnlySpan su if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options)) { if ((options & CompareOptions.IgnoreCase) != 0) - return EndsWithOrdinalIgnoreCaseHelper(source, suffix, options); + return EndsWithOrdinalIgnoreCaseHelper(source, suffix, options, matchLengthPtr); else - return EndsWithOrdinalHelper(source, suffix, options); + return EndsWithOrdinalHelper(source, suffix, options, matchLengthPtr); } else { fixed (char* pSource = &MemoryMarshal.GetReference(source)) // could be null (or otherwise unable to be dereferenced) fixed (char* pSuffix = &MemoryMarshal.GetReference(suffix)) { - return Interop.Globalization.EndsWith(_sortHandle, pSuffix, suffix.Length, pSource, source.Length, options); + return Interop.Globalization.EndsWith(_sortHandle, pSuffix, suffix.Length, pSource, source.Length, options, matchLengthPtr); } } } - private unsafe bool EndsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options) + private unsafe bool EndsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); @@ -653,14 +665,19 @@ private unsafe bool EndsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, R if (*a >= 0x80) goto InteropCall; } + + if (matchLengthPtr != null) + { + *matchLengthPtr = suffix.Length; // non-linguistic match doesn't change UTF-16 length + } return true; InteropCall: - return Interop.Globalization.EndsWith(_sortHandle, bp, suffix.Length, ap, source.Length, options); + return Interop.Globalization.EndsWith(_sortHandle, bp, suffix.Length, ap, source.Length, options, matchLengthPtr); } } - private unsafe bool EndsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options) + private unsafe bool EndsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); @@ -712,10 +729,15 @@ private unsafe bool EndsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpa if (*a >= 0x80) goto InteropCall; } + + if (matchLengthPtr != null) + { + *matchLengthPtr = suffix.Length; // non-linguistic match doesn't change UTF-16 length + } return true; InteropCall: - return Interop.Globalization.EndsWith(_sortHandle, bp, suffix.Length, ap, source.Length, options); + return Interop.Globalization.EndsWith(_sortHandle, bp, suffix.Length, ap, source.Length, options, matchLengthPtr); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Nls.cs index 2031d613d548..0e0454bb201e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Nls.cs @@ -317,7 +317,7 @@ private unsafe int NlsIndexOfCore(ReadOnlySpan source, ReadOnlySpan return FindString(positionFlag | (uint)GetNativeCompareFlags(options), source, target, matchLengthPtr); } - private unsafe bool NlsStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) + private unsafe bool NlsStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(GlobalizationMode.UseNls); @@ -325,10 +325,20 @@ private unsafe bool NlsStartsWith(ReadOnlySpan source, ReadOnlySpan Debug.Assert(!prefix.IsEmpty); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - return FindString(FIND_STARTSWITH | (uint)GetNativeCompareFlags(options), source, prefix, null) >= 0; + int idx = FindString(FIND_STARTSWITH | (uint)GetNativeCompareFlags(options), source, prefix, matchLengthPtr); + if (idx >= 0) + { + if (matchLengthPtr != null) + { + *matchLengthPtr += idx; // account for chars we skipped at the front of the string + } + return true; + } + + return false; } - private unsafe bool NlsEndsWith(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options) + private unsafe bool NlsEndsWith(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(GlobalizationMode.UseNls); @@ -336,7 +346,17 @@ private unsafe bool NlsEndsWith(ReadOnlySpan source, ReadOnlySpan su Debug.Assert(!suffix.IsEmpty); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - return FindString(FIND_ENDSWITH | (uint)GetNativeCompareFlags(options), source, suffix, null) >= 0; + int idx = FindString(FIND_ENDSWITH | (uint)GetNativeCompareFlags(options), source, suffix, pcchFound: null); + if (idx >= 0) + { + if (matchLengthPtr != null) + { + *matchLengthPtr = source.Length - idx; // all chars from idx to the end of the string are consumed + } + return true; + } + + return false; } private const uint LCMAP_SORTKEY = 0x00000400; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index f68b83530439..71e65028c502 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -769,7 +769,7 @@ public bool IsPrefix(string source, string prefix, CompareOptions options) /// /// contains an unsupported combination of flags. /// - public bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options = CompareOptions.None) + public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options = CompareOptions.None) { // The empty string is trivially a prefix of every other string. For compat with // earlier versions of the Framework we'll early-exit here before validating the @@ -788,7 +788,7 @@ public bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix, Compa if (!GlobalizationMode.Invariant) { - return StartsWithCore(source, prefix, options); + return StartsWithCore(source, prefix, options, matchLengthPtr: null); } else if ((options & CompareOptions.IgnoreCase) == 0) { @@ -825,10 +825,57 @@ public bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix, Compa return source.StartsWithOrdinalIgnoreCase(prefix); } - private unsafe bool StartsWithCore(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) => + /// + /// Determines whether a string starts with a specific prefix. + /// + /// The string to search within. + /// The prefix to attempt to match at the start of . + /// The to use during the match. + /// When this method returns, contains the number of characters of + /// that matched the desired prefix. This may be different than the + /// length of if a linguistic comparison is performed. Set to 0 + /// if the prefix did not match. + /// + /// if occurs at the start of ; + /// otherwise, . + /// + /// + /// contains an unsupported combination of flags. + /// + /// + /// This method has greater overhead than other overloads which don't + /// take a argument. Call this overload only if you require + /// the match length information. + /// + public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, out int matchLength) + { + bool matched; + + if (GlobalizationMode.Invariant || prefix.IsEmpty || (options & ValidIndexMaskOffFlags) != 0) + { + // Non-linguistic (ordinal) comparison requested, or options are invalid. + // Delegate to other overload, which validates options and throws on failure. + // If success, non-linguistic matches will always preserve prefix length. + + matched = IsPrefix(source, prefix, options); + matchLength = (matched) ? prefix.Length : 0; + } + else + { + // Linguistic comparison requested and we don't need to special-case any args. + + int tempMatchLength = 0; + matched = StartsWithCore(source, prefix, options, &tempMatchLength); + matchLength = tempMatchLength; + } + + return matched; + } + + private unsafe bool StartsWithCore(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? - NlsStartsWith(source, prefix, options) : - IcuStartsWith(source, prefix, options); + NlsStartsWith(source, prefix, options, matchLengthPtr) : + IcuStartsWith(source, prefix, options, matchLengthPtr); public bool IsPrefix(string source, string prefix) { @@ -866,7 +913,7 @@ public bool IsSuffix(string source, string suffix, CompareOptions options) /// /// contains an unsupported combination of flags. /// - public bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options = CompareOptions.None) + public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options = CompareOptions.None) { // The empty string is trivially a suffix of every other string. For compat with // earlier versions of the Framework we'll early-exit here before validating the @@ -885,7 +932,7 @@ public bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix, Compa if (!GlobalizationMode.Invariant) { - return EndsWithCore(source, suffix, options); + return EndsWithCore(source, suffix, options, matchLengthPtr: null); } else if ((options & CompareOptions.IgnoreCase) == 0) { @@ -922,15 +969,62 @@ public bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix, Compa return source.EndsWithOrdinalIgnoreCase(suffix); } + /// + /// Determines whether a string ends with a specific suffix. + /// + /// The string to search within. + /// The suffix to attempt to match at the end of . + /// The to use during the match. + /// When this method returns, contains the number of characters of + /// that matched the desired suffix. This may be different than the + /// length of if a linguistic comparison is performed. Set to 0 + /// if the suffix did not match. + /// + /// if occurs at the end of ; + /// otherwise, . + /// + /// + /// contains an unsupported combination of flags. + /// + /// + /// This method has greater overhead than other overloads which don't + /// take a argument. Call this overload only if you require + /// the match length information. + /// + public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, out int matchLength) + { + bool matched; + + if (GlobalizationMode.Invariant || suffix.IsEmpty || (options & ValidIndexMaskOffFlags) != 0) + { + // Non-linguistic (ordinal) comparison requested, or options are invalid. + // Delegate to other overload, which validates options and throws on failure. + // If success, non-linguistic matches will always preserve prefix length. + + matched = IsSuffix(source, suffix, options); + matchLength = (matched) ? suffix.Length : 0; + } + else + { + // Linguistic comparison requested and we don't need to special-case any args. + + int tempMatchLength = 0; + matched = EndsWithCore(source, suffix, options, &tempMatchLength); + matchLength = tempMatchLength; + } + + return matched; + } + public bool IsSuffix(string source, string suffix) { return IsSuffix(source, suffix, CompareOptions.None); } - private unsafe bool EndsWithCore(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options) => + private unsafe bool EndsWithCore(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? - NlsEndsWith(source, suffix, options) : - IcuEndsWith(source, suffix, options); + NlsEndsWith(source, suffix, options, matchLengthPtr) : + IcuEndsWith(source, suffix, options, matchLengthPtr); /// /// Returns the first index where value is found in string. The @@ -1108,7 +1202,7 @@ public unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, C } else { - return IndexOfCore(source, value, options, null /* matchLengthPtr */, fromBeginning: true); + return IndexOfCore(source, value, options, matchLengthPtr: null, fromBeginning: true); } } else if ((options & CompareOptions.IgnoreCase) == 0) @@ -1146,6 +1240,36 @@ public unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, C return IndexOfOrdinalIgnoreCase(source, value, fromBeginning: true); } + /// + /// Searches for the first occurrence of a substring within a source string. + /// + /// The string to search within. + /// The substring to locate within . + /// The to use during the search. + /// When this method returns, contains the number of characters of + /// that matched the desired value. This may be different than the + /// length of if a linguistic comparison is performed. Set to 0 + /// if is not found within . + /// + /// The zero-based index into where the substring + /// first appears; or -1 if cannot be found within . + /// + /// + /// contains an unsupported combination of flags. + /// + /// + /// This method has greater overhead than other overloads which don't + /// take a argument. Call this overload only if you require + /// the match length information. + /// + public unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, out int matchLength) + { + int tempMatchLength; + int retVal = IndexOf(source, value, &tempMatchLength, options, fromBeginning: true); + matchLength = tempMatchLength; + return retVal; + } + /// /// Searches for the first occurrence of a within a source string. /// @@ -1200,10 +1324,11 @@ internal static int IndexOfOrdinalIgnoreCase(ReadOnlySpan source, ReadOnly } /// - /// The following IndexOf overload is mainly used by String.Replace. This overload assumes the parameters are already validated - /// and the caller is passing a valid matchLengthPtr pointer. + /// IndexOf overload used when the caller needs the length of the matching substring. + /// Caller needs to ensure is non-null and points + /// to a valid address. This method will validate . /// - internal unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, int* matchLengthPtr, CompareOptions options, bool fromBeginning) + private unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, int* matchLengthPtr, CompareOptions options, bool fromBeginning) { Debug.Assert(matchLengthPtr != null); *matchLengthPtr = 0; @@ -1544,7 +1669,7 @@ public unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan valu } else { - return IndexOfCore(source, value, options, null /* matchLengthPtr */, fromBeginning: false); + return IndexOfCore(source, value, options, matchLengthPtr: null, fromBeginning: false); } } else if ((options & CompareOptions.IgnoreCase) == 0) @@ -1584,6 +1709,36 @@ public unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan valu return IndexOfOrdinalIgnoreCase(source, value, fromBeginning: false); } + /// + /// Searches for the last occurrence of a substring within a source string. + /// + /// The string to search within. + /// The substring to locate within . + /// The to use during the search. + /// When this method returns, contains the number of characters of + /// that matched the desired value. This may be different than the + /// length of if a linguistic comparison is performed. Set to 0 + /// if is not found within . + /// + /// The zero-based index into where the substring + /// last appears; or -1 if cannot be found within . + /// + /// + /// contains an unsupported combination of flags. + /// + /// + /// This method has greater overhead than other overloads which don't + /// take a argument. Call this overload only if you require + /// the match length information. + /// + public unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan value, CompareOptions options, out int matchLength) + { + int tempMatchLength; + int retVal = IndexOf(source, value, &tempMatchLength, options, fromBeginning: false); + matchLength = tempMatchLength; + return retVal; + } + /// /// Searches for the last occurrence of a within a source string. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 3c01bc84d2bb..87bae29b5e88 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -1015,7 +1015,7 @@ private string ReplaceCore(string oldValue, string? newValue, CompareInfo? ci, C ?? this; } - private static unsafe string? ReplaceCore(ReadOnlySpan searchSpace, ReadOnlySpan oldValue, ReadOnlySpan newValue, CompareInfo compareInfo, CompareOptions options) + private static string? ReplaceCore(ReadOnlySpan searchSpace, ReadOnlySpan oldValue, ReadOnlySpan newValue, CompareInfo compareInfo, CompareOptions options) { Debug.Assert(!oldValue.IsEmpty); Debug.Assert(compareInfo != null); @@ -1023,12 +1023,11 @@ private string ReplaceCore(string oldValue, string? newValue, CompareInfo? ci, C var result = new ValueStringBuilder(stackalloc char[256]); result.EnsureCapacity(searchSpace.Length); - int matchLength = 0; bool hasDoneAnyReplacements = false; while (true) { - int index = compareInfo.IndexOf(searchSpace, oldValue, &matchLength, options, fromBeginning: true); + int index = compareInfo.IndexOf(searchSpace, oldValue, options, out int matchLength); // There's the possibility that 'oldValue' has zero collation weight (empty string equivalent). // If this is the case, we behave as if there are no more substitutions to be made. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs index e5309a9ecc19..a004812e61a5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs @@ -280,7 +280,9 @@ private unsafe bool TryFind(Utf8Span value, StringComparison comparisonType, out } else { - idx = compareInfo.IndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, &matchLength, compareOptions, fromBeginning); + idx = (fromBeginning) + ? compareInfo.IndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, compareOptions, out matchLength) + : compareInfo.LastIndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, compareOptions, out matchLength); } #else Debug.Assert(comparisonType == StringComparison.OrdinalIgnoreCase); diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 6481c43f3808..ef8bbb78d73b 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -6044,6 +6044,7 @@ internal CompareInfo() { } public System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw null; } public int GetSortKeyLength(System.ReadOnlySpan source, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } public int IndexOf(System.ReadOnlySpan source, System.ReadOnlySpan value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } + public int IndexOf(System.ReadOnlySpan source, System.ReadOnlySpan value, System.Globalization.CompareOptions options, out int matchLength) { throw null; } public int IndexOf(System.ReadOnlySpan source, System.Text.Rune value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } public int IndexOf(string source, char value) { throw null; } public int IndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; } @@ -6058,6 +6059,7 @@ internal CompareInfo() { } public int IndexOf(string source, string value, int startIndex, int count) { throw null; } public int IndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; } public bool IsPrefix(System.ReadOnlySpan source, System.ReadOnlySpan prefix, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } + public bool IsPrefix(System.ReadOnlySpan source, System.ReadOnlySpan suffix, System.Globalization.CompareOptions options, out int matchLength) { throw null; } public bool IsPrefix(string source, string prefix) { throw null; } public bool IsPrefix(string source, string prefix, System.Globalization.CompareOptions options) { throw null; } public static bool IsSortable(char ch) { throw null; } @@ -6065,9 +6067,11 @@ internal CompareInfo() { } public static bool IsSortable(string text) { throw null; } public static bool IsSortable(System.Text.Rune value) { throw null; } public bool IsSuffix(System.ReadOnlySpan source, System.ReadOnlySpan suffix, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } + public bool IsSuffix(System.ReadOnlySpan source, System.ReadOnlySpan suffix, System.Globalization.CompareOptions options, out int matchLength) { throw null; } public bool IsSuffix(string source, string suffix) { throw null; } public bool IsSuffix(string source, string suffix, System.Globalization.CompareOptions options) { throw null; } public int LastIndexOf(System.ReadOnlySpan source, System.ReadOnlySpan value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } + public int LastIndexOf(System.ReadOnlySpan source, System.ReadOnlySpan value, System.Globalization.CompareOptions options, out int matchLength) { throw null; } public int LastIndexOf(System.ReadOnlySpan source, System.Text.Rune value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } public int LastIndexOf(string source, char value) { throw null; } public int LastIndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; } diff --git a/src/libraries/System.Runtime/tests/System/StringTests.cs b/src/libraries/System.Runtime/tests/System/StringTests.cs index dabb22f2027c..12a0e4ccec91 100644 --- a/src/libraries/System.Runtime/tests/System/StringTests.cs +++ b/src/libraries/System.Runtime/tests/System/StringTests.cs @@ -684,6 +684,11 @@ public static IEnumerable Replace_StringComparison_TestData() yield return new object[] { turkishSource, "\u0130", "a", StringComparison.InvariantCulture, "\u0069a" }; yield return new object[] { turkishSource, "\u0130", "a", StringComparison.InvariantCultureIgnoreCase, "\u0069a" }; } + + // To catch regressions when dealing with zero-length "this" inputs + yield return new object[] { "", "x", "y", StringComparison.InvariantCulture, "" }; + yield return new object[] { "", "\u200d", "y", StringComparison.InvariantCulture, "" }; + yield return new object[] { "", "\0", "y", StringComparison.InvariantCulture, "" }; } [Theory] From 28e2d54da1ae0ccdea86a95c61d0e07f156cc0af Mon Sep 17 00:00:00 2001 From: John Salem Date: Thu, 13 Aug 2020 17:52:34 -0700 Subject: [PATCH 476/755] Add GetProcessEnvironment command to diagnostics server (#40556) --- .../vm/processdiagnosticsprotocolhelper.cpp | 155 +++++++++++++++++- .../src/vm/processdiagnosticsprotocolhelper.h | 38 ++++- .../processenvironment/processenvironment.cs | 96 +++++++++++ .../processenvironment.csproj | 16 ++ .../eventpipe/processinfo/processinfo.cs | 4 +- 5 files changed, 303 insertions(+), 6 deletions(-) create mode 100644 src/tests/tracing/eventpipe/processenvironment/processenvironment.cs create mode 100644 src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj diff --git a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp index 6aad9af96de0..f912efb1f011 100644 --- a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp +++ b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp @@ -11,7 +11,7 @@ #ifdef FEATURE_PERFTRACING -static inline uint32_t GetStringLength(const WCHAR *&value) +static inline uint32_t GetStringLength(const WCHAR *value) { return static_cast(wcslen(value) + 1); } @@ -35,6 +35,28 @@ static bool TryWriteString(uint8_t * &bufferCursor, uint16_t &bufferLen, const W return true; } +static bool TryWriteString(IpcStream *pStream, const WCHAR *value) +{ + uint32_t stringLen = GetStringLength(value); + uint32_t stringLenInBytes = stringLen * sizeof(WCHAR); + uint32_t totalStringSizeInBytes = stringLenInBytes + sizeof(uint32_t); + + uint32_t totalBytesWritten = 0; + uint32_t nBytesWritten = 0; + + bool fSuccess = pStream->Write(&stringLen, sizeof(stringLen), nBytesWritten); + totalBytesWritten += nBytesWritten; + + if (fSuccess) + { + fSuccess &= pStream->Write(value, stringLenInBytes, nBytesWritten); + totalBytesWritten += nBytesWritten; + } + + ASSERT(totalBytesWritten == totalStringSizeInBytes); + return fSuccess && totalBytesWritten == totalStringSizeInBytes; +} + uint16_t ProcessInfoPayload::GetSize() { LIMITED_METHOD_CONTRACT; @@ -114,6 +136,134 @@ bool ProcessInfoPayload::Flatten(BYTE * &lpBuffer, uint16_t &cbSize) return fSuccess; } +void EnvironmentHelper::PopulateEnvironment() +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + if (Environment != nullptr) + return; + + // env block is an array of strings of the form "key=value" delimited by null and terminated by null + // e.g., "key=value\0key=value\0\0"; + LPWSTR envBlock = GetEnvironmentStringsW(); + LPWSTR envCursor = envBlock; + // first calculate the buffer size + uint32_t nWchars = 0; + uint32_t nEntries = 0; + while(*envCursor != 0) + { + uint32_t len = static_cast(wcslen(envCursor) + 1); + nEntries++; + nWchars += len; + envCursor += len; + } + + // serialized size value can't be larger than uint32_t + S_UINT32 size(sizeof(uint32_t) + (nEntries * sizeof(uint32_t)) + (nWchars * sizeof(WCHAR))); + // if the envblock size value is larger than a uint32_t then we should bail + if (!size.IsOverflow()) + { + // copy out the Environment block + LPWSTR tmpEnv = new (nothrow) WCHAR[nWchars + 1]; + if (tmpEnv != nullptr) + { + memcpy(tmpEnv, envBlock, (nWchars + 1) * sizeof(WCHAR)); + Environment = tmpEnv; + } + _nEnvEntries = nEntries; + _nWchars = nWchars; + } + + FreeEnvironmentStringsW(envBlock); + + return; +} + +uint32_t EnvironmentHelper::GetEnvironmentBlockSize() +{ + LIMITED_METHOD_CONTRACT; + + S_UINT32 size(sizeof(uint32_t) + (_nEnvEntries * sizeof(uint32_t)) + (_nWchars * sizeof(WCHAR))); + return size.IsOverflow() ? sizeof(uint32_t) : size.Value(); +} + +bool EnvironmentHelper::WriteToStream(IpcStream *pStream) +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(pStream != nullptr); + PRECONDITION(Environment != nullptr); + } + CONTRACTL_END; + + // Array> + uint32_t nBytesWritten = 0; + bool fSuccess = pStream->Write(&_nEnvEntries, sizeof(_nEnvEntries), nBytesWritten); + + LPCWSTR cursor = Environment; + for (uint32_t i = 0; i < _nEnvEntries; i++) + { + if (!fSuccess || cursor == nullptr) + break; + + uint32_t len = static_cast(wcslen(cursor) + 1); + fSuccess &= TryWriteString(pStream, cursor); + cursor += len; + } + + return fSuccess; +} + +void ProcessDiagnosticsProtocolHelper::GetProcessEnvironment(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(pStream != nullptr); + } + CONTRACTL_END; + + // GetProcessEnvironment responds with a Diagnostics IPC message + // who's payload is a uint32_t that specifies the number of bytes + // that will follow. The optional continuation will contain + // the Environemnt streamed in the standard Diagnostics IPC format (length-prefixed arrays). + + struct EnvironmentHelper helper = {}; + helper.PopulateEnvironment(); + + struct EnvironmentHelper::InitialPayload payload = { helper.GetEnvironmentBlockSize(), 0 }; + + DiagnosticsIpc::IpcMessage ProcessEnvironmentResponse; + const bool fSuccess = ProcessEnvironmentResponse.Initialize(DiagnosticsIpc::GenericSuccessHeader, payload) ? + ProcessEnvironmentResponse.Send(pStream) : + DiagnosticsIpc::IpcMessage::SendErrorMessage(pStream, E_FAIL); + + if (!fSuccess) + { + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "Failed to send DiagnosticsIPC response"); + } + else + { + // send the environment + const bool fSuccessWriteEnv = helper.WriteToStream(pStream); + if (!fSuccessWriteEnv) + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "Failed to stream environment"); + } + + delete pStream; +} + void ProcessDiagnosticsProtocolHelper::GetProcessInfo(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream) { CONTRACTL @@ -202,6 +352,9 @@ void ProcessDiagnosticsProtocolHelper::HandleIpcMessage(DiagnosticsIpc::IpcMessa case ProcessCommandId::ResumeRuntime: ProcessDiagnosticsProtocolHelper::ResumeRuntimeStartup(message, pStream); break; + case ProcessCommandId::GetProcessEnvironment: + ProcessDiagnosticsProtocolHelper::GetProcessEnvironment(message, pStream); + break; default: STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknown request type (%d)\n", message.GetHeader().CommandSet); diff --git a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h index ac4e1e5d1d50..f2de0d7135ab 100644 --- a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h +++ b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h @@ -18,8 +18,9 @@ class IpcStream; // see diagnosticsipc.h and diagnosticserver.h for more details enum class ProcessCommandId : uint8_t { - GetProcessInfo = 0x00, - ResumeRuntime = 0x01, + GetProcessInfo = 0x00, + ResumeRuntime = 0x01, + GetProcessEnvironment = 0x02 // future }; @@ -33,7 +34,6 @@ struct ProcessInfoPayload // 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; @@ -45,12 +45,44 @@ struct ProcessInfoPayload bool Flatten(BYTE * &lpBuffer, uint16_t& cbSize); }; +struct EnvironmentHelper +{ + // The environemnt is sent back as an optional continuation stream of data. + // It is encoded in the typical length-prefixed array format as defined in + // the Diagnostics IPC Spec: https://github.com/dotnet/diagnostics/blob/master/documentation/design-docs/ipc-protocol.md + + struct InitialPayload + { + uint32_t continuationSizeInBytes; + uint16_t future; + }; + + // sent as: Array> + NewArrayHolder Environment = nullptr; + + void PopulateEnvironment(); + uint32_t GetNumberOfElements() { PopulateEnvironment(); return _nEnvEntries; } + + // Write the environment block to the stream + bool WriteToStream(IpcStream *pStream); + + // The size in bytes of the Diagnostic IPC Protocol encoded Environment Block + // It is encoded as Array> so this will return at least sizeof(uint32_t) + // if the env block is empty or failed to be snapshotted since the stream will + // just contain 0 for the array length. + uint32_t GetEnvironmentBlockSize(); +private: + uint32_t _nEnvEntries = 0; + uint32_t _nWchars = 0; +}; + class ProcessDiagnosticsProtocolHelper { public: // IPC event handlers. static void HandleIpcMessage(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); static void GetProcessInfo(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); + static void GetProcessEnvironment(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); static void ResumeRuntimeStartup(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); }; diff --git a/src/tests/tracing/eventpipe/processenvironment/processenvironment.cs b/src/tests/tracing/eventpipe/processenvironment/processenvironment.cs new file mode 100644 index 000000000000..12212cbe3782 --- /dev/null +++ b/src/tests/tracing/eventpipe/processenvironment/processenvironment.cs @@ -0,0 +1,96 @@ +// 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.ProcessEnvironmentValidation +{ + public class ProcessEnvironmentValidation + { + public static int Main(string[] args) + { + + Process currentProcess = Process.GetCurrentProcess(); + int pid = currentProcess.Id; + Logger.logger.Log($"Test PID: {pid}"); + var testEnvPairs = new Dictionary + { + { "TESTKEY1", "TESTVAL1" }, + { "TESTKEY2", "TESTVAL2" }, + { "TESTKEY3", "__TEST__VAL=;--3" } + }; + + foreach (var (key, val) in testEnvPairs) + System.Environment.SetEnvironmentVariable(key, val); + + Stream stream = ConnectionHelper.GetStandardTransport(pid); + + // 0x04 = ProcessCommandSet, 0x02 = ProcessInfo + var processInfoMessage = new IpcMessage(0x04, 0x02); + Logger.logger.Log($"Wrote: {processInfoMessage}"); + Stream continuationStream = IpcClient.SendMessage(stream, processInfoMessage, out IpcMessage response); + 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 + + UInt32 continuationSizeInBytes = BitConverter.ToUInt32(response.Payload[0..4]); + Logger.logger.Log($"continuation size: {continuationSizeInBytes} bytes"); + UInt16 future = BitConverter.ToUInt16(response.Payload[4..]); + Logger.logger.Log($"future value: {future}"); + + using var memoryStream = new MemoryStream(); + Logger.logger.Log($"Starting to copy continuation"); + continuationStream.CopyTo(memoryStream); + Logger.logger.Log($"Finished copying continuation"); + byte[] envBlock = memoryStream.ToArray(); + Logger.logger.Log($"Total bytes in continuation: {envBlock.Length}"); + + Utils.Assert(envBlock.Length == continuationSizeInBytes, $"Continuation size must equal the reported size in the payload response. Expected: {continuationSizeInBytes} bytes, Received: {envBlock.Length} bytes"); + + // VALIDATE ENV + // env block is sent as Array (length-prefixed array of length-prefixed wchar strings) + int start = 0; + int end = start + 4 /* sizeof(uint32_t) */; + UInt32 envCount = BitConverter.ToUInt32(envBlock[start..end]); + Logger.logger.Log($"envCount: {envCount}"); + + var env = new Dictionary(); + for (int i = 0; i < envCount; i++) + { + start = end; + end = start + 4 /* sizeof(uint32_t) */; + UInt32 pairLength = BitConverter.ToUInt32(envBlock[start..end]); + + start = end; + end = start + ((int)pairLength * sizeof(char)); + Utils.Assert(end <= envBlock.Length, $"String end can't exceed payload size. Expected: <{envBlock.Length}, Received: {end} (decoded length: {pairLength})"); + string envPair = System.Text.Encoding.Unicode.GetString(envBlock[start..end]).TrimEnd('\0'); + int equalsIndex = envPair.IndexOf('='); + env[envPair[0..equalsIndex]] = envPair[(equalsIndex+1)..]; + } + Logger.logger.Log($"finished parsing env"); + + + foreach (var (key, val) in testEnvPairs) + Utils.Assert(env.ContainsKey(key) && env[key].Equals(val), $"Did not find test environment pair in the environment block: '{key}' = '{val}'"); + Logger.logger.Log($"Saw test values in env"); + + Utils.Assert(end == envBlock.Length, $"Full payload should have been read. Expected: {envBlock.Length}, Received: {end}"); + + return 100; + } + } +} \ No newline at end of file diff --git a/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj b/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj new file mode 100644 index 000000000000..8633e6ca1883 --- /dev/null +++ b/src/tests/tracing/eventpipe/processenvironment/processenvironment.csproj @@ -0,0 +1,16 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + true + true + + + + + + diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.cs b/src/tests/tracing/eventpipe/processinfo/processinfo.cs index f9f70605e1f5..5762691d0a79 100644 --- a/src/tests/tracing/eventpipe/processinfo/processinfo.cs +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.cs @@ -82,7 +82,7 @@ public static int Main(string[] args) var processInfoMessage = new IpcMessage(0x04, 0x00); Logger.logger.Log($"Wrote: {processInfoMessage}"); IpcMessage response = IpcClient.SendMessage(stream, processInfoMessage); - Logger.logger.Log($"Received: {response}"); + Logger.logger.Log($"Received: "); 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 @@ -95,7 +95,7 @@ public static int Main(string[] args) // LPCWSTR Arch; int totalSize = response.Payload.Length; - Logger.logger.Log($"Total size of Payload == {totalSize} b"); + Logger.logger.Log($"Total size of Payload = {totalSize} bytes"); // VALIDATE PID int start = 0; From 053d6082e2c545647b8fc92a0b1e30db54f421d6 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Thu, 13 Aug 2020 20:55:44 -0400 Subject: [PATCH 477/755] [mono] Adjust wasm gitignore and Makefile (#40797) --- .gitignore | 4 ++++ src/mono/wasm/Makefile | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index bfe14adb6c04..25fc51757e22 100644 --- a/.gitignore +++ b/.gitignore @@ -353,3 +353,7 @@ src/coreclr/src/System.Private.CoreLib/common # The debug directory should not be ignored !src/coreclr/src/debug + +# Mono Wasm-specific excludes +src/mono/wasm/emsdk/ +src/mono/wasm/.stamp-wasm-install-and-select* diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 398bd0e650bf..7efcaed0c0f3 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -120,6 +120,12 @@ icu-data: runtime: EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh --subset mono --arch wasm --os Browser -c $(CONFIG) /p:ContinueOnError=false /p:StopOnFirstFailure=true + cp $(TOP)/artifacts/bin/mono/Browser.wasm.$(CONFIG)/IL/System.Private.CoreLib.dll $(TOP)/artifacts/bin/microsoft.netcore.app.runtime.browser-wasm/$(CONFIG)/runtimes/browser-wasm/native/ + $(MAKE) build + +corlib: + EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh --subset mono.corelib --arch wasm --os Browser -c $(CONFIG) + cp $(TOP)/artifacts/bin/mono/Browser.wasm.$(CONFIG)/IL/System.Private.CoreLib.dll $(TOP)/artifacts/bin/microsoft.netcore.app.runtime.browser-wasm/$(CONFIG)/runtimes/browser-wasm/native/ build-all: EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh --subset mono+libs --arch wasm --os Browser -c $(CONFIG) From 468808d3312d659e996e5e8e3fef1de5a9519b0f Mon Sep 17 00:00:00 2001 From: John Salem Date: Thu, 13 Aug 2020 18:11:50 -0700 Subject: [PATCH 478/755] Rebrand Diagnostics Server to DiagnosticPort (#40499) * renames customer facing portions of the diagnostics server to diagnostic ports * adds the DOTNET_DiagnosticPorts and DOTNET_DefaultDiagnosticPortSuspen environment variables for configuring diagnostic ports * fixes some pre-existing issues: * corrects the scope of the runtime identifier guid so it is the same variable across translation units * protects the window of time between startup resuming and EventPipe::FinishInitialization for doing EventPipe::Disable. --- .../debug/debug-pal/unix/diagnosticsipc.cpp | 16 +- .../debug/debug-pal/win/diagnosticsipc.cpp | 18 +- src/coreclr/src/debug/inc/diagnosticsipc.h | 12 +- src/coreclr/src/inc/clrconfigvalues.h | 6 +- src/coreclr/src/vm/diagnosticserver.cpp | 69 ++- src/coreclr/src/vm/diagnosticsprotocol.h | 14 +- src/coreclr/src/vm/eventpipe.cpp | 58 ++- src/coreclr/src/vm/eventpipe.h | 5 +- src/coreclr/src/vm/ipcstreamfactory.cpp | 177 ++++++-- src/coreclr/src/vm/ipcstreamfactory.h | 83 +++- .../tracing/eventpipe/common/IpcUtils.cs | 49 ++- src/tests/tracing/eventpipe/common/Reverse.cs | 1 + .../diagnosticport/diagnosticport.cs | 413 ++++++++++++++++++ .../diagnosticport/diagnosticport.csproj | 17 + .../eventpipe/pauseonstart/pauseonstart.cs | 10 +- .../tracing/eventpipe/reverse/reverse.cs | 18 +- .../eventpipe/reverseouter/reverseouter.cs | 3 +- 17 files changed, 811 insertions(+), 158 deletions(-) create mode 100644 src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs create mode 100644 src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj diff --git a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp index a718c2bc34e2..2dc6c8807a65 100644 --- a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp @@ -61,8 +61,8 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p "socket"); } - if (mode == ConnectionMode::CLIENT) - return new IpcStream::DiagnosticsIpc(-1, &serverAddress, ConnectionMode::CLIENT); + if (mode == ConnectionMode::CONNECT) + return new IpcStream::DiagnosticsIpc(-1, &serverAddress, ConnectionMode::CONNECT); #ifdef __APPLE__ mode_t prev_mask = umask(~(S_IRUSR | S_IWUSR)); // This will set the default permission bit to 600 @@ -116,8 +116,8 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) { - _ASSERTE(mode == ConnectionMode::SERVER); - if (mode != ConnectionMode::SERVER) + _ASSERTE(mode == ConnectionMode::LISTEN); + if (mode != ConnectionMode::LISTEN) { if (callback != nullptr) callback("Cannot call Listen on a client connection", -1); @@ -150,7 +150,7 @@ bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) { - _ASSERTE(mode == ConnectionMode::SERVER); + _ASSERTE(mode == ConnectionMode::LISTEN); _ASSERTE(_isListening); sockaddr_un from; @@ -168,7 +168,7 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) { - _ASSERTE(mode == ConnectionMode::CLIENT); + _ASSERTE(mode == ConnectionMode::CONNECT); sockaddr_un clientAddress{}; clientAddress.sun_family = AF_UNIX; @@ -194,7 +194,7 @@ IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) return nullptr; } - return new IpcStream(clientSocket, ConnectionMode::CLIENT); + return new IpcStream(clientSocket, ConnectionMode::CONNECT); } int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_t nHandles, int32_t timeoutMs, ErrorCallback callback) @@ -208,7 +208,7 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_ if (rgIpcPollHandles[i].pIpc != nullptr) { // SERVER - _ASSERTE(rgIpcPollHandles[i].pIpc->mode == ConnectionMode::SERVER); + _ASSERTE(rgIpcPollHandles[i].pIpc->mode == ConnectionMode::LISTEN); fd = rgIpcPollHandles[i].pIpc->_serverSocket; } else diff --git a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp index 2b6c38463c1b..3d3d3f03f6bf 100644 --- a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp @@ -56,8 +56,8 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) { - _ASSERTE(mode == ConnectionMode::SERVER); - if (mode != ConnectionMode::SERVER) + _ASSERTE(mode == ConnectionMode::LISTEN); + if (mode != ConnectionMode::LISTEN) { if (callback != nullptr) callback("Cannot call Listen on a client connection", -1); @@ -131,7 +131,7 @@ bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) { _ASSERTE(_isListening); - _ASSERTE(mode == ConnectionMode::SERVER); + _ASSERTE(mode == ConnectionMode::LISTEN); DWORD dwDummy = 0; bool fSuccess = GetOverlappedResult( @@ -148,7 +148,7 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) } // create new IpcStream using handle and reset the Server object so it can listen again - IpcStream *pStream = new IpcStream(_hPipe, ConnectionMode::SERVER); + IpcStream *pStream = new IpcStream(_hPipe, ConnectionMode::LISTEN); // reset the server _hPipe = INVALID_HANDLE_VALUE; @@ -167,8 +167,8 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) { - _ASSERTE(mode == ConnectionMode::CLIENT); - if (mode != ConnectionMode::CLIENT) + _ASSERTE(mode == ConnectionMode::CONNECT); + if (mode != ConnectionMode::CONNECT) { if (callback != nullptr) callback("Cannot call connect on a server connection", 0); @@ -206,7 +206,7 @@ void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback callback) if (_hPipe != INVALID_HANDLE_VALUE) { - if (mode == DiagnosticsIpc::ConnectionMode::SERVER) + if (mode == DiagnosticsIpc::ConnectionMode::LISTEN) { const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); _ASSERTE(fSuccessDisconnectNamedPipe != 0); @@ -248,7 +248,7 @@ void IpcStream::Close(ErrorCallback callback) { Flush(); - if (_mode == DiagnosticsIpc::ConnectionMode::SERVER) + if (_mode == DiagnosticsIpc::ConnectionMode::LISTEN) { const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); _ASSERTE(fSuccessDisconnectNamedPipe != 0); @@ -281,7 +281,7 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_ if (rgIpcPollHandles[i].pIpc != nullptr) { // SERVER - _ASSERTE(rgIpcPollHandles[i].pIpc->mode == DiagnosticsIpc::ConnectionMode::SERVER); + _ASSERTE(rgIpcPollHandles[i].pIpc->mode == DiagnosticsIpc::ConnectionMode::LISTEN); pHandles[i] = rgIpcPollHandles[i].pIpc->_oOverlap.hEvent; } else diff --git a/src/coreclr/src/debug/inc/diagnosticsipc.h b/src/coreclr/src/debug/inc/diagnosticsipc.h index ecbf9db7dfef..b5fff7afc65a 100644 --- a/src/coreclr/src/debug/inc/diagnosticsipc.h +++ b/src/coreclr/src/debug/inc/diagnosticsipc.h @@ -31,8 +31,8 @@ class IpcStream final public: enum ConnectionMode { - CLIENT, - SERVER + CONNECT, + LISTEN }; enum class PollEvents : uint8_t @@ -102,7 +102,7 @@ class IpcStream final sockaddr_un *const _pServerAddress; bool _isClosed; - DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress, ConnectionMode mode = ConnectionMode::SERVER); + DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress, ConnectionMode mode = ConnectionMode::LISTEN); // Used to unlink the socket so it can be removed from the filesystem // when the last reference to it is closed. @@ -113,7 +113,7 @@ class IpcStream final HANDLE _hPipe = INVALID_HANDLE_VALUE; OVERLAPPED _oOverlap = {}; - DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength], ConnectionMode mode = ConnectionMode::SERVER); + DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength], ConnectionMode mode = ConnectionMode::LISTEN); #endif /* TARGET_UNIX */ bool _isListening; @@ -128,13 +128,13 @@ class IpcStream final private: #ifdef TARGET_UNIX int _clientSocket = -1; - IpcStream(int clientSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER) + IpcStream(int clientSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::LISTEN) : _clientSocket(clientSocket), _mode(mode) {} #else HANDLE _hPipe = INVALID_HANDLE_VALUE; OVERLAPPED _oOverlap = {}; BOOL _isTestReading = false; // used to check whether we are already doing a 0-byte read to test for data - IpcStream(HANDLE hPipe, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER); + IpcStream(HANDLE hPipe, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::LISTEN); #endif /* TARGET_UNIX */ DiagnosticsIpc::ConnectionMode _mode; diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 3cd7db89bb7e..efeac155253c 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -710,10 +710,10 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers") // -// Diagnostics Server +// Diagnostics Ports // -RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticsMonitorAddress, W("DOTNET_DiagnosticsMonitorAddress"), "NamedPipe path without '\\\\.\\pipe\\' on Windows; Full path of Unix Domain Socket on Linux/Unix. Used for Diagnostics Monitoring Agents.", CLRConfig::DontPrependCOMPlus_); -RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_DOTNET_DiagnosticsMonitorPauseOnStart, W("DOTNET_DiagnosticsMonitorPauseOnStart"), 1, "If DOTNET_DiagnosticsMonitorAddress is set, this will cause the runtime to pause during startup. Resume using the Diagnostics IPC ResumeStartup command.", CLRConfig::DontPrependCOMPlus_); +RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend, W("DOTNET_DefaultDiagnosticPortSuspend"), 0, "This sets the deafult diagnostic port to suspend causing the runtime to pause during startup before major subsystems are started. Resume using the Diagnostics IPC ResumeStartup command on the default diagnostic port.", CLRConfig::DontPrependCOMPlus_); +RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticPorts, W("DOTNET_DiagnosticPorts"), "A semicolon delimited list of additional Diagnostic Ports, where a Diagnostic Port is a NamedPipe path without '\\\\.\\pipe\\' on Windows or the full path of Unix Domain Socket on Linux/Unix followed by optional tags, e.g., ',connect,nosuspend;'", CLRConfig::DontPrependCOMPlus_); // // LTTng diff --git a/src/coreclr/src/vm/diagnosticserver.cpp b/src/coreclr/src/vm/diagnosticserver.cpp index 7688cabe1511..ef026a1f4053 100644 --- a/src/coreclr/src/vm/diagnosticserver.cpp +++ b/src/coreclr/src/vm/diagnosticserver.cpp @@ -22,6 +22,7 @@ Volatile DiagnosticServer::s_shuttingDown(false); CLREventStatic *DiagnosticServer::s_ResumeRuntimeStartupEvent = nullptr; +GUID DiagnosticsIpc::AdvertiseCookie_V1 = GUID_NULL; DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) { @@ -32,11 +33,11 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) #endif GC_TRIGGERS; MODE_PREEMPTIVE; - PRECONDITION(s_shuttingDown || IpcStreamFactory::HasActiveConnections()); + PRECONDITION(s_shuttingDown || IpcStreamFactory::HasActivePorts()); } CONTRACTL_END; - if (!IpcStreamFactory::HasActiveConnections()) + if (!IpcStreamFactory::HasActivePorts()) { STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "Diagnostics IPC listener was undefined\n"); return 1; @@ -144,30 +145,21 @@ bool DiagnosticServer::Initialize() szMessage); // data2 }; - NewArrayHolder address = nullptr; - CLRConfigStringHolder wAddress = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticsMonitorAddress); - int nCharactersWritten = 0; - if (wAddress != nullptr) + // Initialize the RuntimeIndentifier before use + CoCreateGuid(&DiagnosticsIpc::AdvertiseCookie_V1); + + // Ports can fail to be configured + bool fAnyErrors = IpcStreamFactory::Configure(ErrorCallback); + if (fAnyErrors) + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "At least one Diagnostic Port failed to be configured.\n"); + + if (IpcStreamFactory::AnySuspendedPorts()) { - // By default, opts in to Pause on Start s_ResumeRuntimeStartupEvent = new CLREventStatic(); s_ResumeRuntimeStartupEvent->CreateManualEvent(false); - - nCharactersWritten = WideCharToMultiByte(CP_UTF8, 0, wAddress, -1, NULL, 0, NULL, NULL); - if (nCharactersWritten != 0) - { - address = new char[nCharactersWritten]; - nCharactersWritten = WideCharToMultiByte(CP_UTF8, 0, wAddress, -1, address, nCharactersWritten, NULL, NULL); - assert(nCharactersWritten != 0); - } - - // Create the client mode connection - fSuccess &= IpcStreamFactory::CreateClient(address, ErrorCallback); } - fSuccess &= IpcStreamFactory::CreateServer(nullptr, ErrorCallback); - - if (IpcStreamFactory::HasActiveConnections()) + if (IpcStreamFactory::HasActivePorts()) { #ifdef FEATURE_AUTO_TRACE auto_trace_init(); @@ -184,7 +176,7 @@ bool DiagnosticServer::Initialize() if (hServerThread == NULL) { - IpcStreamFactory::CloseConnections(); + IpcStreamFactory::ClosePorts(); // Failed to create IPC thread. STRESS_LOG1( @@ -229,7 +221,7 @@ bool DiagnosticServer::Shutdown() EX_TRY { - if (IpcStreamFactory::HasActiveConnections()) + if (IpcStreamFactory::HasActivePorts()) { auto ErrorCallback = [](const char *szMessage, uint32_t code) { STRESS_LOG2( @@ -266,22 +258,22 @@ void DiagnosticServer::PauseForDiagnosticsMonitor() } CONTRACTL_END; - CLRConfigStringHolder pDotnetDiagnosticsMonitorAddress = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticsMonitorAddress); - if (pDotnetDiagnosticsMonitorAddress != nullptr) + if (IpcStreamFactory::AnySuspendedPorts()) { - DWORD dwDotnetDiagnosticsMonitorPauseOnStart = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticsMonitorPauseOnStart); - if (dwDotnetDiagnosticsMonitorPauseOnStart != 0) + _ASSERTE(s_ResumeRuntimeStartupEvent != nullptr && s_ResumeRuntimeStartupEvent->IsValid()); + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, "The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command."); + const DWORD dwFiveSecondWait = s_ResumeRuntimeStartupEvent->Wait(5000, false); + if (dwFiveSecondWait == WAIT_TIMEOUT) { - _ASSERTE(s_ResumeRuntimeStartupEvent != nullptr && s_ResumeRuntimeStartupEvent->IsValid()); - STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, "The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command."); - const DWORD dwFiveSecondWait = s_ResumeRuntimeStartupEvent->Wait(5000, false); - if (dwFiveSecondWait == WAIT_TIMEOUT) - { - wprintf(W("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a server at '%s'.\n"), (LPWSTR)pDotnetDiagnosticsMonitorAddress); - fflush(stdout); - STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, "The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command and has waited 5 seconds."); - const DWORD dwWait = s_ResumeRuntimeStartupEvent->Wait(INFINITE, false); - } + CLRConfigStringHolder dotnetDiagnosticPortString = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticPorts); + WCHAR empty[] = W(""); + DWORD dotnetDiagnosticPortSuspend = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend); + wprintf(W("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n")); + wprintf(W("DOTNET_DiagnosticPorts=\"%s\"\n"), dotnetDiagnosticPortString == nullptr ? empty : dotnetDiagnosticPortString.GetValue()); + wprintf(W("DOTNET_DefaultDiagnosticPortSuspend=%d\n"), dotnetDiagnosticPortSuspend); + fflush(stdout); + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, "The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command and has waited 5 seconds."); + const DWORD dwWait = s_ResumeRuntimeStartupEvent->Wait(INFINITE, false); } } // allow wait failures to fall through and the runtime to continue coming up @@ -290,7 +282,8 @@ void DiagnosticServer::PauseForDiagnosticsMonitor() void DiagnosticServer::ResumeRuntimeStartup() { LIMITED_METHOD_CONTRACT; - if (s_ResumeRuntimeStartupEvent != nullptr && s_ResumeRuntimeStartupEvent->IsValid()) + IpcStreamFactory::ResumeCurrentPort(); + if (!IpcStreamFactory::AnySuspendedPorts() && s_ResumeRuntimeStartupEvent != nullptr && s_ResumeRuntimeStartupEvent->IsValid()) s_ResumeRuntimeStartupEvent->Set(); } diff --git a/src/coreclr/src/vm/diagnosticsprotocol.h b/src/coreclr/src/vm/diagnosticsprotocol.h index a31c698723a0..53e7413c04c8 100644 --- a/src/coreclr/src/vm/diagnosticsprotocol.h +++ b/src/coreclr/src/vm/diagnosticsprotocol.h @@ -112,7 +112,7 @@ namespace DiagnosticsIpc * * See spec in: dotnet/diagnostics@documentation/design-docs/ipc-spec.md * - * The flow for Advertise is a one-way burst of 24 bytes consisting of + * The flow for Advertise is a one-way burst of 34 bytes consisting of * 8 bytes - "ADVR_V1\0" (ASCII chars + null byte) * 16 bytes - random 128 bit number cookie (little-endian) * 8 bytes - PID (little-endian) @@ -123,15 +123,11 @@ namespace DiagnosticsIpc const uint32_t AdvertiseSize = 34; - static GUID AdvertiseCookie_V1 = GUID_NULL; + // initialized in DiagnosticServer::Initialize during EEStartupHelper + extern GUID AdvertiseCookie_V1; inline GUID GetAdvertiseCookie_V1() { - if (AdvertiseCookie_V1 == GUID_NULL) - { - CoCreateGuid(&AdvertiseCookie_V1); - } - return AdvertiseCookie_V1; } @@ -143,8 +139,8 @@ namespace DiagnosticsIpc uint64_t *buffer = (uint64_t*)advertiseBuffer; buffer[0] = *(uint64_t*)AdvertiseMagic_V1; - buffer[1] = (((uint64_t)VAL32(cookie.Data1) << 32) | ((uint64_t)VAL16(cookie.Data2) << 16) | VAL16((uint64_t)cookie.Data3)); - buffer[2] = *(uint64_t*)cookie.Data4; + // fills buffer[1] and buffer[2] + memcpy(&buffer[1], &cookie, sizeof(cookie)); buffer[3] = VAL64(pid); // zero out unused field diff --git a/src/coreclr/src/vm/eventpipe.cpp b/src/coreclr/src/vm/eventpipe.cpp index e0b835f40d79..51264b1f351c 100644 --- a/src/coreclr/src/vm/eventpipe.cpp +++ b/src/coreclr/src/vm/eventpipe.cpp @@ -17,6 +17,7 @@ #include "eventpipesession.h" #include "eventpipejsonfile.h" #include "eventtracebase.h" +#include "ipcstreamfactory.h" #include "sampleprofiler.h" #include "win32threadpool.h" #include "ceemain.h" @@ -38,7 +39,8 @@ Volatile EventPipe::s_allowWrite = 0; unsigned int * EventPipe::s_pProcGroupOffsets = nullptr; #endif Volatile EventPipe::s_numberOfSessions(0); -CQuickArrayList EventPipe::s_rgDeferredEventPipeSessionIds = CQuickArrayList(); +CQuickArrayList EventPipe::s_rgDeferredEnableEventPipeSessionIds = CQuickArrayList(); +CQuickArrayList EventPipe::s_rgDeferredDisableEventPipeSessionIds = CQuickArrayList(); bool EventPipe::s_CanStartThreads = false; // This function is auto-generated from /src/scripts/genEventPipe.py @@ -111,21 +113,34 @@ void EventPipe::FinishInitialize() { STANDARD_VM_CONTRACT; - CrstHolder _crst(GetLock()); + // Enable streaming for any deferred sessions + { + CrstHolder _crst(GetLock()); - s_CanStartThreads = true; + s_CanStartThreads = true; - while (s_rgDeferredEventPipeSessionIds.Size() > 0) - { - EventPipeSessionID id = s_rgDeferredEventPipeSessionIds.Pop(); - if (IsSessionIdInCollection(id)) + while (s_rgDeferredEnableEventPipeSessionIds.Size() > 0) { - EventPipeSession *pSession = reinterpret_cast(id); - pSession->StartStreaming(); + EventPipeSessionID id = s_rgDeferredEnableEventPipeSessionIds.Pop(); + if (IsSessionIdInCollection(id)) + { + EventPipeSession *pSession = reinterpret_cast(id); + pSession->StartStreaming(); + } } + + SampleProfiler::CanStartSampling(); } - SampleProfiler::CanStartSampling(); + // release lock in case someone tried to disable while we held it + // s_rgDeferredDisableEventPipeSessionIds is now safe to access without the + // lock since we've set s_canStartThreads to true inside the lock. Anyone + // who was waiting on that lock will see that state and not mutate the defer list + while (s_rgDeferredDisableEventPipeSessionIds.Size() > 0) + { + EventPipeSessionID id = s_rgDeferredDisableEventPipeSessionIds.Pop(); + DisableHelper(id); + } } // @@ -420,7 +435,7 @@ void EventPipe::StartStreaming(EventPipeSessionID id) } else { - s_rgDeferredEventPipeSessionIds.Push(id); + s_rgDeferredEnableEventPipeSessionIds.Push(id); } } @@ -435,6 +450,27 @@ void EventPipe::Disable(EventPipeSessionID id) } CONTRACTL_END; + // EventPipe::Disable is called synchronously since the diagnostics server is + // single threaded. HOWEVER, if the runtime was suspended in EEStartupHelper, + // then EventPipe::FinishInitialize might not have executed yet. Disabling a session + // needs to either happen before we resume or after initialization. We briefly take the + // lock to check s_CanStartThreads to check whether we've finished initialization. We + // also check whether we are still suspended in which case we can safely disable the session + // without deferral. + { + CrstHolder _crst(GetLock()); + if (!s_CanStartThreads && !IpcStreamFactory::AnySuspendedPorts()) + { + s_rgDeferredDisableEventPipeSessionIds.Push(id); + return; + } + } + + DisableHelper(id); +} + +void EventPipe::DisableHelper(EventPipeSessionID id) +{ if (s_CanStartThreads) SetupThread(); diff --git a/src/coreclr/src/vm/eventpipe.h b/src/coreclr/src/vm/eventpipe.h index c03df4d3ed9f..52e7061d0223 100644 --- a/src/coreclr/src/vm/eventpipe.h +++ b/src/coreclr/src/vm/eventpipe.h @@ -179,6 +179,8 @@ class EventPipe Thread *pEventThread = nullptr, StackContents *pStack = nullptr); + static void DisableHelper(EventPipeSessionID id); + static void DisableInternal(EventPipeSessionID id, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue); // Enable the specified EventPipe session. @@ -239,7 +241,8 @@ class EventPipe static bool s_CanStartThreads; - static CQuickArrayList s_rgDeferredEventPipeSessionIds; + static CQuickArrayList s_rgDeferredEnableEventPipeSessionIds; + static CQuickArrayList s_rgDeferredDisableEventPipeSessionIds; //! Bitmask tracking EventPipe active sessions. // in all groups preceding it. For example if there are three groups with sizes: diff --git a/src/coreclr/src/vm/ipcstreamfactory.cpp b/src/coreclr/src/vm/ipcstreamfactory.cpp index 6a82f166c1da..fc880f3e36ae 100644 --- a/src/coreclr/src/vm/ipcstreamfactory.cpp +++ b/src/coreclr/src/vm/ipcstreamfactory.cpp @@ -7,10 +7,27 @@ #ifdef FEATURE_PERFTRACING -CQuickArrayList IpcStreamFactory::s_rgpConnectionStates = CQuickArrayList(); +CQuickArrayList IpcStreamFactory::s_rgpDiagnosticPorts = CQuickArrayList(); Volatile IpcStreamFactory::s_isShutdown = false; +IpcStreamFactory::DiagnosticPort *IpcStreamFactory::s_currentPort = nullptr; -bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) +CQuickArrayList split(LPSTR string, LPCSTR delimiters) +{ + CQuickArrayList parts; + char *context; + char *part = nullptr; + for (char *cursor = string; ; cursor = nullptr) + { + if ((part = strtok_s(cursor, delimiters, &context)) != nullptr) + parts.Push(part); + else + break; + } + + return parts; +} + +bool IpcStreamFactory::ConnectDiagnosticPort::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) { STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO1000, "IpcStreamFactory::ClientConnectionState::GetIpcPollHandle - ENTER.\n"); if (_pStream == nullptr) @@ -44,81 +61,141 @@ bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::Diagno return true; } -IpcStream *IpcStreamFactory::ClientConnectionState::GetConnectedStream(ErrorCallback callback) +IpcStream *IpcStreamFactory::ConnectDiagnosticPort::GetConnectedStream(ErrorCallback callback) { IpcStream *pStream = _pStream; _pStream = nullptr; return pStream; } -void IpcStreamFactory::ClientConnectionState::Reset(ErrorCallback callback) +void IpcStreamFactory::ConnectDiagnosticPort::Reset(ErrorCallback callback) { delete _pStream; _pStream = nullptr; } -bool IpcStreamFactory::ServerConnectionState::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) +bool IpcStreamFactory::ListenDiagnosticPort::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) { *pIpcPollHandle = { _pIpc, nullptr, 0, this }; return true; } -IpcStream *IpcStreamFactory::ServerConnectionState::GetConnectedStream(ErrorCallback callback) +IpcStream *IpcStreamFactory::ListenDiagnosticPort::GetConnectedStream(ErrorCallback callback) { return _pIpc->Accept(callback); } // noop for server -void IpcStreamFactory::ServerConnectionState::Reset(ErrorCallback) +void IpcStreamFactory::ListenDiagnosticPort::Reset(ErrorCallback) { return; } -bool IpcStreamFactory::CreateServer(const char *const pIpcName, ErrorCallback callback) +bool IpcStreamFactory::Configure(ErrorCallback callback) { - IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(pIpcName, IpcStream::DiagnosticsIpc::ConnectionMode::SERVER, callback); - if (pIpc != nullptr) + bool fSuccess = true; + + NewArrayHolder dotnetDiagnosticPorts = nullptr; + CLRConfigStringHolder dotnetDiagnosticPortsW = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticPorts); + int nCharactersWritten = 0; + if (dotnetDiagnosticPortsW != nullptr) { - if (pIpc->Listen(callback)) - { - s_rgpConnectionStates.Push(new ServerConnectionState(pIpc)); - return true; - } - else + nCharactersWritten = WideCharToMultiByte(CP_UTF8, 0, dotnetDiagnosticPortsW, -1, NULL, 0, NULL, NULL); + dotnetDiagnosticPorts = new char[nCharactersWritten]; + nCharactersWritten = WideCharToMultiByte(CP_UTF8, 0, dotnetDiagnosticPortsW, -1, dotnetDiagnosticPorts, nCharactersWritten, NULL, NULL); + ASSERT(nCharactersWritten != 0); + + CQuickArrayList portConfigs = split(dotnetDiagnosticPorts, ";"); + while (portConfigs.Size() > 0) { - delete pIpc; - return false; + LPSTR portConfig = portConfigs.Pop(); + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::Configure - Attempted to create Diagnostic Port from \"%s\".\n", portConfig); + CQuickArrayList portConfigParts = split(portConfig, ","); + DiagnosticPortBuilder builder; + + if (portConfigParts.Size() == 0) + { + fSuccess &= false; + continue; + } + + while (portConfigParts.Size() > 1) + builder.WithTag(portConfigParts.Pop()); + builder.WithPath(portConfigParts.Pop()); + + // Ignore listen type (see conversation in https://github.com/dotnet/runtime/pull/40499 for details) + if (builder.Type == DiagnosticPortType::LISTEN) + { + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::Configure - Ignoring LISTEN port configuration \n"); + continue; + } + + const bool fBuildSuccess = BuildAndAddPort(builder, callback); + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::Configure - Diagnostic Port creation succeeded? %d \n", fBuildSuccess); + fSuccess &= fBuildSuccess; } } - else - { - return false; - } + + // create the default listen port + DWORD dotnetDiagnosticPortSuspend = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend); + DiagnosticPortBuilder defaultListenPortBuilder = DiagnosticPortBuilder{} + .WithPath(nullptr) + .WithSuspendMode(dotnetDiagnosticPortSuspend > 0 ? DiagnosticPortSuspendMode::SUSPEND : DiagnosticPortSuspendMode::NOSUSPEND) + .WithType(DiagnosticPortType::LISTEN); + + + fSuccess &= BuildAndAddPort(defaultListenPortBuilder, callback); + return fSuccess; } -bool IpcStreamFactory::CreateClient(const char *const pIpcName, ErrorCallback callback) +bool IpcStreamFactory::BuildAndAddPort(IpcStreamFactory::DiagnosticPortBuilder builder, ErrorCallback callback) { - IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(pIpcName, IpcStream::DiagnosticsIpc::ConnectionMode::CLIENT, callback); - if (pIpc != nullptr) + if (builder.Type == DiagnosticPortType::LISTEN) { - s_rgpConnectionStates.Push(new ClientConnectionState(pIpc)); - return true; + IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(builder.Path, IpcStream::DiagnosticsIpc::ConnectionMode::LISTEN, callback); + if (pIpc != nullptr) + { + if (pIpc->Listen(callback)) + { + s_rgpDiagnosticPorts.Push(new ListenDiagnosticPort(pIpc, builder)); + return true; + } + else + { + delete pIpc; + return false; + } + } + else + { + return false; + } } - else + else if (builder.Type == DiagnosticPortType::CONNECT) { - return false; + IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(builder.Path, IpcStream::DiagnosticsIpc::ConnectionMode::CONNECT, callback); + if (pIpc != nullptr) + { + s_rgpDiagnosticPorts.Push(new ConnectDiagnosticPort(pIpc, builder)); + return true; + } + else + { + return false; + } } + return false; } -bool IpcStreamFactory::HasActiveConnections() +bool IpcStreamFactory::HasActivePorts() { - return !s_isShutdown && s_rgpConnectionStates.Size() > 0; + return !s_isShutdown && s_rgpDiagnosticPorts.Size() > 0; } -void IpcStreamFactory::CloseConnections(ErrorCallback callback) +void IpcStreamFactory::ClosePorts(ErrorCallback callback) { - for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) - s_rgpConnectionStates[i]->Close(callback); + for (uint32_t i = 0; i < (uint32_t)s_rgpDiagnosticPorts.Size(); i++) + s_rgpDiagnosticPorts[i]->Close(callback); } void IpcStreamFactory::Shutdown(ErrorCallback callback) @@ -126,8 +203,22 @@ void IpcStreamFactory::Shutdown(ErrorCallback callback) if (s_isShutdown) return; s_isShutdown = true; - for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) - s_rgpConnectionStates[i]->Close(true, callback); + for (uint32_t i = 0; i < (uint32_t)s_rgpDiagnosticPorts.Size(); i++) + s_rgpDiagnosticPorts[i]->Close(true, callback); +} + +bool IpcStreamFactory::AnySuspendedPorts() +{ + bool fAnySuspendedPorts = false; + for (uint32_t i = 0; i < (uint32_t)s_rgpDiagnosticPorts.Size(); i++) + fAnySuspendedPorts |= !(s_rgpDiagnosticPorts[i]->SuspendMode == DiagnosticPortSuspendMode::NOSUSPEND || s_rgpDiagnosticPorts[i]->HasResumedRuntime); + return fAnySuspendedPorts; +} + +void IpcStreamFactory::ResumeCurrentPort() +{ + if (s_currentPort != nullptr) + s_currentPort->HasResumedRuntime = true; } // helper function for getting timeout @@ -158,10 +249,10 @@ IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) while (pStream == nullptr) { fConnectSuccess = true; - for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) + for (uint32_t i = 0; i < (uint32_t)s_rgpDiagnosticPorts.Size(); i++) { IpcStream::DiagnosticsIpc::IpcPollHandle pollHandle = {}; - if (s_rgpConnectionStates[i]->GetIpcPollHandle(&pollHandle, callback)) + if (s_rgpDiagnosticPorts[i]->GetIpcPollHandle(&pollHandle, callback)) { rgIpcPollHandles.Push(pollHandle); } @@ -206,13 +297,16 @@ IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) switch ((IpcStream::DiagnosticsIpc::PollEvents)rgIpcPollHandles[i].revents) { case IpcStream::DiagnosticsIpc::PollEvents::HANGUP: - ((ConnectionState*)(rgIpcPollHandles[i].pUserData))->Reset(callback); + ((DiagnosticPort*)(rgIpcPollHandles[i].pUserData))->Reset(callback); STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - HUP :: Poll attempt: %d, connection %d hung up.\n", nPollAttempts, i); pollTimeoutMs = s_pollTimeoutMinMs; break; case IpcStream::DiagnosticsIpc::PollEvents::SIGNALED: if (pStream == nullptr) // only use first signaled stream; will get others on subsequent calls - pStream = ((ConnectionState*)(rgIpcPollHandles[i].pUserData))->GetConnectedStream(callback); + { + pStream = ((DiagnosticPort*)(rgIpcPollHandles[i].pUserData))->GetConnectedStream(callback); + s_currentPort = (DiagnosticPort*)(rgIpcPollHandles[i].pUserData); + } STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - SIG :: Poll attempt: %d, connection %d signalled.\n", nPollAttempts, i); break; case IpcStream::DiagnosticsIpc::PollEvents::ERR: @@ -232,7 +326,10 @@ IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) if (pStream == nullptr && fSawError) + { + s_currentPort = nullptr; return nullptr; + } // clear the view while (rgIpcPollHandles.Size() > 0) diff --git a/src/coreclr/src/vm/ipcstreamfactory.h b/src/coreclr/src/vm/ipcstreamfactory.h index d65994a1e11d..8eec10faafca 100644 --- a/src/coreclr/src/vm/ipcstreamfactory.h +++ b/src/coreclr/src/vm/ipcstreamfactory.h @@ -11,14 +11,67 @@ class IpcStreamFactory { public: - struct ConnectionState + // forward declare + struct DiagnosticPort; + + enum class DiagnosticPortType : uint8_t + { + LISTEN = 0, + CONNECT = 1 + }; + + enum class DiagnosticPortSuspendMode : uint8_t + { + NOSUSPEND = 0, + SUSPEND = 1 + }; + + struct DiagnosticPortBuilder + { + LPSTR Path = nullptr; + DiagnosticPortType Type = DiagnosticPortType::CONNECT; + DiagnosticPortSuspendMode SuspendMode = DiagnosticPortSuspendMode::NOSUSPEND; + + DiagnosticPortBuilder WithPath(LPSTR path) { Path = path; return *this; } + DiagnosticPortBuilder WithType(DiagnosticPortType type) { Type = type; return *this; } + DiagnosticPortBuilder WithSuspendMode(DiagnosticPortSuspendMode mode) { SuspendMode = mode; return *this; } + DiagnosticPortBuilder WithTag(LPSTR tag) + { + // check if port type + if (_stricmp(tag, "listen") == 0) + return WithType(DiagnosticPortType::LISTEN); + + if (_stricmp(tag, "connect") == 0) + return WithType(DiagnosticPortType::CONNECT); + + // check if suspendmode tag + if (_stricmp(tag, "nosuspend") == 0) + return WithSuspendMode(DiagnosticPortSuspendMode::NOSUSPEND); + + if (_stricmp(tag, "suspend") == 0) + return WithSuspendMode(DiagnosticPortSuspendMode::SUSPEND); + + // don't mutate if it's not a valid option + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::DiagnosticPortBuilder::WithTag - Unknown tag '%s'.\n", tag); + return *this; + } + }; + + struct DiagnosticPort { public: - ConnectionState(IpcStream::DiagnosticsIpc *pIpc) : + DiagnosticPort(IpcStream::DiagnosticsIpc *pIpc, DiagnosticPortBuilder builder) : + SuspendMode(builder.SuspendMode), _pIpc(pIpc), - _pStream(nullptr) + _pStream(nullptr), + _type(builder.Type) { } + const DiagnosticPortSuspendMode SuspendMode; + + // Will be false until ResumeRuntime command is sent on this connection + bool HasResumedRuntime = false; + // returns a pollable handle and performs any preparation required // e.g., as a side-effect, will connect and advertise on reverse connections virtual bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) = 0; @@ -42,11 +95,12 @@ class IpcStreamFactory protected: IpcStream::DiagnosticsIpc *_pIpc; IpcStream *_pStream; + DiagnosticPortType _type; }; - struct ClientConnectionState : public ConnectionState + struct ConnectDiagnosticPort : public DiagnosticPort { - ClientConnectionState(IpcStream::DiagnosticsIpc *pIpc) : ConnectionState(pIpc) { } + ConnectDiagnosticPort(IpcStream::DiagnosticsIpc *pIpc, DiagnosticPortBuilder builder) : DiagnosticPort(pIpc, builder) { } // returns a pollable handle and performs any preparation required bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) override; @@ -58,9 +112,9 @@ class IpcStreamFactory void Reset(ErrorCallback callback = nullptr) override; }; - struct ServerConnectionState : public ConnectionState + struct ListenDiagnosticPort : public DiagnosticPort { - ServerConnectionState(IpcStream::DiagnosticsIpc *pIpc) : ConnectionState(pIpc) { } + ListenDiagnosticPort(IpcStream::DiagnosticsIpc *pIpc, DiagnosticPortBuilder builder) : DiagnosticPort(pIpc, builder) { } // returns a pollable handle and performs any preparation required bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) override; @@ -72,15 +126,20 @@ class IpcStreamFactory void Reset(ErrorCallback callback = nullptr) override; }; - static bool CreateServer(const char *const pIpcName, ErrorCallback = nullptr); - static bool CreateClient(const char *const pIpcName, ErrorCallback = nullptr); + static bool Configure(ErrorCallback callback = nullptr); static IpcStream *GetNextAvailableStream(ErrorCallback = nullptr); - static bool HasActiveConnections(); - static void CloseConnections(ErrorCallback callback = nullptr); + static void ResumeCurrentPort(); + static bool AnySuspendedPorts(); + static bool HasActivePorts(); + static void ClosePorts(ErrorCallback callback = nullptr); static void Shutdown(ErrorCallback callback = nullptr); private: - static CQuickArrayList s_rgpConnectionStates; + static bool BuildAndAddPort(DiagnosticPortBuilder builder, ErrorCallback callback = nullptr); + static CQuickArrayList s_rgpDiagnosticPorts; static Volatile s_isShutdown; + // set this in GetNextAvailableStream, and then expose a callback that + // allows us to track which connections have sent their ResumeRuntime commands + static DiagnosticPort *s_currentPort; // Polling timeout semantics // If client connection is opted in diff --git a/src/tests/tracing/eventpipe/common/IpcUtils.cs b/src/tests/tracing/eventpipe/common/IpcUtils.cs index 2f39237f4b58..85e843022929 100644 --- a/src/tests/tracing/eventpipe/common/IpcUtils.cs +++ b/src/tests/tracing/eventpipe/common/IpcUtils.cs @@ -21,8 +21,8 @@ namespace Tracing.Tests.Common { public static class Utils { - public static readonly string DiagnosticsMonitorAddressEnvKey = "DOTNET_DiagnosticsMonitorAddress"; - public static readonly string DiagnosticsMonitorPauseOnStartEnvKey = "DOTNET_DiagnosticsMonitorPauseOnStart"; + public static readonly string DiagnosticPortsEnvKey = "DOTNET_DiagnosticPorts"; + public static readonly string DiagnosticPortSuspend = "DOTNET_DefaultDiagnosticPortSuspend"; public static async Task WaitTillTimeout(Task task, TimeSpan timeout) { @@ -144,8 +144,10 @@ public static async Task RunSubprocess(Assembly currentAssembly, Dictionar } finally { + Logger.logger.Log($"----------------------------------------"); Logger.logger.Log($"Subprocess stdout: {stdoutSb.ToString()}"); Logger.logger.Log($"Subprocess stderr: {stderrSb.ToString()}"); + Logger.logger.Log($"----------------------------------------"); } @@ -291,6 +293,49 @@ override public string ToString() } } + public class ProcessInfo + { + // uint64_t ProcessId; + // GUID RuntimeCookie; + // LPCWSTR CommandLine; + // LPCWSTR OS; + // LPCWSTR Arch; + public UInt64 ProcessId; + public Guid RuntimeCookie; + public string Commandline; + public string OS; + public string Arch; + + public static ProcessInfo TryParse(byte[] buf) + { + var info = new ProcessInfo(); + int start = 0; + int end = 8; /* sizeof(uint64_t) */ + info.ProcessId = BitConverter.ToUInt64(buf[start..end]); + + start = end; + end = start + 16; /* sizeof(guid) */ + info.RuntimeCookie = new Guid(buf[start..end]); + + string ParseString(ref int start, ref int end) + { + start = end; + end = start + 4; /* sizeof(uint32_t) */ + uint nChars = BitConverter.ToUInt32(buf[start..end]); + + start = end; + end = start + ((int)nChars * sizeof(char)); + return System.Text.Encoding.Unicode.GetString(buf[start..end]).TrimEnd('\0'); + } + + info.Commandline = ParseString(ref start, ref end); + info.OS = ParseString(ref start, ref end); + info.Arch = ParseString(ref start, ref end); + + return info; + } + } + public class IpcClient { public static IpcMessage SendMessage(Stream stream, IpcMessage message) diff --git a/src/tests/tracing/eventpipe/common/Reverse.cs b/src/tests/tracing/eventpipe/common/Reverse.cs index 19c9b216ce84..6bc91ac809bc 100644 --- a/src/tests/tracing/eventpipe/common/Reverse.cs +++ b/src/tests/tracing/eventpipe/common/Reverse.cs @@ -151,6 +151,7 @@ private NamedPipeServerStream GetNewNamedPipeServer() public void Shutdown() { + Logger.logger.Log($"Shutting down Reverse Server at {_serverAddress}"); switch (_server) { case NamedPipeServerStream serverStream: diff --git a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs new file mode 100644 index 000000000000..9d3280b37377 --- /dev/null +++ b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs @@ -0,0 +1,413 @@ +// 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.Diagnostics.Tracing; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.Diagnostics.Tools.RuntimeClient; +using Tracing.Tests.Common; +using System.Threading; +using System.Text; +using System.IO; +using Microsoft.Diagnostics.Tracing; +using Microsoft.Diagnostics.Tracing.Parsers; + +namespace Tracing.Tests.DiagnosticPortValidation +{ + public class DiagnosticPortValidation + { + private static readonly int s_NumberOfPorts = 4; + public static async Task TEST_MultipleConnectPortsNoSuspend() + { + bool fSuccess = true; + var serverAndNames = new List<(ReverseServer, string)>(); + string dotnetDiagnosticPorts = ""; + for (int i = 0; i < s_NumberOfPorts; i++) + { + string serverName = ReverseServer.MakeServerAddress(); + var server = new ReverseServer(serverName); + Logger.logger.Log($"Server {i} address is '{serverName}'"); + serverAndNames.Add((server, serverName)); + dotnetDiagnosticPorts += $"{serverName};"; + } + Logger.logger.Log($"export DOTNET_DiagnosticPorts={dotnetDiagnosticPorts}"); + var advertisements = new List(); + Object sync = new Object(); + int subprocessId = -1; + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary + { + { Utils.DiagnosticPortsEnvKey, dotnetDiagnosticPorts } + }, + duringExecution: async (int pid) => + { + subprocessId = pid; + var tasks = new List(); + for (int i = 0; i < s_NumberOfPorts; i++) + { + var (server, _) = serverAndNames[i]; + int serverIndex = i; + tasks.Add(Task.Run(async () => + { + Stream stream = await server.AcceptAsync(); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + lock(sync) + advertisements.Add(advertise); + Logger.logger.Log($"Server {serverIndex} got advertise {advertise.ToString()}"); + })); + } + + await Task.WhenAll(tasks); + } + ); + + fSuccess &= await subprocessTask; + + foreach (var (server, _) in serverAndNames) + server.Shutdown(); + + Guid referenceCookie = advertisements[0].RuntimeInstanceCookie; + foreach (var adv in advertisements) + { + fSuccess &= (int)adv.ProcessId == subprocessId; + fSuccess &= adv.RuntimeInstanceCookie.Equals(referenceCookie); + } + + return fSuccess; + } + + public static async Task TEST_MultipleConnectPortsSuspend() + { + bool fSuccess = true; + var serverAndNames = new List<(ReverseServer, string)>(); + string dotnetDiagnosticPorts = ""; + for (int i = 0; i < s_NumberOfPorts; i++) + { + string serverName = ReverseServer.MakeServerAddress(); + var server = new ReverseServer(serverName); + Logger.logger.Log($"Server {i} address is '{serverName}'"); + serverAndNames.Add((server, serverName)); + dotnetDiagnosticPorts += $"{serverName},suspend;"; + } + Logger.logger.Log($"export DOTNET_DiagnosticPorts={dotnetDiagnosticPorts}"); + + var advertisements = new List(); + Object sync = new Object(); + + int subprocessId = -1; + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary + { + { Utils.DiagnosticPortsEnvKey, dotnetDiagnosticPorts } + }, + duringExecution: async (int pid) => + { + subprocessId = pid; + // Create an eventpipe session that will tell us when + // the EEStartupStarted event happens. This will tell us + // the the runtime has been resumed. This should only happen + // AFTER all suspend ports have sent the resume command. + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose) + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + + var mre = new ManualResetEvent(false); + + Task readerTask = Task.Run(async () => + { + Logger.logger.Log($"Creating EventPipeEventSource"); + using var source = new EventPipeEventSource(eventStream); + var parser = new ClrPrivateTraceEventParser(source); + parser.StartupEEStartupStart += (eventData) => mre.Set(); + Logger.logger.Log($"Created EventPipeEventSource"); + Logger.logger.Log($"Starting processing"); + await Task.Run(() => source.Process()); + Logger.logger.Log($"Finished processing"); + }); + + for (int i = 0; i < s_NumberOfPorts; i++) + { + fSuccess &= !mre.WaitOne(0); + Logger.logger.Log($"Runtime HAS NOT resumed (expects: true): {fSuccess}"); + var (server, _) = serverAndNames[i]; + int serverIndex = i; + Stream stream = await server.AcceptAsync(); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + lock(sync) + advertisements.Add(advertise); + Logger.logger.Log($"Server {serverIndex} got advertise {advertise.ToString()}"); + + // send resume command on this connection + var message = new IpcMessage(0x04,0x01); + Logger.logger.Log($"Port {serverIndex} sent: {message.ToString()}"); + IpcMessage response = IpcClient.SendMessage(stream, message); + Logger.logger.Log($"Port {serverIndex} received: {response.ToString()}"); + } + + Logger.logger.Log($"Waiting on EEStartupStarted event"); + mre.WaitOne(); + Logger.logger.Log($"Saw EEStartupStarted Event"); + + Logger.logger.Log($"Stopping EventPipeSession"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log($"Stopped EventPipeSession"); + + // runtime should have resumed now + fSuccess &= mre.WaitOne(0); + Logger.logger.Log($"Runtime HAS resumed (expects: true): {fSuccess}"); + + } + ); + + + fSuccess &= await subprocessTask; + foreach (var (server, _) in serverAndNames) + server.Shutdown(); + + if (advertisements.Count() > 0) + { + Guid referenceCookie = advertisements[0].RuntimeInstanceCookie; + foreach (var adv in advertisements) + { + fSuccess &= (int)adv.ProcessId == subprocessId; + fSuccess &= adv.RuntimeInstanceCookie.Equals(referenceCookie); + } + } + else + { + fSuccess &= false; + } + + return fSuccess; + } + + public static async Task TEST_SuspendDefaultPort() + { + bool fSuccess = true; + + int subprocessId = -1; + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary + { + { Utils.DiagnosticPortSuspend, "1" } + }, + duringExecution: async (int pid) => + { + subprocessId = pid; + // Create an eventpipe session that will tell us when + // the EEStartupStarted event happens. This will tell us + // the the runtime has been resumed. This should only happen + // AFTER all suspend ports have sent the resume command. + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose) + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + + var mre = new ManualResetEvent(false); + + Task readerTask = Task.Run(async () => + { + Logger.logger.Log($"Creating EventPipeEventSource"); + using var source = new EventPipeEventSource(eventStream); + var parser = new ClrPrivateTraceEventParser(source); + parser.StartupEEStartupStart += (eventData) => mre.Set(); + Logger.logger.Log($"Created EventPipeEventSource"); + Logger.logger.Log($"Starting processing"); + await Task.Run(() => source.Process()); + Logger.logger.Log($"Finished processing"); + }); + + + fSuccess &= !mre.WaitOne(0); + Logger.logger.Log($"Runtime HAS NOT resumed (expects: true): {fSuccess}"); + + // send resume command on this connection + var message = new IpcMessage(0x04,0x01); + Logger.logger.Log($"Sent: {message.ToString()}"); + IpcMessage response = IpcClient.SendMessage(ConnectionHelper.GetStandardTransport(pid), message); + Logger.logger.Log($"Received: {response.ToString()}"); + + Logger.logger.Log($"Waiting for EEStartupStarted event"); + mre.WaitOne(); + Logger.logger.Log($"Saw EEStartupStarted event!"); + + Logger.logger.Log($"Stopping EventPipeSession"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log($"Stopped EventPipeSession"); + + // runtime should have resumed now + fSuccess &= mre.WaitOne(0); + Logger.logger.Log($"Runtime HAS resumed (expects: true): {fSuccess}"); + + } + ); + + + fSuccess &= await subprocessTask; + + return fSuccess; + } + + public static async Task TEST_AdvertiseAndProcessInfoCookiesMatch() + { + bool fSuccess = true; + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + var server = new ReverseServer(serverName); + using var memoryStream = new MemoryStream(); + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, + duringExecution: async (pid) => + { + Stream stream = await server.AcceptAsync(); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + Logger.logger.Log(advertise.ToString()); + + Logger.logger.Log($"Send ProcessInfo Diagnostics IPC Command"); + // send ProcessInfo command (0x04=ProcessCommandSet, 0x00=ProcessInfo commandid) + var message = new IpcMessage(0x04,0x00); + Logger.logger.Log($"Sent: {message.ToString()}"); + IpcMessage response = IpcClient.SendMessage(stream, message); + Logger.logger.Log($"received: {response.ToString()}"); + ProcessInfo info = ProcessInfo.TryParse(response.Payload); + Logger.logger.Log($"ProcessInfo: {{ id={info.ProcessId}, cookie={info.RuntimeCookie}, cmdline={info.Commandline}, OS={info.OS}, arch={info.Arch} }}"); + + Utils.Assert(info.RuntimeCookie.Equals(advertise.RuntimeInstanceCookie), $"The runtime cookie reported by ProcessInfo and Advertise must match. ProcessInfo: {info.RuntimeCookie.ToString()}, Advertise: {advertise.RuntimeInstanceCookie.ToString()}"); + Logger.logger.Log($"ProcessInfo and Advertise Cookies are equal"); + } + ); + + fSuccess &= await subprocessTask; + + return fSuccess; + } + + public static async Task TEST_ConfigValidation() + { + // load the env var with good and bad configs. Operation of good configs shouldn't be impeded by bad ones. + // This test assumes all good configs have a server at the other end of the specified path. + // Note that while a bad config might not crash the application, it may still degrade the process, e.g., + // a bad configuration that specifies at least a path, will most likely still be built and consume resources polling + // for a server that won't exist. + bool fSuccess = true; + var serverAndNames = new List<(ReverseServer, string)>(); + string dotnetDiagnosticPorts = ""; + dotnetDiagnosticPorts += ";;;;;;"; // empty configs shouldn't cause a crash + dotnetDiagnosticPorts += " ; ; ; ; ; ; ; ; ;"; // whitespace only configs shouldn't cause a crash + dotnetDiagnosticPorts += " , , , , , ;,,,,,;;"; // whitespace configs and empty tags with no path shouldn't cause a crash + dotnetDiagnosticPorts += "connect,connect,connect,nosuspend,nosuspend,nosuspend,,,;"; // path that is the same as a tag name and duplicate tags shouldn't cause a crash + dotnetDiagnosticPorts += "SomeRandomPath,nosuspend,suspend,suspend,suspend,suspend;"; // only the first tag from a pair is respected (this should result in a nosuspend port) + dotnetDiagnosticPorts += "%%bad_Path^* fasdf----##2~~,bad tag$$@#@%_)*)@!#(&%.>, , , , :::;"; // invalid path chars and tag chars won't cause a crash + for (int i = 0; i < s_NumberOfPorts; i++) + { + string serverName = ReverseServer.MakeServerAddress(); + var server = new ReverseServer(serverName); + Logger.logger.Log($"Server {i} address is '{serverName}'"); + serverAndNames.Add((server, serverName)); + dotnetDiagnosticPorts += $"{serverName};"; + dotnetDiagnosticPorts += $"{serverName};"; // duplicating port configs shouldn't cause issues + } + Logger.logger.Log($"export DOTNET_DiagnosticPorts={dotnetDiagnosticPorts}"); + var advertisements = new List(); + Object sync = new Object(); + int subprocessId = -1; + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary + { + { Utils.DiagnosticPortsEnvKey, dotnetDiagnosticPorts } + }, + duringExecution: async (int pid) => + { + subprocessId = pid; + var tasks = new List(); + for (int i = 0; i < s_NumberOfPorts; i++) + { + var (server, _) = serverAndNames[i]; + int serverIndex = i; + tasks.Add(Task.Run(async () => + { + Stream stream = await server.AcceptAsync(); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + lock(sync) + advertisements.Add(advertise); + Logger.logger.Log($"Server {serverIndex} got advertise {advertise.ToString()}"); + })); + } + + await Task.WhenAll(tasks); + } + ); + + fSuccess &= await subprocessTask; + + foreach (var (server, _) in serverAndNames) + server.Shutdown(); + + Guid referenceCookie = advertisements[0].RuntimeInstanceCookie; + foreach (var adv in advertisements) + { + fSuccess &= (int)adv.ProcessId == subprocessId; + fSuccess &= adv.RuntimeInstanceCookie.Equals(referenceCookie); + } + + return fSuccess; + } + + public static async Task Main(string[] args) + { + if (args.Length >= 1) + { + Console.Out.WriteLine("Subprocess started! Waiting for input..."); + var input = Console.In.ReadLine(); // will block until data is sent across stdin + Console.Out.WriteLine($"Received '{input}'. Exiting..."); + return 0; + } + + bool fSuccess = true; + if (!IpcTraceTest.EnsureCleanEnvironment()) + return -1; + IEnumerable tests = typeof(DiagnosticPortValidation).GetMethods().Where(mi => mi.Name.StartsWith("TEST_")); + foreach (var test in tests) + { + Logger.logger.Log($"::== Running test: {test.Name}"); + bool result = true; + try + { + result = await (Task)test.Invoke(null, new object[] {}); + } + catch (Exception e) + { + result = false; + Logger.logger.Log(e.ToString()); + } + fSuccess &= result; + Logger.logger.Log($"Test passed: {result}"); + Logger.logger.Log($""); + + } + return fSuccess ? 100 : -1; + } + } +} diff --git a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj new file mode 100644 index 000000000000..cec9486b658b --- /dev/null +++ b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.csproj @@ -0,0 +1,17 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + true + + true + + + + + + diff --git a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs index 4065cd586fee..1bd8009be85e 100644 --- a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs +++ b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs @@ -28,7 +28,7 @@ public static async Task TEST_RuntimeResumesExecutionWithCommand() var server = new ReverseServer(serverName); Task subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), - environment: new Dictionary { { Utils.DiagnosticsMonitorAddressEnvKey, serverName } }, + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName},suspend" } }, duringExecution: async (_) => { Stream stream = await server.AcceptAsync(); @@ -56,7 +56,7 @@ public static async Task TEST_TracesHaveRelevantEvents() using var memoryStream = new MemoryStream(); Task subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), - environment: new Dictionary { { Utils.DiagnosticsMonitorAddressEnvKey, serverName } }, + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName},suspend" } }, duringExecution: async (pid) => { Stream stream = await server.AcceptAsync(); @@ -114,7 +114,7 @@ public static async Task TEST_MultipleSessionsCanBeStartedWhilepaused() using var memoryStream3 = new MemoryStream(); Task subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), - environment: new Dictionary { { Utils.DiagnosticsMonitorAddressEnvKey, serverName } }, + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName},suspend" } }, duringExecution: async (pid) => { Stream stream = await server.AcceptAsync(); @@ -207,7 +207,7 @@ public static async Task TEST_CanStartAndStopSessionWhilepaused() using var memoryStream3 = new MemoryStream(); Task subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), - environment: new Dictionary { { Utils.DiagnosticsMonitorAddressEnvKey, serverName } }, + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName},suspend" } }, duringExecution: async (pid) => { Stream stream = await server.AcceptAsync(); @@ -271,7 +271,7 @@ public static async Task TEST_DisabledCommandsError() using var memoryStream3 = new MemoryStream(); Task subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), - environment: new Dictionary { { Utils.DiagnosticsMonitorAddressEnvKey, serverName } }, + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName},suspend" } }, duringExecution: async (pid) => { Stream stream = await server.AcceptAsync(); diff --git a/src/tests/tracing/eventpipe/reverse/reverse.cs b/src/tests/tracing/eventpipe/reverse/reverse.cs index 05436e574d64..d26c4ee5d87a 100644 --- a/src/tests/tracing/eventpipe/reverse/reverse.cs +++ b/src/tests/tracing/eventpipe/reverse/reverse.cs @@ -28,8 +28,7 @@ public static async Task TEST_RuntimeIsResilientToServerClosing() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (_) => { @@ -59,8 +58,7 @@ public static async Task TEST_RuntimeConnectsToExistingServer() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (_) => { @@ -85,8 +83,7 @@ public static async Task TEST_CanConnectServerAndClientAtSameTime() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (int pid) => { @@ -139,8 +136,7 @@ public static async Task TEST_ServerWorksIfClientDoesntAccept() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (int pid) => { @@ -181,8 +177,7 @@ public static async Task TEST_ServerIsResilientToNoBufferAgent() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (int pid) => { @@ -220,8 +215,7 @@ public static async Task TEST_StandardConnectionStillWorksIfReverseConnect currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (int pid) => { diff --git a/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs b/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs index 15eadb015f58..fda0410e1120 100644 --- a/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs +++ b/src/tests/tracing/eventpipe/reverseouter/reverseouter.cs @@ -28,8 +28,7 @@ public static async Task TEST_ReverseConnectionCanRecycleWhileTracing() currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary { - { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, - { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } + { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async (int pid) => { From 693cb577d08178573768d09f6961308994e3320f Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Thu, 13 Aug 2020 22:43:30 -0300 Subject: [PATCH 479/755] [wasm] Changing debugger wasm test (#40792) * Change test to run the same test on mono/mono and on dotnet/runtime. * Update src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs Co-authored-by: Larry Ewing Co-authored-by: Larry Ewing --- src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 422b2ce1bfb4..34dc5ef605de 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -1482,7 +1482,7 @@ await insp.Ready(async (cli, token) => AssertEqual("WriteLine", top_frame["functionName"]?.Value(), "Expected to be in WriteLine method"); var script_id = top_frame["functionLocation"]["scriptId"].Value(); - AssertEqual("dotnet://System.Console.dll/Console.cs", scripts[script_id], "Expected to stopped in System.Console.WriteLine"); + Assert.Matches ("^dotnet://(mscorlib|System\\.Console)\\.dll/Console.cs", scripts[script_id]); }); } From 133c3761759d7b8a354381c2f1cf3a03a84165f5 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 13 Aug 2020 19:41:56 -0700 Subject: [PATCH 480/755] Make sure Debug.Fail and other similar methods have frame on the stack (#40807) Debugger treats them in a special way Partial fix for #40793 --- .../src/System/Diagnostics/Debugger.cs | 3 --- src/coreclr/src/vm/corelib.h | 2 +- src/coreclr/src/vm/jithelpers.cpp | 17 ++--------------- .../src/System/Diagnostics/Debug.cs | 2 ++ 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 5e51ac062923..1d026a643233 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -16,9 +16,6 @@ public static class Debugger [MethodImpl(MethodImplOptions.NoInlining)] public static void Break() => BreakInternal(); - // The VM depends on this private method. - private static void BreakCanThrow() => BreakInternal(); - [MethodImpl(MethodImplOptions.InternalCall)] private static extern void BreakInternal(); diff --git a/src/coreclr/src/vm/corelib.h b/src/coreclr/src/vm/corelib.h index e7b66f25d5f9..5b08cc4695c6 100644 --- a/src/coreclr/src/vm/corelib.h +++ b/src/coreclr/src/vm/corelib.h @@ -972,7 +972,7 @@ DEFINE_CLASS_U(Threading, WaitHandle, WaitHandleBase) DEFINE_FIELD_U(_waitHandle, WaitHandleBase, m_safeHandle) DEFINE_CLASS(DEBUGGER, Diagnostics, Debugger) -DEFINE_METHOD(DEBUGGER, BREAK_CAN_THROW, BreakCanThrow, SM_RetVoid) +DEFINE_METHOD(DEBUGGER, BREAK, Break, SM_RetVoid) DEFINE_CLASS(BUFFER, System, Buffer) DEFINE_METHOD(BUFFER, MEMCPY_PTRBYTE_ARRBYTE, Memcpy, SM_PtrByte_Int_ArrByte_Int_Int_RetVoid) diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index 54e0cb016609..6eb63a5b6c83 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -4601,17 +4601,8 @@ HCIMPLEND; //======================================================================== /*********************************************************************/ -// JIT_UserBreakpoint // Called by the JIT whenever a cee_break instruction should be executed. -// This ensures that enough info will be pushed onto the stack so that -// we can continue from the exception w/o having special code elsewhere. -// Body of function is written by debugger team -// Args: None // -// make sure this actually gets called by all JITters -// Note: this code is duplicated in the ecall in VM\DebugDebugger:Break, -// so propogate changes to there - HCIMPL0(void, JIT_UserBreakpoint) { FCALL_CONTRACT; @@ -4621,12 +4612,9 @@ HCIMPL0(void, JIT_UserBreakpoint) #ifdef DEBUGGING_SUPPORTED FrameWithCookie __def; - MethodDescCallSite breakCanThrow(METHOD__DEBUGGER__BREAK_CAN_THROW); + MethodDescCallSite debuggerBreak(METHOD__DEBUGGER__BREAK); - // Call Diagnostic.Debugger.BreakCanThrow instead. This will make us demand - // UnmanagedCode permission if debugger is not attached. - // - breakCanThrow.Call((ARG_SLOT*)NULL); + debuggerBreak.Call((ARG_SLOT*)NULL); __def.Pop(); #else // !DEBUGGING_SUPPORTED @@ -4648,7 +4636,6 @@ extern "C" void * _ReturnAddress(void); // if (*pFlag != 0) call JIT_DbgIsJustMyCode // So this is only called if the flag (obtained by GetJMCFlagAddr) is // non-zero. -// Body of this function is maintained by the debugger people. HCIMPL0(void, JIT_DbgIsJustMyCode) { FCALL_CONTRACT; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs index 8f579c749ee8..da744f6d7bee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs @@ -5,6 +5,7 @@ #define DEBUG using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Threading; namespace System.Diagnostics @@ -114,6 +115,7 @@ public static void Fail(string? message) => [System.Diagnostics.Conditional("DEBUG")] [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] // Preserve the frame for debugger public static void Fail(string? message, string? detailMessage) => s_provider.Fail(message, detailMessage); From 47345cd0a15c822d6d25f30fd9d63ff1f342d93a Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Fri, 14 Aug 2020 05:05:27 +0200 Subject: [PATCH 481/755] Add telemetry to System.Net.Security (#40108) * Add telemetry to System.Net.Security * Remove leftover test code * Add Assert to ensure new counters are added with new TLS versions * Add Telemetry.IsEnabled() check * Rename opened connections to opened sessions * Add all-sessions-open and all-handshake-duration counters * Rename all- counters to all-tls- --- .../src/System.Net.Security.csproj | 3 + .../Net/Security/NetSecurityTelemetry.cs | 307 ++++++++++++++++++ .../Net/Security/SslStream.Implementation.cs | 101 +++++- .../src/System/Net/Security/SslStream.cs | 74 +++-- .../System.Net.Security.Tests.csproj | 1 + .../tests/FunctionalTests/TelemetryTest.cs | 161 +++++++++ 6 files changed, 606 insertions(+), 41 deletions(-) create mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/NetSecurityTelemetry.cs create mode 100644 src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 9c5b528027f2..2a4ed69ad0f0 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -20,6 +20,7 @@ + @@ -50,6 +51,8 @@ Link="Common\System\Net\Logging\NetEventSource.Common.cs" /> + diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/NetSecurityTelemetry.cs b/src/libraries/System.Net.Security/src/System/Net/Security/NetSecurityTelemetry.cs new file mode 100644 index 000000000000..f283faf6ee46 --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/NetSecurityTelemetry.cs @@ -0,0 +1,307 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.Tracing; +using System.Security.Authentication; +using System.Threading; +using Microsoft.Extensions.Internal; + +namespace System.Net.Security +{ + [EventSource(Name = "System.Net.Security")] + internal sealed class NetSecurityTelemetry : EventSource + { + public static readonly NetSecurityTelemetry Log = new NetSecurityTelemetry(); + + private IncrementingPollingCounter? _tlsHandshakeRateCounter; + private PollingCounter? _totalTlsHandshakesCounter; + private PollingCounter? _currentTlsHandshakesCounter; + private PollingCounter? _failedTlsHandshakesCounter; + private PollingCounter? _sessionsOpenCounter; + private PollingCounter? _sessionsOpenTls10Counter; + private PollingCounter? _sessionsOpenTls11Counter; + private PollingCounter? _sessionsOpenTls12Counter; + private PollingCounter? _sessionsOpenTls13Counter; + private EventCounter? _handshakeDurationCounter; + private EventCounter? _handshakeDurationTls10Counter; + private EventCounter? _handshakeDurationTls11Counter; + private EventCounter? _handshakeDurationTls12Counter; + private EventCounter? _handshakeDurationTls13Counter; + + private long _finishedTlsHandshakes; // Successfully and failed + private long _startedTlsHandshakes; + private long _failedTlsHandshakes; + private long _sessionsOpen; + private long _sessionsOpenTls10; + private long _sessionsOpenTls11; + private long _sessionsOpenTls12; + private long _sessionsOpenTls13; + + protected override void OnEventCommand(EventCommandEventArgs command) + { + if (command.Command == EventCommand.Enable) + { + _tlsHandshakeRateCounter ??= new IncrementingPollingCounter("tls-handshake-rate", this, () => Interlocked.Read(ref _finishedTlsHandshakes)) + { + DisplayName = "TLS handshakes completed", + DisplayRateTimeScale = TimeSpan.FromSeconds(1) + }; + + _totalTlsHandshakesCounter ??= new PollingCounter("total-tls-handshakes", this, () => Interlocked.Read(ref _finishedTlsHandshakes)) + { + DisplayName = "Total TLS handshakes completed" + }; + + _currentTlsHandshakesCounter ??= new PollingCounter("current-tls-handshakes", this, () => -Interlocked.Read(ref _finishedTlsHandshakes) + Interlocked.Read(ref _startedTlsHandshakes)) + { + DisplayName = "Current TLS handshakes" + }; + + _failedTlsHandshakesCounter ??= new PollingCounter("failed-tls-handshakes", this, () => Interlocked.Read(ref _failedTlsHandshakes)) + { + DisplayName = "Total TLS handshakes failed" + }; + + _sessionsOpenCounter ??= new PollingCounter("all-tls-sessions-open", this, () => Interlocked.Read(ref _sessionsOpen)) + { + DisplayName = "All TLS Sessions Active" + }; + + _sessionsOpenTls10Counter ??= new PollingCounter("tls10-sessions-open", this, () => Interlocked.Read(ref _sessionsOpenTls10)) + { + DisplayName = "TLS 1.0 Sessions Active" + }; + + _sessionsOpenTls11Counter ??= new PollingCounter("tls11-sessions-open", this, () => Interlocked.Read(ref _sessionsOpenTls11)) + { + DisplayName = "TLS 1.1 Sessions Active" + }; + + _sessionsOpenTls12Counter ??= new PollingCounter("tls12-sessions-open", this, () => Interlocked.Read(ref _sessionsOpenTls12)) + { + DisplayName = "TLS 1.2 Sessions Active" + }; + + _sessionsOpenTls13Counter ??= new PollingCounter("tls13-sessions-open", this, () => Interlocked.Read(ref _sessionsOpenTls13)) + { + DisplayName = "TLS 1.3 Sessions Active" + }; + + _handshakeDurationCounter ??= new EventCounter("all-tls-handshake-duration", this) + { + DisplayName = "TLS Handshake Duration", + DisplayUnits = "ms" + }; + + _handshakeDurationTls10Counter ??= new EventCounter("tls10-handshake-duration", this) + { + DisplayName = "TLS 1.0 Handshake Duration", + DisplayUnits = "ms" + }; + + _handshakeDurationTls11Counter ??= new EventCounter("tls11-handshake-duration", this) + { + DisplayName = "TLS 1.1 Handshake Duration", + DisplayUnits = "ms" + }; + + _handshakeDurationTls12Counter ??= new EventCounter("tls12-handshake-duration", this) + { + DisplayName = "TLS 1.2 Handshake Duration", + DisplayUnits = "ms" + }; + + _handshakeDurationTls13Counter ??= new EventCounter("tls13-handshake-duration", this) + { + DisplayName = "TLS 1.3 Handshake Duration", + DisplayUnits = "ms" + }; + } + } + + + [Event(1, Level = EventLevel.Informational)] + public void HandshakeStart(bool isServer, string targetHost) + { + Interlocked.Increment(ref _startedTlsHandshakes); + + if (IsEnabled(EventLevel.Informational, EventKeywords.None)) + { + WriteEvent(eventId: 1, isServer, targetHost); + } + } + + [Event(2, Level = EventLevel.Informational)] + private void HandshakeStop(string protocol) + { + if (IsEnabled(EventLevel.Informational, EventKeywords.None)) + { + WriteEvent(eventId: 2, protocol); + } + } + + [Event(3, Level = EventLevel.Error)] + private void HandshakeFailed(bool isServer, double elapsedMilliseconds, string exceptionMessage) + { + WriteEvent(eventId: 3, isServer, elapsedMilliseconds, exceptionMessage); + } + + + [NonEvent] + public void HandshakeFailed(bool isServer, ValueStopwatch stopwatch, string exceptionMessage) + { + Interlocked.Increment(ref _finishedTlsHandshakes); + Interlocked.Increment(ref _failedTlsHandshakes); + + if (IsEnabled(EventLevel.Error, EventKeywords.None)) + { + HandshakeFailed(isServer, stopwatch.GetElapsedTime().TotalMilliseconds, exceptionMessage); + } + + HandshakeStop(protocol: string.Empty); + } + + [NonEvent] + public void HandshakeCompleted(SslProtocols protocol, ValueStopwatch stopwatch, bool connectionOpen) + { + Interlocked.Increment(ref _finishedTlsHandshakes); + + long dummy = 0; + ref long protocolSessionsOpen = ref dummy; + EventCounter? handshakeDurationCounter = null; + + Debug.Assert(Enum.GetValues()[^1] == SslProtocols.Tls13, "Make sure to add a counter for new SslProtocols"); + + switch (protocol) + { + case SslProtocols.Tls: + protocolSessionsOpen = ref _sessionsOpenTls10; + handshakeDurationCounter = _handshakeDurationTls10Counter; + break; + + case SslProtocols.Tls11: + protocolSessionsOpen = ref _sessionsOpenTls11; + handshakeDurationCounter = _handshakeDurationTls11Counter; + break; + + case SslProtocols.Tls12: + protocolSessionsOpen = ref _sessionsOpenTls12; + handshakeDurationCounter = _handshakeDurationTls12Counter; + break; + + case SslProtocols.Tls13: + protocolSessionsOpen = ref _sessionsOpenTls13; + handshakeDurationCounter = _handshakeDurationTls13Counter; + break; + } + + if (connectionOpen) + { + Interlocked.Increment(ref protocolSessionsOpen); + Interlocked.Increment(ref _sessionsOpen); + } + + double duration = stopwatch.GetElapsedTime().TotalMilliseconds; + handshakeDurationCounter?.WriteMetric(duration); + _handshakeDurationCounter!.WriteMetric(duration); + + if (IsEnabled(EventLevel.Informational, EventKeywords.None)) + { + HandshakeStop(protocol.ToString()); + } + } + + [NonEvent] + public void ConnectionClosed(SslProtocols protocol) + { + long count = 0; + + switch (protocol) + { + case SslProtocols.Tls: + count = Interlocked.Decrement(ref _sessionsOpenTls10); + break; + + case SslProtocols.Tls11: + count = Interlocked.Decrement(ref _sessionsOpenTls11); + break; + + case SslProtocols.Tls12: + count = Interlocked.Decrement(ref _sessionsOpenTls12); + break; + + case SslProtocols.Tls13: + count = Interlocked.Decrement(ref _sessionsOpenTls13); + break; + } + + Debug.Assert(count >= 0); + + count = Interlocked.Decrement(ref _sessionsOpen); + Debug.Assert(count >= 0); + } + + + [NonEvent] + private unsafe void WriteEvent(int eventId, bool arg1, string? arg2) + { + if (IsEnabled()) + { + arg2 ??= string.Empty; + + fixed (char* arg2Ptr = arg2) + { + const int NumEventDatas = 2; + EventData* descrs = stackalloc EventData[NumEventDatas]; + + descrs[0] = new EventData + { + DataPointer = (IntPtr)(&arg1), + Size = sizeof(int) // EventSource defines bool as a 32-bit type + }; + descrs[1] = new EventData + { + DataPointer = (IntPtr)(arg2Ptr), + Size = (arg2.Length + 1) * sizeof(char) + }; + + WriteEventCore(eventId, NumEventDatas, descrs); + } + } + } + + [NonEvent] + private unsafe void WriteEvent(int eventId, bool arg1, double arg2, string? arg3) + { + if (IsEnabled()) + { + arg3 ??= string.Empty; + + fixed (char* arg3Ptr = arg3) + { + const int NumEventDatas = 3; + EventData* descrs = stackalloc EventData[NumEventDatas]; + + descrs[0] = new EventData + { + DataPointer = (IntPtr)(&arg1), + Size = sizeof(int) // EventSource defines bool as a 32-bit type + }; + descrs[1] = new EventData + { + DataPointer = (IntPtr)(&arg2), + Size = sizeof(double) + }; + descrs[2] = new EventData + { + DataPointer = (IntPtr)(arg3Ptr), + Size = (arg3.Length + 1) * sizeof(char) + }; + + WriteEventCore(eventId, NumEventDatas, descrs); + } + } + } + } +} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 5af70ed4cde3..74fb33ec3b50 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -10,6 +10,7 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Internal; namespace System.Net.Security { @@ -41,6 +42,12 @@ private enum Framing private const int InitialHandshakeBufferSize = 4096 + FrameOverhead; // try to fit at least 4K ServerCertificate private ArrayBuffer _handshakeBuffer; + // Used by Telemetry to ensure we log connection close exactly once + // 0 = no handshake + // 1 = handshake completed, connection opened + // 2 = SslStream disposed, connection closed + private int _connectionOpenedStatus; + private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback? remoteCallback, LocalCertSelectionCallback? localCallback) { ThrowIfExceptional(); @@ -146,6 +153,15 @@ private void CloseInternal() // Suppress finalizer if the read buffer was returned. GC.SuppressFinalize(this); } + + if (NetSecurityTelemetry.Log.IsEnabled()) + { + // Set the status to disposed. If it was opened before, log ConnectionClosed + if (Interlocked.Exchange(ref _connectionOpenedStatus, 2) == 1) + { + NetSecurityTelemetry.Log.ConnectionClosed(GetSslProtocolInternal()); + } + } } private SecurityStatusPal EncryptData(ReadOnlyMemory buffer, ref byte[] outBuffer, out int outSize) @@ -182,21 +198,92 @@ private SecurityStatusPal PrivateDecryptData(byte[]? buffer, ref int offset, ref // private Task? ProcessAuthentication(bool isAsync = false, bool isApm = false, CancellationToken cancellationToken = default) { - Task? result; - ThrowIfExceptional(); - if (isAsync) + if (NetSecurityTelemetry.Log.IsEnabled()) { - result = ForceAuthenticationAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), _context!.IsServer, null, isApm); + return ProcessAuthenticationWithTelemetry(isAsync, isApm, cancellationToken); } else { - ForceAuthenticationAsync(new SyncReadWriteAdapter(InnerStream), _context!.IsServer, null).GetAwaiter().GetResult(); - result = null; + if (isAsync) + { + return ForceAuthenticationAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), _context!.IsServer, null, isApm); + } + else + { + ForceAuthenticationAsync(new SyncReadWriteAdapter(InnerStream), _context!.IsServer, null).GetAwaiter().GetResult(); + return null; + } + } + } + + private Task? ProcessAuthenticationWithTelemetry(bool isAsync, bool isApm, CancellationToken cancellationToken) + { + NetSecurityTelemetry.Log.HandshakeStart(_context!.IsServer, _sslAuthenticationOptions!.TargetHost); + ValueStopwatch stopwatch = ValueStopwatch.StartNew(); + + try + { + if (isAsync) + { + Task task = ForceAuthenticationAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), _context.IsServer, null, isApm); + + return task.ContinueWith((t, s) => + { + var tuple = (Tuple)s!; + SslStream thisRef = tuple.Item1; + ValueStopwatch stopwatch = tuple.Item2; + + if (t.IsCompletedSuccessfully) + { + LogSuccess(thisRef, stopwatch); + } + else + { + LogFailure(thisRef._context!.IsServer, stopwatch, t.Exception?.Message ?? "Operation canceled."); + + // Throw the same exception we would if not using Telemetry + t.GetAwaiter().GetResult(); + } + }, + state: Tuple.Create(this, stopwatch), + cancellationToken: default, + TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Current); + } + else + { + ForceAuthenticationAsync(new SyncReadWriteAdapter(InnerStream), _context.IsServer, null).GetAwaiter().GetResult(); + LogSuccess(this, stopwatch); + return null; + } + } + catch (Exception ex) when (LogFailure(_context.IsServer, stopwatch, ex.Message)) + { + Debug.Fail("LogFailure should return false"); + throw; + } + + static bool LogFailure(bool isServer, ValueStopwatch stopwatch, string exceptionMessage) + { + NetSecurityTelemetry.Log.HandshakeFailed(isServer, stopwatch, exceptionMessage); + return false; } - return result; + static void LogSuccess(SslStream thisRef, ValueStopwatch stopwatch) + { + // SslStream could already have been disposed at this point, in which case _connectionOpenedStatus == 2 + // Make sure that we increment the open connection counter only if it is guaranteed to be decremented in dispose/finalize + + // Using a field of a marshal-by-reference class as a ref or out value or taking its address may cause a runtime exception + // Justification: thisRef is a reference to 'this', not a proxy object +#pragma warning disable CS0197 + bool connectionOpen = Interlocked.CompareExchange(ref thisRef._connectionOpenedStatus, 1, 0) == 0; +#pragma warning restore CS0197 + + NetSecurityTelemetry.Log.HandshakeCompleted(thisRef.GetSslProtocolInternal(), stopwatch, connectionOpen); + } } // diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs index f896c0ea0a63..03cf0a8d90f5 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -470,50 +470,56 @@ public virtual SslProtocols SslProtocol get { ThrowIfExceptionalOrNotHandshake(); - SslConnectionInfo? info = _context!.ConnectionInfo; - if (info == null) - { - return SslProtocols.None; - } + return GetSslProtocolInternal(); + } + } + + // Skips the ThrowIfExceptionalOrNotHandshake() check + private SslProtocols GetSslProtocolInternal() + { + SslConnectionInfo? info = _context!.ConnectionInfo; + if (info == null) + { + return SslProtocols.None; + } - SslProtocols proto = (SslProtocols)info.Protocol; - SslProtocols ret = SslProtocols.None; + SslProtocols proto = (SslProtocols)info.Protocol; + SslProtocols ret = SslProtocols.None; #pragma warning disable 0618 // Ssl2, Ssl3 are deprecated. - // Restore client/server bits so the result maps exactly on published constants. - if ((proto & SslProtocols.Ssl2) != 0) - { - ret |= SslProtocols.Ssl2; - } + // Restore client/server bits so the result maps exactly on published constants. + if ((proto & SslProtocols.Ssl2) != 0) + { + ret |= SslProtocols.Ssl2; + } - if ((proto & SslProtocols.Ssl3) != 0) - { - ret |= SslProtocols.Ssl3; - } + if ((proto & SslProtocols.Ssl3) != 0) + { + ret |= SslProtocols.Ssl3; + } #pragma warning restore - if ((proto & SslProtocols.Tls) != 0) - { - ret |= SslProtocols.Tls; - } - - if ((proto & SslProtocols.Tls11) != 0) - { - ret |= SslProtocols.Tls11; - } + if ((proto & SslProtocols.Tls) != 0) + { + ret |= SslProtocols.Tls; + } - if ((proto & SslProtocols.Tls12) != 0) - { - ret |= SslProtocols.Tls12; - } + if ((proto & SslProtocols.Tls11) != 0) + { + ret |= SslProtocols.Tls11; + } - if ((proto & SslProtocols.Tls13) != 0) - { - ret |= SslProtocols.Tls13; - } + if ((proto & SslProtocols.Tls12) != 0) + { + ret |= SslProtocols.Tls12; + } - return ret; + if ((proto & SslProtocols.Tls13) != 0) + { + ret |= SslProtocols.Tls13; } + + return ret; } public virtual bool CheckCertRevocationStatus => _context != null && _context.CheckCertRevocationStatus != X509RevocationMode.NoCheck; diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 84bada8bc9ff..04e1831f2edf 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -88,6 +88,7 @@ + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs new file mode 100644 index 000000000000..1ce02cf14a1c --- /dev/null +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs @@ -0,0 +1,161 @@ +// 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.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.DotNet.RemoteExecutor; +using Xunit; + +namespace System.Net.Security.Tests +{ + public class TelemetryTest + { + [Fact] + public static void EventSource_ExistsWithCorrectId() + { + Type esType = typeof(SslStream).Assembly.GetType("System.Net.Security.NetSecurityTelemetry", throwOnError: true, ignoreCase: false); + Assert.NotNull(esType); + + Assert.Equal("System.Net.Security", EventSource.GetName(esType)); + Assert.Equal(Guid.Parse("7beee6b1-e3fa-5ddb-34be-1404ad0e2520"), EventSource.GetGuid(esType)); + + Assert.NotEmpty(EventSource.GenerateManifest(esType, esType.Assembly.Location)); + } + + [OuterLoop] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void EventSource_SuccessfulHandshake_LogsStartStop() + { + RemoteExecutor.Invoke(async () => + { + using var listener = new TestEventListener("System.Net.Security", EventLevel.Verbose, eventCounterInterval: 0.1d); + + var events = new ConcurrentQueue(); + await listener.RunWithCallbackAsync(events.Enqueue, async () => + { + // Invoke tests that'll cause some events to be generated + var test = new SslStreamStreamToStreamTest_Async(); + await test.SslStream_StreamToStream_Authentication_Success(); + await Task.Delay(300); + }); + Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself + + EventWrittenEventArgs[] starts = events.Where(e => e.EventName == "HandshakeStart").ToArray(); + Assert.Equal(2, starts.Length); + Assert.All(starts, s => Assert.Equal(2, s.Payload.Count)); + Assert.Single(starts, s => s.Payload[0] is bool isServer && isServer); + Assert.Single(starts, s => s.Payload[1] is string targetHost && targetHost.Length == 0); + + EventWrittenEventArgs[] stops = events.Where(e => e.EventName == "HandshakeStop").ToArray(); + Assert.Equal(2, stops.Length); + Assert.All(stops, s => Assert.Equal(1, s.Payload.Count)); + Assert.All(stops, s => Assert.NotEmpty(s.Payload[0] as string)); + + Assert.DoesNotContain(events, e => e.EventName == "HandshakeFailed"); + + VerifyEventCounters(events, shouldHaveFailures: false); + }).Dispose(); + } + + [OuterLoop] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void EventSource_UnsuccessfulHandshake_LogsStartFailureStop() + { + RemoteExecutor.Invoke(async () => + { + using var listener = new TestEventListener("System.Net.Security", EventLevel.Verbose, eventCounterInterval: 0.1d); + + var events = new ConcurrentQueue(); + await listener.RunWithCallbackAsync(events.Enqueue, async () => + { + // Invoke tests that'll cause some events to be generated + var test = new SslStreamStreamToStreamTest_Async(); + await test.SslStream_ServerLocalCertificateSelectionCallbackReturnsNull_Throw(); + await Task.Delay(300); + }); + Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself + + EventWrittenEventArgs[] starts = events.Where(e => e.EventName == "HandshakeStart").ToArray(); + Assert.Equal(2, starts.Length); + Assert.All(starts, s => Assert.Equal(2, s.Payload.Count)); + Assert.Single(starts, s => s.Payload[0] is bool isServer && isServer); + Assert.Single(starts, s => s.Payload[1] is string targetHost && targetHost.Length == 0); + + EventWrittenEventArgs[] failures = events.Where(e => e.EventName == "HandshakeFailed").ToArray(); + Assert.Equal(2, failures.Length); + Assert.All(failures, f => Assert.Equal(3, f.Payload.Count)); + Assert.Single(failures, f => f.Payload[0] is bool isServer && isServer); + Assert.All(failures, f => Assert.NotEmpty(f.Payload[2] as string)); // exceptionMessage + + EventWrittenEventArgs[] stops = events.Where(e => e.EventName == "HandshakeStop").ToArray(); + Assert.Equal(2, stops.Length); + Assert.All(stops, s => Assert.Equal(1, s.Payload.Count)); + Assert.All(stops, s => Assert.Empty(s.Payload[0] as string)); + + VerifyEventCounters(events, shouldHaveFailures: true); + }).Dispose(); + } + + private static void VerifyEventCounters(ConcurrentQueue events, bool shouldHaveFailures) + { + Dictionary eventCounters = events + .Where(e => e.EventName == "EventCounters") + .Select(e => (IDictionary)e.Payload.Single()) + .GroupBy(d => (string)d["Name"], d => (double)(d.ContainsKey("Mean") ? d["Mean"] : d["Increment"])) + .ToDictionary(p => p.Key, p => p.ToArray()); + + Assert.True(eventCounters.TryGetValue("total-tls-handshakes", out double[] totalHandshakes)); + Assert.Equal(2, totalHandshakes[^1]); + + Assert.True(eventCounters.TryGetValue("tls-handshake-rate", out double[] handshakeRate)); + Assert.Contains(handshakeRate, r => r > 0); + + Assert.True(eventCounters.TryGetValue("failed-tls-handshakes", out double[] failedHandshakes)); + if (shouldHaveFailures) + { + Assert.Equal(2, failedHandshakes[^1]); + } + else + { + Assert.All(failedHandshakes, f => Assert.Equal(0, f)); + } + + Assert.True(eventCounters.TryGetValue("current-tls-handshakes", out double[] currentHandshakes)); + Assert.Contains(currentHandshakes, h => h > 0); + Assert.Equal(0, currentHandshakes[^1]); + + double[] openedSessions = eventCounters + .Where(pair => pair.Key.EndsWith("-sessions-open")) + .Select(pair => pair.Value[^1]) + .ToArray(); + + // Events should be emitted for all 5 sessions-open counters + Assert.Equal(5, openedSessions.Length); + Assert.All(openedSessions, oc => Assert.Equal(0, oc)); + + + double[] allHandshakeDurations = eventCounters["all-tls-handshake-duration"]; + double[][] tlsHandshakeDurations = eventCounters + .Where(pair => pair.Key.StartsWith("tls") && pair.Key.EndsWith("-handshake-duration")) + .Select(pair => pair.Value) + .ToArray(); + + // Events should be emitted for all 4 tls**-handshake-duration counters + Assert.Equal(4, tlsHandshakeDurations.Length); + + if (shouldHaveFailures) + { + Assert.All(tlsHandshakeDurations, durations => Assert.All(durations, d => Assert.Equal(0, d))); + Assert.All(allHandshakeDurations, d => Assert.Equal(0, d)); + } + else + { + Assert.Contains(tlsHandshakeDurations, durations => durations.Any(d => d > 0)); + Assert.Contains(allHandshakeDurations, d => d > 0); + } + } + } +} From f0461cb51032e45cbcabf2152e0c82c8c5a890bc Mon Sep 17 00:00:00 2001 From: Jeff Handley Date: Thu, 13 Aug 2020 20:21:13 -0700 Subject: [PATCH 482/755] Mark DirectoryServices CAS APIs as Obsolete (#40756) * Mark DirectoryServices CAS APIs as Obsolete (using an internal attribute) * Refactor how the internal ObsoleteAttribute is pulled in and applied * Include internal ObsoleteAttribute for all netcoreapp (not just netcoreapp2) * Simplify netstandard check for the internal ObsoleteAttribute * Remove IncludeInternalObsoleteAttribute from Directory.Build.props --- src/libraries/Directory.Build.targets | 13 +++++++++++++ .../ref/System.DirectoryServices.cs | 2 ++ .../ref/System.DirectoryServices.csproj | 1 + .../src/System.DirectoryServices.csproj | 2 ++ .../DirectoryServicesPermission.cs | 5 +---- .../DirectoryServicesPermissionAttribute.cs | 5 +---- .../src/System/ObsoleteAttribute.cs | 8 +++++++- 7 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 068faae2a5dc..56168943651d 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -253,6 +253,19 @@ + + + + + + + + + $(NoWarn);CS0436 + + + + diff --git a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs index e19e3c253e9d..b14173fb6c6e 100644 --- a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs +++ b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs @@ -259,6 +259,7 @@ public DirectoryServicesCOMException(string message, System.Exception inner) { } public string ExtendedErrorMessage { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } } + [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public sealed partial class DirectoryServicesPermission : System.Security.Permissions.ResourcePermissionBase { public DirectoryServicesPermission() { } @@ -274,6 +275,7 @@ public enum DirectoryServicesPermissionAccess Browse = 2, Write = 6, } + [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.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public partial class DirectoryServicesPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { diff --git a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj index 68593ef6e13e..a29cfa079c93 100644 --- a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.csproj @@ -1,6 +1,7 @@ netstandard2.0 + true diff --git a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj index fe5b6232d96a..7751f4e3d475 100644 --- a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -3,6 +3,7 @@ true $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT true + true @@ -135,6 +136,7 @@ + diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermission.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermission.cs index 7b1ebc03ec5e..27cab3be2254 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermission.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermission.cs @@ -5,9 +5,7 @@ namespace System.DirectoryServices { -#pragma warning disable SYSLIB0003 - // Conditionally marking this type as obsolete in .NET 5+ will require diverging its net5.0 build from netstandard2.0 - // https://github.com/dotnet/runtime/issues/39413 + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public sealed class DirectoryServicesPermission : ResourcePermissionBase { public DirectoryServicesPermission() { } @@ -16,5 +14,4 @@ public DirectoryServicesPermission(PermissionState state) { } public DirectoryServicesPermission(DirectoryServicesPermissionAccess permissionAccess, string path) { } public DirectoryServicesPermissionEntryCollection PermissionEntries { get; } } -#pragma warning restore SYSLIB0003 } diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermissionAttribute.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermissionAttribute.cs index b4d094115b5b..43c3986daeaa 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermissionAttribute.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesPermissionAttribute.cs @@ -6,9 +6,7 @@ namespace System.DirectoryServices { -#pragma warning disable SYSLIB0003 - // Conditionally marking this type as obsolete in .NET 5+ will require diverging its net5.0 build from netstandard2.0 - // https://github.com/dotnet/runtime/issues/39413 + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] @@ -19,5 +17,4 @@ public DirectoryServicesPermissionAttribute(SecurityAction action) : base(defaul public string Path { get; set; } public override IPermission CreatePermission() { return default(IPermission); } } -#pragma warning restore SYSLIB0003 } diff --git a/src/libraries/System.Private.CoreLib/src/System/ObsoleteAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/ObsoleteAttribute.cs index 11a2777e8506..05dfed0844b1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ObsoleteAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ObsoleteAttribute.cs @@ -24,7 +24,13 @@ namespace System [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Delegate, Inherited = false)] - public sealed class ObsoleteAttribute : Attribute +#if SYSTEM_PRIVATE_CORELIB + public +#else +#nullable enable + internal +#endif + sealed class ObsoleteAttribute : Attribute { public ObsoleteAttribute() { From 54fb5973a01129bea09f838c54c41ee8222f9ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Thu, 13 Aug 2020 22:19:23 -0700 Subject: [PATCH 483/755] /p:Configuration must use "Release" instead of "release" (#40816) I am not very familiar with Unix so I was not aware why I was having below error: ``` /home/jozky/runtime/.dotnet/sdk/5.0.100-preview.8.20362.3/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(379,5): error NETSDK1112: The runtime pack for Microsoft.NETCore.App.Runtime.browser-wasm was not downloaded. Try running a NuGet restore with the RuntimeIdentifier 'browser-wasm'. [/home/jozky/runtime/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj] ``` I tried running `dotnet restore --runtime browser-wasm` as suggested by the error but that didn't help. The correct thing to do was to pass `Release` (with upper case R) to `Configuration` parameter. cc @safern --- docs/workflow/testing/libraries/testing-wasm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/workflow/testing/libraries/testing-wasm.md b/docs/workflow/testing/libraries/testing-wasm.md index 8e067e9f6e49..65de9d32ec9e 100644 --- a/docs/workflow/testing/libraries/testing-wasm.md +++ b/docs/workflow/testing/libraries/testing-wasm.md @@ -35,14 +35,14 @@ and even run tests one by one for each library: ### Running individual test suites The following shows how to run tests for a specific library ``` -./dotnet.sh build /t:Test src/libraries/System.AppContext/tests /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=release +./dotnet.sh build /t:Test src/libraries/System.AppContext/tests /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=Release ``` ### Running tests using different JavaScript engines It's possible to set a JavaScript engine explicitly by adding `/p:JSEngine` property: ``` -./dotnet.sh build /t:Test src/libraries/System.AppContext/tests /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=release /p:JSEngine=SpiderMonkey +./dotnet.sh build /t:Test src/libraries/System.AppContext/tests /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=Release /p:JSEngine=SpiderMonkey ``` At the moment supported values are: From 54d3a76eb69143ba59fcf8532ab7600f90161522 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Thu, 13 Aug 2020 23:07:42 -0700 Subject: [PATCH 484/755] Forbid AllocateValueType from allocating byref like types on the heap (#40632) --- src/coreclr/src/vm/reflectioninvocation.cpp | 5 + .../tests/ParameterInfoTests.cs | 16 ++ .../System.Reflection/tests/TypeInfoTests.cs | 12 +- .../tests/System.Runtime.Tests.csproj | 3 +- .../Reflection/InvokeWithRefLikeArgs.cs | 162 ++++++++++++++++++ 5 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 src/libraries/System.Runtime/tests/System/Reflection/InvokeWithRefLikeArgs.cs diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 4ea56e358a74..5297b44fb21d 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -253,6 +253,11 @@ FCIMPL3(Object*, ReflectionInvocation::AllocateValueType, ReflectClassBaseObject if (InvokeUtil::IsPrimitiveType(targetElementType) || targetElementType == ELEMENT_TYPE_VALUETYPE) { MethodTable* allocMT = targetType.AsMethodTable(); + + if (allocMT->IsByRefLike()) { + COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLike")); + } + if (gc.value != NULL) { // ignore the type of the incoming box if fForceTypeChange is set diff --git a/src/libraries/System.Reflection/tests/ParameterInfoTests.cs b/src/libraries/System.Reflection/tests/ParameterInfoTests.cs index c17802484cfd..e67e982064e6 100644 --- a/src/libraries/System.Reflection/tests/ParameterInfoTests.cs +++ b/src/libraries/System.Reflection/tests/ParameterInfoTests.cs @@ -173,6 +173,15 @@ public void DefaultValue_NoDefaultValue() Assert.Equal(Missing.Value, parameterInfo.DefaultValue); } + [Fact] + public void DefaultValue_ForByRefLikeArg_ReturnsNull() + { + ParameterInfo parameterInfo = GetParameterInfo(typeof(ParameterInfoMetadata), nameof(ParameterInfoMetadata.MethodWithByRefLikeArgWithDefault), 0); + Assert.True(parameterInfo.HasDefaultValue); + Assert.Null(parameterInfo.DefaultValue); + Assert.Null(parameterInfo.RawDefaultValue); + } + [Theory] [InlineData(typeof(ParameterInfoMetadata), "Method1", 1, false)] [InlineData(typeof(ParameterInfoMetadata), "MethodWithOutParameter", 1, false)] @@ -354,6 +363,8 @@ public virtual void VirtualMethod(long data) { } public void MethodWithDefaultDateTime(DateTime arg = default(DateTime)) { } public void MethodWithDefaultNullableDateTime(DateTime? arg = default(DateTime?)) { } + public void MethodWithByRefLikeArgWithDefault(MyByRefLikeStruct arg = default) { } + public void MethodWithEnum(AttributeTargets arg = AttributeTargets.All) { } public void MethodWithNullableEnum(AttributeTargets? arg = AttributeTargets.All) { } @@ -400,5 +411,10 @@ public PodPersonParameterInfo(MemberInfo pretendMember, int pretendPosition) PositionImpl = pretendPosition; } } + + public ref struct MyByRefLikeStruct + { + public int MyInt; + } } } diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index e2198b092140..95e349ca0d59 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -3,8 +3,8 @@ using System.Collections; using System.Collections.Generic; -using System.Linq; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using Xunit; @@ -493,12 +493,18 @@ public void ImplementedInterfaces(Type type, Type[] expected) TypeInfo typeInfo = type.GetTypeInfo(); Type[] implementedInterfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray(); - Array.Sort(implementedInterfaces, delegate (Type a, Type b) { return a.GetHashCode() - b.GetHashCode(); }); - Array.Sort(expected, delegate (Type a, Type b) { return a.GetHashCode() - b.GetHashCode(); }); + Array.Sort(implementedInterfaces, TypeSortComparer); + Array.Sort(expected, TypeSortComparer); Assert.Equal(expected, implementedInterfaces); Assert.All(expected, ti => Assert.True(ti.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))); Assert.All(expected, ti => Assert.True(type.GetTypeInfo().IsAssignableTo(ti.GetTypeInfo()))); + + static int TypeSortComparer(Type a, Type b) + { + // produces a stable (within this process) ordering of two Type objects + return a.TypeHandle.Value.CompareTo(b.TypeHandle.Value); + } } public static IEnumerable IsInstanceOfType_TestData() diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index eff661cba396..1f7ba6debb57 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -196,6 +196,7 @@ + @@ -280,4 +281,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeWithRefLikeArgs.cs b/src/libraries/System.Runtime/tests/System/Reflection/InvokeWithRefLikeArgs.cs new file mode 100644 index 000000000000..c62ddb55b1db --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeWithRefLikeArgs.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Moq; +using Xunit; +using Xunit.Sdk; + +namespace System.Reflection.Tests +{ + public class InvokeWithRefLikeArgs + { + [Fact] + public static void MethodReturnsRefToRefStruct_ThrowsNSE() + { + MethodInfo mi = GetMethod(nameof(TestClass.ReturnsRefToRefStruct)); + Assert.Throws(() => mi.Invoke(null, null)); + } + + [Fact] + public static void MethodTakesRefStructAsArg_DoesNotCopyValueBack() + { + MethodInfo mi = GetMethod(nameof(TestClass.TakesRefStructAsArg)); + + object[] args = new object[] { null }; + mi.Invoke(null, args); + + Assert.Null(args[0]); // no value should have been copied back + } + + [Fact] + public static void MethodTakesRefStructAsArgWithDefaultValue_DoesNotCopyValueBack() + { + MethodInfo mi = GetMethod(nameof(TestClass.TakesRefStructAsArgWithDefaultValue)); + + object[] args = new object[] { Type.Missing }; + mi.Invoke(null, args); + + Assert.Null(args[0]); // no value should have been copied back + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/40738")] + public static void MethodTakesRefToRefStructAsArg_ThrowsNSE() + { + // Use a Binder to trick the reflection stack into treating the returned null + // as meaning "use the default value of the ref struct". + + Mock mockBinder = new Mock(MockBehavior.Strict); + Type myRefStructType = typeof(MyRefStruct); + mockBinder.Setup(o => o.ChangeType("hello", myRefStructType.MakeByRefType(), null)).Returns((object)null); + + MethodInfo mi = GetMethod(nameof(TestClass.TakesRefToRefStructAsArg)); + Assert.Throws(() => mi.Invoke(null, BindingFlags.InvokeMethod, mockBinder.Object, new object[] { "hello" }, null)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/40738")] + public static void MethodTakesOutToRefStructAsArg_ThrowsNSE() + { + MethodInfo mi = GetMethod(nameof(TestClass.TakesOutToRefStructAsArg)); + Assert.Throws(() => mi.Invoke(null, new object[] { null })); + } + + [Fact] + public static void PropertyTypedAsRefToRefStruct_AsMethodInfo_ThrowsNSE() + { + MethodInfo mi = GetMethod("get_" + nameof(TestClass.PropertyTypedAsRefToRefStruct)); + Assert.Throws(() => mi.Invoke(null, null)); + } + + [Fact] + public static void PropertyTypedAsRefToRefStruct_AsPropInfo_ThrowsNSE() + { + PropertyInfo pi = typeof(TestClass).GetProperty(nameof(TestClass.PropertyTypedAsRefToRefStruct)); + Assert.NotNull(pi); + Assert.Throws(() => pi.GetValue(null)); + } + + [Fact] + public static void PropertyIndexerWithRefStructArg_DoesNotCopyValueBack() + { + PropertyInfo pi = typeof(TestClassWithIndexerWithRefStructArg).GetProperty("Item"); + Assert.NotNull(pi); + + object obj = new TestClassWithIndexerWithRefStructArg(); + object[] args = new object[] { null }; + + object retVal = pi.GetValue(obj, args); + Assert.Equal(42, retVal); + Assert.Null(args[0]); // no value should have been copied back + + pi.SetValue(obj, 42, args); + Assert.Null(args[0]); // no value should have been copied back + } + + private sealed class TestClass + { + private static int _backingField = 42; + + public unsafe static ref MyRefStruct ReturnsRefToRefStruct() + { + fixed (int* pInt = &_backingField) + { + return ref *(MyRefStruct*)pInt; // will return a valid ref + } + } + + public static void TakesRefStructAsArg(MyRefStruct o) + { + Assert.Equal(0, o.MyInt); // should be default(T) + } + + public static void TakesRefStructAsArgWithDefaultValue(MyRefStruct o = default) + { + Assert.Equal(0, o.MyInt); // should be default(T) + } + + public static void TakesRefToRefStructAsArg(ref MyRefStruct o) + { + throw new XunitException("Should never be called."); + } + + public static void TakesOutToRefStructAsArg(out MyRefStruct o) + { + throw new XunitException("Should never be called."); + } + + public static ref MyRefStruct PropertyTypedAsRefToRefStruct + { + get { return ref ReturnsRefToRefStruct(); } + } + } + + private static MethodInfo GetMethod(string name) + { + MethodInfo mi = typeof(TestClass).GetMethod(name, BindingFlags.Static | BindingFlags.Public); + Assert.NotNull(mi); + return mi; + } + + private sealed class TestClassWithIndexerWithRefStructArg + { + public int this[MyRefStruct o] + { + get + { + Assert.Equal(0, o.MyInt); // should be default(T) + return 42; + } + set + { + Assert.Equal(0, o.MyInt); // should be default(T) + } + } + } + + private ref struct MyRefStruct + { + public int MyInt; + } + } +} From 276c09cd82b50cad0eaff6223c947b3fc5ace2b9 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Fri, 14 Aug 2020 09:35:47 +0300 Subject: [PATCH 485/755] Re-enable one HttpContentTest library test on browser wasm (#40762) --- .../System.Net.Http/tests/UnitTests/HttpContentTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HttpContentTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/HttpContentTest.cs index 34d8ab712abe..51127fcc1c6a 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/HttpContentTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/HttpContentTest.cs @@ -10,7 +10,7 @@ namespace System.Net.Http.Tests { public class HttpContentTest { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public async Task Dispose_BufferContentThenDisposeContent_BufferedStreamGetsDisposed() { MockContent content = new MockContent(); From 6362ec357baaac66ae461b6a73c49cec5ea37470 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Fri, 14 Aug 2020 09:36:12 +0300 Subject: [PATCH 486/755] Clean up the System.Net.Requests library tests because the respective library is PNSE on browser wasm (#40766) --- .../System.Net.Requests/tests/FileWebRequestTest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs b/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs index 505aa4bf4760..0212efc57dd3 100644 --- a/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs +++ b/src/libraries/System.Net.Requests/tests/FileWebRequestTest.cs @@ -87,7 +87,7 @@ public abstract class FileWebRequestTestBase public abstract Task GetResponseAsync(WebRequest request); public abstract Task GetRequestStreamAsync(WebRequest request); - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public async Task ReadFile_ContainsExpectedContent() { string path = Path.GetTempFileName(); @@ -124,7 +124,7 @@ public async Task ReadFile_ContainsExpectedContent() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public async Task WriteFile_ContainsExpectedContent() { string path = Path.GetTempFileName(); @@ -150,7 +150,7 @@ public async Task WriteFile_ContainsExpectedContent() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public async Task WriteThenReadFile_WriteAccessResultsInNullResponseStream() { string path = Path.GetTempFileName(); @@ -182,7 +182,7 @@ public async Task WriteThenReadFile_WriteAccessResultsInNullResponseStream() protected virtual bool EnableConcurrentReadWriteTests => true; - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public async Task RequestAfterResponse_throws() { string path = Path.GetTempFileName(); @@ -201,7 +201,7 @@ public async Task RequestAfterResponse_throws() } } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [InlineData(null)] [InlineData(false)] [InlineData(true)] From 49d81de083095f7bdf3bfb73bd7e7585719649c5 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Fri, 14 Aug 2020 09:42:29 -0400 Subject: [PATCH 487/755] [mono] Improve MonoImage filename handling for bundled images (#40818) --- src/mono/mono/metadata/appdomain.c | 2 +- src/mono/mono/metadata/assembly.c | 13 ++----------- src/mono/mono/metadata/debug-mono-ppdb.c | 2 +- src/mono/mono/metadata/image.c | 14 +++++++------- src/mono/mono/metadata/metadata-internals.h | 2 +- .../mono/tests/metadata-verifier/gen-md-tests.c | 2 +- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index 11d04619eb13..828264393c62 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -2821,7 +2821,7 @@ mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, gu { MonoAssembly *ass = NULL; MonoImageOpenStatus status; - MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL); + MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL, NULL); if (!image) { mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data); diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index d9a9e7f8c3b5..ccf05748c9e6 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -2500,17 +2500,8 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena name = g_path_get_basename (filename); for (i = 0; !image && bundles [i]; ++i) { if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) { - image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name); -#if defined(TARGET_WASM) && defined(ENABLE_NETCORE) - /* - * Since bundled images do not exist on disk, don't give them a legit file name. - * This is the expected behavior for single file exe's. - */ - if (image->filename) - g_free (image->filename); - - image->filename = NULL; -#endif + // Since bundled images don't exist on disk, don't give them a legit filename + image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name, NULL); break; } } diff --git a/src/mono/mono/metadata/debug-mono-ppdb.c b/src/mono/mono/metadata/debug-mono-ppdb.c index c4dd3d1d4d67..38c619a61b85 100644 --- a/src/mono/mono/metadata/debug-mono-ppdb.c +++ b/src/mono/mono/metadata/debug-mono-ppdb.c @@ -194,7 +194,7 @@ mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size) MonoAssemblyLoadContext *alc = mono_image_get_alc (image); if (raw_contents) { if (size > 4 && strncmp ((char*)raw_contents, "BSJB", 4) == 0) - ppdb_image = mono_image_open_from_data_internal (alc, (char*)raw_contents, size, TRUE, &status, FALSE, TRUE, NULL); + ppdb_image = mono_image_open_from_data_internal (alc, (char*)raw_contents, size, TRUE, &status, FALSE, TRUE, NULL, NULL); } else { /* ppdb files drop the .exe/.dll extension */ filename = mono_image_get_filename (image); diff --git a/src/mono/mono/metadata/image.c b/src/mono/mono/metadata/image.c index d3986bc0e6ca..c82e2c516ed5 100644 --- a/src/mono/mono/metadata/image.c +++ b/src/mono/mono/metadata/image.c @@ -1878,7 +1878,7 @@ register_image (MonoLoadedImages *li, MonoImage *image, gboolean *problematic) } MonoImage * -mono_image_open_from_data_internal (MonoAssemblyLoadContext *alc, char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name) +mono_image_open_from_data_internal (MonoAssemblyLoadContext *alc, char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name, const char *filename) { MonoCLIImageInfo *iinfo; MonoImage *image; @@ -1900,12 +1900,12 @@ mono_image_open_from_data_internal (MonoAssemblyLoadContext *alc, char *data, gu memcpy (datac, data, data_len); } - MonoImageStorage *storage = mono_image_storage_new_raw_data (datac, data_len, need_copy, name); + MonoImageStorage *storage = mono_image_storage_new_raw_data (datac, data_len, need_copy, filename); image = g_new0 (MonoImage, 1); image->storage = storage; mono_image_init_raw_data (image, storage); - image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name); - image->filename = name ? g_strdup (name) : NULL; + image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup (name); + image->filename = filename ? g_strdup (filename) : NULL; iinfo = g_new0 (MonoCLIImageInfo, 1); image->image_info = iinfo; image->ref_only = refonly; @@ -1931,7 +1931,7 @@ mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need MonoImage *result; MONO_ENTER_GC_UNSAFE; MonoDomain *domain = mono_domain_get (); - result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, refonly, FALSE, name); + result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, refonly, FALSE, name, name); MONO_EXIT_GC_UNSAFE; return result; } @@ -1945,7 +1945,7 @@ mono_image_open_from_data_full (char *data, guint32 data_len, gboolean need_copy MonoImage *result; MONO_ENTER_GC_UNSAFE; MonoDomain *domain = mono_domain_get (); - result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, refonly, FALSE, NULL); + result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, refonly, FALSE, NULL, NULL); MONO_EXIT_GC_UNSAFE; return result; } @@ -1959,7 +1959,7 @@ mono_image_open_from_data (char *data, guint32 data_len, gboolean need_copy, Mon MonoImage *result; MONO_ENTER_GC_UNSAFE; MonoDomain *domain = mono_domain_get (); - result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, FALSE, FALSE, NULL); + result = mono_image_open_from_data_internal (mono_domain_default_alc (domain), data, data_len, need_copy, status, FALSE, FALSE, NULL, NULL); MONO_EXIT_GC_UNSAFE; return result; } diff --git a/src/mono/mono/metadata/metadata-internals.h b/src/mono/mono/metadata/metadata-internals.h index 34ef1d307d4b..c37d40fd9515 100644 --- a/src/mono/mono/metadata/metadata-internals.h +++ b/src/mono/mono/metadata/metadata-internals.h @@ -1104,7 +1104,7 @@ MonoImage *mono_image_open_raw (MonoAssemblyLoadContext *alc, const char *fname, MonoImage *mono_image_open_metadata_only (MonoAssemblyLoadContext *alc, const char *fname, MonoImageOpenStatus *status); -MonoImage *mono_image_open_from_data_internal (MonoAssemblyLoadContext *alc, char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name); +MonoImage *mono_image_open_from_data_internal (MonoAssemblyLoadContext *alc, char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name, const char *filename); MonoException *mono_get_exception_field_access_msg (const char *msg); diff --git a/src/mono/mono/tests/metadata-verifier/gen-md-tests.c b/src/mono/mono/tests/metadata-verifier/gen-md-tests.c index 374a2cdd4dc1..b59bc86db617 100644 --- a/src/mono/mono/tests/metadata-verifier/gen-md-tests.c +++ b/src/mono/mono/tests/metadata-verifier/gen-md-tests.c @@ -272,7 +272,7 @@ init_test_set (test_set_t *test_set) if (test_set->init) return; test_set->assembly_data = read_whole_file_and_close (test_set->assembly, &test_set->assembly_size); - test_set->image = mono_image_open_from_data_internal (mono_domain_default_alc (mono_root_domain_get ()), test_set->assembly_data, test_set->assembly_size, FALSE, &status, FALSE, FALSE, NULL); + test_set->image = mono_image_open_from_data_internal (mono_domain_default_alc (mono_root_domain_get ()), test_set->assembly_data, test_set->assembly_size, FALSE, &status, FALSE, FALSE, NULL, NULL); if (!test_set->image || status != MONO_IMAGE_OK) { printf ("Could not parse image %s\n", test_set->assembly); exit (INVALID_BAD_FILE); From 484a23df543450491123452d964ad982f85fa588 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 14 Aug 2020 10:56:22 -0400 Subject: [PATCH 488/755] [runtime] Update cmake build. (#40811) * Update cmake build. * . * Auto detect ENABLE_NETCORE. --- src/mono/CMakeLists.txt | 33 ++++++++++++--- src/mono/cmake/configure.cmake | 4 +- src/mono/cmake/defines-todo.cmake | 4 ++ src/mono/cmake/options.cmake | 7 ++++ src/mono/mono/metadata/native-library.c | 7 ++++ src/mono/mono/mini/CMakeLists.txt | 56 ++++++++++++++++++++----- 6 files changed, 95 insertions(+), 16 deletions(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 574f039b1662..ba0a291c87a2 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -6,6 +6,7 @@ include(GNUInstallDirs) include(CheckIncludeFile) include(CheckFunctionExists) include(TestBigEndian) +include (FindPkgConfig) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} @@ -32,7 +33,7 @@ include(configure) set(VERSION "") execute_process( - COMMAND grep ^MONO_CORLIB_VERSION= configure.ac + COMMAND grep ^MONO_CORLIB_VERSION= ${CMAKE_SOURCE_DIR}/configure.ac COMMAND cut -d = -f 2 OUTPUT_VARIABLE CORLIB_VERSION_OUT ) @@ -42,6 +43,10 @@ endif() string(STRIP "${CORLIB_VERSION_OUT}" MONO_CORLIB_VERSION_BASE) set(MONO_CORLIB_VERSION "\"${MONO_CORLIB_VERSION_BASE}\"") +if(EXISTS "${CMAKE_SOURCE_DIR}/mono.proj") + set(ENABLE_NETCORE 1) +endif() + if (ENABLE_NETCORE) set(DISABLE_REMOTING 1) set(DISABLE_REFLECTION_EMIT_SAVE 1) @@ -55,6 +60,8 @@ if (ENABLE_NETCORE) set(DISABLE_PERFCOUNTERS 1) set(DISABLE_ATTACH 1) set(DISABLE_DLLMAP 1) + set(DISABLE_CONFIG 1) + set(DISABLE_CFGDIR_CONFIG 1) else() message(FATAL_ERROR "Building without -DENABLE_NETCORE=1 is not supported.") endif() @@ -112,7 +119,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(PTHREAD_POINTER_ID 1) set(USE_MACH_SEMA 1) else() - message(FATAL ERROR "") + message(FATAL_ERROR "") endif() ###################################### @@ -129,7 +136,7 @@ if(TARGET_SYSTEM_NAME STREQUAL "Darwin") set(CORETARGETS "-p:TargetsUnix=true -p:TargetsOSX=true") set(NETCORE_HOST_PLATFORM "macos") else() - message(FATAL ERROR "") + message(FATAL_ERROR "") endif() ###################################### @@ -139,7 +146,7 @@ endif() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") set(HOST_AMD64 1) else() - message(FATAL ERROR "") + message(FATAL_ERROR "") endif() ###################################### @@ -154,7 +161,23 @@ if(TARGET_ARCH STREQUAL "x86_64") set(RID_SUFFIX "x64") set(COREARCH "x64") else() - message(FATAL ERROR "") + message(FATAL_ERROR "") +endif() + +###################################### +# ICU CHECKS +###################################### +set(ICU_SHIM_PATH "../../../libraries/Native/Unix/System.Globalization.Native") +if(TARGET_OSX) + # FIXME: Handle errors + # Defines ICU_INCLUDEDIR/ICU_LIBDIR + set(ENV{PKG_CONFIG_PATH} "{$PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig") + pkg_check_modules(ICU icu-uc) + set(OSX_ICU_LIBRARY_PATH /usr/lib/libicucore.dylib) + set(ICU_FLAGS "-DTARGET_UNIX -DU_DISABLE_RENAMING -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option -Wno-deprecated-declarations") + set(HAVE_SYS_ICU 1) +else() + message(FATAL_ERROR "") endif() ###################################### diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index e8d150ccae9c..782f49aff888 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -63,7 +63,7 @@ ac_check_funcs ( sched_getaffinity sched_setaffinity getpwnam_r getpwuid_r readlink chmod lstat getdtablesize ftruncate msync gethostname getpeername utime utimes openlog closelog atexit popen strerror_r inet_pton inet_aton pthread_getname_np pthread_setname_np pthread_cond_timedwait_relative_np pthread_kill - pthread_attr_setstacksize pthread_get_stackaddr_np + pthread_attr_setstacksize pthread_get_stackaddr_np pthread_jit_write_protect_np shm_open poll getfsstat mremap posix_fadvise vsnprintf sendfile statfs statvfs setpgid system fork execv execve waitpid localtime_r mkdtemp getrandom execvp strlcpy stpcpy strtok_r rewinddir vasprintf strndup getpwuid_r getprotobyname getprotobyname_r getaddrinfo mach_absolute_time @@ -81,12 +81,14 @@ check_symbol_exists(IP_PKTINFO "linux/in.h" HAVE_IP_PKTINFO) check_symbol_exists(IPV6_PKTINFO "netdb.h" HAVE_IPV6_PKTINFO) check_symbol_exists(IP_DONTFRAGMENT "Ws2ipdef.h" HAVE_IP_DONTFRAGMENT) check_symbol_exists(IP_MTU_DISCOVER "linux/in.h" HAVE_IP_MTU_DISCOVER) +check_symbol_exists(sys_signame "signal.h" HAVE_SYSSIGNAME) ac_check_type("struct sockaddr_in6" sockaddr_in6 "netinet/in.h") ac_check_type("struct timeval" timeval "sys/time.h;sys/types.h;utime.h") ac_check_type("socklen_t" socklen_t "sys/types.h;sys/socket.h") ac_check_type("struct ip_mreqn" ip_mreqn "netinet/in.h") ac_check_type("struct ip_mreq" ip_mreq "netinet/in.h") +ac_check_type("clockid_t" clockid_t "sys/types.h") check_struct_has_member("struct kinfo_proc" kp_proc "sys/types.h;sys/param.h;sys/sysctl.h;sys/proc.h" HAVE_STRUCT_KINFO_PROC_KP_PROC) check_struct_has_member("struct sockaddr_in" sin_len "netinet/in.h" HAVE_SOCKADDR_IN_SIN_LEN) diff --git a/src/mono/cmake/defines-todo.cmake b/src/mono/cmake/defines-todo.cmake index 0f9e6e46ec53..55c5b6f85bb6 100644 --- a/src/mono/cmake/defines-todo.cmake +++ b/src/mono/cmake/defines-todo.cmake @@ -93,3 +93,7 @@ #option (ENABLE_CHECKED_BUILD_PRIVATE_TYPES "Enable private types checked build") #option (ENABLE_CHECKED_BUILD_CRASH_REPORTING "Enable private types checked build") #option (HAVE_BTLS "BoringTls is supported") +#option (ENABLE_JIT_DUMP "Enable jit dump support on Linux") +#option (DISABLE_CRASH_REPORTING) +#option (ENABLE_CXX) +#option (STATIC_ICU) diff --git a/src/mono/cmake/options.cmake b/src/mono/cmake/options.cmake index 9ad182c91e01..0e24b9f93fe1 100644 --- a/src/mono/cmake/options.cmake +++ b/src/mono/cmake/options.cmake @@ -39,4 +39,11 @@ option (DISABLE_SOCKETS "Disable sockets") option (DISABLE_GAC "Disable GAC") option (DISABLE_DLLMAP "Disables use of DllMaps in MonoVM") option (DISABLE_THREADS "Disable Threads") +option (DISABLE_CONFIG "Disable .config file support") +option (DISABLE_CFGDIR_CONFIG "Disable config directories") +option (DISABLE_SGEN_TOGGLEREF "Disable toggleref support in SGEN") +option (DISABLE_SGEN_BINARY_PROTOCOL "Disable binary protocol logging in SGEN") +option (DISABLE_PROCESSES "Disable process support") +option (DISABLE_EVENTPIPE "Disable EventPipe support") +option (ENABLE_PERFTRACING "Enables support for eventpipe library") diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index ff2c6cc8d647..851225d22f9b 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -1293,6 +1293,13 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou if (strcmp (new_scope, "QCall") == 0) { piinfo->addr = mono_lookup_pinvoke_qcall_internal (method, status_out); + if (!piinfo->addr) { + mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DLLIMPORT, + "Unable to find qcall for '%s'.", + new_import); + status_out->err_code = LOOKUP_PINVOKE_ERR_NO_SYM; + status_out->err_arg = g_strdup (new_import); + } return piinfo->addr; } diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index d98715012547..256316cf1a6b 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -10,6 +10,8 @@ endfunction() include_directories( ${PROJECT_BINARY_DIR}/ ${PROJECT_BINARY_DIR}/../.. + ${PROJECT_BINARY_DIR}/../../mono/eglib + ${CMAKE_SOURCE_DIR}/ ${PROJECT_SOURCE_DIR}/../ ${PROJECT_SOURCE_DIR}/../eglib ${PROJECT_SOURCE_DIR}/../sgen) @@ -188,6 +190,8 @@ set (utils_common_sources lock-free-alloc.h lock-free-array-queue.c lock-free-array-queue.h + lifo-semaphore.c + lifo-semaphore.h mono-linked-list-set.c mono-linked-list-set.h mono-threads.c @@ -205,6 +209,7 @@ set (utils_common_sources mono-threads-haiku.c mono-threads-aix.c mono-threads-wasm.c + mono-threads-sunos.c mono-threads.h mono-threads-debug.h mono-threads-api.h @@ -226,6 +231,7 @@ set (utils_common_sources bsearch.h bsearch.c mono-signal-handler.h + mono-signal-handler.c mono-conc-hashtable.h mono-conc-hashtable.c json.h @@ -328,19 +334,19 @@ set(metadata_common_sources class.c class-getters.h class-init.h + class-init-internals.h class-init.c class-internals.h class-inlines.h class-private-definition.h class-accessors.c + class-setup-vtable.c cominterop.c cominterop.h console-io.h coree.c coree.h coree-internals.h - culture-info.h - culture-info-tables.h debug-helpers.c debug-mono-symfile.h debug-mono-symfile.c @@ -362,12 +368,11 @@ set(metadata_common_sources icall-internals.h icall-def.h icall-table.h + icall-eventpipe.c image.c image-internals.h jit-info.c loader.c - locales.c - locales.h lock-tracer.c lock-tracer.h marshal.c @@ -485,7 +490,7 @@ set(metadata_common_sources native-library.h native-library.c native-library-qcall.c - qcalllist.h + qcall-def.h loaded-images-internals.h loaded-images.c loaded-images-netcore.c @@ -598,6 +603,27 @@ set(sgen_sources_base addprefix (sgen_sources ../sgen/ "${sgen_sources_base}") set_source_files_properties (${sgen_sources} PROPERTIES COMPILE_DEFINITIONS "HAVE_SGEN_GC") +# ICU +if(HAVE_SYS_ICU) +set (icu_shim_sources_base + pal_calendarData.c + pal_casing.c + pal_collation.c + pal_idna.c + pal_locale.c + pal_localeNumberData.c + pal_localeStringData.c + pal_normalization.c + pal_timeZoneInfo.c + entrypoints.c + pal_icushim.c) +addprefix (icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}") +set_source_files_properties (${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}") +set_source_files_properties (${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I${ICU_INCLUDEDIR} -I${CMAKE_SOURCE_DIR}/../libraries/Native/Unix/System.Globalization.Native/ -I${CMAKE_SOURCE_DIR}/../libraries/Native/Unix/Common/ ${ICU_FLAGS}") +set(ICU_LIBS "icucore") +set(ICU_LDFLAGS "-L${ICU_LIBDIR}") +endif() + # # MINI # @@ -667,6 +693,7 @@ set (mini_common_sources mini-cross-helpers.c arch-stubs.c llvm-runtime.h + llvm-intrinsics.h type-checking.c lldb.h lldb.c @@ -727,6 +754,8 @@ set (interp_sources interp/interp.h interp/interp-internals.h interp/interp.c + interp/interp-intrins.h + interp/interp-intrins.c interp/mintops.h interp/mintops.c interp/transform.c) @@ -752,19 +781,25 @@ endif() set (mini_sources "${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h;main-core.c;${mini_common_sources};${arch_sources};${os_sources};${interp_sources};${llvm_sources};${debugger_sources};${llvm_runtime_sources}") -add_library(monosgen-objects OBJECT "${eglib_sources};${metadata_sources};${utils_sources};${sgen_sources};${mini_sources}") +add_library(monosgen-objects OBJECT "${eglib_sources};${metadata_sources};${utils_sources};${sgen_sources};${icu_shim_sources};${mini_sources}") add_library (monosgen-static STATIC $) add_library (monosgen SHARED $) set_target_properties(monosgen PROPERTIES OUTPUT_NAME monosgen-2.0) set_target_properties(monosgen PROPERTIES LIBRARY_OUTPUT_DIRECTORY .libs) +# FIXME: Always rebuilds, creates non-deterministic builds # FIXME: Use the previous format -string(TIMESTAMP BUILD_DATE) +#string(TIMESTAMP BUILD_DATE) +#add_custom_command ( +# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h +# COMMAND echo "const char *build_date = \"${BUILD_DATE}\";" > ${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h +# VERBATIM +#) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h - COMMAND echo "const char *build_date = \"${BUILD_DATE}\";" > ${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h + COMMAND echo "const char *build_date = \"\";" > ${CMAKE_CURRENT_BINARY_DIR}/buildver-sgen.h VERBATIM ) @@ -781,5 +816,6 @@ add_custom_command ( ) add_executable (mono-sgen "main-sgen.c") -target_link_libraries (mono-sgen monosgen-static "-framework CoreFoundation" "-framework Foundation" "iconv" ${LLVM_LIBS}) -target_link_libraries (monosgen "-framework CoreFoundation" "-framework Foundation" "iconv" ${LLVM_LIBS}) +target_link_libraries (mono-sgen monosgen-static "-framework CoreFoundation" "-framework Foundation" "iconv" ${LLVM_LIBS} ${ICU_LIBS}) +target_link_libraries (monosgen "-framework CoreFoundation" "-framework Foundation" "iconv" ${LLVM_LIBS} ${ICU_LIBS}) +set_target_properties (mono-sgen monosgen PROPERTIES LINK_FLAGS ${ICU_LDFLAGS}) From 5e8e1a7a9676226086cf84a1076aa0a4510eab5d Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 14 Aug 2020 07:56:52 -0700 Subject: [PATCH 489/755] Remove unnecessary SwitchToThread on resume from suspend (#40790) Resuming from suspend often calls SwitchToThread at this callstack: KERNELBASE!SwitchToThread [minkernel\kernelbase\thread.c @ 3599] CoreCLR!__SwitchToThread+0x214 [D:\runtime\src\coreclr\src\vm\hosting.cpp @ 313] CoreCLR!Thread::RareDisablePreemptiveGC+0x35b [D:\runtime\src\coreclr\src\vm\threadsuspend.cpp @ 2359] CoreCLR!JIT_RareDisableHelperWorker+0xc8 [D:\runtime\src\coreclr\src\vm\jithelpers.cpp @ 4895] CoreCLR!JIT_RareDisableHelper+0x14 [D:\runtime\src\coreclr\src\vm\amd64\AsmHelpers.asm @ 233] test!ILStubClass.IL_STUB_PInvoke()+0xac This leads to odd effect where GC finishes, threads that are waiting for GC to finish will start running and immediately give up the scheduling quantum to each other. Once everybody gives up the quantum to each other, the regular execution resumes. This change moves the SwitchToThread call to be called only when RareDisablePreemptiveGC needs to reloop to do more work. --- src/coreclr/src/vm/threadsuspend.cpp | 153 ++++++++++++++------------- 1 file changed, 77 insertions(+), 76 deletions(-) diff --git a/src/coreclr/src/vm/threadsuspend.cpp b/src/coreclr/src/vm/threadsuspend.cpp index a9db60e8755e..51a2b07dcd79 100644 --- a/src/coreclr/src/vm/threadsuspend.cpp +++ b/src/coreclr/src/vm/threadsuspend.cpp @@ -2269,111 +2269,112 @@ void Thread::RareDisablePreemptiveGC() goto Exit; } + if (ThreadStore::HoldingThreadStore(this)) + { + goto Exit; + } + // Note IsGCInProgress is also true for say Pause (anywhere SuspendEE happens) and GCThread is the // thread that did the Pause. While in Pause if another thread attempts Rev/Pinvoke it should get inside the following and // block until resume if ((GCHeapUtilities::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) || (m_State & (TS_DebugSuspendPending | TS_StackCrawlNeeded))) { - if (!ThreadStore::HoldingThreadStore(this)) - { - STRESS_LOG1(LF_SYNC, LL_INFO1000, "RareDisablePreemptiveGC: entering. Thread state = %x\n", m_State.Load()); + STRESS_LOG1(LF_SYNC, LL_INFO1000, "RareDisablePreemptiveGC: entering. Thread state = %x\n", m_State.Load()); - DWORD dwSwitchCount = 0; + DWORD dwSwitchCount = 0; - do - { - EnablePreemptiveGC(); + for (;;) + { + EnablePreemptiveGC(); - // Cannot use GCX_PREEMP_NO_DTOR here because we're inside of the thread - // PREEMP->COOP switch mechanism and GCX_PREEMP's assert's will fire. - // Instead we use BEGIN_GCX_ASSERT_PREEMP to inform Scan of the mode - // change here. - BEGIN_GCX_ASSERT_PREEMP; + // Cannot use GCX_PREEMP_NO_DTOR here because we're inside of the thread + // PREEMP->COOP switch mechanism and GCX_PREEMP's assert's will fire. + // Instead we use BEGIN_GCX_ASSERT_PREEMP to inform Scan of the mode + // change here. + BEGIN_GCX_ASSERT_PREEMP; - // just wait until the GC is over. - if (this != ThreadSuspend::GetSuspensionThread()) - { + // just wait until the GC is over. + if (this != ThreadSuspend::GetSuspensionThread()) + { #ifdef PROFILING_SUPPORTED - // If profiler desires GC events, notify it that this thread is waiting until the GC is over - // Do not send suspend notifications for debugger suspensions + // If profiler desires GC events, notify it that this thread is waiting until the GC is over + // Do not send suspend notifications for debugger suspensions + { + BEGIN_PIN_PROFILER(CORProfilerTrackSuspends()); + if (!(m_State & TS_DebugSuspendPending)) { - BEGIN_PIN_PROFILER(CORProfilerTrackSuspends()); - if (!(m_State & TS_DebugSuspendPending)) - { - g_profControlBlock.pProfInterface->RuntimeThreadSuspended((ThreadID)this); - } - END_PIN_PROFILER(); + g_profControlBlock.pProfInterface->RuntimeThreadSuspended((ThreadID)this); } + END_PIN_PROFILER(); + } #endif // PROFILING_SUPPORTED + DWORD status = S_OK; + SetThreadStateNC(TSNC_WaitUntilGCFinished); + status = GCHeapUtilities::GetGCHeap()->WaitUntilGCComplete(); + ResetThreadStateNC(TSNC_WaitUntilGCFinished); - - DWORD status = S_OK; - SetThreadStateNC(TSNC_WaitUntilGCFinished); - status = GCHeapUtilities::GetGCHeap()->WaitUntilGCComplete(); - ResetThreadStateNC(TSNC_WaitUntilGCFinished); - - if (status == (DWORD)COR_E_STACKOVERFLOW) + if (status == (DWORD)COR_E_STACKOVERFLOW) + { + // One of two things can happen here: + // 1. GC is suspending the process. GC needs to wait. + // 2. GC is proceeding after suspension. The current thread needs to spin. + SetThreadState(TS_BlockGCForSO); + while (GCHeapUtilities::IsGCInProgress() && m_fPreemptiveGCDisabled.Load() == 0) { - // One of two things can happen here: - // 1. GC is suspending the process. GC needs to wait. - // 2. GC is proceeding after suspension. The current thread needs to spin. - SetThreadState(TS_BlockGCForSO); - while (GCHeapUtilities::IsGCInProgress() && m_fPreemptiveGCDisabled.Load() == 0) - { #undef Sleep - // We can not go to a host for blocking operation due ot lack of stack. - // Instead we will spin here until - // 1. GC is finished; Or - // 2. GC lets this thread to run and will wait for it - Sleep(10); + // We can not go to a host for blocking operation due ot lack of stack. + // Instead we will spin here until + // 1. GC is finished; Or + // 2. GC lets this thread to run and will wait for it + Sleep(10); #define Sleep(a) Dont_Use_Sleep(a) - } - ResetThreadState(TS_BlockGCForSO); - if (m_fPreemptiveGCDisabled.Load() == 1) - { - // GC suspension has allowed this thread to switch back to cooperative mode. - break; - } } - if (!GCHeapUtilities::IsGCInProgress()) + ResetThreadState(TS_BlockGCForSO); + if (m_fPreemptiveGCDisabled.Load() == 1) { - if (HasThreadState(TS_StackCrawlNeeded)) - { - SetThreadStateNC(TSNC_WaitUntilGCFinished); - ThreadStore::WaitForStackCrawlEvent(); - ResetThreadStateNC(TSNC_WaitUntilGCFinished); - } - else - { - __SwitchToThread(0, ++dwSwitchCount); - } + // GC suspension has allowed this thread to switch back to cooperative mode. + break; } - -#ifdef PROFILING_SUPPORTED - // Let the profiler know that this thread is resuming + } + if (!GCHeapUtilities::IsGCInProgress()) + { + if (HasThreadState(TS_StackCrawlNeeded)) { - BEGIN_PIN_PROFILER(CORProfilerTrackSuspends()); - g_profControlBlock.pProfInterface->RuntimeThreadResumed((ThreadID)this); - END_PIN_PROFILER(); + SetThreadStateNC(TSNC_WaitUntilGCFinished); + ThreadStore::WaitForStackCrawlEvent(); + ResetThreadStateNC(TSNC_WaitUntilGCFinished); } -#endif // PROFILING_SUPPORTED } - END_GCX_ASSERT_PREEMP; +#ifdef PROFILING_SUPPORTED + // Let the profiler know that this thread is resuming + { + BEGIN_PIN_PROFILER(CORProfilerTrackSuspends()); + g_profControlBlock.pProfInterface->RuntimeThreadResumed((ThreadID)this); + END_PIN_PROFILER(); + } +#endif // PROFILING_SUPPORTED + } - // disable preemptive gc. - FastInterlockOr(&m_fPreemptiveGCDisabled, 1); + END_GCX_ASSERT_PREEMP; - // The fact that we check whether 'this' is the GC thread may seem - // strange. After all, we determined this before entering the method. - // However, it is possible for the current thread to become the GC - // thread while in this loop. This happens if you use the COM+ - // debugger to suspend this thread and then release it. + // disable preemptive gc. + FastInterlockOr(&m_fPreemptiveGCDisabled, 1); - } while ((GCHeapUtilities::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) || - (m_State & (TS_DebugSuspendPending | TS_StackCrawlNeeded))); + // The fact that we check whether 'this' is the GC thread may seem + // strange. After all, we determined this before entering the method. + // However, it is possible for the current thread to become the GC + // thread while in this loop. This happens if you use the COM+ + // debugger to suspend this thread and then release it. + if (! ((GCHeapUtilities::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) || + (m_State & (TS_DebugSuspendPending | TS_StackCrawlNeeded))) ) + { + break; + } + + __SwitchToThread(0, ++dwSwitchCount); } STRESS_LOG0(LF_SYNC, LL_INFO1000, "RareDisablePreemptiveGC: leaving\n"); } From 419c5f94c7423b2e757ad045011f849ca51c464d Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 14 Aug 2020 17:03:40 +0200 Subject: [PATCH 490/755] skip the hanging System.Diagnostics.Tests.ProcessWaitingTests.SingleProcess_WaitAfterExited test on Mono (#40837) --- .../System.Diagnostics.Process/tests/ProcessWaitingTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs index b2db1071ab9d..7fd59fe0bce3 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs @@ -207,6 +207,7 @@ public async Task SingleProcess_TryWaitAsyncMultipleTimesBeforeCompleting() Assert.Equal(TaskStatus.RanToCompletion, task.Status); } + [SkipOnMono("Hangs on Mono, https://github.com/dotnet/runtime/issues/38943")] [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(false)] [InlineData(true)] From 2201a8e9ea0f0c3e9adff071edeef983ce51aa73 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Fri, 14 Aug 2020 18:07:25 +0300 Subject: [PATCH 491/755] Small library test clean up (#40833) --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 2 +- .../System.Diagnostics.Process/tests/ProcessWaitingTests.cs | 2 +- src/libraries/System.IO/tests/IndentedTextWriter.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index fe648a0b796b..77d7572ce626 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -45,7 +45,7 @@ public void TestCommonPriorityAndTimeProperties() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public void TestThreadCount() { int numOfThreads = 10; diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs index 7fd59fe0bce3..13935f80ec1a 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessWaitingTests.cs @@ -110,7 +110,7 @@ public async Task MultipleProcesses_ParallelStartKillWaitAsync() await Task.WhenAll(Enumerable.Range(0, Tasks).Select(_ => Task.Run(work)).ToArray()); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [InlineData(0)] // poll [InlineData(10)] // real timeout public void CurrentProcess_WaitNeverCompletes(int milliseconds) diff --git a/src/libraries/System.IO/tests/IndentedTextWriter.cs b/src/libraries/System.IO/tests/IndentedTextWriter.cs index 1c49ccd6de46..b71d4bfdbe11 100644 --- a/src/libraries/System.IO/tests/IndentedTextWriter.cs +++ b/src/libraries/System.IO/tests/IndentedTextWriter.cs @@ -91,7 +91,7 @@ public static void TabString_UsesProvidedString(string tabString) } } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [InlineData("\r\n")] [InlineData("\n")] [InlineData("newline")] From c75992f8ac752098348b0e75a8c538420d056982 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Fri, 14 Aug 2020 08:10:34 -0700 Subject: [PATCH 492/755] Fix ValidateResult for StoreSelectedScalar tests (#40800) Fix #40542 --- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Byte.15.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Double.1.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Int16.7.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Int32.3.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Int64.1.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.SByte.15.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.Single.3.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt16.7.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt32.3.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt64.1.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.Byte.7.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.Int16.3.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.Int32.1.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.SByte.7.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.Single.1.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt16.3.cs | 4 ++-- .../Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt32.1.cs | 4 ++-- .../Arm/Shared/StoreSelectedScalarTest.template | 4 ++-- 18 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Byte.15.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Byte.15.cs index 4902e3c0ff90..942ceb8338e4 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Byte.15.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Byte.15.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberName Byte[] outArray = new Byte[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Byte[] outArray = new Byte[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Double.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Double.1.cs index 17c63ff888d1..a357d8a2dd35 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Double.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Double.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNa Double[] outArray = new Double[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Double[] outArray = new Double[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int16.7.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int16.7.cs index d0b0697cd943..c0c8588acd2c 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int16.7.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int16.7.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNam Int16[] outArray = new Int16[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Int16[] outArray = new Int16[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int32.3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int32.3.cs index bb7cb3f5ddfb..8807b76e6ab4 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int32.3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int32.3.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNam Int32[] outArray = new Int32[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Int32[] outArray = new Int32[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int64.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int64.1.cs index 8b7ba34c8ee8..2d8d4bdd4d5c 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int64.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Int64.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNam Int64[] outArray = new Int64[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Int64[] outArray = new Int64[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.SByte.15.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.SByte.15.cs index 70d743b11f4e..856ea0abb6a5 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.SByte.15.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.SByte.15.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNam SByte[] outArray = new SByte[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m SByte[] outArray = new SByte[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Single.3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Single.3.cs index b367e5d4909c..66f25e05903e 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Single.3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.Single.3.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNa Single[] outArray = new Single[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Single[] outArray = new Single[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt16.7.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt16.7.cs index e3f2f9903cf4..24e151bfca30 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt16.7.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt16.7.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNa UInt16[] outArray = new UInt16[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m UInt16[] outArray = new UInt16[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt32.3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt32.3.cs index 15ea4619e92d..5f3f48e0f389 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt32.3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt32.3.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNa UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt64.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt64.1.cs index a2256eee8585..e28b7e94258e 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt64.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector128.UInt64.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector128 op1, void* result, [CallerMemberNa UInt64[] outArray = new UInt64[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m UInt64[] outArray = new UInt64[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Byte.7.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Byte.7.cs index 84ad6f0c200d..e12d2ee1cef4 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Byte.7.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Byte.7.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] Byte[] outArray = new Byte[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Byte[] outArray = new Byte[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int16.3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int16.3.cs index bc1dbfd3d1ba..94e2d8d4ab64 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int16.3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int16.3.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberName Int16[] outArray = new Int16[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Int16[] outArray = new Int16[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int32.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int32.1.cs index 8d4d914cc359..a2b2908968e1 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int32.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Int32.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberName Int32[] outArray = new Int32[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Int32[] outArray = new Int32[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.SByte.7.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.SByte.7.cs index caeec009fc3c..033cfde06e1a 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.SByte.7.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.SByte.7.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberName SByte[] outArray = new SByte[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m SByte[] outArray = new SByte[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Single.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Single.1.cs index 234926dc4d5e..ac517d26d537 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Single.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.Single.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberNam Single[] outArray = new Single[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m Single[] outArray = new Single[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt16.3.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt16.3.cs index 6db998a0b529..64afd4eb7d01 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt16.3.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt16.3.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberNam UInt16[] outArray = new UInt16[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m UInt16[] outArray = new UInt16[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt32.1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt32.1.cs index 46fc53118acb..6627dc100016 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt32.1.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/StoreSelectedScalar.Vector64.UInt32.1.cs @@ -417,7 +417,7 @@ private void ValidateResult(Vector64 op1, void* result, [CallerMemberNam UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ private void ValidateResult(void* op1, void* result, [CallerMemberName] string m UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template index 3d38d1b4742b..e7c0bf4b57f9 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template @@ -417,7 +417,7 @@ namespace JIT.HardwareIntrinsics.Arm {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf<{RetBaseType}>() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } @@ -428,7 +428,7 @@ namespace JIT.HardwareIntrinsics.Arm {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf<{RetBaseType}>() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } From 36513fe10315c5668ae1be9d7bcca54f2f850de3 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 14 Aug 2020 17:15:04 +0200 Subject: [PATCH 493/755] Dispose Process.Threads and Process.Modules when disposing and refreshing Process (#40681), fixes #40281 * Dispose Process.Threads when disposing and refreshing Process * Dispose Process.Modules when disposing and refreshing Process --- .../src/System/Diagnostics/Process.cs | 2 ++ .../Diagnostics/ProcessModuleCollection.cs | 8 ++++++++ .../Diagnostics/ProcessThreadCollection.cs | 9 ++++++++- .../tests/ProcessModuleTests.cs | 19 +++++++++++++++++++ .../tests/ProcessTestBase.cs | 3 ++- .../tests/ProcessThreadTests.cs | 19 +++++++++++++++++++ 6 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index d6acb3de5ae0..02bbf60cc7cb 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -1128,7 +1128,9 @@ private void RaiseOnExited() public void Refresh() { _processInfo = null; + _threads?.Dispose(); _threads = null; + _modules?.Dispose(); _modules = null; _exited = false; _haveWorkingSetLimits = false; diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs index 8b8f8bcaa641..5d56a6460c85 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs @@ -37,5 +37,13 @@ internal ProcessModuleCollection(int capacity) public bool Contains(ProcessModule module) => InnerList.Contains(module); public void CopyTo(ProcessModule[] array, int index) => InnerList.CopyTo(array, index); + + internal void Dispose() + { + foreach (ProcessModule processModule in this) + { + processModule.Dispose(); + } + } } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThreadCollection.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThreadCollection.cs index 93e10ba5ec29..68f2314490ad 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThreadCollection.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessThreadCollection.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; -using System.Collections.Generic; namespace System.Diagnostics { @@ -81,5 +80,13 @@ public void CopyTo(ProcessThread[] array, int index) { InnerList.CopyTo(array, index); } + + internal void Dispose() + { + foreach (ProcessThread processThread in this) + { + processThread.Dispose(); + } + } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessModuleTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessModuleTests.cs index 16060f8107ae..b716d4b709fe 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessModuleTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessModuleTests.cs @@ -68,5 +68,24 @@ public class ModuleCollectionSubClass : ProcessModuleCollection { public ModuleCollectionSubClass() : base() { } } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void ModulesAreDisposedWhenProcessIsDisposed() + { + Process process = CreateDefaultProcess(); + + ProcessModuleCollection modulesCollection = process.Modules; + int expectedCount = 0; + int disposedCount = 0; + foreach (ProcessModule processModule in modulesCollection) + { + expectedCount += 1; + processModule.Disposed += (_, __) => disposedCount += 1; + } + + process.Dispose(); + + Assert.Equal(expectedCount, disposedCount); + } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTestBase.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTestBase.cs index feb8dff5e849..6b1d00ea06b2 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTestBase.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTestBase.cs @@ -17,10 +17,11 @@ public partial class ProcessTestBase : FileCleanupTestBase protected Process _process; protected readonly List _processes = new List(); - protected void CreateDefaultProcess() + protected Process CreateDefaultProcess() { _process = CreateProcessLong(); _process.Start(); + return _process; } protected override void Dispose(bool disposing) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 77d7572ce626..0a39333d27a8 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -68,6 +68,25 @@ public void TestThreadCount() } } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void ThreadsAreDisposedWhenProcessIsDisposed() + { + Process process = CreateDefaultProcess(); + + ProcessThreadCollection threadCollection = process.Threads; + int expectedCount = 0; + int disposedCount = 0; + foreach (ProcessThread processThread in threadCollection) + { + expectedCount += 1; + processThread.Disposed += (_, __) => disposedCount += 1; + } + + process.Dispose(); + + Assert.Equal(expectedCount, disposedCount); + } + [Fact] [PlatformSpecific(TestPlatforms.OSX|TestPlatforms.FreeBSD)] // OSX and FreeBSD throw PNSE from StartTime public void TestStartTimeProperty_OSX() From 1e6e8d9c8faa9a0dd51c2de67fcf1f5e0a4a1ed5 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Fri, 14 Aug 2020 17:24:32 +0200 Subject: [PATCH 494/755] Console.Unix: make Console.OpenStandardInput Stream aware of terminal (#39192) * Console.Unix: make Console.OpenStandardInput Stream aware of terminal When performing OpenStandardInput against a terminal, perform Reads on a line-by-line basis and perform appropriate processing and echoing. * Add test * fix manual tests for Windows Co-authored-by: Eirik Tsarpalis --- .../src/System/ConsolePal.Unix.cs | 20 ++++- .../src/System/IO/StdInReader.cs | 83 +++++++++++++++---- .../src/System/IO/SyncTextReader.Unix.cs | 3 + .../tests/ManualTests/ManualTests.cs | 52 ++++++------ 4 files changed, 111 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs index 098601bfdbe9..017c55e8c8a3 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs @@ -43,7 +43,8 @@ internal static class ConsolePal public static Stream OpenStandardInput() { - return new UnixConsoleStream(SafeFileHandleHelper.Open(() => Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDIN_FILENO)), FileAccess.Read); + return new UnixConsoleStream(SafeFileHandleHelper.Open(() => Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDIN_FILENO)), FileAccess.Read, + useReadLine: !Console.IsInputRedirected); } public static Stream OpenStandardOutput() @@ -68,7 +69,7 @@ public static Encoding OutputEncoding private static SyncTextReader? s_stdInReader; - private static SyncTextReader StdInReader + internal static SyncTextReader StdInReader { get { @@ -1410,15 +1411,19 @@ private sealed class UnixConsoleStream : ConsoleStream /// The file descriptor for the opened file. private readonly SafeFileHandle _handle; + private readonly bool _useReadLine; + /// Initialize the stream. /// The file handle wrapped by this stream. /// FileAccess.Read or FileAccess.Write. - internal UnixConsoleStream(SafeFileHandle handle, FileAccess access) + /// Use ReadLine API for reading. + internal UnixConsoleStream(SafeFileHandle handle, FileAccess access, bool useReadLine = false) : base(access) { Debug.Assert(handle != null, "Expected non-null console handle"); Debug.Assert(!handle.IsInvalid, "Expected valid console handle"); _handle = handle; + _useReadLine = useReadLine; } protected override void Dispose(bool disposing) @@ -1434,7 +1439,14 @@ public override int Read(byte[] buffer, int offset, int count) { ValidateRead(buffer, offset, count); - return ConsolePal.Read(_handle, buffer, offset, count); + if (_useReadLine) + { + return ConsolePal.StdInReader.ReadLine(buffer, offset, count); + } + else + { + return ConsolePal.Read(_handle, buffer, offset, count); + } } public override void Write(byte[] buffer, int offset, int count) diff --git a/src/libraries/System.Console/src/System/IO/StdInReader.cs b/src/libraries/System.Console/src/System/IO/StdInReader.cs index 99ebbd34c614..6396176fbc90 100644 --- a/src/libraries/System.Console/src/System/IO/StdInReader.cs +++ b/src/libraries/System.Console/src/System/IO/StdInReader.cs @@ -22,6 +22,7 @@ internal sealed class StdInReader : TextReader private readonly Stack _tmpKeys = new Stack(); // temporary working stack; should be empty outside of ReadLine private readonly Stack _availableKeys = new Stack(); // a queue of already processed key infos available for reading private readonly Encoding _encoding; + private Encoder? _bufferReadEncoder; private char[] _unprocessedBufferToBeRead; // Buffer that might have already been read from stdin but not yet processed. private const int BytesToBeRead = 1024; // No. of bytes to be read from the stream at a time. @@ -79,13 +80,63 @@ internal unsafe int ReadStdin(byte* buffer, int bufferSize) public override string? ReadLine() { - return ReadLine(consumeKeys: true); + bool isEnter = ReadLineCore(consumeKeys: true); + string? line = null; + if (isEnter || _readLineSB.Length > 0) + { + line = _readLineSB.ToString(); + _readLineSB.Clear(); + } + return line; } - private string? ReadLine(bool consumeKeys) + public int ReadLine(byte[] buffer, int offset, int count) + { + if (count == 0) + { + return 0; + } + + // Don't read a new line if there are remaining characters in the StringBuilder. + if (_readLineSB.Length == 0) + { + bool isEnter = ReadLineCore(consumeKeys: true); + if (isEnter) + { + _readLineSB.Append('\n'); + } + } + + // Encode line into buffer. + Encoder encoder = _bufferReadEncoder ??= _encoding.GetEncoder(); + int bytesUsedTotal = 0; + int charsUsedTotal = 0; + Span destination = buffer.AsSpan(offset, count); + foreach (ReadOnlyMemory chunk in _readLineSB.GetChunks()) + { + encoder.Convert(chunk.Span, destination, flush: false, out int charsUsed, out int bytesUsed, out bool completed); + destination = destination.Slice(bytesUsed); + bytesUsedTotal += bytesUsed; + charsUsedTotal += charsUsed; + + if (charsUsed == 0) + { + break; + } + } + _readLineSB.Remove(0, charsUsedTotal); + return bytesUsedTotal; + } + + // Reads a line in _readLineSB when consumeKeys is true, + // or _availableKeys when consumeKeys is false. + // Returns whether the line was terminated using the Enter key. + private bool ReadLineCore(bool consumeKeys) { Debug.Assert(_tmpKeys.Count == 0); - string? readLineStr = null; + + // Don't carry over chars from previous ReadLine call. + _readLineSB.Clear(); Interop.Sys.InitializeConsoleBeforeRead(); try @@ -110,23 +161,15 @@ internal unsafe int ReadStdin(byte* buffer, int bufferSize) // try to keep this very simple, at least for now. if (keyInfo.Key == ConsoleKey.Enter) { - readLineStr = _readLineSB.ToString(); - _readLineSB.Clear(); if (!previouslyProcessed) { Console.WriteLine(); } - break; + return true; } else if (IsEol(keyInfo.KeyChar)) { - string line = _readLineSB.ToString(); - _readLineSB.Clear(); - if (line.Length > 0) - { - readLineStr = line; - } - break; + return false; } else if (keyInfo.Key == ConsoleKey.Backspace) { @@ -166,7 +209,10 @@ internal unsafe int ReadStdin(byte* buffer, int bufferSize) } else if (keyInfo.Key == ConsoleKey.Tab) { - _readLineSB.Append(keyInfo.KeyChar); + if (consumeKeys) + { + _readLineSB.Append(keyInfo.KeyChar); + } if (!previouslyProcessed) { Console.Write(' '); @@ -182,7 +228,10 @@ internal unsafe int ReadStdin(byte* buffer, int bufferSize) } else if (keyInfo.KeyChar != '\0') { - _readLineSB.Append(keyInfo.KeyChar); + if (consumeKeys) + { + _readLineSB.Append(keyInfo.KeyChar); + } if (!previouslyProcessed) { Console.Write(keyInfo.KeyChar); @@ -200,8 +249,6 @@ internal unsafe int ReadStdin(byte* buffer, int bufferSize) _availableKeys.Push(_tmpKeys.Pop()); } } - - return readLineStr; } public override int Read() => ReadOrPeek(peek: false); @@ -213,7 +260,7 @@ private int ReadOrPeek(bool peek) // If there aren't any keys in our processed keys stack, read a line to populate it. if (_availableKeys.Count == 0) { - ReadLine(consumeKeys: false); + ReadLineCore(consumeKeys: false); } // Now if there are keys, use the first. diff --git a/src/libraries/System.Console/src/System/IO/SyncTextReader.Unix.cs b/src/libraries/System.Console/src/System/IO/SyncTextReader.Unix.cs index f98499db4387..9e68d74c1b00 100644 --- a/src/libraries/System.Console/src/System/IO/SyncTextReader.Unix.cs +++ b/src/libraries/System.Console/src/System/IO/SyncTextReader.Unix.cs @@ -39,5 +39,8 @@ public bool KeyAvailable } } } + + public int ReadLine(byte[] buffer, int offset, int count) + => Inner.ReadLine(buffer, offset, count); } } diff --git a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs index 9bbec557dbb7..5928b7a34132 100644 --- a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs +++ b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; +using System.IO; using Xunit; namespace System @@ -23,6 +24,26 @@ public static void ReadLine(bool consoleIn) AssertUserExpectedResults("the characters you typed properly echoed as you typed"); } + [ConditionalFact(nameof(ManualTestsEnabled))] + public static void ReadLineFromOpenStandardInput() + { + string expectedLine = "aab"; + + // Use Console.ReadLine + Console.WriteLine($"Please type 'a' 3 times, press 'Backspace' to erase 1, then type a single 'b' and press 'Enter'."); + string result = Console.ReadLine(); + Assert.Equal(expectedLine, result); + AssertUserExpectedResults("the characters you typed properly echoed as you typed"); + + // ReadLine from Console.OpenStandardInput + Console.WriteLine($"Please type 'a' 3 times, press 'Backspace' to erase 1, then type a single 'b' and press 'Enter'."); + using Stream inputStream = Console.OpenStandardInput(); + using StreamReader reader = new StreamReader(inputStream); + result = reader.ReadLine(); + Assert.Equal(expectedLine, result); + AssertUserExpectedResults("the characters you typed properly echoed as you typed"); + } + [ConditionalFact(nameof(ManualTestsEnabled))] public static void ReadLine_BackSpaceCanMoveAccrossWrappedLines() { @@ -36,6 +57,7 @@ public static void ReadLine_BackSpaceCanMoveAccrossWrappedLines() } [ConditionalFact(nameof(ManualTestsEnabled))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/40735", TestPlatforms.Windows)] public static void InPeek() { Console.WriteLine("Please type \"peek\" (without the quotes). You should see it as you type:"); @@ -91,19 +113,11 @@ static string RenderKeyChord(ConsoleKeyInfo key) public static IEnumerable GetKeyChords() { - yield return MkConsoleKeyInfo('\x01', ConsoleKey.A, ConsoleModifiers.Control); - yield return MkConsoleKeyInfo('\x01', ConsoleKey.A, ConsoleModifiers.Control | ConsoleModifiers.Alt); + yield return MkConsoleKeyInfo('\x02', ConsoleKey.B, ConsoleModifiers.Control); + yield return MkConsoleKeyInfo(OperatingSystem.IsWindows() ? '\x00' : '\x02', ConsoleKey.B, ConsoleModifiers.Control | ConsoleModifiers.Alt); yield return MkConsoleKeyInfo('\r', ConsoleKey.Enter, (ConsoleModifiers)0); - - if (OperatingSystem.IsWindows()) - { - // windows will report '\n' as 'Ctrl+Enter', which is typically not picked up by Unix terminals - yield return MkConsoleKeyInfo('\n', ConsoleKey.Enter, ConsoleModifiers.Control); - } - else - { - yield return MkConsoleKeyInfo('\n', ConsoleKey.J, ConsoleModifiers.Control); - } + // windows will report '\n' as 'Ctrl+Enter', which is typically not picked up by Unix terminals + yield return MkConsoleKeyInfo('\n', OperatingSystem.IsWindows() ? ConsoleKey.Enter : ConsoleKey.J, ConsoleModifiers.Control); static object[] MkConsoleKeyInfo (char keyChar, ConsoleKey consoleKey, ConsoleModifiers modifiers) { @@ -117,18 +131,6 @@ static object[] MkConsoleKeyInfo (char keyChar, ConsoleKey consoleKey, ConsoleMo } } - [ConditionalFact(nameof(ManualTestsEnabled))] - public static void OpenStandardInput() - { - Console.WriteLine("Please type \"console\" (without the quotes). You shouldn't see it as you type:"); - var stream = Console.OpenStandardInput(); - var textReader = new System.IO.StreamReader(stream); - var result = textReader.ReadLine(); - - Assert.Equal("console", result); - AssertUserExpectedResults("\"console\" correctly not echoed as you typed it"); - } - [ConditionalFact(nameof(ManualTestsEnabled))] public static void ConsoleOutWriteLine() { @@ -216,7 +218,7 @@ public static void CursorPositionAndArrowKeys() } } - AssertUserExpectedResults("the arrow keys move around the screen as expected with no other bad artificts"); + AssertUserExpectedResults("the arrow keys move around the screen as expected with no other bad artifacts"); } [ConditionalFact(nameof(ManualTestsEnabled))] From ef4bc4d503b71f9de1a8988da6db38bcfcfb0cc4 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 14 Aug 2020 09:12:43 -0700 Subject: [PATCH 495/755] Remove obsoleted InplaceStringBuilder (#40743) --- .../tests/UnitTests/Internal/HostTests.cs | 2 - .../ref/Microsoft.Extensions.Primitives.cs | 13 -- .../src/InplaceStringBuilder.cs | 136 ----------------- .../Microsoft.Extensions.Primitives.csproj | 16 +- .../src/StringValues.cs | 7 +- .../tests/InplaceStringBuilderTest.cs | 143 ------------------ 6 files changed, 8 insertions(+), 309 deletions(-) delete mode 100644 src/libraries/Microsoft.Extensions.Primitives/src/InplaceStringBuilder.cs delete mode 100644 src/libraries/Microsoft.Extensions.Primitives/tests/InplaceStringBuilderTest.cs diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs index d160f022c9ae..12418bf46e83 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Internal/HostTests.cs @@ -1287,8 +1287,6 @@ public void Dispose() } } - - private class DelegateHostedService : IHostedService, IDisposable { private readonly Action _started; diff --git a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs index bfedc6b0be33..8b90df5a0053 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs @@ -36,19 +36,6 @@ public partial interface IChangeToken bool HasChanged { get; } System.IDisposable RegisterChangeCallback(System.Action callback, object state); } - [System.ObsoleteAttribute("This type is obsolete and will be removed in a future version.")] - public partial struct InplaceStringBuilder - { - private object _dummy; - private int _dummyPrimitive; - public InplaceStringBuilder(int capacity) { throw null; } - public int Capacity { get { throw null; } set { } } - public void Append(Microsoft.Extensions.Primitives.StringSegment segment) { } - public void Append(char c) { } - public void Append(string value) { } - public void Append(string value, int offset, int count) { } - public override string ToString() { throw null; } - } public readonly partial struct StringSegment : System.IEquatable, System.IEquatable { private readonly object _dummy; diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/InplaceStringBuilder.cs b/src/libraries/Microsoft.Extensions.Primitives/src/InplaceStringBuilder.cs deleted file mode 100644 index edb24de39fae..000000000000 --- a/src/libraries/Microsoft.Extensions.Primitives/src/InplaceStringBuilder.cs +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Microsoft.Extensions.Primitives -{ - [DebuggerDisplay("Value = {_value}")] - [Obsolete("This type is obsolete and will be removed in a future version.")] - public struct InplaceStringBuilder - { - private int _offset; - private int _capacity; - private string _value; - - public InplaceStringBuilder(int capacity) : this() - { - if (capacity < 0) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity); - } - - _capacity = capacity; - } - - public int Capacity - { - get => _capacity; - set - { - if (value < 0) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value); - } - - // _offset > 0 indicates writing state - if (_offset > 0) - { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Capacity_CannotChangeAfterWriteStarted); - } - - _capacity = value; - } - } - - public void Append(string value) - { - if (value == null) - { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); - } - - Append(value, 0, value.Length); - } - - public void Append(StringSegment segment) - { - Append(segment.Buffer, segment.Offset, segment.Length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(string value, int offset, int count) - { - EnsureValueIsInitialized(); - - if (value == null - || offset < 0 - || value.Length - offset < count - || Capacity - _offset < count) - { - ThrowValidationError(value, offset, count); - } - - fixed (char* destination = _value) - fixed (char* source = value) - { - Unsafe.CopyBlockUnaligned(destination + _offset, source + offset, (uint)count * 2); - _offset += count; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(char c) - { - EnsureValueIsInitialized(); - - if (_offset >= Capacity) - { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Capacity_NotEnough, 1, Capacity - _offset); - } - - fixed (char* destination = _value) - { - destination[_offset++] = c; - } - } - - public override string ToString() - { - if (Capacity != _offset) - { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Capacity_NotUsedEntirely, Capacity, _offset); - } - - return _value; - } - - private void EnsureValueIsInitialized() - { - if (_value == null) - { - _value = new string('\0', _capacity); - } - } - - private void ThrowValidationError(string value, int offset, int count) - { - if (value == null) - { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); - } - - if (offset < 0 || value.Length - offset < count) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset); - } - - if (Capacity - _offset < count) - { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Capacity_NotEnough, value.Length, Capacity - _offset); - } - } - } -} diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj index 0472414867b5..192e8f377e1c 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj +++ b/src/libraries/Microsoft.Extensions.Primitives/src/Microsoft.Extensions.Primitives.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 + true true true @@ -10,17 +11,10 @@ - - - - - - - - - - - + (() => formatter.ToString()); - Assert.Equal("Entire reserved capacity was not used. Capacity: '10', written '3'.", exception.Message); - } - - [Fact] - public void Build_ThrowsIfNotEnoughWritten() - { - var formatter = new InplaceStringBuilder(5); - formatter.Append("123"); - var exception = Assert.Throws(() => formatter.ToString()); - Assert.Equal("Entire reserved capacity was not used. Capacity: '5', written '3'.", exception.Message); - } - - [Fact] - public void Capacity_ThrowsIfAppendWasCalled() - { - var formatter = new InplaceStringBuilder(3); - formatter.Append("123"); - - var exception = Assert.Throws(() => formatter.Capacity = 5); - Assert.Equal("Cannot change capacity after write started.", exception.Message); - } - - [Fact] - public void Capacity_ThrowsIfNegativeValueSet() - { - var formatter = new InplaceStringBuilder(3); - - Assert.Throws(() => formatter.Capacity = -1); - } - - [Fact] - public void Capacity_GetReturnsCorrectValue() - { - var formatter = new InplaceStringBuilder(3); - Assert.Equal(3, formatter.Capacity); - - formatter.Capacity = 10; - Assert.Equal(10, formatter.Capacity); - - formatter.Append("abc"); - Assert.Equal(10, formatter.Capacity); - } - - [Fact] - public void Append_ThrowsIfValueIsNull() - { - var formatter = new InplaceStringBuilder(3); - - Assert.Throws(() => formatter.Append(null as string)); - } - - [Fact] - public void Append_ThrowsIfValueIsNullInOverloadWithIndex() - { - var formatter = new InplaceStringBuilder(3); - - Assert.Throws(() => formatter.Append(null as string, 0, 3)); - } - - [Fact] - public void Append_ThrowsIfOffsetIsNegative() - { - var formatter = new InplaceStringBuilder(3); - - Assert.Throws(() => formatter.Append("abc", -1, 3)); - } - - [Fact] - public void Append_ThrowIfValueLenghtMinusOffsetSmallerThanCount() - { - var formatter = new InplaceStringBuilder(3); - - Assert.Throws(() => formatter.Append("abc", 1, 3)); - } - - [Fact] - public void Append_ThrowsIfNotEnoughCapacity() - { - var formatter = new InplaceStringBuilder(1); - - var exception = Assert.Throws(() => formatter.Append("123")); - Assert.Equal("Not enough capacity to write '3' characters, only '1' left.", exception.Message); - } - - [Fact] - public void Append_ThrowsWhenNoCapacityIsSet() - { - var formatter = new InplaceStringBuilder(); - - var exception = Assert.Throws(() => formatter.Append("123")); - Assert.Equal("Not enough capacity to write '3' characters, only '0' left.", exception.Message); - } - } -} - -#pragma warning restore CS0618 From f3861cc669241640b4ee7cf8771eb1c15fa8915c Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 14 Aug 2020 09:48:43 -0700 Subject: [PATCH 496/755] Publish transport packages that are not runtime packages (#40801) --- src/installer/publish/Directory.Build.targets | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/installer/publish/Directory.Build.targets b/src/installer/publish/Directory.Build.targets index 76bebb473a56..bd6890ed2984 100644 --- a/src/installer/publish/Directory.Build.targets +++ b/src/installer/publish/Directory.Build.targets @@ -68,7 +68,11 @@ $(DownloadDirectory)*\Libraries_AllConfigurations\**\*.nupkg" Exclude="@(RuntimeNupkgFile);@(DownloadedSymbolNupkgFile)" /> - + + + $(NetCoreAppCurrent) + true - @@ -14,6 +15,20 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 6a7cf68cc12a..85997fa96cc5 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -325,15 +325,6 @@ protected override void SerializeToStream(System.IO.Stream stream, System.Net.Tr protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } - public partial class SocketsHttpConnectionFactory : System.Net.Connections.ConnectionFactory - { - public SocketsHttpConnectionFactory() { } - public sealed override System.Threading.Tasks.ValueTask ConnectAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Net.Sockets.Socket CreateSocket(System.Net.Http.HttpRequestMessage message, System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties options) { throw null; } - protected override void Dispose(bool disposing) { } - protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } - public virtual System.Threading.Tasks.ValueTask EstablishConnectionAsync(System.Net.Http.HttpRequestMessage message, System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties options, System.Threading.CancellationToken cancellationToken) { throw null; } - } public sealed partial class SocketsHttpHandler : System.Net.Http.HttpMessageHandler { public SocketsHttpHandler() { } 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 ec91aeb408c9..7794c3985bcf 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -1,4 +1,4 @@ - + win true @@ -177,10 +177,7 @@ - - - - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs deleted file mode 100644 index 664de02694ba..000000000000 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpConnectionFactory.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using System.Net.Connections; -using System.Net.Sockets; - -namespace System.Net.Http -{ - public class SocketsHttpConnectionFactory : ConnectionFactory - { - public sealed override ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) - => throw new NotImplementedException(); - - public virtual Socket CreateSocket(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options) - => throw new NotImplementedException(); - - public virtual ValueTask EstablishConnectionAsync(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options, CancellationToken cancellationToken) - => throw new NotImplementedException(); - } -} 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 97ec60c5c7cd..587913e22893 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 @@ -3,10 +3,12 @@ using System.Diagnostics; using System.IO; +using System.IO.Pipelines; using System.Net.Connections; using System.Net.Quic; using System.Net.Security; using System.Net.Sockets; +using System.Runtime.ExceptionServices; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -76,7 +78,8 @@ public static Connection Connect(string host, int port, CancellationToken cancel throw CreateWrappedException(e, host, port, cancellationToken); } - return new SocketConnection(socket); + // Since we only do GracefulShutdown in SocketsHttpHandler code, Connection.FromStream() should match SocketConnection's behavior: + return Connection.FromStream(new NetworkStream(socket, ownsSocket: true), localEndPoint: socket.LocalEndPoint, remoteEndPoint: socket.RemoteEndPoint); } public static ValueTask EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs index b99801c1fac1..ef4ee0b51029 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs @@ -9,18 +9,18 @@ namespace System.Net.Http // Passed to a connection factory, merges allocations for the DnsEndPoint and connection properties. internal sealed class DnsEndPointWithProperties : DnsEndPoint, IConnectionProperties { - public HttpRequestMessage InitialRequest { get; } + private readonly HttpRequestMessage _initialRequest; public DnsEndPointWithProperties(string host, int port, HttpRequestMessage initialRequest) : base(host, port) { - InitialRequest = initialRequest; + _initialRequest = initialRequest; } bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) { - if (propertyKey == typeof(DnsEndPointWithProperties)) + if (propertyKey == typeof(HttpRequestMessage)) { - property = this; + property = _initialRequest; return true; } 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 33a93b075501..fedcbab4cba3 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 @@ -1265,11 +1265,13 @@ public ValueTask SendAsync(HttpRequestMessage request, bool } } + private static readonly SocketsConnectionFactory s_defaultConnectionFactory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); + private ValueTask ConnectToTcpHostAsync(string host, int port, HttpRequestMessage initialRequest, bool async, CancellationToken cancellationToken) { if (async) { - ConnectionFactory connectionFactory = Settings._connectionFactory ?? SocketsHttpConnectionFactory.Default; + ConnectionFactory connectionFactory = Settings._connectionFactory ?? s_defaultConnectionFactory; var endPoint = new DnsEndPointWithProperties(host, port, initialRequest); return ConnectHelper.ConnectAsync(connectionFactory, endPoint, endPoint, cancellationToken); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs deleted file mode 100644 index 34018a14170a..000000000000 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpConnectionFactory.cs +++ /dev/null @@ -1,94 +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.Net.Connections; -using System.Net.Sockets; -using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Http -{ - /// - /// The default connection factory used by , opening TCP connections. - /// - public class SocketsHttpConnectionFactory : ConnectionFactory - { - internal static SocketsHttpConnectionFactory Default { get; } = new SocketsHttpConnectionFactory(); - - /// - public sealed override ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) - { - if (options == null || !options.TryGet(out DnsEndPointWithProperties? httpOptions)) - { - return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException($"{nameof(SocketsHttpConnectionFactory)} requires a {nameof(DnsEndPointWithProperties)} property."))); - } - - return EstablishConnectionAsync(httpOptions!.InitialRequest, endPoint, options, cancellationToken); - } - - /// - /// Creates the socket to be used for a request. - /// - /// The request causing this socket to be opened. Once opened, it may be reused for many subsequent requests. - /// The EndPoint this socket will be connected to. - /// Properties, if any, that might change how the socket is initialized. - /// A new unconnected socket. - public virtual Socket CreateSocket(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options) - { - return new Socket(SocketType.Stream, ProtocolType.Tcp); - } - - /// - /// Establishes a new connection for a request. - /// - /// The request causing this connection to be established. Once connected, it may be reused for many subsequent requests. - /// The EndPoint to connect to. - /// Properties, if any, that might change how the connection is made. - /// A cancellation token for the asynchronous operation. - /// A new open connection. - public virtual async ValueTask EstablishConnectionAsync(HttpRequestMessage message, EndPoint? endPoint, IConnectionProperties options, CancellationToken cancellationToken) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - if (endPoint == null) throw new ArgumentNullException(nameof(endPoint)); - - Socket socket = CreateSocket(message, endPoint, options); - - try - { - using var args = new TaskSocketAsyncEventArgs(); - args.RemoteEndPoint = endPoint; - - if (socket.ConnectAsync(args)) - { - using (cancellationToken.UnsafeRegister(o => Socket.CancelConnectAsync((SocketAsyncEventArgs)o!), args)) - { - await args.Task.ConfigureAwait(false); - } - } - - if (args.SocketError != SocketError.Success) - { - Exception ex = args.SocketError == SocketError.OperationAborted && cancellationToken.IsCancellationRequested - ? (Exception)new OperationCanceledException(cancellationToken) - : new SocketException((int)args.SocketError); - - throw ex; - } - - socket.NoDelay = true; - return new SocketConnection(socket); - } - catch (SocketException socketException) - { - socket.Dispose(); - throw NetworkErrorHelper.MapSocketException(socketException); - } - catch - { - socket.Dispose(); - throw; - } - } - } -} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index fbe84c6a4a66..dbe8388b05c9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -365,7 +365,7 @@ public bool EnableMultipleHttp2Connections /// /// When non-null, a custom factory used to open new TCP connections. - /// When null, a will be used. + /// When null, a will be used. /// public ConnectionFactory? ConnectionFactory { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 49266bd125ff..c2ab2dfb6372 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -152,7 +152,7 @@ public async Task CustomConnectionFactory_AsyncRequest_Success() [Fact] public async Task CustomConnectionFactory_SyncRequest_Fails() { - await using ConnectionFactory connectionFactory = new SocketsHttpConnectionFactory(); + await using ConnectionFactory connectionFactory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); using SocketsHttpHandler handler = new SocketsHttpHandler { ConnectionFactory = connectionFactory @@ -161,7 +161,46 @@ public async Task CustomConnectionFactory_SyncRequest_Fails() using HttpClient client = CreateHttpClient(handler); HttpRequestException e = await Assert.ThrowsAnyAsync(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo")); - NetworkException networkException = Assert.IsType(e.InnerException); + Assert.IsType(e.InnerException); + } + + class CustomConnectionFactory : SocketsConnectionFactory + { + public CustomConnectionFactory() : base(SocketType.Stream, ProtocolType.Tcp) { } + + public HttpRequestMessage LastHttpRequestMessage { get; private set; } + + public override ValueTask ConnectAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default) + { + if (options.TryGet(out HttpRequestMessage message)) + { + LastHttpRequestMessage = message; + } + + return base.ConnectAsync(endPoint, options, cancellationToken); + } + } + + [Fact] + public Task CustomConnectionFactory_ConnectAsync_CanCaptureHttpRequestMessage() + { + return LoopbackServer.CreateClientAndServerAsync(async uri => + { + using var connectionFactory = new CustomConnectionFactory(); + using var handler = new SocketsHttpHandler() + { + ConnectionFactory = connectionFactory + }; + using HttpClient client = CreateHttpClient(handler); + + using var request = new HttpRequestMessage(HttpMethod.Get, uri); + + using HttpResponseMessage response = await client.SendAsync(request); + string content = await response.Content.ReadAsStringAsync(); + + Assert.Equal("OK", content); + Assert.Same(request, connectionFactory.LastHttpRequestMessage); + }, server => server.HandleRequestAsync(content: "OK")); } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj b/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj index ef710218ea2a..43662fa98f8d 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj @@ -90,4 +90,4 @@ - + \ No newline at end of file From 978b39bbe6f4d799ece1a4153730fab18324f076 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Fri, 14 Aug 2020 10:22:26 -0700 Subject: [PATCH 499/755] Add the GT_MEMORYBARRIER operator to the set of instructions that need to record a ByrefExposed memory havoc impact in loops (#40821) This prevents the hoisting of memory loads out of such a loop --- src/coreclr/src/jit/optimizer.cpp | 9 +-- .../JitBlue/Runtime_40444/Runtime_40444.cs | 66 +++++++++++++++++++ .../Runtime_40444/Runtime_40444.csproj | 12 ++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.csproj diff --git a/src/coreclr/src/jit/optimizer.cpp b/src/coreclr/src/jit/optimizer.cpp index d953ecd92aed..ed5bd116b380 100644 --- a/src/coreclr/src/jit/optimizer.cpp +++ b/src/coreclr/src/jit/optimizer.cpp @@ -7920,10 +7920,11 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) } break; - case GT_LOCKADD: // Binop - case GT_XADD: // Binop - case GT_XCHG: // Binop - case GT_CMPXCHG: // Specialop + case GT_LOCKADD: + case GT_XADD: + case GT_XCHG: + case GT_CMPXCHG: + case GT_MEMORYBARRIER: { assert(!tree->OperIs(GT_LOCKADD) && "LOCKADD should not appear before lowering"); memoryHavoc |= memoryKindSet(GcHeap, ByrefExposed); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.cs b/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.cs new file mode 100644 index 000000000000..922ea41196ff --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.cs @@ -0,0 +1,66 @@ +// 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.Threading; +using System.Runtime.CompilerServices; + +class Runtime_40444 +{ + + public static int t2_result = 0; + public static int t2_finished; + + static void Thread2() + { + t2_result++; + t2_finished = 1; + } + +// [MethodImpl(MethodImplOptions.NoInlining)] + static int TestVolatileRead(ref int address) + { + int ret = address; + Thread.MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. + return ret; + } + + static bool Test() + { + bool result = false; + t2_finished = 0; + + // Run Thread2() in a new thread + new Thread(new ThreadStart(Thread2)).Start(); + + // Wait for Thread2 to signal that it has a result by setting + // t2_finished to 1. + for (int i=0; i<10000000; i++) + { + if (TestVolatileRead(ref t2_finished)==1) + { + Console.WriteLine("{1}: result = {0}", t2_result, i); + result = true; + break; + } + } + if (result == false) + { + Console.WriteLine("FAILED"); + } + return result; + } + + static int Main() + { + for (int i=0; i<100; i++) + { + if (!Test()) + { + return -1; + } + } + Console.WriteLine("Passed"); + return t2_result; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.csproj new file mode 100644 index 000000000000..986494e092b5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.csproj @@ -0,0 +1,12 @@ + + + Exe + + + + True + + + + + From 1355a595aa8a39194f02dff9ba5b53a24305468d Mon Sep 17 00:00:00 2001 From: Charles Stoner Date: Fri, 14 Aug 2020 10:30:59 -0700 Subject: [PATCH 500/755] Fix EmitLoadValueIndirect() for SByte and Byte (#40741) --- .../System/Linq/Expressions/Compiler/ILGen.cs | 4 +-- .../BinaryOperators/Assignment/OpAssign.cs | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs index 918b27e6f1c7..ea863c5bcb4e 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs @@ -61,11 +61,11 @@ internal static void EmitLoadValueIndirect(this ILGenerator il, Type type) switch (type.GetTypeCode()) { - case TypeCode.Byte: + case TypeCode.SByte: il.Emit(OpCodes.Ldind_I1); break; case TypeCode.Boolean: - case TypeCode.SByte: + case TypeCode.Byte: il.Emit(OpCodes.Ldind_U1); break; case TypeCode.Int16: diff --git a/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/OpAssign.cs b/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/OpAssign.cs index 3c72d9005bda..f2d8826eeee1 100644 --- a/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/OpAssign.cs +++ b/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/OpAssign.cs @@ -605,5 +605,36 @@ public void ConvertOpWriteByRefParameterOverloadedOperator(bool useInterpreter) AddsToSomethingElse result = del(ref arg, new AddsToSomethingElse(35)); Assert.Equal(result, arg); } + + private delegate void RightShiftAssignDelegate(ref T left, int right); + + [Fact] + public void RightShiftAssign() + { + Evaluate(unchecked((sbyte)0x80), 7, (sbyte)-1); + Evaluate(unchecked((byte)0x80), 7, (byte)1); + Evaluate(unchecked((short)0x8000), 15, (short)-1); + Evaluate(unchecked((ushort)0x8000), 15, (ushort)1); + Evaluate(unchecked((int)0x8000_0000), 31, (int)-1); + Evaluate(unchecked((uint)0x8000_0000), 31, (uint)1); + Evaluate(unchecked((long)0x8000_0000_0000_0000), 63, (long)-1); + Evaluate(unchecked((ulong)0x8000_0000_0000_0000), 63, (ulong)1); + + static void Evaluate(T left, int right, T expected) + { + var leftOperand = Expression.Parameter(typeof(T).MakeByRefType()); + var rightOperand = Expression.Parameter(typeof(int)); + var expr = Expression.RightShiftAssign(leftOperand, rightOperand); + var lambda = Expression.Lambda>(expr, leftOperand, rightOperand); + CompileAndInvoke(lambda, left, right, expected, preferInterpretation: false); + CompileAndInvoke(lambda, left, right, expected, preferInterpretation: true); + } + + static void CompileAndInvoke(Expression> expr, T left, int right, T expected, bool preferInterpretation) + { + expr.Compile(preferInterpretation).Invoke(ref left, right); + Assert.Equal(expected, left); + } + } } } From b932a519893b1350e3b97e272efca0e777180787 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 14 Aug 2020 18:41:13 +0100 Subject: [PATCH 501/755] Improve SpanHelpers.IndexOfAny(byte,byte) (#40747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve SpanHelpers.IndexOfAny(byte,byte) * Update src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs Co-authored-by: Günther Foidl * Update src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs Co-authored-by: Dan Moseley Co-authored-by: Günther Foidl Co-authored-by: Dan Moseley --- .../src/System/SpanHelpers.Byte.cs | 313 ++++++++++-------- 1 file changed, 177 insertions(+), 136 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs index 2d1d2278e296..18056b147b2e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs @@ -603,19 +603,30 @@ public static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int if (Sse2.IsSupported || AdvSimd.Arm64.IsSupported) { // Avx2 branch also operates on Sse2 sizes, so check is combined. - if (length >= Vector128.Count * 2) + nint vectorDiff = (nint)length - Vector128.Count; + if (vectorDiff >= 0) { - lengthToExamine = UnalignedCountVector128(ref searchSpace); + // >= Sse2 intrinsics are supported, and length is enough to use them so use that path. + // We jump forward to the intrinsics at the end of the method so a naive branch predict + // will choose the non-intrinsic path so short lengths which don't gain anything aren't + // overly disadvantaged by having to jump over a lot of code. Whereas the longer lengths + // more than make this back from the intrinsics. + lengthToExamine = (nuint)vectorDiff; + goto IntrinsicsCompare; } } else if (Vector.IsHardwareAccelerated) { - if (length >= Vector.Count * 2) + // Calculate lengthToExamine here for test, as it is used later + nint vectorDiff = (nint)length - Vector.Count; + if (vectorDiff >= 0) { - lengthToExamine = UnalignedCountVector(ref searchSpace); + // Similar as above for Vector version + lengthToExamine = (nuint)vectorDiff; + goto IntrinsicsCompare; } } - SequentialScan: + uint lookUp; while (lengthToExamine >= 8) { @@ -671,204 +682,234 @@ public static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int while (lengthToExamine > 0) { - lengthToExamine -= 1; lookUp = Unsafe.AddByteOffset(ref searchSpace, offset); if (uValue0 == lookUp || uValue1 == lookUp) goto Found; offset += 1; + lengthToExamine -= 1; } - // We get past SequentialScan only if IsHardwareAccelerated or intrinsic .IsSupported is true. However, we still have the redundant check to allow - // the JIT to see that the code is unreachable and eliminate it when the platform does not have hardware accelerated. - if (Avx2.IsSupported) + NotFound: + return -1; + Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 + return (int)offset; + Found1: + return (int)(offset + 1); + Found2: + return (int)(offset + 2); + Found3: + return (int)(offset + 3); + Found4: + return (int)(offset + 4); + Found5: + return (int)(offset + 5); + Found6: + return (int)(offset + 6); + Found7: + return (int)(offset + 7); + + IntrinsicsCompare: + // When we move into a Vectorized block, we process everything of Vector size; + // and then for any remainder we do a final compare of Vector size but starting at + // the end and forwards, which may overlap on an earlier compare. + + // We include the Supported check again here even though path will not be taken, so the asm isn't generated if not supported. + if (Sse2.IsSupported) { - if (offset < (nuint)(uint)length) + int matches; + if (Avx2.IsSupported) { - lengthToExamine = GetByteVector256SpanLength(offset, length); - if (lengthToExamine > offset) + Vector256 search; + // Guard as we may only have a valid size for Vector128; when we will move to the Sse2 + // We have already subtracted Vector128.Count from lengthToExamine so compare against that + // to see if we have double the size for Vector256.Count + if (lengthToExamine >= (nuint)Vector128.Count) { Vector256 values0 = Vector256.Create(value0); Vector256 values1 = Vector256.Create(value1); - do + + // Subtract Vector128.Count so we have now subtracted Vector256.Count + lengthToExamine -= (nuint)Vector128.Count; + // First time this checks again against 0, however we will move into final compare if it fails. + while (lengthToExamine > offset) { - Vector256 search = LoadVector256(ref searchSpace, offset); - // Bitwise Or to combine the matches and MoveMask to convert them to bitflags - int matches = Avx2.MoveMask( - Avx2.Or( - Avx2.CompareEqual(values0, search), - Avx2.CompareEqual(values1, search))); + search = LoadVector256(ref searchSpace, offset); + // Bitwise Or to combine the flagged matches for the second value to our match flags + matches = Avx2.MoveMask( + Avx2.Or( + Avx2.CompareEqual(values0, search), + Avx2.CompareEqual(values1, search))); // Note that MoveMask has converted the equal vector elements into a set of bit flags, // So the bit position in 'matches' corresponds to the element offset. if (matches == 0) { - // Zero flags set so no matches + // None matched offset += (nuint)Vector256.Count; continue; } - // Find bitflag offset of first match and add to current offset - return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); - } while (lengthToExamine > offset); - } - - lengthToExamine = GetByteVector128SpanLength(offset, length); - if (lengthToExamine > offset) - { - Vector128 values0 = Vector128.Create(value0); - Vector128 values1 = Vector128.Create(value1); + goto IntrinsicsMatch; + } - Vector128 search = LoadVector128(ref searchSpace, offset); - // Same method as above - int matches = Sse2.MoveMask( - Sse2.Or( - Sse2.CompareEqual(values0, search), - Sse2.CompareEqual(values1, search))); + // Move to Vector length from end for final compare + search = LoadVector256(ref searchSpace, lengthToExamine); + offset = lengthToExamine; + // Same as method as above + matches = Avx2.MoveMask( + Avx2.Or( + Avx2.CompareEqual(values0, search), + Avx2.CompareEqual(values1, search))); if (matches == 0) { - // Zero flags set so no matches - offset += (nuint)Vector128.Count; + // None matched + goto NotFound; } - else - { - // Find bitflag offset of first match and add to current offset - return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); - } - } - if (offset < (nuint)(uint)length) - { - lengthToExamine = ((nuint)(uint)length - offset); - goto SequentialScan; + goto IntrinsicsMatch; } } - } - else if (Sse2.IsSupported) - { - if (offset < (nuint)(uint)length) - { - lengthToExamine = GetByteVector128SpanLength(offset, length); + // Initial size check was done on method entry. + Debug.Assert(length >= Vector128.Count); + { + Vector128 search; Vector128 values0 = Vector128.Create(value0); Vector128 values1 = Vector128.Create(value1); - + // First time this checks against 0 and we will move into final compare if it fails. while (lengthToExamine > offset) { - Vector128 search = LoadVector128(ref searchSpace, offset); - // Same method as above - int matches = Sse2.MoveMask( + search = LoadVector128(ref searchSpace, offset); + + matches = Sse2.MoveMask( Sse2.Or( Sse2.CompareEqual(values0, search), - Sse2.CompareEqual(values1, search))); + Sse2.CompareEqual(values1, search)) + .AsByte()); + // Note that MoveMask has converted the equal vector elements into a set of bit flags, + // So the bit position in 'matches' corresponds to the element offset. if (matches == 0) { - // Zero flags set so no matches + // None matched offset += (nuint)Vector128.Count; continue; } - // Find bitflag offset of first match and add to current offset - return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); + goto IntrinsicsMatch; } - - if (offset < (nuint)(uint)length) + // Move to Vector length from end for final compare + search = LoadVector128(ref searchSpace, lengthToExamine); + offset = lengthToExamine; + // Same as method as above + matches = Sse2.MoveMask( + Sse2.Or( + Sse2.CompareEqual(values0, search), + Sse2.CompareEqual(values1, search))); + if (matches == 0) { - lengthToExamine = ((nuint)(uint)length - offset); - goto SequentialScan; + // None matched + goto NotFound; } } + + IntrinsicsMatch: + // Find bitflag offset of first difference and add to current offset + offset += (nuint)BitOperations.TrailingZeroCount(matches); + goto Found; } else if (AdvSimd.Arm64.IsSupported) { - if (offset < (nuint)(uint)length) - { - lengthToExamine = GetByteVector128SpanLength(offset, length); + // Mask to help find the first lane in compareResult that is set. + // LSB 0x01 corresponds to lane 0, 0x10 - to lane 1, and so on. + Vector128 mask = Vector128.Create((ushort)0x1001).AsByte(); + int matchedLane = 0; - // Mask to help find the first lane in compareResult that is set. - // LSB 0x01 corresponds to lane 0, 0x10 - to lane 1, and so on. - Vector128 mask = Vector128.Create((ushort)0x1001).AsByte(); - int matchedLane = 0; + Vector128 search; + Vector128 matches; + Vector128 values0 = Vector128.Create(value0); + Vector128 values1 = Vector128.Create(value1); + // First time this checks against 0 and we will move into final compare if it fails. + while (lengthToExamine > offset) + { + search = LoadVector128(ref searchSpace, offset); - Vector128 values0 = Vector128.Create(value0); - Vector128 values1 = Vector128.Create(value1); + matches = AdvSimd.Or( + AdvSimd.CompareEqual(values0, search), + AdvSimd.CompareEqual(values1, search)); - while (lengthToExamine > offset) + if (!TryFindFirstMatchedLane(mask, matches, ref matchedLane)) { - Vector128 search = LoadVector128(ref searchSpace, offset); + // Zero flags set so no matches + offset += (nuint)Vector128.Count; + continue; + } - // Same method as above - Vector128 compareResult = AdvSimd.Or( - AdvSimd.CompareEqual(values0, search), - AdvSimd.CompareEqual(values1, search)); + // Find bitflag offset of first match and add to current offset + offset += (uint)matchedLane; - if (!TryFindFirstMatchedLane(mask, compareResult, ref matchedLane)) - { - // Zero flags set so no matches - offset += (nuint)Vector128.Count; - continue; - } + goto Found; + } - // Find bitflag offset of first match and add to current offset - return (int)(offset + (uint)matchedLane); - } + // Move to Vector length from end for final compare + search = LoadVector128(ref searchSpace, lengthToExamine); + offset = lengthToExamine; + // Same as method as above + matches = AdvSimd.Or( + AdvSimd.CompareEqual(values0, search), + AdvSimd.CompareEqual(values1, search)); - if (offset < (nuint)(uint)length) - { - lengthToExamine = ((nuint)(uint)length - offset); - goto SequentialScan; - } + if (!TryFindFirstMatchedLane(mask, matches, ref matchedLane)) + { + // None matched + goto NotFound; } + + // Find bitflag offset of first match and add to current offset + offset += (nuint)(uint)matchedLane; + + goto Found; } else if (Vector.IsHardwareAccelerated) { - if (offset < (nuint)(uint)length) - { - lengthToExamine = GetByteVectorSpanLength(offset, length); - - Vector values0 = new Vector(value0); - Vector values1 = new Vector(value1); + Vector values0 = new Vector(value0); + Vector values1 = new Vector(value1); - while (lengthToExamine > offset) + Vector search; + // First time this checks against 0 and we will move into final compare if it fails. + while (lengthToExamine > offset) + { + search = LoadVector(ref searchSpace, offset); + search = Vector.BitwiseOr( + Vector.Equals(search, values0), + Vector.Equals(search, values1)); + if (Vector.Zero.Equals(search)) { - Vector search = LoadVector(ref searchSpace, offset); - var matches = Vector.BitwiseOr( - Vector.Equals(search, values0), - Vector.Equals(search, values1)); - if (Vector.Zero.Equals(matches)) - { - offset += (nuint)Vector.Count; - continue; - } - - // Find offset of first match and add to current offset - return (int)offset + LocateFirstFoundByte(matches); + // None matched + offset += (nuint)Vector.Count; + continue; } - if (offset < (nuint)(uint)length) - { - lengthToExamine = ((nuint)(uint)length - offset); - goto SequentialScan; - } + goto Difference; } + + // Move to Vector length from end for final compare + search = LoadVector(ref searchSpace, lengthToExamine); + offset = lengthToExamine; + search = Vector.BitwiseOr( + Vector.Equals(search, values0), + Vector.Equals(search, values1)); + if (Vector.Zero.Equals(search)) + { + // None matched + goto NotFound; + } + + Difference: + offset += (nuint)LocateFirstFoundByte(search); } - return -1; - Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)offset; - Found1: - return (int)(offset + 1); - Found2: - return (int)(offset + 2); - Found3: - return (int)(offset + 3); - Found4: - return (int)(offset + 4); - Found5: - return (int)(offset + 5); - Found6: - return (int)(offset + 6); - Found7: - return (int)(offset + 7); + + goto Found; } [MethodImpl(MethodImplOptions.AggressiveOptimization)] From 64fd348415942f15a5af8885f522112c0ab57634 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 14 Aug 2020 13:33:23 -0500 Subject: [PATCH 502/755] Remove unused method (#40658) --- .../Runtime/BindingFlagSupport/Shared.cs | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs index 0870a1f583da..dfab8e7c1e4d 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs @@ -76,50 +76,5 @@ public static bool QualifiesBasedOnParameterCount(this MethodBase methodBase, Bi return true; } - - // - // If member is a virtual member that implicitly overrides a member in a base class, return the overridden member. - // Otherwise, return null. - // - // - MethodImpls ignored. (I didn't say it made sense, this is just how the .NET Framework api we're porting behaves.) - // - Implemented interfaces ignores. (I didn't say it made sense, this is just how the .NET Framework api we're porting behaves.) - // - public static M? GetImplicitlyOverriddenBaseClassMember(this M member) where M : MemberInfo - { - MemberPolicies policies = MemberPolicies.Default; - policies.GetMemberAttributes(member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot); - if (isNewSlot || !isVirtual) - { - return null; - } - string name = member.Name; - TypeInfo typeInfo = member.DeclaringType!.GetTypeInfo(); - while (true) - { - Type? baseType = typeInfo.BaseType; - if (baseType == null) - { - return null; - } - typeInfo = baseType.GetTypeInfo(); - foreach (M candidate in policies.GetDeclaredMembers(typeInfo)) - { - if (candidate.Name != name) - { - continue; - } - policies.GetMemberAttributes(member, out MethodAttributes candidateVisibility, out bool isCandidateStatic, out bool isCandidateVirtual, out bool isCandidateNewSlot); - if (!isCandidateVirtual) - { - continue; - } - if (!policies.ImplicitlyOverrides(candidate, member)) - { - continue; - } - return candidate; - } - } - } } } From a2908e327a38ed6871b68ea6fbeca5197cc59ea2 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 14 Aug 2020 13:35:26 -0500 Subject: [PATCH 503/755] Increase method resolution test coverage for generics (#40657) --- .../src/SampleMetadata/SampleMetadata.cs | 25 +++++++++++++++++++ .../tests/src/Tests/Type/TypeTests.cs | 23 +++++++++++++++++ .../TypeInfo_GenericTypeParametersTests.cs | 9 ------- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs index 628d50ceaeb5..743eb72befda 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs @@ -450,6 +450,8 @@ public class MarkAttribute : Attribute public MarkAttribute(int mark) { } } + public class MyGenericClass { } + public class MethodHolderBase { [Mark(10)] @@ -467,6 +469,17 @@ public virtual void Voo(int x, int y) { } [Mark(30)] private void Poo(int x, int y) { } + [Mark(40)] + public virtual void Foo(MyGenericClass x, int y) { } + + [Mark(50)] + public virtual void Foo(MyGenericClass x, int y) { } + + [Mark(60)] + public virtual void Foo(MyGenericClass x, string y) { } + + [Mark(70)] + public virtual void Foo(int x, int y) { } } public class MethodHolderDerived : MethodHolderBase @@ -476,6 +489,18 @@ public class MethodHolderDerived : MethodHolderBase [Mark(10020)] public override void Voo(int x, int y) { } + + [Mark(10040)] + public override void Foo(MyGenericClass x, int y) { } + + [Mark(10050)] + public virtual void Foo(MyGenericClass x, int y) { } + + [Mark(10060)] + public override void Foo(MyGenericClass x, string y) { } + + [Mark(10070)] + public override void Foo(int x, int y) { } } public class PropertyHolder1 diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index d14c4b849f0a..f0693691d865 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -468,6 +468,29 @@ public static void TestMethodSelection1() MethodInfo m = gi.GetMethod("Hoo", bf, binder, types, null); Assert.Equal(11, m.GetMark()); } + + { + Type mgc = typeof(MyGenericClass<>).Project(); + Type mgcClosed = mgc.MakeGenericType(typeof(int).Project()); + Assert.Equal(mgc, mgcClosed.GetGenericTypeDefinition()); + + Type gi = t.MakeGenericType(typeof(int).Project()); + Type[] types = { mgcClosed, typeof(string).Project() }; + MethodInfo m = gi.GetMethod("Foo", bf, binder, types, null); + Assert.Equal(10060, m.GetMark()); + } + + { + Type[] types = { typeof(int).Project(), typeof(short).Project() }; + MethodInfo m = typeof(MethodHolderDerived<>).Project().GetMethod("Foo", bf, binder, types, null); + Assert.Equal(10070, m.GetMark()); + } + + { + Type[] types = { typeof(int).Project(), typeof(int).Project() }; + MethodInfo m = typeof(MethodHolderDerived<>).Project().GetMethod("Foo", bf, binder, types, null); + Assert.Equal(10070, m.GetMark()); + } } [Fact] diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/TypeInfoFromProjectN/TypeInfo_GenericTypeParametersTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/TypeInfoFromProjectN/TypeInfo_GenericTypeParametersTests.cs index e495bcc8de3b..72aae63c0bf2 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/TypeInfoFromProjectN/TypeInfo_GenericTypeParametersTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/TypeInfoFromProjectN/TypeInfo_GenericTypeParametersTests.cs @@ -115,8 +115,6 @@ public static void TestGenericParameters15() VerifyGenericTypeParameters(typeof(Test_SIG21).Project(), new string[] { }, new string[] { }); } - - // Verify Generic Arguments [Fact] public static void TestGenericParameters16() @@ -155,7 +153,6 @@ public static void TestGenericParameters20() VerifyGenericTypeParameters(typeof(Test_C1).Project(), new string[] { }, null); } - // Verify Generic Arguments [Fact] public static void TestGenericParameters21() @@ -198,7 +195,6 @@ public static void TestGenericParameters26() VerifyGenericTypeParameters(typeof(Test_CIG1<>).Project(), new string[] { "T" }, new string[] { }); } - // Verify Generic Arguments [Fact] public static void TestGenericParameters27() @@ -263,13 +259,11 @@ private static void VerifyGenericTypeParameters(Type type, string[] expectedGTP, Assert.Equal(expectedGTP.Length, retGenericTypeParameters.Length); - for (int i = 0; i < retGenericTypeParameters.Length; i++) { Assert.Equal(expectedGTP[i], retGenericTypeParameters[i].Name); } - Type baseType = typeInfo.BaseType; if (baseType == null) return; @@ -282,20 +276,17 @@ private static void VerifyGenericTypeParameters(Type type, string[] expectedGTP, baseType = interfaces[0]; } - TypeInfo typeInfoBase = baseType.GetTypeInfo(); retGenericTypeParameters = typeInfoBase.GenericTypeParameters; Assert.Equal(expectedBaseGTP.Length, retGenericTypeParameters.Length); - for (int i = 0; i < retGenericTypeParameters.Length; i++) { Assert.Equal(expectedBaseGTP[i], retGenericTypeParameters[i].Name); } } - private static Type[] getInterfaces(TypeInfo ti) { List list = new List(); From ac492c9523092d4d8c1c97979c986524bf42ee70 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 14 Aug 2020 13:39:41 -0500 Subject: [PATCH 504/755] Improve JSON serialization perf of longer strings on mono (#39733) --- .../Web/DefaultJavaScriptEncoderBasicLatin.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/DefaultJavaScriptEncoderBasicLatin.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/DefaultJavaScriptEncoderBasicLatin.cs index 9feec9aff57d..82e38db2bce4 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/DefaultJavaScriptEncoderBasicLatin.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/DefaultJavaScriptEncoderBasicLatin.cs @@ -103,11 +103,19 @@ public override unsafe int FindFirstCharacterToEncode(char* text, int textLength #endif Debug.Assert(textLength > 0 && ptr < end); + // For performance on the Mono interpreter, avoid referencing the static table for every value. + ReadOnlySpan allowListLocal = AllowList; + do { Debug.Assert(text <= ptr && ptr < (text + textLength)); - if (NeedsEscaping(*(char*)ptr)) + char value = *(char*)ptr; + + // NeedsEscaping() is lifted below for perf; verify semantics remain consistent. + Debug.Assert((value > LastAsciiCharacter || allowListLocal[value] == 0) == NeedsEscaping(value)); + + if (value > LastAsciiCharacter || allowListLocal[value] == 0) { goto Return; } @@ -276,11 +284,17 @@ public override unsafe int FindFirstCharacterToEncodeUtf8(ReadOnlySpan utf #endif Debug.Assert(textLength > 0 && ptr < end); + // For performance on the Mono interpreter, avoid referencing the static table for every value. + ReadOnlySpan allowListLocal = AllowList; + do { Debug.Assert(pValue <= ptr && ptr < (pValue + utf8Text.Length)); - if (NeedsEscaping(*ptr)) + // NeedsEscaping() is lifted below for perf; verify semantics remain consistent. + Debug.Assert((allowListLocal[*ptr] == 0) == NeedsEscaping(*ptr)); + + if (allowListLocal[*ptr] == 0) { goto Return; } From 53e65e04ea5605eb268020e639c8e5eed42b9f20 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Fri, 14 Aug 2020 11:45:19 -0700 Subject: [PATCH 505/755] Fix resolve_component_dependencies in single-file bundles (#40780) `hostpolicy_resolve_component_dependencies` uses the same infrastructure in the host as when an application is started. Changes made to the host to support .NET 5 single-file modifies some of the code paths shared with the component dependency resolution and broke it. When doing component dependency resolution the host must not consider the bundle in any way - all lookups have to go directly against the file system. This change modifies the initialization path to obey this rule. --- src/installer/corehost/cli/hostpolicy/args.cpp | 18 ++++++++++++++---- src/installer/corehost/cli/hostpolicy/args.h | 1 + .../corehost/cli/hostpolicy/hostpolicy.cpp | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/installer/corehost/cli/hostpolicy/args.cpp b/src/installer/corehost/cli/hostpolicy/args.cpp index cf7ffe57ec21..abe478509fd5 100644 --- a/src/installer/corehost/cli/hostpolicy/args.cpp +++ b/src/installer/corehost/cli/hostpolicy/args.cpp @@ -98,10 +98,12 @@ bool parse_arguments( init.additional_deps_serialized, init.deps_file, init.probe_paths, + /* init_from_file_system */ false, args); } bool set_root_from_app(const pal::string_t& managed_application_path, + bool file_system_lookup_only, arguments_t& args) { args.managed_application = managed_application_path; @@ -113,23 +115,29 @@ bool set_root_from_app(const pal::string_t& managed_application_path, return true; } - if (bundle::info_t::is_single_file_bundle()) + if (!file_system_lookup_only && bundle::info_t::is_single_file_bundle()) { const bundle::runner_t* app = bundle::runner_t::app(); args.app_root = app->base_path(); // Check for the main app within the bundle. // locate() sets args.managed_application to the full path of the app extracted to disk. - pal::string_t managed_application_name = get_filename(managed_application_path); + pal::string_t managed_application_name = get_filename(managed_application_path); if (app->locate(managed_application_name, args.managed_application)) { return true; } trace::info(_X("Managed application [%s] not found in single-file bundle"), managed_application_name.c_str()); - + + // The locate call above will clear the string when it returns false so reinitialize to the specified + // path before continuing. + args.managed_application = managed_application_path; + // If the main assembly is not found in the bundle, continue checking on disk // for very unlikely case where the main app.dll was itself excluded from the app bundle. + // Note that unlike non-single-file we don't want to set the app_root to the location of the app.dll + // it needs to stay the location of the single-file bundle. return pal::realpath(&args.managed_application); } @@ -150,13 +158,15 @@ bool init_arguments( const pal::string_t& additional_deps_serialized, const pal::string_t& deps_file, const std::vector& probe_paths, + bool init_from_file_system, arguments_t& args) { args.host_mode = host_mode; args.host_path = host_info.host_path; args.additional_deps_serialized = additional_deps_serialized; - if (!set_root_from_app(managed_application_path, args)) + // Components are never loaded from the bundle, the managed_application_path always means a file system path for a component case. + if (!set_root_from_app(managed_application_path, /* file_system_lookup_only */ init_from_file_system, args)) { trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str()); return false; diff --git a/src/installer/corehost/cli/hostpolicy/args.h b/src/installer/corehost/cli/hostpolicy/args.h index 7c2cf5b41ece..b7cfa9153fcf 100644 --- a/src/installer/corehost/cli/hostpolicy/args.h +++ b/src/installer/corehost/cli/hostpolicy/args.h @@ -141,6 +141,7 @@ bool init_arguments( const pal::string_t& additional_deps_serialized, const pal::string_t& deps_file, const std::vector& probe_paths, + bool init_from_file_system, arguments_t& args); #endif // ARGS_H diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp index da22a680708c..dbe883eb8410 100644 --- a/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp +++ b/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp @@ -840,6 +840,7 @@ SHARED_API int HOSTPOLICY_CALLTYPE corehost_resolve_component_dependencies( /* additional_deps_serialized */ pal::string_t(), // Additional deps - don't use those from the app, they're already in the app /* deps_file */ pal::string_t(), // Avoid using any other deps file than the one next to the component g_init.probe_paths, + /* init_from_file_system */ true, args)) { return StatusCode::LibHostInvalidArgs; From 8fc4859e1037170f1b207a700d6dbda269c90550 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Fri, 14 Aug 2020 14:50:16 -0400 Subject: [PATCH 506/755] Handle potential null in ALC.ResolveSatelliteAssembly (#40817) This was found on wasm, where assemblies are primarily loaded from a bundle rather than on the filesystem itself and return "" for Assembly.Location. This bug should affect desktop too if you have System.Private.CoreLib in the root of the file system (for whatever reason). --- .../src/System/Runtime/Loader/AssemblyLoadContext.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index 748e90a1898f..3a14f9d0a9cf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -727,7 +727,9 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly) AssemblyLoadContext parentALC = GetLoadContext(parentAssembly)!; - string parentDirectory = Path.GetDirectoryName(parentAssembly.Location)!; + string? parentDirectory = Path.GetDirectoryName(parentAssembly.Location); + if (parentDirectory == null) + return null; string assemblyPath = Path.Combine(parentDirectory, assemblyName.CultureName!, $"{assemblyName.Name}.dll"); From 46a563a551420faf52a34cc81f4c3391650a7e52 Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Fri, 14 Aug 2020 19:53:59 +0100 Subject: [PATCH 507/755] Applied BinaryPrimitives throughout CoreLib (#37582) --- .../System.Private.CoreLib/src/System/Guid.cs | 18 +++---- .../src/System/IO/BinaryWriter.cs | 48 +++---------------- 2 files changed, 14 insertions(+), 52 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index dd5f5b8de6c0..465dad6a7006 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.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.Binary; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; @@ -54,9 +55,9 @@ public Guid(ReadOnlySpan b) // slower path for BigEndian: _k = b[15]; // hoist bounds checks - _a = b[3] << 24 | b[2] << 16 | b[1] << 8 | b[0]; - _b = (short)(b[5] << 8 | b[4]); - _c = (short)(b[7] << 8 | b[6]); + _a = BinaryPrimitives.ReadInt32LittleEndian(b); + _b = BinaryPrimitives.ReadInt16LittleEndian(b.Slice(4)); + _c = BinaryPrimitives.ReadInt16LittleEndian(b.Slice(8)); _d = b[8]; _e = b[9]; _f = b[10]; @@ -749,14 +750,9 @@ public bool TryWriteBytes(Span destination) return false; destination[15] = _k; // hoist bounds checks - destination[0] = (byte)(_a); - destination[1] = (byte)(_a >> 8); - destination[2] = (byte)(_a >> 16); - destination[3] = (byte)(_a >> 24); - destination[4] = (byte)(_b); - destination[5] = (byte)(_b >> 8); - destination[6] = (byte)(_c); - destination[7] = (byte)(_c >> 8); + BinaryPrimitives.WriteInt32LittleEndian(destination, _a); + BinaryPrimitives.WriteInt16LittleEndian(destination.Slice(4), _b); + BinaryPrimitives.WriteInt16LittleEndian(destination.Slice(8), _c); destination[8] = _d; destination[9] = _e; destination[10] = _f; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs index d4ce39297c0c..69476c2f6015 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Buffers; using System.Threading.Tasks; +using System.Buffers.Binary; namespace System.IO { @@ -142,28 +143,18 @@ public virtual long Seek(int offset, SeekOrigin origin) // Writes a boolean to this stream. A single byte is written to the stream // with the value 0 representing false or the value 1 representing true. // - public virtual void Write(bool value) - { - _buffer[0] = (byte)(value ? 1 : 0); - OutStream.Write(_buffer, 0, 1); - } + public virtual void Write(bool value) => OutStream.WriteByte((byte)(value ? 1 : 0)); // Writes a byte to this stream. The current position of the stream is // advanced by one. // - public virtual void Write(byte value) - { - OutStream.WriteByte(value); - } + public virtual void Write(byte value) => OutStream.WriteByte(value); // Writes a signed byte to this stream. The current position of the stream // is advanced by one. // [CLSCompliant(false)] - public virtual void Write(sbyte value) - { - OutStream.WriteByte((byte)value); - } + public virtual void Write(sbyte value) => OutStream.WriteByte((byte)value); // Writes a byte array to this stream. // @@ -187,7 +178,6 @@ public virtual void Write(byte[] buffer, int index, int count) OutStream.Write(buffer, index, count); } - // Writes a character to this stream. The current position of the stream is // advanced by two. // Note this method cannot handle surrogates properly in UTF-8. @@ -231,21 +221,12 @@ public virtual void Write(char[] chars, int index, int count) OutStream.Write(bytes, 0, bytes.Length); } - // Writes a double to this stream. The current position of the stream is // advanced by eight. // public virtual unsafe void Write(double value) { - ulong TmpValue = *(ulong*)&value; - _buffer[0] = (byte)TmpValue; - _buffer[1] = (byte)(TmpValue >> 8); - _buffer[2] = (byte)(TmpValue >> 16); - _buffer[3] = (byte)(TmpValue >> 24); - _buffer[4] = (byte)(TmpValue >> 32); - _buffer[5] = (byte)(TmpValue >> 40); - _buffer[6] = (byte)(TmpValue >> 48); - _buffer[7] = (byte)(TmpValue >> 56); + BinaryPrimitives.WriteDoubleLittleEndian(_buffer, value); OutStream.Write(_buffer, 0, 8); } @@ -306,14 +287,7 @@ public virtual void Write(uint value) // public virtual void Write(long value) { - _buffer[0] = (byte)value; - _buffer[1] = (byte)(value >> 8); - _buffer[2] = (byte)(value >> 16); - _buffer[3] = (byte)(value >> 24); - _buffer[4] = (byte)(value >> 32); - _buffer[5] = (byte)(value >> 40); - _buffer[6] = (byte)(value >> 48); - _buffer[7] = (byte)(value >> 56); + BinaryPrimitives.WriteInt64LittleEndian(_buffer, value); OutStream.Write(_buffer, 0, 8); } @@ -323,14 +297,7 @@ public virtual void Write(long value) [CLSCompliant(false)] public virtual void Write(ulong value) { - _buffer[0] = (byte)value; - _buffer[1] = (byte)(value >> 8); - _buffer[2] = (byte)(value >> 16); - _buffer[3] = (byte)(value >> 24); - _buffer[4] = (byte)(value >> 32); - _buffer[5] = (byte)(value >> 40); - _buffer[6] = (byte)(value >> 48); - _buffer[7] = (byte)(value >> 56); + BinaryPrimitives.WriteUInt64LittleEndian(_buffer, value); OutStream.Write(_buffer, 0, 8); } @@ -347,7 +314,6 @@ public virtual unsafe void Write(float value) OutStream.Write(_buffer, 0, 4); } - // Writes a length-prefixed string to this stream in the BinaryWriter's // current Encoding. This method first writes the length of the string as // an encoded unsigned integer with variable length, and then writes that many characters From 056f728bc26d3348e720e85d265dd07f2b5243aa Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Fri, 14 Aug 2020 21:13:41 +0200 Subject: [PATCH 508/755] Flaky multiple HTTP/2 connection tests read full request body (#40844) There are 2 flaky HTTP/2 tests verifying multiple connections feature which are randomly failing on CI, but not locally. - Http2_MultipleConnectionsEnabled_ConnectionLimitNotReached_ConcurrentRequestsSuccessfullyHandled - Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ConnectionRemovedAndNewCreated It seems the failure is caused by not reading the request body. In current implementation, `Http2LoopbackServer` read only HEADERS frame via `ReadRequestHeaderAsync` and then immediately sends response. However, the client firstly completely sends headers and body and only then starting reading a response. Thus, it seems to get blocked sometimes if the server didn't read the full body. This PR fixes this by calling `ReadAndParseRequestHeaderAsync` instead of `ReadRequestHeaderAsync`. Fixes #40436 Fixes #40115 --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index c2ab2dfb6372..fa0746865eb3 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -2303,23 +2303,24 @@ private static async Task GetConnection(Http2LoopbackSe private async Task<(int Count, int LastStreamId)> HandleAllPendingRequests(Http2LoopbackConnection connection, int totalRequestCount) { - int streamId = -1; + int lastStreamId = -1; for (int i = 0; i < totalRequestCount; i++) { try { // Exact number of requests sent over the given connection is unknown, // so we keep reading headers and sending response while there are available requests. - streamId = await connection.ReadRequestHeaderAsync().ConfigureAwait(false); + (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false); await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); + lastStreamId = streamId; } catch (OperationCanceledException) { - return (i, streamId); + return (i, lastStreamId); } } - return (totalRequestCount, streamId); + return (totalRequestCount, lastStreamId); } private async Task> AcceptRequests(Http2LoopbackConnection connection, int maxRequests = int.MaxValue) @@ -2329,7 +2330,8 @@ private async Task> AcceptRequests(Http2LoopbackConnection connection, { try { - streamIds.Add(await connection.ReadRequestHeaderAsync().ConfigureAwait(false)); + (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false); + streamIds.Add(streamId); } catch (OperationCanceledException) { From 6cc7cffaff2e0413ee84d9a7736f9ae1aa9a3f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Fri, 14 Aug 2020 21:14:56 +0200 Subject: [PATCH 509/755] Fix timing issues with Http2_PingKeepAlive test. (#40788) --- .../HttpClientHandlerTest.Http2.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index 837e079fe125..f96409b9fc24 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -1503,7 +1503,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync( } // Let connection live until server finishes. - await serverFinished.Task.TimeoutAfter(pingTimeout * 2); + await Task.WhenAny(serverFinished.Task, Task.Delay(pingTimeout * 3)); }, async server => { @@ -1534,7 +1534,10 @@ await Http2LoopbackServer.CreateClientAndServerAsync( { ping = await connection.ReadPingAsync(pingTimeout); } - await Task.Delay(pongDelay); + if (pongDelay > TimeSpan.Zero) + { + await Task.Delay(pongDelay); + } await connection.SendPingAckAsync(ping.Data); } @@ -1555,6 +1558,16 @@ await Http2LoopbackServer.CreateClientAndServerAsync( } else { + // If the pings were recently coming, just give the connection time to clear up streams + // and still accept one stray ping. + if (expectStreamPing) + { + try + { + await connection.ReadPingAsync(pingTimeout); + } + catch (OperationCanceledException) { } // if it failed once, it will fail again + } await Assert.ThrowsAsync(() => connection.ReadPingAsync(pingTimeout)); } serverFinished.SetResult(); From 6ed1e41e590c41862b993f99c8f401c1935a523a Mon Sep 17 00:00:00 2001 From: Carlos Sanchez <1175054+carlossanlop@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:04:28 -0700 Subject: [PATCH 510/755] Ensure FileStatus and FileSystemEntry Hidden and ReadOnly attributes are retrieved the same way (#40641) * Ensure FileStatus and FileSystemEntry IsHidden attribute is retrieved the same way * Add missing check in public property FileSystemEntry.IsHidden. Address PR suggestions. * Add tests for Hidden and ReadOnly attribute check for each platform. Split existing Skip attribute test into different platforms. * Use _initialAttributes instead of Attributes for IsHidden. Add comment on top. Co-authored-by: carlossanlop --- .../IO/Enumeration/FileSystemEntry.Unix.cs | 38 +++++------ .../src/System/IO/FileStatus.Unix.cs | 64 +++++++++++++------ .../tests/Enumeration/AttributeTests.cs | 60 +++++++++++++++-- .../tests/Enumeration/SkipAttributeTests.cs | 35 +++++++--- 4 files changed, 144 insertions(+), 53 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs index 78390ccdec28..2880aaa5df8e 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs @@ -48,36 +48,33 @@ internal static FileAttributes Initialize( // directory. else if ((directoryEntry.InodeType == Interop.Sys.NodeType.DT_LNK || directoryEntry.InodeType == Interop.Sys.NodeType.DT_UNKNOWN) - && Interop.Sys.Stat(entry.FullPath, out Interop.Sys.FileStatus targetStatus) >= 0) + && Interop.Sys.Stat(entry.FullPath, out Interop.Sys.FileStatus statInfo) >= 0) { // Symlink or unknown: Stat to it to see if we can resolve it to a directory. - isDirectory = (targetStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR; + isDirectory = FileStatus.IsDirectory(statInfo); } - // Same idea as the directory check, just repeated for (and tweaked due to the - // nature of) symlinks. + + // Same idea as the directory check, just repeated for (and tweaked due to the nature of) symlinks. + int resultLStat = Interop.Sys.LStat(entry.FullPath, out Interop.Sys.FileStatus lstatInfo); + + bool isReadOnly = resultLStat >= 0 && FileStatus.IsReadOnly(lstatInfo); + if (directoryEntry.InodeType == Interop.Sys.NodeType.DT_LNK) { isSymlink = true; } - else if ((directoryEntry.InodeType == Interop.Sys.NodeType.DT_UNKNOWN) - && (Interop.Sys.LStat(entry.FullPath, out Interop.Sys.FileStatus linkTargetStatus) >= 0)) + else if (resultLStat >= 0 && directoryEntry.InodeType == Interop.Sys.NodeType.DT_UNKNOWN) { - isSymlink = (linkTargetStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFLNK; + isSymlink = FileStatus.IsSymLink(lstatInfo); } + // If the filename starts with a period or has UF_HIDDEN flag set, it's hidden. + bool isHidden = directoryEntry.Name[0] == '.' || (resultLStat >= 0 && FileStatus.IsHidden(lstatInfo)); + entry._status = default; FileStatus.Initialize(ref entry._status, isDirectory); - FileAttributes attributes = default; - if (isSymlink) - attributes |= FileAttributes.ReparsePoint; - if (isDirectory) - attributes |= FileAttributes.Directory; - if (directoryEntry.Name[0] == '.') - attributes |= FileAttributes.Hidden; - - if (attributes == default) - attributes = FileAttributes.Normal; + FileAttributes attributes = FileStatus.GetAttributes(isReadOnly, isSymlink, isDirectory, isHidden); entry._initialAttributes = attributes; return attributes; @@ -143,7 +140,12 @@ public FileAttributes Attributes public DateTimeOffset LastAccessTimeUtc => _status.GetLastAccessTime(FullPath, continueOnError: true); public DateTimeOffset LastWriteTimeUtc => _status.GetLastWriteTime(FullPath, continueOnError: true); public bool IsDirectory => _status.InitiallyDirectory; - public bool IsHidden => _directoryEntry.Name[0] == '.'; + /// + /// Returns if the file is hidden; otherwise. + /// In Linux and OSX, a file can be marked hidden if the filename is prepended with a dot. + /// In Windows and OSX, a file can be hidden if the special hidden attribute is set. For example, via the enum flag. + /// + public bool IsHidden => _directoryEntry.Name[0] == '.' || (_initialAttributes & FileAttributes.Hidden) != 0; public FileSystemInfo ToFileSystemInfo() { diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs b/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs index e32d3a1c54df..3b638448ac3e 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/FileStatus.Unix.cs @@ -39,19 +39,23 @@ internal static void Initialize( internal bool IsReadOnly(ReadOnlySpan path, bool continueOnError = false) { EnsureStatInitialized(path, continueOnError); + return IsReadOnly(_fileStatus); + } + + internal static bool IsReadOnly(Interop.Sys.FileStatus fileStatus) + { #if TARGET_BROWSER const Interop.Sys.Permissions readBit = Interop.Sys.Permissions.S_IRUSR; const Interop.Sys.Permissions writeBit = Interop.Sys.Permissions.S_IWUSR; #else Interop.Sys.Permissions readBit, writeBit; - - if (_fileStatus.Uid == Interop.Sys.GetEUid()) + if (fileStatus.Uid == Interop.Sys.GetEUid()) { // User effectively owns the file readBit = Interop.Sys.Permissions.S_IRUSR; writeBit = Interop.Sys.Permissions.S_IWUSR; } - else if (_fileStatus.Gid == Interop.Sys.GetEGid()) + else if (fileStatus.Gid == Interop.Sys.GetEGid()) { // User belongs to a group that effectively owns the file readBit = Interop.Sys.Permissions.S_IRGRP; @@ -65,37 +69,57 @@ internal bool IsReadOnly(ReadOnlySpan path, bool continueOnError = false) } #endif - return ((_fileStatus.Mode & (int)readBit) != 0 && // has read permission - (_fileStatus.Mode & (int)writeBit) == 0); // but not write permission + return (fileStatus.Mode & (int)readBit) != 0 && // has read permission + (fileStatus.Mode & (int)writeBit) == 0; // but not write permission } - public FileAttributes GetAttributes(ReadOnlySpan path, ReadOnlySpan fileName) + internal static bool IsDirectory(Interop.Sys.FileStatus fileStatus) { - // IMPORTANT: Attribute logic must match the logic in FileSystemEntry + return (fileStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR; + } - EnsureStatInitialized(path); + internal static bool IsHidden(Interop.Sys.FileStatus fileStatus) + { + return (fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == (uint)Interop.Sys.UserFlags.UF_HIDDEN; + } - if (!_exists) - return (FileAttributes)(-1); + internal static bool IsSymLink(Interop.Sys.FileStatus fileStatus) + { + return (fileStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFLNK; + } + internal static FileAttributes GetAttributes(bool isReadOnly, bool isSymlink, bool isDirectory, bool isHidden) + { FileAttributes attributes = default; - if (IsReadOnly(path)) + if (isReadOnly) attributes |= FileAttributes.ReadOnly; - - if ((_fileStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFLNK) + if (isSymlink) attributes |= FileAttributes.ReparsePoint; - - if (_isDirectory) + if (isDirectory) attributes |= FileAttributes.Directory; - - // If the filename starts with a period or has UF_HIDDEN flag set, it's hidden. - if (fileName.Length > 0 && (fileName[0] == '.' || (_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == (uint)Interop.Sys.UserFlags.UF_HIDDEN)) + if (isHidden) attributes |= FileAttributes.Hidden; return attributes != default ? attributes : FileAttributes.Normal; } + public FileAttributes GetAttributes(ReadOnlySpan path, ReadOnlySpan fileName) + { + // IMPORTANT: Attribute logic must match the logic in FileSystemEntry + + EnsureStatInitialized(path); + + if (!_exists) + return (FileAttributes)(-1); + + return GetAttributes( + IsReadOnly(path), + IsSymLink(_fileStatus), + _isDirectory, + (fileName.Length > 0 && fileName[0] == '.') || IsHidden(_fileStatus)); + } + public void SetAttributes(string path, FileAttributes attributes) { // Validate that only flags from the attribute are being provided. This is an @@ -300,13 +324,13 @@ public void Refresh(ReadOnlySpan path) _exists = true; // IMPORTANT: Is directory logic must match the logic in FileSystemEntry - _isDirectory = (_fileStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR; + _isDirectory = IsDirectory(_fileStatus); // If we're a symlink, attempt to check the target to see if it is a directory if ((_fileStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFLNK && Interop.Sys.Stat(path, out Interop.Sys.FileStatus targetStatus) >= 0) { - _isDirectory = (targetStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR; + _isDirectory = IsDirectory(targetStatus); } _fileStatusInitialized = 0; diff --git a/src/libraries/System.IO.FileSystem/tests/Enumeration/AttributeTests.cs b/src/libraries/System.IO.FileSystem/tests/Enumeration/AttributeTests.cs index 3736c0669cf7..3974b9565907 100644 --- a/src/libraries/System.IO.FileSystem/tests/Enumeration/AttributeTests.cs +++ b/src/libraries/System.IO.FileSystem/tests/Enumeration/AttributeTests.cs @@ -113,18 +113,42 @@ public void DirectoryAttributesAreExpected() } [Fact] - public void IsHiddenAttribute() + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] + public void IsHiddenAttribute_Windows_OSX() { + // Put a period in front to make it hidden on Unix + IsHiddenAttributeInternal(useDotPrefix: false, useHiddenFlag: true); + + } + + + [Fact] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public void IsHiddenAttribute_Unix() + { + // Windows and MacOS hide a file by setting the hidden attribute + IsHiddenAttributeInternal(useDotPrefix: true, useHiddenFlag: false); + } + + private void IsHiddenAttributeInternal(bool useDotPrefix, bool useHiddenFlag) + { + string prefix = useDotPrefix ? "." : ""; + DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath()); - FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); - // Put a period in front to make it hidden on Unix - FileInfo fileTwo = new FileInfo(Path.Combine(testDirectory.FullName, "." + GetTestFileName())); + FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); + FileInfo fileTwo = new FileInfo(Path.Combine(testDirectory.FullName, prefix + GetTestFileName())); fileOne.Create().Dispose(); fileTwo.Create().Dispose(); - if (PlatformDetection.IsWindows) - fileTwo.Attributes = fileTwo.Attributes | FileAttributes.Hidden; + + if (useHiddenFlag) + { + fileTwo.Attributes |= FileAttributes.Hidden; + } + + FileInfo fileCheck = new FileInfo(fileTwo.FullName); + Assert.Equal(fileTwo.Attributes, fileCheck.Attributes); IEnumerable enumerable = new FileSystemEnumerable( testDirectory.FullName, @@ -136,5 +160,29 @@ public void IsHiddenAttribute() Assert.Equal(new string[] { fileTwo.FullName }, enumerable); } + + [Fact] + public void IsReadOnlyAttribute() + { + DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath()); + + FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); + FileInfo fileTwo = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); + + fileOne.Create().Dispose(); + fileTwo.Create().Dispose(); + + fileTwo.Attributes |= FileAttributes.ReadOnly; + + IEnumerable enumerable = new FileSystemEnumerable( + testDirectory.FullName, + (ref FileSystemEntry entry) => entry.ToFullPath(), + new EnumerationOptions() { AttributesToSkip = 0 }) + { + ShouldIncludePredicate = (ref FileSystemEntry entry) => (entry.Attributes & FileAttributes.ReadOnly) != 0 + }; + + Assert.Equal(new string[] { fileTwo.FullName }, enumerable); + } } } diff --git a/src/libraries/System.IO.FileSystem/tests/Enumeration/SkipAttributeTests.cs b/src/libraries/System.IO.FileSystem/tests/Enumeration/SkipAttributeTests.cs index 3a22c61b6f77..cb79200bc178 100644 --- a/src/libraries/System.IO.FileSystem/tests/Enumeration/SkipAttributeTests.cs +++ b/src/libraries/System.IO.FileSystem/tests/Enumeration/SkipAttributeTests.cs @@ -21,25 +21,42 @@ protected virtual string[] GetPaths(string directory, EnumerationOptions options } [Fact] - public void SkippingHiddenFiles() + [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] + public void SkippingHiddenFiles_Windows_OSX() + { + SkippingHiddenFilesInternal(useDotPrefix: false, useHiddenFlag: true); + } + + [Fact] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public void SkippingHiddenFiles_Unix() + { + SkippingHiddenFilesInternal(useDotPrefix: true, useHiddenFlag: false); + } + + private void SkippingHiddenFilesInternal(bool useDotPrefix, bool useHiddenFlag) { DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath()); DirectoryInfo testSubdirectory = Directory.CreateDirectory(Path.Combine(testDirectory.FullName, GetTestFileName())); - FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); - // Put a period in front to make it hidden on Unix - FileInfo fileTwo = new FileInfo(Path.Combine(testDirectory.FullName, "." + GetTestFileName())); + FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName())); FileInfo fileThree = new FileInfo(Path.Combine(testSubdirectory.FullName, GetTestFileName())); - FileInfo fileFour = new FileInfo(Path.Combine(testSubdirectory.FullName, "." + GetTestFileName())); + + // Put a period in front of files two and four to make them hidden on Unix + string prefix = useDotPrefix ? "." : ""; + FileInfo fileTwo = new FileInfo(Path.Combine(testDirectory.FullName, prefix + GetTestFileName())); + FileInfo fileFour = new FileInfo(Path.Combine(testSubdirectory.FullName, prefix + GetTestFileName())); fileOne.Create().Dispose(); fileTwo.Create().Dispose(); - if (PlatformDetection.IsWindows) - fileTwo.Attributes = fileTwo.Attributes | FileAttributes.Hidden; fileThree.Create().Dispose(); fileFour.Create().Dispose(); - if (PlatformDetection.IsWindows) - fileFour.Attributes = fileTwo.Attributes | FileAttributes.Hidden; + + if (useHiddenFlag) + { + fileTwo.Attributes |= FileAttributes.Hidden; + fileFour.Attributes |= FileAttributes.Hidden; + } // Default EnumerationOptions is to skip hidden string[] paths = GetPaths(testDirectory.FullName, new EnumerationOptions()); From a62b38d052673dbc1eb02fa68d916e1bd406d5ae Mon Sep 17 00:00:00 2001 From: Sergey Aseev Date: Sat, 15 Aug 2020 01:07:24 +0300 Subject: [PATCH 511/755] Move content type verification to a later stage (#40594) * Move content type verification to a later stage Fix #38713 * Rename ValidateContent to ValidateContentType Fix #38713 * Get rid of content type check * Add newline at end of the file * Rename TestValidMediaTypes to TestVariousMediaTypes --- .../src/Resources/Strings.resx | 3 - .../Http/Json/HttpContentJsonExtensions.cs | 67 ++++--------------- .../HttpContentJsonExtensionsTests.cs | 54 +-------------- 3 files changed, 15 insertions(+), 109 deletions(-) diff --git a/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx b/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx index 332b5e17c461..7db4d7ddf0b0 100644 --- a/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx @@ -126,9 +126,6 @@ The character set provided in ContentType is not supported. - - The provided ContentType '{0}' is not supported; the supported types are 'application/json' and the structured syntax suffix 'application/+json'. - The specified type {0} must derive from the specific value's type {1}. diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs index e73c6fb49d73..5457a1b65a7b 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.IO; using System.Text; using System.Text.Json; @@ -14,18 +13,24 @@ public static partial class HttpContentJsonExtensions { public static Task ReadFromJsonAsync(this HttpContent content, Type type, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { - ValidateContent(content); - Debug.Assert(content.Headers.ContentType != null); - Encoding? sourceEncoding = JsonContent.GetEncoding(content.Headers.ContentType.CharSet); + if (content == null) + { + throw new ArgumentNullException(nameof(content)); + } + + Encoding? sourceEncoding = JsonContent.GetEncoding(content.Headers.ContentType?.CharSet); return ReadFromJsonAsyncCore(content, type, sourceEncoding, options, cancellationToken); } public static Task ReadFromJsonAsync(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { - ValidateContent(content); - Debug.Assert(content.Headers.ContentType != null); - Encoding? sourceEncoding = JsonContent.GetEncoding(content.Headers.ContentType.CharSet); + if (content == null) + { + throw new ArgumentNullException(nameof(content)); + } + + Encoding? sourceEncoding = JsonContent.GetEncoding(content.Headers.ContentType?.CharSet); return ReadFromJsonAsyncCore(content, sourceEncoding, options, cancellationToken); } @@ -61,53 +66,5 @@ public static partial class HttpContentJsonExtensions return await JsonSerializer.DeserializeAsync(contentStream, options ?? JsonContent.s_defaultSerializerOptions, cancellationToken).ConfigureAwait(false); } } - - private static void ValidateContent(HttpContent content) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - - string? mediaType = content.Headers.ContentType?.MediaType; - - if (mediaType == null || - !mediaType.Equals(JsonContent.JsonMediaType, StringComparison.OrdinalIgnoreCase) && - !IsValidStructuredSyntaxJsonSuffix(mediaType.AsSpan())) - { - throw new NotSupportedException(SR.Format(SR.ContentTypeNotSupported, mediaType)); - } - } - - private static bool IsValidStructuredSyntaxJsonSuffix(ReadOnlySpan mediaType) - { - int index = 0; - int typeLength = mediaType.IndexOf('/'); - - ReadOnlySpan type = mediaType.Slice(index, typeLength); - if (typeLength < 0 || - type.CompareTo(JsonContent.JsonType.AsSpan(), StringComparison.OrdinalIgnoreCase) != 0) - { - return false; - } - - index += typeLength + 1; - int suffixStart = mediaType.Slice(index).IndexOf('+'); - - // Empty prefix subtype ("application/+json") not allowed. - if (suffixStart <= 0) - { - return false; - } - - index += suffixStart + 1; - ReadOnlySpan suffix = mediaType.Slice(index); - if (suffix.CompareTo(JsonContent.JsonSubtype.AsSpan(), StringComparison.OrdinalIgnoreCase) != 0) - { - return false; - } - - return true; - } } } diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs index 99d5f1ba32ce..4afeed9305c9 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpContentJsonExtensionsTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Net.Test.Common; using System.Text; using System.Text.Json; @@ -88,23 +86,6 @@ await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( server => server.HandleRequestAsync(headers: _headers)); } - [Fact] - public async Task TestReadFromJsonNoContentTypeAsync() - { - await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( - async (handler, uri) => - { - using (HttpClient client = new HttpClient(handler)) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - HttpResponseMessage response = await client.SendAsync(request); - - await Assert.ThrowsAsync(() => response.Content.ReadFromJsonAsync()); - } - }, - server => server.HandleRequestAsync(content: "{}")); - } - [Fact] public async Task TestGetFromJsonQuotedCharSetAsync() { @@ -201,7 +182,9 @@ await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( [InlineData("application/foo+json")] // Structured Syntax Json Suffix [InlineData("application/foo+Json")] [InlineData("appLiCaTiOn/a+JsOn")] - public async Task TestValidMediaTypes(string mediaType) + [InlineData("application/json-custom")] + [InlineData("asdf/ghjk")] + public async Task TestVariousMediaTypes(string mediaType) { List customHeaders = new List { @@ -222,36 +205,5 @@ await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( }, server => server.HandleRequestAsync(headers: customHeaders, content: Person.Create().Serialize())); } - - [Theory] - [InlineData("text/plain")] - [InlineData("/")] - [InlineData("application/")] - [InlineData("application/+")] - [InlineData("application/+json")] // empty subtype before suffix is invalid. - [InlineData("application/problem+")] // no suffix after '+'. - [InlineData("application/problem+foo+json")] // more than one '+' not allowed. - public async Task TestInvalidMediaTypeAsync(string mediaType) - { - List customHeaders = new List - { - new HttpHeaderData("Content-Type", $"{mediaType}; charset=\"utf-8\"") - }; - - await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( - async (handler, uri) => - { - using (HttpClient client = new HttpClient(handler)) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - HttpResponseMessage response = await client.SendAsync(request); - - Exception ex = await Assert.ThrowsAsync(() => response.Content.ReadFromJsonAsync()); - Assert.Contains("application/json", ex.Message); - Assert.Contains("application/+json", ex.Message); - } - }, - server => server.HandleRequestAsync(headers: customHeaders, content: Person.Create().Serialize())); - } } } From 12f46e41eb01ba2c6601bf8222931e8c1a3e17c3 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev <55398552+alnikola@users.noreply.github.com> Date: Sat, 15 Aug 2020 02:09:06 +0200 Subject: [PATCH 512/755] Set MaxConcurrentStreams = 100 on new Http2Connection until first SETTINGS frame (#40779) * Set MaxConcurrentStreams = 100 on new Http2Connection until first SETTINGS frame * Update src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs Co-authored-by: Chris Ross * - Setting infinite MaxConcurrentStreams fixed - Test verifying new connection request queueing added * More tests * - const case fixed - Outerloop attributed added * ExtraStreams case fixed Co-authored-by: Chris Ross --- .../Net/Http/Http2LoopbackConnection.cs | 33 +-- .../SocketsHttpHandler/Http2Connection.cs | 20 +- .../HttpClientHandlerTest.Http2.cs | 195 ++++++++++++++++++ 3 files changed, 232 insertions(+), 16 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 08eee1084e20..2dcbf4cb3e17 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -643,6 +643,27 @@ public override Task InitializeConnectionAsync() } public async Task ReadAndSendSettingsAsync(TimeSpan? ackTimeout, params SettingsEntry[] settingsEntries) + { + SettingsFrame clientSettingsFrame = await ReadSettingsAsync().ConfigureAwait(false); + await SendSettingsAsync(ackTimeout, settingsEntries).ConfigureAwait(false); + return clientSettingsFrame; + } + + public async Task SendSettingsAsync(TimeSpan? ackTimeout, SettingsEntry[] settingsEntries) + { + // Send the initial server settings frame. + SettingsFrame settingsFrame = new SettingsFrame(settingsEntries); + await WriteFrameAsync(settingsFrame).ConfigureAwait(false); + + // Send the client settings frame ACK. + Frame settingsAck = new Frame(0, FrameType.Settings, FrameFlags.Ack, 0); + await WriteFrameAsync(settingsAck).ConfigureAwait(false); + + // The client will send us a SETTINGS ACK eventually, but not necessarily right away. + await ExpectSettingsAckAsync((int?)ackTimeout?.TotalMilliseconds ?? 5000); + } + + public async Task ReadSettingsAsync() { // Receive the initial client settings frame. Frame receivedFrame = await ReadFrameAsync(_timeout).ConfigureAwait(false); @@ -657,18 +678,6 @@ public async Task ReadAndSendSettingsAsync(TimeSpan? ackTimeout, Assert.Equal(FrameType.WindowUpdate, receivedFrame.Type); Assert.Equal(FrameFlags.None, receivedFrame.Flags); Assert.Equal(0, receivedFrame.StreamId); - - // Send the initial server settings frame. - SettingsFrame settingsFrame = new SettingsFrame(settingsEntries); - await WriteFrameAsync(settingsFrame).ConfigureAwait(false); - - // Send the client settings frame ACK. - Frame settingsAck = new Frame(0, FrameType.Settings, FrameFlags.Ack, 0); - await WriteFrameAsync(settingsAck).ConfigureAwait(false); - - // The client will send us a SETTINGS ACK eventually, but not necessarily right away. - await ExpectSettingsAckAsync((int?)ackTimeout?.TotalMilliseconds ?? 5000); - return clientSettingsFrame; } 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 e77e2f5ea61b..8e71e19ab002 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 @@ -65,6 +65,9 @@ internal sealed partial class Http2Connection : HttpConnectionBase, IDisposable private const int MaxStreamId = int.MaxValue; + // Temporary workaround for request burst handling on connection start. + private const int InitialMaxConcurrentStreams = 100; + private static readonly byte[] s_http2ConnectionPreface = Encoding.ASCII.GetBytes("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"); #if DEBUG @@ -124,13 +127,14 @@ public Http2Connection(HttpConnectionPool pool, Connection connection) _httpStreams = new Dictionary(); _connectionWindow = new CreditManager(this, nameof(_connectionWindow), DefaultInitialWindowSize); - _concurrentStreams = new CreditManager(this, nameof(_concurrentStreams), int.MaxValue); + _concurrentStreams = new CreditManager(this, nameof(_concurrentStreams), InitialMaxConcurrentStreams); _writeChannel = Channel.CreateUnbounded(s_channelOptions); _nextStream = 1; _initialWindowSize = DefaultInitialWindowSize; - _maxConcurrentStreams = int.MaxValue; + + _maxConcurrentStreams = InitialMaxConcurrentStreams; _pendingWindowUpdate = 0; _idleSinceTickCount = Environment.TickCount64; @@ -288,7 +292,7 @@ private async Task ProcessIncomingFramesAsync() if (NetEventSource.Log.IsEnabled()) Trace($"Frame 0: {frameHeader}."); // Process the initial SETTINGS frame. This will send an ACK. - ProcessSettingsFrame(frameHeader); + ProcessSettingsFrame(frameHeader, initialFrame: true); } catch (IOException e) { @@ -558,7 +562,7 @@ private void ProcessDataFrame(FrameHeader frameHeader) _incomingBuffer.Discard(frameHeader.PayloadLength); } - private void ProcessSettingsFrame(FrameHeader frameHeader) + private void ProcessSettingsFrame(FrameHeader frameHeader, bool initialFrame = false) { Debug.Assert(frameHeader.Type == FrameType.Settings); @@ -592,6 +596,7 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) // Parse settings and process the ones we care about. ReadOnlySpan settings = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength); + bool maxConcurrentStreamsReceived = false; while (settings.Length > 0) { Debug.Assert((settings.Length % 6) == 0); @@ -605,6 +610,7 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) { case SettingId.MaxConcurrentStreams: ChangeMaxConcurrentStreams(settingValue); + maxConcurrentStreamsReceived = true; break; case SettingId.InitialWindowSize: @@ -632,6 +638,12 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) } } + if (initialFrame && !maxConcurrentStreamsReceived) + { + // Set to 'infinite' because MaxConcurrentStreams was not set on the initial SETTINGS frame. + ChangeMaxConcurrentStreams(int.MaxValue); + } + _incomingBuffer.Discard(frameHeader.PayloadLength); // Send acknowledgement diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index f96409b9fc24..cea66090d91d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -399,6 +399,176 @@ public async Task PostAsync_StreamRefused_RequestIsRetried() } } + [OuterLoop("Uses delays")] + [ConditionalFact(nameof(SupportsAlpn))] + public async Task GetAsync_SettingsFrameNotSentOnNewConnection_ClientApplies100StreamLimit() + { + const int DefaultMaxConcurrentStreams = 100; + TimeSpan timeout = TimeSpan.FromSeconds(3); + using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) + using (HttpClient client = CreateHttpClient()) + { + Task connectionTask = AcceptConnectionAndReadSettings(server, timeout); + + List> sendTasks = new List>(); + for (int i = 0; i < DefaultMaxConcurrentStreams; i++) + { + sendTasks.Add(client.GetAsync(server.Address)); + } + + Http2LoopbackConnection connection = await connectionTask.TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Client sets the default MaxConcurrentStreams to 100, so accept 100 requests. + List acceptedRequests = await AcceptRequests(connection, DefaultMaxConcurrentStreams).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + Assert.Equal(DefaultMaxConcurrentStreams, acceptedRequests.Count); + + // Extra request is queued on the client. + Task extraSendTask = client.GetAsync(server.Address); + await Assert.ThrowsAnyAsync(() => connection.ReadRequestHeaderAsync()).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Send SETTINGS frame to increase the default stream limit by 1, unblocking the extra request. + await connection.SendSettingsAsync(timeout, new[] { new SettingsEntry() { SettingId = SettingId.MaxConcurrentStreams, Value = DefaultMaxConcurrentStreams + 1 } }).ConfigureAwait(false); + + (int extraStreamId, _) = await connection.ReadAndParseRequestHeaderAsync().TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Respond to all the requests. + acceptedRequests.Add(extraStreamId); + foreach (int streamId in acceptedRequests) + { + await connection.SendDefaultResponseAsync(streamId).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + } + + sendTasks.Add(extraSendTask); + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + foreach (Task sendTask in sendTasks) + { + using HttpResponseMessage response = sendTask.Result; + Assert.True(response.IsSuccessStatusCode); + } + } + } + + [OuterLoop("Uses delays")] + [ConditionalFact(nameof(SupportsAlpn))] + public async Task GetAsync_ServerDelaysSendingSettingsThenSetsLowerMaxConcurrentStreamsLimitThenIncreaseIt_ClientAppliesEachLimitChangeProperly() + { + const int DefaultMaxConcurrentStreams = 100; + const int ExtraStreams = 20; + TimeSpan timeout = TimeSpan.FromSeconds(3); + using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) + using (HttpClient client = CreateHttpClient()) + { + Task connectionTask = AcceptConnectionAndReadSettings(server, timeout); + + List> sendTasks = new List>(); + for (int i = 0; i < DefaultMaxConcurrentStreams + ExtraStreams; i++) + { + sendTasks.Add(client.GetAsync(server.Address)); + } + + Http2LoopbackConnection connection = await connectionTask.TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Client sets the default MaxConcurrentStreams to 100, so accept 100 requests. + List acceptedRequests = await AcceptRequests(connection, DefaultMaxConcurrentStreams + ExtraStreams).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.Equal(DefaultMaxConcurrentStreams, acceptedRequests.Count); + + // Send SETTINGS frame with MaxConcurrentStreams = 102 + await connection.SendSettingsAsync(timeout, new[] { new SettingsEntry() { SettingId = SettingId.MaxConcurrentStreams, Value = DefaultMaxConcurrentStreams + 2 } }).ConfigureAwait(false); + + // Increased MaxConcurrentStreams ublocks only 2 requests. + List acceptedExtraRequests = await AcceptRequests(connection, ExtraStreams).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.Equal(2, acceptedExtraRequests.Count); + + acceptedRequests.AddRange(acceptedExtraRequests); + + // Send SETTINGS frame with MaxConcurrentStreams = DefaultMaxConcurrentStreams + ExtraStreams + await connection.ExpectSettingsAckAsync().ConfigureAwait(false); + Frame frame = new SettingsFrame(new SettingsEntry() { SettingId = SettingId.MaxConcurrentStreams, Value = DefaultMaxConcurrentStreams + ExtraStreams }); + await connection.WriteFrameAsync(frame).ConfigureAwait(false); + + // Increased MaxConcurrentStreams ublocks all remaining requests. + acceptedExtraRequests = await AcceptRequests(connection, ExtraStreams - 2).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.Equal(ExtraStreams - 2, acceptedExtraRequests.Count); + + acceptedRequests.AddRange(acceptedExtraRequests); + + // Respond to all the requests. + foreach (int streamId in acceptedRequests) + { + await connection.SendDefaultResponseAsync(streamId).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + } + + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + foreach (Task sendTask in sendTasks) + { + using HttpResponseMessage response = sendTask.Result; + Assert.True(response.IsSuccessStatusCode); + } + } + } + + [OuterLoop("Uses delays")] + [ConditionalFact(nameof(SupportsAlpn))] + public async Task GetAsync_ServerSendSettingsWithoutMaxConcurrentStreams_ClientAppliesInfiniteLimit() + { + const int DefaultMaxConcurrentStreams = 100; + TimeSpan timeout = TimeSpan.FromSeconds(3); + using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) + using (HttpClient client = CreateHttpClient()) + { + Task connectionTask = AcceptConnectionAndReadSettings(server, timeout); + + List> sendTasks = new List>(); + for (int i = 0; i < DefaultMaxConcurrentStreams; i++) + { + sendTasks.Add(client.GetAsync(server.Address)); + } + + Http2LoopbackConnection connection = await connectionTask.TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Client sets the default MaxConcurrentStreams to 100, so accept 100 requests. + List acceptedRequests = await AcceptRequests(connection, DefaultMaxConcurrentStreams).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.Equal(DefaultMaxConcurrentStreams, acceptedRequests.Count); + + // Extra request is queued on the client. + Task extraSendTask = client.GetAsync(server.Address); + await Assert.ThrowsAnyAsync(() => connection.ReadRequestHeaderAsync()).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + // Send SETTINGS frame without MaxConcurrentSettings value. + await connection.SendSettingsAsync(timeout, new SettingsEntry[0]).ConfigureAwait(false); + + // Send 100 more requests + sendTasks.Add(extraSendTask); + for (int i = 0; i < DefaultMaxConcurrentStreams; i++) + { + sendTasks.Add(client.GetAsync(server.Address)); + } + + // Client sets the MaxConcurrentStreams to 'infinite', so accept 100 + 1 extra requests. + List acceptedExtraRequests = await AcceptRequests(connection, DefaultMaxConcurrentStreams + 1).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + Assert.Equal(DefaultMaxConcurrentStreams + 1, acceptedExtraRequests.Count); + + // Respond to all the requests. + acceptedRequests.AddRange(acceptedExtraRequests); + foreach (int streamId in acceptedRequests) + { + await connection.SendDefaultResponseAsync(streamId).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + } + + sendTasks.Add(extraSendTask); + await Task.WhenAll(sendTasks).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds).ConfigureAwait(false); + + foreach (Task sendTask in sendTasks) + { + using HttpResponseMessage response = sendTask.Result; + Assert.True(response.IsSuccessStatusCode); + } + } + } + // This test is based on RFC 7540 section 6.1: // "If a DATA frame is received whose stream identifier field is 0x0, the recipient MUST // respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR." @@ -476,6 +646,31 @@ public async Task HeadersFrame_IdleStream_ConnectionError() } } + private async Task AcceptConnectionAndReadSettings(Http2LoopbackServer server, TimeSpan timeout) + { + Http2LoopbackConnection connection = await server.AcceptConnectionAsync(timeout).ConfigureAwait(false); + await connection.ReadSettingsAsync().ConfigureAwait(false); + return connection; + } + + private async Task> AcceptRequests(Http2LoopbackConnection connection, int maxRequests = int.MaxValue) + { + List streamIds = new List(); + for (int i = 0; i < maxRequests; i++) + { + try + { + streamIds.Add((await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false)).streamId); + } + catch (OperationCanceledException) + { + return streamIds; + } + } + + return streamIds; + } + private static Frame MakeSimpleHeadersFrame(int streamId, bool endHeaders = false, bool endStream = false) => new HeadersFrame(new byte[] { 0x88 }, // :status: 200 (endHeaders ? FrameFlags.EndHeaders : FrameFlags.None) | (endStream ? FrameFlags.EndStream : FrameFlags.None), From 732ea740a112eb52e82bc190f1a25451850c7488 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 14 Aug 2020 17:13:44 -0700 Subject: [PATCH 513/755] Update analyzers and various fixes to be able to build with latest RC1 SDK (#40796) * Disable net analyzers from the SDK and use them from package reference instead * Fix build with new SDK and bump net analyzer version * PR Feedback --- Directory.Build.props | 3 +++ Directory.Build.targets | 2 ++ eng/Analyzers.props | 2 +- eng/referenceAssemblies.props | 3 +++ eng/targetingpacks.targets | 5 +++++ 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index ff2883becc68..2d93ed80c96c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -84,6 +84,9 @@ false + + + false diff --git a/Directory.Build.targets b/Directory.Build.targets index f16e04d9b4e2..e4c7e1d21a57 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -6,6 +6,8 @@ tell Microsoft.Common.targets not to import Directory.Build.targets again --> false + + false diff --git a/eng/Analyzers.props b/eng/Analyzers.props index 34eb83dff697..ff442658c331 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -6,7 +6,7 @@ - + diff --git a/eng/referenceAssemblies.props b/eng/referenceAssemblies.props index 94508fa244ad..4aabb96b8999 100644 --- a/eng/referenceAssemblies.props +++ b/eng/referenceAssemblies.props @@ -4,6 +4,9 @@ !$(BuildTargetFramework.StartsWith('net4'))"> $(AdditionalBuildTargetFrameworks);netstandard2.0 $(AdditionalBuildTargetFrameworks);netstandard2.1 + + + false diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets index e39ce8fdada6..404f9552d073 100644 --- a/eng/targetingpacks.targets +++ b/eng/targetingpacks.targets @@ -6,6 +6,11 @@ false + + <_ShortFrameworkIdentifier>$(TargetFramework.TrimEnd('.0123456789')) + <_ShortFrameworkVersion>$(TargetFramework.Substring($(_ShortFrameworkIdentifier.Length))) + + +#include +#endif +#if HAVE_GETAUXVAL +#include +#endif +#if HAVE_SYS_SYSCTL_H || defined(__FreeBSD__) +#include +#endif + #include using namespace CorUnix; @@ -125,7 +136,7 @@ static DWORD g_initializeDLLFlags = PAL_INITIALIZE_DLL; static int Initialize(int argc, const char *const argv[], DWORD flags); static BOOL INIT_IncreaseDescriptorLimit(void); static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv); -static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_name); +static LPWSTR INIT_GetCurrentEXEPath(); static BOOL INIT_SharedFilesPath(void); #ifdef _DEBUG @@ -560,7 +571,7 @@ Initialize( } /* find out the application's full path */ - exe_path = INIT_ConvertEXEPath(argv[0]); + exe_path = INIT_GetCurrentEXEPath(); if (NULL == exe_path) { ERROR("Unable to find exe path\n"); @@ -1265,45 +1276,160 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv) return retval; } +#if defined(__linux__) +#define symlinkEntrypointExecutable "/proc/self/exe" +#elif !defined(__APPLE__) +#define symlinkEntrypointExecutable "/proc/curproc/exe" +#endif + +bool GetAbsolutePath(const char* path, PathCharString& absolutePath) +{ + bool result = false; + + char realPath[PATH_MAX]; + if (realpath(path, realPath) != nullptr && realPath[0] != '\0') + { + absolutePath.Set(realPath, strlen(realPath)); + // realpath should return canonicalized path without the trailing slash + _ASSERTE(absolutePath[absolutePath.GetCount() - 1] != '/'); + + result = true; + } + + return result; +} + +bool GetEntrypointExecutableAbsolutePath(PathCharString& entrypointExecutable) +{ + bool result = false; + + entrypointExecutable.Clear(); + + // Get path to the executable for the current process using + // platform specific means. +#if defined(__APPLE__) + + // On Mac, we ask the OS for the absolute path to the entrypoint executable + uint32_t lenActualPath = 0; + if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1) + { + // OSX has placed the actual path length in lenActualPath, + // so re-attempt the operation + PathCharString resizedPath; + char *pResizedPath = resizedPath.OpenStringBuffer(lenActualPath); + if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0) + { + resizedPath.CloseBuffer(lenActualPath - 1); + entrypointExecutable.Set(resizedPath); + result = true; + } + } +#elif defined (__FreeBSD__) + static const int name[] = + { + CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 + }; + char path[PATH_MAX]; + size_t len; + + len = sizeof(path); + if (sysctl(name, 4, path, &len, nullptr, 0) == 0) + { + entrypointExecutable.Set(path, len); + result = true; + } + else + { + // ENOMEM + result = false; + } +#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME) + static const int name[] = + { + CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME, + }; + char path[MAXPATHLEN]; + size_t len; + + len = sizeof(path); + if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) + { + entrypointExecutable.Set(path, len); + result = true; + } + else + { + result = false; + } +#elif defined(__sun) + const char *path; + if ((path = getexecname()) == NULL) + { + result = false; + } + else if (*path != '/') + { + char *cwd; + if ((cwd = getcwd(NULL, PATH_MAX)) == NULL) + { + result = false; + } + else + { + entrypointExecutable.Set(cwd, strlen(cwd)); + entrypointExecutable.Append('/'); + entrypointExecutable.Append(path); + + result = true; + free(cwd); + } + } + else + { + entrypointExecutable.Set(path, strlen(path)); + result = true; + } +#else + +#if HAVE_GETAUXVAL && defined(AT_EXECFN) + const char *execfn = (const char *)getauxval(AT_EXECFN); + + if (execfn) + { + entrypointExecutable.Set(execfn, strlen(execfn)); + result = true; + } + else +#endif + // On other OSs, return the symlink that will be resolved by GetAbsolutePath + // to fetch the entrypoint EXE absolute path, inclusive of filename. + result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable); +#endif + + return result; +} + /*++ Function: - INIT_ConvertEXEPath + INIT_GetCurrentEXEPath Abstract: - Check whether the executable path is valid, and convert its type (LPCSTR -> LPWSTR) - -Parameters: - LPCSTR exe_name : full path of the current executable + Get the current exe path Return: pointer to buffer containing the full path. This buffer must be released by the caller using free() -Notes : - this function assumes that "exe_name" is in Unix style (no \) --*/ -static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_path) +static LPWSTR INIT_GetCurrentEXEPath() { PathCharString real_path; LPWSTR return_value; INT return_size; - struct stat theStats; - - if (!strchr(exe_path, '/')) - { - ERROR( "The exe path is not fully specified\n" ); - return NULL; - } - - if (-1 == stat(exe_path, &theStats)) - { - ERROR( "The file does not exist\n" ); - return NULL; - } - if (!CorUnix::RealPathHelper(exe_path, real_path)) + if (!GetEntrypointExecutableAbsolutePath(real_path)) { - ERROR("realpath() failed!\n"); + ERROR( "Cannot get current exe path\n" ); return NULL; } From c67684bead32185f086c3d376c6914dfbd0d4b6a Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Fri, 14 Aug 2020 17:27:34 -0700 Subject: [PATCH 515/755] Fix a deadlock in EventSource and CounterGroup (#40259) * Fix a deadlock in CounterGroup and EventSource * add more comments * Add some more comments * PR feedback * Add comments --- .../Diagnostics/Tracing/CounterGroup.cs | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs index 611c83547b39..effc21fd61ad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs @@ -200,22 +200,47 @@ private void ResetCounters() private void OnTimer() { - Debug.Assert(Monitor.IsEntered(s_counterGroupLock)); if (_eventSource.IsEnabled()) { - DateTime now = DateTime.UtcNow; - TimeSpan elapsed = now - _timeStampSinceCollectionStarted; + DateTime now; + TimeSpan elapsed; + int pollingIntervalInMilliseconds; + DiagnosticCounter[] counters; + lock (s_counterGroupLock) + { + now = DateTime.UtcNow; + elapsed = now - _timeStampSinceCollectionStarted; + pollingIntervalInMilliseconds = _pollingIntervalInMilliseconds; + counters = new DiagnosticCounter[_counters.Count]; + _counters.CopyTo(counters); + } - foreach (DiagnosticCounter counter in _counters) + // MUST keep out of the scope of s_counterGroupLock because this will cause WritePayload + // callback can be re-entrant to CounterGroup (i.e. it's possible it calls back into EnableTimer() + // above, since WritePayload callback can contain user code that can invoke EventSource constructor + // and lead to a deadlock. (See https://github.com/dotnet/runtime/issues/40190 for details) + foreach (DiagnosticCounter counter in counters) { - counter.WritePayload((float)elapsed.TotalSeconds, _pollingIntervalInMilliseconds); + // NOTE: It is still possible for a race condition to occur here. An example is if the session + // that subscribed to these batch of counters was disabled and it was immediately enabled in + // a different session, some of the counter data that was supposed to be written to the old + // session can now "overflow" into the new session. + // This problem pre-existed to this change (when we used to hold lock in the call to WritePayload): + // the only difference being the old behavior caused the entire batch of counters to be either + // written to the old session or the new session. The behavior change is not being treated as a + // significant problem to address for now, but we can come back and address it if it turns out to + // be an actual issue. + counter.WritePayload((float)elapsed.TotalSeconds, pollingIntervalInMilliseconds); } - _timeStampSinceCollectionStarted = now; - do + lock (s_counterGroupLock) { - _nextPollingTimeStamp += new TimeSpan(0, 0, 0, 0, _pollingIntervalInMilliseconds); - } while (_nextPollingTimeStamp <= now); + _timeStampSinceCollectionStarted = now; + do + { + _nextPollingTimeStamp += new TimeSpan(0, 0, 0, 0, _pollingIntervalInMilliseconds); + } while (_nextPollingTimeStamp <= now); + } } } @@ -228,8 +253,15 @@ private void OnTimer() private static void PollForValues() { AutoResetEvent? sleepEvent = null; + + // Cache of onTimer callbacks for each CounterGroup. + // We cache these outside of the scope of s_counterGroupLock because + // calling into the callbacks can cause a re-entrancy into CounterGroup.Enable() + // and result in a deadlock. (See https://github.com/dotnet/runtime/issues/40190 for details) + List onTimers = new List(); while (true) { + onTimers.Clear(); int sleepDurationInMilliseconds = int.MaxValue; lock (s_counterGroupLock) { @@ -239,7 +271,7 @@ private static void PollForValues() DateTime now = DateTime.UtcNow; if (counterGroup._nextPollingTimeStamp < now + new TimeSpan(0, 0, 0, 0, 1)) { - counterGroup.OnTimer(); + onTimers.Add(() => counterGroup.OnTimer()); } int millisecondsTillNextPoll = (int)((counterGroup._nextPollingTimeStamp - now).TotalMilliseconds); @@ -247,6 +279,10 @@ private static void PollForValues() sleepDurationInMilliseconds = Math.Min(sleepDurationInMilliseconds, millisecondsTillNextPoll); } } + foreach (Action onTimer in onTimers) + { + onTimer.Invoke(); + } if (sleepDurationInMilliseconds == int.MaxValue) { sleepDurationInMilliseconds = -1; // WaitOne uses -1 to mean infinite From 3bb51130cffee94fa5b1bb53e0d19ca18b030075 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Fri, 14 Aug 2020 18:28:46 -0700 Subject: [PATCH 516/755] Fixing the allconfig build. (#40812) * fixing all config build * address feedback --- Build.proj | 2 +- src/libraries/Directory.Build.props | 1 + src/libraries/Native/build-native.proj | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Build.proj b/Build.proj index 2041d3d4fcc1..2d96f02056fe 100644 --- a/Build.proj +++ b/Build.proj @@ -1,7 +1,7 @@ - BuildTargetFramework=$([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)')) + BuildTargetFramework=$([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)')) diff --git a/src/libraries/Native/build-native.proj b/src/libraries/Native/build-native.proj index 28dc8184f01c..beaf30987450 100644 --- a/src/libraries/Native/build-native.proj +++ b/src/libraries/Native/build-native.proj @@ -3,7 +3,9 @@ $(ArtifactsObjDir)_version.h $(ArtifactsObjDir)_version.c - <_BuildNativeArgs>$(TargetArchitecture) $(Configuration) outconfig $(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture) -os $(TargetOS) + $(BuildTargetFramework) + $(NetCoreAppCurrent) + <_BuildNativeArgs>$(TargetArchitecture) $(Configuration) outconfig $(TargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture) -os $(TargetOS) @@ -39,7 +41,7 @@ + '$(TargetFramework)' == '$(NetCoreAppCurrent)'"> From 2564f1acff5b998e6079846ffe88cba7698ac924 Mon Sep 17 00:00:00 2001 From: Jimmy Bogard Date: Fri, 14 Aug 2020 21:19:55 -0500 Subject: [PATCH 517/755] Adding support for constrained open generics to DI (#39540) * Porting changes from https://github.com/dotnet/extensions/pull/536 * Correcting reference * Avoiding wrapping exception as there may be other reasons why closing the generic type fails other than constraint failure --- .../src/ServiceLookup/CallSiteFactory.cs | 22 +- .../tests/DI.External.Tests/Autofac.cs | 2 +- ...yInjection.ExternalContainers.Tests.csproj | 14 +- .../tests/DI.External.Tests/StashBox.cs | 2 +- .../DependencyInjectionSpecificationTests.cs | 83 +++++ .../Fakes/AbstractClass.cs | 11 + .../Fakes/ClassImplementingIComparable.cs | 13 + .../Fakes/ClassImplementingIEnumerable.cs | 14 + .../Fakes/ClassInheritingAbstractClass.cs | 21 ++ .../Fakes/ClassWithAbstractClassConstraint.cs | 14 + .../Fakes/ClassWithClassConstraint.cs | 12 + .../Fakes/ClassWithInterfaceConstraint.cs | 16 + .../Fakes/ClassWithNewConstraint.cs | 12 + .../Fakes/ClassWithNoConstraint.cs | 11 + .../ClassWithSelfReferencingConstraint.cs | 16 + .../Fakes/ClassWithStructConstraint.cs | 12 + .../ConstrainedFakeOpenGenericService.cs | 16 + .../Fakes/IFakeOpenGenericService.cs | 2 +- .../tests/DI.Tests/Fakes/AbstractClass.cs | 12 - .../ServiceLookup/CallSiteFactoryTest.cs | 286 ++++++++++++++++++ 20 files changed, 565 insertions(+), 26 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/AbstractClass.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIComparable.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIEnumerable.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassInheritingAbstractClass.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithAbstractClassConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithClassConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithInterfaceConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNewConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNoConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithSelfReferencingConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithStructConstraint.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ConstrainedFakeOpenGenericService.cs delete mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Fakes/AbstractClass.cs diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs index 4aec44848ae0..f3b919212255 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs @@ -119,7 +119,7 @@ private ServiceCallSite TryCreateOpenGeneric(Type serviceType, CallSiteChain cal if (serviceType.IsConstructedGenericType && _descriptorLookup.TryGetValue(serviceType.GetGenericTypeDefinition(), out ServiceDescriptorCacheItem descriptor)) { - return TryCreateOpenGeneric(descriptor.Last, serviceType, callSiteChain, DefaultSlot); + return TryCreateOpenGeneric(descriptor.Last, serviceType, callSiteChain, DefaultSlot, true); } return null; @@ -165,7 +165,7 @@ private ServiceCallSite TryCreateEnumerable(Type serviceType, CallSiteChain call { ServiceDescriptor descriptor = _descriptors[i]; ServiceCallSite callSite = TryCreateExact(descriptor, itemType, callSiteChain, slot) ?? - TryCreateOpenGeneric(descriptor, itemType, callSiteChain, slot); + TryCreateOpenGeneric(descriptor, itemType, callSiteChain, slot, false); if (callSite != null) { @@ -231,14 +231,28 @@ private ServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type servic return null; } - private ServiceCallSite TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot) + private ServiceCallSite TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot, bool throwOnConstraintViolation) { if (serviceType.IsConstructedGenericType && serviceType.GetGenericTypeDefinition() == descriptor.ServiceType) { Debug.Assert(descriptor.ImplementationType != null, "descriptor.ImplementationType != null"); var lifetime = new ResultCache(descriptor.Lifetime, serviceType, slot); - Type closedType = descriptor.ImplementationType.MakeGenericType(serviceType.GenericTypeArguments); + Type closedType; + try + { + closedType = descriptor.ImplementationType.MakeGenericType(serviceType.GenericTypeArguments); + } + catch (ArgumentException) + { + if (throwOnConstraintViolation) + { + throw; + } + + return null; + } + return CreateConstructorCallSite(lifetime, serviceType, closedType, callSiteChain); } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Autofac.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Autofac.cs index 15295982782f..f80fd06d146a 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Autofac.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Autofac.cs @@ -7,7 +7,7 @@ namespace Microsoft.Extensions.DependencyInjection.Specification { - public class AutofacDependencyInjectionSpecificationTests: DependencyInjectionSpecificationTests + public class AutofacDependencyInjectionSpecificationTests : DependencyInjectionSpecificationTests { protected override IServiceProvider CreateServiceProvider(IServiceCollection serviceCollection) { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj index 9357badc0f94..0c8e6b800629 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/Microsoft.Extensions.DependencyInjection.ExternalContainers.Tests.csproj @@ -19,13 +19,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/StashBox.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/StashBox.cs index 28a27f028af5..3deffe4767d7 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/StashBox.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.External.Tests/StashBox.cs @@ -5,7 +5,7 @@ namespace Microsoft.Extensions.DependencyInjection.Specification { - public class StashBoxDependencyInjectionSpecificationTests: DependencyInjectionSpecificationTests + public class StashBoxDependencyInjectionSpecificationTests : DependencyInjectionSpecificationTests { protected override IServiceProvider CreateServiceProvider(IServiceCollection serviceCollection) { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs index e50d9ca8b649..1a1aa7e0a1d0 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs @@ -591,6 +591,89 @@ public void OpenGenericServicesCanBeResolved() Assert.Same(singletonService, genericService.Value); } + [Fact] + public void ConstrainedOpenGenericServicesCanBeResolved() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>)); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(ConstrainedFakeOpenGenericService<>)); + var poco = new PocoClass(); + collection.AddSingleton(poco); + collection.AddSingleton(); + var provider = CreateServiceProvider(collection); + // Act + var allServices = provider.GetServices>().ToList(); + var constrainedServices = provider.GetServices>().ToList(); + var singletonService = provider.GetService(); + // Assert + Assert.Equal(2, allServices.Count); + Assert.Same(poco, allServices[0].Value); + Assert.Same(poco, allServices[1].Value); + Assert.Equal(1, constrainedServices.Count); + Assert.Same(singletonService, constrainedServices[0].Value); + } + + [Fact] + public void ConstrainedOpenGenericServicesReturnsEmptyWithNoMatches() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(ConstrainedFakeOpenGenericService<>)); + collection.AddSingleton(); + var provider = CreateServiceProvider(collection); + // Act + var constrainedServices = provider.GetServices>().ToList(); + // Assert + Assert.Equal(0, constrainedServices.Count); + } + + [Fact] + public void InterfaceConstrainedOpenGenericServicesCanBeResolved() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>)); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(ClassWithInterfaceConstraint<>)); + var enumerableVal = new ClassImplementingIEnumerable(); + collection.AddSingleton(enumerableVal); + collection.AddSingleton(); + var provider = CreateServiceProvider(collection); + // Act + var allServices = provider.GetServices>().ToList(); + var constrainedServices = provider.GetServices>().ToList(); + var singletonService = provider.GetService(); + // Assert + Assert.Equal(2, allServices.Count); + Assert.Same(enumerableVal, allServices[0].Value); + Assert.Same(enumerableVal, allServices[1].Value); + Assert.Equal(1, constrainedServices.Count); + Assert.Same(singletonService, constrainedServices[0].Value); + } + + [Fact] + public void AbstractClassConstrainedOpenGenericServicesCanBeResolved() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>)); + collection.AddTransient(typeof(IFakeOpenGenericService<>), typeof(ClassWithAbstractClassConstraint<>)); + var poco = new PocoClass(); + collection.AddSingleton(poco); + var classInheritingClassInheritingAbstractClass = new ClassInheritingClassInheritingAbstractClass(); + collection.AddSingleton(classInheritingClassInheritingAbstractClass); + var provider = CreateServiceProvider(collection); + // Act + var allServices = provider.GetServices>().ToList(); + var constrainedServices = provider.GetServices>().ToList(); + // Assert + Assert.Equal(2, allServices.Count); + Assert.Same(classInheritingClassInheritingAbstractClass, allServices[0].Value); + Assert.Same(classInheritingClassInheritingAbstractClass, allServices[1].Value); + Assert.Equal(1, constrainedServices.Count); + Assert.Same(poco, constrainedServices[0].Value); + } + [Fact] public void ClosedServicesPreferredOverOpenGenericServices() { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/AbstractClass.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/AbstractClass.cs new file mode 100644 index 000000000000..c6ccfd348708 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/AbstractClass.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public abstract class AbstractClass + { + + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIComparable.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIComparable.cs new file mode 100644 index 000000000000..02ffe2e9c796 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIComparable.cs @@ -0,0 +1,13 @@ +// 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; + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassImplementingIComparable : IComparable + { + public int CompareTo(ClassImplementingIComparable other) => 0; + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIEnumerable.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIEnumerable.cs new file mode 100644 index 000000000000..20fe4e2fc7ce --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassImplementingIEnumerable.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassImplementingIEnumerable : IEnumerable + { + public IEnumerator GetEnumerator() => throw new NotImplementedException(); + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassInheritingAbstractClass.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassInheritingAbstractClass.cs new file mode 100644 index 000000000000..ec37f2b103a2 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassInheritingAbstractClass.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassInheritingAbstractClass : AbstractClass + { + + } + + public class ClassAlsoInheritingAbstractClass : AbstractClass + { + + } + + public class ClassInheritingClassInheritingAbstractClass : ClassInheritingAbstractClass + { + + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithAbstractClassConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithAbstractClassConstraint.cs new file mode 100644 index 000000000000..e5519863348d --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithAbstractClassConstraint.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithAbstractClassConstraint : IFakeOpenGenericService + where T : AbstractClass + { + public ClassWithAbstractClassConstraint(T value) => Value = value; + + public T Value { get; } + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithClassConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithClassConstraint.cs new file mode 100644 index 000000000000..b180203a688a --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithClassConstraint.cs @@ -0,0 +1,12 @@ +// 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. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithClassConstraint : IFakeOpenGenericService + where T : class + { + public T Value { get; } = default; + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithInterfaceConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithInterfaceConstraint.cs new file mode 100644 index 000000000000..efd2c9c6cef6 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithInterfaceConstraint.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithInterfaceConstraint : IFakeOpenGenericService + where T : IEnumerable + { + public ClassWithInterfaceConstraint(T value) => Value = value; + + public T Value { get; } + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNewConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNewConstraint.cs new file mode 100644 index 000000000000..143986cfa112 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNewConstraint.cs @@ -0,0 +1,12 @@ +// 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. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithNewConstraint : IFakeOpenGenericService + where T : new() + { + public T Value { get; } = new T(); + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNoConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNoConstraint.cs new file mode 100644 index 000000000000..848e7551cd6a --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithNoConstraint.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithNoConstraints : IFakeOpenGenericService + { + public T Value { get; } = default; + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithSelfReferencingConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithSelfReferencingConstraint.cs new file mode 100644 index 000000000000..0e4642902294 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithSelfReferencingConstraint.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithSelfReferencingConstraint : IFakeOpenGenericService + where T : IComparable + { + public ClassWithSelfReferencingConstraint(T value) => Value = value; + + public T Value { get; } + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithStructConstraint.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithStructConstraint.cs new file mode 100644 index 000000000000..06355eb905ff --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ClassWithStructConstraint.cs @@ -0,0 +1,12 @@ +// 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. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ClassWithStructConstraint : IFakeOpenGenericService + where T : struct + { + public T Value { get; } = default; + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ConstrainedFakeOpenGenericService.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ConstrainedFakeOpenGenericService.cs new file mode 100644 index 000000000000..940e3621a877 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/ConstrainedFakeOpenGenericService.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes +{ + public class ConstrainedFakeOpenGenericService : IFakeOpenGenericService + where TVal : PocoClass + { + public ConstrainedFakeOpenGenericService(TVal value) + { + Value = value; + } + public TVal Value { get; } + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/IFakeOpenGenericService.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/IFakeOpenGenericService.cs index 71870357fd9d..d556939012de 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/IFakeOpenGenericService.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Specification.Tests/Fakes/IFakeOpenGenericService.cs @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.DependencyInjection.Specification.Fakes { - public interface IFakeOpenGenericService + public interface IFakeOpenGenericService { TValue Value { get; } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Fakes/AbstractClass.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Fakes/AbstractClass.cs deleted file mode 100644 index b2d1cff2734b..000000000000 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Fakes/AbstractClass.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Extensions.DependencyInjection.Tests.Fakes -{ - public abstract class AbstractClass - { - public AbstractClass() - { - } - } -} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs index bc0988f06d64..13d4decd776b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs @@ -111,6 +111,292 @@ public void CreateCallSite_UsesNullaryConstructorIfServicesCannotBeInjectedIntoO Assert.Empty(ctorCallSite.ParameterCallSites); } + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyStructGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithStructConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesStructGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithStructConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyClassGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithClassConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesClassGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithClassConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyNewGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithNewConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesNewGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithNewConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor, new ServiceDescriptor(typeof(TypeWithParameterlessPublicConstructor), new TypeWithParameterlessPublicConstructor())); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyInterfaceGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithInterfaceConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesInterfaceGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithInterfaceConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor, new ServiceDescriptor(typeof(string), "")); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyAbstractClassGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithAbstractClassConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesAbstractClassGenericConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithAbstractClassConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor, new ServiceDescriptor(typeof(ClassInheritingAbstractClass), new ClassInheritingAbstractClass())); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_Throws_IfClosedTypeDoesNotSatisfySelfReferencingConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithSelfReferencingConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_Throws_IfComplexClosedTypeDoesNotSatisfySelfReferencingConstraint() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithSelfReferencingConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor); + // Act + var nonMatchingType = typeof(IFakeOpenGenericService); + // Assert + Assert.Throws(() => callSiteFactory(nonMatchingType)); + } + + [Fact] + public void CreateCallSite_ReturnsService_IfClosedTypeSatisfiesSelfReferencing() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var implementationType = typeof(ClassWithSelfReferencingConstraint<>); + var descriptor = new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient); + var callSiteFactory = GetCallSiteFactory(descriptor, new ServiceDescriptor(typeof(string), "")); + // Act + var matchingType = typeof(IFakeOpenGenericService); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + Assert.NotNull(matchingCallSite); + } + + [Fact] + public void CreateCallSite_ReturnsEmpty_IfClosedTypeSatisfiesBaseClassConstraintButRegisteredTypeNotExactMatch() + { + // Arrange + var classInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classInheritingAbstractClassDescriptor = new ServiceDescriptor(typeof(IFakeOpenGenericService), classInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var classAlsoInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classAlsoInheritingAbstractClassDescriptor = new ServiceDescriptor(typeof(IFakeOpenGenericService), classAlsoInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var classInheritingClassInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classInheritingClassInheritingAbstractClassDescriptor = new ServiceDescriptor(typeof(IFakeOpenGenericService), classInheritingClassInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var notMatchingServiceType = typeof(IFakeOpenGenericService); + var notMatchingType = typeof(FakeService); + var notMatchingDescriptor = new ServiceDescriptor(notMatchingServiceType, notMatchingType, ServiceLifetime.Transient); + + var callSiteFactory = GetCallSiteFactory(classInheritingAbstractClassDescriptor, classAlsoInheritingAbstractClassDescriptor, classInheritingClassInheritingAbstractClassDescriptor, notMatchingDescriptor); + // Act + var matchingType = typeof(IEnumerable>); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + var enumerableCall = Assert.IsType(matchingCallSite); + + Assert.Empty(enumerableCall.ServiceCallSites); + } + + [Fact] + public void CreateCallSite_ReturnsMatchingTypes_IfClosedTypeSatisfiesBaseClassConstraintAndRegisteredType() + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService); + var classInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classInheritingAbstractClassDescriptor = new ServiceDescriptor(serviceType, classInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var classAlsoInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classAlsoInheritingAbstractClassDescriptor = new ServiceDescriptor(serviceType, classAlsoInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var classInheritingClassInheritingAbstractClassImplementationType = typeof(ClassWithAbstractClassConstraint); + var classInheritingClassInheritingAbstractClassDescriptor = new ServiceDescriptor(serviceType, classInheritingClassInheritingAbstractClassImplementationType, ServiceLifetime.Transient); + var notMatchingServiceType = typeof(IFakeOpenGenericService); + var notMatchingType = typeof(FakeService); + var notMatchingDescriptor = new ServiceDescriptor(notMatchingServiceType, notMatchingType, ServiceLifetime.Transient); + + var descriptors = new[] + { + classInheritingAbstractClassDescriptor, + new ServiceDescriptor(typeof(ClassInheritingAbstractClass), new ClassInheritingAbstractClass()), + classAlsoInheritingAbstractClassDescriptor, + new ServiceDescriptor(typeof(ClassAlsoInheritingAbstractClass), new ClassAlsoInheritingAbstractClass()), + classInheritingClassInheritingAbstractClassDescriptor, + new ServiceDescriptor(typeof(ClassInheritingClassInheritingAbstractClass), new ClassInheritingClassInheritingAbstractClass()), + notMatchingDescriptor + }; + var callSiteFactory = GetCallSiteFactory(descriptors); + // Act + var matchingType = typeof(IEnumerable<>).MakeGenericType(serviceType); + var matchingCallSite = callSiteFactory(matchingType); + // Assert + var enumerableCall = Assert.IsType(matchingCallSite); + + var matchingTypes = new[] + { + classInheritingAbstractClassImplementationType, + classAlsoInheritingAbstractClassImplementationType, + classInheritingClassInheritingAbstractClassImplementationType + }; + Assert.Equal(matchingTypes.Length, enumerableCall.ServiceCallSites.Length); + Assert.Equal(matchingTypes, enumerableCall.ServiceCallSites.Select(scs => scs.ImplementationType).ToArray()); + } + + [Theory] + [InlineData(typeof(IFakeOpenGenericService), default(int), new[] { typeof(FakeOpenGenericService), typeof(ClassWithStructConstraint), typeof(ClassWithNewConstraint), typeof(ClassWithSelfReferencingConstraint) })] + [InlineData(typeof(IFakeOpenGenericService), "", new[] { typeof(FakeOpenGenericService), typeof(ClassWithClassConstraint), typeof(ClassWithInterfaceConstraint), typeof(ClassWithSelfReferencingConstraint) })] + [InlineData(typeof(IFakeOpenGenericService), new[] { 1, 2, 3 }, new[] { typeof(FakeOpenGenericService), typeof(ClassWithClassConstraint), typeof(ClassWithInterfaceConstraint) })] + public void CreateCallSite_ReturnsMatchingTypesThatMatchCorrectConstraints(Type closedServiceType, object value, Type[] matchingImplementationTypes) + { + // Arrange + var serviceType = typeof(IFakeOpenGenericService<>); + var noConstraintImplementationType = typeof(FakeOpenGenericService<>); + var noConstraintDescriptor = new ServiceDescriptor(serviceType, noConstraintImplementationType, ServiceLifetime.Transient); + var structImplementationType = typeof(ClassWithStructConstraint<>); + var structDescriptor = new ServiceDescriptor(serviceType, structImplementationType, ServiceLifetime.Transient); + var classImplementationType = typeof(ClassWithClassConstraint<>); + var classDescriptor = new ServiceDescriptor(serviceType, classImplementationType, ServiceLifetime.Transient); + var newImplementationType = typeof(ClassWithNewConstraint<>); + var newDescriptor = new ServiceDescriptor(serviceType, newImplementationType, ServiceLifetime.Transient); + var interfaceImplementationType = typeof(ClassWithInterfaceConstraint<>); + var interfaceDescriptor = new ServiceDescriptor(serviceType, interfaceImplementationType, ServiceLifetime.Transient); + var selfConstraintImplementationType = typeof(ClassWithSelfReferencingConstraint<>); + var selfConstraintDescriptor = new ServiceDescriptor(serviceType, selfConstraintImplementationType, ServiceLifetime.Transient); + var serviceValueType = closedServiceType.GenericTypeArguments[0]; + var serviceValueDescriptor = new ServiceDescriptor(serviceValueType, value); + var callSiteFactory = GetCallSiteFactory(noConstraintDescriptor, structDescriptor, classDescriptor, newDescriptor, interfaceDescriptor, selfConstraintDescriptor, serviceValueDescriptor); + var collectionType = typeof(IEnumerable<>).MakeGenericType(closedServiceType); + // Act + var callSite = callSiteFactory(collectionType); + // Assert + var enumerableCall = Assert.IsType(callSite); + Assert.Equal(matchingImplementationTypes.Length, enumerableCall.ServiceCallSites.Length); + Assert.Equal(matchingImplementationTypes, enumerableCall.ServiceCallSites.Select(scs => scs.ImplementationType).ToArray()); + } + public static TheoryData CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParametersData => new TheoryData, Type[]> { From 99829d5017b274537ada263ea7002ec576fa85d5 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 14 Aug 2020 19:24:36 -0700 Subject: [PATCH 518/755] Throw when non-nullable struct converters indicate that they handle nullable structs (#40824) * Wrap non-nullable struct converters in NullableOfT converter when they explicitly handle nullable structs * Throw exception instead of being nice * Improve exception message --- .../src/Resources/Strings.resx | 5 +- .../JsonSerializerOptions.Converters.cs | 19 +++ .../Text/Json/ThrowHelper.Serialization.cs | 7 + .../CustomConverterTests.NullableTypes.cs | 151 ++++++++++++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 07655cbccea7..d6ae6ad77482 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -542,4 +542,7 @@ 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}'. - + + The converter '{0}' handles type '{1}' but is being asked to convert type '{2}'. Either create a separate converter for type '{2}' or change the converter's 'CanConvert' method to only return 'true' for a single type. + + \ No newline at end of file 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 860b49315a40..018eab87ade1 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 @@ -18,6 +18,8 @@ public sealed partial class JsonSerializerOptions // The global list of built-in simple converters. private static readonly Dictionary s_defaultSimpleConverters = GetDefaultSimpleConverters(); + private static readonly Type s_nullableOfTType = typeof(Nullable<>); + // The global list of built-in converters that override CanConvert(). private static readonly JsonConverter[] s_defaultFactoryConverters = new JsonConverter[] { @@ -177,6 +179,18 @@ internal JsonConverter DetermineConverter(Type? parentClassType, Type runtimePro Debug.Assert(converter != null); } + // User indicated that non-nullable-struct-handling converter should handle a nullable struct type. + // The serializer would have picked that converter up by default and wrapped it in NullableConverter; + // throw so that user can modify or remove their unnecessary CanConvert method override. + // + // We also throw to avoid passing an invalid argument to setters for nullable struct properties, + // which would cause an InvalidProgramException when the generated IL is invoked. + // This is not an issue of the converter is wrapped in NullableConverter. + if (IsNullableType(runtimePropertyType) && !IsNullableType(converter.TypeToConvert)) + { + ThrowHelper.ThrowInvalidOperationException_ConverterCanConvertNullableRedundant(runtimePropertyType, converter); + } + return converter; } @@ -346,5 +360,10 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter ThrowHelper.ThrowInvalidOperationException_SerializationDuplicateAttribute(attributeType, classType, memberInfo); return default; } + + private static bool IsNullableType(Type type) + { + return type.IsGenericType && type.GetGenericTypeDefinition() == s_nullableOfTType; + } } } 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 b9bd641a9cc2..e82f44b05a59 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 @@ -247,6 +247,13 @@ public static void ThrowInvalidOperationException_NumberHandlingOnPropertyInvali memberInfo.DeclaringType)); } + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowInvalidOperationException_ConverterCanConvertNullableRedundant(Type runtimePropertyType, JsonConverter jsonConverter) + { + throw new InvalidOperationException(SR.Format(SR.ConverterCanConvertNullableRedundant, jsonConverter.GetType(), jsonConverter.TypeToConvert, runtimePropertyType)); + } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowNotSupportedException_ObjectWithParameterizedCtorRefMetadataNotHonored( diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs index d9a9f3925241..a45766ba2bdd 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs @@ -1,5 +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; using Xunit; @@ -277,5 +278,155 @@ public static void ReferenceTypeConverterDoesntGetPassedNull() Assert.Equal(@"[{""MyInt"":42},{""MyInt"":42}]", json); } } + + [Fact] + public static void StructConverter_SaysCanConvertNullableStruct_ConverterOnProperty() + { + string converterTypeAsStr = typeof(JsonTestStructValueChangingConverter).ToString(); + string structTypeAsStr = typeof(TestStruct).ToString(); + string nullableStructTypeAsStr = typeof(TestStruct?).ToString(); + + InvalidOperationException ex = Assert.Throws( + () => JsonSerializer.Serialize(new ClassWithNullableStruct_ConverterOnProperty { MyStruct = new TestStruct() })); + string exAsStr = ex.ToString(); + Assert.Contains(converterTypeAsStr, exAsStr); + Assert.Contains(structTypeAsStr, exAsStr); + Assert.Contains(nullableStructTypeAsStr, exAsStr); + + ex = Assert.Throws(() => + JsonSerializer.Deserialize("")); + exAsStr = ex.ToString(); + Assert.Contains(converterTypeAsStr, exAsStr); + Assert.Contains(structTypeAsStr, exAsStr); + Assert.Contains(nullableStructTypeAsStr, exAsStr); + } + + [Fact] + public static void StructConverter_SaysCanConvertNullableStruct_ConverterOnType() + { + // Converter cannot be applied directly to nullable type, so the serializer wraps the converter it with NullableConverter as expected. + + string serialized = JsonSerializer.Serialize(new ClassWithNullableStruct_ConverterOnType { MyStruct = new TestStructWithConverter { InnerValue = 5 } }); + Assert.Equal(@"{""MyStruct"":{""InnerValue"":10}}", serialized); + + ClassWithNullableStruct_ConverterOnType obj = JsonSerializer.Deserialize(serialized); + Assert.Equal(15, obj.MyStruct?.InnerValue); + } + + [Fact] + public static void StructConverter_SaysCanConvertNullableStruct_ConverterOnOptions() + { + var options = new JsonSerializerOptions { Converters = { new JsonTestStructValueChangingConverter() } }; + + Assert.Throws( + () => JsonSerializer.Serialize(new ClassWithNullableStruct { MyStruct = new TestStruct() }, options)); + + Assert.Throws(() => + JsonSerializer.Deserialize("", options)); + } + + [Fact] + public static void StructConverter_SaysCanConvertNullableStruct_StructAsRootType_ConverterOnType() + { + // Converter cannot be applied directly to nullable type, so the serializer wraps the converter it with NullableConverter as expected. + + TestStructWithConverter? obj = new TestStructWithConverter { InnerValue = 5 }; + string serialized = JsonSerializer.Serialize(obj); + Assert.Equal(@"{""InnerValue"":10}", serialized); + + obj = JsonSerializer.Deserialize(serialized); + Assert.Equal(15, obj?.InnerValue); + } + + [Fact] + public static void StructConverter_SaysCanConvertNullableStruct_StructAsRootType_ConverterOnOptions() + { + var options = new JsonSerializerOptions { Converters = { new JsonTestStructValueChangingConverter() } }; + + TestStruct? obj = new TestStruct { InnerValue = 5 }; + + Assert.Throws(() => JsonSerializer.Serialize(obj, options)); + + Assert.Throws(() => + JsonSerializer.Deserialize("", options)); + } + + private class ClassWithNullableStruct_ConverterOnProperty + { + [JsonConverter(typeof(JsonTestStructValueChangingConverter))] + public TestStruct? MyStruct { get; set; } + } + + private class ClassWithNullableStruct_ConverterOnType + { + public TestStructWithConverter? MyStruct { get; set; } + } + + private class ClassWithNullableStruct + { + public TestStruct? MyStruct { get; set; } + } + + [JsonConverter(typeof(JsonTestStructWithConverterValueChangingConverter))] + public struct TestStructWithConverter + { + public int InnerValue { get; set; } + } + + private class JsonTestStructValueChangingConverter : JsonConverter + { + public override bool CanConvert(Type typeToConvert) => + typeToConvert == typeof(TestStruct) || typeToConvert == typeof(TestStruct?); + + public override TestStruct Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + throw new NotImplementedException(); + + public override void Write(Utf8JsonWriter writer, TestStruct value, JsonSerializerOptions options) => + throw new NotImplementedException(); + } + + private class JsonTestStructWithConverterValueChangingConverter : JsonConverter + { + public override bool CanConvert(Type typeToConvert) => + typeToConvert == typeof(TestStructWithConverter) || typeToConvert == typeof(TestStructWithConverter?); + + public override TestStructWithConverter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + reader.Read(); + + if (reader.TokenType != JsonTokenType.PropertyName || reader.GetString() != "InnerValue") + { + throw new JsonException(); + } + + reader.Read(); + + var obj = new TestStructWithConverter + { + InnerValue = reader.GetInt32() + 5 + }; + + reader.Read(); + + if (reader.TokenType != JsonTokenType.EndObject) + { + throw new JsonException(); + } + + return obj; + } + + public override void Write(Utf8JsonWriter writer, TestStructWithConverter value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + writer.WriteNumber("InnerValue", value.InnerValue + 5); + writer.WriteEndObject(); + } + } } } From dc6ad2a89cde71714b87e42a159ed6264fa7093d Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 14 Aug 2020 21:28:40 -0500 Subject: [PATCH 519/755] Change null handling in custom converters for backwards compat (#40859) --- .../Json/Serialization/JsonConverterOfT.cs | 55 ++++++++++++++++--- .../Json/Serialization/JsonPropertyInfoOfT.cs | 6 +- .../CustomConverterTests.HandleNull.cs | 8 ++- .../CustomConverterTests.NullableTypes.cs | 17 +++--- 4 files changed, 65 insertions(+), 21 deletions(-) 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 e6f7d84d3ea7..9c360144a73b 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 @@ -21,9 +21,21 @@ protected internal JsonConverter() // In the future, this will be check for !IsSealed (and excluding value types). CanBePolymorphic = TypeToConvert == JsonClassInfo.ObjectType; IsValueType = TypeToConvert.IsValueType; - HandleNull = IsValueType; CanBeNull = !IsValueType || Nullable.GetUnderlyingType(TypeToConvert) != null; IsInternalConverter = GetType().Assembly == typeof(JsonConverter).Assembly; + + if (HandleNull) + { + HandleNullOnRead = true; + HandleNullOnWrite = true; + } + + // For the HandleNull == false case, either: + // 1) The default values are assigned in this type's virtual HandleNull property + // or + // 2) A converter overroad HandleNull and returned false so HandleNullOnRead and HandleNullOnWrite + // will be their default values of false. + CanUseDirectReadOrWrite = !CanBePolymorphic && IsInternalConverter && ClassType == ClassType.Value; } @@ -61,7 +73,34 @@ internal override sealed JsonParameterInfo CreateJsonParameterInfo() /// /// The default value is for converters for value types, and for converters for reference types. /// - public virtual bool HandleNull { get; } + public virtual bool HandleNull + { + get + { + // HandleNull is only called by the framework once during initialization and any + // subsequent calls elsewhere would just re-initialize to the same values (we don't + // track a "hasInitialized" flag since that isn't necessary). + + // If the type doesn't support null, allow the converter a chance to modify. + // These semantics are backwards compatible with 3.0. + HandleNullOnRead = !CanBeNull; + + // The framework handles null automatically on writes. + HandleNullOnWrite = false; + + return false; + } + } + + /// + /// Does the converter want to be called when reading null tokens. + /// + internal bool HandleNullOnRead { get; private set; } + + /// + /// Does the converter want to be called for null values. + /// + internal bool HandleNullOnWrite { get; private set; } /// /// Can be assigned to ? @@ -109,7 +148,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali Debug.Assert(!state.IsContinuation); // For perf and converter simplicity, handle null here instead of forwarding to the converter. - if (reader.TokenType == JsonTokenType.Null && !HandleNull) + if (reader.TokenType == JsonTokenType.Null && !HandleNullOnRead) { if (!CanBeNull) { @@ -184,7 +223,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { - if (reader.TokenType == JsonTokenType.Null && !HandleNull && !wasContinuation) + if (reader.TokenType == JsonTokenType.Null && !HandleNullOnRead && !wasContinuation) { if (!CanBeNull) { @@ -206,7 +245,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali if (!wasContinuation) { // For perf and converter simplicity, handle null here instead of forwarding to the converter. - if (reader.TokenType == JsonTokenType.Null && !HandleNull) + if (reader.TokenType == JsonTokenType.Null && !HandleNullOnRead) { if (!CanBeNull) { @@ -267,7 +306,7 @@ internal bool TryWrite(Utf8JsonWriter writer, in T value, JsonSerializerOptions { if (value == null) { - if (!HandleNull) + if (!HandleNullOnWrite) { writer.WriteNullValue(); } @@ -303,9 +342,9 @@ internal bool TryWrite(Utf8JsonWriter writer, in T value, JsonSerializerOptions } } } - else if (value == null && !HandleNull) + else if (value == null && !HandleNullOnWrite) { - // We do not pass null values to converters unless HandleNull is true. Null values for properties were + // We do not pass null values to converters unless HandleNullOnWrite is true. Null values for properties were // already handled in GetMemberAndWriteJson() so we don't need to check for IgnoreNullValues here. writer.WriteNullValue(); return true; 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 9e24e2595422..7a0d0155ded8 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 @@ -135,7 +135,7 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf { Debug.Assert(Converter.CanBeNull); - if (Converter.HandleNull) + if (Converter.HandleNullOnWrite) { // No object, collection, or re-entrancy converter handles null. Debug.Assert(Converter.ClassType == ClassType.Value); @@ -194,7 +194,7 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !Converter.HandleNull && !state.IsContinuation) + if (isNullToken && !Converter.HandleNullOnRead && !state.IsContinuation) { if (!Converter.CanBeNull) { @@ -242,7 +242,7 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re { bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !Converter.HandleNull && !state.IsContinuation) + if (isNullToken && !Converter.HandleNullOnRead && !state.IsContinuation) { if (!Converter.CanBeNull) { diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index 2a383cf1d400..191a8283f940 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -172,15 +172,17 @@ public static void NullableValueTypeConverter_NoOverride() Assert.Null(val); Assert.Equal("null", JsonSerializer.Serialize(val)); - // Per null handling default value for value types (true), converter handles null. + // For compat, deserialize does not call converter for null token unless the type doesn't support + // null or HandleNull is overridden and returns 'true'. + // For compat, serialize does not call converter for null unless null is a valid value and HandleNull is true. var options = new JsonSerializerOptions(); options.Converters.Add(new NullableInt32NullConverter_SpecialCaseNull()); val = JsonSerializer.Deserialize("null", options); - Assert.Equal(-1, val); + Assert.Null(val); val = null; - Assert.Equal("-1", JsonSerializer.Serialize(val, options)); + Assert.Equal("null", JsonSerializer.Serialize(val, options)); } private class NullableInt32NullConverter_SpecialCaseNull : JsonConverter diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs index a45766ba2bdd..2a62d336bc09 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.NullableTypes.cs @@ -161,32 +161,35 @@ public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOpti } [Fact] - public static void NullableConverterIsPassedNull() + public static void NullableConverterIsNotPassedNull() { + // For compat, deserialize does not call converter for null token unless the type doesn't support + // null or HandleNull is overridden and returns 'true'. + // For compat, serialize does not call converter for null unless null is a valid value and HandleNull is true. + var options = new JsonSerializerOptions(); options.Converters.Add(new NullIntTo42Converter()); { int? myInt = JsonSerializer.Deserialize("null", options); - Assert.True(myInt.HasValue); - Assert.Equal(42, myInt.Value); + Assert.Null(myInt); } { string json = JsonSerializer.Serialize(null, options); - Assert.Equal("42", json); + Assert.Equal("null", json); } { int?[] ints = JsonSerializer.Deserialize("[null, null]", options); Assert.Equal(2, ints.Length); - Assert.Equal(42, ints[0]); - Assert.Equal(42, ints[1]); + Assert.Null(ints[0]); + Assert.Null(ints[1]); } { string json = JsonSerializer.Serialize(new int?[] { null, null }, options); - Assert.Equal("[42,42]", json); + Assert.Equal("[null,null]", json); } } From 7742b574c02f4e68493aff217fd1c3a957c4ae46 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Fri, 14 Aug 2020 19:33:05 -0700 Subject: [PATCH 520/755] Fix TailCallStress mode. (#40698) Improve validation of tail calls that are not tail-prefixed in the IL but are marked as such because of TailCallStress. We now do the same correctness validation in morph for such tail calls as we do for implicit tail calls. That blocks tail calls when we have address-taken locals, struct promoted params, and pinned vars. Fixes #39398. Fixes #39309. Fixes #38892. Fixes #38889. Fixes #38887. Fixes #37117. Fixes #8017. --- eng/pipelines/libraries/run-test-job.yml | 5 +--- src/coreclr/src/jit/gentree.h | 8 +++++ src/coreclr/src/jit/importer.cpp | 20 +++++++++---- src/coreclr/src/jit/morph.cpp | 29 +++++++------------ src/coreclr/tests/issues.targets | 3 -- .../tests/ProducerConsumerCollectionTests.cs | 1 - .../System.Drawing.Common/tests/FontTests.cs | 2 -- .../tests/AssemblyInfo.cs | 6 ---- .../System.Net.HttpListener.Tests.csproj | 1 - .../tests/RevocationTests/AiaTests.cs | 1 - src/tests/JIT/opt/OSR/tailrecursetry.csproj | 4 +++ .../unittest/getappdomainstaticaddress.csproj | 4 --- 12 files changed, 38 insertions(+), 46 deletions(-) delete mode 100644 src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml index faa5ab29e300..58bcd933f3da 100644 --- a/eng/pipelines/libraries/run-test-job.yml +++ b/eng/pipelines/libraries/run-test-job.yml @@ -143,10 +143,7 @@ jobs: - jitstress2 - jitstress2_tiered - zapdisable - # tailcallstress currently has hundreds of failures on Linux/arm32, so disable it. - # Tracked by https://github.com/dotnet/runtime/issues/38892. - - ${{ if or(eq(parameters.osGroup, 'Windows_NT'), ne(parameters.archType, 'arm')) }}: - - tailcallstress + - tailcallstress ${{ if in(parameters.coreclrTestGroup, 'jitstressregs' ) }}: scenarios: - jitstressregs1 diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 7e2536573072..5c3a94395db6 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -4201,6 +4201,7 @@ struct GenTreeCall final : public GenTree #define GTF_CALL_M_ALLOC_SIDE_EFFECTS 0x00400000 // GT_CALL -- this is a call to an allocator with side effects #define GTF_CALL_M_SUPPRESS_GC_TRANSITION 0x00800000 // GT_CALL -- suppress the GC transition (i.e. during a pinvoke) but a separate GC safe point is required. #define GTF_CALL_M_EXP_RUNTIME_LOOKUP 0x01000000 // GT_CALL -- this call needs to be tranformed into CFG for the dynamic dictionary expansion feature. +#define GTF_CALL_M_STRESS_TAILCALL 0x02000000 // GT_CALL -- the call is NOT "tail" prefixed but GTF_CALL_M_EXPLICIT_TAILCALL was added because of tail call stress mode // clang-format on @@ -4315,6 +4316,13 @@ struct GenTreeCall final : public GenTree return (gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0; } + // Returns true if this call didn't have an explicit tail. prefix in the IL + // but was marked as an explicit tail call because of tail call stress mode. + bool IsStressTailCall() const + { + return (gtCallMoreFlags & GTF_CALL_M_STRESS_TAILCALL) != 0; + } + // This method returning "true" implies that tail call flowgraph morhphing has // performed final checks and committed to making a tail call. bool IsTailCall() const diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 2823851cd094..f03f63943120 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -7526,11 +7526,13 @@ enum PREFIX_TAILCALL_EXPLICIT = 0x00000001, // call has "tail" IL prefix PREFIX_TAILCALL_IMPLICIT = 0x00000010, // call is treated as having "tail" prefix even though there is no "tail" IL prefix - PREFIX_TAILCALL = (PREFIX_TAILCALL_EXPLICIT | PREFIX_TAILCALL_IMPLICIT), - PREFIX_VOLATILE = 0x00000100, - PREFIX_UNALIGNED = 0x00001000, - PREFIX_CONSTRAINED = 0x00010000, - PREFIX_READONLY = 0x00100000 + PREFIX_TAILCALL_STRESS = + 0x00000100, // call doesn't "tail" IL prefix but is treated as explicit because of tail call stress + PREFIX_TAILCALL = (PREFIX_TAILCALL_EXPLICIT | PREFIX_TAILCALL_IMPLICIT | PREFIX_TAILCALL_STRESS), + PREFIX_VOLATILE = 0x00001000, + PREFIX_UNALIGNED = 0x00010000, + PREFIX_CONSTRAINED = 0x00100000, + PREFIX_READONLY = 0x01000000 }; /******************************************************************************** @@ -8674,6 +8676,7 @@ var_types Compiler::impImportCall(OPCODE opcode, { const bool isExplicitTailCall = (tailCallFlags & PREFIX_TAILCALL_EXPLICIT) != 0; const bool isImplicitTailCall = (tailCallFlags & PREFIX_TAILCALL_IMPLICIT) != 0; + const bool isStressTailCall = (tailCallFlags & PREFIX_TAILCALL_STRESS) != 0; // Exactly one of these should be true. assert(isExplicitTailCall != isImplicitTailCall); @@ -8740,6 +8743,12 @@ var_types Compiler::impImportCall(OPCODE opcode, // for in-lining. call->AsCall()->gtCallMoreFlags |= GTF_CALL_M_EXPLICIT_TAILCALL; JITDUMP("\nGTF_CALL_M_EXPLICIT_TAILCALL set for call [%06u]\n", dspTreeID(call)); + + if (isStressTailCall) + { + call->AsCall()->gtCallMoreFlags |= GTF_CALL_M_STRESS_TAILCALL; + JITDUMP("\nGTF_CALL_M_STRESS_TAILCALL set for call [%06u]\n", dspTreeID(call)); + } } else { @@ -14209,6 +14218,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Stress the tailcall. JITDUMP(" (Tailcall stress: prefixFlags |= PREFIX_TAILCALL_EXPLICIT)"); prefixFlags |= PREFIX_TAILCALL_EXPLICIT; + prefixFlags |= PREFIX_TAILCALL_STRESS; } else { diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index ea30779946ef..b173993d6bb5 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -7235,7 +7235,7 @@ GenTree* Compiler::fgMorphPotentialTailCall(GenTreeCall* call) // We still must check for any struct parameters and set 'hasStructParam' // so that we won't transform the recursive tail call into a loop. // - if (call->IsImplicitTailCall()) + if (call->IsImplicitTailCall() || call->IsStressTailCall()) { if (varDsc->lvHasLdAddrOp && !lvaIsImplicitByRefLocal(varNum)) { @@ -8793,7 +8793,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) assert(!call->CanTailCall()); #if FEATURE_MULTIREG_RET - if (fgGlobalMorph && call->HasMultiRegRetVal()) + if (fgGlobalMorph && call->HasMultiRegRetVal() && varTypeIsStruct(call->TypeGet())) { // The tail call has been rejected so we must finish the work deferred // by impFixupCallStructReturn for multi-reg-returning calls and transform @@ -8810,23 +8810,14 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) lvaGrabTemp(false DEBUGARG("Return value temp for multi-reg return (rejected tail call).")); lvaTable[tmpNum].lvIsMultiRegRet = true; - GenTree* assg = nullptr; - if (varTypeIsStruct(call->TypeGet())) - { - CORINFO_CLASS_HANDLE structHandle = call->gtRetClsHnd; - assert(structHandle != NO_CLASS_HANDLE); - const bool unsafeValueClsCheck = false; - lvaSetStruct(tmpNum, structHandle, unsafeValueClsCheck); - var_types structType = lvaTable[tmpNum].lvType; - GenTree* dst = gtNewLclvNode(tmpNum, structType); - assg = gtNewAssignNode(dst, call); - } - else - { - assg = gtNewTempAssign(tmpNum, call); - } - - assg = fgMorphTree(assg); + CORINFO_CLASS_HANDLE structHandle = call->gtRetClsHnd; + assert(structHandle != NO_CLASS_HANDLE); + const bool unsafeValueClsCheck = false; + lvaSetStruct(tmpNum, structHandle, unsafeValueClsCheck); + var_types structType = lvaTable[tmpNum].lvType; + GenTree* dst = gtNewLclvNode(tmpNum, structType); + GenTree* assg = gtNewAssignNode(dst, call); + assg = fgMorphTree(assg); // Create the assignment statement and insert it before the current statement. Statement* assgStmt = gtNewStmt(assg, compCurStmt->GetILOffsetX()); diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index e6c8104ed557..a2f45d4d1401 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -67,9 +67,6 @@ https://github.com/dotnet/runtime/issues/5933 - - https://github.com/dotnet/runtime/issues/8017 - https://github.com/dotnet/runtime/issues/11213 diff --git a/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs b/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs index c6393faa9359..ef699764e421 100644 --- a/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs +++ b/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs @@ -98,7 +98,6 @@ public void Ctor_InitializeFromCollection_ContainsExpectedItems(int numItems) } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/39398", RuntimeTestModes.TailcallStress)] public void Add_TakeFromAnotherThread_ExpectedItemsTaken() { IProducerConsumerCollection c = CreateProducerConsumerCollection(); diff --git a/src/libraries/System.Drawing.Common/tests/FontTests.cs b/src/libraries/System.Drawing.Common/tests/FontTests.cs index 067ff89a7be6..f731cdb9ddad 100644 --- a/src/libraries/System.Drawing.Common/tests/FontTests.cs +++ b/src/libraries/System.Drawing.Common/tests/FontTests.cs @@ -784,7 +784,6 @@ public void SizeInPoints_Get_ReturnsExpected(GraphicsUnit unit) [InlineData(FontStyle.Strikeout | FontStyle.Bold | FontStyle.Italic, 255, true, "@", 700)] [InlineData(FontStyle.Regular, 0, false, "", 400)] [InlineData(FontStyle.Regular, 10, false, "", 400)] - [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38889", RuntimeTestModes.TailcallStress)] public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSet, bool gdiVerticalFont, string expectedNamePrefix, int expectedWeight) { using (FontFamily family = FontFamily.GenericMonospace) @@ -818,7 +817,6 @@ public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSe [InlineData(TextRenderingHint.SingleBitPerPixel)] [InlineData(TextRenderingHint.SingleBitPerPixelGridFit)] [InlineData(TextRenderingHint.ClearTypeGridFit)] - [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38889", RuntimeTestModes.TailcallStress)] public void ToLogFont_InvokeGraphics_ReturnsExpected(TextRenderingHint textRenderingHint) { using (FontFamily family = FontFamily.GenericMonospace) diff --git a/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs b/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs deleted file mode 100644 index 5bfc6fc542f5..000000000000 --- a/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -[assembly: SkipOnCoreClr("https://github.com/dotnet/runtime/issues/39309", RuntimeTestModes.TailcallStress)] diff --git a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj index 9da20596f814..3d8ebf1e50be 100644 --- a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj +++ b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj @@ -5,7 +5,6 @@ $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX - diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs index d05290b14d41..bfdb42328a73 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs @@ -42,7 +42,6 @@ public static void EmptyAiaResponseIsIgnored() } [Fact] - [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38887", RuntimeTestModes.TailcallStress)] public static void DisableAiaOptionWorks() { CertificateAuthority.BuildPrivatePki( diff --git a/src/tests/JIT/opt/OSR/tailrecursetry.csproj b/src/tests/JIT/opt/OSR/tailrecursetry.csproj index 9620f75474a9..c79a0af1d255 100644 --- a/src/tests/JIT/opt/OSR/tailrecursetry.csproj +++ b/src/tests/JIT/opt/OSR/tailrecursetry.csproj @@ -3,6 +3,10 @@ Exe True + + true diff --git a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj index c5769302e859..09f11fb4e527 100644 --- a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj +++ b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj @@ -6,10 +6,6 @@ true 0 true - - true true From 89073400fd3c3bf4a61ff8e131b3a16b68b010e7 Mon Sep 17 00:00:00 2001 From: lindexi Date: Sat, 15 Aug 2020 11:37:53 +0800 Subject: [PATCH 521/755] Ignore the executable file be deleted in Process Start (#40748) --- .../src/System/Diagnostics/Process.OSX.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs index cab74e4ebcf4..1028d215e03f 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs @@ -92,9 +92,18 @@ private int ParentProcessId } /// Gets the path to the current executable, or null if it could not be retrieved. - private static string GetExePath() + private static string? GetExePath() { - return Interop.libproc.proc_pidpath(Environment.ProcessId); + try + { + return Interop.libproc.proc_pidpath(Environment.ProcessId); + } + catch (Win32Exception) + { + // It will throw System.ComponentModel.Win32Exception (2): No such file or Directory when + // the executable file is deleted. + return null; + } } // ---------------------------------- From 1d6fc683c6a7c5b9bb65ca293366a8b5090de4ba Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 14 Aug 2020 20:45:52 -0700 Subject: [PATCH 522/755] Fix stack overflow createdump triggering on Windows (#40869) --- src/coreclr/src/vm/eepolicy.cpp | 4 +++- src/coreclr/src/vm/excep.cpp | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/vm/eepolicy.cpp b/src/coreclr/src/vm/eepolicy.cpp index c6ca684c1437..0440e639edfd 100644 --- a/src/coreclr/src/vm/eepolicy.cpp +++ b/src/coreclr/src/vm/eepolicy.cpp @@ -583,7 +583,9 @@ void DisplayStackOverflowException() DWORD LogStackOverflowStackTraceThread(void* arg) { LogCallstackForLogWorker((Thread*)arg); - +#ifdef HOST_WINDOWS + CreateCrashDumpIfEnabled(); +#endif return 0; } diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 9d672c83010b..97659d38f086 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -4119,10 +4119,11 @@ LaunchCreateDump(LPCWSTR lpCommandLine) void CreateCrashDumpIfEnabled() { - // If enabled, launch the create minidump utility and wait until it completes - if (g_createDumpCommandLine != nullptr) + // If enabled, launch the create minidump utility and wait until it completes. Only launch createdump once for this process. + LPCWSTR createDumpCommandLine = InterlockedExchangeT(&g_createDumpCommandLine, nullptr); + if (createDumpCommandLine != nullptr) { - LaunchCreateDump(g_createDumpCommandLine); + LaunchCreateDump(createDumpCommandLine); } } From 1dbdb8b78738a6da37ac2ea1937b1e16aef7937a Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 14 Aug 2020 20:58:30 -0700 Subject: [PATCH 523/755] Move Font*, Image* and Margins converters to System.Drawing.Common and apply Unit and Name converter (#40825) * Move Font, Image, and Margins converters to System.Drawing.Common * Add FontUnit converter and FontName converter to Font properties * Fix Unix tests * Sort Compile items --- .../ref/System.Drawing.Common.cs | 93 ++++++-- .../src/Resources/Strings.resx | 6 + .../src/System.Drawing.Common.csproj | 7 + .../src/System/Drawing/Font.cs | 6 +- .../src/System/Drawing/FontConverter.cs | 69 +++--- .../src/System/Drawing/Icon.Unix.cs | 4 +- .../src/System/Drawing/Icon.Windows.cs | 4 +- .../src/System/Drawing/IconConverter.cs | 2 +- .../src/System/Drawing/Image.cs | 4 +- .../src/System/Drawing/ImageConverter.cs | 20 +- .../System/Drawing/ImageFormatConverter.cs | 20 +- .../src/System/Drawing/Imaging/ImageFormat.cs | 4 +- .../src/System/Drawing/Printing/Margins.cs | 4 +- .../Drawing/Printing/MarginsConverter.cs | 22 +- .../tests/System.Drawing.Common.Tests.csproj | 7 + .../System/Drawing/FontConverterTests.cs | 201 ++++++++++++++++++ .../System/Drawing/IconConverterTests.cs | 0 .../System/Drawing/ImageConverterTests.cs | 0 .../Drawing/ImageFormatConverterTests.cs | 0 .../Drawing/Printing/MarginsConverterTests.cs | 0 .../ref/System.Windows.Extensions.Forwards.cs | 11 + .../ref/System.Windows.Extensions.cs | 71 ------- .../ref/System.Windows.Extensions.csproj | 4 + .../src/ExcludeApiList.PNSE.txt | 7 + .../src/Resources/Strings.resx | 6 - .../src/System.Windows.Extensions.csproj | 19 +- .../src/TypeForwards.cs | 8 + .../System.Windows.Extensions.Tests.csproj | 5 - .../System/Drawing/FontConverterTests.cs | 166 --------------- 29 files changed, 414 insertions(+), 356 deletions(-) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/src/System/Drawing/FontConverter.cs (88%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/src/System/Drawing/IconConverter.cs (97%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/src/System/Drawing/ImageConverter.cs (90%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/src/System/Drawing/ImageFormatConverter.cs (89%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/src/System/Drawing/Printing/MarginsConverter.cs (90%) create mode 100644 src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/tests/System/Drawing/IconConverterTests.cs (100%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/tests/System/Drawing/ImageConverterTests.cs (100%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/tests/System/Drawing/ImageFormatConverterTests.cs (100%) rename src/libraries/{System.Windows.Extensions => System.Drawing.Common}/tests/System/Drawing/Printing/MarginsConverterTests.cs (100%) create mode 100644 src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.Forwards.cs create mode 100644 src/libraries/System.Windows.Extensions/src/ExcludeApiList.PNSE.txt create mode 100644 src/libraries/System.Windows.Extensions/src/TypeForwards.cs delete mode 100644 src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs diff --git a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs index 463ccfd5d00e..ca1dd6121210 100644 --- a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs +++ b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs @@ -268,9 +268,7 @@ public enum CopyPixelOperation Whiteness = 16711778, CaptureBlt = 1073741824, } -#if NETCOREAPP - [System.ComponentModel.TypeConverterAttribute("System.Drawing.FontConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.FontConverter))] public sealed partial class Font : System.MarshalByRefObject, System.ICloneable, System.IDisposable, System.Runtime.Serialization.ISerializable { public Font(System.Drawing.Font prototype, System.Drawing.FontStyle newStyle) { } @@ -301,6 +299,7 @@ public Font(string familyName, float emSize, System.Drawing.GraphicsUnit unit) { [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public bool Italic { get { throw null; } } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.FontConverter.FontNameConverter))] public string Name { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] public string? OriginalFontName { get { throw null; } } @@ -315,6 +314,7 @@ public Font(string familyName, float emSize, System.Drawing.GraphicsUnit unit) { public string SystemFontName { get { throw null; } } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public bool Underline { get { throw null; } } + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.FontConverter.FontUnitConverter))] public System.Drawing.GraphicsUnit Unit { get { throw null; } } public object Clone() { throw null; } public void Dispose() { } @@ -334,6 +334,33 @@ public void ToLogFont(object logFont) { } public void ToLogFont(object logFont, System.Drawing.Graphics graphics) { } public override string ToString() { throw null; } } + public partial class FontConverter : System.ComponentModel.TypeConverter + { + public FontConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type? sourceType) { throw null; } + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) { throw null; } + public override object? ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; } + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; } + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext? context, System.Collections.IDictionary propertyValues) { throw null; } + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext? context, object? value, System.Attribute[]? attributes) { throw null; } + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } + public sealed partial class FontNameConverter : System.ComponentModel.TypeConverter, System.IDisposable + { + public FontNameConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type? sourceType) { throw null; } + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; } + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + void System.IDisposable.Dispose() { } + } + public partial class FontUnitConverter : System.ComponentModel.EnumConverter + { + public FontUnitConverter() : base (default(System.Type)) { } + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + } + } public sealed partial class FontFamily : System.MarshalByRefObject, System.IDisposable { public FontFamily(System.Drawing.Text.GenericFontFamilies genericFamily) { } @@ -629,9 +656,7 @@ public enum GraphicsUnit Document = 5, Millimeter = 6, } -#if NETCOREAPP - [System.ComponentModel.TypeConverterAttribute("System.Drawing.IconConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.IconConverter))] public sealed partial class Icon : System.MarshalByRefObject, System.ICloneable, System.IDisposable, System.Runtime.Serialization.ISerializable { public Icon(System.Drawing.Icon original, System.Drawing.Size size) { } @@ -660,15 +685,21 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser public System.Drawing.Bitmap ToBitmap() { throw null; } public override string ToString() { throw null; } } + public partial class IconConverter : System.ComponentModel.ExpandableObjectConverter + { + public IconConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } + } public partial interface IDeviceContext : System.IDisposable { System.IntPtr GetHdc(); void ReleaseHdc(); } [System.ComponentModel.ImmutableObjectAttribute(true)] -#if NETCOREAPP - [System.ComponentModel.TypeConverterAttribute("System.Drawing.ImageConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.ImageConverter))] public abstract partial class Image : System.MarshalByRefObject, System.ICloneable, System.IDisposable, System.Runtime.Serialization.ISerializable { internal Image() { } @@ -742,6 +773,26 @@ public static void StopAnimate(System.Drawing.Image image, System.EventHandler o public static void UpdateFrames() { } public static void UpdateFrames(System.Drawing.Image image) { } } + public partial class ImageConverter : System.ComponentModel.TypeConverter + { + public ImageConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type? sourceType) { throw null; } + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) { throw null; } + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; } + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; } + public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext? context, object? value, System.Attribute[]? attributes) { throw null; } + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + } + public partial class ImageFormatConverter : System.ComponentModel.TypeConverter + { + public ImageFormatConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type? sourceType) { throw null; } + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) { throw null; } + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; } + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; } + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + } public sealed partial class Pen : System.MarshalByRefObject, System.ICloneable, System.IDisposable { public Pen(System.Drawing.Brush brush) { } @@ -961,7 +1012,7 @@ public void Intersect(System.Drawing.Region region) { } public bool IsVisible(System.Drawing.Rectangle rect, System.Drawing.Graphics? g) { throw null; } public bool IsVisible(System.Drawing.RectangleF rect) { throw null; } public bool IsVisible(System.Drawing.RectangleF rect, System.Drawing.Graphics? g) { throw null; } - public bool IsVisible(int x, int y, System.Drawing.Graphics g) { throw null; } + public bool IsVisible(int x, int y, System.Drawing.Graphics? g) { throw null; } public bool IsVisible(int x, int y, int width, int height) { throw null; } public bool IsVisible(int x, int y, int width, int height, System.Drawing.Graphics? g) { throw null; } public bool IsVisible(float x, float y) { throw null; } @@ -2292,9 +2343,7 @@ public enum ImageFlags ReadOnly = 65536, Caching = 131072, } -#if NETCOREAPP - [System.ComponentModel.TypeConverterAttribute("System.Drawing.ImageFormatConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.ImageFormatConverter))] public sealed partial class ImageFormat { public ImageFormat(System.Guid guid) { } @@ -2491,9 +2540,7 @@ public InvalidPrinterException(System.Drawing.Printing.PrinterSettings settings) protected InvalidPrinterException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } -#if NETCOREAPP - [System.ComponentModel.TypeConverterAttribute("System.Drawing.Printing.MarginsConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverterAttribute(typeof(System.Drawing.Printing.MarginsConverter))] public partial class Margins : System.ICloneable { public Margins() { } @@ -2505,10 +2552,20 @@ public Margins(int left, int right, int top, int bottom) { } public object Clone() { throw null; } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(System.Drawing.Printing.Margins m1, System.Drawing.Printing.Margins m2) { throw null; } - public static bool operator !=(System.Drawing.Printing.Margins m1, System.Drawing.Printing.Margins m2) { throw null; } + public static bool operator ==(System.Drawing.Printing.Margins? m1, System.Drawing.Printing.Margins? m2) { throw null; } + public static bool operator !=(System.Drawing.Printing.Margins? m1, System.Drawing.Printing.Margins? m2) { throw null; } public override string ToString() { throw null; } } + public partial class MarginsConverter : System.ComponentModel.ExpandableObjectConverter + { + public MarginsConverter() { } + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type? sourceType) { throw null; } + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) { throw null; } + public override object? ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; } + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; } + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext? context, System.Collections.IDictionary propertyValues) { throw null; } + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext? context) { throw null; } + } public partial class PageSettings : System.ICloneable { public PageSettings() { } diff --git a/src/libraries/System.Drawing.Common/src/Resources/Strings.resx b/src/libraries/System.Drawing.Common/src/Resources/Strings.resx index f5ba77ee8ed3..1b718caf5ad6 100644 --- a/src/libraries/System.Drawing.Common/src/Resources/Strings.resx +++ b/src/libraries/System.Drawing.Common/src/Resources/Strings.resx @@ -262,6 +262,9 @@ Value of '{1}' is not valid for '{0}'. + + + Value of '{0}' is not valid for font size unit. Value of '{1}' is not valid for '{0}'. '{0}' should be greater than {2} and less than or equal to {3}. @@ -437,6 +440,9 @@ Operation not implemented under X11 + + (none) + No valid icon image found diff --git a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj index a2a362564252..516a194705c0 100644 --- a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -25,7 +25,10 @@ + + + @@ -116,6 +119,7 @@ + @@ -130,6 +134,7 @@ + @@ -158,6 +163,8 @@ Link="Common\Interop\Windows\User32\Interop.LOGFONT.cs" /> + System.Drawing.DefaultComponent.bmp diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs index 3b0665b32c5f..106653389c38 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs @@ -13,9 +13,7 @@ namespace System.Drawing /// /// Defines a particular format for text, including font face, size, and style attributes. /// -#if NETCOREAPP - [TypeConverter("System.Drawing.FontConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [TypeConverter(typeof(FontConverter))] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, ISerializable @@ -76,11 +74,13 @@ public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, /// Gets the face name of this . /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(FontConverter.FontNameConverter))] public string Name => FontFamily.Name; /// /// Gets the unit of measure for this . /// + [TypeConverter(typeof(FontConverter.FontUnitConverter))] public GraphicsUnit Unit => _fontUnit; /// diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs similarity index 88% rename from src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs index 0a1032379848..99a327b2ba50 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs @@ -4,6 +4,7 @@ using System.Collections; using System.ComponentModel; using System.ComponentModel.Design.Serialization; +using System.Diagnostics; using System.Drawing.Text; using System.Globalization; using System.Reflection; @@ -15,17 +16,17 @@ public class FontConverter : TypeConverter { private const string StylePrefix = "style="; - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type? sourceType) { - return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType); + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) { return (destinationType == typeof(string)) || (destinationType == typeof(InstanceDescriptor)); } - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (value is Font font) { @@ -86,7 +87,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul if (destinationType == typeof(InstanceDescriptor)) { - ConstructorInfo met = typeof(Font).GetTypeInfo().GetConstructor(new Type[] { typeof(string), typeof(float), typeof(FontStyle), typeof(GraphicsUnit) }); + ConstructorInfo? met = typeof(Font).GetTypeInfo().GetConstructor(new Type[] { typeof(string), typeof(float), typeof(FontStyle), typeof(GraphicsUnit) }); object[] args = new object[4]; args[0] = font.Name; args[1] = font.Size; @@ -100,7 +101,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul return base.ConvertTo(context, culture, value, destinationType); } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (!(value is string font)) { @@ -123,8 +124,8 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c char separator = culture.TextInfo.ListSeparator[0]; // For vi-VN: ',' string fontName = font; // start with the assumption that only the font name was provided. - string style = null; - string sizeStr = null; + string? style = null; + string? sizeStr = null; float fontSize = 8.25f; FontStyle fontStyle = FontStyle.Regular; GraphicsUnit units = GraphicsUnit.Point; @@ -161,7 +162,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c } // Parse size. - (string size, string unit) unitTokens = ParseSizeTokens(sizeStr, separator); + (string? size, string? unit) unitTokens = ParseSizeTokens(sizeStr, separator); if (unitTokens.size != null) { @@ -208,10 +209,10 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c return new Font(fontName, fontSize, fontStyle, units); } - private (string, string) ParseSizeTokens(string text, char separator) + private (string?, string?) ParseSizeTokens(string text, char separator) { - string size = null; - string units = null; + string? size = null; + string? units = null; text = text.Trim(); @@ -259,18 +260,23 @@ private GraphicsUnit ParseGraphicsUnits(string units) => "mm" => GraphicsUnit.Millimeter, "px" => GraphicsUnit.Pixel, "world" => GraphicsUnit.World, - _ => throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, units), nameof(units)), + _ => throw new ArgumentException(SR.Format(SR.InvalidArgumentValueFontConverter, units), nameof(units)), }; - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) + public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues) { - object value; + if (propertyValues == null) + { + throw new ArgumentNullException(nameof(propertyValues)); + } + + object? value; byte charSet = 1; float size = 8; - string name = null; + string? name = null; bool vertical = false; FontStyle style = FontStyle.Regular; - FontFamily fontFamily = null; + FontFamily? fontFamily = null; GraphicsUnit unit = GraphicsUnit.Point; if ((value = propertyValues["GdiCharSet"]) != null) @@ -352,12 +358,12 @@ public override object CreateInstance(ITypeDescriptorContext context, IDictionar return new Font(fontFamily, size, style, unit, charSet, vertical); } - public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) => true; + public override bool GetCreateInstanceSupported(ITypeDescriptorContext? context) => true; public override PropertyDescriptorCollection GetProperties( - ITypeDescriptorContext context, - object value, - Attribute[] attributes) + ITypeDescriptorContext? context, + object? value, + Attribute[]? attributes) { return value is Font ? TypeDescriptor.GetProperties(value, attributes) : base.GetProperties(context, value, attributes); } @@ -377,17 +383,17 @@ void IDisposable.Dispose() { } - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type? sourceType) { return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType); } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { return value is string strValue ? MatchFontName(strValue, context) : base.ConvertFrom(context, culture, value); } - public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { string[] values = new string[_fonts.Length]; for (int i = 0; i < _fonts.Length; i++) @@ -400,18 +406,20 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex } // We allow other values other than those in the font list. - public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => false; + public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => false; // Yes, we support picking an element from the list. - public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true; + public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true; - private string MatchFontName(string name, ITypeDescriptorContext context) + private string MatchFontName(string name, ITypeDescriptorContext? context) { // Try a partial match - string bestMatch = null; + string? bestMatch = null; - foreach (string fontName in GetStandardValues(context)) + // setting fontName as nullable since IEnumerable.Current returned nullable in 3.0 + foreach (string? fontName in GetStandardValues(context)) { + Debug.Assert(fontName != null); if (fontName.Equals(name, StringComparison.InvariantCultureIgnoreCase)) { // For an exact match, return immediately @@ -435,12 +443,13 @@ public class FontUnitConverter : EnumConverter { public FontUnitConverter() : base(typeof(GraphicsUnit)) { } - public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { // display graphic unit is not supported. if (Values == null) { base.GetStandardValues(context); // sets "values" + Debug.Assert(Values != null); ArrayList filteredValues = new ArrayList(Values); filteredValues.Remove(GraphicsUnit.Display); Values = new StandardValuesCollection(filteredValues); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs index 04ed13140fdb..c5288cc6744d 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs @@ -44,9 +44,7 @@ namespace System.Drawing { -#if NETCOREAPP - [System.ComponentModel.TypeConverter("System.Drawing.IconConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [System.ComponentModel.TypeConverter(typeof(IconConverter))] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class Icon : MarshalByRefObject, ISerializable, ICloneable, IDisposable diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs index 34c84087194c..6ade4a7267cd 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs @@ -13,9 +13,7 @@ namespace System.Drawing { -#if NETCOREAPP - [TypeConverter("System.Drawing.IconConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [TypeConverter(typeof(IconConverter))] [Serializable] [TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed partial class Icon : MarshalByRefObject, ICloneable, IDisposable, ISerializable diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/IconConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/IconConverter.cs similarity index 97% rename from src/libraries/System.Windows.Extensions/src/System/Drawing/IconConverter.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/IconConverter.cs index b1c01da338b7..48803c35261d 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/IconConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/IconConverter.cs @@ -35,7 +35,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } else if (value is Icon) { - return value.ToString(); + return value.ToString()!; } } else if (destinationType == typeof(byte[])) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs index 23f795b4e947..d6b2d3cc91dd 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs @@ -17,9 +17,7 @@ namespace System.Drawing [ImmutableObject(true)] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] -#if NETCOREAPP - [TypeConverter("System.Drawing.ImageConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [TypeConverter(typeof(ImageConverter))] public abstract partial class Image : MarshalByRefObject, IDisposable, ICloneable, ISerializable { // The signature of this delegate is incorrect. The signature of the corresponding diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/ImageConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageConverter.cs similarity index 90% rename from src/libraries/System.Windows.Extensions/src/System/Drawing/ImageConverter.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/ImageConverter.cs index 4b6f0194ab43..710ce1d4381b 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/ImageConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageConverter.cs @@ -17,17 +17,17 @@ public class ImageConverter : TypeConverter private static ReadOnlySpan BMBytes => new byte[] { (byte)'B', (byte)'M' }; - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type? sourceType) { return sourceType == typeof(byte[]) || sourceType == typeof(Icon); } - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) { return destinationType == typeof(byte[]) || destinationType == typeof(string); } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is Icon icon) { @@ -47,7 +47,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c } } - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (destinationType == typeof(string)) { @@ -57,7 +57,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } else if (value is Image) { - return value.ToString(); + return value.ToString()!; } } else if (destinationType == typeof(byte[])) @@ -79,7 +79,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul // If we don't find an Encoder (for things like Icon), we // just switch back to PNG. - ImageCodecInfo codec = FindEncoder(dest) ?? FindEncoder(ImageFormat.Png); + ImageCodecInfo codec = FindEncoder(dest) ?? FindEncoder(ImageFormat.Png)!; image.Save(ms, codec, null); return ms.ToArray(); } @@ -90,7 +90,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } // Find any random encoder which supports this format. - private static ImageCodecInfo FindEncoder(ImageFormat imageformat) + private static ImageCodecInfo? FindEncoder(ImageFormat imageformat) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); foreach (ImageCodecInfo codec in codecs) @@ -101,14 +101,14 @@ private static ImageCodecInfo FindEncoder(ImageFormat imageformat) return null; } - public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object? value, Attribute[]? attributes) { return TypeDescriptor.GetProperties(typeof(Image), attributes); } - public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true; + public override bool GetPropertiesSupported(ITypeDescriptorContext? context) => true; - private unsafe Stream GetBitmapStream(ReadOnlySpan rawData) + private unsafe Stream? GetBitmapStream(ReadOnlySpan rawData) { try { diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/ImageFormatConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageFormatConverter.cs similarity index 89% rename from src/libraries/System.Windows.Extensions/src/System/Drawing/ImageFormatConverter.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/ImageFormatConverter.cs index 02ab96eaacf4..908477d27beb 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/ImageFormatConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageFormatConverter.cs @@ -11,12 +11,12 @@ namespace System.Drawing { public class ImageFormatConverter : TypeConverter { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type? sourceType) { - return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType); + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) { if ((destinationType == typeof(string)) || (destinationType == typeof(InstanceDescriptor))) { @@ -25,10 +25,10 @@ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinati return base.CanConvertTo(context, destinationType); } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { // we must be able to convert from short names and long names - string strFormat = value as string; + string? strFormat = value as string; if (strFormat == null) { // case #1, this is not a string @@ -66,7 +66,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c throw new FormatException(SR.Format(SR.ConvertInvalidPrimitive, strFormat, nameof(ImageFormat))); } - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (value is ImageFormat imgFormat) { @@ -77,7 +77,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul if (destinationType == typeof(InstanceDescriptor)) { - string strFormat = null; + string? strFormat = null; if (imgFormat.Guid.Equals(ImageFormat.Bmp.Guid)) strFormat = "Bmp"; else if (imgFormat.Guid.Equals(ImageFormat.Emf.Guid)) @@ -105,7 +105,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } else { - ConstructorInfo ctor = typeof(ImageFormat).GetTypeInfo().GetConstructor(new Type[] { typeof(Guid) }); + ConstructorInfo? ctor = typeof(ImageFormat).GetTypeInfo().GetConstructor(new Type[] { typeof(Guid) }); return new InstanceDescriptor(ctor, new object[] { imgFormat.Guid }); } } @@ -114,7 +114,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul return base.ConvertTo(context, culture, value, destinationType); } - public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { return new TypeConverter.StandardValuesCollection(new ImageFormat[] { @@ -131,6 +131,6 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex }); } - public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true; + public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true; } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/ImageFormat.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/ImageFormat.cs index 34c55614f6a8..7107d21b9b6f 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/ImageFormat.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/ImageFormat.cs @@ -8,9 +8,7 @@ namespace System.Drawing.Imaging /// /// Specifies the format of the image. /// -#if NETCOREAPP - [TypeConverter("System.Drawing.ImageFormatConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [TypeConverter(typeof(ImageFormatConverter))] public sealed class ImageFormat { // Format IDs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/Margins.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/Margins.cs index 011b543ddb68..48415cc0b3bf 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/Margins.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/Margins.cs @@ -10,9 +10,7 @@ namespace System.Drawing.Printing /// /// Specifies the margins of a printed page. /// -#if NETCOREAPP - [TypeConverter("System.Drawing.Printing.MarginsConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] -#endif + [TypeConverter(typeof(MarginsConverter))] public partial class Margins : ICloneable { private int _left; diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/Printing/MarginsConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs similarity index 90% rename from src/libraries/System.Windows.Extensions/src/System/Drawing/Printing/MarginsConverter.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs index f693df719d9f..2431fde5eac1 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/Printing/MarginsConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs @@ -19,7 +19,7 @@ public class MarginsConverter : ExpandableObjectConverter /// Determines if a converter can convert an object of the given source /// type to the native type of the converter. /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type? sourceType) { if (sourceType == typeof(string)) { @@ -32,7 +32,7 @@ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceT /// Gets a value indicating whether this converter can /// convert an object to the given destination type using the context. /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) { if (destinationType == typeof(InstanceDescriptor)) { @@ -44,7 +44,7 @@ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinati /// /// Converts the given object to the converter's native type. /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string strValue) { @@ -87,7 +87,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c /// type is string. If this cannot convert to the desitnation type, this will /// throw a NotSupportedException. /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (destinationType == null) { @@ -116,7 +116,7 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul } if (destinationType == typeof(InstanceDescriptor)) { - ConstructorInfo ctor = typeof(Margins).GetConstructor(new Type[] { + ConstructorInfo? ctor = typeof(Margins).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int)}); if (ctor != null) @@ -133,24 +133,24 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul /// Determines if changing a value on this object should require a call to /// CreateInstance to create a new value. /// - public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) => true; + public override bool GetCreateInstanceSupported(ITypeDescriptorContext? context) => true; /// /// Creates an instance of this type given a set of property values /// for the object. This is useful for objects that are immutable, but still /// want to provide changable properties. /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) + public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues) { if (propertyValues == null) { throw new ArgumentNullException(nameof(propertyValues)); } - object left = propertyValues["Left"]; - object right = propertyValues["Right"]; - object top = propertyValues["Top"]; - object bottom = propertyValues["Bottom"]; + object? left = propertyValues["Left"]; + object? right = propertyValues["Right"]; + object? top = propertyValues["Top"]; + object? bottom = propertyValues["Bottom"]; if (left == null || right == null || bottom == null || top == null || !(left is int) || !(right is int) || !(bottom is int) || !(top is int)) diff --git a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj index 5537f87099e4..1371f91e3d1a 100644 --- a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj +++ b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj @@ -72,6 +72,11 @@ + + + + + @@ -89,6 +94,8 @@ + + System.Drawing.Tests.48x48_multiple_entries_4bit.ico diff --git a/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs new file mode 100644 index 000000000000..38f56c80f0d1 --- /dev/null +++ b/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.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. + +using System.Drawing; +using System.Drawing.Text; +using System.Globalization; +using System.Linq; +using Xunit; +using static System.Drawing.FontConverter; + +namespace System.ComponentModel.TypeConverterTests +{ + public class FontNameConverterTest + { + [ConditionalFact(Helpers.IsDrawingSupported)] + public void TestConvertFrom() + { + FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); + // returns "Times" under Linux and "Times New Roman" under Windows + if (PlatformDetection.IsWindows) + { + Assert.Equal("Times New Roman", converter.ConvertFrom("Times") as string); + } + else + { + Assert.Equal("Times", converter.ConvertFrom("Times") as string); + } + Assert.True(converter.GetStandardValuesSupported(), "standard values supported"); + Assert.False(converter.GetStandardValuesExclusive(), "standard values exclusive"); + } + + [ConditionalFact(Helpers.IsDrawingSupported)] + public void ExTestConvertFrom_ThrowsNotSupportedException() + { + FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); + Assert.Throws(() => converter.ConvertFrom(null)); + Assert.Throws(() => converter.ConvertFrom(1)); + } + } + + public class FontConverterTest + { + public static char s_Separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator[0]; + + [ConditionalTheory(Helpers.IsDrawingSupported)] + [MemberData(nameof(TestConvertFormData))] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Full Framework doesn't support inputs without units")] + public void TestConvertFrom(string input, string expectedName, float expectedSize, GraphicsUnit expectedUnits, FontStyle expectedFontStyle) + { + FontConverter converter = new FontConverter(); + Font font = (Font)converter.ConvertFrom(input); + + // Unix fonts + Assert.Equal(expectedName, font.Name); + Assert.Equal(expectedSize, font.Size); + Assert.Equal(expectedUnits, font.Unit); + Assert.Equal(expectedFontStyle, font.Style); + } + + [ConditionalTheory(Helpers.IsDrawingSupported)] + [MemberData(nameof(ArgumentExceptionFontConverterData))] + public void InvalidInputThrowsArgumentException(string input, string paramName, string netfxParamName) + { + FontConverter converter = new FontConverter(); + AssertExtensions.Throws(paramName, netfxParamName, () => converter.ConvertFrom(input)); + } + + [ConditionalTheory(Helpers.IsDrawingSupported)] + [MemberData(nameof(InvalidEnumArgumentExceptionFontConverterData))] + public void InvalidInputThrowsInvalidEnumArgumentException(string input, string paramName) + { + FontConverter converter = new FontConverter(); + Assert.Throws(paramName, () => converter.ConvertFrom(input)); + } + + [ConditionalFact(Helpers.IsDrawingSupported)] + public void EmptyStringInput() + { + FontConverter converter = new FontConverter(); + Font font = (Font)converter.ConvertFrom(string.Empty); + Assert.Null(font); + } + + public static TheoryData TestConvertFormData() + { + var data = PlatformDetection.IsWindows ? + new TheoryData() + { + { $"Courier New", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, + { $"Courier New{s_Separator} 11", "Courier New", 11f, GraphicsUnit.Point, FontStyle.Regular }, + { $"Arial{s_Separator} 11px", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, + { $"Courier New{s_Separator} 11 px", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, + { $"Courier New{s_Separator} 11 px{s_Separator} style=Regular", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, + { $"Courier New{s_Separator} style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, + { $"Courier New{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic }, + { $"Courier New{s_Separator} 11 px{s_Separator} style=Regular, Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular | FontStyle.Italic }, + { $"Courier New{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic{s_Separator} Strikeout", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, + { $"Arial{s_Separator} 11 px{s_Separator} style=Bold, Italic, Strikeout", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, + { $"11px", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, + { $"Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, + { $"arIAL{s_Separator} 10{s_Separator} style=bold", "Arial", 10f, GraphicsUnit.Point, FontStyle.Bold }, + { $"Arial{s_Separator} 10{s_Separator}", "Arial", 10f, GraphicsUnit.Point, FontStyle.Regular }, + { $"Arial{s_Separator}", "Arial", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, + { $"Arial{s_Separator} 10{s_Separator} style=12", "Arial", 10f, GraphicsUnit.Point, FontStyle.Underline | FontStyle.Strikeout }, + { $"Courier New{s_Separator} Style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. + { $"11px{s_Separator} Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Bold} + } + : new TheoryData() + { + // Unix has different fonts installed, let's use a default one. + { FontFamily.GenericSansSerif.Name, FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Regular }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Point, FontStyle.Regular }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Regular", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} style=Bold", FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Bold }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Regular, Italic", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular | FontStyle.Italic }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic{s_Separator} Strikeout", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, + { $"{FontFamily.GenericSansSerif.Name}{s_Separator} Style=Bold", FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. + }; + + if (PlatformDetection.IsWindows) + { + // FullFramework disregards all arguments if the font name is an empty string. + // Empty string is not an installed font on Windows 7, windows 8 and some versions of windows 10. + if (EmptyFontPresent) + { + data.Add($"{s_Separator} 10{s_Separator} style=bold", "", 10f, GraphicsUnit.Point, FontStyle.Bold); + } + else + { + data.Add($"{s_Separator} 10{s_Separator} style=bold", "Microsoft Sans Serif", 10f, GraphicsUnit.Point, FontStyle.Bold); + } + } + + return data; + } + + private static bool EmptyFontPresent + { + get + { + using (var installedFonts = new InstalledFontCollection()) + { + return installedFonts.Families.Select(t => t.Name).Contains(string.Empty); + } + } + } + + public static TheoryData ArgumentExceptionFontConverterData() => new TheoryData() + { + { $"Courier New{s_Separator} 11 px{s_Separator} type=Bold{s_Separator} Italic", "units", null }, + { $"Courier New{s_Separator} {s_Separator} Style=Bold", "value", null }, + { $"Courier New{s_Separator} 11{s_Separator} Style=", "value", null }, + { $"Courier New{s_Separator} 11{s_Separator} Style=RandomEnum", null, null }, + { $"Arial{s_Separator} 10{s_Separator} style=bold{s_Separator}", "value", null }, + { $"Arial{s_Separator} 10{s_Separator} style=null", null, null }, + { $"Arial{s_Separator} 10{s_Separator} style=abc#", null, null }, + { $"Arial{s_Separator} 10{s_Separator} style=##", null, null }, + { $"Arial{s_Separator} 10display{s_Separator} style=bold", null, null }, + { $"Arial{s_Separator} 10style{s_Separator} style=bold", "units", null }, + }; + + public static TheoryData InvalidEnumArgumentExceptionFontConverterData() => new TheoryData() + { + { $"Arial{s_Separator} 10{s_Separator} style=56", "style" }, + { $"Arial{s_Separator} 10{s_Separator} style=-1", "style" }, + }; + } + + public class FontUnitConverterTest + { + [ConditionalFact(Helpers.IsDrawingSupported)] + public void GetStandardValuesTest() + { + FontUnitConverter converter = new FontUnitConverter(); + var values = converter.GetStandardValues(); + Assert.Equal(6, values.Count); // The six supported values of Graphics unit: World, Pixel, Point, Inch, Document, Millimeter. + + foreach (var item in values) + { + Assert.NotEqual(GraphicsUnit.Display, (GraphicsUnit)item); + } + } + + [ConditionalTheory(Helpers.IsDrawingSupported)] + [InlineData("Display", GraphicsUnit.Display)] + [InlineData("Document", GraphicsUnit.Document)] + [InlineData("Inch", GraphicsUnit.Inch)] + [InlineData("Millimeter", GraphicsUnit.Millimeter)] + [InlineData("Pixel", GraphicsUnit.Pixel)] + [InlineData("Point", GraphicsUnit.Point)] + [InlineData("World", GraphicsUnit.World)] + public void CanConvertFrom(string input, GraphicsUnit expected) + { + FontUnitConverter converter = new FontUnitConverter(); + GraphicsUnit value = (GraphicsUnit)converter.ConvertFrom(input); + Assert.Equal(expected, value); + } + } +} diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/IconConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/IconConverterTests.cs similarity index 100% rename from src/libraries/System.Windows.Extensions/tests/System/Drawing/IconConverterTests.cs rename to src/libraries/System.Drawing.Common/tests/System/Drawing/IconConverterTests.cs diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/ImageConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/ImageConverterTests.cs similarity index 100% rename from src/libraries/System.Windows.Extensions/tests/System/Drawing/ImageConverterTests.cs rename to src/libraries/System.Drawing.Common/tests/System/Drawing/ImageConverterTests.cs diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/ImageFormatConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/ImageFormatConverterTests.cs similarity index 100% rename from src/libraries/System.Windows.Extensions/tests/System/Drawing/ImageFormatConverterTests.cs rename to src/libraries/System.Drawing.Common/tests/System/Drawing/ImageFormatConverterTests.cs diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/Printing/MarginsConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/Printing/MarginsConverterTests.cs similarity index 100% rename from src/libraries/System.Windows.Extensions/tests/System/Drawing/Printing/MarginsConverterTests.cs rename to src/libraries/System.Drawing.Common/tests/System/Drawing/Printing/MarginsConverterTests.cs diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.Forwards.cs b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.Forwards.cs new file mode 100644 index 000000000000..c64d5ead3990 --- /dev/null +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.Forwards.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.FontConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.IconConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.ImageConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.ImageFormatConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.Printing.MarginsConverter))] diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs index c3dd8dc7ecca..ac07897be2c8 100644 --- a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs @@ -4,77 +4,6 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ -namespace System.Drawing -{ - public partial class FontConverter : System.ComponentModel.TypeConverter - { - public FontConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } - public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { throw null; } - public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes) { throw null; } - public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - public sealed partial class FontNameConverter : System.ComponentModel.TypeConverter, System.IDisposable - { - public FontNameConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - void System.IDisposable.Dispose() { } - } - public partial class FontUnitConverter : System.ComponentModel.EnumConverter - { - public FontUnitConverter() : base (default(System.Type)) { } - public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - } - } - public partial class IconConverter : System.ComponentModel.ExpandableObjectConverter - { - public IconConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } - } - public partial class ImageConverter : System.ComponentModel.TypeConverter - { - public ImageConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } - public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes) { throw null; } - public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - } - public partial class ImageFormatConverter : System.ComponentModel.TypeConverter - { - public ImageFormatConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } - public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - } -} -namespace System.Drawing.Printing -{ - public partial class MarginsConverter : System.ComponentModel.ExpandableObjectConverter - { - public MarginsConverter() { } - public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; } - public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; } - public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; } - public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; } - public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { throw null; } - public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; } - } -} namespace System.Media { public partial class SoundPlayer : System.ComponentModel.Component, System.Runtime.Serialization.ISerializable diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj index d8548ee597d3..e015f1365222 100644 --- a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj @@ -5,6 +5,10 @@ + + + + diff --git a/src/libraries/System.Windows.Extensions/src/ExcludeApiList.PNSE.txt b/src/libraries/System.Windows.Extensions/src/ExcludeApiList.PNSE.txt new file mode 100644 index 000000000000..4537903f66be --- /dev/null +++ b/src/libraries/System.Windows.Extensions/src/ExcludeApiList.PNSE.txt @@ -0,0 +1,7 @@ +T:System.Drawing.FontConverter +T:System.Drawing.FontConverter.FontNameConverter +T:System.Drawing.FontConverter.FontUnitConverter +T:System.Drawing.IconConverter +T:System.Drawing.ImageConverter +T:System.Drawing.ImageFormatConverter +T:System.Drawing.Printing.MarginsConverter diff --git a/src/libraries/System.Windows.Extensions/src/Resources/Strings.resx b/src/libraries/System.Windows.Extensions/src/Resources/Strings.resx index 0d363ab629fb..bafdb5f343cd 100644 --- a/src/libraries/System.Windows.Extensions/src/Resources/Strings.resx +++ b/src/libraries/System.Windows.Extensions/src/Resources/Strings.resx @@ -125,12 +125,6 @@ Enumeration value '{0}' specified in condition mapping is not valid. - - (none) - - - Value of '{0}' is not valid for font size unit. - System.Windows.Extensions types are not supported on this platform. diff --git a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj index 7e4df72fa5eb..178344cc5fe4 100644 --- a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj @@ -1,10 +1,16 @@ - SR.PlatformNotSupported_System_Windows_Extensions true $(NetCoreAppCurrent)-Windows_NT;netcoreapp3.0-Windows_NT;$(NetCoreAppCurrent);netcoreapp3.0 true + + SR.PlatformNotSupported_System_Windows_Extensions + --exclude-api-list ExcludeApiList.PNSE.txt + + + + @@ -40,23 +46,16 @@ Link="Common\Interop\Windows\Interop.Libraries.cs" /> - - - - - - - - + + diff --git a/src/libraries/System.Windows.Extensions/src/TypeForwards.cs b/src/libraries/System.Windows.Extensions/src/TypeForwards.cs new file mode 100644 index 000000000000..f3974c73b750 --- /dev/null +++ b/src/libraries/System.Windows.Extensions/src/TypeForwards.cs @@ -0,0 +1,8 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.FontConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.IconConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.ImageConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.ImageFormatConverter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Drawing.Printing.MarginsConverter))] diff --git a/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj b/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj index f41f912cb05b..f0f105858a70 100644 --- a/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj +++ b/src/libraries/System.Windows.Extensions/tests/System.Windows.Extensions.Tests.csproj @@ -12,11 +12,6 @@ Link="Common\System\Drawing\Helpers.cs" /> - - - - - diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs b/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs deleted file mode 100644 index 3f9a9da40efa..000000000000 --- a/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs +++ /dev/null @@ -1,166 +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.Drawing; -using System.Drawing.Text; -using System.Globalization; -using System.Linq; -using Xunit; -using static System.Drawing.FontConverter; - -namespace System.ComponentModel.TypeConverterTests -{ - public class FontNameConverterTest - { - [ConditionalFact(Helpers.IsDrawingSupported)] - public void TestConvertFrom() - { - FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); - // returns "Times" under Linux and "Times New Roman" under Windows - if (PlatformDetection.IsWindows) - { - Assert.Equal("Times New Roman", converter.ConvertFrom("Times") as string); - } - else - { - Assert.Equal("Times", converter.ConvertFrom("Times") as string); - } - Assert.True(converter.GetStandardValuesSupported(), "standard values supported"); - Assert.False(converter.GetStandardValuesExclusive(), "standard values exclusive"); - } - - [ConditionalFact(Helpers.IsDrawingSupported)] - public void ExTestConvertFrom_ThrowsNotSupportedException() - { - FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); - Assert.Throws(() => converter.ConvertFrom(null)); - Assert.Throws(() => converter.ConvertFrom(1)); - } - } - - public class FontConverterTest - { - public static char s_Separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator[0]; - - [ConditionalTheory(Helpers.IsDrawingSupported)] - [MemberData(nameof(TestConvertFormData))] - public void TestConvertFrom(string input, string expectedName, float expectedSize, GraphicsUnit expectedUnits, FontStyle expectedFontStyle) - { - FontConverter converter = new FontConverter(); - Font font = (Font)converter.ConvertFrom(input); - Assert.Equal(expectedName, font.Name); - Assert.Equal(expectedSize, font.Size); - Assert.Equal(expectedUnits, font.Unit); - Assert.Equal(expectedFontStyle, font.Style); - } - - [ConditionalTheory(Helpers.IsDrawingSupported)] - [MemberData(nameof(ArgumentExceptionFontConverterData))] - public void InvalidInputThrowsArgumentException(string input, string paramName, string netfxParamName) - { - FontConverter converter = new FontConverter(); - AssertExtensions.Throws(paramName, netfxParamName, () => converter.ConvertFrom(input)); - } - - [ConditionalTheory(Helpers.IsDrawingSupported)] - [MemberData(nameof(InvalidEnumArgumentExceptionFontConverterData))] - public void InvalidInputThrowsInvalidEnumArgumentException(string input, string paramName) - { - FontConverter converter = new FontConverter(); - Assert.Throws(paramName, () => converter.ConvertFrom(input)); - } - - [ConditionalFact(Helpers.IsDrawingSupported)] - public void EmptyStringInput() - { - FontConverter converter = new FontConverter(); - Font font = (Font)converter.ConvertFrom(string.Empty); - Assert.Null(font); - } - - public static TheoryData TestConvertFormData() - { - var data = new TheoryData() - { - { $"Courier New", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Courier New{s_Separator} 11", "Courier New", 11f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_Separator} 11px", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_Separator} 11 px", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_Separator} 11 px{s_Separator} style=Regular", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_Separator} style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, - { $"Courier New{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic }, - { $"Courier New{s_Separator} 11 px{s_Separator} style=Regular, Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular | FontStyle.Italic }, - { $"Courier New{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic{s_Separator} Strikeout", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, - { $"Arial{s_Separator} 11 px{s_Separator} style=Bold, Italic, Strikeout", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, - { $"11px", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"arIAL{s_Separator} 10{s_Separator} style=bold", "Arial", 10f, GraphicsUnit.Point, FontStyle.Bold }, - { $"Arial{s_Separator} 10{s_Separator}", "Arial", 10f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_Separator}", "Arial", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_Separator} 10{s_Separator} style=12", "Arial", 10f, GraphicsUnit.Point, FontStyle.Underline | FontStyle.Strikeout }, - { $"Courier New{s_Separator} Style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. - { $"11px{s_Separator} Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Bold} - }; - - // FullFramework disregards all arguments if the font name is an empty string. - // Empty string is not an installed font on Windows 7, windows 8 and some versions of windows 10. - if (EmptyFontPresent) - { - data.Add($"{s_Separator} 10{s_Separator} style=bold", "", 10f, GraphicsUnit.Point, FontStyle.Bold); - } - else - { - data.Add($"{s_Separator} 10{s_Separator} style=bold", "Microsoft Sans Serif", 10f, GraphicsUnit.Point, FontStyle.Bold); - } - - return data; - } - - private static bool EmptyFontPresent - { - get - { - using (var installedFonts = new InstalledFontCollection()) - { - return installedFonts.Families.Select(t => t.Name).Contains(string.Empty); - } - } - } - - public static TheoryData ArgumentExceptionFontConverterData() => new TheoryData() - { - { $"Courier New{s_Separator} 11 px{s_Separator} type=Bold{s_Separator} Italic", "units", null }, - { $"Courier New{s_Separator} {s_Separator} Style=Bold", "value", null }, - { $"Courier New{s_Separator} 11{s_Separator} Style=", "value", null }, - { $"Courier New{s_Separator} 11{s_Separator} Style=RandomEnum", null, null }, - { $"Arial{s_Separator} 10{s_Separator} style=bold{s_Separator}", "value", null }, - { $"Arial{s_Separator} 10{s_Separator} style=null", null, null }, - { $"Arial{s_Separator} 10{s_Separator} style=abc#", null, null }, - { $"Arial{s_Separator} 10{s_Separator} style=##", null, null }, - { $"Arial{s_Separator} 10display{s_Separator} style=bold", null, null }, - { $"Arial{s_Separator} 10style{s_Separator} style=bold", "units", null }, - }; - - public static TheoryData InvalidEnumArgumentExceptionFontConverterData() => new TheoryData() - { - { $"Arial{s_Separator} 10{s_Separator} style=56", "style" }, - { $"Arial{s_Separator} 10{s_Separator} style=-1", "style" }, - }; - } - - public class FontUnitConverterTest - { - [ConditionalFact(Helpers.IsDrawingSupported)] - public void GetStandardValuesTest() - { - FontUnitConverter converter = new FontUnitConverter(); - var values = converter.GetStandardValues(); - Assert.Equal(6, values.Count); // The six supported values of Graphics unit: World, Pixel, Point, Inch, Document, Millimeter. - - foreach (var item in values) - { - Assert.NotEqual(GraphicsUnit.Display, (GraphicsUnit)item); - } - } - } -} From 71c83f38bc5cc461f561ccc77829df8684916d14 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Sat, 15 Aug 2020 00:18:38 -0400 Subject: [PATCH 524/755] [mono] Make bundle filename changes netcore-only (#40845) --- src/mono/mono/metadata/assembly.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index ccf05748c9e6..34cd398cd90c 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -2500,8 +2500,12 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena name = g_path_get_basename (filename); for (i = 0; !image && bundles [i]; ++i) { if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) { +#ifdef ENABLE_NETCORE // Since bundled images don't exist on disk, don't give them a legit filename image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name, NULL); +#else + image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name, name); +#endif break; } } From f35d747e8d7fe44d7dab76b9683d7c642ec26888 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Fri, 14 Aug 2020 23:52:14 -0700 Subject: [PATCH 525/755] Generational aware analysis based on environment variable. (#40332) --- src/coreclr/src/gc/env/gcenv.ee.h | 2 +- src/coreclr/src/gc/gc.cpp | 12 ++- src/coreclr/src/gc/gcee.cpp | 12 +-- src/coreclr/src/gc/gcenv.ee.standalone.inl | 4 +- src/coreclr/src/gc/gcimpl.h | 6 +- src/coreclr/src/gc/gcinterface.ee.h | 2 +- src/coreclr/src/gc/sample/gcenv.ee.cpp | 2 +- src/coreclr/src/inc/clrconfigvalues.h | 7 ++ src/coreclr/src/vm/CMakeLists.txt | 1 + src/coreclr/src/vm/ClrEtwAll.man | 9 +++ src/coreclr/src/vm/ceemain.cpp | 3 + src/coreclr/src/vm/eventpipe.cpp | 4 +- src/coreclr/src/vm/eventpipesession.cpp | 16 ++++ src/coreclr/src/vm/eventpipesession.h | 32 ++++++++ src/coreclr/src/vm/eventtrace.cpp | 22 +++++- src/coreclr/src/vm/fastserializer.cpp | 1 - src/coreclr/src/vm/finalizerthread.cpp | 19 ++++- src/coreclr/src/vm/gcenv.ee.cpp | 27 ++++++- src/coreclr/src/vm/gcenv.ee.h | 2 +- src/coreclr/src/vm/gcenv.ee.standalone.cpp | 3 + src/coreclr/src/vm/gcenv.ee.static.cpp | 3 + src/coreclr/src/vm/genanalysis.cpp | 79 ++++++++++++++++++++ src/coreclr/src/vm/genanalysis.h | 39 ++++++++++ src/coreclr/src/vm/proftoeeinterfaceimpl.cpp | 2 +- 24 files changed, 280 insertions(+), 29 deletions(-) create mode 100644 src/coreclr/src/vm/genanalysis.cpp create mode 100644 src/coreclr/src/vm/genanalysis.h diff --git a/src/coreclr/src/gc/env/gcenv.ee.h b/src/coreclr/src/gc/env/gcenv.ee.h index 986acabacbec..d596575ad2b4 100644 --- a/src/coreclr/src/gc/env/gcenv.ee.h +++ b/src/coreclr/src/gc/env/gcenv.ee.h @@ -86,7 +86,7 @@ class GCToEEInterface static uint32_t GetTotalNumSizedRefHandles(); static bool AnalyzeSurvivorsRequested(int condemnedGeneration); - static void AnalyzeSurvivorsFinished(int condemnedGeneration); + static void AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()); static void VerifySyncTableEntry(); static void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords); diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index f6910c0b2464..34c983521b61 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -20909,9 +20909,19 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p) if (gc_t_join.joined()) #endif //MULTIPLE_HEAPS { + uint64_t promoted_bytes_global = 0; #ifdef HEAP_ANALYZE heap_analyze_enabled = FALSE; - GCToEEInterface::AnalyzeSurvivorsFinished(condemned_gen_number); +#ifdef MULTIPLE_HEAPS + for (int i = 0; i < n_heaps; i++) + { + promoted_bytes_global += promoted_bytes (i); + } +#else + promoted_bytes_global = promoted_bytes (0); +#endif //MULTIPLE_HEAPS + + GCToEEInterface::AnalyzeSurvivorsFinished (settings.gc_index, condemned_gen_number, promoted_bytes_global, GCHeap::ReportGenerationBounds); #endif // HEAP_ANALYZE GCToEEInterface::AfterGcScanRoots (condemned_gen_number, max_generation, &sc); diff --git a/src/coreclr/src/gc/gcee.cpp b/src/coreclr/src/gc/gcee.cpp index 2964b14190e9..4912f2e86691 100644 --- a/src/coreclr/src/gc/gcee.cpp +++ b/src/coreclr/src/gc/gcee.cpp @@ -53,6 +53,11 @@ void GCHeap::UpdatePreGCCounters() #endif // BACKGROUND_GC FIRE_EVENT(GCStart_V2, count, depth, reason, static_cast(type)); + ReportGenerationBounds(); +} + +void GCHeap::ReportGenerationBounds() +{ g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved) { uint64_t range = static_cast(rangeEnd - rangeStart); @@ -148,12 +153,7 @@ void GCHeap::UpdatePostGCCounters() #endif //FEATURE_EVENT_TRACE #ifdef FEATURE_EVENT_TRACE - g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved) - { - uint64_t range = static_cast(rangeEnd - rangeStart); - uint64_t rangeReserved = static_cast(rangeEndReserved - rangeStart); - FIRE_EVENT(GCGenerationRange, generation, rangeStart, range, rangeReserved); - }, nullptr); + ReportGenerationBounds(); FIRE_EVENT(GCEnd_V1, static_cast(pSettings->gc_index), condemned_gen); diff --git a/src/coreclr/src/gc/gcenv.ee.standalone.inl b/src/coreclr/src/gc/gcenv.ee.standalone.inl index 650812644b01..f14b327a31e1 100644 --- a/src/coreclr/src/gc/gcenv.ee.standalone.inl +++ b/src/coreclr/src/gc/gcenv.ee.standalone.inl @@ -274,10 +274,10 @@ inline bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration) return g_theGCToCLR->AnalyzeSurvivorsRequested(condemnedGeneration); } -inline void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration) +inline void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()) { assert(g_theGCToCLR != nullptr); - g_theGCToCLR->AnalyzeSurvivorsFinished(condemnedGeneration); + g_theGCToCLR->AnalyzeSurvivorsFinished(gcIndex, condemnedGeneration, promoted_bytes, reportGenerationBounds); } inline void GCToEEInterface::VerifySyncTableEntry() diff --git a/src/coreclr/src/gc/gcimpl.h b/src/coreclr/src/gc/gcimpl.h index d1f062efb44c..b1c8cb91a7b6 100644 --- a/src/coreclr/src/gc/gcimpl.h +++ b/src/coreclr/src/gc/gcimpl.h @@ -31,7 +31,7 @@ inline void deleteGCShadow() {} inline void checkGCWriteBarrier() {} #endif -void GCProfileWalkHeap(); +void GCProfileWalkHeap(bool etwOnly); class gc_heap; class CFinalize; @@ -57,7 +57,7 @@ class GCHeap : public IGCHeapInternal friend void EnterAllocLock(); friend void LeaveAllocLock(); friend void ProfScanRootsHelper(Object** object, ScanContext *pSC, uint32_t dwFlags); - friend void GCProfileWalkHeap(); + friend void GCProfileWalkHeap(bool etwOnly); public: //In order to keep gc.cpp cleaner, ugly EE specific code is relegated to methods. @@ -315,6 +315,8 @@ class GCHeap : public IGCHeapInternal size_t GetLastGCGenerationSize(int gen); virtual void Shutdown(); + + static void ReportGenerationBounds(); }; #endif // GCIMPL_H_ diff --git a/src/coreclr/src/gc/gcinterface.ee.h b/src/coreclr/src/gc/gcinterface.ee.h index 158da1867dbb..f61fdf5c5e65 100644 --- a/src/coreclr/src/gc/gcinterface.ee.h +++ b/src/coreclr/src/gc/gcinterface.ee.h @@ -414,7 +414,7 @@ class IGCToCLR { bool AnalyzeSurvivorsRequested(int condemnedGeneration) = 0; virtual - void AnalyzeSurvivorsFinished(int condemnedGeneration) = 0; + void AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()) = 0; virtual void VerifySyncTableEntry() = 0; diff --git a/src/coreclr/src/gc/sample/gcenv.ee.cpp b/src/coreclr/src/gc/sample/gcenv.ee.cpp index 4ed20f07786e..1480e62c23b4 100644 --- a/src/coreclr/src/gc/sample/gcenv.ee.cpp +++ b/src/coreclr/src/gc/sample/gcenv.ee.cpp @@ -339,7 +339,7 @@ inline bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration) return false; } -inline void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration) +inline void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()) { } diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index efeac155253c..bf49107ea062 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -709,6 +709,13 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeRundown, W("EventPipeRundown"), 1, "E RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), 1024, "The EventPipe circular buffer size in megabytes.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers") +// +// Generational Aware Analysis +// +RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisGen, W("GCGenAnalysisGen"), 0, "The generation to trigger generational aware analysis") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisBytes, W("GCGenAnalysisBytes"), 0, "The number of bytes to trigger generational aware analysis") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisIndex, W("GCGenAnalysisIndex"), 0, "The gc index to trigger generational aware analysis") + // // Diagnostics Ports // diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index 6c97ca4ee013..0cb75e5629f3 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -357,6 +357,7 @@ set(VM_SOURCES_WKS gcenv.ee.common.cpp gcenv.os.cpp gchelpers.cpp + genanalysis.cpp genmeth.cpp hosting.cpp ibclogger.cpp diff --git a/src/coreclr/src/vm/ClrEtwAll.man b/src/coreclr/src/vm/ClrEtwAll.man index cf2108b4e56a..cb4eb215bd85 100644 --- a/src/coreclr/src/vm/ClrEtwAll.man +++ b/src/coreclr/src/vm/ClrEtwAll.man @@ -3795,6 +3795,13 @@ task="AssemblyLoader" symbol="KnownPathProbed" message="$(string.RuntimePublisher.KnownPathProbedEventMessage)"/> + + + @@ -7548,6 +7555,8 @@ + + diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 75bb51cca491..b1cbb7ba9470 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -220,6 +220,8 @@ #include "gdbjit.h" #endif // FEATURE_GDBJIT +#include "genanalysis.h" + #ifndef CROSSGEN_COMPILE static int GetThreadUICultureId(__out LocaleIDValue* pLocale); // TODO: This shouldn't use the LCID. We should rely on name instead @@ -676,6 +678,7 @@ void EEStartupHelper() // Initialize the event pipe. EventPipe::Initialize(); #endif // FEATURE_PERFTRACING + GenAnalysis::Initialize(); #ifdef TARGET_UNIX PAL_SetShutdownCallback(EESocketCleanupHelper); diff --git a/src/coreclr/src/vm/eventpipe.cpp b/src/coreclr/src/vm/eventpipe.cpp index 51264b1f351c..a25f6c20370a 100644 --- a/src/coreclr/src/vm/eventpipe.cpp +++ b/src/coreclr/src/vm/eventpipe.cpp @@ -22,6 +22,7 @@ #include "win32threadpool.h" #include "ceemain.h" #include "configuration.h" +#include "genanalysis.h" #ifdef TARGET_UNIX #include "pal.h" @@ -164,7 +165,7 @@ void EventPipe::EnableViaEnvironmentVariables() { outputPath = configOutputPath; } - auto configuration = XplatEventLoggerConfiguration(); + LPWSTR configToParse = eventpipeConfig; int providerCnt = 0; @@ -183,6 +184,7 @@ void EventPipe::EnableViaEnvironmentVariables() } else { + auto configuration = XplatEventLoggerConfiguration(); // Count how many providers there are to parse static WCHAR comma = W(','); while (*configToParse != '\0') diff --git a/src/coreclr/src/vm/eventpipesession.cpp b/src/coreclr/src/vm/eventpipesession.cpp index 49b9d54b1c15..6e85703598c1 100644 --- a/src/coreclr/src/vm/eventpipesession.cpp +++ b/src/coreclr/src/vm/eventpipesession.cpp @@ -81,6 +81,7 @@ EventPipeSession::EventPipeSession( GetSystemTimeAsFileTime(&m_sessionStartTime); QueryPerformanceCounter(&m_sessionStartTimeStamp); + this->m_paused = false; } EventPipeSession::~EventPipeSession() @@ -315,6 +316,16 @@ bool EventPipeSession::WriteAllBuffersToFile(bool *pEventsWritten) return !m_pFile->HasErrors(); } +void EventPipeSession::Pause() +{ + this->m_paused = true; +} + +void EventPipeSession::Resume() +{ + this->m_paused = false; +} + bool EventPipeSession::WriteEvent( Thread *pThread, EventPipeEvent &event, @@ -332,6 +343,11 @@ bool EventPipeSession::WriteEvent( } CONTRACTL_END; + if (this->m_paused) + { + return true; + } + // Filter events specific to "this" session based on precomputed flag on provider/events. if (event.IsEnabled(GetMask())) { diff --git a/src/coreclr/src/vm/eventpipesession.h b/src/coreclr/src/vm/eventpipesession.h index 10974859c6b5..39d91f853607 100644 --- a/src/coreclr/src/vm/eventpipesession.h +++ b/src/coreclr/src/vm/eventpipesession.h @@ -96,6 +96,20 @@ class EventPipeSession void DisableIpcStreamingThread(); + // Note - access to this field is NOT synchronized + // + // This field is currently modified in EventPipe::EnableViaEnvironmentVariables() during process startup + // and GCToEEInterface::AnalyzeSurvivorsFinished() while the GC has already synchronized all the threads. + // + // It is read in EventPipeSession::WriteEvent(). While it is possible for other preemptive threads to read + // the field while GC is happening, it should not happen because the only gcGenAwareSession only subscribe + // to GC events. + // + // This functionality is a workaround because we couldn't safely Enable()/Disable() the session where we wanted to due to lock-leveling. + // we expect to remove it in the future once that limitation is resolved + // other scenarios are discouraged from using this given that we plan to make it go away + bool m_paused; + public: EventPipeSession( uint32_t index, @@ -111,6 +125,24 @@ class EventPipeSession ~EventPipeSession(); + /** + * Please do not use this function, see EventPipeSession::m_paused for more information + */ + void Pause(); + + /** + * Please do not use this function, see EventPipeSession::m_paused for more information + */ + void Resume(); + + /** + * Please do not use this function, see EventPipeSession::m_paused for more information + */ + bool Paused() + { + return this->m_paused; + } + uint64_t GetMask() const { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index 67a134072397..802c5211ab71 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -1095,9 +1095,14 @@ void BulkComLogger::WriteRcw(RCW *pRcw, Object *obj) _ASSERTE(m_currRcw < kMaxRcwCount); #ifdef FEATURE_COMINTEROP + TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible(); + if (typeHandle == NULL) + { + return; + } EventRCWEntry &rcw = m_etwRcwData[m_currRcw]; rcw.ObjectID = (ULONGLONG)obj; - rcw.TypeID = (ULONGLONG)obj->GetTypeHandle().AsTAddr(); + rcw.TypeID = (ULONGLONG)typeHandle.AsTAddr(); rcw.IUnk = (ULONGLONG)pRcw->GetIUnknown_NoAddRef(); rcw.VTable = (ULONGLONG)pRcw->GetVTablePtr(); rcw.RefCount = pRcw->GetRefCount(); @@ -1179,10 +1184,16 @@ void BulkComLogger::WriteCcw(ComCallWrapper *pCcw, Object **handle, Object *obj) flags |= EventCCWEntry::Strong; } + TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible(); + if (typeHandle == NULL) + { + return; + } + EventCCWEntry &ccw = m_etwCcwData[m_currCcw++]; ccw.RootID = (ULONGLONG)handle; ccw.ObjectID = (ULONGLONG)obj; - ccw.TypeID = (ULONGLONG)obj->GetTypeHandle().AsTAddr(); + ccw.TypeID = (ULONGLONG)typeHandle.AsTAddr(); ccw.IUnk = (ULONGLONG)iUnk; ccw.RefCount = refCount; ccw.JupiterRefCount = 0; @@ -1463,7 +1474,12 @@ void BulkStaticsLogger::WriteEntry(AppDomain *domain, Object **address, Object * m_domain = domain; } - ULONGLONG th = (ULONGLONG)obj->GetTypeHandle().AsTAddr(); + TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible(); + if (typeHandle == NULL) + { + return; + } + ULONGLONG th = (ULONGLONG)typeHandle.AsTAddr(); ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(m_typeLogger, th, ETW::TypeSystemLog::kTypeLogBehaviorTakeLockAndLogIfFirstTime); // We should have at least 512 characters remaining in the buffer here. diff --git a/src/coreclr/src/vm/fastserializer.cpp b/src/coreclr/src/vm/fastserializer.cpp index a15880079b6f..238e5b772f2c 100644 --- a/src/coreclr/src/vm/fastserializer.cpp +++ b/src/coreclr/src/vm/fastserializer.cpp @@ -72,7 +72,6 @@ FileStreamWriter::FileStreamWriter(const SString &outputFilePath) m_pFileStream = new CFileStream(); if (FAILED(m_pFileStream->OpenForWrite(outputFilePath))) { - _ASSERTE(!"Unable to open file for write."); delete m_pFileStream; m_pFileStream = NULL; return; diff --git a/src/coreclr/src/vm/finalizerthread.cpp b/src/coreclr/src/vm/finalizerthread.cpp index a46166b3a85e..facb5e4c1928 100644 --- a/src/coreclr/src/vm/finalizerthread.cpp +++ b/src/coreclr/src/vm/finalizerthread.cpp @@ -7,6 +7,9 @@ #include "finalizerthread.h" #include "threadsuspend.h" #include "jithost.h" +#include "eventpipe.h" +#include "eventpipesession.h" +#include "genanalysis.h" #ifdef FEATURE_COMINTEROP #include "runtimecallablewrapper.h" @@ -214,12 +217,8 @@ void FinalizerThread::WaitForFinalizerEvent (CLREvent *event) } } - - static BOOL s_FinalizerThreadOK = FALSE; - - VOID FinalizerThread::FinalizerThreadWorker(void *args) { SCAN_IGNORE_THROW; @@ -267,6 +266,18 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args) g_TriggerHeapDump = FALSE; } #endif + if (gcGenAnalysisState == GcGenAnalysisState::Done) + { + gcGenAnalysisState = GcGenAnalysisState::Disabled; + EventPipe::Disable(gcGenAnalysisEventPipeSessionId); + // Writing an empty file to indicate completion + fclose(fopen(GENAWARE_COMPLETION_FILE_NAME,"w+")); +#ifdef GEN_ANALYSIS_STRESS + { + GenAnalysis::EnableGenerationalAwareSession(); + } +#endif + } if (!bPriorityBoosted) { diff --git a/src/coreclr/src/vm/gcenv.ee.cpp b/src/coreclr/src/vm/gcenv.ee.cpp index 394475996015..54bde52c750b 100644 --- a/src/coreclr/src/vm/gcenv.ee.cpp +++ b/src/coreclr/src/vm/gcenv.ee.cpp @@ -685,7 +685,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE } #endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE) -void GCProfileWalkHeap() +void GCProfileWalkHeap(bool etwOnly) { BOOL fWalkedHeapForProfiler = FALSE; @@ -702,7 +702,7 @@ void GCProfileWalkHeap() #if defined (GC_PROFILING) { - BEGIN_PIN_PROFILER(CORProfilerTrackGC()); + BEGIN_PIN_PROFILER(!etwOnly && CORProfilerTrackGC()); GCProfileWalkHeapWorker(TRUE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw); fWalkedHeapForProfiler = TRUE; END_PIN_PROFILER(); @@ -764,7 +764,7 @@ void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurr // we will do these for all GCs. if (!fConcurrent) { - GCProfileWalkHeap(); + GCProfileWalkHeap(false); } if (CORProfilerTrackBasicGC() || (!fConcurrent && CORProfilerTrackGC())) @@ -1582,7 +1582,7 @@ bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration) return false; } -void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration) +void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()) { LIMITED_METHOD_CONTRACT; @@ -1596,6 +1596,25 @@ void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration) DACNotify::DoGCNotification(gea); } } + + if (gcGenAnalysisState == GcGenAnalysisState::Enabled) + { +#ifndef GEN_ANALYSIS_STRESS + if ((condemnedGeneration == gcGenAnalysisGen) && (promoted_bytes > (uint64_t)gcGenAnalysisBytes) && (gcIndex > (uint64_t)gcGenAnalysisIndex)) +#endif + { + gcGenAnalysisEventPipeSession->Resume(); + FireEtwGenAwareBegin(); + s_forcedGCInProgress = true; + GCProfileWalkHeap(true); + s_forcedGCInProgress = false; + reportGenerationBounds(); + FireEtwGenAwareEnd(); + gcGenAnalysisEventPipeSession->Pause(); + gcGenAnalysisState = GcGenAnalysisState::Done; + EnableFinalization(true); + } + } } void GCToEEInterface::VerifySyncTableEntry() diff --git a/src/coreclr/src/vm/gcenv.ee.h b/src/coreclr/src/vm/gcenv.ee.h index 908fb465dc98..c9a1cc27ab6c 100644 --- a/src/coreclr/src/vm/gcenv.ee.h +++ b/src/coreclr/src/vm/gcenv.ee.h @@ -77,7 +77,7 @@ class GCToEEInterface : public IGCToCLR { uint32_t GetTotalNumSizedRefHandles(); bool AnalyzeSurvivorsRequested(int condemnedGeneration); - void AnalyzeSurvivorsFinished(int condemnedGeneration); + void AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()); void VerifySyncTableEntry(); diff --git a/src/coreclr/src/vm/gcenv.ee.standalone.cpp b/src/coreclr/src/vm/gcenv.ee.standalone.cpp index 8aa1d4893fea..93638697aeaa 100644 --- a/src/coreclr/src/vm/gcenv.ee.standalone.cpp +++ b/src/coreclr/src/vm/gcenv.ee.standalone.cpp @@ -15,6 +15,9 @@ #include "gctoclreventsink.h" #include "configuration.h" +#include "eventpipe.h" +#include "eventpipesession.h" +#include "genanalysis.h" // the method table for the WeakReference class extern MethodTable* pWeakReferenceMT; diff --git a/src/coreclr/src/vm/gcenv.ee.static.cpp b/src/coreclr/src/vm/gcenv.ee.static.cpp index 5e1b452b256a..63a0795f975e 100644 --- a/src/coreclr/src/vm/gcenv.ee.static.cpp +++ b/src/coreclr/src/vm/gcenv.ee.static.cpp @@ -15,6 +15,9 @@ #include "gctoclreventsink.h" #include "configuration.h" +#include "eventpipe.h" +#include "eventpipesession.h" +#include "genanalysis.h" // the method table for the WeakReference class extern MethodTable* pWeakReferenceMT; diff --git a/src/coreclr/src/vm/genanalysis.cpp b/src/coreclr/src/vm/genanalysis.cpp new file mode 100644 index 000000000000..e679467c9ebb --- /dev/null +++ b/src/coreclr/src/vm/genanalysis.cpp @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" +#include "genanalysis.h" + +GcGenAnalysisState gcGenAnalysisState = GcGenAnalysisState::Uninitialized; +EventPipeSession* gcGenAnalysisEventPipeSession = nullptr; +uint64_t gcGenAnalysisEventPipeSessionId = (uint64_t)-1; +GcGenAnalysisState gcGenAnalysisConfigured = GcGenAnalysisState::Uninitialized; +int64_t gcGenAnalysisGen = -1; +int64_t gcGenAnalysisBytes = 0; +int64_t gcGenAnalysisIndex = 0; + +/* static */ void GenAnalysis::Initialize() +{ +#ifndef GEN_ANALYSIS_STRESS + if (gcGenAnalysisConfigured == GcGenAnalysisState::Uninitialized) + { + if (CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisGen"))) + { + gcGenAnalysisGen = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisGen); + if (CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisBytes"))) + { + gcGenAnalysisBytes = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisBytes); + if (CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisIndex"))) + { + gcGenAnalysisIndex = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisIndex); + gcGenAnalysisConfigured = GcGenAnalysisState::Enabled; + } + else + { + gcGenAnalysisConfigured = GcGenAnalysisState::Disabled; + } + } + else + { + gcGenAnalysisConfigured = GcGenAnalysisState::Disabled; + } + } + } + if ((gcGenAnalysisConfigured == GcGenAnalysisState::Enabled) && (gcGenAnalysisState == GcGenAnalysisState::Uninitialized)) +#endif + { + EnableGenerationalAwareSession(); + } +} + +/* static */ void GenAnalysis::EnableGenerationalAwareSession() +{ + LPCWSTR outputPath = nullptr; + outputPath = GENAWARE_FILE_NAME; + NewHolder pProviders = nullptr; + int providerCnt = 1; + pProviders = new EventPipeProviderConfiguration[providerCnt]; + const uint64_t GCHeapAndTypeNamesKeyword = 0x00001000000; // This keyword is necessary for the type names + const uint64_t GCHeapSurvivalAndMovementKeyword = 0x00000400000; // This keyword is necessary for the generation range data. + const uint64_t GCHeapDumpKeyword = 0x00000100000; // This keyword is necessary for enabling walking the heap + const uint64_t TypeKeyword = 0x00000080000; // This keyword is necessary for enabling BulkType events + const uint64_t keyword = GCHeapAndTypeNamesKeyword|GCHeapSurvivalAndMovementKeyword|GCHeapDumpKeyword|TypeKeyword; + pProviders[0] = EventPipeProviderConfiguration(W("Microsoft-Windows-DotNETRuntime"), keyword, 5, nullptr); + gcGenAnalysisEventPipeSessionId = EventPipe::Enable( + outputPath, + 1024, + pProviders, + providerCnt, + EventPipeSessionType::File, + EventPipeSerializationFormat::NetTraceV4, + false, + nullptr + ); + if (gcGenAnalysisEventPipeSessionId > 0) + { + gcGenAnalysisEventPipeSession= EventPipe::GetSession(gcGenAnalysisEventPipeSessionId); + gcGenAnalysisEventPipeSession->Pause(); + EventPipe::StartStreaming(gcGenAnalysisEventPipeSessionId); + gcGenAnalysisState = GcGenAnalysisState::Enabled; + } +} diff --git a/src/coreclr/src/vm/genanalysis.h b/src/coreclr/src/vm/genanalysis.h new file mode 100644 index 000000000000..3ed25d8cf7b8 --- /dev/null +++ b/src/coreclr/src/vm/genanalysis.h @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// #define GEN_ANALYSIS_STRESS + +#ifndef __GENANALYSIS_H__ +#define __GENANALYSIS_H__ + +#include "eventpipe.h" +#include "eventpipesession.h" + +enum GcGenAnalysisState +{ + Uninitialized = 0, + Enabled = 1, + Disabled = 2, + Done = 3, +}; + +#define GENAWARE_FILE_NAME W("gcgenaware.nettrace") +#define GENAWARE_COMPLETION_FILE_NAME "gcgenaware.nettrace.completed" + +extern bool s_forcedGCInProgress; +extern GcGenAnalysisState gcGenAnalysisState; +extern EventPipeSession* gcGenAnalysisEventPipeSession; +extern uint64_t gcGenAnalysisEventPipeSessionId; +extern GcGenAnalysisState gcGenAnalysisConfigured; +extern int64_t gcGenAnalysisGen; +extern int64_t gcGenAnalysisBytes; +extern int64_t gcGenAnalysisIndex; + +class GenAnalysis +{ +public: + static void Initialize(); + static void EnableGenerationalAwareSession(); +}; + +#endif diff --git a/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp index a5e4206a5a1a..487e12313708 100644 --- a/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp @@ -1091,7 +1091,7 @@ bool HeapWalkHelper(Object * pBO, void * pvContext) OBJECTREF * arrObjRef = NULL; size_t cNumRefs = 0; bool bOnStack = false; - MethodTable * pMT = pBO->GetMethodTable(); + MethodTable * pMT = pBO->GetGCSafeMethodTable(); ProfilerWalkHeapContext * pProfilerWalkHeapContext = (ProfilerWalkHeapContext *) pvContext; From 12f8e34fec1215c411f8ecc1bf6341e8cee61940 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Sat, 15 Aug 2020 10:44:47 +0200 Subject: [PATCH 526/755] Nullable: System.Xml, part 6 (XSLT minus XSLT.Runtime) (#40368) * Nullable: System.Xml, part 6 (XSLT minus XSLT.Runtime) * change Evaluate to take non-nullable * apply pr feedback * fix nullability merge conflicts * apply feedback --- .../Xml/XPath/Internal/BooleanFunctions.cs | 2 +- .../Xml/XPath/Internal/CompiledXPathExpr.cs | 2 +- .../System/Xml/XPath/Internal/ContextQuery.cs | 2 + .../Xml/XPath/Internal/FunctionQuery.cs | 2 +- .../Xml/XPath/Internal/NumberFunctions.cs | 2 +- .../Xml/XPath/Internal/StringFunctions.cs | 4 +- .../src/System/Xml/Xsl/ISourceLineInfo.cs | 3 +- .../System/Xml/Xsl/IlGen/GenerateHelper.cs | 187 ++++---- .../Xml/Xsl/IlGen/IteratorDescriptor.cs | 31 +- .../System/Xml/Xsl/IlGen/OptimizerPatterns.cs | 21 +- .../System/Xml/Xsl/IlGen/StaticDataManager.cs | 31 +- .../System/Xml/Xsl/IlGen/TailCallAnalyzer.cs | 3 +- .../System/Xml/Xsl/IlGen/XmlILAnnotation.cs | 27 +- .../Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs | 91 ++-- .../src/System/Xml/Xsl/IlGen/XmlILModule.cs | 31 +- .../System/Xml/Xsl/IlGen/XmlILOptimization.cs | 1 + .../Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs | 443 +++++++++--------- .../src/System/Xml/Xsl/IlGen/XmlILTrace.cs | 9 +- .../System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs | 1 + .../src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs | 280 +++++------ .../src/System/Xml/Xsl/ListBase.cs | 38 +- .../src/System/Xml/Xsl/Pair.cs | 3 +- .../src/System/Xml/Xsl/QIL/QilBinary.cs | 1 + .../src/System/Xml/Xsl/QIL/QilChoice.cs | 1 + .../src/System/Xml/Xsl/QIL/QilCloneVisitor.cs | 12 +- .../src/System/Xml/Xsl/QIL/QilDataSource.cs | 1 + .../src/System/Xml/Xsl/QIL/QilExpression.cs | 7 +- .../src/System/Xml/Xsl/QIL/QilFactory.cs | 5 +- .../src/System/Xml/Xsl/QIL/QilFunction.cs | 1 + .../src/System/Xml/Xsl/QIL/QilInvoke.cs | 1 + .../System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs | 3 +- .../System/Xml/Xsl/QIL/QilInvokeLateBound.cs | 1 + .../src/System/Xml/Xsl/QIL/QilIterator.cs | 9 +- .../src/System/Xml/Xsl/QIL/QilList.cs | 9 +- .../src/System/Xml/Xsl/QIL/QilLiteral.cs | 21 +- .../src/System/Xml/Xsl/QIL/QilLoop.cs | 1 + .../src/System/Xml/Xsl/QIL/QilName.cs | 17 +- .../src/System/Xml/Xsl/QIL/QilNode.cs | 13 +- .../src/System/Xml/Xsl/QIL/QilNodeType.cs | 1 + .../src/System/Xml/Xsl/QIL/QilParameter.cs | 15 +- .../System/Xml/Xsl/QIL/QilPatternFactory.cs | 13 +- .../System/Xml/Xsl/QIL/QilPatternVisitor.cs | 7 +- .../src/System/Xml/Xsl/QIL/QilReference.cs | 7 +- .../System/Xml/Xsl/QIL/QilReplaceVisitor.cs | 11 +- .../System/Xml/Xsl/QIL/QilScopedVisitor.cs | 1 + .../src/System/Xml/Xsl/QIL/QilSortKey.cs | 1 + .../src/System/Xml/Xsl/QIL/QilStrConcat.cs | 1 + .../src/System/Xml/Xsl/QIL/QilTargetType.cs | 3 +- .../src/System/Xml/Xsl/QIL/QilTernary.cs | 1 + .../src/System/Xml/Xsl/QIL/QilTypeChecker.cs | 87 ++-- .../src/System/Xml/Xsl/QIL/QilUnary.cs | 1 + .../Xml/Xsl/QIL/QilValidationVisitor.cs | 5 +- .../src/System/Xml/Xsl/QIL/QilVisitor.cs | 8 +- .../src/System/Xml/Xsl/QIL/QilXmlWriter.cs | 36 +- .../System/Xml/Xsl/QIL/SerializationHints.cs | 1 + .../System/Xml/Xsl/QIL/SubstitutionList.cs | 5 +- .../src/System/Xml/Xsl/QIL/WhitespaceRule.cs | 14 +- .../src/System/Xml/Xsl/QueryReaderSettings.cs | 18 +- .../src/System/Xml/Xsl/SourceLineInfo.cs | 11 +- .../System/Xml/Xsl/XPath/IXPathEnvironment.cs | 2 +- .../src/System/Xml/Xsl/XPath/XPathBuilder.cs | 34 +- .../Xml/Xsl/XPath/XPathCompileException.cs | 2 +- .../System/Xml/Xsl/XPath/XPathQilFactory.cs | 40 +- .../src/System/Xml/Xsl/XmlILCommand.cs | 7 +- .../src/System/Xml/Xsl/XmlIlGenerator.cs | 45 +- .../src/System/Xml/Xsl/XmlNodeKindFlags.cs | 1 + .../System/Xml/Xsl/XmlQualifiedNameTest.cs | 5 +- .../src/System/Xml/Xsl/XmlQueryCardinality.cs | 4 +- .../src/System/Xml/Xsl/XmlQueryType.cs | 21 +- .../src/System/Xml/Xsl/XmlQueryTypeFactory.cs | 28 +- .../src/System/Xml/Xsl/XslException.cs | 40 +- .../src/System/Xml/Xsl/Xslt/Compiler.cs | 53 ++- .../src/System/Xml/Xsl/Xslt/CompilerError.cs | 1 + .../Xml/Xsl/Xslt/CompilerScopeManager.cs | 32 +- .../src/System/Xml/Xsl/Xslt/Focus.cs | 30 +- .../src/System/Xml/Xsl/Xslt/IErrorHelper.cs | 5 +- .../System/Xml/Xsl/Xslt/InvokeGenerator.cs | 29 +- .../System/Xml/Xsl/Xslt/KeyMatchBuilder.cs | 9 +- .../src/System/Xml/Xsl/Xslt/Keywords.cs | 1 + .../src/System/Xml/Xsl/Xslt/MatcherBuilder.cs | 34 +- .../System/Xml/Xsl/Xslt/OutputScopeManager.cs | 16 +- .../src/System/Xml/Xsl/Xslt/QilGenerator.cs | 347 +++++++------- .../System/Xml/Xsl/Xslt/QilGeneratorEnv.cs | 68 +-- .../System/Xml/Xsl/Xslt/QilStrConcatenator.cs | 9 +- .../src/System/Xml/Xsl/Xslt/Scripts.cs | 9 +- .../src/System/Xml/Xsl/Xslt/Stylesheet.cs | 1 + .../Xml/Xsl/Xslt/XPathPatternBuilder.cs | 20 +- .../src/System/Xml/Xsl/Xslt/XslAst.cs | 126 ++--- .../src/System/Xml/Xsl/Xslt/XslAstAnalyzer.cs | 197 ++++---- .../src/System/Xml/Xsl/Xslt/XslFlags.cs | 1 + .../src/System/Xml/Xsl/Xslt/XslVisitor.cs | 5 +- .../src/System/Xml/Xsl/Xslt/XsltInput.cs | 71 +-- .../src/System/Xml/Xsl/Xslt/XsltLoader.cs | 261 ++++++----- .../src/System/Xml/Xsl/Xslt/XsltQilFactory.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/Action.cs | 1 + .../src/System/Xml/Xsl/XsltOld/ActionFrame.cs | 59 +-- .../Xml/Xsl/XsltOld/ApplyImportsAction.cs | 5 +- .../Xml/Xsl/XsltOld/ApplyTemplatesAction.cs | 11 +- .../System/Xml/Xsl/XsltOld/AttributeAction.cs | 23 +- .../Xml/Xsl/XsltOld/AttributeSetAction.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/Avt.cs | 11 +- .../src/System/Xml/Xsl/XsltOld/AvtEvent.cs | 1 + .../src/System/Xml/Xsl/XsltOld/BeginEvent.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/BuilderInfo.cs | 24 +- .../Xml/Xsl/XsltOld/CallTemplateAction.cs | 9 +- .../System/Xml/Xsl/XsltOld/ChooseAction.cs | 3 +- .../System/Xml/Xsl/XsltOld/CommentAction.cs | 1 + .../System/Xml/Xsl/XsltOld/CompiledAction.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/Compiler.cs | 111 ++--- .../System/Xml/Xsl/XsltOld/ContainerAction.cs | 57 +-- .../src/System/Xml/Xsl/XsltOld/CopyAction.cs | 11 +- .../Xml/Xsl/XsltOld/CopyAttributesAction.cs | 11 +- .../System/Xml/Xsl/XsltOld/CopyCodeAction.cs | 5 +- .../Xml/Xsl/XsltOld/CopyNamespacesAction.cs | 9 +- .../Xml/Xsl/XsltOld/CopyNodeSetAction.cs | 9 +- .../System/Xml/Xsl/XsltOld/CopyOfAction.cs | 5 +- .../src/System/Xml/Xsl/XsltOld/DbgCompiler.cs | 13 +- .../System/Xml/Xsl/XsltOld/DocumentScope.cs | 13 +- .../System/Xml/Xsl/XsltOld/ElementAction.cs | 23 +- .../src/System/Xml/Xsl/XsltOld/EndEvent.cs | 1 + .../src/System/Xml/Xsl/XsltOld/Event.cs | 1 + .../System/Xml/Xsl/XsltOld/ForEachAction.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/HtmlProps.cs | 9 +- .../System/Xml/Xsl/XsltOld/IRecordOutput.cs | 1 + .../src/System/Xml/Xsl/XsltOld/IfAction.cs | 1 + .../src/System/Xml/Xsl/XsltOld/InputScope.cs | 33 +- .../Xml/Xsl/XsltOld/InputScopeManager.cs | 17 +- .../System/Xml/Xsl/XsltOld/MessageAction.cs | 3 +- .../System/Xml/Xsl/XsltOld/NameSpaceEvent.cs | 5 +- .../System/Xml/Xsl/XsltOld/NamespaceDecl.cs | 13 +- .../System/Xml/Xsl/XsltOld/NavigatorInput.cs | 19 +- .../System/Xml/Xsl/XsltOld/NavigatorOutput.cs | 5 +- .../System/Xml/Xsl/XsltOld/NumberAction.cs | 87 ++-- .../src/System/Xml/Xsl/XsltOld/OutKeywords.cs | 3 +- .../src/System/Xml/Xsl/XsltOld/OutputScope.cs | 12 +- .../Xml/Xsl/XsltOld/OutputScopeManager.cs | 21 +- .../src/System/Xml/Xsl/XsltOld/PrefixQName.cs | 11 +- .../XsltOld/ProcessingInstructionAction.cs | 9 +- .../src/System/Xml/Xsl/XsltOld/Processor.cs | 144 +++--- .../System/Xml/Xsl/XsltOld/ReaderOutput.cs | 83 ++-- .../System/Xml/Xsl/XsltOld/RecordBuilder.cs | 57 +-- .../src/System/Xml/Xsl/XsltOld/RootAction.cs | 40 +- .../Xml/Xsl/XsltOld/SequentialOutput.cs | 35 +- .../src/System/Xml/Xsl/XsltOld/SortAction.cs | 25 +- .../System/Xml/Xsl/XsltOld/StateMachine.cs | 1 + .../System/Xml/Xsl/XsltOld/StringOutput.cs | 7 +- .../src/System/Xml/Xsl/XsltOld/Stylesheet.cs | 77 +-- .../System/Xml/Xsl/XsltOld/TemplateAction.cs | 13 +- .../Xml/Xsl/XsltOld/TemplateBaseAction.cs | 1 + .../Xml/Xsl/XsltOld/TemplateLookupAction.cs | 42 +- .../System/Xml/Xsl/XsltOld/TemplateManager.cs | 11 +- .../src/System/Xml/Xsl/XsltOld/TextAction.cs | 3 +- .../src/System/Xml/Xsl/XsltOld/TextEvent.cs | 5 +- .../System/Xml/Xsl/XsltOld/TextOnlyOutput.cs | 1 + .../src/System/Xml/Xsl/XsltOld/TextOutput.cs | 5 +- .../src/System/Xml/Xsl/XsltOld/TheQuery.cs | 1 + .../Xml/Xsl/XsltOld/UseAttributeSetsAction.cs | 11 +- .../System/Xml/Xsl/XsltOld/ValueOfAction.cs | 5 +- .../System/Xml/Xsl/XsltOld/VariableAction.cs | 19 +- .../System/Xml/Xsl/XsltOld/WithParamAction.cs | 9 +- .../System/Xml/Xsl/XsltOld/WriterOutput.cs | 5 +- .../Xml/Xsl/XsltOld/XsltCompileContext.cs | 131 +++--- .../System/Xml/Xsl/XsltOld/XsltDebugger.cs | 1 + .../src/System/Xml/Xsl/XsltOld/XsltOutput.cs | 15 +- .../Xml/Xsl/XsltOld/newinstructionaction.cs | 5 +- .../System/Xml/Xslt/XslCompiledTransform.cs | 90 ++-- .../src/System/Xml/Xslt/XslTransform.cs | 87 ++-- .../src/System/Xml/Xslt/XsltArgumentList.cs | 15 +- .../src/System/Xml/Xslt/XsltContext.cs | 1 + .../src/System/Xml/Xslt/XsltException.cs | 45 +- .../src/System/Xml/Xslt/XsltSettings.cs | 1 + 171 files changed, 2544 insertions(+), 2266 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs index ae0e4144c36e..2fab357bfc26 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/BooleanFunctions.cs @@ -42,7 +42,7 @@ public override object Evaluate(XPathNodeIterator nodeIterator) => FT.FuncNot => Not(nodeIterator), FT.FuncTrue => true, FT.FuncFalse => false, - FT.FuncLang => Lang(nodeIterator), + FT.FuncLang => Lang(nodeIterator!), _ => false, }; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs index e8c5556b22ea..736a8159f219 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/CompiledXPathExpr.cs @@ -162,7 +162,7 @@ internal sealed class XPathComparerHelper : IComparer private readonly CultureInfo _cinfo; private readonly XmlDataType _dataType; - public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) + public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string? lang, XmlDataType dataType) { if (lang == null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs index 6725fea72579..1f463a451de2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/ContextQuery.cs @@ -14,10 +14,12 @@ public ContextQuery() { this.count = 0; } + protected ContextQuery(ContextQuery other) : base(other) { this.contextNode = other.contextNode; // Don't need to clone here } + public override void Reset() { count = 0; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs index 31a38e173321..405319df5b63 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/FunctionQuery.cs @@ -82,7 +82,7 @@ public override object Evaluate(XPathNodeIterator nodeIterator) try { Debug.Assert(_function != null); - object? retVal = ProcessResult(_function.Invoke(xsltContext, argVals, nodeIterator.Current)); + object? retVal = ProcessResult(_function.Invoke(xsltContext, argVals, nodeIterator.Current!)); // ProcessResult may return null when the input value is XmlNode and here doesn't seem to be the case. Debug.Assert(retVal != null); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs index 6675f776aa35..3cf4ae14fe12 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/NumberFunctions.cs @@ -59,7 +59,7 @@ private double Number(XPathNodeIterator nodeIterator) { if (_arg == null) { - Debug.Assert(nodeIterator.Current != null); + Debug.Assert(nodeIterator!.Current != null); return XmlConvert.ToXPathDouble(nodeIterator.Current.Value); } object argVal = _arg.Evaluate(nodeIterator); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs index d2634c7084ed..3ea556f6d736 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/Internal/StringFunctions.cs @@ -212,7 +212,7 @@ private double StringLength(XPathNodeIterator nodeIterator) { return _argList[0].Evaluate(nodeIterator).ToString()!.Length; } - Debug.Assert(nodeIterator.Current != null); + Debug.Assert(nodeIterator!.Current != null); return nodeIterator.Current.Value.Length; } @@ -225,7 +225,7 @@ private string Normalize(XPathNodeIterator nodeIterator) } else { - Debug.Assert(nodeIterator.Current != null); + Debug.Assert(nodeIterator!.Current != null); value = nodeIterator.Current.Value; } int modifyPos = -1; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ISourceLineInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ISourceLineInfo.cs index bf93c639cc49..8a45cc4da4e4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ISourceLineInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ISourceLineInfo.cs @@ -1,11 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml.Xsl { internal interface ISourceLineInfo { - string Uri { get; } + string? Uri { get; } bool IsNoSource { get; } Location Start { get; } Location End { get; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/GenerateHelper.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/GenerateHelper.cs index fb8401058ecb..1b770d4d5b1e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/GenerateHelper.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/GenerateHelper.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. +#nullable enable using System; using System.Globalization; using System.Xml; @@ -17,6 +18,7 @@ using System.Xml.Xsl.Qil; using System.Xml.Xsl.Runtime; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.IlGen { @@ -26,16 +28,16 @@ namespace System.Xml.Xsl.IlGen internal class XmlILStorageMethods { // Aggregates - public MethodInfo AggAvg; - public MethodInfo AggAvgResult; - public MethodInfo AggCreate; - public MethodInfo AggIsEmpty; - public MethodInfo AggMax; - public MethodInfo AggMaxResult; - public MethodInfo AggMin; - public MethodInfo AggMinResult; - public MethodInfo AggSum; - public MethodInfo AggSumResult; + public MethodInfo? AggAvg; + public MethodInfo? AggAvgResult; + public MethodInfo? AggCreate; + public MethodInfo? AggIsEmpty; + public MethodInfo? AggMax; + public MethodInfo? AggMaxResult; + public MethodInfo? AggMin; + public MethodInfo? AggMinResult; + public MethodInfo? AggSum; + public MethodInfo? AggSumResult; // Sequences public Type SeqType; @@ -51,10 +53,10 @@ internal class XmlILStorageMethods public MethodInfo IListItem; // XPathItem - public MethodInfo ValueAs; + public MethodInfo? ValueAs; // ToAtomicValue - public MethodInfo ToAtomicValue; + public MethodInfo? ToAtomicValue; public XmlILStorageMethods(Type storageType) { @@ -62,7 +64,9 @@ public XmlILStorageMethods(Type storageType) if (storageType == typeof(int) || storageType == typeof(long) || storageType == typeof(decimal) || storageType == typeof(double)) { - Type aggType = Type.GetType("System.Xml.Xsl.Runtime." + storageType.Name + "Aggregator"); + string aggTypeName = "System.Xml.Xsl.Runtime." + storageType.Name + "Aggregator"; + Type? aggType = Type.GetType(aggTypeName); + Debug.Assert(aggType != null, $"Could not find type `{aggTypeName}`"); AggAvg = XmlILMethods.GetMethod(aggType, "Average"); AggAvgResult = XmlILMethods.GetMethod(aggType, "get_AverageResult"); AggCreate = XmlILMethods.GetMethod(aggType, "Create"); @@ -92,7 +96,9 @@ public XmlILStorageMethods(Type storageType) SeqAdd = XmlILMethods.GetMethod(SeqType, "Add"); } - SeqEmpty = SeqType.GetField("Empty"); + FieldInfo? seqEmpty = SeqType.GetField("Empty"); + Debug.Assert(seqEmpty != null, "Field `Empty` could not be found"); + SeqEmpty = seqEmpty; SeqReuse = XmlILMethods.GetMethod(SeqType, "CreateOrReuse", SeqType); SeqReuseSgl = XmlILMethods.GetMethod(SeqType, "CreateOrReuse", SeqType, storageType); SeqSortByKeys = XmlILMethods.GetMethod(SeqType, "SortByKeys"); @@ -140,14 +146,14 @@ internal static class XmlILConstructors private static ConstructorInfo GetConstructor(Type className) { - ConstructorInfo constrInfo = className.GetConstructor(Array.Empty()); + ConstructorInfo constrInfo = className.GetConstructor(Array.Empty())!; Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null."); return constrInfo; } private static ConstructorInfo GetConstructor(Type className, params Type[] args) { - ConstructorInfo constrInfo = className.GetConstructor(args); + ConstructorInfo constrInfo = className.GetConstructor(args)!; Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null."); return constrInfo; } @@ -415,14 +421,14 @@ internal static class XmlILMethods public static MethodInfo GetMethod(Type className, string methName) { - MethodInfo methInfo = className.GetMethod(methName); + MethodInfo? methInfo = className.GetMethod(methName); Debug.Assert(methInfo != null, "Method " + className.Name + "." + methName + " cannot be null."); return methInfo; } public static MethodInfo GetMethod(Type className, string methName, params Type[] args) { - MethodInfo methInfo = className.GetMethod(methName, args); + MethodInfo? methInfo = className.GetMethod(methName, args); Debug.Assert(methInfo != null, "Method " + methName + " cannot be null."); return methInfo; } @@ -448,22 +454,22 @@ internal enum GenerateNameType /// internal class GenerateHelper { - private MethodBase _methInfo; - private ILGenerator _ilgen; - private LocalBuilder _locXOut; + private MethodBase? _methInfo; + private ILGenerator? _ilgen; + private LocalBuilder? _locXOut; private readonly XmlILModule _module; private readonly bool _isDebug; private bool _initWriters; private readonly StaticDataManager _staticData; - private ISourceLineInfo _lastSourceInfo; - private MethodInfo _methSyncToNav; + private ISourceLineInfo? _lastSourceInfo; + private MethodInfo? _methSyncToNav; #if DEBUG private int _lblNum; - private Hashtable _symbols; + private Hashtable? _symbols; private int _numLocals; - private string _sourceFile; - private TextWriter _writerDump; + private string? _sourceFile; + private TextWriter? _writerDump; #endif /// @@ -490,7 +496,7 @@ public GenerateHelper(XmlILModule module, bool isDebug) // SxS note: Using hardcoded "dump.il" is an SxS issue. Since we are doing this ONLY in debug builds // and only for tracing purposes and MakeVersionSafeName does not seem to be able to handle file // extensions correctly I decided to suppress the SxS message (as advised by SxS guys). - public void MethodBegin(MethodBase methInfo, ISourceLineInfo sourceInfo, bool initWriters) + public void MethodBegin(MethodBase methInfo, ISourceLineInfo? sourceInfo, bool initWriters) { _methInfo = methInfo; _ilgen = XmlILModule.DefineMethodBody(methInfo); @@ -505,7 +511,7 @@ public void MethodBegin(MethodBase methInfo, ISourceLineInfo sourceInfo, bool in _sourceFile = null; _writerDump = XmlILTrace.GetTraceWriter("dump.il"); - _writerDump.WriteLine(".method {0}()", methInfo.Name); + _writerDump!.WriteLine(".method {0}()", methInfo.Name); _writerDump.WriteLine("{"); } #endif @@ -559,7 +565,7 @@ public void MethodEnd() #if DEBUG if (XmlILTrace.IsEnabled) { - _writerDump.WriteLine("}"); + _writerDump!.WriteLine("}"); _writerDump.WriteLine(""); _writerDump.Close(); } @@ -583,7 +589,7 @@ public void CallSyncToNavigator() if (_methSyncToNav == null) _methSyncToNav = _module.FindMethod("SyncToNavigator"); - Call(_methSyncToNav); + Call(_methSyncToNav!); } //----------------------------------------------- @@ -633,11 +639,11 @@ public void LoadType(Type clrTyp) /// public LocalBuilder DeclareLocal(string name, Type type) { - LocalBuilder locBldr = _ilgen.DeclareLocal(type); + LocalBuilder locBldr = _ilgen!.DeclareLocal(type); #if DEBUG if (XmlILTrace.IsEnabled) { - _symbols.Add(locBldr, name + _numLocals.ToString(CultureInfo.InvariantCulture)); + _symbols!.Add(locBldr, name + _numLocals.ToString(CultureInfo.InvariantCulture)); _numLocals++; } #endif @@ -663,7 +669,7 @@ public void LoadXsltLibrary() public void LoadQueryOutput() { - Emit(OpCodes.Ldloc, _locXOut); + Emit(OpCodes.Ldloc, _locXOut!); } @@ -801,7 +807,7 @@ private void TraceCall(OpCode opcode, MethodInfo meth) retType = meth.ReturnType.Name; } - _writerDump.WriteLine(" {0, -10} {1} {2}({3})", new object[] { opcode.Name, retType, meth.Name, strBldr.ToString() }); + _writerDump!.WriteLine(" {0, -10} {1} {2}({3})", new object?[] { opcode.Name, retType, meth.Name, strBldr.ToString() }); } #endif } @@ -811,7 +817,7 @@ public void Call(MethodInfo meth) OpCode opcode = meth.IsVirtual || meth.IsAbstract ? OpCodes.Callvirt : OpCodes.Call; TraceCall(opcode, meth); - _ilgen.Emit(opcode, meth); + _ilgen!.Emit(opcode, meth); if (_lastSourceInfo != null) { @@ -919,7 +925,7 @@ public void ConstructLiteralQName(string localName, string namespaceName) public void CallArithmeticOp(QilNodeType opType, XmlTypeCode code) { - MethodInfo meth = null; + MethodInfo? meth = null; switch (code) { @@ -962,7 +968,7 @@ public void CallArithmeticOp(QilNodeType opType, XmlTypeCode code) public void CallCompareEquals(XmlTypeCode code) { - MethodInfo meth = null; + MethodInfo? meth = null; switch (code) { @@ -979,7 +985,7 @@ public void CallCompareEquals(XmlTypeCode code) public void CallCompare(XmlTypeCode code) { - MethodInfo meth = null; + MethodInfo? meth = null; switch (code) { @@ -1010,7 +1016,7 @@ public void CallStartRtfConstruction(string baseUri) public void CallEndRtfConstruction() { LoadQueryRuntime(); - Emit(OpCodes.Ldloca, _locXOut); + Emit(OpCodes.Ldloca, _locXOut!); Call(XmlILMethods.EndRtfConstr); } @@ -1025,7 +1031,7 @@ public void CallStartSequenceConstruction() public void CallEndSequenceConstruction() { LoadQueryRuntime(); - Emit(OpCodes.Ldloca, _locXOut); + Emit(OpCodes.Ldloca, _locXOut!); Call(XmlILMethods.EndSeqConstr); } @@ -1092,6 +1098,7 @@ public void CallGetCollation(int idxName) Call(XmlILMethods.GetCollation); } + [MemberNotNull(nameof(_locXOut))] private void EnsureWriter() { // If write variable has not yet been initialized, do it now @@ -1100,6 +1107,8 @@ private void EnsureWriter() _locXOut = DeclareLocal("$$$xwrtChk", typeof(XmlQueryOutput)); _initWriters = true; } + + Debug.Assert(_locXOut != null); } @@ -1148,7 +1157,7 @@ public void CallWriteEndRoot() public void CallWriteStartElement(GenerateNameType nameType, bool callChk) { - MethodInfo meth = null; + MethodInfo? meth = null; // If runtime checks need to be made, if (callChk) @@ -1181,7 +1190,7 @@ public void CallWriteStartElement(GenerateNameType nameType, bool callChk) public void CallWriteEndElement(GenerateNameType nameType, bool callChk) { - MethodInfo meth = null; + MethodInfo? meth = null; // If runtime checks need to be made, if (callChk) @@ -1211,7 +1220,7 @@ public void CallStartElementContent() public void CallWriteStartAttribute(GenerateNameType nameType, bool callChk) { - MethodInfo meth = null; + MethodInfo? meth = null; // If runtime checks need to be made, if (callChk) @@ -1341,7 +1350,7 @@ public void CallCacheItem(Type itemStorageType) public void CallValueAs(Type clrType) { - MethodInfo meth; + MethodInfo? meth; meth = XmlILMethods.StorageMethods[clrType].ValueAs; if (meth == null) @@ -1366,9 +1375,9 @@ public void CallValueAs(Type clrType) // XmlSortKeyAccumulator methods //----------------------------------------------- - public void AddSortKey(XmlQueryType keyType) + public void AddSortKey(XmlQueryType? keyType) { - MethodInfo meth = null; + MethodInfo? meth = null; if (keyType == null) { @@ -1417,7 +1426,7 @@ public void AddSortKey(XmlQueryType keyType) /// public void DebugStartScope() { - _ilgen.BeginScope(); + _ilgen!.BeginScope(); } /// @@ -1425,7 +1434,7 @@ public void DebugStartScope() /// public void DebugEndScope() { - _ilgen.EndScope(); + _ilgen!.EndScope(); } /// @@ -1447,16 +1456,16 @@ public void DebugSequencePoint(ISourceLineInfo sourceInfo) MarkSequencePoint(sourceInfo); } - private string _lastUriString; - private string _lastFileName; + private string? _lastUriString; + private string? _lastFileName; // SQLBUDT 278010: debugger does not work with network paths in uri format, like file://server/share/dir/file private string GetFileName(ISourceLineInfo sourceInfo) { - string uriString = sourceInfo.Uri; - if ((object)uriString == (object)_lastUriString) + string uriString = sourceInfo.Uri!; + if ((object)uriString == (object?)_lastUriString) { - return _lastFileName; + return _lastFileName!; } _lastUriString = uriString; @@ -1480,15 +1489,15 @@ private void MarkSequencePoint(ISourceLineInfo sourceInfo) if (XmlILTrace.IsEnabled) { if (sourceInfo.IsNoSource) - _writerDump.WriteLine("//[no source]"); + _writerDump!.WriteLine("//[no source]"); else { if (sourceFile != _sourceFile) { _sourceFile = sourceFile; - _writerDump.WriteLine("// Source File '{0}'", _sourceFile); + _writerDump!.WriteLine("// Source File '{0}'", _sourceFile); } - _writerDump.WriteLine("//[{0},{1} -- {2},{3}]", sourceInfo.Start.Line, sourceInfo.Start.Pos, sourceInfo.End.Line, sourceInfo.End.Pos); + _writerDump!.WriteLine("//[{0},{1} -- {2},{3}]", sourceInfo.Start.Line, sourceInfo.Start.Pos, sourceInfo.End.Line, sourceInfo.End.Pos); } } #endif @@ -1504,11 +1513,11 @@ private void MarkSequencePoint(ISourceLineInfo sourceInfo) public Label DefineLabel() { - Label lbl = _ilgen.DefineLabel(); + Label lbl = _ilgen!.DefineLabel(); #if DEBUG if (XmlILTrace.IsEnabled) - _symbols.Add(lbl, ++_lblNum); + _symbols!.Add(lbl, ++_lblNum); #endif return lbl; @@ -1525,55 +1534,55 @@ public void MarkLabel(Label lbl) #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine("Label {0}:", _symbols[lbl]); + _writerDump!.WriteLine("Label {0}:", _symbols![lbl]); #endif - _ilgen.MarkLabel(lbl); + _ilgen!.MarkLabel(lbl); } public void Emit(OpCode opcode) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0}", opcode.Name); + _writerDump!.WriteLine(" {0}", opcode.Name); #endif - _ilgen.Emit(opcode); + _ilgen!.Emit(opcode); } public void Emit(OpCode opcode, byte byteVal) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, byteVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, byteVal); #endif - _ilgen.Emit(opcode, byteVal); + _ilgen!.Emit(opcode, byteVal); } public void Emit(OpCode opcode, ConstructorInfo constrInfo) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, constrInfo); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, constrInfo); #endif - _ilgen.Emit(opcode, constrInfo); + _ilgen!.Emit(opcode, constrInfo); } public void Emit(OpCode opcode, double dblVal) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, dblVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, dblVal); #endif - _ilgen.Emit(opcode, dblVal); + _ilgen!.Emit(opcode, dblVal); } public void Emit(OpCode opcode, FieldInfo fldInfo) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, fldInfo.Name); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, fldInfo.Name); #endif - _ilgen.Emit(opcode, fldInfo); + _ilgen!.Emit(opcode, fldInfo); } public void Emit(OpCode opcode, int intVal) @@ -1581,9 +1590,9 @@ public void Emit(OpCode opcode, int intVal) Debug.Assert(opcode.OperandType == OperandType.InlineI || opcode.OperandType == OperandType.InlineVar); #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, intVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, intVal); #endif - _ilgen.Emit(opcode, intVal); + _ilgen!.Emit(opcode, intVal); } public void Emit(OpCode opcode, long longVal) @@ -1591,9 +1600,9 @@ public void Emit(OpCode opcode, long longVal) Debug.Assert(opcode.OperandType == OperandType.InlineI8); #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, longVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, longVal); #endif - _ilgen.Emit(opcode, longVal); + _ilgen!.Emit(opcode, longVal); } public void Emit(OpCode opcode, Label lblVal) @@ -1601,9 +1610,9 @@ public void Emit(OpCode opcode, Label lblVal) Debug.Assert(!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S), "Use EmitUnconditionalBranch and be careful not to emit unverifiable code."); #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, _symbols[lblVal]); + _writerDump!.WriteLine(" {0, -10} Label {1}", opcode.Name, _symbols![lblVal]); #endif - _ilgen.Emit(opcode, lblVal); + _ilgen!.Emit(opcode, lblVal); } public void Emit(OpCode opcode, Label[] arrLabels) @@ -1611,51 +1620,51 @@ public void Emit(OpCode opcode, Label[] arrLabels) #if DEBUG if (XmlILTrace.IsEnabled) { - _writerDump.Write(" {0, -10} (Label {1}", opcode.Name, arrLabels.Length != 0 ? _symbols[arrLabels[0]].ToString() : ""); + _writerDump!.Write(" {0, -10} (Label {1}", opcode.Name, arrLabels.Length != 0 ? _symbols![arrLabels[0]]!.ToString() : ""); for (int i = 1; i < arrLabels.Length; i++) { - _writerDump.Write(", Label {0}", _symbols[arrLabels[i]]); + _writerDump.Write(", Label {0}", _symbols![arrLabels[i]]); } _writerDump.WriteLine(")"); } #endif - _ilgen.Emit(opcode, arrLabels); + _ilgen!.Emit(opcode, arrLabels); } public void Emit(OpCode opcode, LocalBuilder locBldr) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1} ({2})", opcode.Name, _symbols[locBldr], locBldr.LocalType.Name); + _writerDump!.WriteLine(" {0, -10} {1} ({2})", opcode.Name, _symbols![locBldr], locBldr.LocalType.Name); #endif - _ilgen.Emit(opcode, locBldr); + _ilgen!.Emit(opcode, locBldr); } public void Emit(OpCode opcode, sbyte sbyteVal) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, sbyteVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, sbyteVal); #endif - _ilgen.Emit(opcode, sbyteVal); + _ilgen!.Emit(opcode, sbyteVal); } public void Emit(OpCode opcode, string strVal) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} \"{1}\"", opcode.Name, strVal); + _writerDump!.WriteLine(" {0, -10} \"{1}\"", opcode.Name, strVal); #endif - _ilgen.Emit(opcode, strVal); + _ilgen!.Emit(opcode, strVal); } public void Emit(OpCode opcode, Type typVal) { #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} {1}", opcode.Name, typVal); + _writerDump!.WriteLine(" {0, -10} {1}", opcode.Name, typVal); #endif - _ilgen.Emit(opcode, typVal); + _ilgen!.Emit(opcode, typVal); } /// @@ -1706,9 +1715,9 @@ public void EmitUnconditionalBranch(OpCode opcode, Label lblTarget) #if DEBUG if (XmlILTrace.IsEnabled) - _writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, _symbols[lblTarget]); + _writerDump!.WriteLine(" {0, -10} Label {1}", opcode.Name, _symbols![lblTarget]); #endif - _ilgen.Emit(opcode, lblTarget); + _ilgen!.Emit(opcode, lblTarget); if (_lastSourceInfo != null && (opcode.Equals(OpCodes.Br) || opcode.Equals(OpCodes.Br_S))) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/IteratorDescriptor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/IteratorDescriptor.cs index 99befbe03dd9..d69b9853c28d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/IteratorDescriptor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/IteratorDescriptor.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -12,6 +13,7 @@ using System.Reflection; using System.Reflection.Emit; using System.Xml.Xsl.Runtime; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.IlGen { @@ -107,7 +109,7 @@ public static StorageDescriptor Local(LocalBuilder loc, Type itemStorageType, bo /// public static StorageDescriptor Current(LocalBuilder locIter, Type itemStorageType) { - Debug.Assert(locIter.LocalType.GetMethod("get_Current").ReturnType == itemStorageType, + Debug.Assert(locIter.LocalType.GetMethod("get_Current")!.ReturnType == itemStorageType, "Type " + itemStorageType + " does not match type of Current property."); StorageDescriptor storage = default; @@ -184,7 +186,7 @@ public int ParameterLocation /// /// Return the LocalBuilder that stores this iterator's values. /// - public LocalBuilder LocalLocation + public LocalBuilder? LocalLocation { get { return _locationObject as LocalBuilder; } } @@ -193,7 +195,7 @@ public LocalBuilder LocalLocation /// Return the LocalBuilder that will store this iterator's helper class. The Current property /// on this iterator can be accessed to get the current iteration value. /// - public LocalBuilder CurrentLocation + public LocalBuilder? CurrentLocation { get { return _locationObject as LocalBuilder; } } @@ -201,7 +203,7 @@ public LocalBuilder CurrentLocation /// /// Return the MethodInfo for the method that computes this global value. /// - public MethodInfo GlobalLocation + public MethodInfo? GlobalLocation { get { return _locationObject as MethodInfo; } } @@ -232,12 +234,12 @@ internal class IteratorDescriptor private GenerateHelper _helper; // Related iterators - private IteratorDescriptor _iterParent; + private IteratorDescriptor? _iterParent; // Iteration private Label _lblNext; private bool _hasNext; - private LocalBuilder _locPos; + private LocalBuilder? _locPos; // Branching private BranchingContext _brctxt; @@ -270,7 +272,8 @@ public IteratorDescriptor(IteratorDescriptor iterParent) /// /// Internal helper initializor. /// - private void Init(IteratorDescriptor iterParent, GenerateHelper helper) + [MemberNotNull(nameof(_helper))] + private void Init(IteratorDescriptor? iterParent, GenerateHelper helper) { _helper = helper; _iterParent = iterParent; @@ -284,7 +287,7 @@ private void Init(IteratorDescriptor iterParent, GenerateHelper helper) /// /// Return the iterator in which this iterator is nested. /// - public IteratorDescriptor ParentIterator + public IteratorDescriptor? ParentIterator { get { return _iterParent; } } @@ -361,7 +364,7 @@ public void LoopToEnd(Label lblOnEnd) /// This location is only defined on iterators, and then only if they might be /// referenced by a PositionOf operator. /// - public LocalBuilder LocalPosition + public LocalBuilder? LocalPosition { get { return _locPos; } set { _locPos = value; } @@ -509,12 +512,12 @@ public void PushValue() break; case ItemLocation.Local: - _helper.Emit(OpCodes.Ldloc, _storage.LocalLocation); + _helper.Emit(OpCodes.Ldloc, _storage.LocalLocation!); break; case ItemLocation.Current: - _helper.Emit(OpCodes.Ldloca, _storage.CurrentLocation); - _helper.Call(_storage.CurrentLocation.LocalType.GetMethod("get_Current")); + _helper.Emit(OpCodes.Ldloca, _storage.CurrentLocation!); + _helper.Call(_storage.CurrentLocation!.LocalType.GetMethod("get_Current")!); break; default: @@ -543,7 +546,7 @@ public void EnsureStack() case ItemLocation.Global: // Call method that computes the value of this global value _helper.LoadQueryRuntime(); - _helper.Call(_storage.GlobalLocation); + _helper.Call(_storage.GlobalLocation!); break; default: @@ -702,7 +705,7 @@ public void EnsureItemStorageType(XmlQueryType xmlType, Type storageTypeDest) // Destination type must be item, so generate code to create an XmlAtomicValue _helper.LoadInteger(_helper.StaticData.DeclareXmlType(xmlType)); _helper.LoadQueryRuntime(); - _helper.Call(XmlILMethods.StorageMethods[_storage.ItemStorageType].ToAtomicValue); + _helper.Call(XmlILMethods.StorageMethods[_storage.ItemStorageType].ToAtomicValue!); SetStorageType: _storage = _storage.ToStorageType(storageTypeDest); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/OptimizerPatterns.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/OptimizerPatterns.cs index e3fd512b884a..93904a435363 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/OptimizerPatterns.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/OptimizerPatterns.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.Xsl.Qil; @@ -58,23 +59,23 @@ internal class OptimizerPatterns : IQilAnnotation private int _patterns; // Set of patterns that the annotated Qil node and its subtree matches private bool _isReadOnly; // True if setters are disabled in the case of singleton OptimizerPatterns - private object _arg0, _arg1, _arg2; // Arguments to the matching patterns + private object? _arg0, _arg1, _arg2; // Arguments to the matching patterns - private static volatile OptimizerPatterns s_zeroOrOneDefault; - private static volatile OptimizerPatterns s_maybeManyDefault; - private static volatile OptimizerPatterns s_dodDefault; + private static volatile OptimizerPatterns? s_zeroOrOneDefault; + private static volatile OptimizerPatterns? s_maybeManyDefault; + private static volatile OptimizerPatterns? s_dodDefault; /// /// Get OptimizerPatterns annotation for the specified node. Lazily create if necessary. /// public static OptimizerPatterns Read(QilNode nd) { - XmlILAnnotation ann = nd.Annotation as XmlILAnnotation; - OptimizerPatterns optPatt = (ann != null) ? ann.Patterns : null; + XmlILAnnotation? ann = nd.Annotation as XmlILAnnotation; + OptimizerPatterns? optPatt = (ann != null) ? ann.Patterns : null; if (optPatt == null) { - if (!nd.XmlType.MaybeMany) + if (!nd.XmlType!.MaybeMany) { // Expressions with ZeroOrOne cardinality should always report IsDocOrderDistinct and NoContainedNodes if (s_zeroOrOneDefault == null) @@ -131,14 +132,14 @@ public static OptimizerPatterns Read(QilNode nd) public static OptimizerPatterns Write(QilNode nd) { XmlILAnnotation ann = XmlILAnnotation.Write(nd); - OptimizerPatterns optPatt = ann.Patterns; + OptimizerPatterns? optPatt = ann.Patterns; if (optPatt == null || optPatt._isReadOnly) { optPatt = new OptimizerPatterns(); ann.Patterns = optPatt; - if (!nd.XmlType.MaybeMany) + if (!nd.XmlType!.MaybeMany) { optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct); optPatt.AddPattern(OptimizerPatternName.SameDepth); @@ -224,7 +225,7 @@ public void AddArgument(OptimizerPatternArgument argId, object arg) /// public object GetArgument(OptimizerPatternArgument argNum) { - object arg = null; + object? arg = null; switch ((int)argNum) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs index eda928e80263..e0d47c7007d7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.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. +#nullable enable using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -14,7 +15,7 @@ namespace System.Xml.Xsl.IlGen /// This internal class maintains a list of unique values. Each unique value is assigned a unique ID, which can /// be used to quickly access the value, since it corresponds to the value's position in the list. /// - internal class UniqueList + internal class UniqueList where T : notnull { private readonly Dictionary _lookup = new Dictionary(); private readonly List _list = new List(); @@ -60,13 +61,13 @@ public T[] ToArray() /// internal class StaticDataManager { - private UniqueList _uniqueNames; - private UniqueList _uniqueFilters; - private List _prefixMappingsList; - private List _globalNames; - private UniqueList _earlyInfo; - private UniqueList _uniqueXmlTypes; - private UniqueList _uniqueCollations; + private UniqueList? _uniqueNames; + private UniqueList? _uniqueFilters; + private List? _prefixMappingsList; + private List? _globalNames; + private UniqueList? _earlyInfo; + private UniqueList? _uniqueXmlTypes; + private UniqueList? _uniqueCollations; /// /// Add "name" to the list of unique names that are used by this query. Return the index of @@ -83,7 +84,7 @@ public int DeclareName(string name) /// /// Return an array of all names that are used by the query (null if no names). /// - public string[] Names + public string[]? Names { get { return (_uniqueNames != null) ? _uniqueNames.ToArray() : null; } } @@ -104,7 +105,7 @@ public int DeclareNameFilter(string locName, string nsUri) /// Return an array of all name filters, where each name filter is represented as a pair of integer offsets (localName, namespaceUri) /// into the Names array (null if no name filters). /// - public Int32Pair[] NameFilters + public Int32Pair[]? NameFilters { get { return (_uniqueFilters != null) ? _uniqueFilters.ToArray() : null; } } @@ -140,7 +141,7 @@ public int DeclarePrefixMappings(IList list) /// /// Return an array of all prefix mappings that are used by the query to compute names (null if no mappings). /// - public StringPair[][] PrefixMappingsList + public StringPair[][]? PrefixMappingsList { get { return (_prefixMappingsList != null) ? _prefixMappingsList.ToArray() : null; } } @@ -163,7 +164,7 @@ public int DeclareGlobalValue(string name) /// /// Return an array containing the names of all global variables and parameters. /// - public string[] GlobalNames + public string[]? GlobalNames { get { return (_globalNames != null) ? _globalNames.ToArray() : null; } } @@ -183,7 +184,7 @@ public int DeclareEarlyBound(string namespaceUri, Type ebType) /// /// Return an array of all early bound information that is used by the query (null if none is used). /// - public EarlyBoundInfo[] EarlyBound + public EarlyBoundInfo[]? EarlyBound { get { @@ -210,7 +211,7 @@ public int DeclareXmlType(XmlQueryType type) /// /// Return an array of all types that are used by the query (null if no names). /// - public XmlQueryType[] XmlTypes + public XmlQueryType[]? XmlTypes { get { return (_uniqueXmlTypes != null) ? _uniqueXmlTypes.ToArray() : null; } } @@ -230,7 +231,7 @@ public int DeclareCollation(string collation) /// /// Return an array of all collations that are used by the query (null if no names). /// - public XmlCollation[] Collations + public XmlCollation[]? Collations { get { return (_uniqueCollations != null) ? _uniqueCollations.ToArray() : null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs index aa9e8ae0cd99..99cdf8f6a489 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/TailCallAnalyzer.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.Xsl.Qil; @@ -50,7 +51,7 @@ private static void AnalyzeDefinition(QilNode nd) { // Recursively analyze Loop return value QilLoop ndLoop = (QilLoop)nd; - if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany) + if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding!.XmlType!.MaybeMany) AnalyzeDefinition(ndLoop.Body); break; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILAnnotation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILAnnotation.cs index 0fdbb76a1c69..b691af96ffbd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILAnnotation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILAnnotation.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. +#nullable enable using System; using System.Reflection; using System.Xml.Xsl.Qil; @@ -10,14 +11,14 @@ namespace System.Xml.Xsl.IlGen /// /// Several annotations are created and attached to Qil nodes during the optimization and code generation phase. /// - internal class XmlILAnnotation : ListBase + internal class XmlILAnnotation : ListBase { - private readonly object _annPrev; - private MethodInfo _funcMethod; + private readonly object? _annPrev; + private MethodInfo? _funcMethod; private int _argPos; - private IteratorDescriptor _iterInfo; - private XmlILConstructInfo _constrInfo; - private OptimizerPatterns _optPatt; + private IteratorDescriptor? _iterInfo; + private XmlILConstructInfo? _constrInfo; + private OptimizerPatterns? _optPatt; //----------------------------------------------- @@ -29,7 +30,7 @@ internal class XmlILAnnotation : ListBase /// public static XmlILAnnotation Write(QilNode nd) { - XmlILAnnotation ann = nd.Annotation as XmlILAnnotation; + XmlILAnnotation? ann = nd.Annotation as XmlILAnnotation; if (ann == null) { @@ -40,7 +41,7 @@ public static XmlILAnnotation Write(QilNode nd) return ann; } - private XmlILAnnotation(object annPrev) + private XmlILAnnotation(object? annPrev) { _annPrev = annPrev; } @@ -54,7 +55,7 @@ private XmlILAnnotation(object annPrev) /// User-defined functions and global variables and parameters are bound to Clr MethodInfo objects. /// Attached to Function, global Let, and global Parameter nodes. /// - public MethodInfo FunctionBinding + public MethodInfo? FunctionBinding { get { return _funcMethod; } set { _funcMethod = value; } @@ -75,7 +76,7 @@ public int ArgumentPosition /// For/Let node is referenced. /// Attached to For and Let nodes. /// - public IteratorDescriptor CachedIteratorDescriptor + public IteratorDescriptor? CachedIteratorDescriptor { get { return _iterInfo; } set { _iterInfo = value; } @@ -85,7 +86,7 @@ public IteratorDescriptor CachedIteratorDescriptor /// Contains information about how this expression will be constructed by ILGen. /// Attached to any kind of Qil node. /// - public XmlILConstructInfo ConstructInfo + public XmlILConstructInfo? ConstructInfo { get { return _constrInfo; } set { _constrInfo = value; } @@ -95,7 +96,7 @@ public XmlILConstructInfo ConstructInfo /// Contains patterns that the subtree rooted at this node matches. /// Attached to any kind of Qil node. /// - public OptimizerPatterns Patterns + public OptimizerPatterns? Patterns { get { return _optPatt; } set { _optPatt = value; } @@ -117,7 +118,7 @@ public override int Count /// /// Return the annotation at the specified index. /// - public override object this[int index] + public override object? this[int index] { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs index f22db4ec2f1c..98ac3aea46d5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.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. +#nullable enable using System; using System.Xml; using System.Xml.Schema; @@ -53,19 +54,19 @@ internal class XmlILConstructInfo : IQilAnnotation private PossibleXmlStates _xstatesInitial, _xstatesFinal, _xstatesBeginLoop, _xstatesEndLoop; private bool _isNmspInScope, _mightHaveNmsp, _mightHaveAttrs, _mightHaveDupAttrs, _mightHaveNmspAfterAttrs; private XmlILConstructMethod _constrMeth; - private XmlILConstructInfo _parentInfo; - private ArrayList _callersInfo; + private XmlILConstructInfo? _parentInfo; + private ArrayList? _callersInfo; private bool _isReadOnly; - private static volatile XmlILConstructInfo s_default; + private static volatile XmlILConstructInfo? s_default; /// /// Get ConstructInfo annotation for the specified node. Lazily create if necessary. /// public static XmlILConstructInfo Read(QilNode nd) { - XmlILAnnotation ann = nd.Annotation as XmlILAnnotation; - XmlILConstructInfo constrInfo = (ann != null) ? ann.ConstructInfo : null; + XmlILAnnotation? ann = nd.Annotation as XmlILAnnotation; + XmlILConstructInfo? constrInfo = (ann != null) ? ann.ConstructInfo : null; if (constrInfo == null) { @@ -91,7 +92,7 @@ public static XmlILConstructInfo Read(QilNode nd) public static XmlILConstructInfo Write(QilNode nd) { XmlILAnnotation ann = XmlILAnnotation.Write(nd); - XmlILConstructInfo constrInfo = ann.ConstructInfo; + XmlILConstructInfo? constrInfo = ann.ConstructInfo; if (constrInfo == null || constrInfo._isReadOnly) { @@ -260,7 +261,7 @@ public bool PullFromIteratorFirst /// If the annotated expression will be constructed as the content of another constructor, and this can be /// guaranteed at compile-time, then this property will be the non-null XmlILConstructInfo of that constructor. /// - public XmlILConstructInfo ParentInfo + public XmlILConstructInfo? ParentInfo { //get { return this.parentInfo; } set @@ -274,7 +275,7 @@ public XmlILConstructInfo ParentInfo /// If the annotated expression will be constructed as the content of an ElementCtor, and this can be /// guaranteed at compile-time, then this property will be the non-null XmlILConstructInfo of that constructor. /// - public XmlILConstructInfo ParentElementInfo + public XmlILConstructInfo? ParentElementInfo { get { @@ -422,7 +423,7 @@ public override string ToString() /// internal class XmlILStateAnalyzer { - protected XmlILConstructInfo parentInfo; + protected XmlILConstructInfo? parentInfo; protected QilFactory fac; protected PossibleXmlStates xstates; protected bool withinElem; @@ -439,7 +440,7 @@ public XmlILStateAnalyzer(QilFactory fac) /// Perform analysis on the specified constructor and its content. Return the ndContent that was passed in, /// or a replacement. /// - public virtual QilNode Analyze(QilNode ndConstr, QilNode ndContent) + public virtual QilNode? Analyze(QilNode? ndConstr, QilNode? ndContent) { if (ndConstr == null) { @@ -514,7 +515,7 @@ public virtual QilNode Analyze(QilNode ndConstr, QilNode ndContent) ndContent = AnalyzeContent(ndContent); if (ndConstr.NodeType == QilNodeType.Choice) - AnalyzeChoice(ndConstr as QilChoice, this.parentInfo); + AnalyzeChoice((ndConstr as QilChoice)!, this.parentInfo); // Since Function will never be another node's content, set its final states here if (ndConstr.NodeType == QilNodeType.Function) @@ -558,10 +559,10 @@ protected virtual QilNode AnalyzeContent(QilNode nd) switch (nd.NodeType) { - case QilNodeType.Loop: AnalyzeLoop(nd as QilLoop, info); break; - case QilNodeType.Sequence: AnalyzeSequence(nd as QilList, info); break; - case QilNodeType.Conditional: AnalyzeConditional(nd as QilTernary, info); break; - case QilNodeType.Choice: AnalyzeChoice(nd as QilChoice, info); break; + case QilNodeType.Loop: AnalyzeLoop((nd as QilLoop)!, info); break; + case QilNodeType.Sequence: AnalyzeSequence((nd as QilList)!, info); break; + case QilNodeType.Conditional: AnalyzeConditional((nd as QilTernary)!, info); break; + case QilNodeType.Choice: AnalyzeChoice((nd as QilChoice)!, info); break; case QilNodeType.Error: case QilNodeType.Warning: @@ -570,7 +571,7 @@ protected virtual QilNode AnalyzeContent(QilNode nd) break; case QilNodeType.Nop: - ndChild = (nd as QilUnary).Child; + ndChild = (nd as QilUnary)!.Child; switch (ndChild.NodeType) { case QilNodeType.For: @@ -604,7 +605,7 @@ protected virtual QilNode AnalyzeContent(QilNode nd) /// protected virtual void AnalyzeLoop(QilLoop ndLoop, XmlILConstructInfo info) { - XmlQueryType typ = ndLoop.XmlType; + XmlQueryType typ = ndLoop.XmlType!; // Ensure that construct method is Writer info.ConstructMethod = XmlILConstructMethod.Writer; @@ -688,7 +689,7 @@ protected virtual void AnalyzeChoice(QilChoice ndChoice, XmlILConstructInfo info /// protected virtual void AnalyzeCopy(QilNode ndCopy, XmlILConstructInfo info) { - XmlQueryType typ = ndCopy.XmlType; + XmlQueryType typ = ndCopy.XmlType!; // Copying item(s) to output involves looping if there is not exactly one item in the sequence if (!typ.IsSingleton) @@ -805,9 +806,9 @@ public XmlILElementAnalyzer(QilFactory fac) : base(fac) /// Analyze the content argument of the ElementCtor. Try to eliminate as many runtime checks as possible, /// both for the ElementCtor and for content constructors. /// - public override QilNode Analyze(QilNode ndElem, QilNode ndContent) + public override QilNode? Analyze(QilNode? ndElem, QilNode? ndContent) { - Debug.Assert(ndElem.NodeType == QilNodeType.ElementCtor); + Debug.Assert(ndElem!.NodeType == QilNodeType.ElementCtor); this.parentInfo = XmlILConstructInfo.Write(ndElem); // Start by assuming that these properties are false (they default to true, but analyzer might be able to @@ -831,7 +832,7 @@ public override QilNode Analyze(QilNode ndElem, QilNode ndContent) protected override void AnalyzeLoop(QilLoop ndLoop, XmlILConstructInfo info) { // Constructing attributes/namespaces in a loop can cause duplicates, namespaces after attributes, etc. - if (ndLoop.XmlType.MaybeMany) + if (ndLoop.XmlType!.MaybeMany) CheckAttributeNamespaceConstruct(ndLoop.XmlType); base.AnalyzeLoop(ndLoop, info); @@ -844,11 +845,13 @@ protected override void AnalyzeCopy(QilNode ndCopy, XmlILConstructInfo info) { if (ndCopy.NodeType == QilNodeType.AttributeCtor) { - AnalyzeAttributeCtor(ndCopy as QilBinary, info); + QilBinary? binaryNode = ndCopy as QilBinary; + Debug.Assert(binaryNode != null); + AnalyzeAttributeCtor(binaryNode, info); } else { - CheckAttributeNamespaceConstruct(ndCopy.XmlType); + CheckAttributeNamespaceConstruct(ndCopy.XmlType!); } base.AnalyzeCopy(ndCopy, info); @@ -861,12 +864,13 @@ private void AnalyzeAttributeCtor(QilBinary ndAttr, XmlILConstructInfo info) { if (ndAttr.Left.NodeType == QilNodeType.LiteralQName) { - QilName ndName = ndAttr.Left as QilName; + QilName? ndName = ndAttr.Left as QilName; + Debug.Assert(ndName != null); XmlQualifiedName qname; int idx; // This attribute might be constructed on the parent element - this.parentInfo.MightHaveAttributes = true; + this.parentInfo!.MightHaveAttributes = true; // Check to see whether this attribute is a duplicate of a previous attribute if (!this.parentInfo.MightHaveDuplicateAttributes) @@ -875,7 +879,7 @@ private void AnalyzeAttributeCtor(QilBinary ndAttr, XmlILConstructInfo info) for (idx = 0; idx < _dupAttrs.Count; idx++) { - XmlQualifiedName qnameDup = (XmlQualifiedName)_dupAttrs[idx]; + XmlQualifiedName qnameDup = (XmlQualifiedName)_dupAttrs[idx]!; if ((object)qnameDup.Name == (object)qname.Name && (object)qnameDup.Namespace == (object)qname.Namespace) { @@ -898,7 +902,7 @@ private void AnalyzeAttributeCtor(QilBinary ndAttr, XmlILConstructInfo info) else { // Attribute prefix and namespace are not known at compile-time - CheckAttributeNamespaceConstruct(ndAttr.XmlType); + CheckAttributeNamespaceConstruct(ndAttr.XmlType!); } } @@ -911,7 +915,7 @@ private void CheckAttributeNamespaceConstruct(XmlQueryType typ) if ((typ.NodeKinds & XmlNodeKindFlags.Attribute) != XmlNodeKindFlags.None) { // Mark element as possibly having attributes and duplicate attributes (since we don't know the names) - this.parentInfo.MightHaveAttributes = true; + this.parentInfo!.MightHaveAttributes = true; this.parentInfo.MightHaveDuplicateAttributes = true; // Attribute namespaces might be declared @@ -922,7 +926,7 @@ private void CheckAttributeNamespaceConstruct(XmlQueryType typ) if ((typ.NodeKinds & XmlNodeKindFlags.Namespace) != XmlNodeKindFlags.None) { // Then element might have namespaces, - this.parentInfo.MightHaveNamespaces = true; + this.parentInfo!.MightHaveNamespaces = true; // If attributes might already have been constructed, if (this.parentInfo.MightHaveAttributes) @@ -978,7 +982,7 @@ private void AnalyzeContent(QilNode nd) { case QilNodeType.Loop: _addInScopeNmsp = false; - AnalyzeContent((nd as QilLoop).Body); + AnalyzeContent((nd as QilLoop)!.Body); break; case QilNodeType.Sequence: @@ -988,13 +992,13 @@ private void AnalyzeContent(QilNode nd) case QilNodeType.Conditional: _addInScopeNmsp = false; - AnalyzeContent((nd as QilTernary).Center); - AnalyzeContent((nd as QilTernary).Right); + AnalyzeContent((nd as QilTernary)!.Center); + AnalyzeContent((nd as QilTernary)!.Right); break; case QilNodeType.Choice: _addInScopeNmsp = false; - QilList ndBranches = (nd as QilChoice).Branches; + QilList ndBranches = (nd as QilChoice)!.Branches; for (int idx = 0; idx < ndBranches.Count; idx++) AnalyzeContent(ndBranches[idx]); @@ -1006,8 +1010,8 @@ private void AnalyzeContent(QilNode nd) _nsmgr.PushScope(); cntNmspSave = _cntNmsp; - if (CheckNamespaceInScope(nd as QilBinary)) - AnalyzeContent((nd as QilBinary).Right); + if (CheckNamespaceInScope((nd as QilBinary)!)) + AnalyzeContent((nd as QilBinary)!.Right); _nsmgr.PopScope(); _addInScopeNmsp = false; @@ -1016,15 +1020,15 @@ private void AnalyzeContent(QilNode nd) case QilNodeType.AttributeCtor: _addInScopeNmsp = false; - CheckNamespaceInScope(nd as QilBinary); + CheckNamespaceInScope((nd as QilBinary)!); break; case QilNodeType.NamespaceDecl: - CheckNamespaceInScope(nd as QilBinary); + CheckNamespaceInScope((nd as QilBinary)!); break; case QilNodeType.Nop: - AnalyzeContent((nd as QilUnary).Child); + AnalyzeContent((nd as QilUnary)!.Child); break; default: @@ -1040,8 +1044,9 @@ private void AnalyzeContent(QilNode nd) /// private bool CheckNamespaceInScope(QilBinary nd) { - QilName ndName; - string prefix, ns, prefixExisting, nsExisting; + QilName? ndName; + string prefix, ns; + string? prefixExisting, nsExisting; XPathNodeType nodeType; switch (nd.NodeType) @@ -1081,7 +1086,7 @@ private bool CheckNamespaceInScope(QilBinary nd) return false; // Atomize names - prefix = _nsmgr.NameTable.Add(prefix); + prefix = _nsmgr.NameTable!.Add(prefix); ns = _nsmgr.NameTable.Add(ns); // Determine whether namespace is already in-scope @@ -1090,10 +1095,10 @@ private bool CheckNamespaceInScope(QilBinary nd) _nsmgr.GetNamespaceDeclaration(iNmsp, out prefixExisting, out nsExisting); // If prefix is already declared, - if ((object)prefix == (object)prefixExisting) + if ((object)prefix == (object?)prefixExisting) { // Then if the namespace is the same, this namespace is redundant - if ((object)ns == (object)nsExisting) + if ((object)ns == (object?)nsExisting) XmlILConstructInfo.Write(nd).IsNamespaceInScope = true; // Else quit searching, because any further matching prefixes will be hidden (not in-scope) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILModule.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILModule.cs index 74e0fbeb689f..f6b43070e81b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILModule.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILModule.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. +#nullable enable using System.Collections; using System.Diagnostics; using System.Reflection; @@ -25,7 +26,7 @@ internal class XmlILModule private static long s_assemblyId; // Unique identifier used to ensure that assembly names are unique within AppDomain private static readonly ModuleBuilder s_LREModule = CreateLREModule(); // Module used to emit dynamic lightweight-reflection-emit (LRE) methods - private TypeBuilder _typeBldr; + private TypeBuilder? _typeBldr; private Hashtable _methods; private readonly bool _useLRE, _emitSymbols; @@ -114,7 +115,7 @@ public XmlILModule(bool useLRE, bool emitSymbols) /// /// Define a method in this module with the specified name and parameters. /// - public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, string[] paramNames, XmlILMethodAttributes xmlAttrs) + public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, string?[] paramNames, XmlILMethodAttributes xmlAttrs) { MethodInfo methResult; int uniqueId = 1; @@ -141,9 +142,7 @@ public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, if (!_useLRE) { - MethodBuilder methBldr; - - methBldr = _typeBldr.DefineMethod( + MethodBuilder methBldr = _typeBldr!.DefineMethod( name, MethodAttributes.Private | MethodAttributes.Static, returnType, @@ -161,7 +160,7 @@ public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, for (int i = 0; i < paramNames.Length; i++) { - if (paramNames[i] != null && paramNames[i].Length != 0) + if (paramNames[i] != null && paramNames[i]!.Length != 0) methBldr.DefineParameter(i + (isRaw ? 1 : 2), ParameterAttributes.None, paramNames[i]); } @@ -185,11 +184,11 @@ public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, /// public static ILGenerator DefineMethodBody(MethodBase methInfo) { - DynamicMethod methDyn = methInfo as DynamicMethod; + DynamicMethod? methDyn = methInfo as DynamicMethod; if (methDyn != null) return methDyn.GetILGenerator(); - MethodBuilder methBldr = methInfo as MethodBuilder; + MethodBuilder? methBldr = methInfo as MethodBuilder; if (methBldr != null) return methBldr.GetILGenerator(); @@ -199,9 +198,9 @@ public static ILGenerator DefineMethodBody(MethodBase methInfo) /// /// Find a MethodInfo of the specified name and return it. Return null if no such method exists. /// - public MethodInfo FindMethod(string name) + public MethodInfo? FindMethod(string name) { - return (MethodInfo)_methods[name]; + return (MethodInfo?)_methods[name]; } /// @@ -210,7 +209,7 @@ public MethodInfo FindMethod(string name) public FieldInfo DefineInitializedData(string name, byte[] data) { Debug.Assert(!_useLRE, "Cannot create initialized data for an LRE module"); - return _typeBldr.DefineInitializedData(name, data, FieldAttributes.Private | FieldAttributes.Static); + return _typeBldr!.DefineInitializedData(name, data, FieldAttributes.Private | FieldAttributes.Static); } /// @@ -219,7 +218,7 @@ public FieldInfo DefineInitializedData(string name, byte[] data) public FieldInfo DefineField(string fieldName, Type type) { Debug.Assert(!_useLRE, "Cannot create field for an LRE module"); - return _typeBldr.DefineField(fieldName, type, FieldAttributes.Private | FieldAttributes.Static); + return _typeBldr!.DefineField(fieldName, type, FieldAttributes.Private | FieldAttributes.Static); } /// @@ -228,7 +227,7 @@ public FieldInfo DefineField(string fieldName, Type type) public ConstructorInfo DefineTypeInitializer() { Debug.Assert(!_useLRE, "Cannot create type initializer for an LRE module"); - return _typeBldr.DefineTypeInitializer(); + return _typeBldr!.DefineTypeInitializer(); } /// @@ -242,7 +241,7 @@ public void BakeMethods() if (!_useLRE) { - typBaked = _typeBldr.CreateTypeInfo().AsType(); + typBaked = _typeBldr!.CreateTypeInfo()!.AsType(); // Replace all MethodInfos in this.methods methodsBaked = new Hashtable(_methods.Count); @@ -263,9 +262,9 @@ public void BakeMethods() public Delegate CreateDelegate(string name, Type typDelegate) { if (!_useLRE) - return ((MethodInfo)_methods[name]).CreateDelegate(typDelegate); + return ((MethodInfo)_methods[name]!).CreateDelegate(typDelegate); - return ((DynamicMethod)_methods[name]).CreateDelegate(typDelegate); + return ((DynamicMethod)_methods[name]!).CreateDelegate(typDelegate); } /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimization.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimization.cs index c00eb27ab801..d7c7c6df808e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimization.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimization.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. +#nullable enable namespace System.Xml.Xsl.IlGen { /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs index 2461629a0e55..fbdcd37eb200 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.Schema; using System.Xml.XPath; using System.Xml.Xsl.Qil; @@ -114,7 +116,7 @@ protected override QilNode Visit(QilNode nd) } // Continue visitation - return base.Visit(nd); + return base.Visit(nd!); } /// @@ -122,7 +124,7 @@ protected override QilNode Visit(QilNode nd) /// protected override QilNode VisitReference(QilNode oldNode) { - QilNode newNode = _subs.FindReplacement(oldNode); + QilNode? newNode = _subs.FindReplacement(oldNode); if (newNode == null) newNode = oldNode; @@ -133,7 +135,7 @@ protected override QilNode VisitReference(QilNode oldNode) { if (newNode.NodeType == QilNodeType.Let || newNode.NodeType == QilNodeType.For) { - QilNode binding = ((QilIterator)oldNode).Binding; + QilNode binding = ((QilIterator)oldNode).Binding!; if (IsLiteral(binding)) return Replace(XmlILOptimization.EliminateLiteralVariables, newNode, binding.ShallowClone(f)); @@ -141,11 +143,11 @@ protected override QilNode VisitReference(QilNode oldNode) } if (this[XmlILOptimization.EliminateUnusedGlobals]) { - if (IsGlobalValue(newNode)) - OptimizerPatterns.Write(newNode).AddPattern(OptimizerPatternName.IsReferenced); + if (IsGlobalValue(newNode!)) + OptimizerPatterns.Write(newNode!).AddPattern(OptimizerPatternName.IsReferenced); } - return base.VisitReference(newNode); + return base.VisitReference(newNode!); } /// @@ -167,7 +169,8 @@ protected QilNode Replace(XmlILOptimization pattern, QilNode original, QilNode r /// /// Called when all replacements have already been made and all annotations are complete. /// - protected override QilNode NoReplace(QilNode node) + [return: NotNullIfNotNull("node")] + protected override QilNode? NoReplace(QilNode? node) { // Calculate MaybeSideEffects pattern. This is done here rather than using P because every node needs // to compute it and P has no good way of matching every node type. @@ -252,12 +255,12 @@ protected override QilNode VisitQilExpression(QilExpression local0) if (IsConstructedExpression(ndFunc.Definition)) { // Perform state analysis on function's content - ndFunc.Definition = _contentAnalyzer.Analyze(ndFunc, ndFunc.Definition); + ndFunc.Definition = _contentAnalyzer.Analyze(ndFunc, ndFunc.Definition)!; } } // Perform state analysis on the root expression - local0.Root = _contentAnalyzer.Analyze(null, local0.Root); + local0.Root = _contentAnalyzer.Analyze(null, local0.Root)!; // Make sure that root expression is pushed to writer XmlILConstructInfo.Write(local0.Root).PushToWriterLast = true; @@ -289,7 +292,7 @@ protected override QilNode VisitDataSource(QilDataSource local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (DataSource $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -300,7 +303,7 @@ protected override QilNode VisitDataSource(QilDataSource local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (DataSource * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -331,7 +334,7 @@ protected override QilNode VisitError(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Error $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -348,7 +351,7 @@ protected override QilNode VisitWarning(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Warning $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -366,7 +369,7 @@ protected override QilNode VisitWarning(QilUnary local0) protected override QilNode VisitLet(QilIterator local0) { QilNode local1 = local0[0]; - if (((((local0).XmlType).IsSingleton) && (!(IsGlobalVariable(local0)))) && (this[XmlILOptimization.NormalizeSingletonLet])) + if (((((local0).XmlType)!.IsSingleton) && (!(IsGlobalVariable(local0)))) && (this[XmlILOptimization.NormalizeSingletonLet])) { // PATTERN: [NormalizeSingletonLet] $iter:(Let $bind:*) ^ (Single? (TypeOf $iter)) ^ ~((GlobalVariable? $iter)) => { ... } if (AllowReplace(XmlILOptimization.NormalizeSingletonLet, local0)) @@ -405,7 +408,7 @@ protected override QilNode VisitPositionOf(QilUnary local0) if (local1.NodeType == QilNodeType.For) { QilNode local2 = local1[0]; - if (((local2).XmlType).IsSingleton) + if (((local2).XmlType)!.IsSingleton) { // PATTERN: [EliminatePositionOf] (PositionOf (For $x:* ^ (Single? (TypeOf $x)))) => (LiteralInt32 1) if (AllowReplace(XmlILOptimization.EliminatePositionOf, local0)) @@ -438,7 +441,7 @@ protected override QilNode VisitAnd(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (And $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -449,7 +452,7 @@ protected override QilNode VisitAnd(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (And * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -511,7 +514,7 @@ protected override QilNode VisitOr(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Or $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -522,7 +525,7 @@ protected override QilNode VisitOr(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Or * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -583,7 +586,7 @@ protected override QilNode VisitNot(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Not $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -627,7 +630,7 @@ protected override QilNode VisitConditional(QilTernary local0) QilNode local3 = local0[2]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Conditional $x:* ^ (None? (TypeOf $x)) * *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -740,7 +743,7 @@ protected override QilNode VisitLength(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Length $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -765,7 +768,7 @@ protected override QilNode VisitLength(QilUnary local0) } if (this[XmlILOptimization.EliminateLength]) { - if ((((local1).XmlType).IsSingleton) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) + if ((((local1).XmlType)!.IsSingleton) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) { // PATTERN: [EliminateLength] (Length $x:* ^ (Single? (TypeOf $x)) ^ (NoSideEffects? $x)) => (LiteralInt32 1) if (AllowReplace(XmlILOptimization.EliminateLength, local0)) @@ -826,7 +829,7 @@ protected override QilNode VisitUnion(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Union $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -837,7 +840,7 @@ protected override QilNode VisitUnion(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Union * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -941,7 +944,7 @@ protected override QilNode VisitIntersection(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Intersection $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -952,7 +955,7 @@ protected override QilNode VisitIntersection(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Intersection * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1042,7 +1045,7 @@ protected override QilNode VisitDifference(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Difference $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1053,7 +1056,7 @@ protected override QilNode VisitDifference(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Difference * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1142,7 +1145,7 @@ protected override QilNode VisitAverage(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Average $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1153,7 +1156,7 @@ protected override QilNode VisitAverage(QilUnary local0) } if (this[XmlILOptimization.EliminateAverage]) { - if (((local1).XmlType).Cardinality == XmlQueryCardinality.Zero) + if (((local1).XmlType)!.Cardinality == XmlQueryCardinality.Zero) { // PATTERN: [EliminateAverage] (Average $x:* ^ (Empty? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.EliminateAverage, local0)) @@ -1170,7 +1173,7 @@ protected override QilNode VisitSum(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Sum $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1181,7 +1184,7 @@ protected override QilNode VisitSum(QilUnary local0) } if (this[XmlILOptimization.EliminateSum]) { - if (((local1).XmlType).Cardinality == XmlQueryCardinality.Zero) + if (((local1).XmlType)!.Cardinality == XmlQueryCardinality.Zero) { // PATTERN: [EliminateSum] (Sum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.EliminateSum, local0)) @@ -1198,7 +1201,7 @@ protected override QilNode VisitMinimum(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Minimum $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1209,7 +1212,7 @@ protected override QilNode VisitMinimum(QilUnary local0) } if (this[XmlILOptimization.EliminateMinimum]) { - if (((local1).XmlType).Cardinality == XmlQueryCardinality.Zero) + if (((local1).XmlType)!.Cardinality == XmlQueryCardinality.Zero) { // PATTERN: [EliminateMinimum] (Minimum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.EliminateMinimum, local0)) @@ -1226,7 +1229,7 @@ protected override QilNode VisitMaximum(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Maximum $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1237,7 +1240,7 @@ protected override QilNode VisitMaximum(QilUnary local0) } if (this[XmlILOptimization.EliminateMaximum]) { - if (((local1).XmlType).Cardinality == XmlQueryCardinality.Zero) + if (((local1).XmlType)!.Cardinality == XmlQueryCardinality.Zero) { // PATTERN: [EliminateMaximum] (Maximum $x:* ^ (Empty? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.EliminateMaximum, local0)) @@ -1257,7 +1260,7 @@ protected override QilNode VisitNegate(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Negate $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1270,7 +1273,7 @@ protected override QilNode VisitNegate(QilUnary local0) { if (local1.NodeType == QilNodeType.LiteralDecimal) { - decimal local2 = (decimal)((QilLiteral)local1).Value; + decimal local2 = (decimal)((QilLiteral)local1).Value!; // PATTERN: [EliminateNegate] (Negate (LiteralDecimal $x:*)) => (LiteralDecimal { -{$x} }) if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) { @@ -1282,7 +1285,7 @@ protected override QilNode VisitNegate(QilUnary local0) { if (local1.NodeType == QilNodeType.LiteralDouble) { - double local2 = (double)((QilLiteral)local1).Value; + double local2 = (double)((QilLiteral)local1).Value!; // PATTERN: [EliminateNegate] (Negate (LiteralDouble $x:*)) => (LiteralDouble { -{$x} }) if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) { @@ -1294,7 +1297,7 @@ protected override QilNode VisitNegate(QilUnary local0) { if (local1.NodeType == QilNodeType.LiteralInt32) { - int local2 = (int)((QilLiteral)local1).Value; + int local2 = (int)((QilLiteral)local1).Value!; // PATTERN: [EliminateNegate] (Negate (LiteralInt32 $x:*)) => (LiteralInt32 { -{$x} }) if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) { @@ -1306,7 +1309,7 @@ protected override QilNode VisitNegate(QilUnary local0) { if (local1.NodeType == QilNodeType.LiteralInt64) { - long local2 = (long)((QilLiteral)local1).Value; + long local2 = (long)((QilLiteral)local1).Value!; // PATTERN: [EliminateNegate] (Negate (LiteralInt64 $x:*)) => (LiteralInt64 { -{$x} }) if (AllowReplace(XmlILOptimization.EliminateNegate, local0)) { @@ -1323,7 +1326,7 @@ protected override QilNode VisitAdd(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Add $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1334,7 +1337,7 @@ protected override QilNode VisitAdd(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Add * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1380,7 +1383,7 @@ protected override QilNode VisitSubtract(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Subtract $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1391,7 +1394,7 @@ protected override QilNode VisitSubtract(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Subtract * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1423,7 +1426,7 @@ protected override QilNode VisitMultiply(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Multiply $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1434,7 +1437,7 @@ protected override QilNode VisitMultiply(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Multiply * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1480,7 +1483,7 @@ protected override QilNode VisitDivide(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Divide $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1491,7 +1494,7 @@ protected override QilNode VisitDivide(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Divide * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1523,7 +1526,7 @@ protected override QilNode VisitModulo(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Modulo $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1534,7 +1537,7 @@ protected override QilNode VisitModulo(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Modulo * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1568,7 +1571,7 @@ protected override QilNode VisitStrLength(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (StrLength $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1581,7 +1584,7 @@ protected override QilNode VisitStrLength(QilUnary local0) { if (local1.NodeType == QilNodeType.LiteralString) { - string local2 = (string)((QilLiteral)local1).Value; + string local2 = (string)((QilLiteral)local1).Value!; // PATTERN: [EliminateStrLength] (StrLength (LiteralString $x:*)) => (LiteralInt32 { {$x}.Length }) if (AllowReplace(XmlILOptimization.EliminateStrLength, local0)) { @@ -1598,7 +1601,7 @@ protected override QilNode VisitStrConcat(QilStrConcat local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (StrConcat $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1609,7 +1612,7 @@ protected override QilNode VisitStrConcat(QilStrConcat local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (StrConcat * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1618,7 +1621,7 @@ protected override QilNode VisitStrConcat(QilStrConcat local0) } } } - if ((((local2).XmlType).IsSingleton) && (this[XmlILOptimization.EliminateStrConcatSingle])) + if ((((local2).XmlType)!.IsSingleton) && (this[XmlILOptimization.EliminateStrConcatSingle])) { // PATTERN: [EliminateStrConcatSingle] (StrConcat * $x:*) ^ (Single? (TypeOf $x)) => (Nop $x) if (AllowReplace(XmlILOptimization.EliminateStrConcatSingle, local0)) @@ -1630,7 +1633,7 @@ protected override QilNode VisitStrConcat(QilStrConcat local0) { if (local1.NodeType == QilNodeType.LiteralString) { - string local3 = (string)((QilLiteral)local1).Value; + string local3 = (string)((QilLiteral)local1).Value!; if (local2.NodeType == QilNodeType.Sequence) { if (AreLiteralArgs(local2)) @@ -1659,7 +1662,7 @@ protected override QilNode VisitStrParseQName(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (StrParseQName $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1670,7 +1673,7 @@ protected override QilNode VisitStrParseQName(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (StrParseQName * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1691,7 +1694,7 @@ protected override QilNode VisitNe(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Ne $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1702,7 +1705,7 @@ protected override QilNode VisitNe(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Ne * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1747,15 +1750,15 @@ protected override QilNode VisitNe(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertNe] (Ne (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Ne $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertNe, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertNe, local0, VisitNe(f.Ne(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertNe, local0, VisitNe(f.Ne(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -1767,12 +1770,12 @@ protected override QilNode VisitNe(QilBinary local0) if (local1.NodeType == QilNodeType.XsltGenerateId) { QilNode local3 = local1[0]; - if (((local3).XmlType).IsSingleton) + if (((local3).XmlType)!.IsSingleton) { if (local2.NodeType == QilNodeType.XsltGenerateId) { QilNode local4 = local2[0]; - if (((local4).XmlType).IsSingleton) + if (((local4).XmlType)!.IsSingleton) { // PATTERN: [NormalizeIdNe] (Ne (XsltGenerateId $arg1:*) ^ (Single? (TypeOf $arg1)) (XsltGenerateId $arg2:*) ^ (Single? (TypeOf $arg2))) => (Not (Is $arg1 $arg2)) if (AllowReplace(XmlILOptimization.NormalizeIdNe, local0)) @@ -1791,7 +1794,7 @@ protected override QilNode VisitNe(QilBinary local0) QilNode local3 = local1[0]; if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; if (local4 == 0) { // PATTERN: [NormalizeLengthNe] (Ne (Length $expr:*) (LiteralInt32 0)) => (Not (IsEmpty $expr)) @@ -1809,7 +1812,7 @@ protected override QilNode VisitNe(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthNe] (Ne $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthNe, local0)) { @@ -1827,7 +1830,7 @@ protected override QilNode VisitEq(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Eq $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1838,7 +1841,7 @@ protected override QilNode VisitEq(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Eq * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -1883,15 +1886,15 @@ protected override QilNode VisitEq(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertEq] (Eq (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Eq $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertEq, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertEq, local0, VisitEq(f.Eq(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertEq, local0, VisitEq(f.Eq(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -1922,12 +1925,12 @@ protected override QilNode VisitEq(QilBinary local0) if (local1.NodeType == QilNodeType.XsltGenerateId) { QilNode local3 = local1[0]; - if (((local3).XmlType).IsSingleton) + if (((local3).XmlType)!.IsSingleton) { if (local2.NodeType == QilNodeType.XsltGenerateId) { QilNode local4 = local2[0]; - if (((local4).XmlType).IsSingleton) + if (((local4).XmlType)!.IsSingleton) { // PATTERN: [NormalizeIdEq] (Eq (XsltGenerateId $arg1:*) ^ (Single? (TypeOf $arg1)) (XsltGenerateId $arg2:*) ^ (Single? (TypeOf $arg2))) => (Is $arg1 $arg2) if (AllowReplace(XmlILOptimization.NormalizeIdEq, local0)) @@ -1944,7 +1947,7 @@ protected override QilNode VisitEq(QilBinary local0) if (local1.NodeType == QilNodeType.XsltGenerateId) { QilNode local3 = local1[0]; - if (((local3).XmlType).IsSingleton) + if (((local3).XmlType)!.IsSingleton) { if (local2.NodeType == QilNodeType.StrConcat) { @@ -1956,7 +1959,7 @@ protected override QilNode VisitEq(QilBinary local0) if (local6.NodeType == QilNodeType.For) { QilNode local7 = local6[0]; - if (!((local7).XmlType).MaybeMany) + if (!((local7).XmlType)!.MaybeMany) { if (local8.NodeType == QilNodeType.XsltGenerateId) { @@ -1990,7 +1993,7 @@ protected override QilNode VisitEq(QilBinary local0) if (local5.NodeType == QilNodeType.For) { QilNode local6 = local5[0]; - if (!((local6).XmlType).MaybeMany) + if (!((local6).XmlType)!.MaybeMany) { if (local7.NodeType == QilNodeType.XsltGenerateId) { @@ -2000,7 +2003,7 @@ protected override QilNode VisitEq(QilBinary local0) if (local2.NodeType == QilNodeType.XsltGenerateId) { QilNode local9 = local2[0]; - if (((local9).XmlType).IsSingleton) + if (((local9).XmlType)!.IsSingleton) { // PATTERN: [NormalizeIdEq] (Eq (StrConcat * (Loop $iter:(For $bind:* ^ (AtMostOne? (TypeOf $bind))) (XsltGenerateId $iter))) (XsltGenerateId $arg:*) ^ (Single? (TypeOf $arg))) => (Not (IsEmpty (Filter $iterNew:(For $bind) (Is $arg $iterNew)))) if (AllowReplace(XmlILOptimization.NormalizeIdEq, local0)) @@ -2026,11 +2029,11 @@ protected override QilNode VisitEq(QilBinary local0) { QilNode local4 = local3[0]; QilNode local5 = local3[1]; - if ((((local4).XmlType).IsSingleton) && (!((local5).XmlType).MaybeMany)) + if ((((local4).XmlType)!.IsSingleton) && (!((local5).XmlType)!.MaybeMany)) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local6 = (int)((QilLiteral)local2).Value; + int local6 = (int)((QilLiteral)local2).Value!; if (local6 == 1) { // PATTERN: [NormalizeMuenchian] (Eq (Length (Union $arg1:* $arg2:*) ^ (Single? (TypeOf $arg1)) ^ (AtMostOne? (TypeOf $arg2))) (LiteralInt32 1)) => (IsEmpty (Filter $iterNew:(For $arg2) (Not (Is $arg1 $iterNew)))) @@ -2054,11 +2057,11 @@ protected override QilNode VisitEq(QilBinary local0) { QilNode local4 = local3[0]; QilNode local5 = local3[1]; - if ((!((local4).XmlType).MaybeMany) && (((local5).XmlType).IsSingleton)) + if ((!((local4).XmlType)!.MaybeMany) && (((local5).XmlType)!.IsSingleton)) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local6 = (int)((QilLiteral)local2).Value; + int local6 = (int)((QilLiteral)local2).Value!; if (local6 == 1) { // PATTERN: [NormalizeMuenchian] (Eq (Length (Union $arg1:* $arg2:*) ^ (AtMostOne? (TypeOf $arg1)) ^ (Single? (TypeOf $arg2))) (LiteralInt32 1)) => (IsEmpty (Filter $iterNew:(For $arg1) (Not (Is $iterNew $arg2)))) @@ -2079,7 +2082,7 @@ protected override QilNode VisitEq(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthEq] (Eq $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthEq, local0)) { @@ -2097,7 +2100,7 @@ protected override QilNode VisitGt(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Gt $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2108,7 +2111,7 @@ protected override QilNode VisitGt(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Gt * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2153,15 +2156,15 @@ protected override QilNode VisitGt(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertGt] (Gt (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Gt $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertGt, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertGt, local0, VisitGt(f.Gt(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertGt, local0, VisitGt(f.Gt(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -2175,7 +2178,7 @@ protected override QilNode VisitGt(QilBinary local0) QilNode local3 = local1[0]; if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; if (local4 == 0) { // PATTERN: [NormalizeLengthGt] (Gt (Length $expr:*) (LiteralInt32 0)) => (Not (IsEmpty $expr)) @@ -2193,7 +2196,7 @@ protected override QilNode VisitGt(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthGt] (Gt $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthGt, local0)) { @@ -2211,7 +2214,7 @@ protected override QilNode VisitGe(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Ge $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2222,7 +2225,7 @@ protected override QilNode VisitGe(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Ge * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2267,15 +2270,15 @@ protected override QilNode VisitGe(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertGe] (Ge (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Ge $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertGe, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertGe, local0, VisitGe(f.Ge(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertGe, local0, VisitGe(f.Ge(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -2288,7 +2291,7 @@ protected override QilNode VisitGe(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthGe] (Ge $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthGe, local0)) { @@ -2306,7 +2309,7 @@ protected override QilNode VisitLt(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Lt $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2317,7 +2320,7 @@ protected override QilNode VisitLt(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Lt * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2362,15 +2365,15 @@ protected override QilNode VisitLt(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertLt] (Lt (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Lt $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertLt, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertLt, local0, VisitLt(f.Lt(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertLt, local0, VisitLt(f.Lt(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -2383,7 +2386,7 @@ protected override QilNode VisitLt(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthLt] (Lt $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthLt, local0)) { @@ -2401,7 +2404,7 @@ protected override QilNode VisitLe(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Le $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2412,7 +2415,7 @@ protected override QilNode VisitLe(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Le * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2457,15 +2460,15 @@ protected override QilNode VisitLe(QilBinary local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((IsPrimitiveNumeric((local3).XmlType)) && (IsPrimitiveNumeric(local5))) { - if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType))) + if ((IsLiteral((local2))) && (CanFoldXsltConvertNonLossy(local2, (local3).XmlType!))) { // PATTERN: [NormalizeXsltConvertLe] (Le (XsltConvert $expr:* (LiteralType $typ:*)) ^ (PrimitiveNumeric? (TypeOf $expr)) ^ (PrimitiveNumeric? $typ) $lit:* ^ (Literal? $lit) ^ (CanFoldXsltConvertNonLossy? $lit (TypeOf $expr))) => (Le $expr (FoldXsltConvert $lit (TypeOf $expr))) if (AllowReplace(XmlILOptimization.NormalizeXsltConvertLe, local0)) { - return Replace(XmlILOptimization.NormalizeXsltConvertLe, local0, VisitLe(f.Le(local3, FoldXsltConvert(local2, (local3).XmlType)))); + return Replace(XmlILOptimization.NormalizeXsltConvertLe, local0, VisitLe(f.Le(local3, FoldXsltConvert(local2, (local3).XmlType!)))); } } } @@ -2478,7 +2481,7 @@ protected override QilNode VisitLe(QilBinary local0) { if (local2.NodeType == QilNodeType.LiteralInt32) { - int local4 = (int)((QilLiteral)local2).Value; + int local4 = (int)((QilLiteral)local2).Value!; // PATTERN: [AnnotateMaxLengthLe] (Le $len:(Length *) (LiteralInt32 $num:*)) => (AddPattern $len {MaxPosition}) ^ (AddArgument $len {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxLengthLe, local0)) { @@ -2499,7 +2502,7 @@ protected override QilNode VisitIs(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Is $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2510,7 +2513,7 @@ protected override QilNode VisitIs(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Is * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2539,7 +2542,7 @@ protected override QilNode VisitAfter(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (After $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2550,7 +2553,7 @@ protected override QilNode VisitAfter(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (After * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2579,7 +2582,7 @@ protected override QilNode VisitBefore(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Before $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2590,7 +2593,7 @@ protected override QilNode VisitBefore(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Before * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2622,7 +2625,7 @@ protected override QilNode VisitLoop(QilLoop local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Loop $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i)) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2700,7 +2703,7 @@ protected override QilNode VisitLoop(QilLoop local0) if (local1.NodeType == QilNodeType.For) { QilNode local3 = local1[0]; - if (((local3).XmlType).IsSingleton) + if (((local3).XmlType!).IsSingleton) { if (local2.NodeType == QilNodeType.TextCtor) { @@ -2716,7 +2719,7 @@ protected override QilNode VisitLoop(QilLoop local0) } if (this[XmlILOptimization.EliminateIteratorUsedAtMostOnce]) { - if ((((local1).NodeType == QilNodeType.Let) || ((((QilNode)(local1)[0]).XmlType).IsSingleton)) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) + if ((((local1).NodeType == QilNodeType.Let) || ((((QilNode)(local1)[0]).XmlType!).IsSingleton)) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) { if (_nodeCounter.Count(local2, local1) <= 1) { @@ -2854,7 +2857,7 @@ protected override QilNode VisitLoop(QilLoop local0) if (local1.NodeType == QilNodeType.For) { QilNode local3 = local1[0]; - if (!((local3).XmlType).MaybeMany) + if (!((local3).XmlType!).MaybeMany) { // PATTERN: [AnnotateSingletonLoop] $outer:(Loop (For $bind:* ^ (AtMostOne? (TypeOf $bind))) $ret:*) => (InheritPattern $outer $ret {IsDocOrderDistinct}) ^ (InheritPattern $outer $ret {SameDepth}) ^ { } if (AllowReplace(XmlILOptimization.AnnotateSingletonLoop, local0)) @@ -2935,7 +2938,7 @@ protected override QilNode VisitFilter(QilLoop local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Filter $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i)) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -2946,7 +2949,7 @@ protected override QilNode VisitFilter(QilLoop local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Filter $i:* $w:* ^ (None? (TypeOf $w))) => (Loop $i $w) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3000,7 +3003,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local7.NodeType == QilNodeType.LiteralType) { - XmlQueryType local8 = (XmlQueryType)((QilLiteral)local7).Value; + XmlQueryType local8 = (XmlQueryType)((QilLiteral)local7).Value!; if ((local8) == (XmlQueryTypeFactory.Attribute)) { if (local9.NodeType == QilNodeType.Eq) @@ -3079,7 +3082,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local5.NodeType == QilNodeType.LiteralInt32) { - int local6 = (int)((QilLiteral)local5).Value; + int local6 = (int)((QilLiteral)local5).Value!; // PATTERN: [AnnotateMaxPositionEq] $outer:(Filter $iter:* (Eq (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxPositionEq, local0)) { @@ -3103,7 +3106,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local5.NodeType == QilNodeType.LiteralInt32) { - int local6 = (int)((QilLiteral)local5).Value; + int local6 = (int)((QilLiteral)local5).Value!; // PATTERN: [AnnotateMaxPositionLe] $outer:(Filter $iter:* (Le (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLe, local0)) { @@ -3127,7 +3130,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local5.NodeType == QilNodeType.LiteralInt32) { - int local6 = (int)((QilLiteral)local5).Value; + int local6 = (int)((QilLiteral)local5).Value!; // PATTERN: [AnnotateMaxPositionLt] $outer:(Filter $iter:* (Lt (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} { {$num} - 1 }) ^ { } if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLt, local0)) { @@ -3169,7 +3172,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local6.NodeType == QilNodeType.LiteralType) { - XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value; + XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value!; if ((local7) == (XmlQueryTypeFactory.Element)) { if (local8.NodeType == QilNodeType.Eq) @@ -3215,7 +3218,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local5.NodeType == QilNodeType.LiteralType) { - XmlQueryType local6 = (XmlQueryType)((QilLiteral)local5).Value; + XmlQueryType local6 = (XmlQueryType)((QilLiteral)local5).Value!; if (MatchesContentTest(local6)) { // PATTERN: [AnnotateFilterContentKind] $outer:(Filter $iter:(For $bind:* ^ (Pattern? $bind {Axis})) (IsType $iter (LiteralType $kind:* ^ (ContentTest? $kind)))) => (AddPattern $outer {FilterContentKind}) ^ (AddArgument $outer {KindTestType} $kind) ^ { } @@ -3245,7 +3248,7 @@ protected override QilNode VisitFilter(QilLoop local0) { if (local6.NodeType == QilNodeType.LiteralType) { - XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value; + XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value!; if ((local7) == (XmlQueryTypeFactory.Attribute)) { // PATTERN: [AnnotateFilterAttributeKind] $outer:(Filter $iter:(For (Content *)) (IsType $iter (LiteralType $kind:*) ^ (Equal? $kind (ConstructType {Attribute})))) => (AddPattern $outer {FilterAttributeKind}) ^ { } @@ -3272,7 +3275,7 @@ protected override QilNode VisitSort(QilLoop local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Sort $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i)) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3286,7 +3289,7 @@ protected override QilNode VisitSort(QilLoop local0) if (local1.NodeType == QilNodeType.For) { QilNode local3 = local1[0]; - if (((local3).XmlType).IsSingleton) + if (((local3).XmlType)!.IsSingleton) { // PATTERN: [EliminateSort] (Sort (For $bind:* ^ (Single? (TypeOf $bind))) *) => (Nop $bind) if (AllowReplace(XmlILOptimization.EliminateSort, local0)) @@ -3311,7 +3314,7 @@ protected override QilNode VisitSortKey(QilSortKey local0) QilNode local4 = local1[1]; if (local4.NodeType == QilNodeType.LiteralType) { - XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value; + XmlQueryType local5 = (XmlQueryType)((QilLiteral)local4).Value!; if ((((local3).XmlType) == (XmlQueryTypeFactory.IntX)) && ((local5) == (XmlQueryTypeFactory.DoubleX))) { // PATTERN: [NormalizeSortXsltConvert] (SortKey (XsltConvert $expr:* (LiteralType $typ:*)) ^ (Equal? (TypeOf $expr) (ConstructType {IntX})) ^ (Equal? $typ (ConstructType {DoubleX})) $coll:*) => (SortKey $expr $coll) @@ -3331,7 +3334,7 @@ protected override QilNode VisitDocOrderDistinct(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (DocOrderDistinct $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3483,7 +3486,7 @@ protected override QilNode VisitDocOrderDistinct(QilUnary local0) QilNode local3 = local2[0]; if (!(IsDocOrderDistinct(local3))) { - if ((!OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.IsPositional)) && ((local3).XmlType.IsSubtypeOf(XmlQueryTypeFactory.NodeNotRtfS))) + if ((!OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.IsPositional)) && ((local3).XmlType!.IsSubtypeOf(XmlQueryTypeFactory.NodeNotRtfS))) { if (((!(OptimizerPatterns.Read((QilNode)(local1)).MatchesPattern(OptimizerPatternName.FilterElements))) && (!(OptimizerPatterns.Read((QilNode)(local1)).MatchesPattern(OptimizerPatternName.FilterContentKind)))) && (!(OptimizerPatterns.Read((QilNode)(local1)).MatchesPattern(OptimizerPatternName.FilterAttributeKind)))) { @@ -3606,10 +3609,10 @@ protected override QilNode VisitFunction(QilFunction local0) QilNode local1 = local0[0]; QilNode local2 = local0[1]; QilNode local3 = local0[2]; - XmlQueryType local4 = (XmlQueryType)((QilFunction)local0).XmlType; - if (((local0).XmlType.IsSubtypeOf(XmlQueryTypeFactory.NodeS)) && (this[XmlILOptimization.AnnotateIndex1])) + XmlQueryType? local4 = (XmlQueryType?)((QilFunction)local0).XmlType; + if (((local0).XmlType!.IsSubtypeOf(XmlQueryTypeFactory.NodeS)) && (this[XmlILOptimization.AnnotateIndex1])) { - if (((local1.Count == 2) && (((QilNode)(local1)[0]).XmlType.IsSubtypeOf(XmlQueryTypeFactory.Node))) && ((((QilNode)(local1)[1]).XmlType) == (XmlQueryTypeFactory.StringX))) + if (((local1.Count == 2) && (((QilNode)(local1)[0]).XmlType!.IsSubtypeOf(XmlQueryTypeFactory.Node))) && ((((QilNode)(local1)[1]).XmlType) == (XmlQueryTypeFactory.StringX))) { if (local2.NodeType == QilNodeType.Filter) { @@ -3778,7 +3781,7 @@ protected override QilNode VisitContent(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Content $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3804,7 +3807,7 @@ protected override QilNode VisitAttribute(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Attribute $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3815,7 +3818,7 @@ protected override QilNode VisitAttribute(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Attribute * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3840,7 +3843,7 @@ protected override QilNode VisitParent(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Parent $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3865,7 +3868,7 @@ protected override QilNode VisitRoot(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Root $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3890,7 +3893,7 @@ protected override QilNode VisitDescendant(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Descendant $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3915,7 +3918,7 @@ protected override QilNode VisitDescendantOrSelf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (DescendantOrSelf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3940,7 +3943,7 @@ protected override QilNode VisitAncestor(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Ancestor $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3965,7 +3968,7 @@ protected override QilNode VisitAncestorOrSelf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (AncestorOrSelf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -3990,7 +3993,7 @@ protected override QilNode VisitPreceding(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Preceding $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4015,7 +4018,7 @@ protected override QilNode VisitFollowingSibling(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (FollowingSibling $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4040,7 +4043,7 @@ protected override QilNode VisitPrecedingSibling(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (PrecedingSibling $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4066,7 +4069,7 @@ protected override QilNode VisitNodeRange(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NodeRange $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4077,7 +4080,7 @@ protected override QilNode VisitNodeRange(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NodeRange * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4103,7 +4106,7 @@ protected override QilNode VisitDeref(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Deref $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4114,7 +4117,7 @@ protected override QilNode VisitDeref(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (Deref * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4135,7 +4138,7 @@ protected override QilNode VisitElementCtor(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (ElementCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4146,7 +4149,7 @@ protected override QilNode VisitElementCtor(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (ElementCtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4162,7 +4165,7 @@ protected override QilNode VisitElementCtor(QilBinary local0) { // The analysis occasionally makes small changes to the content of constructors, which is // why the result of Analyze is assigned to $ctor.Right. - local0.Right = _elemAnalyzer.Analyze(local0, local2); + local0.Right = _elemAnalyzer.Analyze(local0, local2)!; } } return NoReplace(local0); @@ -4174,7 +4177,7 @@ protected override QilNode VisitAttributeCtor(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (AttributeCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4185,7 +4188,7 @@ protected override QilNode VisitAttributeCtor(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (AttributeCtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4199,7 +4202,7 @@ protected override QilNode VisitAttributeCtor(QilBinary local0) // PATTERN: [AnnotateConstruction] $ctor:(AttributeCtor * $content:*) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Right = _contentAnalyzer.Analyze(local0, local2); + local0.Right = _contentAnalyzer.Analyze(local0, local2)!; } } return NoReplace(local0); @@ -4210,7 +4213,7 @@ protected override QilNode VisitCommentCtor(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (CommentCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4224,7 +4227,7 @@ protected override QilNode VisitCommentCtor(QilUnary local0) // PATTERN: [AnnotateConstruction] $ctor:(CommentCtor $content:*) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Child = _contentAnalyzer.Analyze(local0, local1); + local0.Child = _contentAnalyzer.Analyze(local0, local1)!; } } return NoReplace(local0); @@ -4236,7 +4239,7 @@ protected override QilNode VisitPICtor(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (PICtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4247,7 +4250,7 @@ protected override QilNode VisitPICtor(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (PICtor * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4261,7 +4264,7 @@ protected override QilNode VisitPICtor(QilBinary local0) // PATTERN: [AnnotateConstruction] $ctor:(PICtor * $content:*) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Right = _contentAnalyzer.Analyze(local0, local2); + local0.Right = _contentAnalyzer.Analyze(local0, local2)!; } } return NoReplace(local0); @@ -4272,7 +4275,7 @@ protected override QilNode VisitTextCtor(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (TextCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4297,7 +4300,7 @@ protected override QilNode VisitRawTextCtor(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (RawTextCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4322,7 +4325,7 @@ protected override QilNode VisitDocumentCtor(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (DocumentCtor $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4336,7 +4339,7 @@ protected override QilNode VisitDocumentCtor(QilUnary local0) // PATTERN: [AnnotateConstruction] $ctor:(DocumentCtor $content:*) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Child = _contentAnalyzer.Analyze(local0, local1); + local0.Child = _contentAnalyzer.Analyze(local0, local1)!; } } return NoReplace(local0); @@ -4348,7 +4351,7 @@ protected override QilNode VisitNamespaceDecl(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NamespaceDecl $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4359,7 +4362,7 @@ protected override QilNode VisitNamespaceDecl(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NamespaceDecl * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4393,7 +4396,7 @@ protected override QilNode VisitRtfCtor(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (RtfCtor $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4407,7 +4410,7 @@ protected override QilNode VisitRtfCtor(QilBinary local0) // PATTERN: [AnnotateConstruction] $ctor:(RtfCtor $content:* *) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Left = _contentAnalyzer.Analyze(local0, local1); + local0.Left = _contentAnalyzer.Analyze(local0, local1)!; } } if (this[XmlILOptimization.AnnotateSingleTextRtf]) @@ -4435,7 +4438,7 @@ protected override QilNode VisitNameOf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NameOf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4452,7 +4455,7 @@ protected override QilNode VisitLocalNameOf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (LocalNameOf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4469,7 +4472,7 @@ protected override QilNode VisitNamespaceUriOf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (NamespaceUriOf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4486,7 +4489,7 @@ protected override QilNode VisitPrefixOf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (PrefixOf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4507,7 +4510,7 @@ protected override QilNode VisitTypeAssert(QilTargetType local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (TypeAssert $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4520,8 +4523,8 @@ protected override QilNode VisitTypeAssert(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.NeverSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.NeverSubtypeOf(local3)) { // PATTERN: [EliminateTypeAssert] (TypeAssert $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (Error (LiteralString "")) if (AllowReplace(XmlILOptimization.EliminateTypeAssert, local0)) @@ -4535,8 +4538,8 @@ protected override QilNode VisitTypeAssert(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.Prime.NeverSubtypeOf(local3.Prime)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.Prime.NeverSubtypeOf(local3.Prime)) { // PATTERN: [EliminateTypeAssert] (TypeAssert $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (Prime (TypeOf $opnd)) (Prime $typ))) => (Conditional (IsEmpty $opnd) (Sequence) (Error (LiteralString ""))) if (AllowReplace(XmlILOptimization.EliminateTypeAssert, local0)) @@ -4550,8 +4553,8 @@ protected override QilNode VisitTypeAssert(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.IsSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.IsSubtypeOf(local3)) { // PATTERN: [EliminateTypeAssertOptional] (TypeAssert $opnd:* (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => $opnd if (AllowReplace(XmlILOptimization.EliminateTypeAssertOptional, local0)) @@ -4570,7 +4573,7 @@ protected override QilNode VisitIsType(QilTargetType local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (IsType $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4585,8 +4588,8 @@ protected override QilNode VisitIsType(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.IsSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.IsSubtypeOf(local3)) { // PATTERN: [EliminateIsType] (IsType $opnd:* ^ (NoSideEffects? $opnd) (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => (True) if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) @@ -4603,8 +4606,8 @@ protected override QilNode VisitIsType(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.NeverSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.NeverSubtypeOf(local3)) { // PATTERN: [EliminateIsType] (IsType $opnd:* ^ (NoSideEffects? $opnd) (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (False) if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) @@ -4619,8 +4622,8 @@ protected override QilNode VisitIsType(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.Prime.NeverSubtypeOf(local3.Prime)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.Prime.NeverSubtypeOf(local3.Prime)) { // PATTERN: [EliminateIsType] (IsType $opnd:* (LiteralType $typ:*) ^ (NeverSubtypeOf? (Prime (TypeOf $opnd)) (Prime $typ))) => (IsEmpty $opnd) if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) @@ -4636,8 +4639,8 @@ protected override QilNode VisitIsType(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.IsSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.IsSubtypeOf(local3)) { // PATTERN: [EliminateIsType] (IsType $opnd:* ^ ~((NoSideEffects? $opnd)) (LiteralType $base:*) ^ (SubtypeOf? (TypeOf $opnd) $base)) => (Loop (Let $opnd) (True)) if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) @@ -4654,8 +4657,8 @@ protected override QilNode VisitIsType(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; - if ((local1).XmlType.NeverSubtypeOf(local3)) + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; + if ((local1).XmlType!.NeverSubtypeOf(local3)) { // PATTERN: [EliminateIsType] (IsType $opnd:* ^ ~((NoSideEffects? $opnd)) (LiteralType $typ:*) ^ (NeverSubtypeOf? (TypeOf $opnd) $typ)) => (Loop (Let $opnd) (False)) if (AllowReplace(XmlILOptimization.EliminateIsType, local0)) @@ -4674,7 +4677,7 @@ protected override QilNode VisitIsEmpty(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (IsEmpty $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4699,7 +4702,7 @@ protected override QilNode VisitIsEmpty(QilUnary local0) } if (this[XmlILOptimization.EliminateIsEmpty]) { - if ((!((local1).XmlType).MaybeEmpty) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) + if ((!((local1).XmlType)!.MaybeEmpty) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))) { // PATTERN: [EliminateIsEmpty] (IsEmpty $expr:* ^ (NonEmpty? (TypeOf $expr)) ^ (NoSideEffects? $expr)) => (False) if (AllowReplace(XmlILOptimization.EliminateIsEmpty, local0)) @@ -4710,7 +4713,7 @@ protected override QilNode VisitIsEmpty(QilUnary local0) } if (this[XmlILOptimization.EliminateIsEmpty]) { - if (!((local1).XmlType).MaybeEmpty) + if (!((local1).XmlType)!.MaybeEmpty) { // PATTERN: [EliminateIsEmpty] (IsEmpty $expr:* ^ (NonEmpty? (TypeOf $expr))) => (Loop (Let $expr) (False)) if (AllowReplace(XmlILOptimization.EliminateIsEmpty, local0)) @@ -4730,7 +4733,7 @@ protected override QilNode VisitXPathNodeValue(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XPathNodeValue $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4747,7 +4750,7 @@ protected override QilNode VisitXPathFollowing(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XPathFollowing $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4772,7 +4775,7 @@ protected override QilNode VisitXPathPreceding(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XPathPreceding $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4797,7 +4800,7 @@ protected override QilNode VisitXPathNamespace(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XPathNamespace $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4825,7 +4828,7 @@ protected override QilNode VisitXsltGenerateId(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XsltGenerateId $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4843,7 +4846,7 @@ protected override QilNode VisitXsltCopy(QilBinary local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XsltCopy $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4854,7 +4857,7 @@ protected override QilNode VisitXsltCopy(QilBinary local0) } if (this[XmlILOptimization.FoldNone]) { - if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local2).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XsltCopy * $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4868,7 +4871,7 @@ protected override QilNode VisitXsltCopy(QilBinary local0) // PATTERN: [AnnotateConstruction] $ctor:(XsltCopy * $content:*) => { ... } if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) { - local0.Right = _contentAnalyzer.Analyze(local0, local2); + local0.Right = _contentAnalyzer.Analyze(local0, local2)!; } } return NoReplace(local0); @@ -4879,7 +4882,7 @@ protected override QilNode VisitXsltCopyOf(QilUnary local0) QilNode local1 = local0[0]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XsltCopyOf $x:* ^ (None? (TypeOf $x))) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4905,7 +4908,7 @@ protected override QilNode VisitXsltConvert(QilTargetType local0) QilNode local2 = local0[1]; if (this[XmlILOptimization.FoldNone]) { - if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None) + if ((object?)((local1).XmlType) == (object)XmlQueryTypeFactory.None) { // PATTERN: [FoldNone] (XsltConvert $x:* ^ (None? (TypeOf $x)) *) => (Nop $x) if (AllowReplace(XmlILOptimization.FoldNone, local0)) @@ -4920,7 +4923,7 @@ protected override QilNode VisitXsltConvert(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; if (CanFoldXsltConvert(local1, local3)) { // PATTERN: [FoldXsltConvertLiteral] (XsltConvert $lit:* ^ (Literal? $lit) (LiteralType $typ:*) ^ (CanFoldXsltConvert? $lit $typ)) => (FoldXsltConvert $lit $typ) @@ -4936,7 +4939,7 @@ protected override QilNode VisitXsltConvert(QilTargetType local0) { if (local2.NodeType == QilNodeType.LiteralType) { - XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value; + XmlQueryType local3 = (XmlQueryType)((QilLiteral)local2).Value!; if (((local1).XmlType) == (local3)) { // PATTERN: [EliminateXsltConvert] (XsltConvert $expr:* (LiteralType $typ:*) ^ (Equal? (TypeOf $expr) $typ)) => $expr @@ -4964,7 +4967,7 @@ private bool this[XmlILOptimization ann] private class NodeCounter : QilVisitor { - protected QilNode target; + protected QilNode? target; protected int cnt; /// @@ -4981,7 +4984,7 @@ public int Count(QilNode expr, QilNode target) protected override QilNode Visit(QilNode n) { if (n == null) - return null; + return null!; if (n == this.target) this.cnt++; @@ -5001,7 +5004,7 @@ protected override QilNode VisitReference(QilNode n) private class NodeFinder : QilVisitor { protected bool result; - protected QilNode target, parent; + protected QilNode? target, parent; /// /// Returns true if "target" node exists within the subtree of "expr". @@ -5027,7 +5030,7 @@ protected override QilNode Visit(QilNode expr) if (!this.result) { - QilNode parentOld = this.parent; + QilNode? parentOld = this.parent; this.parent = expr; VisitChildren(expr); this.parent = parentOld; @@ -5071,7 +5074,7 @@ protected override bool OnFound(QilNode expr) private class EqualityIndexVisitor : QilVisitor { protected bool result; - protected QilNode ctxt, key; + protected QilNode? ctxt, key; /// /// Returns true if the subtree of "expr" meets the following requirements: @@ -5173,7 +5176,7 @@ private bool IsGlobalValue(QilNode nd) /// /// Return true if "typ" is xs:decimal=, xs:integer=, xs:int=, xs:double=, or xs:float=. /// - private bool IsPrimitiveNumeric(XmlQueryType typ) + private bool IsPrimitiveNumeric(XmlQueryType? typ) { if (typ == XmlQueryTypeFactory.IntX) return true; if (typ == XmlQueryTypeFactory.IntegerX) return true; @@ -5212,7 +5215,7 @@ private bool IsConstructedExpression(QilNode nd) if (_qil.IsDebug) return true; - if (nd.XmlType.IsNode) + if (nd.XmlType!.IsNode) { switch (nd.NodeType) { @@ -5252,7 +5255,7 @@ private bool IsConstructedExpression(QilNode nd) case QilNodeType.Invoke: // Return true if the function might return nodes - return !((QilInvoke)nd).Function.XmlType.IsAtomicValue; + return !((QilInvoke)nd).Function.XmlType!.IsAtomicValue; } } @@ -5304,7 +5307,7 @@ private object ExtractLiteralValue(QilNode nd) return nd; Debug.Assert(nd is QilLiteral, "All literals except True, False, and QName must use QilLiteral"); - return ((QilLiteral)nd).Value; + return ((QilLiteral)nd).Value!; } /// @@ -5386,7 +5389,7 @@ private bool CanFoldXsltConvertNonLossy(QilNode ndLiteral, XmlQueryType typTarge return false; // Convert back to source type; if conversion cannot be folded, a XsltConvert node is returned - ndDest = FoldXsltConvert(ndDest, ndLiteral.XmlType); + ndDest = FoldXsltConvert(ndDest, ndLiteral.XmlType!); if (ndDest.NodeType == QilNodeType.XsltConvert) return false; @@ -5406,7 +5409,7 @@ private QilNode FoldXsltConvert(QilNode ndLiteral, XmlQueryType typTarget) if (typTarget.IsAtomicValue) { // Convert the literal to an XmlAtomicValue - XmlAtomicValue value = new XmlAtomicValue(ndLiteral.XmlType.SchemaType, ExtractLiteralValue(ndLiteral)); + XmlAtomicValue value = new XmlAtomicValue(ndLiteral.XmlType!.SchemaType, ExtractLiteralValue(ndLiteral)); value = XsltConvert.ConvertToType(value, typTarget); if (typTarget == XmlQueryTypeFactory.StringX) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILTrace.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILTrace.cs index 741140b2d149..7a8e9819bf40 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILTrace.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILTrace.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. +#nullable enable using System; using System.IO; using System.Security; @@ -24,7 +25,7 @@ internal static class XmlILTrace /// Check environment variable in order to determine whether to write out trace files. This really should be a /// check of the configuration file, but System.Xml does not yet have a good tracing story. /// - private static volatile string s_dirName; + private static volatile string? s_dirName; private static volatile bool s_alreadyCheckedEnabled; /// @@ -71,7 +72,7 @@ public static void PrepareTraceWriter(string fileName) /// If tracing is enabled, this method will open a TextWriter over "fileName" and return it. Otherwise, /// null will be returned. /// - public static TextWriter GetTraceWriter(string fileName) + public static TextWriter? GetTraceWriter(string fileName) { if (!IsEnabled) return null; @@ -165,7 +166,7 @@ private static void WriteQil(QilExpression qil, XmlWriter w) /// /// Serialize rewritten Qil tree to writer "w". /// - private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string rewriteName) + private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string? rewriteName) { w.WriteStartElement("Diff"); if (rewriteName != null) @@ -179,7 +180,7 @@ private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string rewri /// private static string OptimizationToString(int opt) { - string s = Enum.GetName(typeof(XmlILOptimization), opt); + string s = Enum.GetName(typeof(XmlILOptimization), opt)!; if (s.StartsWith("Introduce", StringComparison.Ordinal)) { return s.Substring(9) + " introduction"; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs index a7ead3818658..a3cbb3e37b45 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlTypeHelper.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. +#nullable enable using System; using System.Collections.Generic; using System.IO; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs index 2ac8ec71d728..ce44e31df7c8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.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. +#nullable enable using System; using System.Xml; using System.Xml.XPath; @@ -14,6 +15,7 @@ using System.Xml.Xsl; using System.Xml.Xsl.Qil; using System.Xml.Xsl.Runtime; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.IlGen { @@ -28,9 +30,10 @@ namespace System.Xml.Xsl.IlGen /// internal class XmlILVisitor : QilVisitor { - private QilExpression _qil; - private GenerateHelper _helper; - private IteratorDescriptor _iterCurr, _iterNested; + private QilExpression _qil = null!; + private GenerateHelper _helper = null!; + private IteratorDescriptor _iterCurr = null!; + private IteratorDescriptor? _iterNested; private int _indexId; @@ -79,7 +82,7 @@ public void Visit(QilExpression qil, GenerateHelper helper, MethodInfo methRoot) /// private void PrepareGlobalValues(QilList globalIterators) { - MethodInfo methGlobal; + MethodInfo? methGlobal; IteratorDescriptor iterInfo; foreach (QilIterator iter in globalIterators) @@ -94,7 +97,7 @@ private void PrepareGlobalValues(QilList globalIterators) iterInfo = new IteratorDescriptor(_helper); // Iterator items will be stored in a global location - iterInfo.Storage = StorageDescriptor.Global(methGlobal, GetItemStorageType(iter), !iter.XmlType.IsSingleton); + iterInfo.Storage = StorageDescriptor.Global(methGlobal, GetItemStorageType(iter), !iter.XmlType!.IsSingleton); // Associate IteratorDescriptor with parameter XmlILAnnotation.Write(iter).CachedIteratorDescriptor = iterInfo; @@ -114,14 +117,14 @@ private void VisitGlobalValues(QilList globalIterators) foreach (QilIterator iter in globalIterators) { - QilParameter param = iter as QilParameter; + QilParameter? param = iter as QilParameter; // Get MethodInfo for method that computes the value of this global - methGlobal = XmlILAnnotation.Write(iter).CachedIteratorDescriptor.Storage.GlobalLocation; - isCached = !iter.XmlType.IsSingleton; + methGlobal = XmlILAnnotation.Write(iter).CachedIteratorDescriptor!.Storage.GlobalLocation!; + isCached = !iter.XmlType!.IsSingleton; // Notify the StaticDataManager of the new global value - idxValue = _helper.StaticData.DeclareGlobalValue(iter.DebugName); + idxValue = _helper.StaticData.DeclareGlobalValue(iter.DebugName!); // Generate code for this method _helper.MethodBegin(methGlobal, iter.SourceLine, false); @@ -145,7 +148,7 @@ private void VisitGlobalValues(QilList globalIterators) // param = runtime.ExternalContext.GetParameter(localName, namespaceUri); // if (param == null) goto LabelComputeGlobal; LocalBuilder locParam = _helper.DeclareLocal("$$$param", typeof(object)); - _helper.CallGetParameter(param.Name.LocalName, param.Name.NamespaceUri); + _helper.CallGetParameter(param.Name!.LocalName, param.Name.NamespaceUri); _helper.Emit(OpCodes.Stloc, locParam); _helper.Emit(OpCodes.Ldloc, locParam); _helper.Emit(OpCodes.Brfalse, lblComputeGlobal); @@ -186,7 +189,7 @@ private void VisitGlobalValues(QilList globalIterators) // XmlQueryRuntime.ThrowException("..."); Debug.Assert(iter.NodeType == QilNodeType.Parameter, "Only parameters may not have a default value"); _helper.LoadQueryRuntime(); - _helper.Emit(OpCodes.Ldstr, SR.Format(SR.XmlIl_UnknownParam, new string[] { param.Name.LocalName, param.Name.NamespaceUri })); + _helper.Emit(OpCodes.Ldstr, SR.Format(SR.XmlIl_UnknownParam, new string?[] { param!.Name!.LocalName, param.Name.NamespaceUri })); _helper.Call(XmlILMethods.ThrowException); } @@ -223,13 +226,13 @@ private void Function(QilFunction ndFunc) paramId = XmlILAnnotation.Write(iter).ArgumentPosition + 1; // The ParameterInfo for each argument should be set as its location - iterInfo.Storage = StorageDescriptor.Parameter(paramId, GetItemStorageType(iter), !iter.XmlType.IsSingleton); + iterInfo.Storage = StorageDescriptor.Parameter(paramId, GetItemStorageType(iter), !iter.XmlType!.IsSingleton); // Associate IteratorDescriptor with Let iterator XmlILAnnotation.Write(iter).CachedIteratorDescriptor = iterInfo; } - methFunc = XmlILAnnotation.Write(ndFunc).FunctionBinding; + methFunc = XmlILAnnotation.Write(ndFunc).FunctionBinding!; useWriter = (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer); // Generate query code from QilExpression tree @@ -245,7 +248,7 @@ private void Function(QilFunction ndFunc) if (iter.Binding != null) { Debug.Assert(iter.XmlType == TypeFactory.ItemS, "IlGen currently only supports default values in parameters of type item*."); - paramId = (iter.Annotation as XmlILAnnotation).ArgumentPosition + 1; + paramId = (iter.Annotation as XmlILAnnotation)!.ArgumentPosition + 1; // runtime.MatchesXmlType(param, XmlTypeCode.QName); Label lblLocalComputed = _helper.DefineLabel(); @@ -272,7 +275,7 @@ private void Function(QilFunction ndFunc) if (useWriter) NestedVisit(ndFunc.Definition); else - NestedVisitEnsureStack(ndFunc.Definition, GetItemStorageType(ndFunc), !ndFunc.XmlType.IsSingleton); + NestedVisitEnsureStack(ndFunc.Definition, GetItemStorageType(ndFunc), !ndFunc.XmlType!.IsSingleton); EndNestedIterator(ndFunc); @@ -289,7 +292,7 @@ private void Function(QilFunction ndFunc) protected override QilNode Visit(QilNode nd) { if (nd == null) - return null; + return null!; // DebugInfo: Sequence point just before generating code for this expression if (_qil.IsDebug && nd.SourceLine != null && !(nd is QilIterator)) @@ -309,7 +312,7 @@ protected override QilNode Visit(QilNode nd) break; case XmlILConstructMethod.Iterator: - Debug.Assert(nd.XmlType.IsSingleton || CachesResult(nd) || _iterCurr.HasLabelNext, + Debug.Assert(nd.XmlType!.IsSingleton || CachesResult(nd) || _iterCurr.HasLabelNext, "When generating code for a non-singleton expression, LabelNext must be defined."); goto default; @@ -352,7 +355,7 @@ private void NestedConstruction(QilNode nd) /// private void CopySequence(QilNode nd) { - XmlQueryType typ = nd.XmlType; + XmlQueryType typ = nd.XmlType!; bool hasOnEnd; Label lblOnEnd; @@ -365,13 +368,13 @@ private void CopySequence(QilNode nd) // Allow base internal class to dispatch to correct Visit method base.Visit(nd); - _iterCurr.EnsureItemStorageType(nd.XmlType, typeof(XPathItem)); + _iterCurr.EnsureItemStorageType(nd.XmlType!, typeof(XPathItem)); } else { // Allow base internal class to dispatch to correct Visit method base.Visit(nd); - _iterCurr.EnsureItemStorageType(nd.XmlType, typeof(XPathItem)); + _iterCurr.EnsureItemStorageType(nd.XmlType!, typeof(XPathItem)); // Save any stack values in a temporary local _iterCurr.EnsureNoStackNoCache("$$$copyTemp"); @@ -896,17 +899,17 @@ protected override QilNode VisitConditional(QilTernary ndCond) } else { - IteratorDescriptor iterInfoTrue; - LocalBuilder locBool = null, locCond = null; + IteratorDescriptor? iterInfoTrue; + LocalBuilder? locBool = null, locCond = null; Label lblFalse, lblDone, lblNext; Type itemStorageType = GetItemStorageType(ndCond); Debug.Assert(info.ConstructMethod == XmlILConstructMethod.Iterator); // Evaluate conditional test -- save boolean result in boolResult - Debug.Assert(ndCond.Left.XmlType.TypeCode == XmlTypeCode.Boolean); + Debug.Assert(ndCond.Left.XmlType!.TypeCode == XmlTypeCode.Boolean); lblFalse = _helper.DefineLabel(); - if (ndCond.XmlType.IsSingleton) + if (ndCond.XmlType!.IsSingleton) { // if (!bool-expr) goto LabelFalse; NestedVisitWithBranch(ndCond.Left, BranchingContext.OnFalse, lblFalse); @@ -940,7 +943,7 @@ protected override QilNode VisitConditional(QilTernary ndCond) // If conditional is not cardinality one, then need to iterate through all values if (!ndCond.XmlType.IsSingleton) { - Debug.Assert(!ndCond.Center.XmlType.IsSingleton || !ndCond.Right.XmlType.IsSingleton); + Debug.Assert(!ndCond.Center.XmlType!.IsSingleton || !ndCond.Right.XmlType!.IsSingleton); // IL's rules do not allow OpCodes.Br here // goto LabelDone; @@ -951,11 +954,11 @@ protected override QilNode VisitConditional(QilTernary ndCond) _helper.MarkLabel(lblNext); // if (boolResult) goto LabelNextTrue else goto LabelNextFalse; - _helper.Emit(OpCodes.Ldloc, locBool); - _helper.Emit(OpCodes.Brtrue, iterInfoTrue.GetLabelNext()); - _helper.EmitUnconditionalBranch(OpCodes.Br, _iterNested.GetLabelNext()); + _helper.Emit(OpCodes.Ldloc, locBool!); + _helper.Emit(OpCodes.Brtrue, iterInfoTrue!.GetLabelNext()); + _helper.EmitUnconditionalBranch(OpCodes.Br, _iterNested!.GetLabelNext()); - _iterCurr.SetIterator(lblNext, StorageDescriptor.Local(locCond, itemStorageType, false)); + _iterCurr.SetIterator(lblNext, StorageDescriptor.Local(locCond!, itemStorageType, false)); } // LabelDone: @@ -968,11 +971,11 @@ protected override QilNode VisitConditional(QilTernary ndCond) /// /// Generate code for one of the branches of QilNodeType.Conditional. /// - private void ConditionalBranch(QilNode ndBranch, Type itemStorageType, LocalBuilder locResult) + private void ConditionalBranch(QilNode ndBranch, Type itemStorageType, LocalBuilder? locResult) { if (locResult == null) { - Debug.Assert(ndBranch.XmlType.IsSingleton, "Conditional must produce a singleton"); + Debug.Assert(ndBranch.XmlType!.IsSingleton, "Conditional must produce a singleton"); // If in a branching context, then inherit branch target from parent context if (_iterCurr.IsBranching) @@ -989,7 +992,7 @@ private void ConditionalBranch(QilNode ndBranch, Type itemStorageType, LocalBuil { // Link nested iterator to parent conditional's iterator NestedVisit(ndBranch, _iterCurr.GetLabelNext()); - _iterCurr.EnsureItemStorageType(ndBranch.XmlType, itemStorageType); + _iterCurr.EnsureItemStorageType(ndBranch.XmlType!, itemStorageType); _iterCurr.EnsureLocalNoCache(locResult); } } @@ -1068,7 +1071,7 @@ protected override QilNode VisitLength(QilUnary ndSetLen) if (CachesResult(ndSetLen.Child)) { NestedVisitEnsureStack(ndSetLen.Child); - _helper.CallCacheCount(_iterNested.Storage.ItemStorageType); + _helper.CallCacheCount(_iterNested!.Storage.ItemStorageType); } else { @@ -1164,7 +1167,7 @@ private void Sequence(QilList ndSeq) foreach (QilNode nd in ndSeq) { // Generate nested iterator's code - if (nd.XmlType.IsSingleton) + if (nd.XmlType!.IsSingleton) { NestedVisitEnsureStack(nd); } @@ -1209,11 +1212,11 @@ private void Sequence(QilList ndSeq) NestedVisit(ndSeq[i], lblOnEnd); // Result of list should be saved to a common type and location - _iterCurr.EnsureItemStorageType(ndSeq[i].XmlType, itemStorageType); + _iterCurr.EnsureItemStorageType(ndSeq[i].XmlType!, itemStorageType); _iterCurr.EnsureLocalNoCache(locList); // Switch statement will jump to nested iterator's LabelNext - arrSwitchLabels[i] = _iterNested.GetLabelNext(); + arrSwitchLabels[i] = _iterNested!.GetLabelNext(); // IL's rules prevent OpCodes.Br here // goto LabelStart; @@ -1288,7 +1291,7 @@ private QilNode CreateSetIterator(QilBinary ndSet, string iterName, Type iterTyp // Generate left nested iterator. When it is empty, it will branch to lblNext. // goto LabelCall; NestedVisit(ndSet.Left, lblNext); - lblNextLeft = _iterNested.GetLabelNext(); + lblNextLeft = _iterNested!.GetLabelNext(); _iterCurr.EnsureLocal(locNav); _helper.EmitUnconditionalBranch(OpCodes.Brtrue, lblCall); @@ -1320,7 +1323,7 @@ private QilNode CreateSetIterator(QilBinary ndSet, string iterName, Type iterTyp // If this iterator always returns a single node, then NoMoreNodes will never be returned // Don't expose Next label if this iterator always returns a single node - if (ndSet.XmlType.IsSingleton) + if (ndSet.XmlType!.IsSingleton) { _helper.Emit(OpCodes.Switch, new Label[] { lblInitRight, lblNextLeft, lblNextRight }); _iterCurr.Storage = StorageDescriptor.Current(locIter, typeof(XPathNavigator)); @@ -1340,7 +1343,7 @@ private QilNode CreateSetIterator(QilBinary ndSet, string iterName, Type iterTyp protected override QilNode VisitAverage(QilUnary ndAvg) { XmlILStorageMethods meths = XmlILMethods.StorageMethods[GetItemStorageType(ndAvg)]; - return CreateAggregator(ndAvg, "$$$aggAvg", meths, meths.AggAvg, meths.AggAvgResult); + return CreateAggregator(ndAvg, "$$$aggAvg", meths, meths.AggAvg!, meths.AggAvgResult!); } /// @@ -1349,7 +1352,7 @@ protected override QilNode VisitAverage(QilUnary ndAvg) protected override QilNode VisitSum(QilUnary ndSum) { XmlILStorageMethods meths = XmlILMethods.StorageMethods[GetItemStorageType(ndSum)]; - return CreateAggregator(ndSum, "$$$aggSum", meths, meths.AggSum, meths.AggSumResult); + return CreateAggregator(ndSum, "$$$aggSum", meths, meths.AggSum!, meths.AggSumResult!); } /// @@ -1358,7 +1361,7 @@ protected override QilNode VisitSum(QilUnary ndSum) protected override QilNode VisitMinimum(QilUnary ndMin) { XmlILStorageMethods meths = XmlILMethods.StorageMethods[GetItemStorageType(ndMin)]; - return CreateAggregator(ndMin, "$$$aggMin", meths, meths.AggMin, meths.AggMinResult); + return CreateAggregator(ndMin, "$$$aggMin", meths, meths.AggMin!, meths.AggMinResult!); } /// @@ -1367,7 +1370,7 @@ protected override QilNode VisitMinimum(QilUnary ndMin) protected override QilNode VisitMaximum(QilUnary ndMax) { XmlILStorageMethods meths = XmlILMethods.StorageMethods[GetItemStorageType(ndMax)]; - return CreateAggregator(ndMax, "$$$aggMax", meths, meths.AggMax, meths.AggMaxResult); + return CreateAggregator(ndMax, "$$$aggMax", meths, meths.AggMax!, meths.AggMaxResult!); } /// @@ -1376,14 +1379,14 @@ protected override QilNode VisitMaximum(QilUnary ndMax) private QilNode CreateAggregator(QilUnary ndAgg, string aggName, XmlILStorageMethods methods, MethodInfo methAgg, MethodInfo methResult) { Label lblOnEnd = _helper.DefineLabel(); - Type typAgg = methAgg.DeclaringType; + Type typAgg = methAgg.DeclaringType!; LocalBuilder locAgg; // Aggregate agg; // agg.Create(); locAgg = _helper.DeclareLocal(aggName, typAgg); _helper.Emit(OpCodes.Ldloca, locAgg); - _helper.Call(methods.AggCreate); + _helper.Call(methods.AggCreate!); // foreach (num in expr) { StartNestedIterator(ndAgg.Child, lblOnEnd); @@ -1392,7 +1395,7 @@ private QilNode CreateAggregator(QilUnary ndAgg, string aggName, XmlILStorageMet // agg.Aggregate(num); _iterCurr.EnsureStackNoCache(); - _iterCurr.EnsureItemStorageType(ndAgg.XmlType, GetItemStorageType(ndAgg)); + _iterCurr.EnsureItemStorageType(ndAgg.XmlType!, GetItemStorageType(ndAgg)); _helper.Call(methAgg); _helper.Emit(OpCodes.Ldloca, locAgg); @@ -1403,10 +1406,10 @@ private QilNode CreateAggregator(QilUnary ndAgg, string aggName, XmlILStorageMet EndNestedIterator(ndAgg.Child); // If aggregate might be empty sequence, then generate code to handle this possibility - if (ndAgg.XmlType.MaybeEmpty) + if (ndAgg.XmlType!.MaybeEmpty) { // if (agg.IsEmpty) goto LabelNextCtxt; - _helper.Call(methods.AggIsEmpty); + _helper.Call(methods.AggIsEmpty!); _helper.Emit(OpCodes.Brtrue, _iterCurr.GetLabelNext()); _helper.Emit(OpCodes.Ldloca, locAgg); } @@ -1424,7 +1427,7 @@ private QilNode CreateAggregator(QilUnary ndAgg, string aggName, XmlILStorageMet protected override QilNode VisitNegate(QilUnary ndNeg) { NestedVisitEnsureStack(ndNeg.Child); - _helper.CallArithmeticOp(QilNodeType.Negate, ndNeg.XmlType.TypeCode); + _helper.CallArithmeticOp(QilNodeType.Negate, ndNeg.XmlType!.TypeCode); _iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndNeg), false); return ndNeg; } @@ -1475,7 +1478,7 @@ protected override QilNode VisitModulo(QilBinary ndMod) private QilNode ArithmeticOp(QilBinary ndOp) { NestedVisitEnsureStack(ndOp.Left, ndOp.Right); - _helper.CallArithmeticOp(ndOp.NodeType, ndOp.XmlType.TypeCode); + _helper.CallArithmeticOp(ndOp.NodeType, ndOp.XmlType!.TypeCode); _iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndOp), false); return ndOp; } @@ -1498,9 +1501,9 @@ protected override QilNode VisitStrConcat(QilStrConcat ndStrConcat) { LocalBuilder locStringConcat; bool fasterConcat; - QilNode delimiter; + QilNode? delimiter; QilNode listStrings; - Debug.Assert(!ndStrConcat.Values.XmlType.IsSingleton, "Optimizer should have folded StrConcat of a singleton value"); + Debug.Assert(!ndStrConcat.Values.XmlType!.IsSingleton, "Optimizer should have folded StrConcat of a singleton value"); // Get delimiter (assuming it's not the empty string) delimiter = ndStrConcat.Delimiter; @@ -1516,7 +1519,7 @@ protected override QilNode VisitStrConcat(QilStrConcat ndStrConcat) fasterConcat = true; foreach (QilNode ndStr in listStrings) { - if (!ndStr.XmlType.IsSingleton) + if (!ndStr.XmlType!.IsSingleton) fasterConcat = false; } } @@ -1583,7 +1586,7 @@ private void GenerateConcat(QilNode ndStr, LocalBuilder locStringConcat) // strcat.Concat(str); _iterCurr.EnsureStackNoCache(); - _iterCurr.EnsureItemStorageType(ndStr.XmlType, typeof(string)); + _iterCurr.EnsureItemStorageType(ndStr.XmlType!, typeof(string)); _helper.Call(XmlILMethods.StrCatCat); _helper.Emit(OpCodes.Ldloca, locStringConcat); @@ -1618,7 +1621,7 @@ private void VisitStrParseQName(QilBinary ndParsedTagName, bool preservePrefix) NestedVisitEnsureStack(ndParsedTagName.Left); // If type of second parameter is string, - if (ndParsedTagName.Right.XmlType.TypeCode == XmlTypeCode.String) + if (ndParsedTagName.Right.XmlType!.TypeCode == XmlTypeCode.String) { // Then push (possibly computed) namespace onto the stack Debug.Assert(ndParsedTagName.Right.XmlType.IsSingleton); @@ -1704,7 +1707,7 @@ private void Compare(QilBinary ndComp) { QilNodeType relOp = ndComp.NodeType; XmlTypeCode code; - Debug.Assert(ndComp.Left.XmlType.IsAtomicValue && ndComp.Right.XmlType.IsAtomicValue, "Operands to compare must be atomic values."); + Debug.Assert(ndComp.Left.XmlType!.IsAtomicValue && ndComp.Right.XmlType!.IsAtomicValue, "Operands to compare must be atomic values."); Debug.Assert(ndComp.Left.XmlType.IsSingleton && ndComp.Right.XmlType.IsSingleton, "Operands to compare must be cardinality one."); Debug.Assert(ndComp.Left.XmlType == ndComp.Right.XmlType, "Operands to compare may not be heterogenous."); @@ -1823,7 +1826,7 @@ protected override QilNode VisitFor(QilIterator ndFor) IteratorDescriptor iterInfo; // Reference saved location - iterInfo = XmlILAnnotation.Write(ndFor).CachedIteratorDescriptor; + iterInfo = XmlILAnnotation.Write(ndFor).CachedIteratorDescriptor!; _iterCurr.Storage = iterInfo.Storage; // If the iterator is a reference to a global variable or parameter, @@ -1888,11 +1891,11 @@ protected override QilNode VisitFilter(QilLoop ndFilter) StartBinding(ndFilter.Variable); // Result of filter is the sequence bound to the iterator - _iterCurr.SetIterator(_iterNested); + _iterCurr.SetIterator(_iterNested!); // If filter is false, skip the current item StartNestedIterator(ndFilter.Body); - _iterCurr.SetBranching(BranchingContext.OnFalse, _iterCurr.ParentIterator.GetLabelNext()); + _iterCurr.SetBranching(BranchingContext.OnFalse, _iterCurr.ParentIterator!.GetLabelNext()); Visit(ndFilter.Body); EndNestedIterator(ndFilter.Body); @@ -1911,7 +1914,7 @@ private bool HandleFilterPatterns(QilLoop ndFilter) OptimizerPatterns patt = OptimizerPatterns.Read(ndFilter); LocalBuilder locIter; XmlNodeKindFlags kinds; - QilName name; + QilName? name; QilNode input, step; bool isFilterElements; @@ -1945,7 +1948,7 @@ private bool HandleFilterPatterns(QilLoop ndFilter) // iter.Create(navCtxt, locName, ns); _helper.Emit(OpCodes.Ldloca, locIter); NestedVisitEnsureStack(input); - _helper.CallGetAtomizedName(_helper.StaticData.DeclareName(name.LocalName)); + _helper.CallGetAtomizedName(_helper.StaticData.DeclareName(name!.LocalName)); _helper.CallGetAtomizedName(_helper.StaticData.DeclareName(name.NamespaceUri)); _helper.Call(XmlILMethods.ElemContentCreate); @@ -2067,7 +2070,7 @@ private bool HandleFilterPatterns(QilLoop ndFilter) _iterCurr.EnsureStackNoCache(); VisitFor(nodes); _iterCurr.EnsureStackNoCache(); - _iterCurr.EnsureItemStorageType(nodes.XmlType, typeof(XPathNavigator)); + _iterCurr.EnsureItemStorageType(nodes.XmlType!, typeof(XPathNavigator)); _helper.Call(XmlILMethods.IndexAdd); _helper.Emit(OpCodes.Ldloc, locIndex); @@ -2108,7 +2111,7 @@ private void StartBinding(QilIterator ndIter) _helper.DebugSequencePoint(ndIter.SourceLine); // Treat cardinality one Let iterators as if they were For iterators (no nesting necessary) - if (ndIter.NodeType == QilNodeType.For || ndIter.XmlType.IsSingleton) + if (ndIter.NodeType == QilNodeType.For || ndIter.XmlType!.IsSingleton) { StartForBinding(ndIter, patt); } @@ -2131,8 +2134,8 @@ private void StartBinding(QilIterator ndIter) /// private void StartForBinding(QilIterator ndFor, OptimizerPatterns patt) { - LocalBuilder locPos = null; - Debug.Assert(ndFor.XmlType.IsSingleton); + LocalBuilder? locPos = null; + Debug.Assert(ndFor.XmlType!.IsSingleton); // For expression iterator will be unnested as part of parent iterator if (_iterCurr.HasLabelNext) @@ -2149,7 +2152,7 @@ private void StartForBinding(QilIterator ndFor, OptimizerPatterns patt) } // Allow base internal class to dispatch based on QilExpression node type - Visit(ndFor.Binding); + Visit(ndFor.Binding!); // DebugInfo: Open variable scope // DebugInfo: Ensure that for variable is stored in a local and tag it with the user-defined name @@ -2169,24 +2172,24 @@ private void StartForBinding(QilIterator ndFor, OptimizerPatterns patt) if (patt.MatchesPattern(OptimizerPatternName.IsPositional)) { // Increment position - _helper.Emit(OpCodes.Ldloc, locPos); + _helper.Emit(OpCodes.Ldloc, locPos!); _helper.Emit(OpCodes.Ldc_I4_1); _helper.Emit(OpCodes.Add); - _helper.Emit(OpCodes.Stloc, locPos); + _helper.Emit(OpCodes.Stloc, locPos!); if (patt.MatchesPattern(OptimizerPatternName.MaxPosition)) { // Short-circuit rest of loop if max position has already been reached - _helper.Emit(OpCodes.Ldloc, locPos); + _helper.Emit(OpCodes.Ldloc, locPos!); _helper.LoadInteger((int)patt.GetArgument(OptimizerPatternArgument.MaxPosition)); - _helper.Emit(OpCodes.Bgt, _iterCurr.ParentIterator.GetLabelNext()); + _helper.Emit(OpCodes.Bgt, _iterCurr.ParentIterator!.GetLabelNext()); } _iterCurr.LocalPosition = locPos; } - EndNestedIterator(ndFor.Binding); - _iterCurr.SetIterator(_iterNested); + EndNestedIterator(ndFor.Binding!); + _iterCurr.SetIterator(_iterNested!); } /// @@ -2194,13 +2197,13 @@ private void StartForBinding(QilIterator ndFor, OptimizerPatterns patt) /// public void StartLetBinding(QilIterator ndLet) { - Debug.Assert(!ndLet.XmlType.IsSingleton); + Debug.Assert(!ndLet.XmlType!.IsSingleton); // Construct nested iterator StartNestedIterator(ndLet); // Allow base internal class to dispatch based on QilExpression node type - NestedVisit(ndLet.Binding, GetItemStorageType(ndLet), !ndLet.XmlType.IsSingleton); + NestedVisit(ndLet.Binding!, GetItemStorageType(ndLet), !ndLet.XmlType.IsSingleton); // DebugInfo: Open variable scope // DebugInfo: Ensure that for variable is stored in a local and tag it with the user-defined name @@ -2237,11 +2240,11 @@ private void EndBinding(QilIterator ndIter) /// protected override QilNode VisitPositionOf(QilUnary ndPos) { - QilIterator ndIter = ndPos.Child as QilIterator; + QilIterator ndIter = (ndPos.Child as QilIterator)!; LocalBuilder locPos; Debug.Assert(ndIter.NodeType == QilNodeType.For); - locPos = XmlILAnnotation.Write(ndIter).CachedIteratorDescriptor.LocalPosition; + locPos = XmlILAnnotation.Write(ndIter).CachedIteratorDescriptor!.LocalPosition!; Debug.Assert(locPos != null); _iterCurr.Storage = StorageDescriptor.Local(locPos, typeof(int), false); @@ -2277,11 +2280,11 @@ protected override QilNode VisitSort(QilLoop ndSort) // foreach (item in sort-expr) { StartNestedIterator(ndSort.Variable, lblOnEndSort); StartBinding(ndSort.Variable); - Debug.Assert(!_iterNested.Storage.IsCached); + Debug.Assert(!_iterNested!.Storage.IsCached); // cache.Add(item); _iterCurr.EnsureStackNoCache(); - _iterCurr.EnsureItemStorageType(ndSort.Variable.XmlType, GetItemStorageType(ndSort.Variable)); + _iterCurr.EnsureItemStorageType(ndSort.Variable.XmlType!, GetItemStorageType(ndSort.Variable)); _helper.Call(methods.SeqAdd); _helper.Emit(OpCodes.Ldloca, locKeys); @@ -2321,7 +2324,7 @@ protected override QilNode VisitSort(QilLoop ndSort) private void VisitSortKey(QilSortKey ndKey, LocalBuilder locKeys) { Label lblOnEndKey; - Debug.Assert(ndKey.Key.XmlType.IsAtomicValue, "Sort key must be an atomic value."); + Debug.Assert(ndKey.Key.XmlType!.IsAtomicValue, "Sort key must be an atomic value."); // Push collation onto the stack _helper.Emit(OpCodes.Ldloca, locKeys); @@ -2338,7 +2341,7 @@ private void VisitSortKey(QilSortKey ndKey, LocalBuilder locKeys) _helper.Call(XmlILMethods.CreateCollation); } - if (ndKey.XmlType.IsSingleton) + if (ndKey.XmlType!.IsSingleton) { NestedVisitEnsureStack(ndKey.Key); @@ -2379,7 +2382,7 @@ private void VisitSortKey(QilSortKey ndKey, LocalBuilder locKeys) protected override QilNode VisitDocOrderDistinct(QilUnary ndDod) { // DocOrderDistinct applied to a singleton is a no-op - if (ndDod.XmlType.IsSingleton) + if (ndDod.XmlType!.IsSingleton) return Visit(ndDod.Child); // Handle any special-case patterns that are rooted at DocOrderDistinct @@ -2404,7 +2407,7 @@ private bool HandleDodPatterns(QilUnary ndDod) { OptimizerPatterns pattDod = OptimizerPatterns.Read(ndDod); XmlNodeKindFlags kinds; - QilName name; + QilName? name; QilNode input, step; bool isJoinAndDod; @@ -2429,7 +2432,7 @@ private bool HandleDodPatterns(QilUnary ndDod) else { Debug.Assert(pattStep.MatchesPattern(OptimizerPatternName.Axis), "Dod patterns should only match if step is FilterElements or FilterKindTest or Axis"); - kinds = ((ndDod.XmlType.NodeKinds & XmlNodeKindFlags.Attribute) != 0) ? XmlNodeKindFlags.Any : XmlNodeKindFlags.Content; + kinds = ((ndDod.XmlType!.NodeKinds & XmlNodeKindFlags.Attribute) != 0) ? XmlNodeKindFlags.Any : XmlNodeKindFlags.Content; name = null; } @@ -2541,7 +2544,7 @@ private bool HandleDodPatterns(QilUnary ndDod) protected override QilNode VisitInvoke(QilInvoke ndInvoke) { QilFunction ndFunc = ndInvoke.Function; - MethodInfo methInfo = XmlILAnnotation.Write(ndFunc).FunctionBinding; + MethodInfo methInfo = XmlILAnnotation.Write(ndFunc).FunctionBinding!; bool useWriter = (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer); Debug.Assert(!XmlILConstructInfo.Read(ndInvoke).PushToWriterFirst || useWriter); @@ -2553,7 +2556,7 @@ protected override QilNode VisitInvoke(QilInvoke ndInvoke) { QilNode ndActualArg = ndInvoke.Arguments[iArg]; QilNode ndFormalArg = ndInvoke.Function.Arguments[iArg]; - NestedVisitEnsureStack(ndActualArg, GetItemStorageType(ndFormalArg), !ndFormalArg.XmlType.IsSingleton); + NestedVisitEnsureStack(ndActualArg, GetItemStorageType(ndFormalArg), !ndFormalArg.XmlType!.IsSingleton); } // Check whether this call should compiled using the .tailcall instruction @@ -2566,7 +2569,7 @@ protected override QilNode VisitInvoke(QilInvoke ndInvoke) if (!useWriter) { // Return value is on the stack; ensure it has the correct storage type - _iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndInvoke), !ndInvoke.XmlType.IsSingleton); + _iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndInvoke), !ndInvoke.XmlType!.IsSingleton); } else { @@ -2590,7 +2593,7 @@ protected override QilNode VisitContent(QilUnary ndContent) /// protected override QilNode VisitAttribute(QilBinary ndAttr) { - QilName ndName = ndAttr.Right as QilName; + QilName? ndName = ndAttr.Right as QilName; Debug.Assert(ndName != null, "Attribute node must have a literal QName as its second argument"); // XPathNavigator navAttr; @@ -3140,7 +3143,7 @@ private QilNode VisitNodeProperty(QilUnary ndProp) /// protected override QilNode VisitTypeAssert(QilTargetType ndTypeAssert) { - if (!ndTypeAssert.Source.XmlType.IsSingleton && ndTypeAssert.XmlType.IsSingleton && !_iterCurr.HasLabelNext) + if (!ndTypeAssert.Source.XmlType!.IsSingleton && ndTypeAssert.XmlType!.IsSingleton && !_iterCurr.HasLabelNext) { // This case occurs when a non-singleton expression is treated as cardinality One. // The trouble is that the expression will branch to an end label when it's done iterating, so @@ -3170,9 +3173,9 @@ protected override QilNode VisitIsType(QilTargetType ndIsType) XmlQueryType typDerived, typBase; XmlTypeCode codeBase; - typDerived = ndIsType.Source.XmlType; + typDerived = ndIsType.Source.XmlType!; typBase = ndIsType.TargetType; - Debug.Assert(!typDerived.NeverSubtypeOf(typBase), "Normalizer should have eliminated IsType where source can never be a subtype of destination type."); + Debug.Assert(!typDerived!.NeverSubtypeOf(typBase), "Normalizer should have eliminated IsType where source can never be a subtype of destination type."); // Special Case: Test whether singleton item is a Node if (typDerived.IsSingleton && (object)typBase == (object)TypeFactory.Node) @@ -3351,7 +3354,7 @@ protected override QilNode VisitIsEmpty(QilUnary ndIsEmpty) { // Then get the count directly from the cache NestedVisitEnsureStack(ndIsEmpty.Child); - _helper.CallCacheCount(_iterNested.Storage.ItemStorageType); + _helper.CallCacheCount(_iterNested!.Storage.ItemStorageType); switch (_iterCurr.CurrentBranchingContext) { @@ -3430,7 +3433,7 @@ protected override QilNode VisitIsEmpty(QilUnary ndIsEmpty) protected override QilNode VisitXPathNodeValue(QilUnary ndVal) { Label lblOnEnd, lblDone; - Debug.Assert(ndVal.Child.XmlType.IsNode, "XPathNodeValue node may only be applied to a sequence of Nodes."); + Debug.Assert(ndVal.Child.XmlType!.IsNode, "XPathNodeValue node may only be applied to a sequence of Nodes."); // If the expression is a singleton, if (ndVal.Child.XmlType.IsSingleton) @@ -3508,7 +3511,7 @@ protected override QilNode VisitXsltGenerateId(QilUnary ndGenId) _helper.LoadQueryRuntime(); // If the expression is a singleton, - if (ndGenId.Child.XmlType.IsSingleton) + if (ndGenId.Child.XmlType!.IsSingleton) { // Then generate code to push expresion result onto the stack NestedVisitEnsureStack(ndGenId.Child, typeof(XPathNavigator), false); @@ -3607,7 +3610,7 @@ protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvok clrTypeRetDst = GetStorageType(ndInvoke); // Prepare to call runtime.ChangeTypeXsltResult - if (clrTypeRetSrc != clrTypeRetDst && !ndInvoke.XmlType.IsEmpty) + if (clrTypeRetSrc != clrTypeRetDst && !ndInvoke.XmlType!.IsEmpty) { _helper.LoadQueryRuntime(); _helper.LoadInteger(_helper.StaticData.DeclareXmlType(ndInvoke.XmlType)); @@ -3620,7 +3623,7 @@ protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvok if (ndName.NamespaceUri.Length == 0) _helper.LoadXsltLibrary(); else - _helper.CallGetEarlyBoundObject(_helper.StaticData.DeclareEarlyBound(ndName.NamespaceUri, extFunc.Method.DeclaringType), extFunc.Method.DeclaringType); + _helper.CallGetEarlyBoundObject(_helper.StaticData.DeclareEarlyBound(ndName.NamespaceUri, extFunc.Method.DeclaringType!), extFunc.Method.DeclaringType!); } // Generate code to push each Invoke argument onto the stack @@ -3636,7 +3639,7 @@ protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvok xmlTypeFormalArg = extFunc.GetXmlArgumentType(iArg); clrTypeFormalArg = extFunc.GetClrArgumentType(iArg); - Debug.Assert(ndActualArg.XmlType.IsSubtypeOf(xmlTypeFormalArg), "Xml type of actual arg must be a subtype of the Xml type of the formal arg"); + Debug.Assert(ndActualArg.XmlType!.IsSubtypeOf(xmlTypeFormalArg), "Xml type of actual arg must be a subtype of the Xml type of the formal arg"); // Use different conversion rules for internal Xslt libraries. If the actual argument is // stored using Clr type T, then library must use type T, XPathItem, IList, or IList. @@ -3698,7 +3701,7 @@ protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvok _helper.Call(extFunc.Method); // Return value is on the stack; convert it to canonical ILGen storage type - if (ndInvoke.XmlType.IsEmpty) + if (ndInvoke.XmlType!.IsEmpty) { _helper.Emit(OpCodes.Ldsfld, XmlILMethods.StorageMethods[typeof(XPathItem)].SeqEmpty); } @@ -3738,7 +3741,7 @@ protected override QilNode VisitXsltCopy(QilBinary ndCopy) _helper.LoadQueryOutput(); NestedVisitEnsureStack(ndCopy.Left); - Debug.Assert(ndCopy.Left.XmlType.IsNode); + Debug.Assert(ndCopy.Left.XmlType!.IsNode); _helper.Call(XmlILMethods.StartCopy); _helper.Emit(OpCodes.Brfalse, lblSkipContent); @@ -3784,9 +3787,9 @@ protected override QilNode VisitXsltCopyOf(QilUnary ndCopyOf) protected override QilNode VisitXsltConvert(QilTargetType ndConv) { XmlQueryType typSrc, typDst; - MethodInfo meth; + MethodInfo? meth; - typSrc = ndConv.Source.XmlType; + typSrc = ndConv.Source.XmlType!; typDst = ndConv.TargetType; if (GetXsltConvertMethod(typSrc, typDst, out meth)) @@ -3813,7 +3816,7 @@ protected override QilNode VisitXsltConvert(QilTargetType ndConv) /// Get the XsltConvert method that converts from "typSrc" to "typDst". Return false if no /// such method exists. This conversion matrix should match the one in XsltConvert.ExternalValueToExternalValue. /// - private bool GetXsltConvertMethod(XmlQueryType typSrc, XmlQueryType typDst, out MethodInfo meth) + private bool GetXsltConvertMethod(XmlQueryType typSrc, XmlQueryType typDst, out MethodInfo? meth) { meth = null; @@ -3933,7 +3936,7 @@ private void CreateSimpleIterator(QilNode ndCtxt, string iterName, Type iterType /// goto LabelNextCtxt; /// private void CreateFilteredIterator(QilNode ndCtxt, string iterName, Type iterType, MethodInfo methCreate, MethodInfo methNext, - XmlNodeKindFlags kinds, QilName ndName, TriState orSelf, QilNode ndEnd) + XmlNodeKindFlags kinds, QilName? ndName, TriState orSelf, QilNode? ndEnd) { // Iterator iter; LocalBuilder locIter = _helper.DeclareLocal(iterName, iterType); @@ -3969,7 +3972,7 @@ private void CreateFilteredIterator(QilNode ndCtxt, string iterName, Type iterTy /// } /// private void CreateContainerIterator(QilUnary ndDod, string iterName, Type iterType, MethodInfo methCreate, MethodInfo methNext, - XmlNodeKindFlags kinds, QilName ndName, TriState orSelf) + XmlNodeKindFlags kinds, QilName? ndName, TriState orSelf) { // Iterator iter; LocalBuilder locIter = _helper.DeclareLocal(iterName, iterType); @@ -3990,7 +3993,7 @@ private void CreateContainerIterator(QilUnary ndDod, string iterName, Type iterT StartBinding(ndLoop.Variable); EndBinding(ndLoop.Variable); EndNestedIterator(ndLoop.Variable); - _iterCurr.Storage = _iterNested.Storage; + _iterCurr.Storage = _iterNested!.Storage; GenerateContainerIterator(ndDod, locIter, lblOnEndNested, methNext, typeof(XPathNavigator)); } @@ -4046,7 +4049,7 @@ private void GenerateContainerIterator(QilNode nd, LocalBuilder locIter, Label l // iter.MoveNext(input); // goto LabelCall; - _iterCurr.EnsureNoStackNoCache(nd.XmlType.IsNode ? "$$$navInput" : "$$$itemInput"); + _iterCurr.EnsureNoStackNoCache(nd.XmlType!.IsNode ? "$$$navInput" : "$$$itemInput"); _helper.Emit(OpCodes.Ldloca, locIter); _iterCurr.PushValue(); _helper.EmitUnconditionalBranch(OpCodes.Br, lblCall); @@ -4067,7 +4070,7 @@ private void GenerateContainerIterator(QilNode nd, LocalBuilder locIter, Label l { // if (result == IteratorResult.NeedInputNode) goto LabelNextInput; _helper.LoadInteger((int)IteratorResult.NeedInputNode); - _helper.Emit(OpCodes.Beq, _iterNested.GetLabelNext()); + _helper.Emit(OpCodes.Beq, _iterNested!.GetLabelNext()); _iterCurr.Storage = StorageDescriptor.Current(locIter, itemStorageType); } @@ -4077,7 +4080,7 @@ private void GenerateContainerIterator(QilNode nd, LocalBuilder locIter, Label l // case IteratorResult.NoMoreNodes: goto LabelNextCtxt; // case IteratorResult.NeedInputNode: goto LabelNextInput; // } - _helper.Emit(OpCodes.Switch, new Label[] { _iterCurr.GetLabelNext(), _iterNested.GetLabelNext() }); + _helper.Emit(OpCodes.Switch, new Label[] { _iterCurr.GetLabelNext(), _iterNested!.GetLabelNext() }); _iterCurr.SetIterator(lblOnEndNested, StorageDescriptor.Current(locIter, itemStorageType)); } @@ -4092,7 +4095,7 @@ private GenerateNameType LoadNameAndType(XPathNodeType nodeType, QilNode ndName, QilName ndLiteralName; string prefix, localName, ns; GenerateNameType nameType; - Debug.Assert(ndName.XmlType.TypeCode == XmlTypeCode.QName, "Element or attribute name must have QName type."); + Debug.Assert(ndName.XmlType!.TypeCode == XmlTypeCode.QName, "Element or attribute name must have QName type."); _helper.LoadQueryOutput(); @@ -4105,7 +4108,7 @@ private GenerateNameType LoadNameAndType(XPathNodeType nodeType, QilNode ndName, // If checks need to be made on End construction, then always pop names from stack if (isStart || !callChk) { - ndLiteralName = ndName as QilName; + ndLiteralName = (ndName as QilName)!; prefix = ndLiteralName.Prefix; localName = ndLiteralName.LocalName; ns = ndLiteralName.NamespaceUri; @@ -4153,17 +4156,17 @@ private GenerateNameType LoadNameAndType(XPathNodeType nodeType, QilNode ndName, if (ndName.NodeType == QilNodeType.NameOf) { // Preserve prefix of source node, so just push navigator onto stack - NestedVisitEnsureStack((ndName as QilUnary).Child); + NestedVisitEnsureStack((ndName as QilUnary)!.Child); nameType = GenerateNameType.CopiedName; } // 3. Parsed tag names (foo:bar) else if (ndName.NodeType == QilNodeType.StrParseQName) { // Preserve prefix from parsed tag name - VisitStrParseQName(ndName as QilBinary, true); + VisitStrParseQName((ndName as QilBinary)!, true); // Type of name depends upon data-type of name argument - if ((ndName as QilBinary).Right.XmlType.TypeCode == XmlTypeCode.String) + if ((ndName as QilBinary)!.Right.XmlType!.TypeCode == XmlTypeCode.String) nameType = GenerateNameType.TagNameAndNamespace; else nameType = GenerateNameType.TagNameAndMappings; @@ -4216,7 +4219,7 @@ private bool TryZeroCompare(QilNodeType relOp, QilNode ndFirst, QilNode ndSecond NestedVisitEnsureStack(ndSecond); // Generate comparison code -- op == 0 or op != 0 - ZeroCompare(relOp, ndSecond.XmlType.TypeCode == XmlTypeCode.Boolean); + ZeroCompare(relOp, ndSecond.XmlType!.TypeCode == XmlTypeCode.Boolean); return true; } @@ -4239,12 +4242,12 @@ private bool TryNameCompare(QilNodeType relOp, QilNode ndFirst, QilNode ndSecond _helper.LoadQueryRuntime(); // Push left navigator onto the stack - NestedVisitEnsureStack((ndFirst as QilUnary).Child); + NestedVisitEnsureStack((ndFirst as QilUnary)!.Child); // Push the local name and namespace uri of the right argument onto the stack if (ndSecond.NodeType == QilNodeType.LiteralQName) { - QilName ndName = ndSecond as QilName; + QilName ndName = (ndSecond as QilName)!; _helper.LoadInteger(_helper.StaticData.DeclareName(ndName.LocalName)); _helper.LoadInteger(_helper.StaticData.DeclareName(ndName.NamespaceUri)); @@ -4415,7 +4418,7 @@ private void StartWriterLoop(QilNode nd, out bool hasOnEnd, out Label lblOnEnd) lblOnEnd = default; // If loop is not involved in Xml construction, or if loop returns exactly one value, then do nothing - if (!info.PushToWriterLast || nd.XmlType.IsSingleton) + if (!info.PushToWriterLast || nd.XmlType!.IsSingleton) return; if (!_iterCurr.HasLabelNext) @@ -4443,7 +4446,7 @@ private void EndWriterLoop(QilNode nd, bool hasOnEnd, Label lblOnEnd) _iterCurr.Storage = StorageDescriptor.None(); // If loop returns exactly one value, then do nothing further - if (nd.XmlType.IsSingleton) + if (nd.XmlType!.IsSingleton) return; if (hasOnEnd) @@ -4457,7 +4460,7 @@ private void EndWriterLoop(QilNode nd, bool hasOnEnd, Label lblOnEnd) /// Returns true if the specified node's owner element might have local namespaces added to it /// after attributes have already been added. /// - private bool MightHaveNamespacesAfterAttributes(XmlILConstructInfo info) + private bool MightHaveNamespacesAfterAttributes(XmlILConstructInfo? info) { // Get parent element if (info != null) @@ -4598,7 +4601,7 @@ private XPathNodeType QilConstructorToNodeType(QilNodeType typ) /// /// Load an XmlNavigatorFilter that matches only the specified name and types onto the stack. /// - private void LoadSelectFilter(XmlNodeKindFlags xmlTypes, QilName ndName) + private void LoadSelectFilter(XmlNodeKindFlags xmlTypes, QilName? ndName) { if (ndName != null) { @@ -4646,9 +4649,10 @@ private static bool IsNodeTypeUnion(XmlNodeKindFlags xmlTypes) /// is a top-level, or root iterator. Otherwise, the new iterator will be nested within the /// current iterator. /// - private void StartNestedIterator(QilNode nd) + [MemberNotNull(nameof(_iterCurr))] + private void StartNestedIterator(QilNode? nd) { - IteratorDescriptor iterParent = _iterCurr; + IteratorDescriptor? iterParent = _iterCurr; // Create a new, nested iterator if (iterParent == null) @@ -4669,7 +4673,7 @@ private void StartNestedIterator(QilNode nd) /// Calls StartNestedIterator(nd) and also sets up the nested iterator to branch to "lblOnEnd" when iteration /// is complete. /// - private void StartNestedIterator(QilNode nd, Label lblOnEnd) + private void StartNestedIterator(QilNode? nd, Label lblOnEnd) { StartNestedIterator(nd); _iterCurr.SetIterator(lblOnEnd, StorageDescriptor.None()); @@ -4683,7 +4687,7 @@ private void EndNestedIterator(QilNode nd) Debug.Assert(_iterCurr.Storage.Location == ItemLocation.None || _iterCurr.Storage.ItemStorageType == GetItemStorageType(nd) || _iterCurr.Storage.ItemStorageType == typeof(XPathItem) || - nd.XmlType.TypeCode == XmlTypeCode.None, + nd.XmlType!.TypeCode == XmlTypeCode.None, "QilNodeType " + nd.NodeType + " cannot be stored using type " + _iterCurr.Storage.ItemStorageType + "."); // If the nested iterator was constructed in branching mode, @@ -4692,7 +4696,7 @@ private void EndNestedIterator(QilNode nd) // Then if branching hasn't already taken place, do so now if (_iterCurr.Storage.Location != ItemLocation.None) { - _iterCurr.EnsureItemStorageType(nd.XmlType, typeof(bool)); + _iterCurr.EnsureItemStorageType(nd.XmlType!, typeof(bool)); _iterCurr.EnsureStackNoCache(); if (_iterCurr.CurrentBranchingContext == BranchingContext.OnTrue) @@ -4708,7 +4712,7 @@ private void EndNestedIterator(QilNode nd) _iterNested = _iterCurr; // Update current iterator to be parent iterator - _iterCurr = _iterCurr.ParentIterator; + _iterCurr = _iterCurr.ParentIterator!; } /// @@ -4727,7 +4731,7 @@ private void NestedVisit(QilNode nd, Type itemStorageType, bool isCached) EndNestedIterator(nd); _iterCurr.Storage = StorageDescriptor.None(); } - else if (!isCached && nd.XmlType.IsSingleton) + else if (!isCached && nd.XmlType!.IsSingleton) { // Storage of result will be a non-cached singleton StartNestedIterator(nd); @@ -4735,7 +4739,7 @@ private void NestedVisit(QilNode nd, Type itemStorageType, bool isCached) _iterCurr.EnsureNoCache(); _iterCurr.EnsureItemStorageType(nd.XmlType, itemStorageType); EndNestedIterator(nd); - _iterCurr.Storage = _iterNested.Storage; + _iterCurr.Storage = _iterNested!.Storage; } else { @@ -4748,7 +4752,7 @@ private void NestedVisit(QilNode nd, Type itemStorageType, bool isCached) /// private void NestedVisit(QilNode nd) { - NestedVisit(nd, GetItemStorageType(nd), !nd.XmlType.IsSingleton); + NestedVisit(nd, GetItemStorageType(nd), !nd.XmlType!.IsSingleton); } /// @@ -4761,9 +4765,9 @@ private void NestedVisit(QilNode nd, Label lblOnEnd) StartNestedIterator(nd, lblOnEnd); Visit(nd); _iterCurr.EnsureNoCache(); - _iterCurr.EnsureItemStorageType(nd.XmlType, GetItemStorageType(nd)); + _iterCurr.EnsureItemStorageType(nd.XmlType!, GetItemStorageType(nd)); EndNestedIterator(nd); - _iterCurr.Storage = _iterNested.Storage; + _iterCurr.Storage = _iterNested!.Storage; } /// @@ -4810,7 +4814,7 @@ private void NestedVisitEnsureLocal(QilNode nd, LocalBuilder loc) /// private void NestedVisitWithBranch(QilNode nd, BranchingContext brctxt, Label lblBranch) { - Debug.Assert(nd.XmlType.IsSingleton && !XmlILConstructInfo.Read(nd).PushToWriterLast); + Debug.Assert(nd.XmlType!.IsSingleton && !XmlILConstructInfo.Read(nd).PushToWriterLast); StartNestedIterator(nd); _iterCurr.SetBranching(brctxt, lblBranch); Visit(nd); @@ -4837,7 +4841,7 @@ private void NestedVisitEnsureCache(QilNode nd, Type itemStorageType) StartNestedIterator(nd); Visit(nd); EndNestedIterator(nd); - _iterCurr.Storage = _iterNested.Storage; + _iterCurr.Storage = _iterNested!.Storage; Debug.Assert(_iterCurr.Storage.IsCached, "Expression result should be cached. CachesResult() might have a bug in it."); // If type of items in the cache matches "itemStorageType", then done @@ -4848,7 +4852,7 @@ private void NestedVisitEnsureCache(QilNode nd, Type itemStorageType) // can directly convert without needing to create a new cache. if (_iterCurr.Storage.ItemStorageType == typeof(XPathNavigator) || itemStorageType == typeof(XPathNavigator)) { - _iterCurr.EnsureItemStorageType(nd.XmlType, itemStorageType); + _iterCurr.EnsureItemStorageType(nd.XmlType!, itemStorageType); return; } @@ -4864,7 +4868,7 @@ private void NestedVisitEnsureCache(QilNode nd, Type itemStorageType) _helper.Emit(OpCodes.Ldloc, locCache); // Special case non-navigator singletons to use overload of CreateOrReuse - if (nd.XmlType.IsSingleton) + if (nd.XmlType!.IsSingleton) { // cache = XmlQuerySequence.CreateOrReuse(cache, item); NestedVisitEnsureStack(nd, cacheType, false); @@ -4882,7 +4886,7 @@ private void NestedVisitEnsureCache(QilNode nd, Type itemStorageType) StartNestedIterator(nd, lblOnEnd); if (cachesResult) - _iterCurr.Storage = _iterCurr.ParentIterator.Storage; + _iterCurr.Storage = _iterCurr.ParentIterator!.Storage; else Visit(nd); @@ -4919,7 +4923,7 @@ private bool CachesResult(QilNode nd) case QilNodeType.Invoke: case QilNodeType.XsltInvokeLateBound: case QilNodeType.XsltInvokeEarlyBound: - return !nd.XmlType.IsSingleton; + return !nd.XmlType!.IsSingleton; case QilNodeType.Filter: // EqualityIndex pattern caches results @@ -4927,7 +4931,7 @@ private bool CachesResult(QilNode nd) return patt.MatchesPattern(OptimizerPatternName.EqualityIndex); case QilNodeType.DocOrderDistinct: - if (nd.XmlType.IsSingleton) + if (nd.XmlType!.IsSingleton) return false; // JoinAndDod and DodReverse patterns don't cache results @@ -4948,7 +4952,7 @@ private bool CachesResult(QilNode nd) /// private Type GetStorageType(QilNode nd) { - return XmlILTypeHelper.GetStorageType(nd.XmlType); + return XmlILTypeHelper.GetStorageType(nd.XmlType!); } /// @@ -4964,7 +4968,7 @@ private Type GetStorageType(XmlQueryType typ) /// private Type GetItemStorageType(QilNode nd) { - return XmlILTypeHelper.GetStorageType(nd.XmlType.Prime); + return XmlILTypeHelper.GetStorageType(nd.XmlType!.Prime); } /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ListBase.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ListBase.cs index 6d43e7c04d79..e9e85c1d8e6a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ListBase.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/ListBase.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. +#nullable enable using System; using System.Xml; using System.Xml.Schema; @@ -8,6 +9,7 @@ using System.Diagnostics; using System.Text; using System.Reflection; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl { @@ -37,7 +39,7 @@ public virtual bool Contains(T value) public virtual int IndexOf(T value) { for (int i = 0; i < Count; i++) - if (value.Equals(this[i])) + if (value!.Equals(this[i])) return i; return -1; @@ -127,21 +129,21 @@ void System.Collections.ICollection.CopyTo(Array array, int index) array.SetValue(this[i], index); } - object System.Collections.IList.this[int index] + object? System.Collections.IList.this[int index] { get { return this[index]; } set { - if (!IsCompatibleType(value.GetType())) + if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); this[index] = (T)value; } } - int System.Collections.IList.Add(object value) + int System.Collections.IList.Add(object? value) { - if (!IsCompatibleType(value.GetType())) + if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); Add((T)value); @@ -153,33 +155,33 @@ void System.Collections.IList.Clear() Clear(); } - bool System.Collections.IList.Contains(object value) + bool System.Collections.IList.Contains(object? value) { - if (!IsCompatibleType(value.GetType())) + if (!IsCompatibleType(value!.GetType())) return false; return Contains((T)value); } - int System.Collections.IList.IndexOf(object value) + int System.Collections.IList.IndexOf(object? value) { - if (!IsCompatibleType(value.GetType())) + if (!IsCompatibleType(value!.GetType())) return -1; return IndexOf((T)value); } - void System.Collections.IList.Insert(int index, object value) + void System.Collections.IList.Insert(int index, object? value) { - if (!IsCompatibleType(value.GetType())) + if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); Insert(index, (T)value); } - void System.Collections.IList.Remove(object value) + void System.Collections.IList.Remove(object? value) { - if (IsCompatibleType(value.GetType())) + if (IsCompatibleType(value!.GetType())) { Remove((T)value); } @@ -190,7 +192,7 @@ void System.Collections.IList.Remove(object value) // Helper methods and classes //----------------------------------------------- - private static bool IsCompatibleType(object value) + private static bool IsCompatibleType(object? value) { if ((value == null && !typeof(T).IsValueType) || (value is T)) return true; @@ -215,7 +217,7 @@ public IListEnumerator(IList sequence) { _sequence = sequence; _index = 0; - _current = default(T); + _current = default(T)!; } /// @@ -246,7 +248,7 @@ object System.Collections.IEnumerator.Current if (_index > _sequence.Count) throw new InvalidOperationException(SR.Format(SR.Sch_EnumFinished, string.Empty)); - return _current; + return _current!; } } @@ -262,7 +264,7 @@ public bool MoveNext() return true; } - _current = default(T); + _current = default(T)!; return false; } @@ -272,7 +274,7 @@ public bool MoveNext() void System.Collections.IEnumerator.Reset() { _index = 0; - _current = default(T); + _current = default(T)!; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Pair.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Pair.cs index 478b5a78d9e8..893ec61b7b9e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Pair.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Pair.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. +#nullable enable using System; using System.Diagnostics; @@ -20,7 +21,7 @@ public Int32Pair(int left, int right) public int Left { get { return _left; } } public int Right { get { return _right; } } - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is Int32Pair) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilBinary.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilBinary.cs index 47765658b99f..a71c32a6e8dd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilBinary.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilBinary.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilChoice.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilChoice.cs index daff0690f6d2..2a3a6ec1dfdd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilChoice.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilChoice.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. +#nullable enable using System; using System.Collections; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs index 8a253a29fd89..2865ecc906b3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml; using System.Xml.Xsl; @@ -52,10 +54,10 @@ public QilNode Clone(QilNode node) /// protected override QilNode Visit(QilNode oldNode) { - QilNode newNode = null; + QilNode? newNode = null; if (oldNode == null) - return null; + return null!; // ShallowClone any nodes which have not yet been cloned if (oldNode is QilReference) @@ -93,7 +95,7 @@ protected override QilNode VisitChildren(QilNode parent) else { // Otherwise, visit the node and substitute its copy - parent[i] = Visit(child); + parent[i] = Visit(child)!; } } @@ -105,7 +107,7 @@ protected override QilNode VisitChildren(QilNode parent) /// protected override QilNode VisitReference(QilNode oldNode) { - QilNode newNode = FindClonedReference(oldNode); + QilNode? newNode = FindClonedReference(oldNode); return base.VisitReference(newNode == null ? oldNode : newNode); } @@ -138,7 +140,7 @@ protected override void EndScope(QilNode node) /// /// Find the clone of an in-scope reference. /// - protected QilNode FindClonedReference(QilNode node) + protected QilNode? FindClonedReference(QilNode node) { return _subs.FindReplacement(node); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilDataSource.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilDataSource.cs index 99ad88b9a45a..cca511141a67 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilDataSource.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilDataSource.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. +#nullable enable using System; using System.Collections.Generic; using System.Xml.Schema; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilExpression.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilExpression.cs index d24583ff88d4..74378ec7f643 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilExpression.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilExpression.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. +#nullable enable using System.Collections.Generic; using System.Xml.Xsl.Runtime; @@ -119,7 +120,7 @@ public bool IsDebug /// public XmlWriterSettings DefaultWriterSettings { - get { return (XmlWriterSettings)((QilLiteral)_defWSet).Value; } + get { return (XmlWriterSettings)((QilLiteral)_defWSet).Value!; } set { value.ReadOnly = true; @@ -132,7 +133,7 @@ public XmlWriterSettings DefaultWriterSettings /// public IList WhitespaceRules { - get { return (IList)((QilLiteral)_wsRules).Value; } + get { return (IList)((QilLiteral)_wsRules).Value!; } set { ((QilLiteral)_wsRules).Value = value; } } @@ -159,7 +160,7 @@ public QilList GlobalVariableList /// public IList EarlyBoundTypes { - get { return (IList)((QilLiteral)_earlBnd).Value; } + get { return (IList)((QilLiteral)_earlBnd).Value!; } set { ((QilLiteral)_earlBnd).Value = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFactory.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFactory.cs index d052c40f55c8..695fc459e78b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFactory.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFactory.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. +#nullable enable using System.Collections.Generic; namespace System.Xml.Xsl.Qil @@ -236,7 +237,7 @@ public QilIterator Let(QilNode binding) return n; } - public QilParameter Parameter(QilNode defaultValue, QilNode name, XmlQueryType xmlType) + public QilParameter Parameter(QilNode? defaultValue, QilNode? name, XmlQueryType xmlType) { QilParameter n = new QilParameter(QilNodeType.Parameter, defaultValue, name, xmlType); n.XmlType = _typeCheck.CheckParameter(n); @@ -274,7 +275,7 @@ public QilNode False() return n; } - public QilLiteral LiteralString(string value) + public QilLiteral LiteralString(string? value) { QilLiteral n = new QilLiteral(QilNodeType.LiteralString, value); n.XmlType = _typeCheck.CheckLiteralString(n); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFunction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFunction.cs index b6dd25a1c8da..d00e2262c141 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFunction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilFunction.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvoke.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvoke.cs index 0530d062e2c9..48326db762dc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvoke.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvoke.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. +#nullable enable using System; using System.Diagnostics; using System.Xml.Schema; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs index 7f775dbb455e..b8e07b16e937 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeEarlyBound.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. +#nullable enable using System; using System.Diagnostics; using System.Reflection; @@ -38,7 +39,7 @@ public QilName Name public MethodInfo ClrMethod { - get { return (MethodInfo)((QilLiteral)Center).Value; } + get { return (MethodInfo)((QilLiteral)Center).Value!; } set { ((QilLiteral)Center).Value = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeLateBound.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeLateBound.cs index dfa095333190..a558cc2f65f2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeLateBound.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilInvokeLateBound.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. +#nullable enable using System; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilIterator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilIterator.cs index 6d3c464128f5..3a9247e91347 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilIterator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilIterator.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. +#nullable enable using System; using System.Diagnostics; @@ -11,7 +12,7 @@ namespace System.Xml.Xsl.Qil /// internal class QilIterator : QilReference { - private QilNode _binding; + private QilNode? _binding; //----------------------------------------------- // Constructor @@ -20,7 +21,7 @@ internal class QilIterator : QilReference /// /// Construct an iterator /// - public QilIterator(QilNodeType nodeType, QilNode binding) : base(nodeType) + public QilIterator(QilNodeType nodeType, QilNode? binding) : base(nodeType) { Binding = binding; } @@ -37,7 +38,7 @@ public override int Count public override QilNode this[int index] { - get { if (index != 0) throw new IndexOutOfRangeException(); return _binding; } + get { if (index != 0) throw new IndexOutOfRangeException(); return _binding!; } set { if (index != 0) throw new IndexOutOfRangeException(); _binding = value; } } @@ -49,7 +50,7 @@ public override QilNode this[int index] /// /// Expression which is bound to the iterator. /// - public QilNode Binding + public QilNode? Binding { get { return _binding; } set { _binding = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilList.cs index 9061249c03ec..171fde25f79e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilList.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -53,15 +54,15 @@ public override XmlQueryType XmlType if (this.nodeType == QilNodeType.Sequence) { for (int i = 0; i < _count; i++) - xt = XmlQueryTypeFactory.Sequence(xt, _members[i].XmlType); + xt = XmlQueryTypeFactory.Sequence(xt, _members[i].XmlType!); Debug.Assert(!xt.IsDod, "Sequences do not preserve DocOrderDistinct"); } else if (this.nodeType == QilNodeType.BranchList) { - xt = _members[0].XmlType; + xt = _members[0].XmlType!; for (int i = 1; i < _count; i++) - xt = XmlQueryTypeFactory.Choice(xt, _members[i].XmlType); + xt = XmlQueryTypeFactory.Choice(xt, _members[i].XmlType!); } } @@ -145,7 +146,7 @@ public override void RemoveAt(int index) if (index < _count) Array.Copy(_members, index + 1, _members, index, _count - index); - _members[_count] = null; + _members[_count] = null!; // Invalidate XmlType this.xmlType = null; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLiteral.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLiteral.cs index b40a74482f47..c86dbb2712ff 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLiteral.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLiteral.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Qil { @@ -14,7 +16,7 @@ namespace System.Xml.Xsl.Qil /// internal class QilLiteral : QilNode { - private object _value; + private object? _value; //----------------------------------------------- @@ -24,7 +26,7 @@ internal class QilLiteral : QilNode /// /// Construct a new node /// - public QilLiteral(QilNodeType nodeType, object value) : base(nodeType) + public QilLiteral(QilNodeType nodeType, object? value) : base(nodeType) { Value = value; } @@ -33,8 +35,7 @@ public QilLiteral(QilNodeType nodeType, object value) : base(nodeType) //----------------------------------------------- // QilLiteral methods //----------------------------------------------- - - public object Value + public object? Value { get { return _value; } set { _value = value; } @@ -42,32 +43,32 @@ public object Value public static implicit operator string(QilLiteral literal) { - return (string)literal._value; + return (string)literal._value!; } public static implicit operator int(QilLiteral literal) { - return (int)literal._value; + return (int)literal._value!; } public static implicit operator long(QilLiteral literal) { - return (long)literal._value; + return (long)literal._value!; } public static implicit operator double(QilLiteral literal) { - return (double)literal._value; + return (double)literal._value!; } public static implicit operator decimal(QilLiteral literal) { - return (decimal)literal._value; + return (decimal)literal._value!; } public static implicit operator XmlQueryType(QilLiteral literal) { - return (XmlQueryType)literal._value; + return (XmlQueryType)literal._value!; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLoop.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLoop.cs index b3f2f2989856..cfe90c421faf 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLoop.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilLoop.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. +#nullable enable using System; using System.Collections; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilName.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilName.cs index 6526eac1ef6c..a51f7597c50d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilName.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilName.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Qil { @@ -42,18 +44,21 @@ public QilName(QilNodeType nodeType, string local, string uri, string prefix) : public string LocalName { get { return _local; } + [MemberNotNull(nameof(_local))] set { _local = value; } } public string NamespaceUri { get { return _uri; } + [MemberNotNull(nameof(_uri))] set { _uri = value; } } public string Prefix { get { return _prefix; } + [MemberNotNull(nameof(_prefix))] set { _prefix = value; } } @@ -88,9 +93,9 @@ public override int GetHashCode() /// Override Equals() so that the QilName can be used as a key in the hashtable. /// /// Does not compare their prefixes (if any). - public override bool Equals(object other) + public override bool Equals(object? other) { - QilName name = other as QilName; + QilName? name = other as QilName; if (name == null) return false; @@ -101,13 +106,13 @@ public override bool Equals(object other) /// Implement operator == to prevent accidental referential comparison /// /// Does not compare their prefixes (if any). - public static bool operator ==(QilName a, QilName b) + public static bool operator ==(QilName? a, QilName? b) { - if ((object)a == (object)b) + if ((object?)a == (object?)b) { return true; } - if ((object)a == null || (object)b == null) + if ((object?)a == null || (object?)b == null) { return false; } @@ -118,7 +123,7 @@ public override bool Equals(object other) /// Implement operator != to prevent accidental referential comparison /// /// Does not compare their prefixes (if any). - public static bool operator !=(QilName a, QilName b) + public static bool operator !=(QilName? a, QilName? b) { return !(a == b); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNode.cs index 9c1f146beaa3..cd2cca2f7a0c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNode.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -22,9 +23,9 @@ namespace System.Xml.Xsl.Qil internal class QilNode : IList { protected QilNodeType nodeType; - protected XmlQueryType xmlType; - protected ISourceLineInfo sourceLine; - protected object annotation; + protected XmlQueryType? xmlType; + protected ISourceLineInfo? sourceLine; + protected object? annotation; //----------------------------------------------- // Constructor @@ -64,7 +65,7 @@ public QilNodeType NodeType /// /// Access the QIL type. /// - public virtual XmlQueryType XmlType + public virtual XmlQueryType? XmlType { get { return this.xmlType; } set { this.xmlType = value; } @@ -73,7 +74,7 @@ public virtual XmlQueryType XmlType /// /// Line info information for tools support. /// - public ISourceLineInfo SourceLine + public ISourceLineInfo? SourceLine { get { return this.sourceLine; } set { this.sourceLine = value; } @@ -82,7 +83,7 @@ public ISourceLineInfo SourceLine /// /// Access an annotation which may have been attached to this node. /// - public object Annotation + public object? Annotation { get { return this.annotation; } set { this.annotation = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNodeType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNodeType.cs index c9973ae9a244..387544491a6c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNodeType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilNodeType.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. +#nullable enable namespace System.Xml.Xsl.Qil { /// An enumeration of all the possible QilExpression node types. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilParameter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilParameter.cs index c2e5add838c3..085962bbbbbd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilParameter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilParameter.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. +#nullable enable using System; using System.Diagnostics; @@ -11,7 +12,7 @@ namespace System.Xml.Xsl.Qil /// internal class QilParameter : QilIterator { - private QilNode _name; + private QilNode? _name; //----------------------------------------------- // Constructor @@ -20,7 +21,7 @@ internal class QilParameter : QilIterator /// /// Construct a parameter /// - public QilParameter(QilNodeType nodeType, QilNode defaultValue, QilNode name, XmlQueryType xmlType) : base(nodeType, defaultValue) + public QilParameter(QilNodeType nodeType, QilNode? defaultValue, QilNode? name, XmlQueryType xmlType) : base(nodeType, defaultValue) { _name = name; this.xmlType = xmlType; @@ -42,8 +43,8 @@ public override QilNode this[int index] { return index switch { - 0 => Binding, - 1 => _name, + 0 => Binding!, + 1 => _name!, _ => throw new IndexOutOfRangeException(), }; } @@ -66,7 +67,7 @@ public override QilNode this[int index] /// /// Default value expression of this parameter (may be null). /// - public QilNode DefaultValue + public QilNode? DefaultValue { get { return Binding; } set { Binding = value; } @@ -75,9 +76,9 @@ public QilNode DefaultValue /// /// Name of this parameter (may be null). /// - public QilName Name + public QilName? Name { - get { return (QilName)_name; } + get { return (QilName?)_name; } set { _name = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternFactory.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternFactory.cs index 5a3bfb047fb8..5d655c188d02 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternFactory.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternFactory.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Reflection; @@ -33,7 +34,7 @@ public QilPatternFactory(QilFactory f, bool debug) #region Convenience methods - public QilLiteral String(string val) + public QilLiteral String(string? val) { return _f.LiteralString(val); } @@ -186,7 +187,7 @@ public QilParameter Parameter(XmlQueryType t) return _f.Parameter(t); } - public QilParameter Parameter(QilNode defaultValue, QilName name, XmlQueryType t) + public QilParameter Parameter(QilNode? defaultValue, QilName? name, XmlQueryType t) { return _f.Parameter(defaultValue, name, t); } @@ -226,7 +227,7 @@ public QilNode Boolean(bool b) private static void CheckLogicArg(QilNode arg) { Debug.Assert(arg != null, "Argument shouldn't be null"); - Debug.Assert(arg.XmlType.TypeCode == XmlTypeCode.Boolean && arg.XmlType.IsSingleton, + Debug.Assert(arg.XmlType!.TypeCode == XmlTypeCode.Boolean && arg.XmlType.IsSingleton, "The operand must be boolean-typed" ); } @@ -443,7 +444,7 @@ public QilNode StrConcat(QilNode values) { if (!_debug) { - if (values.XmlType.IsSingleton) + if (values.XmlType!.IsSingleton) return values; } return _f.StrConcat(values); @@ -551,7 +552,7 @@ public QilNode Filter(QilIterator variable, QilNode expr) //((Filter (For $Binding) (True ) ) => ($binding)) if (expr.NodeType == QilNodeType.True) { - return variable.Binding; + return variable.Binding!; } // The following optimization is not safe if the iterator has side effects //((Filter (For $Binding) (False) ) => (Sequence)) @@ -598,7 +599,7 @@ public QilFunction Function(QilList args, QilNode sideEffects, XmlQueryType resu public QilFunction Function(QilList args, QilNode defn, QilNode sideEffects) { Debug.Assert(args.NodeType == QilNodeType.FormalParameterList); - return _f.Function(args, defn, sideEffects, defn.XmlType); + return _f.Function(args, defn, sideEffects, defn.XmlType!); } public QilNode Invoke(QilFunction func, QilList args) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternVisitor.cs index d77d8bcc8d27..8e82891582d0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilPatternVisitor.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Qil { @@ -63,7 +65,8 @@ protected virtual QilNode Replace(int pattern, QilNode original, QilNode replace /// /// Called when all replacements have already been made and all annotations are complete. /// - protected virtual QilNode NoReplace(QilNode node) + [return: NotNullIfNotNull("node")] + protected virtual QilNode? NoReplace(QilNode? node) { return node; } @@ -79,7 +82,7 @@ protected virtual QilNode NoReplace(QilNode node) protected override QilNode Visit(QilNode node) { if (node == null) - return VisitNull(); + return VisitNull()!; node = VisitChildren(node); return base.Visit(node); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReference.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReference.cs index 973086fde844..107a645db29c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReference.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReference.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Qil { @@ -17,7 +19,7 @@ internal class QilReference : QilNode // the truncation. private const int MaxDebugNameLength = 1000; - private string _debugName; + private string? _debugName; //----------------------------------------------- // Constructor @@ -38,7 +40,8 @@ public QilReference(QilNodeType nodeType) : base(nodeType) /// /// Name of this reference, preserved for debugging (may be null). /// - public string DebugName + [DisallowNull] + public string? DebugName { get { return _debugName; } set diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReplaceVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReplaceVisitor.cs index f03325553d31..a7799c4e2a1d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReplaceVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilReplaceVisitor.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -31,23 +32,23 @@ public QilReplaceVisitor(QilFactory f) /// protected override QilNode VisitChildren(QilNode parent) { - XmlQueryType oldParentType = parent.XmlType; + XmlQueryType oldParentType = parent.XmlType!; bool recalcType = false; // Visit children for (int i = 0; i < parent.Count; i++) { QilNode oldChild = parent[i], newChild; - XmlQueryType oldChildType = oldChild != null ? oldChild.XmlType : null; + XmlQueryType? oldChildType = oldChild != null ? oldChild.XmlType : null; // Visit child if (IsReference(parent, i)) - newChild = VisitReference(oldChild); + newChild = VisitReference(oldChild!); else - newChild = Visit(oldChild); + newChild = Visit(oldChild!); // Only replace child and recalculate type if oldChild != newChild or oldChild.XmlType != newChild.XmlType - if ((object)oldChild != (object)newChild || (newChild != null && (object)oldChildType != (object)newChild.XmlType)) + if ((object?)oldChild != (object)newChild || (newChild != null && (object?)oldChildType != (object?)newChild.XmlType)) { recalcType = true; parent[i] = newChild; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilScopedVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilScopedVisitor.cs index 84b4cba51682..01519661151b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilScopedVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilScopedVisitor.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. +#nullable enable using System; using System.Collections.Generic; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilSortKey.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilSortKey.cs index 073e8a291fd6..cab41ac94651 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilSortKey.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilSortKey.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. +#nullable enable using System; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilStrConcat.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilStrConcat.cs index 8dafd52113c4..49761767eed5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilStrConcat.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilStrConcat.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. +#nullable enable using System; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTargetType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTargetType.cs index dc159addb54b..e5c77760b538 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTargetType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTargetType.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. +#nullable enable using System; using System.Collections.Generic; using System.Xml.Schema; @@ -40,7 +41,7 @@ public QilNode Source public XmlQueryType TargetType { - get { return (XmlQueryType)((QilLiteral)Right).Value; } + get { return (XmlQueryType)((QilLiteral)Right).Value!; } set { ((QilLiteral)Right).Value = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTernary.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTernary.cs index 787937751c41..86ddd1fe85a3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTernary.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTernary.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTypeChecker.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTypeChecker.cs index d560c09507e6..ac947b5a9ed9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTypeChecker.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilTypeChecker.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. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -227,12 +228,12 @@ public XmlQueryType CheckBranchList(QilList node) public XmlQueryType CheckOptimizeBarrier(QilUnary node) { - return node.Child.XmlType; + return node.Child.XmlType!; } public XmlQueryType CheckUnknown(QilNode node) { - return node.XmlType; + return node.XmlType!; } #endregion // meta @@ -250,7 +251,7 @@ public XmlQueryType CheckDataSource(QilDataSource node) public XmlQueryType CheckNop(QilUnary node) { - return node.Child.XmlType; + return node.Child.XmlType!; } public XmlQueryType CheckError(QilUnary node) @@ -273,18 +274,18 @@ public XmlQueryType CheckWarning(QilUnary node) //----------------------------------------------- public XmlQueryType CheckFor(QilIterator node) { - return node.Binding.XmlType.Prime; + return node.Binding!.XmlType!.Prime; } public XmlQueryType CheckLet(QilIterator node) { - return node.Binding.XmlType; + return node.Binding!.XmlType!; } public XmlQueryType CheckParameter(QilParameter node) { - Check(node.Binding == null || node.Binding.XmlType.IsSubtypeOf(node.XmlType), node, "Parameter binding's xml type must be a subtype of the parameter's type"); - return node.XmlType; + Check(node.Binding == null || node.Binding.XmlType!.IsSubtypeOf(node.XmlType!), node, "Parameter binding's xml type must be a subtype of the parameter's type"); + return node.XmlType!; } public XmlQueryType CheckPositionOf(QilUnary node) @@ -391,7 +392,7 @@ public XmlQueryType CheckNot(QilUnary node) public XmlQueryType CheckConditional(QilTernary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.BooleanX); - return XmlQueryTypeFactory.Choice(node.Center.XmlType, node.Right.XmlType); + return XmlQueryTypeFactory.Choice(node.Center.XmlType!, node.Right.XmlType!); } public XmlQueryType CheckChoice(QilChoice node) @@ -422,7 +423,7 @@ public XmlQueryType CheckUnion(QilBinary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.NodeNotRtfS); CheckXmlType(node.Right, XmlQueryTypeFactory.NodeNotRtfS); - return DistinctType(XmlQueryTypeFactory.Sequence(node.Left.XmlType, node.Right.XmlType)); + return DistinctType(XmlQueryTypeFactory.Sequence(node.Left.XmlType!, node.Right.XmlType!)); } public XmlQueryType CheckIntersection(QilBinary node) @@ -434,12 +435,12 @@ public XmlQueryType CheckDifference(QilBinary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.NodeNotRtfS); CheckXmlType(node.Right, XmlQueryTypeFactory.NodeNotRtfS); - return XmlQueryTypeFactory.AtMost(node.Left.XmlType, node.Left.XmlType.Cardinality); + return XmlQueryTypeFactory.AtMost(node.Left.XmlType!, node.Left.XmlType!.Cardinality); } public XmlQueryType CheckAverage(QilUnary node) { - XmlQueryType xmlType = node.Child.XmlType; + XmlQueryType xmlType = node.Child.XmlType!; CheckNumericXS(node.Child); return XmlQueryTypeFactory.PrimeProduct(xmlType, xmlType.MaybeEmpty ? XmlQueryCardinality.ZeroOrOne : XmlQueryCardinality.One); } @@ -468,7 +469,7 @@ public XmlQueryType CheckMaximum(QilUnary node) public XmlQueryType CheckNegate(QilUnary node) { CheckNumericX(node.Child); - return node.Child.XmlType; + return node.Child.XmlType!; } public XmlQueryType CheckAdd(QilBinary node) @@ -476,7 +477,7 @@ public XmlQueryType CheckAdd(QilBinary node) CheckNumericX(node.Left); CheckNumericX(node.Right); CheckNotDisjoint(node); - return node.Left.XmlType.TypeCode == XmlTypeCode.None ? node.Right.XmlType : node.Left.XmlType; + return node.Left.XmlType!.TypeCode == XmlTypeCode.None ? node.Right.XmlType! : node.Left.XmlType!; } public XmlQueryType CheckSubtract(QilBinary node) @@ -521,7 +522,7 @@ public XmlQueryType CheckStrConcat(QilStrConcat node) public XmlQueryType CheckStrParseQName(QilBinary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.StringX); - Check(node.Right.XmlType.IsSubtypeOf(XmlQueryTypeFactory.StringX) || node.Right.XmlType.IsSubtypeOf(XmlQueryTypeFactory.NamespaceS), + Check(node.Right.XmlType!.IsSubtypeOf(XmlQueryTypeFactory.StringX) || node.Right.XmlType.IsSubtypeOf(XmlQueryTypeFactory.NamespaceS), node, "StrParseQName must take either a string or a list of namespace as its second argument"); return XmlQueryTypeFactory.QNameX; } @@ -599,8 +600,8 @@ public XmlQueryType CheckLoop(QilLoop node) CheckClass(node[0], typeof(QilIterator)); Check(node.Variable.NodeType == QilNodeType.For || node.Variable.NodeType == QilNodeType.Let, node, "Loop variable must be a For or Let iterator"); - XmlQueryType bodyType = node.Body.XmlType; - XmlQueryCardinality variableCard = node.Variable.NodeType == QilNodeType.Let ? XmlQueryCardinality.One : node.Variable.Binding.XmlType.Cardinality; + XmlQueryType bodyType = node.Body.XmlType!; + XmlQueryCardinality variableCard = node.Variable.NodeType == QilNodeType.Let ? XmlQueryCardinality.One : node.Variable.Binding!.XmlType!.Cardinality; // Loops do not preserve DocOrderDistinct return XmlQueryTypeFactory.PrimeProduct(bodyType, variableCard * bodyType.Cardinality); @@ -613,11 +614,11 @@ public XmlQueryType CheckFilter(QilLoop node) CheckXmlType(node.Body, XmlQueryTypeFactory.BooleanX); // Attempt to restrict filter's type by checking condition - XmlQueryType filterType = FindFilterType(node.Variable, node.Body); + XmlQueryType? filterType = FindFilterType(node.Variable, node.Body); if (filterType != null) return filterType; - return XmlQueryTypeFactory.AtMost(node.Variable.Binding.XmlType, node.Variable.Binding.XmlType.Cardinality); + return XmlQueryTypeFactory.AtMost(node.Variable.Binding!.XmlType!, node.Variable.Binding.XmlType!.Cardinality); } #endregion // loops @@ -628,7 +629,7 @@ public XmlQueryType CheckFilter(QilLoop node) //----------------------------------------------- public XmlQueryType CheckSort(QilLoop node) { - XmlQueryType varType = node.Variable.Binding.XmlType; + XmlQueryType varType = node.Variable.Binding!.XmlType!; CheckClassAndNodeType(node[0], typeof(QilIterator), QilNodeType.For); CheckClassAndNodeType(node[1], typeof(QilList), QilNodeType.SortKeyList); @@ -641,13 +642,13 @@ public XmlQueryType CheckSortKey(QilSortKey node) { CheckAtomicX(node.Key); CheckXmlType(node.Collation, XmlQueryTypeFactory.StringX); - return node.Key.XmlType; + return node.Key.XmlType!; } public XmlQueryType CheckDocOrderDistinct(QilUnary node) { CheckXmlType(node.Child, XmlQueryTypeFactory.NodeNotRtfS); - return DistinctType(node.Child.XmlType); + return DistinctType(node.Child.XmlType!); } #endregion // sorting @@ -660,8 +661,8 @@ public XmlQueryType CheckFunction(QilFunction node) { CheckClassAndNodeType(node[0], typeof(QilList), QilNodeType.FormalParameterList); Check(node[2].NodeType == QilNodeType.False || node[2].NodeType == QilNodeType.True, node, "SideEffects must either be True or False"); - Check(node.Definition.XmlType.IsSubtypeOf(node.XmlType), node, "Function definition's xml type must be a subtype of the function's return type"); - return node.XmlType; + Check(node.Definition.XmlType!.IsSubtypeOf(node.XmlType!), node, "Function definition's xml type must be a subtype of the function's return type"); + return node.XmlType!; } public XmlQueryType CheckInvoke(QilInvoke node) @@ -674,10 +675,10 @@ public XmlQueryType CheckInvoke(QilInvoke node) Check(actualArgs.Count == formalArgs.Count, actualArgs, "Invoke argument count must match function's argument count"); for (int i = 0; i < actualArgs.Count; i++) - Check(actualArgs[i].XmlType.IsSubtypeOf(formalArgs[i].XmlType), actualArgs[i], "Invoke argument must be a subtype of the invoked function's argument"); + Check(actualArgs[i].XmlType!.IsSubtypeOf(formalArgs[i].XmlType!), actualArgs[i], "Invoke argument must be a subtype of the invoked function's argument"); #endif - return node.Function.XmlType; + return node.Function.XmlType!; } #endregion // function definition and invocation @@ -725,7 +726,7 @@ public XmlQueryType CheckDescendant(QilUnary node) public XmlQueryType CheckDescendantOrSelf(QilUnary node) { CheckXmlType(node.Child, XmlQueryTypeFactory.NodeNotRtf); - return XmlQueryTypeFactory.Choice(node.Child.XmlType, XmlQueryTypeFactory.ContentS); + return XmlQueryTypeFactory.Choice(node.Child.XmlType!, XmlQueryTypeFactory.ContentS); } public XmlQueryType CheckAncestor(QilUnary node) @@ -737,7 +738,7 @@ public XmlQueryType CheckAncestor(QilUnary node) public XmlQueryType CheckAncestorOrSelf(QilUnary node) { CheckXmlType(node.Child, XmlQueryTypeFactory.NodeNotRtf); - return XmlQueryTypeFactory.Choice(node.Child.XmlType, XmlQueryTypeFactory.DocumentOrElementS); + return XmlQueryTypeFactory.Choice(node.Child.XmlType!, XmlQueryTypeFactory.DocumentOrElementS); } public XmlQueryType CheckPreceding(QilUnary node) @@ -762,7 +763,7 @@ public XmlQueryType CheckNodeRange(QilBinary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.NodeNotRtf); CheckXmlType(node.Right, XmlQueryTypeFactory.NodeNotRtf); - return XmlQueryTypeFactory.Choice(node.Left.XmlType, XmlQueryTypeFactory.ContentS, node.Right.XmlType); + return XmlQueryTypeFactory.Choice(node.Left.XmlType!, XmlQueryTypeFactory.ContentS, node.Right.XmlType!); } public XmlQueryType CheckDeref(QilBinary node) @@ -955,25 +956,25 @@ public XmlQueryType CheckXsltInvokeEarlyBound(QilInvokeEarlyBound node) for (int i = 0; i < actualArgs.Count; i++) { - Check(actualArgs[i].XmlType.IsSubtypeOf(extFunc.GetXmlArgumentType(i)), actualArgs[i], "InvokeEarlyBound argument must be a subtype of the invoked function's argument type"); + Check(actualArgs[i].XmlType!.IsSubtypeOf(extFunc.GetXmlArgumentType(i)), actualArgs[i], "InvokeEarlyBound argument must be a subtype of the invoked function's argument type"); } #endif - return node.XmlType; + return node.XmlType!; } public XmlQueryType CheckXsltCopy(QilBinary node) { CheckXmlType(node.Left, XmlQueryTypeFactory.NodeNotRtf); CheckXmlType(node.Right, XmlQueryTypeFactory.NodeS); - return XmlQueryTypeFactory.Choice(node.Left.XmlType, node.Right.XmlType); + return XmlQueryTypeFactory.Choice(node.Left.XmlType!, node.Right.XmlType!); } public XmlQueryType CheckXsltCopyOf(QilUnary node) { CheckXmlType(node.Child, XmlQueryTypeFactory.Node); - if ((node.Child.XmlType.NodeKinds & XmlNodeKindFlags.Document) != 0) + if ((node.Child.XmlType!.NodeKinds & XmlNodeKindFlags.Document) != 0) return XmlQueryTypeFactory.NodeNotRtfS; return node.Child.XmlType; @@ -1003,7 +1004,7 @@ private void CheckLiteralValue(QilNode node, Type clrTypeValue) { Check(node is QilLiteral, node, "Node must be instance of QilLiteral"); - Type clrType = ((QilLiteral)node).Value.GetType(); + Type clrType = ((QilLiteral)node).Value!.GetType(); Check(clrTypeValue.IsAssignableFrom(clrType), node, "Literal value must be of type " + clrTypeValue.Name); } @@ -1023,31 +1024,31 @@ private void CheckClassAndNodeType(QilNode node, Type clrTypeClass, QilNodeType [Conditional("DEBUG")] private void CheckXmlType(QilNode node, XmlQueryType xmlType) { - Check(node.XmlType.IsSubtypeOf(xmlType), node, "Node's type " + node.XmlType + " is not a subtype of " + xmlType); + Check(node.XmlType!.IsSubtypeOf(xmlType), node, "Node's type " + node.XmlType + " is not a subtype of " + xmlType); } [Conditional("DEBUG")] private void CheckNumericX(QilNode node) { - Check(node.XmlType.IsNumeric && node.XmlType.IsSingleton && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict singleton numeric type"); + Check(node.XmlType!.IsNumeric && node.XmlType.IsSingleton && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict singleton numeric type"); } [Conditional("DEBUG")] private void CheckNumericXS(QilNode node) { - Check(node.XmlType.IsNumeric && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict numeric type"); + Check(node.XmlType!.IsNumeric && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict numeric type"); } [Conditional("DEBUG")] private void CheckAtomicX(QilNode node) { - Check(node.XmlType.IsAtomicValue && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict atomic value type"); + Check(node.XmlType!.IsAtomicValue && node.XmlType.IsStrict, node, "Node's type " + node.XmlType + " must be a strict atomic value type"); } [Conditional("DEBUG")] private void CheckNotDisjoint(QilBinary node) { - Check(node.Left.XmlType.IsSubtypeOf(node.Right.XmlType) || node.Right.XmlType.IsSubtypeOf(node.Left.XmlType), node, + Check(node.Left.XmlType!.IsSubtypeOf(node.Right.XmlType!) || node.Right.XmlType!.IsSubtypeOf(node.Left.XmlType), node, "Node must not have arguments with disjoint types " + node.Left.XmlType + " and " + node.Right.XmlType); } @@ -1062,12 +1063,12 @@ private XmlQueryType DistinctType(XmlQueryType type) return type; } - private XmlQueryType FindFilterType(QilIterator variable, QilNode body) + private XmlQueryType? FindFilterType(QilIterator variable, QilNode body) { - XmlQueryType leftType; + XmlQueryType? leftType; QilBinary binary; - if (body.XmlType.TypeCode == XmlTypeCode.None) + if (body.XmlType!.TypeCode == XmlTypeCode.None) return XmlQueryTypeFactory.None; switch (body.NodeType) @@ -1078,7 +1079,7 @@ private XmlQueryType FindFilterType(QilIterator variable, QilNode body) case QilNodeType.IsType: // If testing the type of "variable", then filter type can be restricted if ((object)((QilTargetType)body).Source == (object)variable) - return XmlQueryTypeFactory.AtMost(((QilTargetType)body).TargetType, variable.Binding.XmlType.Cardinality); + return XmlQueryTypeFactory.AtMost(((QilTargetType)body).TargetType, variable.Binding!.XmlType!.Cardinality); break; case QilNodeType.And: @@ -1095,7 +1096,7 @@ private XmlQueryType FindFilterType(QilIterator variable, QilNode body) if (binary.Left.NodeType == QilNodeType.PositionOf) { if ((object)((QilUnary)binary.Left).Child == (object)variable) - return XmlQueryTypeFactory.AtMost(variable.Binding.XmlType, XmlQueryCardinality.ZeroOrOne); + return XmlQueryTypeFactory.AtMost(variable.Binding!.XmlType!, XmlQueryCardinality.ZeroOrOne); } break; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilUnary.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilUnary.cs index 112cf6097148..151ab3fa5cb9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilUnary.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilUnary.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. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilValidationVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilValidationVisitor.cs index d6ae6606999e..8134de7f5ca4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilValidationVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilValidationVisitor.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. +#nullable enable using System.Collections; using System.Diagnostics; @@ -152,7 +153,7 @@ protected override void EndScope(QilNode node) private class ObjectHashtable : Hashtable { - protected override bool KeyEquals(object item, object key) + protected override bool KeyEquals(object? item, object key) { return item == key; } @@ -182,7 +183,7 @@ internal static void SetError(QilNode n, string message) message += " ["+ n.NodeId + " (" + n.NodeType.ToString("G") + ")]"; #endif - string s = n.Annotation as string; + string? s = n.Annotation as string; if (s != null) { message = s + "\n" + message; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilVisitor.cs index 60fdfad6a3a8..88ac380bd6f5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilVisitor.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Qil { @@ -103,7 +105,7 @@ protected virtual bool IsReference(QilNode parent, int childNum) protected virtual QilNode Visit(QilNode n) { if (n == null) - return VisitNull(); + return VisitNull()!; return n.NodeType switch { @@ -241,7 +243,7 @@ protected virtual QilNode Visit(QilNode n) protected virtual QilNode VisitReference(QilNode n) { if (n == null) - return VisitNull(); + return VisitNull()!; return n.NodeType switch { @@ -255,7 +257,7 @@ protected virtual QilNode VisitReference(QilNode n) }; } - protected virtual QilNode VisitNull() { return null; } + protected virtual QilNode? VisitNull() { return null; } #region meta protected virtual QilNode VisitQilExpression(QilExpression n) { return VisitChildren(n); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs index efd9af44d872..9188c3e8866f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using System.Xml; @@ -89,9 +91,9 @@ public void ToXml(QilNode node) /// 3. IList{object} -- recursively call WriteAnnotations for each object in list /// 4. otherwise, do not write the annotation /// - protected virtual void WriteAnnotations(object ann) + protected virtual void WriteAnnotations(object? ann) { - string s = null, name = null; + string? s = null, name = null; if (ann == null) { @@ -101,17 +103,13 @@ protected virtual void WriteAnnotations(object ann) { s = ann as string; } - else if (ann is IQilAnnotation) + else if (ann is IQilAnnotation qilann) { - // Get annotation's name and string value - IQilAnnotation qilann = ann as IQilAnnotation; name = qilann.Name; s = ann.ToString(); } - else if (ann is IList) + else if (ann is IList list) { - IList list = (IList)ann; - foreach (object annItem in list) WriteAnnotations(annItem); return; @@ -127,7 +125,7 @@ protected virtual void WriteAnnotations(object ann) protected virtual void WriteLineInfo(QilNode node) { this.writer.WriteAttributeString("lineInfo", string.Format(CultureInfo.InvariantCulture, "[{0},{1} -- {2},{3}]", - node.SourceLine.Start.Line, node.SourceLine.Start.Pos, + node.SourceLine!.Start.Line, node.SourceLine.Start.Pos, node.SourceLine.End.Line, node.SourceLine.End.Pos )); } @@ -137,7 +135,7 @@ protected virtual void WriteLineInfo(QilNode node) /// protected virtual void WriteXmlType(QilNode node) { - this.writer.WriteAttributeString("xmlType", node.XmlType.ToString((this.options & Options.RoundTripTypeInfo) != 0 ? "S" : "G")); + this.writer.WriteAttributeString("xmlType", node.XmlType!.ToString((this.options & Options.RoundTripTypeInfo) != 0 ? "S" : "G")); } @@ -213,7 +211,7 @@ protected override QilNode VisitQilExpression(QilExpression qil) foreach (QilNode n in fdecls) { // i.e. - this.writer.WriteStartElement(Enum.GetName(typeof(QilNodeType), n.NodeType)); + this.writer.WriteStartElement(Enum.GetName(typeof(QilNodeType), n.NodeType)!); this.writer.WriteAttributeString("id", _ngen.NameOf(n)); WriteXmlType(n); @@ -284,7 +282,7 @@ protected override void BeforeVisit(QilNode node) WriteAnnotations(node.Annotation); // Call WriteStartElement - this.writer.WriteStartElement("", Enum.GetName(typeof(QilNodeType), node.NodeType), ""); + this.writer.WriteStartElement("", Enum.GetName(typeof(QilNodeType), node.NodeType)!, ""); // Write common attributes #if QIL_TRACE_NODE_CREATION @@ -413,10 +411,10 @@ public string NextName() /// the node name (unique across nodes) public string NameOf(QilNode n) { - string name = null; + string? name = null; - object old = n.Annotation; - NameAnnotation a = old as NameAnnotation; + object? old = n.Annotation; + NameAnnotation? a = old as NameAnnotation; if (a == null) { name = NextName(); @@ -442,12 +440,12 @@ public void ClearName(QilNode n) /// /// Class used to hold our annotations on the graph /// - private class NameAnnotation : ListBase + private class NameAnnotation : ListBase { public string Name; - public object PriorAnnotation; + public object? PriorAnnotation; - public NameAnnotation(string s, object a) + public NameAnnotation(string s, object? a) { Name = s; PriorAnnotation = a; @@ -458,7 +456,7 @@ public override int Count get { return 1; } } - public override object this[int index] + public override object? this[int index] { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SerializationHints.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SerializationHints.cs index fc9635c2033b..952080b25513 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SerializationHints.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SerializationHints.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. +#nullable enable using System; namespace System.Xml.Xsl.Qil diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SubstitutionList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SubstitutionList.cs index db12c8e2be13..54c03eae52cb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SubstitutionList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/SubstitutionList.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. +#nullable enable using System; using System.Collections; using System.Diagnostics; @@ -46,12 +47,12 @@ public void RemoveLastSubstitutionPair() /// /// the node to replace /// null if no replacement is found - public QilNode FindReplacement(QilNode n) + public QilNode? FindReplacement(QilNode n) { Debug.Assert(_s.Count % 2 == 0); for (int i = _s.Count - 2; i >= 0; i -= 2) if (_s[i] == n) - return (QilNode)_s[i + 1]; + return (QilNode)_s[i + 1]!; return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/WhitespaceRule.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/WhitespaceRule.cs index 1e88fcd68fb2..18bf7065770e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/WhitespaceRule.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/WhitespaceRule.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Xml.Xsl.Runtime; @@ -12,8 +14,8 @@ namespace System.Xml.Xsl.Qil /// internal class WhitespaceRule { - private string _localName; - private string _namespaceName; + private string? _localName; + private string? _namespaceName; private bool _preserveSpace; /// @@ -26,7 +28,7 @@ protected WhitespaceRule() /// /// Construct new whitespace rule. /// - public WhitespaceRule(string localName, string namespaceName, bool preserveSpace) + public WhitespaceRule(string? localName, string? namespaceName, bool preserveSpace) { Init(localName, namespaceName, preserveSpace); } @@ -34,7 +36,7 @@ public WhitespaceRule(string localName, string namespaceName, bool preserveSpace /// /// Initialize whitespace rule after it's been constructed. /// - protected void Init(string localName, string namespaceName, bool preserveSpace) + protected void Init(string? localName, string? namespaceName, bool preserveSpace) { _localName = localName; _namespaceName = namespaceName; @@ -44,7 +46,7 @@ protected void Init(string localName, string namespaceName, bool preserveSpace) /// /// Local name of the element. /// - public string LocalName + public string? LocalName { get { return _localName; } set { _localName = value; } @@ -53,7 +55,7 @@ public string LocalName /// /// Namespace name (uri) of the element. /// - public string NamespaceName + public string? NamespaceName { get { return _namespaceName; } set { _namespaceName = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QueryReaderSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QueryReaderSettings.cs index d1b63c6212c9..d95ef698a6f2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QueryReaderSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QueryReaderSettings.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. +#nullable enable using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -12,14 +13,14 @@ namespace System.Xml.Xsl internal class QueryReaderSettings { private readonly bool _validatingReader; - private readonly XmlReaderSettings _xmlReaderSettings; - private readonly XmlNameTable _xmlNameTable; + private readonly XmlReaderSettings? _xmlReaderSettings; + private readonly XmlNameTable? _xmlNameTable; private readonly EntityHandling _entityHandling; private readonly bool _namespaces; private readonly bool _normalization; private readonly bool _prohibitDtd; private readonly WhitespaceHandling _whitespaceHandling; - private readonly XmlResolver _xmlResolver; + private readonly XmlResolver? _xmlResolver; public QueryReaderSettings(XmlNameTable xmlNameTable) { @@ -35,7 +36,7 @@ public QueryReaderSettings(XmlNameTable xmlNameTable) public QueryReaderSettings(XmlReader reader) { #pragma warning disable 618 - XmlValidatingReader valReader = reader as XmlValidatingReader; + XmlValidatingReader? valReader = reader as XmlValidatingReader; #pragma warning restore 618 if (valReader != null) { @@ -43,6 +44,7 @@ public QueryReaderSettings(XmlReader reader) _validatingReader = true; reader = valReader.Impl.Reader; } + _xmlReaderSettings = reader.Settings; if (_xmlReaderSettings != null) { @@ -51,7 +53,7 @@ public QueryReaderSettings(XmlReader reader) _xmlReaderSettings.CloseInput = true; _xmlReaderSettings.LineNumberOffset = 0; _xmlReaderSettings.LinePositionOffset = 0; - XmlTextReaderImpl impl = reader as XmlTextReaderImpl; + XmlTextReaderImpl? impl = reader as XmlTextReaderImpl; if (impl != null) { _xmlReaderSettings.XmlResolver = impl.GetResolver(); @@ -60,7 +62,7 @@ public QueryReaderSettings(XmlReader reader) else { _xmlNameTable = reader.NameTable; - XmlTextReader xmlTextReader = reader as XmlTextReader; + XmlTextReader? xmlTextReader = reader as XmlTextReader; if (xmlTextReader != null) { XmlTextReaderImpl impl = xmlTextReader.Impl; @@ -92,7 +94,7 @@ public XmlReader CreateReader(Stream stream, string baseUri) } else { - XmlTextReaderImpl readerImpl = new XmlTextReaderImpl(baseUri, stream, _xmlNameTable); + XmlTextReaderImpl readerImpl = new XmlTextReaderImpl(baseUri, stream, _xmlNameTable!); readerImpl.EntityHandling = _entityHandling; readerImpl.Namespaces = _namespaces; readerImpl.Normalization = _normalization; @@ -112,7 +114,7 @@ public XmlReader CreateReader(Stream stream, string baseUri) public XmlNameTable NameTable { - get { return _xmlReaderSettings != null ? _xmlReaderSettings.NameTable : _xmlNameTable; } + get { return _xmlReaderSettings != null ? _xmlReaderSettings.NameTable! : _xmlNameTable!; } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/SourceLineInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/SourceLineInfo.cs index 1542b08aa18c..d979a4c12a8f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/SourceLineInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/SourceLineInfo.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. +#nullable enable using System.Diagnostics; namespace System.Xml.Xsl @@ -27,15 +28,15 @@ public bool LessOrEqual(Location that) [DebuggerDisplay("{Uri} [{StartLine},{StartPos} -- {EndLine},{EndPos}]")] internal class SourceLineInfo : ISourceLineInfo { - protected string uriString; + protected string? uriString; protected Location start; protected Location end; - public SourceLineInfo(string uriString, int startLine, int startPos, int endLine, int endPos) + public SourceLineInfo(string? uriString, int startLine, int startPos, int endLine, int endPos) : this(uriString, new Location(startLine, startPos), new Location(endLine, endPos)) { } - public SourceLineInfo(string uriString, Location start, Location end) + public SourceLineInfo(string? uriString, Location start, Location end) { this.uriString = uriString; this.start = start; @@ -43,7 +44,7 @@ public SourceLineInfo(string uriString, Location start, Location end) Validate(this); } - public string Uri { get { return this.uriString; } } + public string? Uri { get { return this.uriString; } } public int StartLine { get { return this.start.Line; } } public Location End { get { return this.end; } } public Location Start { get { return this.start; } } @@ -82,7 +83,7 @@ public static void Validate(ISourceLineInfo lineInfo) public static string GetFileName(string uriString) { Debug.Assert(uriString != null); - Uri uri; + Uri? uri; if (uriString.Length != 0 && System.Uri.TryCreate(uriString, UriKind.Absolute, out uri) && diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs index 077c176e6418..201217f13c92 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs @@ -11,7 +11,7 @@ namespace System.Xml.Xsl.XPath internal interface IFocus { // The context item: the item currently being processed - QilNode GetCurrent(); + QilNode? GetCurrent(); // The context position: the position of the context item within the sequence of items // currently being processed diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs index 43631e67c32d..dff13ae08889 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs @@ -80,7 +80,7 @@ public virtual void StartBuild() return result; } Debug.Assert(_inTheBuild, "StartBuild() wasn't called"); - if (result.XmlType.MaybeMany && result.XmlType.IsNode && result.XmlType.IsNotRtf) + if (result.XmlType!.MaybeMany && result.XmlType.IsNode && result.XmlType.IsNotRtf) { result = _f.DocOrderDistinct(result); } @@ -147,7 +147,7 @@ private QilNode LogicalOperator(XPathOperator op, QilNode left, QilNode right) private QilNode CompareValues(XPathOperator op, QilNode left, QilNode right, XmlTypeCode compType) { Debug.Assert(compType == XmlTypeCode.Boolean || compType == XmlTypeCode.Double || compType == XmlTypeCode.String); - Debug.Assert(compType == XmlTypeCode.Boolean || left.XmlType.IsSingleton && right.XmlType.IsSingleton, "Both comparison operands must be singletons"); + Debug.Assert(compType == XmlTypeCode.Boolean || left.XmlType!.IsSingleton && right.XmlType!.IsSingleton, "Both comparison operands must be singletons"); left = _f.ConvertToType(compType, left); right = _f.ConvertToType(compType, right); @@ -168,9 +168,9 @@ private QilNode CompareValues(XPathOperator op, QilNode left, QilNode right, Xml private QilNode CompareNodeSetAndValue(XPathOperator op, QilNode nodeset, QilNode val, XmlTypeCode compType) { _f.CheckNodeSet(nodeset); - Debug.Assert(val.XmlType.IsSingleton); + Debug.Assert(val.XmlType!.IsSingleton); Debug.Assert(compType == XmlTypeCode.Boolean || compType == XmlTypeCode.Double || compType == XmlTypeCode.String, "I don't know what to do with RTF here"); - if (compType == XmlTypeCode.Boolean || nodeset.XmlType.IsSingleton) + if (compType == XmlTypeCode.Boolean || nodeset.XmlType!.IsSingleton) { return CompareValues(op, nodeset, val, compType); } @@ -197,11 +197,11 @@ private QilNode CompareNodeSetAndNodeSet(XPathOperator op, QilNode left, QilNode { _f.CheckNodeSet(left); _f.CheckNodeSet(right); - if (right.XmlType.IsSingleton) + if (right.XmlType!.IsSingleton) { return CompareNodeSetAndValue(op, /*nodeset:*/left, /*value:*/right, compType); } - if (left.XmlType.IsSingleton) + if (left.XmlType!.IsSingleton) { op = InvertOp(op); return CompareNodeSetAndValue(op, /*nodeset:*/right, /*value:*/left, compType); @@ -214,8 +214,8 @@ private QilNode CompareNodeSetAndNodeSet(XPathOperator op, QilNode left, QilNode private QilNode EqualityOperator(XPathOperator op, QilNode left, QilNode right) { Debug.Assert(op == XPathOperator.Eq || op == XPathOperator.Ne); - XmlQueryType leftType = left.XmlType; - XmlQueryType rightType = right.XmlType; + XmlQueryType leftType = left.XmlType!; + XmlQueryType rightType = right.XmlType!; if (_f.IsAnyType(left) || _f.IsAnyType(right)) { @@ -247,8 +247,8 @@ private QilNode EqualityOperator(XPathOperator op, QilNode left, QilNode right) private QilNode RelationalOperator(XPathOperator op, QilNode left, QilNode right) { Debug.Assert(op == XPathOperator.Lt || op == XPathOperator.Le || op == XPathOperator.Gt || op == XPathOperator.Ge); - XmlQueryType leftType = left.XmlType; - XmlQueryType rightType = right.XmlType; + XmlQueryType leftType = left.XmlType!; + XmlQueryType rightType = right.XmlType!; if (_f.IsAnyType(left) || _f.IsAnyType(right)) { @@ -329,7 +329,7 @@ public static XmlNodeKindFlags AxisTypeMask(XmlNodeKindFlags inputTypeMask, XPat private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeType nodeType, string? name, string? nsUri) { - XmlNodeKindFlags original = qilAxis.XmlType.NodeKinds; + XmlNodeKindFlags original = qilAxis.XmlType!.NodeKinds; XmlNodeKindFlags required = AxisTypeMask(original, nodeType, xpathAxis); QilIterator itr; @@ -344,7 +344,7 @@ private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeT else { qilAxis = _f.Filter(itr = _f.For(qilAxis), _f.IsType(itr, T.NodeChoice(required))); - qilAxis.XmlType = T.PrimeProduct(T.NodeChoice(required), qilAxis.XmlType.Cardinality); + qilAxis.XmlType = T.PrimeProduct(T.NodeChoice(required), qilAxis.XmlType!.Cardinality); // Without code bellow IlGeneragion gives stack overflow exception for the following passage. @@ -476,7 +476,7 @@ public static QilNode PredicateToBoolean(QilNode predicate, XPathQilFactory f, I // Prepocess predicate: if (predicate is number) then predicate := (position() == predicate) if (!f.IsAnyType(predicate)) { - if (predicate.XmlType.TypeCode == XmlTypeCode.Double) + if (predicate.XmlType!.TypeCode == XmlTypeCode.Double) { predicate = f.Eq(env.GetPosition(), predicate); } @@ -613,7 +613,7 @@ public virtual QilNode Function(string prefix, string name, IList args) private QilNode LocalNameOfFirstNode(QilNode arg) { _f.CheckNodeSet(arg); - if (arg.XmlType.IsSingleton) + if (arg.XmlType!.IsSingleton) { return _f.LocalNameOf(arg); } @@ -627,7 +627,7 @@ private QilNode LocalNameOfFirstNode(QilNode arg) private QilNode NamespaceOfFirstNode(QilNode arg) { _f.CheckNodeSet(arg); - if (arg.XmlType.IsSingleton) + if (arg.XmlType!.IsSingleton) { return _f.NamespaceUriOf(arg); } @@ -659,7 +659,7 @@ private QilNode NameOf(QilNode arg) private QilNode NameOfFirstNode(QilNode arg) { _f.CheckNodeSet(arg); - if (arg.XmlType.IsSingleton) + if (arg.XmlType!.IsSingleton) { return NameOf(arg); } @@ -897,7 +897,7 @@ protected override QilNode VisitUnknown(QilNode unknown) { if (_environment != null) { - unknown = _environment.GetCurrent(); + unknown = _environment.GetCurrent()!; } else if (_current != null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs index cc10b5257d90..42470c834f8a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs @@ -14,7 +14,7 @@ internal class XPathCompileException : XslLoadException public int startChar; public int endChar; - internal XPathCompileException(string queryString, int startChar, int endChar, string resId, params string[] args) + internal XPathCompileException(string queryString, int startChar, int endChar, string resId, params string?[]? args) : base(resId, args) { this.queryString = queryString; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs index f92d203ff81e..09e635a6d30a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs @@ -24,7 +24,7 @@ public QilNode Error(string res, QilNode args) return Error(InvokeFormatMessage(String(res), args)); } - public QilNode Error(ISourceLineInfo lineInfo, string res, params string[] args) + public QilNode Error(ISourceLineInfo? lineInfo, string res, params string[] args) { return Error(String(XslLoadException.CreateMessage(lineInfo, res, args))); } @@ -38,8 +38,8 @@ public QilIterator FirstNode(QilNode n) public bool IsAnyType(QilNode n) { - XmlQueryType xt = n.XmlType; - bool result = !(xt.IsStrict || xt.IsNode); + XmlQueryType? xt = n.XmlType; + bool result = !(xt!.IsStrict || xt.IsNode); Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?"); return result; } @@ -47,56 +47,56 @@ public bool IsAnyType(QilNode n) [Conditional("DEBUG")] public void CheckNode(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); + Debug.Assert(n != null && n.XmlType!.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); } [Conditional("DEBUG")] public void CheckNodeSet(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsNode, "Must be a node-set"); + Debug.Assert(n != null && n.XmlType!.IsNode, "Must be a node-set"); } [Conditional("DEBUG")] public void CheckNodeNotRtf(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); + Debug.Assert(n != null && n.XmlType!.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); } [Conditional("DEBUG")] public void CheckString(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringX), "Must be a singleton string"); + Debug.Assert(n != null && n.XmlType!.IsSubtypeOf(T.StringX), "Must be a singleton string"); } [Conditional("DEBUG")] public void CheckStringS(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringXS), "Must be a sequence of strings"); + Debug.Assert(n != null && n.XmlType!.IsSubtypeOf(T.StringXS), "Must be a sequence of strings"); } [Conditional("DEBUG")] public void CheckDouble(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); + Debug.Assert(n != null && n.XmlType!.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); } [Conditional("DEBUG")] public void CheckBool(QilNode n) { - Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); + Debug.Assert(n != null && n.XmlType!.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); } // Return true if inferred type of the given expression is never a subtype of T.NodeS public bool CannotBeNodeSet(QilNode n) { - XmlQueryType xt = n.XmlType; + XmlQueryType xt = n.XmlType!; // Do not report compile error if n is a VarPar, whose inferred type forbids nodes (SQLBUDT 339398) return xt.IsAtomicValue && !xt.IsEmpty && !(n is QilIterator); } public QilNode SafeDocOrderDistinct(QilNode n) { - XmlQueryType xt = n.XmlType; + XmlQueryType xt = n.XmlType!; if (xt.MaybeMany) { @@ -169,7 +169,7 @@ public QilNode InvokeRelationalOperator(QilNodeType op, QilNode left, QilNode ri [Conditional("DEBUG")] private void ExpectAny(QilNode n) { - Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType.ToString()); + Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType!.ToString()); } public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) @@ -188,7 +188,7 @@ public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) // XPath spec $4.2, string() public QilNode ConvertToString(QilNode n) { - switch (n.XmlType.TypeCode) + switch (n.XmlType!.TypeCode) { case XmlTypeCode.Boolean: return ( @@ -217,7 +217,7 @@ public QilNode ConvertToString(QilNode n) // XPath spec $4.3, boolean() public QilNode ConvertToBoolean(QilNode n) { - switch (n.XmlType.TypeCode) + switch (n.XmlType!.TypeCode) { case XmlTypeCode.Boolean: return n; @@ -247,7 +247,7 @@ public QilNode ConvertToBoolean(QilNode n) // XPath spec $4.4, number() public QilNode ConvertToNumber(QilNode n) { - switch (n.XmlType.TypeCode) + switch (n.XmlType!.TypeCode) { case XmlTypeCode.Boolean: return ( @@ -272,7 +272,7 @@ public QilNode ConvertToNumber(QilNode n) public QilNode ConvertToNode(QilNode n) { - if (n.XmlType.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) + if (n.XmlType!.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) { return n; } @@ -281,7 +281,7 @@ public QilNode ConvertToNode(QilNode n) public QilNode ConvertToNodeSet(QilNode n) { - if (n.XmlType.IsNode && n.XmlType.IsNotRtf) + if (n.XmlType!.IsNode && n.XmlType.IsNotRtf) { return n; } @@ -292,7 +292,7 @@ public QilNode ConvertToNodeSet(QilNode n) // Returns null if the given expression is never a node-set public QilNode? TryEnsureNodeSet(QilNode n) { - if (n.XmlType.IsNode && n.XmlType.IsNotRtf) + if (n.XmlType!.IsNode && n.XmlType.IsNotRtf) { return n; } @@ -329,7 +329,7 @@ public QilNode Id(QilNode context, QilNode id) { CheckNodeNotRtf(context); - if (id.XmlType.IsSingleton) + if (id.XmlType!.IsSingleton) { return Deref(context, ConvertToString(id)); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlILCommand.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlILCommand.cs index 75aec68b045a..6649cbbe5544 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlILCommand.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlILCommand.cs @@ -4,6 +4,7 @@ // http://webdata/xml/specs/querylowlevel.xml //------------------------------------------------------------------------------ +#nullable enable using System.Collections; using System.Diagnostics; using System.IO; @@ -92,7 +93,7 @@ public override IList Evaluate(XmlReader contextDocument, XmlResolver dataSource /// /// Execute the dynamic assembly generated by the XmlILGenerator. /// - public void Execute(object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer) + public void Execute(object defaultDocument, XmlResolver? dataSources, XsltArgumentList? argumentList, XmlWriter writer) { try { @@ -102,7 +103,7 @@ public void Execute(object defaultDocument, XmlResolver dataSources, XsltArgumen } // Try to extract a RawWriter - XmlWellFormedWriter wellFormedWriter = writer as XmlWellFormedWriter; + XmlWellFormedWriter? wellFormedWriter = writer as XmlWellFormedWriter; if (wellFormedWriter != null && wellFormedWriter.RawWriter != null && @@ -127,7 +128,7 @@ public void Execute(object defaultDocument, XmlResolver dataSources, XsltArgumen /// /// Execute the dynamic assembly generated by the XmlILGenerator. /// - private void Execute(object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) + private void Execute(object defaultDocument, XmlResolver? dataSources, XsltArgumentList? argumentList, XmlSequenceWriter results) { Debug.Assert(results != null); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs index e0ab38c610b9..e20f724312c9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.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. +#nullable enable using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -13,6 +14,7 @@ using System.Xml.Xsl.Qil; using System.Xml.Xsl.Runtime; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl { @@ -50,11 +52,11 @@ namespace System.Xml.Xsl /// internal class XmlILGenerator { - private QilExpression _qil; - private GenerateHelper _helper; - private XmlILOptimizerVisitor _optVisitor; - private XmlILVisitor _xmlIlVisitor; - private XmlILModule _module; + private QilExpression? _qil; + private GenerateHelper? _helper; + private XmlILOptimizerVisitor? _optVisitor; + private XmlILVisitor? _xmlIlVisitor; + private XmlILModule? _module; /// /// Always output debug information in debug mode. @@ -69,7 +71,8 @@ public XmlILGenerator() // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail // builds. As a result it is fine to suppress the FxCop SxS warning. - public XmlILCommand Generate(QilExpression query, TypeBuilder typeBldr) + // TODO-NULLABLE: missing [return: NotNullIfNull("typeBldr")] + public XmlILCommand? Generate(QilExpression query, TypeBuilder? typeBldr) { _qil = query; @@ -204,7 +207,7 @@ private void CreateFunctionMetadata(IList funcList) Debug.Assert(ndParam.NodeType == QilNodeType.Parameter); // Get the type of each argument as a Clr type - paramTypes[arg] = XmlILTypeHelper.GetStorageType(ndParam.XmlType); + paramTypes[arg] = XmlILTypeHelper.GetStorageType(ndParam.XmlType!); // Get the name of each argument if (ndParam.DebugName != null) @@ -220,12 +223,12 @@ private void CreateFunctionMetadata(IList funcList) else { // Pull mode functions have a return value - typReturn = XmlILTypeHelper.GetStorageType(ndFunc.XmlType); + typReturn = XmlILTypeHelper.GetStorageType(ndFunc.XmlType!); } // Create the method metadata methAttrs = ndFunc.SourceLine == null ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None; - methInfo = _module.DefineMethod(ndFunc.DebugName, typReturn, paramTypes, paramNames, methAttrs); + methInfo = _module!.DefineMethod(ndFunc.DebugName!, typReturn, paramTypes, paramNames, methAttrs); for (int arg = 0; arg < ndFunc.Arguments.Count; arg++) { @@ -250,9 +253,9 @@ private void CreateGlobalValueMetadata(IList globalList) foreach (QilReference ndRef in globalList) { // public T GlobalValue() - typReturn = XmlILTypeHelper.GetStorageType(ndRef.XmlType); + typReturn = XmlILTypeHelper.GetStorageType(ndRef.XmlType!); methAttrs = ndRef.SourceLine == null ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None; - methInfo = _module.DefineMethod(ndRef.DebugName.ToString(), typReturn, Array.Empty(), Array.Empty(), methAttrs); + methInfo = _module!.DefineMethod(ndRef.DebugName!.ToString(), typReturn, Array.Empty(), Array.Empty(), methAttrs); // Annotate function with MethodBuilder XmlILAnnotation.Write(ndRef).FunctionBinding = methInfo; @@ -264,10 +267,10 @@ private void CreateGlobalValueMetadata(IList globalList) /// private MethodInfo GenerateExecuteFunction(MethodInfo methExec, MethodInfo methRoot) { - _helper.MethodBegin(methExec, null, false); + _helper!.MethodBegin(methExec, null, false); // Force some or all global values to be evaluated at start of query - EvaluateGlobalValues(_qil.GlobalVariableList); + EvaluateGlobalValues(_qil!.GlobalVariableList); EvaluateGlobalValues(_qil.GlobalParameterList); // Root(runtime); @@ -288,14 +291,14 @@ private void CreateHelperFunctions() Label lblClone; // public static XPathNavigator SyncToNavigator(XPathNavigator, XPathNavigator); - meth = _module.DefineMethod( + meth = _module!.DefineMethod( "SyncToNavigator", typeof(XPathNavigator), new Type[] { typeof(XPathNavigator), typeof(XPathNavigator) }, - new string[] { null, null }, + new string?[] { null, null }, XmlILMethodAttributes.NonUser | XmlILMethodAttributes.Raw); - _helper.MethodBegin(meth, null, false); + _helper!.MethodBegin(meth, null, false); // if (navigatorThis != null && navigatorThis.MoveTo(navigatorThat)) // return navigatorThis; @@ -323,18 +326,18 @@ private void CreateHelperFunctions() /// private void EvaluateGlobalValues(IList iterList) { - MethodInfo methInfo; + MethodInfo? methInfo; foreach (QilIterator ndIter in iterList) { // Evaluate global if generating debug code, or if global might have side effects - if (_qil.IsDebug || OptimizerPatterns.Read(ndIter).MatchesPattern(OptimizerPatternName.MaybeSideEffects)) + if (_qil!.IsDebug || OptimizerPatterns.Read(ndIter).MatchesPattern(OptimizerPatternName.MaybeSideEffects)) { // Get MethodInfo that evaluates the global value and discard its return value methInfo = XmlILAnnotation.Write(ndIter).FunctionBinding; Debug.Assert(methInfo != null, "MethodInfo for global value should have been created previously."); - _helper.LoadQueryRuntime(); + _helper!.LoadQueryRuntime(); _helper.Call(methInfo); _helper.Emit(OpCodes.Pop); } @@ -352,12 +355,12 @@ public void CreateTypeInitializer(XmlQueryStaticData staticData) ConstructorInfo cctor; staticData.GetObjectData(out data, out ebTypes); - fldInitData = _module.DefineInitializedData("__" + XmlQueryStaticData.DataFieldName, data); + fldInitData = _module!.DefineInitializedData("__" + XmlQueryStaticData.DataFieldName, data); fldData = _module.DefineField(XmlQueryStaticData.DataFieldName, typeof(object)); fldTypes = _module.DefineField(XmlQueryStaticData.TypesFieldName, typeof(Type[])); cctor = _module.DefineTypeInitializer(); - _helper.MethodBegin(cctor, null, false); + _helper!.MethodBegin(cctor, null, false); // s_data = new byte[s_initData.Length] { s_initData }; _helper.LoadInteger(data.Length); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlNodeKindFlags.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlNodeKindFlags.cs index 4101c0fb4459..882264228e95 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlNodeKindFlags.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlNodeKindFlags.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. +#nullable enable using System; namespace System.Xml.Xsl diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs index 06b36f107164..66363cf8683d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs @@ -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. +#nullable enable using System; using System.Xml; using System.Xml.Schema; @@ -38,7 +39,7 @@ public static XmlQualifiedNameTest Wildcard /// /// Constructor /// - private XmlQualifiedNameTest(string name, string ns, bool exclude) : base(name, ns) + private XmlQualifiedNameTest(string? name, string? ns, bool exclude) : base(name, ns) { _exclude = exclude; } @@ -46,7 +47,7 @@ private XmlQualifiedNameTest(string name, string ns, bool exclude) : base(name, /// /// Construct new from name and namespace. Returns singleton Wildcard in case full wildcard /// - public static XmlQualifiedNameTest New(string name, string ns) + public static XmlQualifiedNameTest New(string? name, string? ns) { if (ns == null && name == null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryCardinality.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryCardinality.cs index 6ab2d01e8d21..012b94fa9d42 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryCardinality.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryCardinality.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. +#nullable enable using System.Diagnostics; using System.IO; @@ -119,12 +120,13 @@ public bool Equals(XmlQueryCardinality other) /// /// True if "other" is an XmlQueryCardinality, and this type is the exact same static type. /// - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is XmlQueryCardinality) { return Equals((XmlQueryCardinality)other); } + return false; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryType.cs index 26b2be064e54..3005c4d7bb8c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryType.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -167,7 +168,7 @@ public bool NeverSubtypeOf(XmlQueryType baseType) /// /// Strongly-typed Equals that returns true if this type and "that" type are equivalent. /// - public bool Equals(XmlQueryType that) + public bool Equals(XmlQueryType? that) { if (that == null) return false; @@ -227,10 +228,10 @@ public bool Equals(XmlQueryType that) /// /// Overload == operator to call Equals rather than do reference equality. /// - public static bool operator ==(XmlQueryType left, XmlQueryType right) + public static bool operator ==(XmlQueryType? left, XmlQueryType? right) { - if ((object)left == null) - return ((object)right == null); + if ((object?)left == null) + return ((object?)right == null); return left.Equals(right); } @@ -238,10 +239,10 @@ public bool Equals(XmlQueryType that) /// /// Overload != operator to call Equals rather than do reference inequality. /// - public static bool operator !=(XmlQueryType left, XmlQueryType right) + public static bool operator !=(XmlQueryType? left, XmlQueryType? right) { - if ((object)left == null) - return ((object)right != null); + if ((object?)left == null) + return ((object?)right != null); return !left.Equals(right); } @@ -318,9 +319,9 @@ public bool IsNumeric /// /// True if "obj" is an XmlQueryType, and this type is the exact same static type. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { - XmlQueryType that = obj as XmlQueryType; + XmlQueryType? that = obj as XmlQueryType; if (that == null) return false; @@ -336,7 +337,7 @@ public override int GetHashCode() if (_hashCode == 0) { int hash; - XmlSchemaType schemaType; + XmlSchemaType? schemaType; hash = (int)TypeCode; schemaType = SchemaType; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryTypeFactory.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryTypeFactory.cs index a5963a7d7cf4..b844184dd7f4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryTypeFactory.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQueryTypeFactory.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -41,7 +42,7 @@ public static XmlQueryType Type(XmlTypeCode code, bool isStrict) /// the atomic value type public static XmlQueryType Type(XmlSchemaSimpleType schemaType, bool isStrict) { - if (schemaType.Datatype.Variety == XmlSchemaDatatypeVariety.Atomic) + if (schemaType.Datatype!.Variety == XmlSchemaDatatypeVariety.Atomic) { // We must special-case xs:anySimpleType because it is broken in Xsd and is sometimes treated as // an atomic value and sometimes as a list value. In XQuery, it always maps to xdt:anyAtomicType*. @@ -53,16 +54,16 @@ public static XmlQueryType Type(XmlSchemaSimpleType schemaType, bool isStrict) // Skip restrictions. It is safe to do that because this is a list or union, so it's not a build in type while (schemaType.DerivedBy == XmlSchemaDerivationMethod.Restriction) - schemaType = (XmlSchemaSimpleType)schemaType.BaseXmlSchemaType; + schemaType = (XmlSchemaSimpleType)schemaType.BaseXmlSchemaType!; // Convert Xsd list if (schemaType.DerivedBy == XmlSchemaDerivationMethod.List) - return PrimeProduct(Type(((XmlSchemaSimpleTypeList)schemaType.Content).BaseItemType, isStrict), XmlQueryCardinality.ZeroOrMore); + return PrimeProduct(Type(((XmlSchemaSimpleTypeList)schemaType.Content!).BaseItemType!, isStrict), XmlQueryCardinality.ZeroOrMore); // Convert Xsd union Debug.Assert(schemaType.DerivedBy == XmlSchemaDerivationMethod.Union); - XmlSchemaSimpleType[] baseMemberTypes = ((XmlSchemaSimpleTypeUnion)schemaType.Content).BaseMemberTypes; - XmlQueryType[] queryMemberTypes = new XmlQueryType[baseMemberTypes.Length]; + XmlSchemaSimpleType[] baseMemberTypes = ((XmlSchemaSimpleTypeUnion)schemaType.Content!).BaseMemberTypes!; + XmlQueryType[] queryMemberTypes = new XmlQueryType[baseMemberTypes!.Length]; for (int i = 0; i < baseMemberTypes.Length; i++) queryMemberTypes[i] = Type(baseMemberTypes[i], isStrict); @@ -348,7 +349,7 @@ static ItemType() { #if DEBUG Array arrEnum = Enum.GetValues(typeof(XmlTypeCode)); - Debug.Assert((XmlTypeCode)arrEnum.GetValue(arrEnum.Length - 1) == XmlTypeCode.DayTimeDuration, + Debug.Assert((XmlTypeCode)arrEnum.GetValue(arrEnum.Length - 1)! == XmlTypeCode.DayTimeDuration, "DayTimeDuration is no longer the last item in XmlTypeCode. This code expects it to be."); #endif @@ -434,7 +435,7 @@ public static XmlQueryType Create(XmlTypeCode code, bool isStrict) /// public static XmlQueryType Create(XmlSchemaSimpleType schemaType, bool isStrict) { - Debug.Assert(schemaType.Datatype.Variety == XmlSchemaDatatypeVariety.Atomic, "List or Union Xsd types should have been handled by caller."); + Debug.Assert(schemaType.Datatype!.Variety == XmlSchemaDatatypeVariety.Atomic, "List or Union Xsd types should have been handled by caller."); XmlTypeCode code = schemaType.Datatype.TypeCode; // If schemaType is a built-in type, @@ -510,7 +511,7 @@ private ItemType(XmlTypeCode code, XmlQualifiedNameTest nameTest, XmlSchemaType _isStrict = isStrict; _isNotRtf = isNotRtf; - Debug.Assert(!IsAtomicValue || schemaType.Datatype.Variety == XmlSchemaDatatypeVariety.Atomic); + Debug.Assert(!IsAtomicValue || schemaType.Datatype!.Variety == XmlSchemaDatatypeVariety.Atomic); _nodeKinds = code switch { @@ -690,7 +691,7 @@ private sealed class ChoiceType : XmlQueryType public static readonly XmlQueryType None = new ChoiceType(new List()); private readonly XmlTypeCode _code; - private readonly XmlSchemaType _schemaType; + private readonly XmlSchemaType? _schemaType; private readonly XmlNodeKindFlags _nodeKinds; private readonly List _members; @@ -853,7 +854,14 @@ public override XmlQualifiedNameTest NameTest /// public override XmlSchemaType SchemaType { - get { return _schemaType; } + get + { + // TODO-NULLABLE: Per documentation of base class we should not be returning null here + // Currently we return null for some type codes (i.e. Item, Node) + // but doc says we should be returning AnyType + // which presumably means XmlSchemaComplexType.AnyType + return _schemaType!; + } } /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XslException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XslException.cs index 146f6ce06dee..a239d96c103d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XslException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XslException.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. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Resources; @@ -12,7 +13,7 @@ namespace System.Xml.Xsl { internal class XslTransformException : XsltException { - public XslTransformException(Exception inner, string res, params string[] args) + public XslTransformException(Exception? inner, string res, params string?[]? args) : base(CreateMessage(res, args), inner) { } @@ -25,13 +26,13 @@ public XslTransformException(string message) : base(CreateMessage(message, null), null) { } - internal XslTransformException(string res, params string[] args) + internal XslTransformException(string res, params string?[]? args) : this(null, res, args) { } - internal static string CreateMessage(string res, params string[] args) + internal static string CreateMessage(string res, params string?[]? args) { - string message = null; + string? message = null; try { @@ -66,6 +67,7 @@ internal static string CreateMessage(string res, params string[] args) } sb.Append(')'); } + return sb.ToString(); } @@ -76,7 +78,7 @@ internal virtual string FormatDetailedMessage() public override string ToString() { - string result = this.GetType().FullName; + string result = this.GetType().FullName!; string info = FormatDetailedMessage(); if (info != null && info.Length > 0) { @@ -97,13 +99,13 @@ public override string ToString() [Serializable] internal class XslLoadException : XslTransformException { - private ISourceLineInfo _lineInfo; + private ISourceLineInfo? _lineInfo; - internal XslLoadException(string res, params string[] args) + internal XslLoadException(string res, params string?[]? args) : base(null, res, args) { } - internal XslLoadException(Exception inner, ISourceLineInfo lineInfo) + internal XslLoadException(Exception? inner, ISourceLineInfo? lineInfo) : base(inner, SR.Xslt_CompileError2, null) { SetSourceLineInfo(lineInfo); @@ -112,15 +114,15 @@ internal XslLoadException(Exception inner, ISourceLineInfo lineInfo) internal XslLoadException(SerializationInfo info, StreamingContext context) : base(info, context) { - bool hasLineInfo = (bool)info.GetValue("hasLineInfo", typeof(bool)); + bool hasLineInfo = (bool)info.GetValue("hasLineInfo", typeof(bool))!; if (hasLineInfo) { - string uriString = (string)info.GetValue("Uri", typeof(string)); - int startLine = (int)info.GetValue("StartLine", typeof(int)); - int startPos = (int)info.GetValue("StartPos", typeof(int)); - int endLine = (int)info.GetValue("EndLine", typeof(int)); - int endPos = (int)info.GetValue("EndPos", typeof(int)); + string uriString = (string)info.GetValue("Uri", typeof(string))!; + int startLine = (int)info.GetValue("StartLine", typeof(int))!; + int startPos = (int)info.GetValue("StartPos", typeof(int))!; + int endLine = (int)info.GetValue("EndLine", typeof(int))!; + int endPos = (int)info.GetValue("EndPos", typeof(int))!; _lineInfo = new SourceLineInfo(uriString, startLine, startPos, endLine, endPos); } @@ -154,7 +156,7 @@ internal XslLoadException(CompilerError error) SetSourceLineInfo(new SourceLineInfo(error.FileName, errorLine, errorColumn, errorLine, errorColumn)); } - internal void SetSourceLineInfo(ISourceLineInfo lineInfo) + internal void SetSourceLineInfo(ISourceLineInfo? lineInfo) { Debug.Assert(lineInfo == null || lineInfo.Uri != null); _lineInfo = lineInfo; @@ -175,7 +177,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont } } - public override string SourceUri + public override string? SourceUri { get { return _lineInfo != null ? _lineInfo.Uri : null; } } @@ -190,11 +192,11 @@ public override int LinePosition get { return _lineInfo != null ? _lineInfo.Start.Pos : 0; } } - private static string AppendLineInfoMessage(string message, ISourceLineInfo lineInfo) + private static string AppendLineInfoMessage(string message, ISourceLineInfo? lineInfo) { if (lineInfo != null) { - string fileName = SourceLineInfo.GetFileName(lineInfo.Uri); + string fileName = SourceLineInfo.GetFileName(lineInfo.Uri!); string lineInfoMessage = CreateMessage(SR.Xml_ErrorFilePosition, fileName, lineInfo.Start.Line.ToString(CultureInfo.InvariantCulture), lineInfo.Start.Pos.ToString(CultureInfo.InvariantCulture)); if (lineInfoMessage != null && lineInfoMessage.Length > 0) { @@ -208,7 +210,7 @@ private static string AppendLineInfoMessage(string message, ISourceLineInfo line return message; } - internal static string CreateMessage(ISourceLineInfo lineInfo, string res, params string[] args) + internal static string CreateMessage(ISourceLineInfo? lineInfo, string res, params string?[]? args) { return AppendLineInfoMessage(CreateMessage(res, args), lineInfo); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs index e8e141b26291..dcf14189c205 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.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. +#nullable enable using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -41,14 +42,14 @@ internal class Compiler { public XsltSettings Settings; public bool IsDebug; - public string ScriptAssemblyPath; + public string? ScriptAssemblyPath; public int Version; // 0 - Auto; 1 - XSLT 1.0; 2 - XSLT 2.0 - public string inputTypeAnnotations; // null - "unspecified"; "preserve"; "strip" + public string? inputTypeAnnotations; // null - "unspecified"; "preserve"; "strip" public CompilerErrorCollection CompilerErrorColl; // Results of the compilation public int CurrentPrecedence; // Decreases by 1 with each import - public XslNode StartApplyTemplates; - public RootLevel Root; + public XslNode? StartApplyTemplates; + public RootLevel? Root; public Scripts Scripts; public Output Output = new Output(); public List ExternalPars = new List(); @@ -65,7 +66,7 @@ internal class Compiler private readonly Dictionary _moduleOrder = new Dictionary(); - public Compiler(XsltSettings settings, bool debug, string scriptAssemblyPath) + public Compiler(XsltSettings settings, bool debug, string? scriptAssemblyPath) { Debug.Assert(CompilerErrorColl == null, "Compiler cannot be reused"); @@ -77,7 +78,7 @@ public Compiler(XsltSettings settings, bool debug, string scriptAssemblyPath) Scripts = new Scripts(this); } - public CompilerErrorCollection Compile(object stylesheet, XmlResolver xmlResolver, out QilExpression qil) + public CompilerErrorCollection Compile(object stylesheet, XmlResolver? xmlResolver, out QilExpression qil) { Debug.Assert(stylesheet != null); Debug.Assert(Root == null, "Compiler cannot be reused"); @@ -106,9 +107,9 @@ public void AddModule(string baseUri) } } - public void ApplyNsAliases(ref string prefix, ref string nsUri) + public void ApplyNsAliases(ref string? prefix, ref string nsUri) { - NsAlias alias; + NsAlias? alias; if (NsAliases.TryGetValue(nsUri, out alias)) { nsUri = alias.ResultNsUri; @@ -117,9 +118,9 @@ public void ApplyNsAliases(ref string prefix, ref string nsUri) } // Returns true in case of redefinition - public bool SetNsAlias(string ssheetNsUri, string resultNsUri, string resultPrefix, int importPrecedence) + public bool SetNsAlias(string ssheetNsUri, string resultNsUri, string? resultPrefix, int importPrecedence) { - NsAlias oldNsAlias; + NsAlias? oldNsAlias; if (NsAliases.TryGetValue(ssheetNsUri, out oldNsAlias)) { // Namespace alias for this stylesheet namespace URI has already been defined @@ -149,7 +150,7 @@ private void MergeAttributeSets(Stylesheet sheet) { foreach (QilName attSetName in sheet.AttributeSets.Keys) { - AttributeSet attSet; + AttributeSet? attSet; if (!this.AttributeSets.TryGetValue(attSetName, out attSet)) { this.AttributeSets[attSetName] = sheet.AttributeSets[attSetName]; @@ -168,7 +169,7 @@ private void MergeGlobalVarPars(Stylesheet sheet) foreach (VarPar var in sheet.GlobalVarPars) { Debug.Assert(var.NodeType == XslNodeType.Variable || var.NodeType == XslNodeType.Param); - if (!AllGlobalVarPars.ContainsKey(var.Name)) + if (!AllGlobalVarPars.ContainsKey(var.Name!)) { if (var.NodeType == XslNodeType.Variable) { @@ -178,7 +179,7 @@ private void MergeGlobalVarPars(Stylesheet sheet) { ExternalPars.Add(var); } - AllGlobalVarPars[var.Name] = var; + AllGlobalVarPars[var.Name!] = var; } } sheet.GlobalVarPars = null; @@ -220,7 +221,7 @@ public bool ParseQName(string qname, out string prefix, out string localName, IE } } - public bool ParseNameTest(string nameTest, out string prefix, out string localName, IErrorHelper errorHelper) + public bool ParseNameTest(string nameTest, out string? prefix, out string? localName, IErrorHelper errorHelper) { Debug.Assert(nameTest != null); try @@ -313,22 +314,22 @@ public bool ExitForwardsCompatible(bool fwdCompat) return true; } - public CompilerError CreateError(ISourceLineInfo lineInfo, string res, params string[] args) + public CompilerError CreateError(ISourceLineInfo lineInfo, string res, params string?[]? args) { - AddModule(lineInfo.Uri); + AddModule(lineInfo.Uri!); return new CompilerError( - lineInfo.Uri, lineInfo.Start.Line, lineInfo.Start.Pos, /*errorNumber:*/string.Empty, + lineInfo.Uri!, lineInfo.Start.Line, lineInfo.Start.Pos, /*errorNumber:*/string.Empty, /*errorText:*/XslTransformException.CreateMessage(res, args) ); } - public void ReportError(ISourceLineInfo lineInfo, string res, params string[] args) + public void ReportError(ISourceLineInfo lineInfo, string res, params string?[]? args) { CompilerError error = CreateError(lineInfo, res, args); CompilerErrorColl.Add(error); } - public void ReportWarning(ISourceLineInfo lineInfo, string res, params string[] args) + public void ReportWarning(ISourceLineInfo lineInfo, string res, params string?[]? args) { int warningLevel = 1; if (0 <= Settings.WarningLevel && Settings.WarningLevel < warningLevel) @@ -371,9 +372,9 @@ public CompilerErrorComparer(Dictionary moduleOrder) _moduleOrder = moduleOrder; } - public int Compare(CompilerError x, CompilerError y) + public int Compare(CompilerError? x, CompilerError? y) { - if ((object)x == (object)y) + if ((object?)x == (object?)y) return 0; if (x == null) @@ -410,9 +411,9 @@ public int Compare(CompilerError x, CompilerError y) internal class Output { public XmlWriterSettings Settings; - public string Version; - public string Encoding; - public XmlQualifiedName Method; + public string? Version; + public string? Encoding; + public XmlQualifiedName? Method; // All the xsl:output elements occurring in a stylesheet are merged into a single effective xsl:output element. // We store the import precedence of each attribute value to catch redefinitions with the same import precedence. @@ -467,10 +468,10 @@ public DecimalFormatDecl(XmlQualifiedName name, string infinitySymbol, string na internal class NsAlias { public readonly string ResultNsUri; - public readonly string ResultPrefix; + public readonly string? ResultPrefix; public readonly int ImportPrecedence; - public NsAlias(string resultNsUri, string resultPrefix, int importPrecedence) + public NsAlias(string resultNsUri, string? resultPrefix, int importPrecedence) { this.ResultNsUri = resultNsUri; this.ResultPrefix = resultPrefix; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerError.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerError.cs index fa10fd9a2480..4a313c993844 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerError.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerError.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. +#nullable enable using System.Collections; namespace System.Xml.Xsl.Xslt diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerScopeManager.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerScopeManager.cs index 66ce38dd6830..315f81ad6399 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerScopeManager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/CompilerScopeManager.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Xslt { @@ -31,8 +33,9 @@ public struct ScopeRecord { public int scopeCount; public ScopeFlags flags; - public string ncName; // local-name for variable, prefix for namespace, null for extension or excluded namespace - public string nsUri; // namespace uri + public string? ncName; // local-name for variable, prefix for namespace, null for extension or excluded namespace + public string? nsUri; // namespace uri + [AllowNull] public V value; // value for variable, null for namespace // Exactly one of these three properties is true for every given record @@ -96,7 +99,7 @@ public void CheckEmpty() } // returns true if ns decls was added to scope - public bool EnterScope(NsDecl nsDecl) + public bool EnterScope(NsDecl? nsDecl) { _lastScopes++; @@ -142,7 +145,7 @@ private void AddRecord() _lastScopes = 0; } - private void AddRecord(ScopeFlags flag, string ncName, string uri, V value) + private void AddRecord(ScopeFlags flag, string? ncName, string? uri, [AllowNull] V value) { Debug.Assert(flag == (flag & ScopeFlags.ExclusiveFlags) && (flag & (flag - 1)) == 0 && flag != 0, "One exclusive flag"); Debug.Assert(uri != null || ncName == null, "null, null means exclude '#all'"); @@ -202,12 +205,12 @@ public void AddVariable(QilName varName, V value) // Since the prefix might be redefined in an inner scope, we search in descending order in [to, from] // If interval is empty (from < to), the function returns null. - private string LookupNamespace(string prefix, int from, int to) + private string? LookupNamespace(string prefix, int from, int to) { Debug.Assert(prefix != null); for (int record = from; to <= record; --record) { - string recPrefix, recNsUri; + string? recPrefix, recNsUri; ScopeFlags flags = GetName(ref _records[record], out recPrefix, out recNsUri); if ( (flags & ScopeFlags.NsDecl) != 0 && @@ -220,12 +223,12 @@ private string LookupNamespace(string prefix, int from, int to) return null; } - public string LookupNamespace(string prefix) + public string? LookupNamespace(string prefix) { return LookupNamespace(prefix, _lastRecord, 0); } - private static ScopeFlags GetName(ref ScopeRecord re, out string prefix, out string nsUri) + private static ScopeFlags GetName(ref ScopeRecord re, out string? prefix, out string? nsUri) { prefix = re.ncName; nsUri = re.nsUri; @@ -237,7 +240,7 @@ public void AddNsDeclaration(string prefix, string nsUri) AddRecord(ScopeFlags.NsDecl, prefix, nsUri, default(V)); } - public void AddExNamespace(string nsUri) + public void AddExNamespace(string? nsUri) { AddRecord(ScopeFlags.NsExcl, null, nsUri, default(V)); } @@ -248,7 +251,7 @@ public bool IsExNamespace(string nsUri) int exAll = 0; for (int record = _lastRecord; 0 <= record; record--) { - string recPrefix, recNsUri; + string? recPrefix, recNsUri; ScopeFlags flags = GetName(ref _records[record], out recPrefix, out recNsUri); if ((flags & ScopeFlags.NsExcl) != 0) { @@ -272,7 +275,7 @@ public bool IsExNamespace(string nsUri) bool undefined = false; for (int prev = record + 1; prev < exAll; prev++) { - string prevPrefix, prevNsUri; + string? prevPrefix, prevNsUri; ScopeFlags prevFlags = GetName(ref _records[prev], out prevPrefix, out prevNsUri); if ( (flags & ScopeFlags.NsDecl) != 0 && @@ -299,7 +302,7 @@ private int SearchVariable(string localName, string uri) Debug.Assert(localName != null); for (int record = _lastRecord; 0 <= record; --record) { - string recLocal, recNsUri; + string? recLocal, recNsUri; ScopeFlags flags = GetName(ref _records[record], out recLocal, out recNsUri); if ( (flags & ScopeFlags.Variable) != 0 && @@ -313,6 +316,7 @@ private int SearchVariable(string localName, string uri) return -1; } + [return: MaybeNull] public V LookupVariable(string localName, string uri) { int record = SearchVariable(localName, uri); @@ -359,7 +363,7 @@ internal System.Collections.Generic.IEnumerable GetActiveRecords() if (_records[currentRecord].IsNamespace) { // This is a namespace declaration - if (LookupNamespace(_records[currentRecord].ncName, _lastRecord, currentRecord + 1) != null) + if (LookupNamespace(_records[currentRecord].ncName!, _lastRecord, currentRecord + 1) != null) { continue; } @@ -394,7 +398,7 @@ public bool MoveNext() if (_scope._records[_currentRecord].IsNamespace) { // This is a namespace declaration - if (_scope.LookupNamespace(_scope._records[_currentRecord].ncName, _lastRecord, _currentRecord + 1) == null) + if (_scope.LookupNamespace(_scope._records[_currentRecord].ncName!, _lastRecord, _currentRecord + 1) == null) { // Its prefix has not been redefined later in [currentRecord + 1, lastRecord] return true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Focus.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Focus.cs index a36998b2bf9f..632349da5c31 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Focus.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Focus.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml.Xsl.XPath; @@ -34,7 +35,7 @@ internal struct SingletonFocus : IFocus { private readonly XPathQilFactory _f; private SingletonFocusType _focusType; - private QilIterator _current; + private QilIterator? _current; public SingletonFocus(XPathQilFactory f) { @@ -49,7 +50,7 @@ public void SetFocus(SingletonFocusType focusType) _focusType = focusType; } - public void SetFocus(QilIterator current) + public void SetFocus(QilIterator? current) { if (current != null) { @@ -98,7 +99,7 @@ public QilNode GetLast() internal struct FunctionFocus : IFocus { private bool _isSet; - private QilParameter _current, _position, _last; + private QilParameter? _current, _position, _last; public void StartFocus(IList args, XslFlags flags) { @@ -107,17 +108,17 @@ public void StartFocus(IList args, XslFlags flags) if ((flags & XslFlags.Current) != 0) { _current = (QilParameter)args[argNum++]; - Debug.Assert(_current.Name.NamespaceUri == XmlReservedNs.NsXslDebug && _current.Name.LocalName == "current"); + Debug.Assert(_current.Name!.NamespaceUri == XmlReservedNs.NsXslDebug && _current.Name.LocalName == "current"); } if ((flags & XslFlags.Position) != 0) { _position = (QilParameter)args[argNum++]; - Debug.Assert(_position.Name.NamespaceUri == XmlReservedNs.NsXslDebug && _position.Name.LocalName == "position"); + Debug.Assert(_position.Name!.NamespaceUri == XmlReservedNs.NsXslDebug && _position.Name.LocalName == "position"); } if ((flags & XslFlags.Last) != 0) { _last = (QilParameter)args[argNum++]; - Debug.Assert(_last.Name.NamespaceUri == XmlReservedNs.NsXslDebug && _last.Name.LocalName == "last"); + Debug.Assert(_last.Name!.NamespaceUri == XmlReservedNs.NsXslDebug && _last.Name.LocalName == "last"); } _isSet = true; } @@ -154,7 +155,7 @@ public QilNode GetLast() internal struct LoopFocus : IFocus { private readonly XPathQilFactory _f; - private QilIterator _current, _cached, _last; + private QilIterator? _current, _cached, _last; public LoopFocus(XPathQilFactory f) { @@ -173,14 +174,14 @@ public bool IsFocusSet get { return _current != null; } } - public QilNode GetCurrent() + public QilNode? GetCurrent() { return _current; } public QilNode GetPosition() { - return _f.XsltConvert(_f.PositionOf(_current), T.DoubleX); + return _f.XsltConvert(_f.PositionOf(_current!), T.DoubleX); } public QilNode GetLast() @@ -197,19 +198,19 @@ public void EnsureCache() { if (_cached == null) { - _cached = _f.Let(_current.Binding); + _cached = _f.Let(_current!.Binding!); _current.Binding = _cached; } } - public void Sort(QilNode sortKeys) + public void Sort(QilNode? sortKeys) { if (sortKeys != null) { // If sorting is required, cache the input node-set to support last() within sort key expressions EnsureCache(); // The rest of the loop content must be compiled in the context of already sorted node-set - _current = _f.For(_f.Sort(_current, sortKeys)); + _current = _f.For(_f.Sort(_current!, sortKeys)); } } @@ -220,9 +221,10 @@ public QilLoop ConstructLoop(QilNode body) { // last() encountered either in the sort keys or in the body of the current loop EnsureCache(); - _last.Binding = _f.XsltConvert(_f.Length(_cached), T.DoubleX); + _last.Binding = _f.XsltConvert(_f.Length(_cached!), T.DoubleX); } - result = _f.BaseFactory.Loop(_current, body); + + result = _f.BaseFactory.Loop(_current!, body); if (_last != null) { result = _f.BaseFactory.Loop(_last, result); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/IErrorHelper.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/IErrorHelper.cs index db716fccb056..4565dfa83b00 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/IErrorHelper.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/IErrorHelper.cs @@ -1,12 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Xml.Xsl { internal interface IErrorHelper { - void ReportError(string res, params string[] args); + void ReportError(string res, params string?[]? args); - void ReportWarning(string res, params string[] args); + void ReportWarning(string res, params string?[]? args); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/InvokeGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/InvokeGenerator.cs index f844f36e5fe9..d7d4c0234dd1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/InvokeGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/InvokeGenerator.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. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Xml.Xsl.Qil; @@ -25,8 +26,8 @@ internal class InvokeGenerator : QilCloneVisitor private readonly bool _debug; private readonly Stack _iterStack; - private QilList _formalArgs; - private QilList _invokeArgs; + private QilList? _formalArgs; + private QilList? _invokeArgs; private int _curArg; // this.Clone() depends on this value private readonly XsltQilFactory _fac; @@ -49,14 +50,14 @@ public QilNode GenerateInvoke(QilFunction func, IList actualArgs) { // Find actual value for a given formal arg QilParameter formalArg = (QilParameter)_formalArgs[_curArg]; - QilNode invokeArg = FindActualArg(formalArg, actualArgs); + QilNode? invokeArg = FindActualArg(formalArg, actualArgs); // If actual value was not specified, use the default value and copy its debug comment if (invokeArg == null) { if (_debug) { - if (formalArg.Name.NamespaceUri == XmlReservedNs.NsXslDebug) + if (formalArg.Name!.NamespaceUri == XmlReservedNs.NsXslDebug) { Debug.Assert(formalArg.Name.LocalName == "namespaces", "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs()"); Debug.Assert(formalArg.DefaultValue != null, "PrecompileProtoTemplatesHeaders() set it"); @@ -69,13 +70,13 @@ public QilNode GenerateInvoke(QilFunction func, IList actualArgs) } else { - Debug.Assert(formalArg.Name.NamespaceUri != XmlReservedNs.NsXslDebug, "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs(). We don't have $namespaces in !debug."); - invokeArg = Clone(formalArg.DefaultValue); + Debug.Assert(formalArg.Name!.NamespaceUri != XmlReservedNs.NsXslDebug, "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs(). We don't have $namespaces in !debug."); + invokeArg = Clone(formalArg.DefaultValue!); } } - XmlQueryType formalType = formalArg.XmlType; - XmlQueryType invokeType = invokeArg.XmlType; + XmlQueryType formalType = formalArg.XmlType!; + XmlQueryType invokeType = invokeArg.XmlType!; // Possible arg types: anyType, node-set, string, boolean, and number _fac.CheckXsltType(formalArg); @@ -99,13 +100,13 @@ public QilNode GenerateInvoke(QilFunction func, IList actualArgs) return invoke; } - private QilNode FindActualArg(QilParameter formalArg, IList actualArgs) + private QilNode? FindActualArg(QilParameter formalArg, IList actualArgs) { - QilName argName = formalArg.Name; + QilName? argName = formalArg.Name; Debug.Assert(argName != null); foreach (XslNode actualArg in actualArgs) { - if (actualArg.Name.Equals(argName)) + if (actualArg.Name!.Equals(argName)) { return ((VarPar)actualArg).Value; } @@ -117,7 +118,7 @@ private QilNode FindActualArg(QilParameter formalArg, IList actualArgs) protected override QilNode VisitReference(QilNode n) { - QilNode replacement = FindClonedReference(n); + QilNode? replacement = FindClonedReference(n); // If the reference is internal for the subtree being cloned, return it as is if (replacement != null) @@ -130,8 +131,8 @@ protected override QilNode VisitReference(QilNode n) // xsl:param's) must be taken care of. for (int prevArg = 0; prevArg < _curArg; prevArg++) { - Debug.Assert(_formalArgs[prevArg] != null, "formalArg must be in the list"); - Debug.Assert(_invokeArgs[prevArg] != null, "This arg should be compiled already"); + Debug.Assert(_formalArgs![prevArg] != null, "formalArg must be in the list"); + Debug.Assert(_invokeArgs![prevArg] != null, "This arg should be compiled already"); // Is this a reference to prevArg? if (n == _formalArgs[prevArg]) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs index 70243675da70..81cd01cc051c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/KeyMatchBuilder.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. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -10,6 +11,7 @@ using MS.Internal.Xml; using System.Xml.Xsl.XPath; using System.Xml.Xsl.Qil; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Xslt { @@ -33,7 +35,8 @@ public override void StartBuild() _depth++; } - public override QilNode EndBuild(QilNode result) + [return: NotNullIfNotNull("result")] + public override QilNode? EndBuild(QilNode? result) { _depth--; Debug.Assert(0 <= _depth && _depth <= 1, "this shouldn't happen"); @@ -63,7 +66,7 @@ public virtual IXPathBuilder GetPredicateBuilder(QilNode ctx) internal class PathConvertor : QilReplaceVisitor { private new readonly XPathQilFactory f; - private QilNode _fixup; + private QilNode? _fixup; public PathConvertor(XPathQilFactory f) : base(f.BaseFactory) { this.f = f; @@ -96,7 +99,7 @@ protected override QilNode Visit(QilNode n) // Filter($j= ... Filter($i = Content(fixup), ...)) -> Filter($j= ... Filter($i = Loop($j = DesendentOrSelf(Root(fixup)), Content($j), ...))) protected override QilNode VisitLoop(QilLoop n) { - if (n.Variable.Binding.NodeType == QilNodeType.Root || n.Variable.Binding.NodeType == QilNodeType.Deref) + if (n.Variable.Binding!.NodeType == QilNodeType.Root || n.Variable.Binding.NodeType == QilNodeType.Deref) { // This is absolute path already. We shouldn't touch it return n; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Keywords.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Keywords.cs index 7574183e0ca1..9bcc76bda2f2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Keywords.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Keywords.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. +#nullable enable using System.Xml; namespace System.Xml.Xsl.Xslt diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/MatcherBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/MatcherBuilder.cs index 6d99510a7440..ca2cde344eb7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/MatcherBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/MatcherBuilder.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.Xsl.Qil; using System.Xml.Xsl.XPath; @@ -92,16 +94,16 @@ internal class TemplateMatch private readonly Template _template; private readonly double _priority; private XmlNodeKindFlags _nodeKind; - private QilName _qname; + private QilName? _qname; private readonly QilIterator _iterator; - private QilNode _condition; // null means f.True() + private QilNode? _condition; // null means f.True() public XmlNodeKindFlags NodeKind { get { return _nodeKind; } } - public QilName QName + public QilName? QName { get { return _qname; } } @@ -111,12 +113,12 @@ public QilIterator Iterator get { return _iterator; } } - public QilNode Condition + public QilNode? Condition { get { return _condition; } } - public QilFunction TemplateFunction + public QilFunction? TemplateFunction { get { return _template.Function; } } @@ -156,7 +158,7 @@ private void NipOffTypeNameCheck() { QilBinary[] leftPath = new QilBinary[4]; // Circular buffer for last 4 And nodes int idx = -1; // Index of last element in leftPath - QilNode node = _condition; // Walker through left path of the tree + QilNode node = _condition!; // Walker through left path of the tree _nodeKind = XmlNodeKindFlags.None; _qname = null; @@ -178,7 +180,7 @@ private void NipOffTypeNameCheck() return; } - XmlNodeKindFlags nodeKinds = isType.Right.XmlType.NodeKinds; + XmlNodeKindFlags nodeKinds = isType.Right.XmlType!.NodeKinds; if (!Bits.ExactlyOne((uint)nodeKinds)) { return; @@ -200,7 +202,7 @@ private void NipOffTypeNameCheck() { // Recognized pattern B x = lastAnd; - _qname = (QilName)((QilLiteral)eq.Right).Value; + _qname = (QilName?)((QilLiteral)eq.Right).Value; idx--; } } @@ -230,10 +232,10 @@ internal class TemplateMatchComparer : IComparer // * x's priority is equal to y's priority, and x occurs later in the stylesheet than y. // Order of TemplateMatch'es from the same xsl:template/@match attribute does not matter. - public int Compare(TemplateMatch x, TemplateMatch y) + public int Compare(TemplateMatch? x, TemplateMatch? y) { - Debug.Assert(!double.IsNaN(x._priority)); - Debug.Assert(!double.IsNaN(y._priority)); + Debug.Assert(!double.IsNaN(x!._priority)); + Debug.Assert(!double.IsNaN(y!._priority)); return ( x._priority > y._priority ? 1 : x._priority < y._priority ? -1 : @@ -272,8 +274,8 @@ public void Clear() public void Add(Pattern pattern) { - QilName qname = pattern.Match.QName; - List list; + QilName? qname = pattern.Match.QName; + List? list; if (qname == null) { @@ -361,7 +363,7 @@ private void CollectPatternsInternal(Stylesheet sheet, QilName mode) CollectPatternsInternal(import, mode); } - List matchesForMode; + List? matchesForMode; if (sheet.TemplateMatches.TryGetValue(mode, out matchesForMode)) { AddPatterns(matchesForMode); @@ -380,7 +382,7 @@ public void CollectPatterns(StylesheetLevel sheet, QilName mode) private QilNode MatchPattern(QilIterator it, TemplateMatch match) { - QilNode cond = match.Condition; + QilNode? cond = match.Condition; if (cond == null) { return _f.True(); @@ -515,7 +517,7 @@ public QilNode BuildMatcher(QilIterator it, IList actualArgs, QilNode o { foreach (TemplateMatch match in list) { - branches[++priority] = _invkGen.GenerateInvoke(match.TemplateFunction, actualArgs); + branches[++priority] = _invkGen.GenerateInvoke(match.TemplateFunction!, actualArgs); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/OutputScopeManager.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/OutputScopeManager.cs index 3672878e2e34..9dde09dbc401 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/OutputScopeManager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/OutputScopeManager.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable using System; using System.Diagnostics; using System.Xml; using System.Collections; +#nullable enable namespace System.Xml.Xsl.Xslt { internal class OutputScopeManager @@ -13,8 +15,8 @@ internal class OutputScopeManager public struct ScopeReord { public int scopeCount; - public string prefix; - public string nsUri; + public string? prefix; + public string? nsUri; } private ScopeReord[] _records = new ScopeReord[32]; private int _lastRecord; @@ -63,7 +65,7 @@ public void AddNamespace(string prefix, string uri) AddRecord(prefix, uri); } - private void AddRecord(string prefix, string uri) + private void AddRecord(string? prefix, string? uri) { _records[_lastRecord].scopeCount = _lastScopes; _lastRecord++; @@ -117,7 +119,7 @@ public void InvalidateAllPrefixes() public void InvalidateNonDefaultPrefixes() { - string defaultNs = LookupNamespace(string.Empty); + string? defaultNs = LookupNamespace(string.Empty); if (defaultNs == null) { // We don't know default NS anyway. InvalidateAllPrefixes(); @@ -125,18 +127,19 @@ public void InvalidateNonDefaultPrefixes() else { if ( - _records[_lastRecord].prefix.Length == 0 && + _records[_lastRecord].prefix!.Length == 0 && _records[_lastRecord - 1].prefix == null ) { return; // Averything was already done } + AddRecord(null, null); AddRecord(string.Empty, defaultNs); } } - public string LookupNamespace(string prefix) + public string? LookupNamespace(string prefix) { Debug.Assert(prefix != null); for ( @@ -151,6 +154,7 @@ public string LookupNamespace(string prefix) return _records[record].nsUri; } } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs index bafb3f8cf059..a799185c1587 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs @@ -5,10 +5,12 @@ // http://www.w3.org/TR/xslt20/ //------------------------------------------------------------------------------ +#nullable enable using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text; using System.Xml.Xsl.Qil; @@ -24,7 +26,7 @@ namespace System.Xml.Xsl.Xslt internal class ReferenceReplacer : QilReplaceVisitor { - private QilReference _lookFor, _replaceBy; + private QilReference? _lookFor, _replaceBy; public ReferenceReplacer(QilFactory f) : base(f) { @@ -40,7 +42,7 @@ public QilNode Replace(QilNode expr, QilReference lookFor, QilReference replaceB protected override QilNode VisitReference(QilNode n) { - return (n == _lookFor) ? _replaceBy : n; + return (n == _lookFor) ? _replaceBy! : n; } } @@ -56,23 +58,23 @@ internal partial class QilGenerator : IErrorHelper private readonly XPathPatternBuilder _ptrnBuilder; private readonly XPathPatternParser _ptrnParser; private readonly ReferenceReplacer _refReplacer; - private KeyMatchBuilder _keyMatchBuilder; + private KeyMatchBuilder? _keyMatchBuilder; private readonly InvokeGenerator _invkGen; private readonly MatcherBuilder _matcherBuilder; private readonly QilStrConcatenator _strConcat; private readonly VariableHelper _varHelper; - private Compiler _compiler; - private QilList _functions; - private QilFunction _generalKey; + private Compiler _compiler = null!; + private QilList _functions = null!; + private QilFunction? _generalKey; private bool _formatNumberDynamicUsed; - private QilList _extPars; - private QilList _gloVars; - private QilList _nsVars; + private QilList _extPars = null!; + private QilList _gloVars = null!; + private QilList _nsVars = null!; private readonly XmlQueryType _elementOrDocumentType; private readonly XmlQueryType _textOrAttributeType; - private XslNode _lastScope; + private XslNode? _lastScope; private XslVersion _xslVersion; private readonly QilName _nameCurrent; @@ -155,7 +157,7 @@ private QilExpression Compile(Compiler compiler) try { CompileKeys(); - CompileAndSortMatches(compiler.Root.Imports[0]); + CompileAndSortMatches(compiler.Root!.Imports[0]); PrecompileProtoTemplatesHeaders(); CompileGlobalVariables(); @@ -167,7 +169,7 @@ private QilExpression Compile(Compiler compiler) } catch (XslLoadException e) { - e.SetSourceLineInfo(_lastScope.SourceLine); + e.SetSourceLineInfo(_lastScope!.SourceLine); throw; } catch (Exception e) @@ -176,18 +178,18 @@ private QilExpression Compile(Compiler compiler) { throw; } - throw new XslLoadException(e, _lastScope.SourceLine); + throw new XslLoadException(e, _lastScope!.SourceLine); } CompileInitializationCode(); - QilNode root = CompileRootExpression(compiler.StartApplyTemplates); + QilNode root = CompileRootExpression(compiler.StartApplyTemplates!); // Clean default values which we calculate in caller context foreach (ProtoTemplate tmpl in compiler.AllTemplates) { - foreach (QilParameter par in tmpl.Function.Arguments) + foreach (QilParameter par in tmpl.Function!.Arguments) { - if (!IsDebug || par.Name.Equals(_nameNamespaces)) + if (!IsDebug || par.Name!.Equals(_nameNamespaces)) { par.DefaultValue = null; } @@ -195,9 +197,9 @@ private QilExpression Compile(Compiler compiler) } // Create list of all early bound objects - Dictionary scriptClasses = compiler.Scripts.ScriptClasses; + Dictionary scriptClasses = compiler.Scripts.ScriptClasses; List ebTypes = new List(scriptClasses.Count); - foreach (KeyValuePair pair in scriptClasses) + foreach (KeyValuePair pair in scriptClasses) { if (pair.Value != null) { @@ -225,7 +227,7 @@ private QilNode InvokeOnCurrentNodeChanged() { Debug.Assert(IsDebug && _curLoop.IsFocusSet); QilIterator i; - return _f.Loop(i = _f.Let(_f.InvokeOnCurrentNodeChanged(_curLoop.GetCurrent())), _f.Sequence()); + return _f.Loop(i = _f.Let(_f.InvokeOnCurrentNodeChanged(_curLoop.GetCurrent()!)), _f.Sequence()); } [Conditional("DEBUG")] @@ -289,13 +291,13 @@ private QilNode CompileRootExpression(XslNode applyTmpls) // Compile start apply-templates call CheckSingletonFocus(); _singlFocus.SetFocus(SingletonFocusType.InitialContextNode); - QilNode result = GenerateApply(_compiler.Root, applyTmpls); + QilNode result = GenerateApply(_compiler.Root!, applyTmpls); _singlFocus.SetFocus(null); return _f.DocumentCtor(result); } - private QilList EnterScope(XslNode node) + private QilList? EnterScope(XslNode node) { // This is the only place where lastScope is changed _lastScope = node; @@ -312,14 +314,14 @@ private void ExitScope() _scope.ExitScope(); } - private QilList BuildDebuggerNamespaces() + private QilList? BuildDebuggerNamespaces() { if (IsDebug) { QilList nsDecls = _f.BaseFactory.Sequence(); foreach (ScopeRecord rec in _scope) { - nsDecls.Add(_f.NamespaceDecl(_f.String(rec.ncName), _f.String(rec.nsUri))); + nsDecls.Add(_f.NamespaceDecl(_f.String(rec.ncName!), _f.String(rec.nsUri!))); } return nsDecls; } @@ -354,7 +356,7 @@ private QilNode GetCurrentNode() { if (_curLoop.IsFocusSet) { - return _curLoop.GetCurrent(); + return _curLoop.GetCurrent()!; } else if (_funcFocus.IsFocusSet) { @@ -433,7 +435,7 @@ private QilIterator GetNsVar(QilList nsList) // All global vars at this point are nsList like one we are looking now. foreach (QilIterator var in _nsVars) { - Debug.Assert(var.XmlType.IsSubtypeOf(T.NamespaceS)); + Debug.Assert(var.XmlType!.IsSubtypeOf(T.NamespaceS)); Debug.Assert(var.Binding is QilList); QilList varList = (QilList)var.Binding; if (varList.Count != nsList.Count) @@ -469,9 +471,9 @@ private QilIterator GetNsVar(QilList nsList) private void PrecompileProtoTemplatesHeaders() { // All global variables should be in scoupe here. - List paramWithCalls = null; - Dictionary paramToTemplate = null; - Dictionary paramToFunction = null; + List? paramWithCalls = null; + Dictionary? paramToTemplate = null; + Dictionary? paramToFunction = null; foreach (ProtoTemplate tmpl in _compiler.AllTemplates) { @@ -480,7 +482,7 @@ private void PrecompileProtoTemplatesHeaders() QilList args = _f.FormalParameterList(); XslFlags flags = !IsDebug ? tmpl.Flags : XslFlags.FullFocus; - QilList nsList = EnterScope(tmpl); + QilList? nsList = EnterScope(tmpl); if ((flags & XslFlags.Current) != 0) { args.Add(CreateXslParam(CloneName(_nameCurrent), T.NodeNotRtf)); @@ -502,7 +504,7 @@ private void PrecompileProtoTemplatesHeaders() args.Add(ns); } - Template template = tmpl as Template; + Template? template = tmpl as Template; if (template != null) { Debug.Assert(tmpl.NodeType == XslNodeType.Template); @@ -522,7 +524,7 @@ private void PrecompileProtoTemplatesHeaders() { VarPar xslPar = (VarPar)node; EnterScope(xslPar); - if (_scope.IsLocalVariable(xslPar.Name.LocalName, xslPar.Name.NamespaceUri)) + if (_scope.IsLocalVariable(xslPar.Name!.LocalName, xslPar.Name.NamespaceUri)) { ReportError(/*[XT0580]*/SR.Xslt_DupLocalVariable, xslPar.Name.QualifiedName); } @@ -549,10 +551,10 @@ private void PrecompileProtoTemplatesHeaders() QilList paramActual = _f.ActualParameterList(); for (int j = 0; j < args.Count; j++) { - QilParameter formal = _f.Parameter(args[j].XmlType); + QilParameter formal = _f.Parameter(args[j].XmlType!); { - formal.DebugName = ((QilParameter)args[j]).DebugName; - formal.Name = CloneName(((QilParameter)args[j]).Name); + formal.DebugName = ((QilParameter)args[j]).DebugName!; + formal.Name = CloneName(((QilParameter)args[j]).Name!); SetLineInfo(formal, args[j].SourceLine); } paramFormal.Add(formal); @@ -576,8 +578,8 @@ private void PrecompileProtoTemplatesHeaders() paramToFunction = new Dictionary(); } paramWithCalls.Add(xslPar); - paramToTemplate.Add(xslPar, template); - paramToFunction.Add(xslPar, paramFunc); + paramToTemplate!.Add(xslPar, template); + paramToFunction!.Add(xslPar, paramFunc); } } SetLineInfo(param, xslPar.SourceLine); @@ -610,15 +612,15 @@ private void PrecompileProtoTemplatesHeaders() Debug.Assert(!IsDebug, "In debug mode we don't generate parumWithCalls functions. Otherwise focus flags should be adjusted"); foreach (VarPar par in paramWithCalls) { - Template tmpl = paramToTemplate[par]; - QilFunction func = paramToFunction[par]; + Template tmpl = paramToTemplate![par]; + QilFunction func = paramToFunction![par]; CheckSingletonFocus(); _funcFocus.StartFocus(func.Arguments, par.Flags); EnterScope(tmpl); EnterScope(par); foreach (QilParameter arg in func.Arguments) { - _scope.AddVariable(arg.Name, arg); + _scope.AddVariable(arg.Name!, arg); } func.Definition = CompileVarParValue(par); SetLineInfo(func.Definition, par.SourceLine); @@ -648,14 +650,14 @@ private void CompileProtoTemplate(ProtoTemplate tmpl) _funcFocus.StartFocus(tmpl.Function.Arguments, !IsDebug ? tmpl.Flags : XslFlags.FullFocus); foreach (QilParameter arg in tmpl.Function.Arguments) { - if (arg.Name.NamespaceUri != XmlReservedNs.NsXslDebug) + if (arg.Name!.NamespaceUri != XmlReservedNs.NsXslDebug) { Debug.Assert(tmpl is Template, "Only templates can have explicit arguments"); if (IsDebug) { Debug.Assert(arg.DefaultValue == null, "Argument must not be compiled yet"); - VarPar xslParam = (VarPar)arg.Annotation; - QilList nsListParam = EnterScope(xslParam); + VarPar xslParam = (VarPar)arg.Annotation!; + QilList? nsListParam = EnterScope(xslParam); arg.DefaultValue = CompileVarParValue(xslParam); ExitScope(); arg.DefaultValue = SetDebugNs(arg.DefaultValue, nsListParam); @@ -706,7 +708,7 @@ private QilNode CompileInstructions(IList instructions, int from, QilLi { continue; // already compiled by CompileProtoTemplate() } - QilList nsList = EnterScope(node); + QilList? nsList = EnterScope(node); QilNode result; switch (nodeType) @@ -760,7 +762,7 @@ private QilNode CompileInstructions(IList instructions, int from, QilLi if (nodeType == XslNodeType.Variable) { QilIterator var = _f.Let(result); - var.DebugName = node.Name.ToString(); + var.DebugName = node.Name!.ToString(); _scope.AddVariable(node.Name, var); // Process all remaining instructions in the recursive call result = _f.Loop(var, CompileInstructions(instructions, i + 1)); @@ -808,14 +810,14 @@ private QilNode CompileLiteralElement(XslNode node) Start: _prefixesInUse.Clear(); - QilName qname = node.Name; - string prefix = qname.Prefix; + QilName qname = node.Name!; + string prefix = qname!.Prefix; string nsUri = qname.NamespaceUri; - _compiler.ApplyNsAliases(ref prefix, ref nsUri); + _compiler.ApplyNsAliases(ref prefix!, ref nsUri); if (changePrefixes) { - _prefixesInUse.Add(prefix, nsUri); + _prefixesInUse.Add(prefix!, nsUri); } else { @@ -829,16 +831,16 @@ private QilNode CompileLiteralElement(XslNode node) QilList nsList = InstructionList(); foreach (ScopeRecord rec in _scope) { - string recPrefix = rec.ncName; - string recNsUri = rec.nsUri; - if (recNsUri != XmlReservedNs.NsXslt && !_scope.IsExNamespace(recNsUri)) + string? recPrefix = rec.ncName; + string? recNsUri = rec.nsUri; + if (recNsUri != XmlReservedNs.NsXslt && !_scope.IsExNamespace(recNsUri!)) { - _compiler.ApplyNsAliases(ref recPrefix, ref recNsUri); + _compiler.ApplyNsAliases(ref recPrefix, ref recNsUri!); if (changePrefixes) { - if (_prefixesInUse.Contains(recPrefix)) + if (_prefixesInUse.Contains(recPrefix!)) { - if ((string)_prefixesInUse[recPrefix] != recNsUri) + if ((string?)_prefixesInUse[recPrefix!] != recNsUri) { // Found a prefix conflict. Start again from the beginning leaving all prefixes untouched. _outputScope.PopScope(); @@ -848,14 +850,14 @@ private QilNode CompileLiteralElement(XslNode node) } else { - _prefixesInUse.Add(recPrefix, recNsUri); + _prefixesInUse.Add(recPrefix!, recNsUri); } } else { recPrefix = rec.ncName; } - AddNsDecl(nsList, recPrefix, recNsUri); + AddNsDecl(nsList, recPrefix!, recNsUri); } } @@ -869,7 +871,7 @@ private QilNode CompileLiteralElement(XslNode node) private QilNode CompileElement(NodeCtor node) { - QilNode qilNs = CompileStringAvt(node.NsAvt); + QilNode? qilNs = CompileStringAvt(node.NsAvt); QilNode qilName = CompileStringAvt(node.NameAvt); QilNode qname; @@ -912,22 +914,22 @@ private QilNode CompileElement(NodeCtor node) private QilNode CompileLiteralAttribute(XslNode node) { - QilName qname = node.Name; + QilName qname = node.Name!; string prefix = qname.Prefix; string nsUri = qname.NamespaceUri; // The default namespace do not apply directly to attributes if (prefix.Length != 0) { - _compiler.ApplyNsAliases(ref prefix, ref nsUri); + _compiler.ApplyNsAliases(ref prefix!, ref nsUri); } qname.Prefix = prefix; qname.NamespaceUri = nsUri; - return _f.AttributeCtor(qname, CompileTextAvt(node.Select)); + return _f.AttributeCtor(qname, CompileTextAvt(node.Select!)); } private QilNode CompileAttribute(NodeCtor node) { - QilNode qilNs = CompileStringAvt(node.NsAvt); + QilNode? qilNs = CompileStringAvt(node.NsAvt); QilNode qilName = CompileStringAvt(node.NameAvt); QilNode qname; bool explicitNamespace = false; @@ -978,7 +980,7 @@ private QilNode CompileAttribute(NodeCtor node) private readonly StringBuilder _unescapedText = new StringBuilder(); - private QilNode ExtractText(string source, ref int pos) + private QilNode? ExtractText(string source, ref int pos) { Debug.Assert(pos < source.Length); int i, start = pos; @@ -1011,7 +1013,7 @@ private QilNode ExtractText(string source, ref int pos) ReportError(/*[XT0370]*/SR.Xslt_SingleRightBraceInAvt, source); return null; } - return _f.Error(_lastScope.SourceLine, SR.Xslt_SingleRightBraceInAvt, source); + return _f.Error(_lastScope!.SourceLine, SR.Xslt_SingleRightBraceInAvt, source); } } } @@ -1035,7 +1037,7 @@ private QilNode CompileAvt(string source) int pos = 0; while (pos < source.Length) { - QilNode fixedPart = ExtractText(source, ref pos); + QilNode? fixedPart = ExtractText(source, ref pos); if (fixedPart != null) { result.Add(fixedPart); @@ -1056,7 +1058,8 @@ private QilNode CompileAvt(string source) private static readonly char[] s_curlyBraces = { '{', '}' }; - private QilNode CompileStringAvt(string avt) + [return: NotNullIfNotNull("avt")] + private QilNode? CompileStringAvt(string? avt) { if (avt == null) { @@ -1095,14 +1098,14 @@ private QilNode CompileTextAvt(string avt) private QilNode CompileText(Text node) { if (node.Hints == SerializationHints.None) - return _f.TextCtor(_f.String(node.Select)); + return _f.TextCtor(_f.String(node.Select!)); - return _f.RawTextCtor(_f.String(node.Select)); + return _f.RawTextCtor(_f.String(node.Select!)); } private QilNode CompilePI(XslNode node) { - QilNode qilName = CompileStringAvt(node.Select); + QilNode qilName = CompileStringAvt(node.Select!); if (qilName.NodeType == QilNodeType.LiteralString) { string name = (string)(QilLiteral)qilName; @@ -1118,10 +1121,10 @@ private QilNode CompileComment(XslNode node) private QilNode CompileError(XslNode node) { - return _f.Error(_f.String(node.Select)); + return _f.Error(_f.String(node.Select!)); } - private QilNode WrapLoopBody(ISourceLineInfo before, QilNode expr, ISourceLineInfo after) + private QilNode WrapLoopBody(ISourceLineInfo? before, QilNode expr, ISourceLineInfo? after) { Debug.Assert(_curLoop.IsFocusSet); if (IsDebug) @@ -1142,7 +1145,7 @@ private QilNode CompileForEach(XslNodeEx node) // Push new loop frame on the stack LoopFocus curLoopSaved = _curLoop; - QilIterator it = _f.For(CompileNodeSetExpression(node.Select)); + QilIterator it = _f.For(CompileNodeSetExpression(node.Select!)); _curLoop.SetFocus(it); // Compile sort keys and body @@ -1167,23 +1170,23 @@ private QilNode CompileApplyTemplates(XslNodeEx node) // Calculate select expression int varScope = _varHelper.StartVariables(); - QilIterator select = _f.Let(CompileNodeSetExpression(node.Select)); + QilIterator select = _f.Let(CompileNodeSetExpression(node.Select!)); _varHelper.AddVariable(select); // Compile with-param's, they must be calculated outside the loop and // if they are neither constant nor reference we need to cache them in Let's for (int i = 0; i < content.Count; i++) { - VarPar withParam = content[i] as VarPar; + VarPar? withParam = content[i] as VarPar; if (withParam != null) { Debug.Assert(withParam.NodeType == XslNodeType.WithParam); CompileWithParam(withParam); - QilNode val = withParam.Value; + QilNode? val = withParam.Value; if (IsDebug || !(val is QilIterator || val is QilLiteral)) { - QilIterator let = _f.Let(val); - let.DebugName = _f.QName("with-param " + withParam.Name.QualifiedName, XmlReservedNs.NsXslDebug).ToString(); + QilIterator let = _f.Let(val!); + let.DebugName = _f.QName("with-param " + withParam.Name!.QualifiedName, XmlReservedNs.NsXslDebug).ToString(); _varHelper.AddVariable(let); withParam.Value = let; } @@ -1198,7 +1201,7 @@ private QilNode CompileApplyTemplates(XslNodeEx node) // Compile sort keys and body _curLoop.Sort(CompileSorts(content, ref curLoopSaved)); - result = GenerateApply(_compiler.Root, node); + result = GenerateApply(_compiler.Root!, node); result = WrapLoopBody(node.ElemNameLi, result, node.EndTagLi); result = AddCurrentPositionLast(result); @@ -1216,12 +1219,12 @@ private QilNode CompileApplyImports(XslNode node) Debug.Assert(node.NodeType == XslNodeType.ApplyImports); Debug.Assert(!_curLoop.IsFocusSet, "xsl:apply-imports cannot be inside of xsl:for-each"); - return GenerateApply((StylesheetLevel)node.Arg, node); + return GenerateApply((StylesheetLevel)node.Arg!, node); } private QilNode CompileCallTemplate(XslNodeEx node) { - VerifyXPathQName(node.Name); + VerifyXPathQName(node.Name!); int varScope = _varHelper.StartVariables(); IList content = node.Content; @@ -1231,9 +1234,9 @@ private QilNode CompileCallTemplate(XslNodeEx node) // In debug mode precalculate all with-param's if (IsDebug) { - QilNode val = withParam.Value; + QilNode val = withParam.Value!; QilIterator let = _f.Let(val); - let.DebugName = _f.QName("with-param " + withParam.Name.QualifiedName, XmlReservedNs.NsXslDebug).ToString(); + let.DebugName = _f.QName("with-param " + withParam.Name!.QualifiedName, XmlReservedNs.NsXslDebug).ToString(); _varHelper.AddVariable(let); withParam.Value = let; } @@ -1241,17 +1244,17 @@ private QilNode CompileCallTemplate(XslNodeEx node) QilNode result; { - Template tmpl; - if (_compiler.NamedTemplates.TryGetValue(node.Name, out tmpl)) + Template? tmpl; + if (_compiler.NamedTemplates.TryGetValue(node.Name!, out tmpl)) { Debug.Assert(tmpl.Function != null, "All templates should be already compiled"); - result = _invkGen.GenerateInvoke(tmpl.Function, AddRemoveImplicitArgs(node.Content, tmpl.Flags)); + result = _invkGen.GenerateInvoke(tmpl.Function, AddRemoveImplicitArgs(node.Content, tmpl.Flags)!); } else { - if (!_compiler.IsPhantomName(node.Name)) + if (!_compiler.IsPhantomName(node.Name!)) { - _compiler.ReportError(/*[XT0710]*/node.SourceLine, SR.Xslt_InvalidCallTemplate, node.Name.QualifiedName); + _compiler.ReportError(/*[XT0710]*/node.SourceLine!, SR.Xslt_InvalidCallTemplate, node.Name!.QualifiedName); } result = _f.Sequence(); } @@ -1272,21 +1275,21 @@ private QilNode CompileCallTemplate(XslNodeEx node) private QilNode CompileUseAttributeSet(XslNode node) { - VerifyXPathQName(node.Name); + VerifyXPathQName(node.Name!); // REVIEW: Future optimization: invalidate only if there were AVTs _outputScope.InvalidateAllPrefixes(); - AttributeSet attSet; - if (_compiler.AttributeSets.TryGetValue(node.Name, out attSet)) + AttributeSet? attSet; + if (_compiler.AttributeSets.TryGetValue(node.Name!, out attSet)) { Debug.Assert(attSet.Function != null, "All templates should be already compiled"); - return _invkGen.GenerateInvoke(attSet.Function, AddRemoveImplicitArgs(node.Content, attSet.Flags)); + return _invkGen.GenerateInvoke(attSet.Function, AddRemoveImplicitArgs(node.Content, attSet.Flags)!); } else { - if (!_compiler.IsPhantomName(node.Name)) + if (!_compiler.IsPhantomName(node.Name!)) { - _compiler.ReportError(/*[XT0710]*/node.SourceLine, SR.Xslt_NoAttributeSet, node.Name.QualifiedName); + _compiler.ReportError(/*[XT0710]*/node.SourceLine!, SR.Xslt_NoAttributeSet, node.Name!.QualifiedName); } return _f.Sequence(); } @@ -1298,7 +1301,7 @@ private QilNode CompileCopy(XslNode copy) { QilNode node = GetCurrentNode(); _f.CheckNodeNotRtf(node); - if ((node.XmlType.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None) + if ((node.XmlType!.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None) { _outputScope.InvalidateAllPrefixes(); } @@ -1336,7 +1339,7 @@ private QilNode CompileCopy(XslNode copy) private QilNode CompileCopyOf(XslNode node) { QilNode selectExpr = CompileXPathExpression(node.Select); - if (selectExpr.XmlType.IsNode) + if (selectExpr.XmlType!.IsNode) { if ((selectExpr.XmlType.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None) { @@ -1409,14 +1412,14 @@ private QilNode CompileIf(XslNode ifNode) private QilNode CompileChoose(XslNode node) { IList cases = node.Content; - QilNode result = null; + QilNode? result = null; // It's easier to compile xsl:choose from bottom to top for (int i = cases.Count - 1; 0 <= i; i--) { XslNode when = cases[i]; Debug.Assert(when.NodeType == XslNodeType.If || when.NodeType == XslNodeType.Otherwise); - QilList nsList = EnterScope(when); + QilList? nsList = EnterScope(when); if (when.NodeType == XslNodeType.Otherwise) { Debug.Assert(result == null, "xsl:otherwise must be the last child of xsl:choose"); @@ -1439,14 +1442,14 @@ private QilNode CompileChoose(XslNode node) private QilNode CompileMessage(XslNode node) { - string baseUri = _lastScope.SourceLine.Uri; + string? baseUri = _lastScope!.SourceLine!.Uri; QilNode content = _f.RtfCtor(CompileInstructions(node.Content), _f.String(baseUri)); //content = f.ConvertToString(content); content = _f.InvokeOuterXml(content); // If terminate="no", then create QilNodeType.Warning - if (!(bool)node.Arg) + if (!(bool)node.Arg!) { return _f.Warning(content); } @@ -1459,7 +1462,7 @@ private QilNode CompileMessage(XslNode node) private QilNode CompileVariable(XslNode node) { Debug.Assert(node.NodeType == XslNodeType.Variable); - if (_scope.IsLocalVariable(node.Name.LocalName, node.Name.NamespaceUri)) + if (_scope.IsLocalVariable(node.Name!.LocalName, node.Name.NamespaceUri)) { ReportError(/*[XT_030]*/SR.Xslt_DupLocalVariable, node.Name.QualifiedName); } @@ -1469,11 +1472,11 @@ private QilNode CompileVariable(XslNode node) private QilNode CompileVarParValue(XslNode node) { Debug.Assert(node.NodeType == XslNodeType.Variable || node.NodeType == XslNodeType.Param || node.NodeType == XslNodeType.WithParam); - VerifyXPathQName(node.Name); + VerifyXPathQName(node.Name!); - string baseUri = _lastScope.SourceLine.Uri; + string? baseUri = _lastScope!.SourceLine!.Uri; IList content = node.Content; - string select = node.Select; + string? select = node.Select; QilNode varValue; if (select != null) @@ -1507,7 +1510,7 @@ private QilNode CompileVarParValue(XslNode node) private void CompileWithParam(VarPar withParam) { Debug.Assert(withParam.NodeType == XslNodeType.WithParam); - QilList nsList = EnterScope(withParam); + QilList? nsList = EnterScope(withParam); QilNode paramValue = CompileVarParValue(withParam); ExitScope(); SetLineInfo(paramValue, withParam.SourceLine); @@ -1517,7 +1520,7 @@ private void CompileWithParam(VarPar withParam) // REVIEW: Can we handle both sort's and with-param's in the document order? // CompileSorts() creates helper variables in varHelper - private QilNode CompileSorts(IList content, ref LoopFocus parentLoop) + private QilNode? CompileSorts(IList content, ref LoopFocus parentLoop) { QilList keyList = _f.BaseFactory.SortKeyList(); @@ -1525,7 +1528,7 @@ private QilNode CompileSorts(IList content, ref LoopFocus parentLoop) while (i < content.Count) { - Sort sort = content[i] as Sort; + Sort? sort = content[i] as Sort; if (sort != null) { CompileSort(sort, keyList, ref parentLoop); @@ -1543,9 +1546,9 @@ private QilNode CompileSorts(IList content, ref LoopFocus parentLoop) return keyList; } - private QilNode CompileLangAttribute(string attValue, bool fwdCompat) + private QilNode? CompileLangAttribute(string? attValue, bool fwdCompat) { - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result == null) { @@ -1574,12 +1577,12 @@ private QilNode CompileLangAttribute(string attValue, bool fwdCompat) return result; } - private QilNode CompileLangAttributeToLcid(string attValue, bool fwdCompat) + private QilNode CompileLangAttributeToLcid(string? attValue, bool fwdCompat) { return CompileLangToLcid(CompileStringAvt(attValue), fwdCompat); } - private QilNode CompileLangToLcid(QilNode lang, bool fwdCompat) + private QilNode CompileLangToLcid(QilNode? lang, bool fwdCompat) { if (lang == null) { @@ -1595,11 +1598,11 @@ private QilNode CompileLangToLcid(QilNode lang, bool fwdCompat) } } - private void CompileDataTypeAttribute(string attValue, bool fwdCompat, ref QilNode select, out QilNode select2) + private void CompileDataTypeAttribute(string? attValue, bool fwdCompat, ref QilNode select, out QilNode? select2) { const string DtText = "text"; const string DtNumber = "number"; - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result != null) { if (result.NodeType == QilNodeType.LiteralString) @@ -1644,7 +1647,7 @@ private void CompileDataTypeAttribute(string attValue, bool fwdCompat, ref QilNo _f.Conditional(_f.Eq(dt, _f.String(DtText)), _f.True(), fwdCompat ? _f.True() : _f.Loop(qname = _f.Let(ResolveQNameDynamic(/*ignoreDefaultNs:*/true, dt)), - _f.Error(_lastScope.SourceLine, + _f.Error(_lastScope!.SourceLine, SR.Xslt_BistateAttribute, "data-type", DtText, DtNumber ) ) @@ -1679,9 +1682,10 @@ private void CompileDataTypeAttribute(string attValue, bool fwdCompat, ref QilNo /// returning "1" if AVT evaluates to value1, or "0" if AVT evaluates to value0 or any other value. /// If AVT evaluates to neither value0 nor value1 and fwdCompat == false, an error is reported. /// - private QilNode CompileOrderAttribute(string attName, string attValue, string value0, string value1, bool fwdCompat) + [return: NotNullIfNotNull("attName")] + private QilNode CompileOrderAttribute(string attName, string? attValue, string value0, string value1, bool fwdCompat) { - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result != null) { if (result.NodeType == QilNodeType.LiteralString) @@ -1707,20 +1711,22 @@ private QilNode CompileOrderAttribute(string attName, string attValue, string va _f.Conditional(_f.Eq(i, _f.String(value1)), _f.String("1"), fwdCompat ? _f.String("0") : _f.Conditional(_f.Eq(i, _f.String(value0)), _f.String("0"), - _f.Error(_lastScope.SourceLine, + _f.Error(_lastScope!.SourceLine, SR.Xslt_BistateAttribute, attName, value0, value1 ) ))); } Debug.Assert(result.XmlType == T.StringX); } - return result; + + return result!; } private void CompileSort(Sort sort, QilList keyList, ref LoopFocus parentLoop) { Debug.Assert(sort.NodeType == XslNodeType.Sort); - QilNode select, select2, lang, order, caseOrder; + QilNode select; + QilNode? select2, lang, order, caseOrder; bool fwdCompat; EnterScope(sort); @@ -1832,7 +1838,7 @@ private QilNode MatchPattern(QilNode pattern, QilIterator testNode) return result; } - private QilNode MatchCountPattern(QilNode countPattern, QilIterator testNode) + private QilNode MatchCountPattern(QilNode? countPattern, QilIterator testNode) { /* If the 'count' attribute is not specified, then it defaults to the pattern that matches any node @@ -1847,7 +1853,7 @@ the same expanded-QName as the context node. { QilNode current = GetCurrentNode(); QilNode result; - XmlNodeKindFlags nodeKinds = current.XmlType.NodeKinds; + XmlNodeKindFlags nodeKinds = current.XmlType!.NodeKinds; // If node kind is not known, invoke a runtime function if ((nodeKinds & (nodeKinds - 1)) != 0) @@ -1878,7 +1884,7 @@ the same expanded-QName as the context node. } } - private QilNode PlaceMarker(QilNode countPattern, QilNode fromPattern, bool multiple) + private QilNode PlaceMarker(QilNode? countPattern, QilNode? fromPattern, bool multiple) { /* Quotation from XSLT 2.0 spec: @@ -1900,7 +1906,8 @@ private QilNode PlaceMarker(QilNode countPattern, QilNode fromPattern, bool mult '$A[. >> $F]' if the 'from' attribute is present. */ - QilNode countPattern2, countMatches, fromMatches, A, F, AF; + QilNode? countPattern2; + QilNode countMatches, fromMatches, A, F, AF; QilIterator i, j; countPattern2 = (countPattern != null) ? countPattern.DeepClone(_f.BaseFactory) : null; @@ -1930,7 +1937,7 @@ private QilNode PlaceMarker(QilNode countPattern, QilNode fromPattern, bool mult ); } - private QilNode PlaceMarkerAny(QilNode countPattern, QilNode fromPattern) + private QilNode PlaceMarkerAny(QilNode? countPattern, QilNode? fromPattern) { /* Quotation from XSLT 2.0 spec: @@ -1979,14 +1986,14 @@ private QilNode PlaceMarkerAny(QilNode countPattern, QilNode fromPattern) } // Returns one of XsltLibrary.LetterValue enum values - private QilNode CompileLetterValueAttribute(string attValue, bool fwdCompat) + private QilNode CompileLetterValueAttribute(string? attValue, bool fwdCompat) { const string Default = "default"; const string Alphabetic = "alphabetic"; const string Traditional = "traditional"; string letterValue; - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result != null) { @@ -2015,16 +2022,16 @@ private QilNode CompileLetterValueAttribute(string attValue, bool fwdCompat) _f.Or(_f.Eq(i, _f.String(Alphabetic)), _f.Eq(i, _f.String(Traditional))), i, fwdCompat ? _f.String(Default) : - _f.Error(_lastScope.SourceLine, SR.Xslt_BistateAttribute, "letter-value", Alphabetic, Traditional) + _f.Error(_lastScope!.SourceLine, SR.Xslt_BistateAttribute, "letter-value", Alphabetic, Traditional) )); } } return _f.String(Default); } - private QilNode CompileGroupingSeparatorAttribute(string attValue, bool fwdCompat) + private QilNode CompileGroupingSeparatorAttribute(string? attValue, bool fwdCompat) { - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result == null) { @@ -2050,15 +2057,15 @@ private QilNode CompileGroupingSeparatorAttribute(string attValue, bool fwdCompa result = _f.Loop(i, _f.Conditional(_f.Eq(_f.StrLength(i), _f.Int32(1)), i, fwdCompat ? _f.String(string.Empty) : - _f.Error(_lastScope.SourceLine, SR.Xslt_CharAttribute, "grouping-separator") + _f.Error(_lastScope!.SourceLine, SR.Xslt_CharAttribute, "grouping-separator") )); } return result; } - private QilNode CompileGroupingSizeAttribute(string attValue, bool fwdCompat) + private QilNode CompileGroupingSizeAttribute(string? attValue, bool fwdCompat) { - QilNode result = CompileStringAvt(attValue); + QilNode? result = CompileStringAvt(attValue); if (result == null) { @@ -2103,8 +2110,8 @@ private QilNode CompileNumber(Number num) } else { - QilNode countPattern = (num.Count != null) ? CompileNumberPattern(num.Count) : null; - QilNode fromPattern = (num.From != null) ? CompileNumberPattern(num.From) : null; + QilNode? countPattern = (num.Count != null) ? CompileNumberPattern(num.Count) : null; + QilNode? fromPattern = (num.From != null) ? CompileNumberPattern(num.From) : null; switch (num.Level) { @@ -2226,7 +2233,7 @@ private void CreateGlobalVarPar(VarPar varPar) { it = _f.Parameter(null, varPar.Name, xt); } - it.DebugName = varPar.Name.ToString(); + it.DebugName = varPar.Name!.ToString(); varPar.Value = it; SetLineInfo(it, varPar.SourceLine); _scope.AddVariable(varPar.Name, it); @@ -2252,9 +2259,9 @@ private void CompileGlobalVariables() private QilIterator CompileGlobalVarPar(VarPar varPar) { Debug.Assert(varPar.NodeType == XslNodeType.Variable || varPar.NodeType == XslNodeType.Param); - QilIterator it = (QilIterator)varPar.Value; + QilIterator it = (QilIterator)varPar.Value!; - QilList nsList = EnterScope(varPar); + QilList? nsList = EnterScope(varPar); QilNode content = CompileVarParValue(varPar); SetLineInfo(content, it.SourceLine); content = AddCurrentPositionLast(content); @@ -2269,9 +2276,9 @@ private QilIterator CompileGlobalVarPar(VarPar varPar) private void ReportErrorInXPath(XslLoadException e) { - XPathCompileException ex = e as XPathCompileException; + XPathCompileException? ex = e as XPathCompileException; string errorText = (ex != null) ? ex.FormatDetailedMessage() : e.Message; - _compiler.ReportError(_lastScope.SourceLine, SR.Xml_UserException, errorText); + _compiler.ReportError(_lastScope!.SourceLine!, SR.Xml_UserException, errorText); } private QilNode PhantomXPathExpression() @@ -2286,7 +2293,7 @@ private QilNode PhantomKeyMatch() // Calls to CompileXPathExpression() can't be nested in the XSLT. So we can reuse the same instance of xpathBuilder. // The only thing we need to do before its use is adjustment of IXPathEnvironment to have correct context tuple. - private QilNode CompileXPathExpression(string expr) + private QilNode CompileXPathExpression(string? expr) { XPathScanner scanner; QilNode result; @@ -2322,7 +2329,7 @@ private QilNode CompileXPathExpression(string expr) private QilNode CompileNodeSetExpression(string expr) { - QilNode result = _f.TryEnsureNodeSet(CompileXPathExpression(expr)); + QilNode? result = _f.TryEnsureNodeSet(CompileXPathExpression(expr)); if (result == null) { // The expression is never a node-set @@ -2415,7 +2422,7 @@ private QilNode CompileNumberPattern(string pttrn) return result; } - private QilNode CompileKeyMatch(string pttrn) + private QilNode CompileKeyMatch(string? pttrn) { XPathScanner scanner; QilNode result; @@ -2450,7 +2457,7 @@ private QilNode CompileKeyMatch(string pttrn) private QilNode CompileKeyUse(Key key) { - string expr = key.Use; + string? expr = key.Use; XPathScanner scanner; QilNode result; @@ -2492,8 +2499,8 @@ private QilNode ResolveQNameDynamic(bool ignoreDefaultNs, QilNode qilName) } foreach (ScopeRecord rec in _scope) { - string recPrefix = rec.ncName; - string recNsUri = rec.nsUri; + string recPrefix = rec.ncName!; + string? recNsUri = rec.nsUri; if (ignoreDefaultNs && recPrefix.Length == 0) { @@ -2501,7 +2508,7 @@ private QilNode ResolveQNameDynamic(bool ignoreDefaultNs, QilNode qilName) } else { - nsDecls.Add(_f.NamespaceDecl(_f.String(recPrefix), _f.String(recNsUri))); + nsDecls.Add(_f.NamespaceDecl(_f.String(recPrefix), _f.String(recNsUri!))); } } return _f.StrParseQName(qilName, nsDecls); @@ -2520,7 +2527,7 @@ private QilNode GenerateApply(StylesheetLevel sheet, XslNode node) { return _f.Sequence(); } - return InvokeApplyFunction(sheet, /*mode:*/node.Name, node.Content); + return InvokeApplyFunction(sheet, /*mode:*/node.Name!, node.Content); } private void SetArg(IList args, int pos, QilName name, QilNode value) @@ -2537,7 +2544,7 @@ private void SetArg(IList args, int pos, QilName name, QilNode value) } varPar.Value = value; } - private IList AddRemoveImplicitArgs(IList args, XslFlags flags) + private IList? AddRemoveImplicitArgs(IList? args, XslFlags flags) { //We currently don't reuse the same argument list. So remove is not needed and will not work in this code if (IsDebug) @@ -2571,9 +2578,9 @@ private bool FillupInvokeArgs(IList formalArgs, IList actualAr invokeArgs.Clear(); for (int invArg = 0; invArg < formalArgs.Count; invArg++) { - QilName formalArgName = ((QilParameter)formalArgs[invArg]).Name; - XmlQueryType paramType = formalArgs[invArg].XmlType; - QilNode arg = null; + QilName formalArgName = ((QilParameter)formalArgs[invArg]).Name!; + XmlQueryType paramType = formalArgs[invArg].XmlType!; + QilNode? arg = null; { for (int actArg = 0; actArg < actualArgs.Count; actArg++) { @@ -2581,8 +2588,8 @@ private bool FillupInvokeArgs(IList formalArgs, IList actualAr VarPar withParam = (VarPar)actualArgs[actArg]; if (formalArgName.Equals(withParam.Name)) { - QilNode value = withParam.Value; - XmlQueryType valueType = value.XmlType; + QilNode value = withParam.Value!; + XmlQueryType valueType = value.XmlType!; if (valueType != paramType) { if (valueType.IsNode && paramType.IsNode && valueType.IsSubtypeOf(paramType)) @@ -2611,7 +2618,7 @@ private bool FillupInvokeArgs(IList formalArgs, IList actualAr return true; } - private QilNode InvokeApplyFunction(StylesheetLevel sheet, QilName mode, IList actualArgs) + private QilNode InvokeApplyFunction(StylesheetLevel sheet, QilName mode, IList? actualArgs) { // Here we create function that has one argument for each with-param in apply-templates // We have actualArgs -- list of xsl:with-param(name, value) @@ -2631,10 +2638,10 @@ private QilNode InvokeApplyFunction(StylesheetLevel sheet, QilName mode, IList functionsForMode; + List? functionsForMode; if (!sheet.ApplyFunctions.TryGetValue(mode, out functionsForMode)) { functionsForMode = sheet.ApplyFunctions[mode] = new List(); @@ -2642,7 +2649,7 @@ private QilNode InvokeApplyFunction(StylesheetLevel sheet, QilName mode, IList 1 ? args[1] : null); case FuncId.FormatNumber: return CompileFormatNumber(args[0], args[1], args.Count > 2 ? args[2] : null); case FuncId.UnparsedEntityUri: return CompileUnparsedEntityUri(args[0]); - case FuncId.GenerateId: return CompileGenerateId(args.Count > 0 ? args[0] : env.GetCurrent()); + case FuncId.GenerateId: return CompileGenerateId(args.Count > 0 ? args[0] : env.GetCurrent()!); case FuncId.SystemProperty: return CompileSystemProperty(args[0]); case FuncId.ElementAvailable: return CompileElementAvailable(args[0]); case FuncId.FunctionAvailable: return CompileFunctionAvailable(args[0]); @@ -181,7 +182,7 @@ QilNode IXPathEnvironment.ResolveFunction(string prefix, string name, IList defList, QilNode key, IFocus env) Debug.Assert(defList != null && defList.Count > 0); if (defList.Count == 1) { - return _f.Invoke(defList[0].Function, _f.ActualParameterList(env.GetCurrent(), key)); + return _f.Invoke(defList[0].Function!, _f.ActualParameterList(env.GetCurrent()!, key)); } QilIterator i = _f.Let(key); QilNode result = _f.Sequence(); foreach (Key keyDef in defList) { - result.Add(_f.Invoke(keyDef.Function, _f.ActualParameterList(env.GetCurrent(), i))); + result.Add(_f.Invoke(keyDef.Function!, _f.ActualParameterList(env.GetCurrent()!, i))); } return _f.Loop(i, result); } @@ -455,14 +456,14 @@ private QilNode CompileSingleKey(List defList, QilIterator key, QilIterator { Debug.Assert(defList != null && defList.Count > 0); QilList result = _f.BaseFactory.Sequence(); - QilNode keyRef = null; + QilNode? keyRef = null; foreach (Key keyDef in defList) { - keyRef = _f.Invoke(keyDef.Function, _f.ActualParameterList(context, key)); + keyRef = _f.Invoke(keyDef.Function!, _f.ActualParameterList(context, key)); result.Add(keyRef); } - return defList.Count == 1 ? keyRef : result; + return defList.Count == 1 ? keyRef! : result; } private QilFunction CreateGeneralKeyFunction() @@ -475,7 +476,7 @@ private QilFunction CreateGeneralKeyFunction() QilNode fdef = _f.Error(SR.Xslt_UndefinedKey, name); for (int idx = 0; idx < _compiler.Keys.Count; idx++) { - fdef = _f.Conditional(_f.Eq(resolvedName, _compiler.Keys[idx][0].Name.DeepClone(_f.BaseFactory)), + fdef = _f.Conditional(_f.Eq(resolvedName, _compiler.Keys[idx][0].Name!.DeepClone(_f.BaseFactory)), CompileSingleKey(_compiler.Keys[idx], key, context), fdef ); @@ -487,17 +488,18 @@ private QilFunction CreateGeneralKeyFunction() return result; } - private QilNode CompileFnDocument(QilNode uris, QilNode baseNode) + private QilNode CompileFnDocument(QilNode uris, QilNode? baseNode) { QilNode result; - QilIterator i, j, u; + QilIterator i, u; + QilIterator? j; if (!_compiler.Settings.EnableDocumentFunction) { ReportWarning(SR.Xslt_DocumentFuncProhibited); - return _f.Error(_lastScope.SourceLine, SR.Xslt_DocumentFuncProhibited); + return _f.Error(_lastScope!.SourceLine, SR.Xslt_DocumentFuncProhibited); } - if (uris.XmlType.IsNode) + if (uris.XmlType!.IsNode) { result = _f.DocOrderDistinct(_f.Loop(i = _f.For(uris), CompileSingleDocument(_f.ConvertToString(i), baseNode ?? i) @@ -517,25 +519,25 @@ private QilNode CompileFnDocument(QilNode uris, QilNode baseNode) )), CompileSingleDocument(_f.XsltConvert(u, T.StringX), j) ); - result = (baseNode != null) ? _f.Loop(j, result) : result; + result = (baseNode != null) ? _f.Loop(j!, result) : result; result = _f.Loop(u, result); } return result; } - private QilNode CompileSingleDocument(QilNode uri, QilNode baseNode) + private QilNode CompileSingleDocument(QilNode uri, QilNode? baseNode) { _f.CheckString(uri); QilNode baseUri; if (baseNode == null) { - baseUri = _f.String(_lastScope.SourceLine.Uri); + baseUri = _f.String(_lastScope!.SourceLine!.Uri); } else { _f.CheckNodeSet(baseNode); - if (baseNode.XmlType.IsSingleton) + if (baseNode.XmlType!.IsSingleton) { baseUri = _f.InvokeBaseUri(baseNode); } @@ -553,11 +555,11 @@ private QilNode CompileSingleDocument(QilNode uri, QilNode baseNode) return _f.DataSource(uri, baseUri); } - private QilNode CompileFormatNumber(QilNode value, QilNode formatPicture, QilNode formatName) + private QilNode CompileFormatNumber(QilNode value, QilNode formatPicture, QilNode? formatName) { _f.CheckDouble(value); _f.CheckString(formatPicture); - XmlQualifiedName resolvedName; + XmlQualifiedName? resolvedName; if (formatName == null) { @@ -622,13 +624,13 @@ private QilNode CompileFormatNumber(QilNode value, QilNode formatPicture, QilNod private QilNode CompileUnparsedEntityUri(QilNode n) { _f.CheckString(n); - return _f.Error(_lastScope.SourceLine, SR.Xslt_UnsupportedXsltFunction, "unparsed-entity-uri"); + return _f.Error(_lastScope!.SourceLine, SR.Xslt_UnsupportedXsltFunction, "unparsed-entity-uri"); } private QilNode CompileGenerateId(QilNode n) { _f.CheckNodeSet(n); - if (n.XmlType.IsSingleton) + if (n.XmlType!.IsSingleton) { return _f.XsltGenerateId(n); } @@ -721,7 +723,7 @@ private QilNode CompileFunctionAvailable(QilNode name) private QilNode CompileMsNodeSet(QilNode n) { - if (n.XmlType.IsNode && n.XmlType.IsNotRtf) + if (n.XmlType!.IsNode && n.XmlType.IsNotRtf) { return n; } @@ -737,7 +739,7 @@ private QilNode EXslObjectType(QilNode n) { if (EvaluateFuncCalls) { - switch (n.XmlType.TypeCode) + switch (n.XmlType!.TypeCode) { case XmlTypeCode.Boolean: return _f.String("boolean"); case XmlTypeCode.Double: return _f.String("number"); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilStrConcatenator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilStrConcatenator.cs index 80ef988abf93..80ded330780a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilStrConcatenator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilStrConcatenator.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. +#nullable enable using System.Diagnostics; using System.Xml; using System.Text; @@ -14,7 +15,7 @@ internal class QilStrConcatenator { private readonly XPathQilFactory _f; private readonly StringBuilder _builder; - private QilList _concat; + private QilList? _concat; private bool _inUse; public QilStrConcatenator(XPathQilFactory f) @@ -56,12 +57,12 @@ public void Append(char value) _builder.Append(value); } - public void Append(QilNode value) + public void Append(QilNode? value) { Debug.Assert(_inUse, "Reset() wasn't called"); if (value != null) { - Debug.Assert(value.XmlType.TypeCode == XmlTypeCode.String); + Debug.Assert(value.XmlType!.TypeCode == XmlTypeCode.String); if (value.NodeType == QilNodeType.LiteralString) { _builder.Append((string)(QilLiteral)value); @@ -69,7 +70,7 @@ public void Append(QilNode value) else { FlushBuilder(); - _concat.Add(value); + _concat!.Add(value); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs index e117eb07a379..479af7a79a11 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs @@ -4,6 +4,7 @@ // http://devdiv/Documents/Whidbey/CLR/CurrentSpecs/BCL/CodeDom%20Activation.doc //------------------------------------------------------------------------------ +#nullable enable using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; @@ -25,7 +26,7 @@ namespace System.Xml.Xsl.Xslt internal class Scripts { private readonly Compiler _compiler; - private readonly Dictionary _nsToType = new Dictionary(); + private readonly Dictionary _nsToType = new Dictionary(); private readonly XmlExtensionFunctionTable _extFuncs = new XmlExtensionFunctionTable(); public Scripts(Compiler compiler) @@ -33,14 +34,14 @@ public Scripts(Compiler compiler) _compiler = compiler; } - public Dictionary ScriptClasses + public Dictionary ScriptClasses { get { return _nsToType; } } - public XmlExtensionFunction ResolveFunction(string name, string ns, int numArgs, IErrorHelper errorHelper) + public XmlExtensionFunction? ResolveFunction(string name, string ns, int numArgs, IErrorHelper errorHelper) { - Type type; + Type? type; if (_nsToType.TryGetValue(ns, out type)) { try diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Stylesheet.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Stylesheet.cs index cdaa1d5226d1..26ecb7c6e148 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Stylesheet.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Stylesheet.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Xml.Xsl.Qil; namespace System.Xml.Xsl.Xslt diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs index ef4f222eace8..52e5f32430f1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs @@ -52,9 +52,9 @@ public virtual void StartBuild() public void AssertFilter(QilLoop filter) { Debug.Assert(filter.NodeType == QilNodeType.Filter, "XPathPatternBuilder expected to generate list of Filters on top level"); - Debug.Assert(filter.Variable.XmlType.IsSubtypeOf(T.NodeNotRtf)); - Debug.Assert(filter.Variable.Binding.NodeType == QilNodeType.Unknown); // fixupNode - Debug.Assert(filter.Body.XmlType.IsSubtypeOf(T.Boolean)); + Debug.Assert(filter.Variable.XmlType!.IsSubtypeOf(T.NodeNotRtf)); + Debug.Assert(filter.Variable.Binding!.NodeType == QilNodeType.Unknown); // fixupNode + Debug.Assert(filter.Body.XmlType!.IsSubtypeOf(T.Boolean)); } private void FixupFilterBinding(QilLoop filter, QilNode newBinding) @@ -109,7 +109,7 @@ private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPa /*name == nsUri == null*/ f.True() // * ); - XmlNodeKindFlags intersection = XPathBuilder.AxisTypeMask(itr.XmlType.NodeKinds, nodeType, xpathAxis); + XmlNodeKindFlags intersection = XPathBuilder.AxisTypeMask(itr.XmlType!.NodeKinds, nodeType, xpathAxis); QilNode typeTest = ( intersection == 0 ? f.False() : // input & required doesn't intersect @@ -118,7 +118,7 @@ private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPa ); QilLoop filter = f.BaseFactory.Filter(itr, f.And(typeTest, nameTest)); - filter.XmlType = T.PrimeProduct(T.NodeChoice(intersection), filter.XmlType.Cardinality); + filter.XmlType = T.PrimeProduct(T.NodeChoice(intersection), filter.XmlType!.Cardinality); return filter; } @@ -285,7 +285,7 @@ public QilNode BuildPredicates(QilNode nodeset, List predicates) QilNode filterCurrent = _f.Filter(matchNodeIter, _f.Is(matchNodeIter, current)); nodeFilter.Body = _f.Not(_f.IsEmpty(filterCurrent)); //for passing type check, explicit say the result is target type - nodeFilter.Body = _f.And(_f.IsType(current, nodeFilter.XmlType), nodeFilter.Body); + nodeFilter.Body = _f.And(_f.IsType(current, nodeFilter.XmlType!), nodeFilter.Body); } SetPriority(nodeset, 0.5); @@ -346,27 +346,27 @@ private class Annotation public static void SetPriority(QilNode node, double priority) { - Annotation ann = (Annotation)node.Annotation ?? new Annotation(); + Annotation ann = (Annotation?)node.Annotation ?? new Annotation(); ann.Priority = priority; node.Annotation = ann; } public static double GetPriority(QilNode node) { - return ((Annotation)node.Annotation).Priority; + return ((Annotation)node.Annotation!).Priority; } private static void SetLastParent(QilNode node, QilLoop parent) { Debug.Assert(parent.NodeType == QilNodeType.Filter); - Annotation ann = (Annotation)node.Annotation ?? new Annotation(); + Annotation ann = (Annotation?)node.Annotation ?? new Annotation(); ann.Parent = parent; node.Annotation = ann; } private static QilLoop? GetLastParent(QilNode node) { - return ((Annotation)node.Annotation).Parent; + return ((Annotation)node.Annotation!).Parent; } public static void CleanAnnotation(QilNode node) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XslAst.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XslAst.cs index 0dd73e5762c4..1e99401dab2f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XslAst.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XslAst.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. +#nullable enable using System.Text; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -60,11 +61,11 @@ internal enum XslNodeType internal class NsDecl { - public readonly NsDecl Prev; - public readonly string Prefix; // Empty string denotes the default namespace, null - extension or excluded namespace - public readonly string NsUri; // null means "#all" -- all namespace defined above this one are excluded. + public readonly NsDecl? Prev; + public readonly string? Prefix; // Empty string denotes the default namespace, null - extension or excluded namespace + public readonly string? NsUri; // null means "#all" -- all namespace defined above this one are excluded. - public NsDecl(NsDecl prev, string prefix, string nsUri) + public NsDecl(NsDecl? prev, string? prefix, string? nsUri) { Debug.Assert(nsUri != null || Prefix == null); this.Prev = prev; @@ -76,15 +77,15 @@ public NsDecl(NsDecl prev, string prefix, string nsUri) internal class XslNode { public readonly XslNodeType NodeType; - public ISourceLineInfo SourceLine; - public NsDecl Namespaces; - public readonly QilName Name; // name or mode - public readonly object Arg; // select or test or terminate or stylesheet;-) + public ISourceLineInfo? SourceLine; + public NsDecl? Namespaces; + public readonly QilName? Name; // name or mode + public readonly object? Arg; // select or test or terminate or stylesheet;-) public readonly XslVersion XslVersion; public XslFlags Flags; - private List _content; + private List? _content; - public XslNode(XslNodeType nodeType, QilName name, object arg, XslVersion xslVer) + public XslNode(XslNodeType nodeType, QilName? name, object? arg, XslVersion xslVer) { this.NodeType = nodeType; this.Name = name; @@ -98,7 +99,7 @@ public XslNode(XslNodeType nodeType) this.XslVersion = XslVersion.Current; } - public string Select { get { return (string)Arg; } } + public string? Select { get { return (string?)Arg; } } public bool ForwardsCompatible { get { return XslVersion == XslVersion.ForwardsCompatible; } } // -------------------------------- Content Management -------------------------------- @@ -110,7 +111,7 @@ public IList Content get { return _content ?? s_emptyList; } } - public void SetContent(List content) + public void SetContent(List? content) { _content = content; } @@ -137,7 +138,7 @@ public void InsertContent(IEnumerable collection) } } - internal string TraceName + internal string? TraceName { get { @@ -158,7 +159,8 @@ internal string TraceName sb.Append(' '); sb.Append(Name.QualifiedName); } - ISourceLineInfo lineInfo = SourceLine; + + ISourceLineInfo? lineInfo = SourceLine; if (lineInfo == null && NodeType == XslNodeType.AttributeSet) { lineInfo = Content[0].SourceLine; @@ -166,7 +168,7 @@ internal string TraceName } if (lineInfo != null) { - string fileName = SourceLineInfo.GetFileName(lineInfo.Uri); + string fileName = SourceLineInfo.GetFileName(lineInfo.Uri!); int idx = fileName.LastIndexOf(System.IO.Path.DirectorySeparatorChar) + 1; sb.Append(" ("); sb.Append(fileName, idx, fileName.Length - idx); @@ -184,9 +186,9 @@ internal string TraceName internal abstract class ProtoTemplate : XslNode { - public QilFunction Function; // Compiled body + public QilFunction? Function; // Compiled body - public ProtoTemplate(XslNodeType nt, QilName name, XslVersion xslVer) : base(nt, name, null, xslVer) { } + public ProtoTemplate(XslNodeType nt, QilName? name, XslVersion xslVer) : base(nt, name, null, xslVer) { } public abstract string GetDebugName(); } @@ -207,7 +209,7 @@ public override string GetDebugName() { StringBuilder dbgName = new StringBuilder(); dbgName.Append(""); return dbgName.ToString(); } @@ -226,13 +228,13 @@ public void MergeContent(AttributeSet other) internal class Template : ProtoTemplate { - public readonly string Match; + public readonly string? Match; public readonly QilName Mode; public readonly double Priority; public int ImportPrecedence; public int OrderNumber; - public Template(QilName name, string match, QilName mode, double priority, XslVersion xslVer) + public Template(QilName? name, string? match, QilName mode, double priority, XslVersion xslVer) : base(XslNodeType.Template, name, xslVer) { this.Match = match; @@ -276,19 +278,19 @@ public override string GetDebugName() internal class VarPar : XslNode { public XslFlags DefValueFlags; - public QilNode Value; // Contains value for WithParams and global VarPars + public QilNode? Value; // Contains value for WithParams and global VarPars - public VarPar(XslNodeType nt, QilName name, string select, XslVersion xslVer) : base(nt, name, select, xslVer) { } + public VarPar(XslNodeType nt, QilName name, string? select, XslVersion xslVer) : base(nt, name, select, xslVer) { } } internal class Sort : XslNode { - public readonly string Lang; - public readonly string DataType; - public readonly string Order; - public readonly string CaseOrder; + public readonly string? Lang; + public readonly string? DataType; + public readonly string? Order; + public readonly string? CaseOrder; - public Sort(string select, string lang, string dataType, string order, string caseOrder, XslVersion xslVer) + public Sort(string select, string? lang, string? dataType, string? order, string? caseOrder, XslVersion xslVer) : base(XslNodeType.Sort, null, select, xslVer) { this.Lang = lang; @@ -303,17 +305,17 @@ internal class Keys : KeyedCollection> protected override QilName GetKeyForItem(List list) { Debug.Assert(list != null && list.Count > 0); - return list[0].Name; + return list[0].Name!; } } internal class Key : XslNode { - public readonly string Match; - public readonly string Use; - public QilFunction Function; + public readonly string? Match; + public readonly string? Use; + public QilFunction? Function; - public Key(QilName name, string match, string use, XslVersion xslVer) + public Key(QilName name, string? match, string? use, XslVersion xslVer) : base(XslNodeType.Key, name, null, xslVer) { // match and use can be null in case of incorrect stylesheet @@ -326,7 +328,7 @@ public string GetDebugName() { StringBuilder dbgName = new StringBuilder(); dbgName.Append(" { - private CompilerScopeManager _scope; - private Compiler _compiler; + private CompilerScopeManager? _scope; + private Compiler? _compiler; #if DEBUG // List of all variables and parameters private readonly List _allVarPars = new List(); #endif private int _forEachDepth; - private XPathAnalyzer _xpathAnalyzer; - private ProtoTemplate _currentTemplate; + private XPathAnalyzer? _xpathAnalyzer; + private ProtoTemplate? _currentTemplate; // Type donor of the last analyzed VarPar. Used for optimization of WithParam's. - private VarPar _typeDonor; + private VarPar? _typeDonor; // Template dependencies // rev/fwd - Callee-to-Coller/Coller-to-Callee // 0/1 - for-each depth - private Graph _revCall0Graph = new Graph(); - private Graph _revCall1Graph = new Graph(); - private Dictionary _fwdApplyImportsGraph = new Dictionary(); - private Dictionary> _revApplyTemplatesGraph = new Dictionary>(); + private Graph? _revCall0Graph = new Graph(); + private Graph? _revCall1Graph = new Graph(); + private Dictionary? _fwdApplyImportsGraph = new Dictionary(); + private Dictionary>? _revApplyTemplatesGraph = new Dictionary>(); // Data flow graph - private Graph _dataFlow = new Graph(); + private Graph? _dataFlow = new Graph(); // Mapping (mode, param name) -> helper vertex in data flow graph private readonly Dictionary _applyTemplatesParams = new Dictionary(); @@ -51,14 +53,14 @@ internal class XslAstAnalyzer : XslVisitor /// Represents a graph using hashtable of adjacency lists. /// /// Vertex type - internal class Graph : Dictionary> + internal class Graph : Dictionary?> where V : XslNode { private static readonly IList s_empty = (new List()).AsReadOnly(); public IEnumerable GetAdjList(V v) { - List adjList; + List? adjList; if (TryGetValue(v, out adjList) && adjList != null) { return adjList; @@ -74,7 +76,7 @@ public void AddEdge(V v1, V v2) return; } - List adjList; + List? adjList; if (!TryGetValue(v1, out adjList) || adjList == null) { adjList = this[v1] = new List(); @@ -149,11 +151,11 @@ public XslFlags Analyze(Compiler compiler) // Add global parameters and variables to the scope, they are visible everywhere foreach (VarPar par in compiler.ExternalPars) { - _scope.AddVariable(par.Name, par); + _scope.AddVariable(par.Name!, par); } foreach (VarPar var in compiler.GlobalVars) { - _scope.AddVariable(var.Name, var); + _scope.AddVariable(var.Name!, var); } // Visit global parameters and variables, but ignore calculated flags @@ -205,13 +207,13 @@ public XslFlags Analyze(Compiler compiler) // types Rtf, Nodeset, Node, Boolean, Number, String through the data flow graph. for (int flag = (int)XslFlags.Rtf; flag != 0; flag >>= 1) { - _dataFlow.PropagateFlag((XslFlags)flag); + _dataFlow!.PropagateFlag((XslFlags)flag); } _dataFlow = null; // We need to follow revCall0Graph graph to propagate focus flags. But first complete // dependency graph with fwdApplyImportsGraph - foreach (KeyValuePair pair in _fwdApplyImportsGraph) + foreach (KeyValuePair pair in _fwdApplyImportsGraph!) { foreach (Stylesheet import in pair.Value.Imports) { @@ -222,15 +224,15 @@ public XslFlags Analyze(Compiler compiler) if ((result & XslFlags.Current) != 0) { - _revCall0Graph.PropagateFlag(XslFlags.Current); + _revCall0Graph!.PropagateFlag(XslFlags.Current); } if ((result & XslFlags.Position) != 0) { - _revCall0Graph.PropagateFlag(XslFlags.Position); + _revCall0Graph!.PropagateFlag(XslFlags.Position); } if ((result & XslFlags.Last) != 0) { - _revCall0Graph.PropagateFlag(XslFlags.Last); + _revCall0Graph!.PropagateFlag(XslFlags.Last); } if ((result & XslFlags.SideEffects) != 0) { @@ -242,7 +244,7 @@ public XslFlags Analyze(Compiler compiler) // We can do this only after all flags were propagated. // Otherwise we can miss case when flag comes to template from attribute-set - FillModeFlags(compiler.Root.ModeFlags, compiler.Root.Imports[0]); + FillModeFlags(compiler.Root!.ModeFlags, compiler.Root.Imports[0]); return result; } @@ -253,7 +255,7 @@ private void AddImportDependencies(Stylesheet sheet, Template focusDonor) { if (tmpl.Mode.Equals(focusDonor.Mode)) { - _revCall0Graph.AddEdge(tmpl, focusDonor); + _revCall0Graph!.AddEdge(tmpl, focusDonor); } } foreach (Stylesheet import in sheet.Imports) @@ -299,14 +301,14 @@ private void FillModeFlags(Dictionary parentModeFlags, Styles protected override XslFlags Visit(XslNode node) { - _scope.EnterScope(node.Namespaces); + _scope!.EnterScope(node.Namespaces); XslFlags result = base.Visit(node); _scope.ExitScope(); // Local variables and parameters must be added to the outer scope if (_currentTemplate != null && (node.NodeType == XslNodeType.Variable || node.NodeType == XslNodeType.Param)) { - _scope.AddVariable(node.Name, (VarPar)node); + _scope.AddVariable(node.Name!, (VarPar)node); } Debug.Assert( (result & XslFlags.TypeFilter & ~XslFlags.Rtf) == 0, @@ -346,7 +348,7 @@ protected override XslFlags VisitApplyImports(XslNode node) { Debug.Assert(_forEachDepth == 0, "xsl:apply-imports cannot be inside of xsl:for-each"); Debug.Assert(_currentTemplate is Template, "xsl:apply-imports can only occur within xsl:template"); - _fwdApplyImportsGraph[(Template)_currentTemplate] = (Stylesheet)node.Arg; + _fwdApplyImportsGraph![(Template)_currentTemplate] = (Stylesheet)node.Arg!; // xsl:apply-imports uses context node and is not in context of any for-each so it requires current return XslFlags.HasCalls | XslFlags.Current | XslFlags.Rtf; } @@ -361,17 +363,17 @@ protected override XslFlags VisitApplyTemplates(XslNode node) result |= Visit(instr); if (instr.NodeType == XslNodeType.WithParam) { - ModeName mn = new ModeName(/*mode:*/node.Name, instr.Name); - VarPar modePar; + ModeName mn = new ModeName(/*mode:*/node.Name!, instr.Name!); + VarPar? modePar; if (!_applyTemplatesParams.TryGetValue(mn, out modePar)) { - modePar = _applyTemplatesParams[mn] = AstFactory.WithParam(instr.Name); + modePar = _applyTemplatesParams[mn] = AstFactory.WithParam(instr.Name!); } if (_typeDonor != null) { - _dataFlow.AddEdge(_typeDonor, modePar); + _dataFlow!.AddEdge(_typeDonor, modePar); } else { @@ -382,7 +384,7 @@ protected override XslFlags VisitApplyTemplates(XslNode node) if (_currentTemplate != null) { - AddApplyTemplatesEdge(/*mode:*/node.Name, _currentTemplate); + AddApplyTemplatesEdge(/*mode:*/node.Name!, _currentTemplate); } return XslFlags.HasCalls | XslFlags.Rtf | result; @@ -401,9 +403,9 @@ protected override XslFlags VisitAttribute(NodeCtor node) protected override XslFlags VisitCallTemplate(XslNode node) { XslFlags result = XslFlags.None; - Template target; + Template? target; - if (_compiler.NamedTemplates.TryGetValue(node.Name, out target)) + if (_compiler!.NamedTemplates.TryGetValue(node.Name!, out target)) { Debug.Assert(target != null); if (_currentTemplate != null) @@ -411,17 +413,17 @@ protected override XslFlags VisitCallTemplate(XslNode node) if (_forEachDepth == 0) { // Naked xsl:call-template, target would take its focus from currentTemplate - _revCall0Graph.AddEdge(target, _currentTemplate); + _revCall0Graph!.AddEdge(target, _currentTemplate); } else { // in other cases we need it as donor for side effects flag - _revCall1Graph.AddEdge(target, _currentTemplate); + _revCall1Graph!.AddEdge(target, _currentTemplate); } } } - VarPar[] typeDonors = new VarPar[node.Content.Count]; + VarPar?[] typeDonors = new VarPar[node.Content.Count]; int idx = 0; foreach (XslNode instr in node.Content) @@ -451,12 +453,12 @@ protected override XslFlags VisitCallTemplate(XslNode node) } VarPar par = (VarPar)instr; - VarPar found = null; + VarPar? found = null; idx = 0; foreach (XslNode withPar in node.Content) { - if (withPar.Name.Equals(par.Name)) + if (withPar.Name!.Equals(par.Name)) { found = (VarPar)withPar; _typeDonor = typeDonors[idx]; @@ -471,7 +473,7 @@ protected override XslFlags VisitCallTemplate(XslNode node) if (_typeDonor != null) { // add an edge from its type donor to xsl:param - _dataFlow.AddEdge(_typeDonor, par); + _dataFlow!.AddEdge(_typeDonor, par); } else { @@ -505,7 +507,7 @@ protected override XslFlags VisitCopy(XslNode node) protected override XslFlags VisitCopyOf(XslNode node) { - return XslFlags.Rtf | ProcessExpr(node.Select); + return XslFlags.Rtf | ProcessExpr(node.Select!); } protected override XslFlags VisitElement(NodeCtor node) @@ -527,7 +529,7 @@ protected override XslFlags VisitError(XslNode node) protected override XslFlags VisitForEach(XslNode node) { - XslFlags result = ProcessExpr(node.Select); + XslFlags result = ProcessExpr(node.Select!); _forEachDepth++; foreach (XslNode child in node.Content) { @@ -547,7 +549,7 @@ protected override XslFlags VisitForEach(XslNode node) protected override XslFlags VisitIf(XslNode node) { - return ProcessExpr(node.Select) | VisitChildren(node); + return ProcessExpr(node.Select!) | VisitChildren(node); } /* @@ -564,7 +566,7 @@ protected override XslFlags VisitLiteralAttribute(XslNode node) { return ( XslFlags.Rtf | - ProcessAvt(node.Select) | + ProcessAvt(node.Select!) | VisitChildren(node) ); } @@ -602,7 +604,7 @@ protected override XslFlags VisitPI(XslNode node) { return ( XslFlags.Rtf | - ProcessAvt(node.Select) | + ProcessAvt(node.Select!) | VisitChildren(node) ); } @@ -612,7 +614,7 @@ protected override XslFlags VisitSort(Sort node) return ( // @select is calculated in context of xsl:for-each or xsl:apply-templates, // so it does not affect focus flags - ProcessExpr(node.Select) & ~XslFlags.FocusFilter | + ProcessExpr(node.Select!) & ~XslFlags.FocusFilter | ProcessAvt(node.Lang) | ProcessAvt(node.DataType) | ProcessAvt(node.Order) | @@ -627,17 +629,17 @@ protected override XslFlags VisitText(Text node) protected override XslFlags VisitUseAttributeSet(XslNode node) { - if (_compiler.AttributeSets.TryGetValue(node.Name, out AttributeSet attSet) && _currentTemplate != null) + if (_compiler!.AttributeSets.TryGetValue(node.Name!, out AttributeSet? attSet) && _currentTemplate != null) { if (_forEachDepth == 0) { // Naked [xsl:]use-attribute-sets, attSet would take its focus from currentTemplate - _revCall0Graph.AddEdge(attSet, _currentTemplate); + _revCall0Graph!.AddEdge(attSet, _currentTemplate); } else { // in other cases we need it as donor for side effects flag - _revCall1Graph.AddEdge(attSet, _currentTemplate); + _revCall1Graph!.AddEdge(attSet, _currentTemplate); } } @@ -646,31 +648,31 @@ protected override XslFlags VisitUseAttributeSet(XslNode node) protected override XslFlags VisitValueOf(XslNode node) { - return XslFlags.Rtf | ProcessExpr(node.Select); + return XslFlags.Rtf | ProcessExpr(node.Select!); } protected override XslFlags VisitValueOfDoe(XslNode node) { - return XslFlags.Rtf | ProcessExpr(node.Select); + return XslFlags.Rtf | ProcessExpr(node.Select!); } protected override XslFlags VisitParam(VarPar node) { - Template tmpl = _currentTemplate as Template; + Template? tmpl = _currentTemplate as Template; if (tmpl != null && tmpl.Match != null) { // This template has 'match' attribute and might be called from built-in template rules, // all xsl:param's will be defaulted in that case node.Flags |= XslFlags.MayBeDefault; - ModeName mn = new ModeName(tmpl.Mode, node.Name); - VarPar par; + ModeName mn = new ModeName(tmpl.Mode, node.Name!); + VarPar? par; if (!_applyTemplatesParams.TryGetValue(mn, out par)) { - par = _applyTemplatesParams[mn] = AstFactory.WithParam(node.Name); + par = _applyTemplatesParams[mn] = AstFactory.WithParam(node.Name!); } - _dataFlow.AddEdge(par, node); + _dataFlow!.AddEdge(par, node); } node.DefValueFlags = ProcessVarPar(node); return node.DefValueFlags & ~XslFlags.TypeFilter; @@ -704,16 +706,16 @@ private XslFlags ProcessVarPar(VarPar node) { // In case of incorrect stylesheet, variable or parameter may have both a 'select' attribute and non-empty content // NOTE: This code must be in sync with recovery logic in QilGenerator - result = _xpathAnalyzer.Analyze(node.Select) | VisitChildren(node) | XslFlags.AnyType; + result = _xpathAnalyzer!.Analyze(node.Select) | VisitChildren(node) | XslFlags.AnyType; _typeDonor = null; } else { - result = _xpathAnalyzer.Analyze(node.Select); + result = _xpathAnalyzer!.Analyze(node.Select); _typeDonor = _xpathAnalyzer.TypeDonor; if (_typeDonor != null && node.NodeType != XslNodeType.WithParam) { - _dataFlow.AddEdge(_typeDonor, node); + _dataFlow!.AddEdge(_typeDonor, node); } } } @@ -733,26 +735,26 @@ private XslFlags ProcessVarPar(VarPar node) // Ignores XPath type flags private XslFlags ProcessExpr(string expr) { - return _xpathAnalyzer.Analyze(expr) & ~XslFlags.TypeFilter; + return _xpathAnalyzer!.Analyze(expr) & ~XslFlags.TypeFilter; } // Ignores XPath type flags - private XslFlags ProcessAvt(string avt) + private XslFlags ProcessAvt(string? avt) { - return _xpathAnalyzer.AnalyzeAvt(avt) & ~XslFlags.TypeFilter; + return _xpathAnalyzer!.AnalyzeAvt(avt) & ~XslFlags.TypeFilter; } // Ignores XPath type flags and focus flags - private XslFlags ProcessPattern(string pattern) + private XslFlags ProcessPattern(string? pattern) { // We need to analyze using of variables in the pattern - return _xpathAnalyzer.Analyze(pattern) & ~XslFlags.TypeFilter & ~XslFlags.FocusFilter; + return _xpathAnalyzer!.Analyze(pattern) & ~XslFlags.TypeFilter & ~XslFlags.FocusFilter; } private void AddApplyTemplatesEdge(QilName mode, ProtoTemplate dependentTemplate) { - List templates; - if (!_revApplyTemplatesGraph.TryGetValue(mode, out templates)) + List? templates; + if (!_revApplyTemplatesGraph!.TryGetValue(mode, out templates)) { templates = new List(); _revApplyTemplatesGraph.Add(mode, templates); @@ -771,11 +773,11 @@ private void AddApplyTemplatesEdge(QilName mode, ProtoTemplate dependentTemplate private void PropagateSideEffectsFlag() { // Clean Stop flags - foreach (ProtoTemplate t in _revCall0Graph.Keys) + foreach (ProtoTemplate t in _revCall0Graph!.Keys) { t.Flags &= ~XslFlags.Stop; } - foreach (ProtoTemplate t in _revCall1Graph.Keys) + foreach (ProtoTemplate t in _revCall1Graph!.Keys) { t.Flags &= ~XslFlags.Stop; } @@ -806,8 +808,8 @@ private void DepthFirstSearch(ProtoTemplate t) { Debug.Assert((t.Flags & XslFlags.Stop) == 0, "Already visited this vertex"); t.Flags |= (XslFlags.SideEffects | XslFlags.Stop); - List list; - foreach (ProtoTemplate u in _revCall0Graph.GetAdjList(t)) + List? list; + foreach (ProtoTemplate u in _revCall0Graph!.GetAdjList(t)) { if ((u.Flags & XslFlags.Stop) == 0) { @@ -815,7 +817,7 @@ private void DepthFirstSearch(ProtoTemplate t) } Debug.Assert((u.Flags & XslFlags.SideEffects) == XslFlags.SideEffects, "Flag was not set on an adjacent vertex"); } - foreach (ProtoTemplate u in _revCall1Graph.GetAdjList(t)) + foreach (ProtoTemplate u in _revCall1Graph!.GetAdjList(t)) { if ((u.Flags & XslFlags.Stop) == 0) { @@ -823,10 +825,10 @@ private void DepthFirstSearch(ProtoTemplate t) } Debug.Assert((u.Flags & XslFlags.SideEffects) == XslFlags.SideEffects, "Flag was not set on an adjacent vertex"); } - Template template = t as Template; + Template? template = t as Template; if ( template != null && // This ProteTemplate is Template - _revApplyTemplatesGraph.TryGetValue(template.Mode, out list) // list - ProtoTemplates that have apply-templatess mode="{template.Mode}" + _revApplyTemplatesGraph!.TryGetValue(template.Mode, out list) // list - ProtoTemplates that have apply-templatess mode="{template.Mode}" ) { _revApplyTemplatesGraph.Remove(template.Mode); // to prevent recursion remove this list from dictionary @@ -846,8 +848,8 @@ private void DepthFirstSearch(ProtoTemplate t) // Ignores all errors and warnings internal readonly struct NullErrorHelper : IErrorHelper { - public void ReportError(string res, params string[] args) { } - public void ReportWarning(string res, params string[] args) { } + public void ReportError(string res, params string?[]? args) { } + public void ReportWarning(string res, params string?[]? args) { } } internal class XPathAnalyzer : IXPathBuilder @@ -861,9 +863,9 @@ internal class XPathAnalyzer : IXPathBuilder // If the expression is just a reference to some VarPar, like "(($foo))", // then this field contains that VarPar, and null otherwise. - private VarPar _typeDonor; + private VarPar? _typeDonor; - public VarPar TypeDonor + public VarPar? TypeDonor { get { return _typeDonor; } } @@ -874,7 +876,7 @@ public XPathAnalyzer(Compiler compiler, CompilerScopeManager scope) _scope = scope; } - public XslFlags Analyze(string xpathExpr) + public XslFlags Analyze(string? xpathExpr) { _typeDonor = null; if (xpathExpr == null) @@ -899,7 +901,7 @@ public XslFlags Analyze(string xpathExpr) } } - public XslFlags AnalyzeAvt(string source) + public XslFlags AnalyzeAvt(string? source) { _typeDonor = null; if (source == null) @@ -944,9 +946,9 @@ public XslFlags AnalyzeAvt(string source) } // Returns null in case of error - private VarPar ResolveVariable(string prefix, string name) + private VarPar? ResolveVariable(string prefix, string name) { - string ns = ResolvePrefix(prefix); + string? ns = ResolvePrefix(prefix); if (ns == null) { return null; @@ -955,7 +957,7 @@ private VarPar ResolveVariable(string prefix, string name) } // Returns null in case of error - private string ResolvePrefix(string prefix) + private string? ResolvePrefix(string prefix) { // ignoreDefaultNs == true if (prefix.Length == 0) @@ -1016,7 +1018,7 @@ public virtual XslFlags Operator(XPathOperator op, XslFlags left, XslFlags right return result | s_operatorType[(int)op]; } - public virtual XslFlags Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name) + public virtual XslFlags Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name) { _typeDonor = null; if (xpathAxis == XPathAxis.Self && nodeType == XPathNodeType.All && prefix == null && name == null) @@ -1067,8 +1069,8 @@ public virtual XslFlags Function(string prefix, string name, IList arg if (prefix.Length == 0) { - XPathFunctionInfo xpathFunc; - XsltFunctionInfo xsltFunc; + XPathFunctionInfo? xpathFunc; + XsltFunctionInfo? xsltFunc; if (XPathBuilder.FunctionTable.TryGetValue(name, out xpathFunc)) { @@ -1103,7 +1105,7 @@ public virtual XslFlags Function(string prefix, string name, IList arg } else { - string ns = ResolvePrefix(prefix); + string? ns = ResolvePrefix(prefix); if (ns == XmlReservedNs.NsMsxsl) { switch (name) @@ -1133,7 +1135,7 @@ public virtual XslFlags Function(string prefix, string name, IList arg funcFlags = XslFlags.AnyType; if (_compiler.Settings.EnableScript && ns != null) { - XmlExtensionFunction scrFunc = _compiler.Scripts.ResolveFunction(name, ns, args.Count, default(NullErrorHelper)); + XmlExtensionFunction? scrFunc = _compiler.Scripts.ResolveFunction(name, ns, args.Count, default(NullErrorHelper)); if (scrFunc != null) { XmlQueryType xt = scrFunc.XmlReturnType; @@ -1230,10 +1232,11 @@ public virtual XslFlags Function(string prefix, string name, IList arg internal sealed class XslAstRewriter { - private CompilerScopeManager _scope; - private Stack